summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOwen Taylor <otaylor@redhat.com>2000-12-11 17:47:24 +0000
committerOwen Taylor <otaylor@src.gnome.org>2000-12-11 17:47:24 +0000
commit0cdc00ec0b5364bcbe9b0567be64bd9efdda3074 (patch)
tree7c15c586d752ed8976d6e22492d00082fc62477a
parent5a188a9f13cd4fd4b4ae243796c92cb771313f64 (diff)
downloadgtk+-0cdc00ec0b5364bcbe9b0567be64bd9efdda3074.tar.gz
Add a function to determine if a window is the focus widget within its
Wed Oct 25 14:17:43 2000 Owen Taylor <otaylor@redhat.com> * gtk/gtkwidget.[ch] (gtk_widget_is_focus): Add a function to determine if a window is the focus widget within its toplevel. * gtk/gtkcontainer.[ch]: Fix the return type of ::focus to be boolean. * gtk/gtkcontainer.c (gtk_container_real_focus): Move handling of the case where the container CAN_FOCUS to here instead of having it in each individual move-the-focus place. * gtk/gtkcontainer.c: Rewrite handling of left-right and up-down focusing to be geometric in a much more obvious sense. Arrowing around is still non-intuitive because it isn't perfect and because entries, etc, grab the arrow keys, but it at least usually will do what you expect now. * gtk/gtknotebook.[ch]: Many cleanups. Moved docs inline in this file. * gtk/gtknotebook.c: Change tabs to be a single item in the focus chain. Make movement of focus on tabs with arrow keys wrap around. * gtk/gtknotebook.c (gtk_notebook_find_child): Add CHECK_FIND_CHILD macro to give informative error messages instead of silent returns. * gtk/gtknotebook.c (gtk_notebook_init): Set the RECEIVES_DEFAULT flag since we handle GdkReturn on the tabs. * gtk/gtknotebook.c (gtk_notebook_expose_tabs): Invalidate windows rather than sending expose events directly. * gtk/gtknotebook.[ch] docs/Changes-2.0.txt: Move structure definition for GtkNotebookPage into .c file, since it is private. * gtk/testgtk.c (create_notebook): Add option for testing borderless notebook. * gtk/testgtk.c (page_switch): Removed egregious poking around in GTK+ internals. * docs/widget-system.txt: Remove references to GTK_REDRAW_PENDING. * gtk/gtkclist.[ch]: Remove key press handler, handle focusing properly through gtk_clist_focus. Make the title headers a single item in the tab-focus chain, and make left-right wrap around. * gtk/gtkwindow.c (gtk_window_focus): Add a custom focus method so that wrapping around works properly. * gtk/gtktreeview.c: Remove calls to gtk_container_set_focus_child() - that is handled for the widget now.
-rw-r--r--ChangeLog59
-rw-r--r--ChangeLog.pre-2-059
-rw-r--r--ChangeLog.pre-2-1059
-rw-r--r--ChangeLog.pre-2-259
-rw-r--r--ChangeLog.pre-2-459
-rw-r--r--ChangeLog.pre-2-659
-rw-r--r--ChangeLog.pre-2-859
-rw-r--r--docs/Changes-2.0.txt4
-rw-r--r--docs/reference/ChangeLog5
-rw-r--r--docs/reference/gtk/tmpl/gtknotebook.sgml279
-rw-r--r--docs/widget_system.txt11
-rw-r--r--gtk/gtkclist.c401
-rw-r--r--gtk/gtkclist.h5
-rw-r--r--gtk/gtkcontainer.c484
-rw-r--r--gtk/gtkcontainer.h24
-rw-r--r--gtk/gtknotebook.c1233
-rw-r--r--gtk/gtknotebook.h39
-rw-r--r--gtk/gtktreeview.c23
-rw-r--r--gtk/gtkwidget.c26
-rw-r--r--gtk/gtkwidget.h1
-rw-r--r--gtk/gtkwindow.c57
-rw-r--r--gtk/testgtk.c70
-rw-r--r--tests/testgtk.c70
23 files changed, 1979 insertions, 1166 deletions
diff --git a/ChangeLog b/ChangeLog
index d951aa6465..b43810e866 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,61 @@
+Wed Oct 25 14:17:43 2000 Owen Taylor <otaylor@redhat.com>
+
+ * gtk/gtkwidget.[ch] (gtk_widget_is_focus): Add a function
+ to determine if a window is the focus widget within
+ its toplevel.
+
+ * gtk/gtkcontainer.[ch]: Fix the return type of ::focus
+ to be boolean.
+
+ * gtk/gtkcontainer.c (gtk_container_real_focus): Move handling
+ of the case where the container CAN_FOCUS to here instead
+ of having it in each individual move-the-focus place.
+
+ * gtk/gtkcontainer.c: Rewrite handling of left-right and up-down
+ focusing to be geometric in a much more obvious sense. Arrowing
+ around is still non-intuitive because it isn't perfect and
+ because entries, etc, grab the arrow keys, but it at least
+ usually will do what you expect now.
+
+ * gtk/gtknotebook.[ch]: Many cleanups. Moved docs inline in this
+ file.
+
+ * gtk/gtknotebook.c: Change tabs to be a single item in
+ the focus chain. Make movement of focus on tabs with arrow
+ keys wrap around.
+
+ * gtk/gtknotebook.c (gtk_notebook_find_child): Add
+ CHECK_FIND_CHILD macro to give informative error messages
+ instead of silent returns.
+
+ * gtk/gtknotebook.c (gtk_notebook_init): Set the RECEIVES_DEFAULT
+ flag since we handle GdkReturn on the tabs.
+
+ * gtk/gtknotebook.c (gtk_notebook_expose_tabs): Invalidate
+ windows rather than sending expose events directly.
+
+ * gtk/gtknotebook.[ch] docs/Changes-2.0.txt: Move structure
+ definition for GtkNotebookPage into .c file, since it is private.
+
+ * gtk/testgtk.c (create_notebook): Add option for
+ testing borderless notebook.
+
+ * gtk/testgtk.c (page_switch): Removed egregious poking
+ around in GTK+ internals.
+
+ * docs/widget-system.txt: Remove references to GTK_REDRAW_PENDING.
+
+ * gtk/gtkclist.[ch]: Remove key press handler, handle focusing
+ properly through gtk_clist_focus. Make the title headers a
+ single item in the tab-focus chain, and make left-right wrap
+ around.
+
+ * gtk/gtkwindow.c (gtk_window_focus): Add a custom
+ focus method so that wrapping around works properly.
+
+ * gtk/gtktreeview.c: Remove calls to gtk_container_set_focus_child() -
+ that is handled for the widget now.
+
Mon Dec 11 11:41:12 2000 Owen Taylor <otaylor@redhat.com>
* gtk/gtkinvisible.c (gtk_invisible_init): Flag invisible
@@ -149,6 +207,7 @@ Mon Dec 11 10:02:26 2000 Owen Taylor <otaylor@redhat.com>
2000-12-06 Elliot Lee <sopwith@redhat.com>
* configure.in: Detect freetype properly
+
* modules/basic/Makefile.am, gdk/linux-fb/Makefile.am: Make use of
above.
diff --git a/ChangeLog.pre-2-0 b/ChangeLog.pre-2-0
index d951aa6465..b43810e866 100644
--- a/ChangeLog.pre-2-0
+++ b/ChangeLog.pre-2-0
@@ -1,3 +1,61 @@
+Wed Oct 25 14:17:43 2000 Owen Taylor <otaylor@redhat.com>
+
+ * gtk/gtkwidget.[ch] (gtk_widget_is_focus): Add a function
+ to determine if a window is the focus widget within
+ its toplevel.
+
+ * gtk/gtkcontainer.[ch]: Fix the return type of ::focus
+ to be boolean.
+
+ * gtk/gtkcontainer.c (gtk_container_real_focus): Move handling
+ of the case where the container CAN_FOCUS to here instead
+ of having it in each individual move-the-focus place.
+
+ * gtk/gtkcontainer.c: Rewrite handling of left-right and up-down
+ focusing to be geometric in a much more obvious sense. Arrowing
+ around is still non-intuitive because it isn't perfect and
+ because entries, etc, grab the arrow keys, but it at least
+ usually will do what you expect now.
+
+ * gtk/gtknotebook.[ch]: Many cleanups. Moved docs inline in this
+ file.
+
+ * gtk/gtknotebook.c: Change tabs to be a single item in
+ the focus chain. Make movement of focus on tabs with arrow
+ keys wrap around.
+
+ * gtk/gtknotebook.c (gtk_notebook_find_child): Add
+ CHECK_FIND_CHILD macro to give informative error messages
+ instead of silent returns.
+
+ * gtk/gtknotebook.c (gtk_notebook_init): Set the RECEIVES_DEFAULT
+ flag since we handle GdkReturn on the tabs.
+
+ * gtk/gtknotebook.c (gtk_notebook_expose_tabs): Invalidate
+ windows rather than sending expose events directly.
+
+ * gtk/gtknotebook.[ch] docs/Changes-2.0.txt: Move structure
+ definition for GtkNotebookPage into .c file, since it is private.
+
+ * gtk/testgtk.c (create_notebook): Add option for
+ testing borderless notebook.
+
+ * gtk/testgtk.c (page_switch): Removed egregious poking
+ around in GTK+ internals.
+
+ * docs/widget-system.txt: Remove references to GTK_REDRAW_PENDING.
+
+ * gtk/gtkclist.[ch]: Remove key press handler, handle focusing
+ properly through gtk_clist_focus. Make the title headers a
+ single item in the tab-focus chain, and make left-right wrap
+ around.
+
+ * gtk/gtkwindow.c (gtk_window_focus): Add a custom
+ focus method so that wrapping around works properly.
+
+ * gtk/gtktreeview.c: Remove calls to gtk_container_set_focus_child() -
+ that is handled for the widget now.
+
Mon Dec 11 11:41:12 2000 Owen Taylor <otaylor@redhat.com>
* gtk/gtkinvisible.c (gtk_invisible_init): Flag invisible
@@ -149,6 +207,7 @@ Mon Dec 11 10:02:26 2000 Owen Taylor <otaylor@redhat.com>
2000-12-06 Elliot Lee <sopwith@redhat.com>
* configure.in: Detect freetype properly
+
* modules/basic/Makefile.am, gdk/linux-fb/Makefile.am: Make use of
above.
diff --git a/ChangeLog.pre-2-10 b/ChangeLog.pre-2-10
index d951aa6465..b43810e866 100644
--- a/ChangeLog.pre-2-10
+++ b/ChangeLog.pre-2-10
@@ -1,3 +1,61 @@
+Wed Oct 25 14:17:43 2000 Owen Taylor <otaylor@redhat.com>
+
+ * gtk/gtkwidget.[ch] (gtk_widget_is_focus): Add a function
+ to determine if a window is the focus widget within
+ its toplevel.
+
+ * gtk/gtkcontainer.[ch]: Fix the return type of ::focus
+ to be boolean.
+
+ * gtk/gtkcontainer.c (gtk_container_real_focus): Move handling
+ of the case where the container CAN_FOCUS to here instead
+ of having it in each individual move-the-focus place.
+
+ * gtk/gtkcontainer.c: Rewrite handling of left-right and up-down
+ focusing to be geometric in a much more obvious sense. Arrowing
+ around is still non-intuitive because it isn't perfect and
+ because entries, etc, grab the arrow keys, but it at least
+ usually will do what you expect now.
+
+ * gtk/gtknotebook.[ch]: Many cleanups. Moved docs inline in this
+ file.
+
+ * gtk/gtknotebook.c: Change tabs to be a single item in
+ the focus chain. Make movement of focus on tabs with arrow
+ keys wrap around.
+
+ * gtk/gtknotebook.c (gtk_notebook_find_child): Add
+ CHECK_FIND_CHILD macro to give informative error messages
+ instead of silent returns.
+
+ * gtk/gtknotebook.c (gtk_notebook_init): Set the RECEIVES_DEFAULT
+ flag since we handle GdkReturn on the tabs.
+
+ * gtk/gtknotebook.c (gtk_notebook_expose_tabs): Invalidate
+ windows rather than sending expose events directly.
+
+ * gtk/gtknotebook.[ch] docs/Changes-2.0.txt: Move structure
+ definition for GtkNotebookPage into .c file, since it is private.
+
+ * gtk/testgtk.c (create_notebook): Add option for
+ testing borderless notebook.
+
+ * gtk/testgtk.c (page_switch): Removed egregious poking
+ around in GTK+ internals.
+
+ * docs/widget-system.txt: Remove references to GTK_REDRAW_PENDING.
+
+ * gtk/gtkclist.[ch]: Remove key press handler, handle focusing
+ properly through gtk_clist_focus. Make the title headers a
+ single item in the tab-focus chain, and make left-right wrap
+ around.
+
+ * gtk/gtkwindow.c (gtk_window_focus): Add a custom
+ focus method so that wrapping around works properly.
+
+ * gtk/gtktreeview.c: Remove calls to gtk_container_set_focus_child() -
+ that is handled for the widget now.
+
Mon Dec 11 11:41:12 2000 Owen Taylor <otaylor@redhat.com>
* gtk/gtkinvisible.c (gtk_invisible_init): Flag invisible
@@ -149,6 +207,7 @@ Mon Dec 11 10:02:26 2000 Owen Taylor <otaylor@redhat.com>
2000-12-06 Elliot Lee <sopwith@redhat.com>
* configure.in: Detect freetype properly
+
* modules/basic/Makefile.am, gdk/linux-fb/Makefile.am: Make use of
above.
diff --git a/ChangeLog.pre-2-2 b/ChangeLog.pre-2-2
index d951aa6465..b43810e866 100644
--- a/ChangeLog.pre-2-2
+++ b/ChangeLog.pre-2-2
@@ -1,3 +1,61 @@
+Wed Oct 25 14:17:43 2000 Owen Taylor <otaylor@redhat.com>
+
+ * gtk/gtkwidget.[ch] (gtk_widget_is_focus): Add a function
+ to determine if a window is the focus widget within
+ its toplevel.
+
+ * gtk/gtkcontainer.[ch]: Fix the return type of ::focus
+ to be boolean.
+
+ * gtk/gtkcontainer.c (gtk_container_real_focus): Move handling
+ of the case where the container CAN_FOCUS to here instead
+ of having it in each individual move-the-focus place.
+
+ * gtk/gtkcontainer.c: Rewrite handling of left-right and up-down
+ focusing to be geometric in a much more obvious sense. Arrowing
+ around is still non-intuitive because it isn't perfect and
+ because entries, etc, grab the arrow keys, but it at least
+ usually will do what you expect now.
+
+ * gtk/gtknotebook.[ch]: Many cleanups. Moved docs inline in this
+ file.
+
+ * gtk/gtknotebook.c: Change tabs to be a single item in
+ the focus chain. Make movement of focus on tabs with arrow
+ keys wrap around.
+
+ * gtk/gtknotebook.c (gtk_notebook_find_child): Add
+ CHECK_FIND_CHILD macro to give informative error messages
+ instead of silent returns.
+
+ * gtk/gtknotebook.c (gtk_notebook_init): Set the RECEIVES_DEFAULT
+ flag since we handle GdkReturn on the tabs.
+
+ * gtk/gtknotebook.c (gtk_notebook_expose_tabs): Invalidate
+ windows rather than sending expose events directly.
+
+ * gtk/gtknotebook.[ch] docs/Changes-2.0.txt: Move structure
+ definition for GtkNotebookPage into .c file, since it is private.
+
+ * gtk/testgtk.c (create_notebook): Add option for
+ testing borderless notebook.
+
+ * gtk/testgtk.c (page_switch): Removed egregious poking
+ around in GTK+ internals.
+
+ * docs/widget-system.txt: Remove references to GTK_REDRAW_PENDING.
+
+ * gtk/gtkclist.[ch]: Remove key press handler, handle focusing
+ properly through gtk_clist_focus. Make the title headers a
+ single item in the tab-focus chain, and make left-right wrap
+ around.
+
+ * gtk/gtkwindow.c (gtk_window_focus): Add a custom
+ focus method so that wrapping around works properly.
+
+ * gtk/gtktreeview.c: Remove calls to gtk_container_set_focus_child() -
+ that is handled for the widget now.
+
Mon Dec 11 11:41:12 2000 Owen Taylor <otaylor@redhat.com>
* gtk/gtkinvisible.c (gtk_invisible_init): Flag invisible
@@ -149,6 +207,7 @@ Mon Dec 11 10:02:26 2000 Owen Taylor <otaylor@redhat.com>
2000-12-06 Elliot Lee <sopwith@redhat.com>
* configure.in: Detect freetype properly
+
* modules/basic/Makefile.am, gdk/linux-fb/Makefile.am: Make use of
above.
diff --git a/ChangeLog.pre-2-4 b/ChangeLog.pre-2-4
index d951aa6465..b43810e866 100644
--- a/ChangeLog.pre-2-4
+++ b/ChangeLog.pre-2-4
@@ -1,3 +1,61 @@
+Wed Oct 25 14:17:43 2000 Owen Taylor <otaylor@redhat.com>
+
+ * gtk/gtkwidget.[ch] (gtk_widget_is_focus): Add a function
+ to determine if a window is the focus widget within
+ its toplevel.
+
+ * gtk/gtkcontainer.[ch]: Fix the return type of ::focus
+ to be boolean.
+
+ * gtk/gtkcontainer.c (gtk_container_real_focus): Move handling
+ of the case where the container CAN_FOCUS to here instead
+ of having it in each individual move-the-focus place.
+
+ * gtk/gtkcontainer.c: Rewrite handling of left-right and up-down
+ focusing to be geometric in a much more obvious sense. Arrowing
+ around is still non-intuitive because it isn't perfect and
+ because entries, etc, grab the arrow keys, but it at least
+ usually will do what you expect now.
+
+ * gtk/gtknotebook.[ch]: Many cleanups. Moved docs inline in this
+ file.
+
+ * gtk/gtknotebook.c: Change tabs to be a single item in
+ the focus chain. Make movement of focus on tabs with arrow
+ keys wrap around.
+
+ * gtk/gtknotebook.c (gtk_notebook_find_child): Add
+ CHECK_FIND_CHILD macro to give informative error messages
+ instead of silent returns.
+
+ * gtk/gtknotebook.c (gtk_notebook_init): Set the RECEIVES_DEFAULT
+ flag since we handle GdkReturn on the tabs.
+
+ * gtk/gtknotebook.c (gtk_notebook_expose_tabs): Invalidate
+ windows rather than sending expose events directly.
+
+ * gtk/gtknotebook.[ch] docs/Changes-2.0.txt: Move structure
+ definition for GtkNotebookPage into .c file, since it is private.
+
+ * gtk/testgtk.c (create_notebook): Add option for
+ testing borderless notebook.
+
+ * gtk/testgtk.c (page_switch): Removed egregious poking
+ around in GTK+ internals.
+
+ * docs/widget-system.txt: Remove references to GTK_REDRAW_PENDING.
+
+ * gtk/gtkclist.[ch]: Remove key press handler, handle focusing
+ properly through gtk_clist_focus. Make the title headers a
+ single item in the tab-focus chain, and make left-right wrap
+ around.
+
+ * gtk/gtkwindow.c (gtk_window_focus): Add a custom
+ focus method so that wrapping around works properly.
+
+ * gtk/gtktreeview.c: Remove calls to gtk_container_set_focus_child() -
+ that is handled for the widget now.
+
Mon Dec 11 11:41:12 2000 Owen Taylor <otaylor@redhat.com>
* gtk/gtkinvisible.c (gtk_invisible_init): Flag invisible
@@ -149,6 +207,7 @@ Mon Dec 11 10:02:26 2000 Owen Taylor <otaylor@redhat.com>
2000-12-06 Elliot Lee <sopwith@redhat.com>
* configure.in: Detect freetype properly
+
* modules/basic/Makefile.am, gdk/linux-fb/Makefile.am: Make use of
above.
diff --git a/ChangeLog.pre-2-6 b/ChangeLog.pre-2-6
index d951aa6465..b43810e866 100644
--- a/ChangeLog.pre-2-6
+++ b/ChangeLog.pre-2-6
@@ -1,3 +1,61 @@
+Wed Oct 25 14:17:43 2000 Owen Taylor <otaylor@redhat.com>
+
+ * gtk/gtkwidget.[ch] (gtk_widget_is_focus): Add a function
+ to determine if a window is the focus widget within
+ its toplevel.
+
+ * gtk/gtkcontainer.[ch]: Fix the return type of ::focus
+ to be boolean.
+
+ * gtk/gtkcontainer.c (gtk_container_real_focus): Move handling
+ of the case where the container CAN_FOCUS to here instead
+ of having it in each individual move-the-focus place.
+
+ * gtk/gtkcontainer.c: Rewrite handling of left-right and up-down
+ focusing to be geometric in a much more obvious sense. Arrowing
+ around is still non-intuitive because it isn't perfect and
+ because entries, etc, grab the arrow keys, but it at least
+ usually will do what you expect now.
+
+ * gtk/gtknotebook.[ch]: Many cleanups. Moved docs inline in this
+ file.
+
+ * gtk/gtknotebook.c: Change tabs to be a single item in
+ the focus chain. Make movement of focus on tabs with arrow
+ keys wrap around.
+
+ * gtk/gtknotebook.c (gtk_notebook_find_child): Add
+ CHECK_FIND_CHILD macro to give informative error messages
+ instead of silent returns.
+
+ * gtk/gtknotebook.c (gtk_notebook_init): Set the RECEIVES_DEFAULT
+ flag since we handle GdkReturn on the tabs.
+
+ * gtk/gtknotebook.c (gtk_notebook_expose_tabs): Invalidate
+ windows rather than sending expose events directly.
+
+ * gtk/gtknotebook.[ch] docs/Changes-2.0.txt: Move structure
+ definition for GtkNotebookPage into .c file, since it is private.
+
+ * gtk/testgtk.c (create_notebook): Add option for
+ testing borderless notebook.
+
+ * gtk/testgtk.c (page_switch): Removed egregious poking
+ around in GTK+ internals.
+
+ * docs/widget-system.txt: Remove references to GTK_REDRAW_PENDING.
+
+ * gtk/gtkclist.[ch]: Remove key press handler, handle focusing
+ properly through gtk_clist_focus. Make the title headers a
+ single item in the tab-focus chain, and make left-right wrap
+ around.
+
+ * gtk/gtkwindow.c (gtk_window_focus): Add a custom
+ focus method so that wrapping around works properly.
+
+ * gtk/gtktreeview.c: Remove calls to gtk_container_set_focus_child() -
+ that is handled for the widget now.
+
Mon Dec 11 11:41:12 2000 Owen Taylor <otaylor@redhat.com>
* gtk/gtkinvisible.c (gtk_invisible_init): Flag invisible
@@ -149,6 +207,7 @@ Mon Dec 11 10:02:26 2000 Owen Taylor <otaylor@redhat.com>
2000-12-06 Elliot Lee <sopwith@redhat.com>
* configure.in: Detect freetype properly
+
* modules/basic/Makefile.am, gdk/linux-fb/Makefile.am: Make use of
above.
diff --git a/ChangeLog.pre-2-8 b/ChangeLog.pre-2-8
index d951aa6465..b43810e866 100644
--- a/ChangeLog.pre-2-8
+++ b/ChangeLog.pre-2-8
@@ -1,3 +1,61 @@
+Wed Oct 25 14:17:43 2000 Owen Taylor <otaylor@redhat.com>
+
+ * gtk/gtkwidget.[ch] (gtk_widget_is_focus): Add a function
+ to determine if a window is the focus widget within
+ its toplevel.
+
+ * gtk/gtkcontainer.[ch]: Fix the return type of ::focus
+ to be boolean.
+
+ * gtk/gtkcontainer.c (gtk_container_real_focus): Move handling
+ of the case where the container CAN_FOCUS to here instead
+ of having it in each individual move-the-focus place.
+
+ * gtk/gtkcontainer.c: Rewrite handling of left-right and up-down
+ focusing to be geometric in a much more obvious sense. Arrowing
+ around is still non-intuitive because it isn't perfect and
+ because entries, etc, grab the arrow keys, but it at least
+ usually will do what you expect now.
+
+ * gtk/gtknotebook.[ch]: Many cleanups. Moved docs inline in this
+ file.
+
+ * gtk/gtknotebook.c: Change tabs to be a single item in
+ the focus chain. Make movement of focus on tabs with arrow
+ keys wrap around.
+
+ * gtk/gtknotebook.c (gtk_notebook_find_child): Add
+ CHECK_FIND_CHILD macro to give informative error messages
+ instead of silent returns.
+
+ * gtk/gtknotebook.c (gtk_notebook_init): Set the RECEIVES_DEFAULT
+ flag since we handle GdkReturn on the tabs.
+
+ * gtk/gtknotebook.c (gtk_notebook_expose_tabs): Invalidate
+ windows rather than sending expose events directly.
+
+ * gtk/gtknotebook.[ch] docs/Changes-2.0.txt: Move structure
+ definition for GtkNotebookPage into .c file, since it is private.
+
+ * gtk/testgtk.c (create_notebook): Add option for
+ testing borderless notebook.
+
+ * gtk/testgtk.c (page_switch): Removed egregious poking
+ around in GTK+ internals.
+
+ * docs/widget-system.txt: Remove references to GTK_REDRAW_PENDING.
+
+ * gtk/gtkclist.[ch]: Remove key press handler, handle focusing
+ properly through gtk_clist_focus. Make the title headers a
+ single item in the tab-focus chain, and make left-right wrap
+ around.
+
+ * gtk/gtkwindow.c (gtk_window_focus): Add a custom
+ focus method so that wrapping around works properly.
+
+ * gtk/gtktreeview.c: Remove calls to gtk_container_set_focus_child() -
+ that is handled for the widget now.
+
Mon Dec 11 11:41:12 2000 Owen Taylor <otaylor@redhat.com>
* gtk/gtkinvisible.c (gtk_invisible_init): Flag invisible
@@ -149,6 +207,7 @@ Mon Dec 11 10:02:26 2000 Owen Taylor <otaylor@redhat.com>
2000-12-06 Elliot Lee <sopwith@redhat.com>
* configure.in: Detect freetype properly
+
* modules/basic/Makefile.am, gdk/linux-fb/Makefile.am: Make use of
above.
diff --git a/docs/Changes-2.0.txt b/docs/Changes-2.0.txt
index 50877024bc..0c5789f39d 100644
--- a/docs/Changes-2.0.txt
+++ b/docs/Changes-2.0.txt
@@ -255,6 +255,10 @@ Incompatible Changes from GTK+-1.2 to GTK+-2.0:
void gtk_progress_bar_set_orientation (GtkProgressBar *pbar,
GtkProgressBarOrientation orientation);
+* The GtkNotebookPage structure has been removed from the public header files;
+ this was never meant to be a public structure, and all functionality that
+ could be done by accessing the struct fields of this structure should be
+ accesible otherwise.
- GtkMenuPositionFunc has a new parameter push_in which controls how
menus placed outside the screen is handled. If this is set to true and
diff --git a/docs/reference/ChangeLog b/docs/reference/ChangeLog
index 96b66d7d1c..e2bbb8bced 100644
--- a/docs/reference/ChangeLog
+++ b/docs/reference/ChangeLog
@@ -1,3 +1,8 @@
+Wed Oct 25 15:19:40 2000 Owen Taylor <otaylor@redhat.com>
+
+ * gtk/tmpl/gtknotebook.sgml: Moved function docs into .c
+ file, fairly extensive rewriting.
+
Thu Nov 30 00:53:45 2000 Owen Taylor <otaylor@redhat.com>
* gtk/tmpl/gtkfilesel.sgml: Fix to say that file_selection_complete()
diff --git a/docs/reference/gtk/tmpl/gtknotebook.sgml b/docs/reference/gtk/tmpl/gtknotebook.sgml
index 4b73f7b5d1..a51536f49d 100644
--- a/docs/reference/gtk/tmpl/gtknotebook.sgml
+++ b/docs/reference/gtk/tmpl/gtknotebook.sgml
@@ -2,13 +2,21 @@
GtkNotebook
<!-- ##### SECTION Short_Description ##### -->
-Set of pages with bookmarks.
+A tabbed notebook container.
<!-- ##### SECTION Long_Description ##### -->
<para>
The #GtkNotebook widget is a #GtkContainer whose children are pages that
-can be accessed through bookmarks. The pages are displayed all at the same
-place. <!-- TODO: talk about the menu -->
+can be switched between using tab labels along one edge.
+</para>
+<para>
+There are many configuration options for #GtkNotebook. Among other
+things, you can choose on which edge the tabs appear
+(see gtk_notebook_set_tab_pos()), whether, if there are too many
+tabs to fit the noteobook should be made bigger or scrolling
+arrows added (see gtk_notebook_set_scrollable), and whether there
+will be a popup menu allowing the users to switch pages.
+(see gtk_notebook_enable_popup(), gtk_noteobook_disable_popup())
</para>
<!-- ##### SECTION See_Also ##### -->
@@ -28,124 +36,83 @@ place. <!-- TODO: talk about the menu -->
</para>
-<!-- ##### MACRO GTK_NOTEBOOK_PAGE ##### -->
-<para>
-Extracts the contents of the current element of #GList @_glist_ as a
-#GtkNotebookPage.
-</para>
-
-@_glist_:
-
-
<!-- ##### STRUCT GtkNotebookPage ##### -->
<para>
-The #GtkNotebookPage structure is used to store the pages of a notebook. It
-is not an object.
+The #GtkNotebookPage is an opaque implementation detail of #GtkNotebook.
</para>
-@child: the contents of the page
-@tab_label: the label shown in the bookmark
-@menu_label: the label shown in the popup menu
-@default_menu:
-@default_tab:
-@expand:
-@fill:
-@pack:
-@requisition:
-@allocation:
-
<!-- ##### FUNCTION gtk_notebook_new ##### -->
<para>
-Creates a new #GtkNotebook widget
</para>
-@Returns: the newly created G=#GtkNotebook
+@Returns:
<!-- ##### FUNCTION gtk_notebook_append_page ##### -->
<para>
-Appends to @notebook a page whose content is @child, and whose bookmark is
-@tab_label.
</para>
-@notebook: the notebook widget
-@child: the content of the new page
-@tab_label: the bookmark for the page
+@notebook:
+@child:
+@tab_label:
<!-- ##### FUNCTION gtk_notebook_append_page_menu ##### -->
<para>
-Appends to @notebook a page whose content is @child, whose bookmark is
-@tab_label, and whose menu label is @menu_label.
</para>
-@notebook: the notebook widget
-@child: the content of the new page
-@tab_label: the bookmark of the page
-@menu_label: the menu label of the page
+@notebook:
+@child:
+@tab_label:
+@menu_label:
<!-- ##### FUNCTION gtk_notebook_prepend_page ##### -->
<para>
-Prepends to @notebook a page whose content is @child, whose bookmark is
-@tab_label, and whose menu label is @menu_label.
</para>
-@notebook: the notebook widget
-@child: the content of the new page
-@tab_label: the bookmark of the page
+@notebook:
+@child: the
+@tab_label:
<!-- ##### FUNCTION gtk_notebook_prepend_page_menu ##### -->
<para>
-Appends to @notebook a page whose content is @child, whose bookmark is
-@tab_label, and whose menu label is @menu_label.
</para>
-@notebook: the notebook widget
-@child: the content of the new page
-@tab_label: the bookmark of the page
-@menu_label: the menu label of the page
+@notebook:
+@child:
+@tab_label:
+@menu_label:
<!-- ##### FUNCTION gtk_notebook_insert_page ##### -->
<para>
-Inserts in @notebook a new page whose content is @child, and whose
-bookmark is @tab_label. The page is inserted just
-before the page number @position, starting with 0. If @position is out of
-bounds, it is assumed to be the current number of pages.
</para>
-@notebook: the notebook widget
-@child: the content of the new page
-@tab_label: the bookmark of the page
-@position: the position to insert the page
+@notebook:
+@child:
+@tab_label:
+@position:
<!-- ##### FUNCTION gtk_notebook_insert_page_menu ##### -->
<para>
-Inserts in @notebook a new page whose content is @child, whose bookmark is
-@tab_label, and whose menu label is @menu_label. The page is inserted just
-before the page number @position, starting with 0. If @position is out of
-bounds, it is assumed to be the current number of pages.
</para>
-@notebook: the notebook widget
-@child: the content of the new page
-@tab_label: the bookmark of the page
-@menu_label: the menu label of the page
-@position: the position to insert the page
+@notebook:
+@child:
+@tab_label:
+@menu_label:
+@position:
<!-- ##### FUNCTION gtk_notebook_remove_page ##### -->
<para>
-Removes the page @page_num form @notebook. Pages are numbered starting at
-zero. Negative values stand for the last page; too large values are
-ignored.
</para>
-@notebook: the notebook widget
-@page_num: the page number
+@notebook:
+@page_num:
<!-- ##### MACRO gtk_notebook_current_page ##### -->
@@ -157,56 +124,45 @@ Compatibility macro; in gtkcompat.h.
<!-- ##### FUNCTION gtk_notebook_page_num ##### -->
<para>
-Returns the page number of @child in @notebook.
</para>
-@notebook: the notebook widget
-@child: the child
-@Returns: the page number, or -1 if @child is not in @notebook
+@notebook:
+@child:
+@Returns:
<!-- ##### FUNCTION gtk_notebook_set_page ##### -->
<para>
-Switches to the page number @page_num. Negative values stand for the last
-page; too large values are ignored.
</para>
-@notebook: the notebook widget
-@page_num: the page number
+@notebook:
+@page_num:
<!-- ##### FUNCTION gtk_notebook_next_page ##### -->
<para>
-Switches to the next page. Nothing happens if the current page is the last
-page.
</para>
-@notebook: the notebook widget.
+@notebook:
<!-- ##### FUNCTION gtk_notebook_prev_page ##### -->
<para>
-Switches to the previous page. Nothing happens if the current page is the
-first page.
</para>
-@notebook: the notebook widget
+@notebook:
<!-- ##### FUNCTION gtk_notebook_reorder_child ##### -->
<para>
-Moves the page @child, so that it appears in position @position. Out of
-bounds @position will be clamped.
</para>
-@notebook: the notebook widget
-@child: the child to deplace
-@position: the new position
-
+@notebook
+@child:
+@position:
<!-- ##### FUNCTION gtk_notebook_set_tab_pos ##### -->
<para>
-Sets the position of the bookmarks.
</para>
@notebook: the notebook widget
@@ -215,62 +171,51 @@ Sets the position of the bookmarks.
<!-- ##### FUNCTION gtk_notebook_set_show_tabs ##### -->
<para>
-Sets whether to show the bookmarks or not.
</para>
-@notebook: the notebook widget
-@show_tabs: a boolean value
+@notebook:
+@show_tabs:
<!-- ##### FUNCTION gtk_notebook_set_show_border ##### -->
<para>
-Sets whether to show the border of the notebook or not. Bookmarks are in the
-border.
</para>
-@notebook: the notebook widget
-@show_border: a boolean value
+@notebook:
+@show_border:
<!-- ##### FUNCTION gtk_notebook_set_scrollable ##### -->
<para>
-Sets whether the bookmarks area may be scrollable or not if there are too
-many bookmarks to fit in the allocated area.
</para>
-@notebook: the notebook widget
-@scrollable: a boolean value
+@notebook:
+@scrollable:
<!-- ##### FUNCTION gtk_notebook_set_tab_border ##### -->
<para>
-Sets whether there should be a border around the bookmarks or not.
</para>
-@notebook: the notebook widget
-@border_width: a boolean value
+@notebook:
+@border_width:
<!-- ##### FUNCTION gtk_notebook_popup_enable ##### -->
<para>
-Enables the popup menu: if the user clicks with the right mouse button on
-the bookmarks, a menu with all the pages will be popped up.
</para>
-@notebook: the notebook widget
+@notebook:
<!-- ##### FUNCTION gtk_notebook_popup_disable ##### -->
<para>
-Disables the popup menu
</para>
-@notebook: the notebook widget
-
+@notebook:
<!-- ##### FUNCTION gtk_notebook_get_current_page ##### -->
<para>
-Returns the page number of the current page.
</para>
@notebook: the notebook widget
@@ -279,129 +224,108 @@ Returns the page number of the current page.
<!-- ##### FUNCTION gtk_notebook_get_menu_label ##### -->
<para>
-Returns the menu label of the page @child. NULL is returned if @child is not
-in @notebook or NULL if it has the default menu label.
</para>
-@notebook: the notebook widget
-@child: the page
-@Returns: the menu label
+@notebook:
+@child:
+@Returns:
<!-- ##### FUNCTION gtk_notebook_get_nth_page ##### -->
<para>
-Returns the content of the page number @page_num, or NULL if @page_num is
-out of bounds.
</para>
-@notebook: the notebook widget
-@page_num: the page number
-@Returns: the content of the page
+@notebook:
+@page_num:
+@Returns:
<!-- ##### FUNCTION gtk_notebook_get_tab_label ##### -->
<para>
-Returns the menu tab of the page @child. NULL is returned if @child is not
-in @notebook or NULL if it has the default tab label.
</para>
-@notebook: the notebook widget
-@child: the page
-@Returns: the tab label
+@notebook:
+@child:
+@Returns:
<!-- ##### FUNCTION gtk_notebook_query_tab_label_packing ##### -->
<para>
-Looks for the packing attributes of the bookmarks of @child.
</para>
-@notebook: the notebook widget
-@child: the page
-@expand: a pointer to return the expand value (or NULL)
-@fill: a pointer to return the fill value (or NULL)
-@pack_type: a pointer to return the pack_type (or NULL)
+@notebook:
+@child:
+@expand:
+@fill:
+@pack_type:
<!-- ##### FUNCTION gtk_notebook_set_homogeneous_tabs ##### -->
<para>
-Sets whether the tabs must have all the same size or not.
</para>
-@notebook: the notebook widget
-@homogeneous: a boolean value
+@notebook:
+@homogeneous:
<!-- ##### FUNCTION gtk_notebook_set_menu_label ##### -->
<para>
-Changes the menu label of @child. Nothing happens if @child is not in
-@notebook.
</para>
-@notebook: the notebook widget
-@child: the page
-@menu_label: the menu label, or NULL for default
+@notebook:
+@child:
+@menu_label:
<!-- ##### FUNCTION gtk_notebook_set_menu_label_text ##### -->
<para>
-Creates a new label and sets it as the menu label of @child.
</para>
-@notebook: the notebook widget
-@child: the page
-@menu_text: the label text
<!-- ##### FUNCTION gtk_notebook_set_tab_hborder ##### -->
<para>
-Sets whether the tabs should have a horizontal border.
</para>
-@notebook: the notebook widget
-@tab_hborder: a boolean value
+@notebook:
+@tab_hborder:
<!-- ##### FUNCTION gtk_notebook_set_tab_label ##### -->
<para>
-Changes the bookmark label of @child. Nothing happens if @child is not in
-@notebook.
</para>
-@notebook: the notebook widget
-@child: the page
-@tab_label: the bookmark label, or NULL for default
+@notebook:
+@child:
+@tab_label:
<!-- ##### FUNCTION gtk_notebook_set_tab_label_packing ##### -->
<para>
-Sets the packing parameters for the bookmark of @child. See
-#GtkBoxPackStart for the exact meanings.
</para>
-@notebook: the notebook widget
-@child: the child widget
-@expand: whether to expand the bookmark or not
-@fill: whether the bookmark should fill the allocated area or not
-@pack_type: the position of the bookmark
+@notebook:
+@child:
+@expand:
+@fill:
+@pack_type:
<!-- ##### FUNCTION gtk_notebook_set_tab_label_text ##### -->
<para>
-Creates a new label and sets it as the bookmark label of @child.
</para>
-@notebook: the notebook widget
-@child: the page
-@tab_text: the label text
+@notebook:
+@child:
+@tab_text:
<!-- ##### FUNCTION gtk_notebook_set_tab_vborder ##### -->
<para>
-Sets whether the tabs should have a vertical border.
</para>
-@notebook: the notebook widget
-@tab_vborder: a boolean value
+@notebook:
+@tab_vborder:
<!-- ##### SIGNAL GtkNotebook::switch-page ##### -->
@@ -420,46 +344,47 @@ The current page
<!-- ##### ARG GtkNotebook:tab_pos ##### -->
<para>
-The position of the bookmarks
+The edge at which the tabs for switching pages are drawn.
</para>
<!-- ##### ARG GtkNotebook:tab_border ##### -->
<para>
-Whether the bookmarks have a border or not
+Whether the tab labels have a border on all sides.
</para>
<!-- ##### ARG GtkNotebook:tab_hborder ##### -->
<para>
-Whether the bookmarks have a horizontal border or not
+Whether the tab labels have a horizontal border.
</para>
<!-- ##### ARG GtkNotebook:tab_vborder ##### -->
<para>
-Whether the bookmarks have a vertical border or not
+Whether the tab labels have a vertical border.
</para>
<!-- ##### ARG GtkNotebook:show_tabs ##### -->
<para>
-Whether to show the bookmarks or not
+Whether to show tabs for the notebook pages.
</para>
<!-- ##### ARG GtkNotebook:show_border ##### -->
<para>
-Whether to show the border or not
+Whether to draw a bevel around the noteobook.
</para>
<!-- ##### ARG GtkNotebook:scrollable ##### -->
<para>
-Whether the bookmarks should be scrollable or not
+Whether the tab label area will have arrows for scrolling if there
+are too many tabs to fit in the area.
</para>
<!-- ##### ARG GtkNotebook:enable_popup ##### -->
<para>
-Whether the popup menu is enabled or not
+Whether the popup menu for switching pages is enabled.
</para>
<!-- ##### ARG GtkNotebook:homogeneous ##### -->
<para>
-
+whether the tabs must have all the same size.
</para>
diff --git a/docs/widget_system.txt b/docs/widget_system.txt
index 07a5532db6..1c6428af11 100644
--- a/docs/widget_system.txt
+++ b/docs/widget_system.txt
@@ -150,15 +150,6 @@ GTK_USER_STYLE:
wich share a global user style from the ones which got a certain
style assign from outside the toolkit.
-GTK_REDRAW_PENDING:
- Relies on GTK_WIDGET_MAPPED (widget).
- [FIXME: this is not really enforced throughout the code, but should
- be. it only requires a few checks for GTK_WIDGET_MAPPED and
- minor changes to gtk_widget_unmap, we can then remove the check
- in gtk_widget_real_destroy]
- Means: there is an idle handler waiting for the widget, that
- will cause a full redraw (gtk_widget_draw (widget, NULL)).
-
GTK_RESIZE_PENDING:
First, this is only valid for GtkContainers.
[some of the code should move to gtkcontainer.c therefore]
@@ -245,7 +236,7 @@ In the following
Note:, the definition
[ GTK_WIDGET_DRAWABLE = GTK_WIDGET_VISIBLE && GTK_WIDGET_MAPPED
- is made in gtkwidget.c, but by 3) and 5),
+ is made in gtkwidget.h, but by 3) and 5),
GTK_WIDGET_MAPPED => GTK_WIDGET_VISIBLE
]
diff --git a/gtk/gtkclist.c b/gtk/gtkclist.c
index 8d83c47f1b..ab5ca5edfa 100644
--- a/gtk/gtkclist.c
+++ b/gtk/gtkclist.c
@@ -198,8 +198,6 @@ static void gtk_clist_map (GtkWidget *widget);
static void gtk_clist_unmap (GtkWidget *widget);
static gint gtk_clist_expose (GtkWidget *widget,
GdkEventExpose *event);
-static gint gtk_clist_key_press (GtkWidget *widget,
- GdkEventKey *event);
static gint gtk_clist_button_press (GtkWidget *widget,
GdkEventButton *event);
static gint gtk_clist_button_release (GtkWidget *widget,
@@ -217,6 +215,8 @@ static gint gtk_clist_focus_out (GtkWidget *widget,
GdkEventFocus *event);
static gint gtk_clist_focus (GtkContainer *container,
GtkDirectionType direction);
+static void gtk_clist_set_focus_child (GtkContainer *container,
+ GtkWidget *child);
static void gtk_clist_style_set (GtkWidget *widget,
GtkStyle *previous_style);
static void gtk_clist_drag_begin (GtkWidget *widget,
@@ -250,8 +250,6 @@ static void gtk_clist_drag_data_received (GtkWidget *widget,
guint time);
/* GtkContainer Methods */
-static void gtk_clist_set_focus_child (GtkContainer *container,
- GtkWidget *child);
static void gtk_clist_forall (GtkContainer *container,
gboolean include_internals,
GtkCallback callback,
@@ -438,8 +436,11 @@ static GList *gtk_clist_mergesort (GtkCList *clist,
GList *list,
gint num);
/* Misc */
-static gboolean title_focus (GtkCList *clist,
- gint dir);
+static gboolean title_focus_in (GtkCList *clist,
+ gint dir);
+static gboolean title_focus_move (GtkCList *clist,
+ gint dir);
+
static void real_row_move (GtkCList *clist,
gint source_row,
gint dest_row);
@@ -675,7 +676,6 @@ gtk_clist_class_init (GtkCListClass *klass)
widget_class->expose_event = gtk_clist_expose;
widget_class->size_request = gtk_clist_size_request;
widget_class->size_allocate = gtk_clist_size_allocate;
- widget_class->key_press_event = gtk_clist_key_press;
widget_class->focus_in_event = gtk_clist_focus_in;
widget_class->focus_out_event = gtk_clist_focus_out;
widget_class->draw_focus = gtk_clist_draw_focus;
@@ -921,7 +921,6 @@ gtk_clist_init (GtkCList *clist)
GTK_WIDGET_UNSET_FLAGS (clist, GTK_NO_WINDOW);
GTK_WIDGET_SET_FLAGS (clist, GTK_CAN_FOCUS);
- GTK_CLIST_SET_FLAG (clist, CLIST_CHILD_HAS_FOCUS);
GTK_CLIST_SET_FLAG (clist, CLIST_DRAW_DRAG_LINE);
GTK_CLIST_SET_FLAG (clist, CLIST_USE_DRAG_ICONS);
@@ -973,6 +972,7 @@ gtk_clist_init (GtkCList *clist)
clist->undo_unselection = NULL;
clist->focus_row = -1;
+ clist->focus_header_column = -1;
clist->undo_anchor = -1;
clist->anchor = -1;
@@ -4425,7 +4425,6 @@ gtk_clist_finalize (GObject *object)
* gtk_clist_unmap
* gtk_clist_expose
* gtk_clist_style_set
- * gtk_clist_key_press
* gtk_clist_button_press
* gtk_clist_button_release
* gtk_clist_motion
@@ -4466,7 +4465,6 @@ gtk_clist_realize (GtkWidget *widget)
attributes.event_mask |= (GDK_EXPOSURE_MASK |
GDK_BUTTON_PRESS_MASK |
GDK_BUTTON_RELEASE_MASK |
- GDK_KEY_PRESS_MASK |
GDK_KEY_RELEASE_MASK);
attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP;
@@ -4524,8 +4522,7 @@ gtk_clist_realize (GtkWidget *widget)
attributes.event_mask = (GDK_BUTTON_PRESS_MASK |
GDK_BUTTON_RELEASE_MASK |
GDK_POINTER_MOTION_MASK |
- GDK_POINTER_MOTION_HINT_MASK |
- GDK_KEY_PRESS_MASK);
+ GDK_POINTER_MOTION_HINT_MASK);
attributes_mask = GDK_WA_CURSOR;
attributes.cursor = gdk_cursor_new (GDK_SB_H_DOUBLE_ARROW);
clist->cursor_drag = attributes.cursor;
@@ -4842,34 +4839,6 @@ gtk_clist_style_set (GtkWidget *widget,
}
static gint
-gtk_clist_key_press (GtkWidget *widget,
- GdkEventKey *event)
-{
- g_return_val_if_fail (widget != NULL, FALSE);
- g_return_val_if_fail (GTK_IS_CLIST (widget), FALSE);
- g_return_val_if_fail (event != NULL, FALSE);
-
- if (GTK_WIDGET_CLASS (parent_class)->key_press_event &&
- GTK_WIDGET_CLASS (parent_class)->key_press_event (widget, event))
- return TRUE;
-
- switch (event->keyval)
- {
- case GDK_Tab:
- case GDK_ISO_Left_Tab:
- if (event->state & GDK_SHIFT_MASK)
- return gtk_container_focus (GTK_CONTAINER (widget),
- GTK_DIR_TAB_BACKWARD);
- else
- return gtk_container_focus (GTK_CONTAINER (widget),
- GTK_DIR_TAB_FORWARD);
- default:
- break;
- }
- return FALSE;
-}
-
-static gint
gtk_clist_button_press (GtkWidget *widget,
GdkEventButton *event)
{
@@ -6196,6 +6165,7 @@ hadjustment_value_changed (GtkAdjustment *adjustment,
gpointer data)
{
GtkCList *clist;
+ GtkContainer *container;
GdkRectangle area;
gint i;
gint y = 0;
@@ -6207,6 +6177,7 @@ hadjustment_value_changed (GtkAdjustment *adjustment,
g_return_if_fail (GTK_IS_CLIST (data));
clist = GTK_CLIST (data);
+ container = GTK_CONTAINER (data);
if (!GTK_WIDGET_DRAWABLE (clist) || adjustment != clist->hadjustment)
return;
@@ -6250,7 +6221,7 @@ hadjustment_value_changed (GtkAdjustment *adjustment,
}
if (GTK_WIDGET_CAN_FOCUS(clist) && GTK_WIDGET_HAS_FOCUS(clist) &&
- !GTK_CLIST_CHILD_HAS_FOCUS(clist) && GTK_CLIST_ADD_MODE(clist))
+ !container->focus_child && GTK_CLIST_ADD_MODE(clist))
{
y = ROW_TOP_YPIXEL (clist, clist->focus_row);
@@ -6285,7 +6256,7 @@ hadjustment_value_changed (GtkAdjustment *adjustment,
}
if (GTK_WIDGET_CAN_FOCUS(clist) && GTK_WIDGET_HAS_FOCUS(clist) &&
- !GTK_CLIST_CHILD_HAS_FOCUS(clist) && GTK_CLIST_ADD_MODE(clist))
+ !container->focus_child && GTK_CLIST_ADD_MODE(clist))
{
y = ROW_TOP_YPIXEL (clist, clist->focus_row);
@@ -6313,7 +6284,7 @@ hadjustment_value_changed (GtkAdjustment *adjustment,
check_exposures (clist);
if (GTK_WIDGET_CAN_FOCUS(clist) && GTK_WIDGET_HAS_FOCUS(clist) &&
- !GTK_CLIST_CHILD_HAS_FOCUS(clist))
+ !container->focus_child)
{
if (GTK_CLIST_ADD_MODE(clist))
{
@@ -6503,109 +6474,115 @@ row_delete (GtkCList *clist,
}
/* FOCUS FUNCTIONS
+ * gtk_clist_focus_content_area
* gtk_clist_focus
* gtk_clist_draw_focus
* gtk_clist_focus_in
* gtk_clist_focus_out
- * gtk_clist_set_focus_child
* title_focus
*/
-static gint
+static void
+gtk_clist_focus_content_area (GtkCList *clist)
+{
+ if (clist->focus_row < 0)
+ {
+ clist->focus_row = 0;
+
+ if ((clist->selection_mode == GTK_SELECTION_BROWSE ||
+ clist->selection_mode == GTK_SELECTION_EXTENDED) &&
+ !clist->selection)
+ gtk_signal_emit (GTK_OBJECT (clist),
+ clist_signals[SELECT_ROW],
+ clist->focus_row, -1, NULL);
+ }
+ gtk_widget_grab_focus (GTK_WIDGET (clist));
+}
+
+static gboolean
gtk_clist_focus (GtkContainer *container,
GtkDirectionType direction)
{
- GtkCList *clist;
- GtkWidget *focus_child;
- gint old_row;
-
- g_return_val_if_fail (container != NULL, FALSE);
- g_return_val_if_fail (GTK_IS_CLIST (container), FALSE);
+ GtkCList *clist = GTK_CLIST (container);
+ GtkWidget *focus_child = container->focus_child;
+ gboolean is_current_focus;
if (!GTK_WIDGET_IS_SENSITIVE (container))
return FALSE;
-
- clist = GTK_CLIST (container);
- focus_child = container->focus_child;
- old_row = clist->focus_row;
+ is_current_focus = gtk_widget_is_focus (GTK_WIDGET (clist));
+
+ if (focus_child &&
+ GTK_IS_CONTAINER (focus_child) &&
+ GTK_WIDGET_DRAWABLE (focus_child) &&
+ GTK_WIDGET_IS_SENSITIVE (focus_child) &&
+ gtk_container_focus (GTK_CONTAINER (focus_child), direction))
+ return TRUE;
+
switch (direction)
{
case GTK_DIR_LEFT:
case GTK_DIR_RIGHT:
- if (GTK_CLIST_CHILD_HAS_FOCUS(clist))
+ if (focus_child)
{
- if (title_focus (clist, direction))
+ if (title_focus_move (clist, direction))
return TRUE;
- gtk_container_set_focus_child (container, NULL);
- return FALSE;
- }
- gtk_widget_grab_focus (GTK_WIDGET (container));
- return TRUE;
+ }
+ else if (!is_current_focus)
+ {
+ gtk_clist_focus_content_area (clist);
+ return TRUE;
+ }
+ break;
case GTK_DIR_DOWN:
case GTK_DIR_TAB_FORWARD:
- if (GTK_CLIST_CHILD_HAS_FOCUS(clist))
+ if (!focus_child && !is_current_focus)
{
- gboolean tf = FALSE;
-
- if (((focus_child && direction == GTK_DIR_DOWN) ||
- !(tf = title_focus (clist, GTK_DIR_TAB_FORWARD)))
- && clist->rows)
- {
- if (clist->focus_row < 0)
- {
- clist->focus_row = 0;
-
- if ((clist->selection_mode == GTK_SELECTION_BROWSE ||
- clist->selection_mode == GTK_SELECTION_EXTENDED) &&
- !clist->selection)
- gtk_signal_emit (GTK_OBJECT (clist),
- clist_signals[SELECT_ROW],
- clist->focus_row, -1, NULL);
- }
- gtk_widget_grab_focus (GTK_WIDGET (container));
- return TRUE;
- }
-
- if (tf)
+ if (title_focus_in (clist, direction))
return TRUE;
}
- GTK_CLIST_SET_FLAG (clist, CLIST_CHILD_HAS_FOCUS);
+ if (!is_current_focus && clist->rows)
+ {
+ gtk_clist_focus_content_area (clist);
+ return TRUE;
+ }
break;
case GTK_DIR_UP:
case GTK_DIR_TAB_BACKWARD:
- if (!focus_child &&
- GTK_CLIST_CHILD_HAS_FOCUS(clist) && clist->rows)
+ if (!focus_child && is_current_focus)
{
- if (clist->focus_row < 0)
- {
- clist->focus_row = 0;
- if ((clist->selection_mode == GTK_SELECTION_BROWSE ||
- clist->selection_mode == GTK_SELECTION_EXTENDED) &&
- !clist->selection)
- gtk_signal_emit (GTK_OBJECT (clist),
- clist_signals[SELECT_ROW],
- clist->focus_row, -1, NULL);
- }
- gtk_widget_grab_focus (GTK_WIDGET (container));
+ if (title_focus_in (clist, direction))
+ return TRUE;
+ }
+
+ if (!is_current_focus && !focus_child && clist->rows)
+ {
+ gtk_clist_focus_content_area (clist);
return TRUE;
}
-
- GTK_CLIST_SET_FLAG (clist, CLIST_CHILD_HAS_FOCUS);
-
- if (title_focus (clist, direction))
- return TRUE;
-
break;
default:
break;
}
- gtk_container_set_focus_child (container, NULL);
return FALSE;
}
static void
+gtk_clist_set_focus_child (GtkContainer *container,
+ GtkWidget *child)
+{
+ GtkCList *clist = GTK_CLIST (container);
+ gint i;
+
+ for (i = 0; i < clist->columns; i++)
+ if (clist->column[i].button == child)
+ clist->focus_header_column = i;
+
+ parent_class->set_focus_child (container, child);
+}
+
+static void
gtk_clist_draw_focus (GtkWidget *widget)
{
GtkCList *clist;
@@ -6635,7 +6612,6 @@ gtk_clist_focus_in (GtkWidget *widget,
g_return_val_if_fail (event != NULL, FALSE);
GTK_WIDGET_SET_FLAGS (widget, GTK_HAS_FOCUS);
- GTK_CLIST_UNSET_FLAG (widget, CLIST_CHILD_HAS_FOCUS);
clist = GTK_CLIST (widget);
@@ -6668,7 +6644,6 @@ gtk_clist_focus_out (GtkWidget *widget,
g_return_val_if_fail (event != NULL, FALSE);
GTK_WIDGET_UNSET_FLAGS (widget, GTK_HAS_FOCUS);
- GTK_CLIST_SET_FLAG (widget, CLIST_CHILD_HAS_FOCUS);
gtk_widget_draw_focus (widget);
@@ -6679,123 +6654,154 @@ gtk_clist_focus_out (GtkWidget *widget,
return FALSE;
}
-static void
-gtk_clist_set_focus_child (GtkContainer *container,
- GtkWidget *child)
+static gboolean
+focus_column (GtkCList *clist, gint column, gint dir)
{
- g_return_if_fail (container != NULL);
- g_return_if_fail (GTK_IS_CLIST (container));
+ GtkWidget *child = clist->column[column].button;
+
+ if (GTK_IS_CONTAINER (child) &&
+ gtk_container_focus (GTK_CONTAINER (child), dir))
+ {
+ return TRUE;
+ }
+ else if (GTK_WIDGET_CAN_FOCUS (child))
+ {
+ gtk_widget_grab_focus (child);
+ return TRUE;
+ }
- if (child)
+ return FALSE;
+}
+
+/* Focus moved onto the headers. Focus first focusable and visible child.
+ * (FIXME: focus the last focused child if visible)
+ */
+static gboolean
+title_focus_in (GtkCList *clist, gint dir)
+{
+ gint i;
+ gint left, right;
+
+ /* Check last focused column */
+ if (clist->focus_header_column != -1)
+ {
+ i = clist->focus_header_column;
+
+ left = COLUMN_LEFT_XPIXEL (clist, i);
+ right = left + clist->column[i].area.width;
+
+ if (left >= 0 && right <= clist->clist_window_width)
+ {
+ if (focus_column (clist, i, dir))
+ return TRUE;
+ }
+ }
+
+ /* Check fully visible columns */
+ for (i = 0 ; i < clist->columns ; i++)
{
- g_return_if_fail (GTK_IS_WIDGET (child));
- GTK_CLIST_SET_FLAG (container, CLIST_CHILD_HAS_FOCUS);
+ left = COLUMN_LEFT_XPIXEL (clist, i);
+ right = left + clist->column[i].area.width;
+
+ if (left >= 0 && right <= clist->clist_window_width)
+ {
+ if (focus_column (clist, i, dir))
+ return TRUE;
+ }
}
- parent_class->set_focus_child (container, child);
+ /* Check partially visible columns */
+ for (i = 0 ; i < clist->columns ; i++)
+ {
+ left = COLUMN_LEFT_XPIXEL (clist, i);
+ right = left + clist->column[i].area.width;
+
+ if ((left < 0 && right > 0) ||
+ (left < clist->clist_window_width && right > clist->clist_window_width))
+ {
+ if (focus_column (clist, i, dir))
+ return TRUE;
+ }
+ }
+
+ return FALSE;
}
+/* Move the focus right or left within the title buttons, scrolling
+ * as necessary to keep the focused child visible.
+ */
static gboolean
-title_focus (GtkCList *clist,
- gint dir)
+title_focus_move (GtkCList *clist,
+ gint dir)
{
GtkWidget *focus_child;
gboolean return_val = FALSE;
- gint last_column;
- gint d = 1;
- gint i = 0;
+ gint d = 0;
+ gint i = -1;
gint j;
if (!GTK_CLIST_SHOW_TITLES(clist))
return FALSE;
focus_child = GTK_CONTAINER (clist)->focus_child;
+ g_assert (focus_child);
- for (last_column = clist->columns - 1;
- last_column >= 0 && !clist->column[last_column].visible; last_column--)
- ;
-
+ /* Movement direction within headers
+ */
switch (dir)
{
- case GTK_DIR_TAB_BACKWARD:
- case GTK_DIR_UP:
- if (!focus_child || !GTK_CLIST_CHILD_HAS_FOCUS(clist))
- {
- if (dir == GTK_DIR_UP)
- i = COLUMN_FROM_XPIXEL (clist, 0);
- else
- i = last_column;
- focus_child = clist->column[i].button;
- dir = GTK_DIR_TAB_FORWARD;
- }
- else
- d = -1;
+ case GTK_DIR_RIGHT:
+ d = 1;
break;
case GTK_DIR_LEFT:
d = -1;
- if (!focus_child)
- {
- i = last_column;
- focus_child = clist->column[i].button;
- }
break;
- case GTK_DIR_RIGHT:
- if (!focus_child)
+ }
+
+ for (i = 0; i < clist->columns; i++)
+ if (clist->column[i].button == focus_child)
+ break;
+
+ g_assert (i != -1); /* Have a starting column */
+
+ j = i + d;
+ while (!return_val && j >= 0 && j < clist->columns)
+ {
+ if (clist->column[j].button &&
+ GTK_WIDGET_VISIBLE (clist->column[j].button))
{
- i = 0;
- focus_child = clist->column[i].button;
+ if (focus_column (clist, j, dir))
+ {
+ return_val = TRUE;
+ break;
+ }
}
- break;
+ j += d;
}
- if (focus_child)
- while (i < clist->columns)
- {
- if (clist->column[i].button == focus_child)
- {
- if (clist->column[i].button &&
- GTK_WIDGET_VISIBLE (clist->column[i].button) &&
- GTK_IS_CONTAINER (clist->column[i].button) &&
- !GTK_WIDGET_HAS_FOCUS(clist->column[i].button))
- if (gtk_container_focus
- (GTK_CONTAINER (clist->column[i].button), dir))
+ /* If we didn't find it, wrap around and keep looking
+ */
+ if (!return_val)
+ {
+ j = d > 0 ? 0 : clist->columns - 1;
+
+ while (!return_val && j != i)
+ {
+ if (clist->column[j].button &&
+ GTK_WIDGET_VISIBLE (clist->column[j].button))
+ {
+ if (focus_column (clist, j, dir))
{
return_val = TRUE;
- i -= d;
+ break;
}
- if (!return_val && dir == GTK_DIR_UP)
- return FALSE;
- i += d;
- break;
- }
- i++;
- }
-
- j = i;
+ }
+ j += d;
+ }
+ }
- if (!return_val)
- while (j >= 0 && j < clist->columns)
- {
- if (clist->column[j].button &&
- GTK_WIDGET_VISIBLE (clist->column[j].button))
- {
- if (GTK_IS_CONTAINER (clist->column[j].button) &&
- gtk_container_focus
- (GTK_CONTAINER (clist->column[j].button), dir))
- {
- return_val = TRUE;
- break;
- }
- else if (GTK_WIDGET_CAN_FOCUS (clist->column[j].button))
- {
- gtk_widget_grab_focus (clist->column[j].button);
- return_val = TRUE;
- break;
- }
- }
- j += d;
- }
-
+ /* Scroll horizontally so focused column is visible
+ */
if (return_val)
{
if (COLUMN_LEFT_XPIXEL (clist, j) < CELL_SPACING + COLUMN_INSET)
@@ -6803,13 +6809,20 @@ title_focus (GtkCList *clist,
else if (COLUMN_LEFT_XPIXEL(clist, j) + clist->column[j].area.width >
clist->clist_window_width)
{
+ gint last_column;
+
+ for (last_column = clist->columns - 1;
+ last_column >= 0 && !clist->column[last_column].visible; last_column--);
+
if (j == last_column)
gtk_clist_moveto (clist, -1, j, 0, 0);
else
gtk_clist_moveto (clist, -1, j, 0, 1);
}
}
- return return_val;
+ return TRUE; /* Even if we didn't find a new one, we can keep the
+ * focus in the same place.
+ */
}
/* PRIVATE SCROLLING FUNCTIONS
diff --git a/gtk/gtkclist.h b/gtk/gtkclist.h
index 7bd437c404..8de30f6927 100644
--- a/gtk/gtkclist.h
+++ b/gtk/gtkclist.h
@@ -46,7 +46,7 @@ enum {
GTK_CLIST_IN_DRAG = 1 << 0,
GTK_CLIST_ROW_HEIGHT_SET = 1 << 1,
GTK_CLIST_SHOW_TITLES = 1 << 2,
- GTK_CLIST_CHILD_HAS_FOCUS = 1 << 3,
+ /* Unused */
GTK_CLIST_ADD_MODE = 1 << 4,
GTK_CLIST_AUTO_SORT = 1 << 5,
GTK_CLIST_AUTO_RESIZE_BLOCKED = 1 << 6,
@@ -97,7 +97,6 @@ typedef enum
#define GTK_CLIST_IN_DRAG(clist) (GTK_CLIST_FLAGS (clist) & GTK_CLIST_IN_DRAG)
#define GTK_CLIST_ROW_HEIGHT_SET(clist) (GTK_CLIST_FLAGS (clist) & GTK_CLIST_ROW_HEIGHT_SET)
#define GTK_CLIST_SHOW_TITLES(clist) (GTK_CLIST_FLAGS (clist) & GTK_CLIST_SHOW_TITLES)
-#define GTK_CLIST_CHILD_HAS_FOCUS(clist) (GTK_CLIST_FLAGS (clist) & GTK_CLIST_CHILD_HAS_FOCUS)
#define GTK_CLIST_ADD_MODE(clist) (GTK_CLIST_FLAGS (clist) & GTK_CLIST_ADD_MODE)
#define GTK_CLIST_AUTO_SORT(clist) (GTK_CLIST_FLAGS (clist) & GTK_CLIST_AUTO_SORT)
#define GTK_CLIST_AUTO_RESIZE_BLOCKED(clist) (GTK_CLIST_FLAGS (clist) & GTK_CLIST_AUTO_RESIZE_BLOCKED)
@@ -225,6 +224,8 @@ struct _GtkCList
/* focus handling */
gint focus_row;
+
+ gint focus_header_column;
/* dragging the selection */
gint anchor;
diff --git a/gtk/gtkcontainer.c b/gtk/gtkcontainer.c
index 053a6a893a..d3ee4fbffa 100644
--- a/gtk/gtkcontainer.c
+++ b/gtk/gtkcontainer.c
@@ -24,13 +24,15 @@
* GTK+ at ftp://ftp.gtk.org/pub/gtk/.
*/
+#include <stdarg.h>
#include <string.h>
+#include <stdlib.h>
+
#include "gtkcontainer.h"
#include "gtkprivate.h"
#include "gtksignal.h"
#include "gtkmain.h"
-#include <stdarg.h>
-
+#include "gtkwindow.h"
enum {
ADD,
@@ -59,41 +61,42 @@ struct _GtkChildArgInfo
guint seq_id;
};
-static void gtk_container_base_class_init (GtkContainerClass *klass);
-static void gtk_container_class_init (GtkContainerClass *klass);
-static void gtk_container_init (GtkContainer *container);
-static void gtk_container_destroy (GtkObject *object);
-static void gtk_container_get_arg (GtkObject *object,
- GtkArg *arg,
- guint arg_id);
-static void gtk_container_set_arg (GtkObject *object,
- GtkArg *arg,
- guint arg_id);
-static void gtk_container_add_unimplemented (GtkContainer *container,
- GtkWidget *widget);
-static void gtk_container_remove_unimplemented (GtkContainer *container,
- GtkWidget *widget);
-static void gtk_container_real_check_resize (GtkContainer *container);
-static gint gtk_container_real_focus (GtkContainer *container,
- GtkDirectionType direction);
-static void gtk_container_real_set_focus_child (GtkContainer *container,
- GtkWidget *widget);
-static gint gtk_container_focus_tab (GtkContainer *container,
- GList *children,
- GtkDirectionType direction);
-static gint gtk_container_focus_up_down (GtkContainer *container,
- GList *children,
- GtkDirectionType direction);
-static gint gtk_container_focus_left_right (GtkContainer *container,
- GList *children,
- GtkDirectionType direction);
-static gint gtk_container_focus_move (GtkContainer *container,
- GList *children,
- GtkDirectionType direction);
-static void gtk_container_children_callback (GtkWidget *widget,
- gpointer client_data);
-static void gtk_container_show_all (GtkWidget *widget);
-static void gtk_container_hide_all (GtkWidget *widget);
+static void gtk_container_base_class_init (GtkContainerClass *klass);
+static void gtk_container_class_init (GtkContainerClass *klass);
+static void gtk_container_init (GtkContainer *container);
+static void gtk_container_destroy (GtkObject *object);
+static void gtk_container_get_arg (GtkObject *object,
+ GtkArg *arg,
+ guint arg_id);
+static void gtk_container_set_arg (GtkObject *object,
+ GtkArg *arg,
+ guint arg_id);
+static void gtk_container_add_unimplemented (GtkContainer *container,
+ GtkWidget *widget);
+static void gtk_container_remove_unimplemented (GtkContainer *container,
+ GtkWidget *widget);
+static void gtk_container_real_check_resize (GtkContainer *container);
+static gboolean gtk_container_real_focus (GtkContainer *container,
+ GtkDirectionType direction);
+static void gtk_container_real_set_focus_child (GtkContainer *container,
+ GtkWidget *widget);
+static gboolean gtk_container_focus_tab (GtkContainer *container,
+ GList *children,
+ GtkDirectionType direction);
+static gboolean gtk_container_focus_up_down (GtkContainer *container,
+ GList **children,
+ GtkDirectionType direction);
+static gboolean gtk_container_focus_left_right (GtkContainer *container,
+ GList **children,
+ GtkDirectionType direction);
+static gboolean gtk_container_focus_move (GtkContainer *container,
+ GList *children,
+ GtkDirectionType direction);
+static void gtk_container_children_callback (GtkWidget *widget,
+ gpointer client_data);
+static void gtk_container_show_all (GtkWidget *widget);
+static void gtk_container_hide_all (GtkWidget *widget);
+
static gchar* gtk_container_child_default_composite_name (GtkContainer *container,
GtkWidget *child);
@@ -1182,7 +1185,7 @@ gtk_container_foreach_full (GtkContainer *container,
notify (callback_data);
}
-gint
+gboolean
gtk_container_focus (GtkContainer *container,
GtkDirectionType direction)
{
@@ -1342,7 +1345,7 @@ gtk_container_real_set_focus_child (GtkContainer *container,
}
}
-static gint
+static gboolean
gtk_container_real_focus (GtkContainer *container,
GtkDirectionType direction)
{
@@ -1364,8 +1367,11 @@ gtk_container_real_focus (GtkContainer *container,
if (GTK_WIDGET_CAN_FOCUS (container))
{
- gtk_widget_grab_focus (GTK_WIDGET (container));
- return_val = TRUE;
+ if (!GTK_WIDGET_HAS_FOCUS (container))
+ {
+ gtk_widget_grab_focus (GTK_WIDGET (container));
+ return_val = TRUE;
+ }
}
else
{
@@ -1407,11 +1413,11 @@ gtk_container_real_focus (GtkContainer *container,
break;
case GTK_DIR_UP:
case GTK_DIR_DOWN:
- return_val = gtk_container_focus_up_down (container, children, direction);
+ return_val = gtk_container_focus_up_down (container, &children, direction);
break;
case GTK_DIR_LEFT:
case GTK_DIR_RIGHT:
- return_val = gtk_container_focus_left_right (container, children, direction);
+ return_val = gtk_container_focus_left_right (container, &children, direction);
break;
}
@@ -1422,7 +1428,7 @@ gtk_container_real_focus (GtkContainer *container,
return return_val;
}
-static gint
+static gboolean
gtk_container_focus_tab (GtkContainer *container,
GList *children,
GtkDirectionType direction)
@@ -1493,227 +1499,285 @@ gtk_container_focus_tab (GtkContainer *container,
return gtk_container_focus_move (container, children, direction);
}
-static gint
-gtk_container_focus_up_down (GtkContainer *container,
- GList *children,
- GtkDirectionType direction)
+static gboolean
+old_focus_coords (GtkContainer *container, GdkRectangle *old_focus_rect)
{
- GtkWidget *child;
- GtkWidget *child2;
- GList *tmp_list;
- gint dist1, dist2;
- gint focus_x;
- gint focus_width;
- guint length;
- guint i, j;
-
- /* return failure if there isn't a focus child */
- if (container->focus_child)
+ GtkWidget *widget = GTK_WIDGET (container);
+ GtkWidget *toplevel = gtk_widget_get_toplevel (widget);
+
+ if (toplevel &&
+ GTK_IS_WINDOW (toplevel) && GTK_WINDOW (toplevel)->focus_widget &&
+ GTK_WIDGET_REALIZED (container) &&
+ GTK_WIDGET_REALIZED (GTK_WINDOW (toplevel)->focus_widget))
{
- focus_width = container->focus_child->allocation.width / 2;
- focus_x = container->focus_child->allocation.x + focus_width;
+ GtkWidget *old_focus = GTK_WINDOW (toplevel)->focus_widget;
+ GdkWindow *old_parent_window = old_focus->parent ? old_focus->parent->window : old_focus->window;
+ GdkWindow *new_parent_window = widget->window;
+ GdkWindow *toplevel_window = toplevel->window;
+
+ *old_focus_rect = old_focus->allocation;
+
+ /* Translate coordinates to the toplevel */
+
+ while (old_parent_window != toplevel_window)
+ {
+ gint dx, dy;
+
+ gdk_window_get_position (old_parent_window, &dx, &dy);
+
+ old_focus_rect->x += dx;
+ old_focus_rect->y += dy;
+
+ old_parent_window = gdk_window_get_parent (old_parent_window);
+ }
+
+ /* Translate coordinates back to the new container */
+
+ while (new_parent_window != toplevel_window)
+ {
+ gint dx, dy;
+
+ gdk_window_get_position (new_parent_window, &dx, &dy);
+
+ old_focus_rect->x -= dx;
+ old_focus_rect->y -= dy;
+
+ new_parent_window = gdk_window_get_parent (new_parent_window);
+ }
+
+ return TRUE;
}
- else
+
+ return FALSE;
+}
+
+typedef struct _CompareInfo CompareInfo;
+
+struct _CompareInfo
+{
+ gint x;
+ gint y;
+};
+
+static gint
+up_down_compare (gconstpointer a,
+ gconstpointer b,
+ gpointer data)
+{
+ const GtkWidget *child1 = a;
+ const GtkWidget *child2 = b;
+ CompareInfo *compare = data;
+
+ gint y1 = child1->allocation.y + child1->allocation.height / 2;
+ gint y2 = child2->allocation.y + child2->allocation.height / 2;
+
+ if (y1 == y2)
{
- focus_width = GTK_WIDGET (container)->allocation.width;
- if (GTK_WIDGET_NO_WINDOW (container))
- focus_x = GTK_WIDGET (container)->allocation.x;
+ gint x1 = abs (child1->allocation.x + child1->allocation.width / 2 - compare->x);
+ gint x2 = abs (child2->allocation.x + child2->allocation.width / 2 - compare->x);
+
+ if (compare->y < y1)
+ return (x1 < x2) ? -1 : ((x1 == x2) ? 0 : 1);
else
- focus_x = 0;
+ return (x1 < x2) ? 1 : ((x1 == x2) ? 0 : -1);
}
+ else
+ return (y1 < y2) ? -1 : 1;
+}
- length = g_list_length (children);
+static gboolean
+gtk_container_focus_up_down (GtkContainer *container,
+ GList **children,
+ GtkDirectionType direction)
+{
+ CompareInfo compare;
+ GList *tmp_list;
- /* sort the children in the y direction */
- for (i = 1; i < length; i++)
+ if (container->focus_child)
{
- j = i;
- tmp_list = g_list_nth (children, j);
- child = tmp_list->data;
+ gint compare_x1;
+ gint compare_x2;
+ gint compare_y;
+
+ /* Delete widgets from list that don't match minimum criteria */
- while (j > 0)
+ compare_x1 = container->focus_child->allocation.x;
+ compare_x2 = container->focus_child->allocation.x + container->focus_child->allocation.width;
+
+ if (direction == GTK_DIR_UP)
+ compare_y = container->focus_child->allocation.y;
+ else
+ compare_y = container->focus_child->allocation.y + container->focus_child->allocation.height;
+
+ tmp_list = *children;
+ while (tmp_list)
{
- child2 = tmp_list->prev->data;
- if (child->allocation.y < child2->allocation.y)
+ GtkWidget *child = tmp_list->data;
+ GList *next = tmp_list->next;
+ gint child_x1, child_x2;
+
+ if (child != container->focus_child)
{
- tmp_list->data = tmp_list->prev->data;
- tmp_list = tmp_list->prev;
- j--;
+ child_x1 = child->allocation.x;
+ child_x2 = child->allocation.x + child->allocation.width;
+
+ if ((child_x2 <= compare_x1 || child_x1 >= compare_x2) /* No horizontal overlap */ ||
+ (direction == GTK_DIR_DOWN && child->allocation.y + child->allocation.height < compare_y) || /* Not below */
+ (direction == GTK_DIR_UP && child->allocation.y > compare_y)) /* Not above */
+ {
+ *children = g_list_delete_link (*children, tmp_list);
+ }
}
- else
- break;
+
+ tmp_list = next;
}
- tmp_list->data = child;
+ compare.x = (compare_x1 + compare_x2) / 2;
+ compare.y = container->focus_child->allocation.y + container->focus_child->allocation.height / 2;
}
-
- /* sort the children in distance in the x direction
- * in distance from the current focus child while maintaining the
- * sort in the y direction
- */
- for (i = 1; i < length; i++)
+ else
{
- j = i;
- tmp_list = g_list_nth (children, j);
- child = tmp_list->data;
- dist1 = (child->allocation.x + child->allocation.width / 2) - focus_x;
+ /* No old focus widget, need to figure out starting x,y some other way
+ */
+ GtkWidget *widget = GTK_WIDGET (container);
+ GdkRectangle old_focus_rect;
- while (j > 0)
+ if (old_focus_coords (container, &old_focus_rect))
{
- child2 = tmp_list->prev->data;
- dist2 = (child2->allocation.x + child2->allocation.width / 2) - focus_x;
-
- if ((dist1 < dist2) &&
- (child->allocation.y >= child2->allocation.y))
- {
- tmp_list->data = tmp_list->prev->data;
- tmp_list = tmp_list->prev;
- j--;
- }
+ compare.x = old_focus_rect.x + old_focus_rect.width / 2;
+ }
+ else
+ {
+ if (GTK_WIDGET_NO_WINDOW (widget))
+ compare.x = widget->allocation.x + widget->allocation.width / 2;
else
- break;
+ compare.x = widget->allocation.width / 2;
}
-
- tmp_list->data = child;
+
+ if (GTK_WIDGET_NO_WINDOW (widget))
+ compare.y = (direction == GTK_DIR_DOWN) ? widget->allocation.y : widget->allocation.y + widget->allocation.height;
+ else
+ compare.y = (direction == GTK_DIR_DOWN) ? 0 : + widget->allocation.height;
}
- /* go and invalidate any widget which is too
- * far from the focus widget.
- */
- if (!container->focus_child &&
- (direction == GTK_DIR_UP))
- focus_x += focus_width;
+ *children = g_list_sort_with_data (*children, up_down_compare, &compare);
- tmp_list = children;
- while (tmp_list)
- {
- child = tmp_list->data;
+ if (direction == GTK_DIR_UP)
+ *children = g_list_reverse (*children);
- dist1 = (child->allocation.x + child->allocation.width / 2) - focus_x;
- if (((direction == GTK_DIR_DOWN) && (dist1 < 0)) ||
- ((direction == GTK_DIR_UP) && (dist1 > 0)))
- tmp_list->data = NULL;
+ return gtk_container_focus_move (container, *children, direction);
+}
- tmp_list = tmp_list->next;
- }
+static gint
+left_right_compare (gconstpointer a,
+ gconstpointer b,
+ gpointer data)
+{
+ const GtkWidget *child1 = a;
+ const GtkWidget *child2 = b;
+ CompareInfo *compare = data;
- if (direction == GTK_DIR_UP)
- children = g_list_reverse (children);
+ gint x1 = child1->allocation.x + child1->allocation.width / 2;
+ gint x2 = child2->allocation.x + child2->allocation.width / 2;
- return gtk_container_focus_move (container, children, direction);
+ if (x1 == x2)
+ {
+ gint y1 = abs (child1->allocation.y + child1->allocation.height / 2 - compare->y);
+ gint y2 = abs (child2->allocation.y + child2->allocation.height / 2 - compare->y);
+
+ if (compare->x < x1)
+ return (y1 < y2) ? -1 : ((y1 == y2) ? 0 : 1);
+ else
+ return (y1 < y2) ? 1 : ((y1 == y2) ? 0 : -1);
+ }
+ else
+ return (x1 < x2) ? -1 : 1;
}
-static gint
+static gboolean
gtk_container_focus_left_right (GtkContainer *container,
- GList *children,
+ GList **children,
GtkDirectionType direction)
{
- GtkWidget *child;
- GtkWidget *child2;
+ CompareInfo compare;
GList *tmp_list;
- gint dist1, dist2;
- gint focus_y;
- gint focus_height;
- guint length;
- guint i, j;
- /* return failure if there isn't a focus child */
if (container->focus_child)
{
- focus_height = container->focus_child->allocation.height / 2;
- focus_y = container->focus_child->allocation.y + focus_height;
- }
- else
- {
- focus_height = GTK_WIDGET (container)->allocation.height;
- if (GTK_WIDGET_NO_WINDOW (container))
- focus_y = GTK_WIDGET (container)->allocation.y;
- else
- focus_y = 0;
- }
+ gint compare_y1;
+ gint compare_y2;
+ gint compare_x;
+
+ /* Delete widgets from list that don't match minimum criteria */
- length = g_list_length (children);
+ compare_y1 = container->focus_child->allocation.y;
+ compare_y2 = container->focus_child->allocation.y + container->focus_child->allocation.height;
- /* sort the children in the x direction */
- for (i = 1; i < length; i++)
- {
- j = i;
- tmp_list = g_list_nth (children, j);
- child = tmp_list->data;
-
- while (j > 0)
+ if (direction == GTK_DIR_LEFT)
+ compare_x = container->focus_child->allocation.x;
+ else
+ compare_x = container->focus_child->allocation.x + container->focus_child->allocation.width;
+
+ tmp_list = *children;
+ while (tmp_list)
{
- child2 = tmp_list->prev->data;
- if (child->allocation.x < child2->allocation.x)
+ GtkWidget *child = tmp_list->data;
+ GList *next = tmp_list->next;
+ gint child_y1, child_y2;
+
+ if (child != container->focus_child)
{
- tmp_list->data = tmp_list->prev->data;
- tmp_list = tmp_list->prev;
- j--;
+ child_y1 = child->allocation.y;
+ child_y2 = child->allocation.y + child->allocation.height;
+
+ if ((child_y2 <= compare_y1 || child_y1 >= compare_y2) /* No vertical overlap */ ||
+ (direction == GTK_DIR_RIGHT && child->allocation.x + child->allocation.width < compare_x) || /* Not to left */
+ (direction == GTK_DIR_LEFT && child->allocation.x > compare_x)) /* Not to right */
+ {
+ *children = g_list_delete_link (*children, tmp_list);
+ }
}
- else
- break;
+
+ tmp_list = next;
}
- tmp_list->data = child;
+ compare.y = (compare_y1 + compare_y2) / 2;
+ compare.x = container->focus_child->allocation.x + container->focus_child->allocation.width / 2;
}
-
- /* sort the children in distance in the y direction
- * in distance from the current focus child while maintaining the
- * sort in the x direction
- */
- for (i = 1; i < length; i++)
+ else
{
- j = i;
- tmp_list = g_list_nth (children, j);
- child = tmp_list->data;
- dist1 = (child->allocation.y + child->allocation.height / 2) - focus_y;
+ /* No old focus widget, need to figure out starting x,y some other way
+ */
+ GtkWidget *widget = GTK_WIDGET (container);
+ GdkRectangle old_focus_rect;
- while (j > 0)
+ if (old_focus_coords (container, &old_focus_rect))
{
- child2 = tmp_list->prev->data;
- dist2 = (child2->allocation.y + child2->allocation.height / 2) - focus_y;
-
- if ((dist1 < dist2) &&
- (child->allocation.x >= child2->allocation.x))
- {
- tmp_list->data = tmp_list->prev->data;
- tmp_list = tmp_list->prev;
- j--;
- }
+ compare.y = old_focus_rect.y + old_focus_rect.height / 2;
+ }
+ else
+ {
+ if (GTK_WIDGET_NO_WINDOW (widget))
+ compare.y = widget->allocation.y + widget->allocation.height / 2;
else
- break;
+ compare.y = widget->allocation.height / 2;
}
-
- tmp_list->data = child;
+
+ if (GTK_WIDGET_NO_WINDOW (widget))
+ compare.x = (direction == GTK_DIR_RIGHT) ? widget->allocation.x : widget->allocation.x + widget->allocation.width;
+ else
+ compare.x = (direction == GTK_DIR_RIGHT) ? 0 : widget->allocation.width;
}
- /* go and invalidate any widget which is too
- * far from the focus widget.
- */
- if (!container->focus_child &&
- (direction == GTK_DIR_LEFT))
- focus_y += focus_height;
-
- tmp_list = children;
- while (tmp_list)
- {
- child = tmp_list->data;
-
- dist1 = (child->allocation.y + child->allocation.height / 2) - focus_y;
- if (((direction == GTK_DIR_RIGHT) && (dist1 < 0)) ||
- ((direction == GTK_DIR_LEFT) && (dist1 > 0)))
- tmp_list->data = NULL;
-
- tmp_list = tmp_list->next;
- }
+ *children = g_list_sort_with_data (*children, left_right_compare, &compare);
if (direction == GTK_DIR_LEFT)
- children = g_list_reverse (children);
+ *children = g_list_reverse (*children);
- return gtk_container_focus_move (container, children, direction);
+ return gtk_container_focus_move (container, *children, direction);
}
-static gint
+static gboolean
gtk_container_focus_move (GtkContainer *container,
GList *children,
GtkDirectionType direction)
@@ -1722,7 +1786,6 @@ gtk_container_focus_move (GtkContainer *container,
GtkWidget *child;
focus_child = container->focus_child;
- gtk_container_set_focus_child (container, NULL);
while (children)
{
@@ -1739,8 +1802,7 @@ gtk_container_focus_move (GtkContainer *container,
focus_child = NULL;
if (GTK_WIDGET_DRAWABLE (child) &&
- GTK_IS_CONTAINER (child) &&
- !GTK_WIDGET_HAS_FOCUS (child))
+ GTK_IS_CONTAINER (child))
if (gtk_container_focus (GTK_CONTAINER (child), direction))
return TRUE;
}
diff --git a/gtk/gtkcontainer.h b/gtk/gtkcontainer.h
index 93c29c0428..0da0c11845 100644
--- a/gtk/gtkcontainer.h
+++ b/gtk/gtkcontainer.h
@@ -83,7 +83,7 @@ struct _GtkContainerClass
gboolean include_internals,
GtkCallback callback,
gpointer callbabck_data);
- gint (* focus) (GtkContainer *container,
+ gboolean (* focus) (GtkContainer *container,
GtkDirectionType direction);
void (* set_focus_child) (GtkContainer *container,
GtkWidget *widget);
@@ -119,17 +119,17 @@ void gtk_container_set_resize_mode (GtkContainer *container,
void gtk_container_check_resize (GtkContainer *container);
-void gtk_container_foreach (GtkContainer *container,
- GtkCallback callback,
- gpointer callback_data);
-void gtk_container_foreach_full (GtkContainer *container,
- GtkCallback callback,
- GtkCallbackMarshal marshal,
- gpointer callback_data,
- GtkDestroyNotify notify);
-GList* gtk_container_children (GtkContainer *container);
-gint gtk_container_focus (GtkContainer *container,
- GtkDirectionType direction);
+void gtk_container_foreach (GtkContainer *container,
+ GtkCallback callback,
+ gpointer callback_data);
+void gtk_container_foreach_full (GtkContainer *container,
+ GtkCallback callback,
+ GtkCallbackMarshal marshal,
+ gpointer callback_data,
+ GtkDestroyNotify notify);
+GList* gtk_container_children (GtkContainer *container);
+gboolean gtk_container_focus (GtkContainer *container,
+ GtkDirectionType direction);
/* Widget-level methods */
diff --git a/gtk/gtknotebook.c b/gtk/gtknotebook.c
index 73f5a35291..424fd869da 100644
--- a/gtk/gtknotebook.c
+++ b/gtk/gtknotebook.c
@@ -78,6 +78,33 @@ enum {
CHILD_ARG_TAB_PACK
};
+#define GTK_NOTEBOOK_PAGE(_glist_) ((GtkNotebookPage *)((GList *)(_glist_))->data)
+
+struct _GtkNotebookPage
+{
+ GtkWidget *child;
+ GtkWidget *tab_label;
+ GtkWidget *menu_label;
+
+ guint default_menu : 1; /* If true, we create the menu label ourself */
+ guint default_tab : 1; /* If true, we create the tab label ourself */
+ guint expand : 1;
+ guint fill : 1;
+ guint pack : 1;
+
+ GtkRequisition requisition;
+ GtkAllocation allocation;
+};
+
+#ifdef G_DISABLE_CHECKS
+#define CHECK_FIND_CHILD(notebook, child) \
+ gtk_notebook_find_child(notebook, child, \
+ G_GNUC_PRETTY_FUNCTION)
+#else
+#define CHECK_FIND_CHILD(notebook, child) \
+ gtk_notebook_find_child(notebook, child, NULL)
+#endif
+
/*** GtkNotebook Methods ***/
static void gtk_notebook_class_init (GtkNotebookClass *klass);
static void gtk_notebook_init (GtkNotebook *notebook);
@@ -147,7 +174,8 @@ static void gtk_notebook_forall (GtkContainer *container,
/*** GtkNotebook Private Functions ***/
static void gtk_notebook_panel_realize (GtkNotebook *notebook);
-static void gtk_notebook_expose_tabs (GtkNotebook *notebook);
+static void gtk_notebook_redraw_tabs (GtkNotebook *notebook);
+static void gtk_notebook_redraw_arrows (GtkNotebook *notebook);
static void gtk_notebook_focus_changed (GtkNotebook *notebook,
GtkNotebookPage *old_page);
static void gtk_notebook_real_remove (GtkNotebook *notebook,
@@ -156,6 +184,9 @@ 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 GList *gtk_notebook_find_child (GtkNotebook *notebook,
+ GtkWidget *child,
+ const gchar *function);
static gint gtk_notebook_real_page_position (GtkNotebook *notebook,
GList *list);
static GList * gtk_notebook_search_page (GtkNotebook *notebook,
@@ -174,8 +205,7 @@ static void gtk_notebook_draw_arrow (GtkNotebook *notebook,
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_pages_allocate (GtkNotebook *notebook);
static void gtk_notebook_page_allocate (GtkNotebook *notebook,
GtkNotebookPage *page,
GtkAllocation *allocation);
@@ -194,7 +224,8 @@ static void gtk_notebook_real_switch_page (GtkNotebook *notebook,
static void gtk_notebook_switch_page (GtkNotebook *notebook,
GtkNotebookPage *page,
gint page_num);
-static gint gtk_notebook_page_select (GtkNotebook *notebook);
+static gint gtk_notebook_page_select (GtkNotebook *notebook,
+ gboolean move_focus);
static void gtk_notebook_switch_focus_tab (GtkNotebook *notebook,
GList *new_child);
static void gtk_notebook_menu_switch_page (GtkWidget *widget,
@@ -315,7 +346,7 @@ gtk_notebook_class_init (GtkNotebookClass *class)
static void
gtk_notebook_init (GtkNotebook *notebook)
{
- GTK_WIDGET_SET_FLAGS (notebook, GTK_CAN_FOCUS);
+ GTK_WIDGET_SET_FLAGS (notebook, GTK_CAN_FOCUS | GTK_RECEIVES_DEFAULT);
GTK_WIDGET_UNSET_FLAGS (notebook, GTK_NO_WINDOW);
notebook->cur_page = NULL;
@@ -340,6 +371,14 @@ gtk_notebook_init (GtkNotebook *notebook)
notebook->have_visible_child = FALSE;
}
+/**
+ * gtk_notebook_new:
+ * @void:
+ *
+ * Creates a new #GtkNotebook widget with no pages.
+
+ * Return value: the newly created #GtkNotebook
+ **/
GtkWidget*
gtk_notebook_new (void)
{
@@ -500,7 +539,7 @@ gtk_notebook_map (GtkWidget *widget)
gtk_widget_map (notebook->cur_page->child);
if (notebook->scrollable)
- gtk_notebook_pages_allocate (notebook, &(widget->allocation));
+ gtk_notebook_pages_allocate (notebook);
else
{
children = notebook->children;
@@ -915,7 +954,7 @@ gtk_notebook_size_allocate (GtkWidget *widget,
gtk_widget_size_allocate (page->child, &child_allocation);
}
- gtk_notebook_pages_allocate (notebook, allocation);
+ gtk_notebook_pages_allocate (notebook);
}
gtk_notebook_set_shape (notebook);
}
@@ -956,7 +995,51 @@ gtk_notebook_expose (GtkWidget *widget,
return FALSE;
}
-static gint
+static gboolean
+gtk_notebook_arrow_button_press (GtkNotebook *notebook,
+ GdkEventButton *event)
+{
+ GtkWidget *widget = GTK_WIDGET (notebook);
+
+ GtkArrowType arrow = event->x <= ARROW_SIZE + ARROW_SPACING / 2 ? GTK_ARROW_LEFT : GTK_ARROW_RIGHT;
+
+ if (!GTK_WIDGET_HAS_FOCUS (widget))
+ gtk_widget_grab_focus (widget);
+
+ notebook->button = event->button;
+ notebook->click_child = arrow;
+
+ if (event->button == 1)
+ {
+ if (!notebook->focus_tab ||
+ gtk_notebook_search_page (notebook, notebook->focus_tab,
+ arrow == GTK_ARROW_LEFT ? STEP_PREV : STEP_NEXT,
+ TRUE))
+ gtk_container_focus (GTK_CONTAINER (notebook),
+ arrow == GTK_ARROW_LEFT ? GTK_DIR_LEFT : GTK_DIR_RIGHT);
+
+ if (!notebook->timer)
+ {
+ notebook->timer = gtk_timeout_add
+ (NOTEBOOK_INIT_SCROLL_DELAY,
+ (GtkFunction) gtk_notebook_timer, (gpointer) notebook);
+ notebook->need_timer = TRUE;
+ }
+ }
+ else if (event->button == 2)
+ gtk_notebook_page_select (notebook, TRUE);
+ else if (event->button == 3)
+ gtk_notebook_switch_focus_tab (notebook,
+ gtk_notebook_search_page (notebook,
+ NULL,
+ arrow == GTK_ARROW_LEFT ? STEP_NEXT : STEP_PREV,
+ TRUE));
+ gtk_notebook_redraw_arrows (notebook);
+
+ return TRUE;
+}
+
+static gboolean
gtk_notebook_button_press (GtkWidget *widget,
GdkEventButton *event)
{
@@ -977,66 +1060,7 @@ gtk_notebook_button_press (GtkWidget *widget,
if (event->window == notebook->panel)
{
- if (!GTK_WIDGET_HAS_FOCUS (widget))
- gtk_widget_grab_focus (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 ||
- gtk_notebook_search_page (notebook, notebook->focus_tab,
- STEP_PREV, TRUE))
- gtk_container_focus (GTK_CONTAINER (notebook), GTK_DIR_LEFT);
-
- if (!notebook->timer)
- {
- notebook->timer = gtk_timeout_add
- (NOTEBOOK_INIT_SCROLL_DELAY,
- (GtkFunction) gtk_notebook_timer, (gpointer) notebook);
- notebook->need_timer = TRUE;
- }
- }
- else if (event->button == 2)
- gtk_notebook_page_select (GTK_NOTEBOOK (widget));
- else if (event->button == 3)
- gtk_notebook_switch_focus_tab (notebook,
- gtk_notebook_search_page (notebook,
- NULL,
- STEP_NEXT,
- TRUE));
- gtk_notebook_draw_arrow (notebook, GTK_ARROW_LEFT);
- }
- else
- {
- notebook->click_child = GTK_ARROW_RIGHT;
- if (event->button == 1)
- {
- 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
- (NOTEBOOK_INIT_SCROLL_DELAY,
- (GtkFunction) gtk_notebook_timer, (gpointer) notebook);
- notebook->need_timer = TRUE;
- }
- }
- else if (event->button == 2)
- gtk_notebook_page_select (GTK_NOTEBOOK (widget));
- else if (event->button == 3)
- gtk_notebook_switch_focus_tab
- (notebook, gtk_notebook_search_page (notebook, NULL,
- STEP_PREV, TRUE));
- gtk_notebook_draw_arrow (notebook, GTK_ARROW_RIGHT);
- }
+ return gtk_notebook_arrow_button_press (notebook, event);
}
else if (event->window == widget->window)
{
@@ -1044,7 +1068,7 @@ gtk_notebook_button_press (GtkWidget *widget,
{
gtk_menu_popup (GTK_MENU (notebook->menu), NULL, NULL,
NULL, NULL, 3, event->time);
- return FALSE;
+ return TRUE;
}
num = 0;
@@ -1086,8 +1110,8 @@ gtk_notebook_button_press (GtkWidget *widget,
if (!children && !GTK_WIDGET_HAS_FOCUS (widget))
gtk_widget_grab_focus (widget);
}
- gtk_notebook_set_shape (notebook);
- return FALSE;
+
+ return TRUE;
}
static gint
@@ -1115,11 +1139,10 @@ gtk_notebook_button_release (GtkWidget *widget,
notebook->timer = 0;
notebook->need_timer = FALSE;
}
- gtk_grab_remove (widget);
click_child = notebook->click_child;
notebook->click_child = 0;
notebook->button = 0;
- gtk_notebook_draw_arrow (notebook, click_child);
+ gtk_notebook_redraw_arrows (notebook);
}
return FALSE;
@@ -1145,19 +1168,11 @@ gtk_notebook_enter_notify (GtkWidget *widget,
gdk_window_get_pointer (notebook->panel, &x, &y, NULL);
if (x <= ARROW_SIZE + ARROW_SPACING / 2)
- {
- notebook->in_child = GTK_ARROW_LEFT;
-
- if (notebook->click_child == 0)
- gtk_notebook_draw_arrow (notebook, GTK_ARROW_LEFT);
- }
- else
- {
- notebook->in_child = GTK_ARROW_RIGHT;
+ notebook->in_child = GTK_ARROW_LEFT;
+ else
+ notebook->in_child = GTK_ARROW_RIGHT;
- if (notebook->click_child == 0)
- gtk_notebook_draw_arrow (notebook, GTK_ARROW_RIGHT);
- }
+ gtk_notebook_redraw_arrows (notebook);
}
return FALSE;
@@ -1175,19 +1190,9 @@ gtk_notebook_leave_notify (GtkWidget *widget,
notebook = GTK_NOTEBOOK (widget);
- if (event->window == notebook->panel && !notebook->click_child)
- {
- if (notebook->in_child == GTK_ARROW_LEFT)
- {
- notebook->in_child = 0;
- gtk_notebook_draw_arrow (notebook,GTK_ARROW_LEFT);
- }
- else
- {
- notebook->in_child = 0;
- gtk_notebook_draw_arrow (notebook,GTK_ARROW_RIGHT);
- }
- }
+ if (event->window == notebook->panel)
+ gtk_notebook_redraw_arrows (notebook);
+
return FALSE;
}
@@ -1209,27 +1214,21 @@ gtk_notebook_motion_notify (GtkWidget *widget,
if (event->window == notebook->panel)
{
gint x;
+ GtkArrowType old_child = notebook->in_child;
x = event->x;
if (event->is_hint)
gdk_window_get_pointer (notebook->panel, &x, NULL, NULL);
- if (x <= ARROW_SIZE + ARROW_SPACING / 2 &&
- notebook->in_child == GTK_ARROW_RIGHT)
- {
- notebook->in_child = GTK_ARROW_LEFT;
- gtk_notebook_draw_arrow (notebook, GTK_ARROW_LEFT);
- gtk_notebook_draw_arrow (notebook, GTK_ARROW_RIGHT);
- }
- else if (x > ARROW_SIZE + ARROW_SPACING / 2 &&
- notebook->in_child == GTK_ARROW_LEFT)
- {
- notebook->in_child = GTK_ARROW_RIGHT;
- gtk_notebook_draw_arrow (notebook, GTK_ARROW_RIGHT);
- gtk_notebook_draw_arrow (notebook, GTK_ARROW_LEFT);
- }
- return FALSE;
+ if (x <= ARROW_SIZE + ARROW_SPACING / 2)
+ notebook->in_child = GTK_ARROW_LEFT;
+ else
+ notebook->in_child = GTK_ARROW_RIGHT;
+
+ if (old_child != notebook->in_child)
+ gtk_notebook_redraw_arrows (notebook);
}
+
return FALSE;
}
@@ -1238,7 +1237,6 @@ gtk_notebook_key_press (GtkWidget *widget,
GdkEventKey *event)
{
GtkNotebook *notebook;
- GtkDirectionType direction = 0;
GList *list;
g_return_val_if_fail (widget != NULL, FALSE);
@@ -1252,65 +1250,6 @@ gtk_notebook_key_press (GtkWidget *widget,
switch (event->keyval)
{
- case GDK_Up:
- switch (notebook->tab_pos)
- {
- case GTK_POS_BOTTOM:
- gtk_notebook_page_select (GTK_NOTEBOOK (widget));
- return TRUE;
- case GTK_POS_TOP:
- return FALSE;
- default:
- direction = GTK_DIR_UP;
- break;
- }
- break;
- case GDK_Left:
- switch (notebook->tab_pos)
- {
- case GTK_POS_RIGHT:
- gtk_notebook_page_select (GTK_NOTEBOOK (widget));
- return TRUE;
- case GTK_POS_LEFT:
- return FALSE;
- default:
- direction = GTK_DIR_LEFT;
- break;
- }
- break;
- case GDK_Down:
- switch (notebook->tab_pos)
- {
- case GTK_POS_TOP:
- gtk_notebook_page_select (GTK_NOTEBOOK (widget));
- return TRUE;
- case GTK_POS_BOTTOM:
- return FALSE;
- default:
- direction = GTK_DIR_DOWN;
- break;
- }
- break;
- case GDK_Right:
- switch (notebook->tab_pos)
- {
- case GTK_POS_LEFT:
- gtk_notebook_page_select (GTK_NOTEBOOK (widget));
- return TRUE;
- case GTK_POS_RIGHT:
- return FALSE;
- default:
- direction = GTK_DIR_RIGHT;
- break;
- }
- 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)
@@ -1322,13 +1261,14 @@ gtk_notebook_key_press (GtkWidget *widget,
gtk_notebook_switch_focus_tab (notebook, list);
return TRUE;
case GDK_Return:
+ gtk_notebook_page_select (GTK_NOTEBOOK (widget), TRUE);
+ return TRUE;
case GDK_space:
- gtk_notebook_page_select (GTK_NOTEBOOK (widget));
+ gtk_notebook_page_select (GTK_NOTEBOOK (widget), FALSE);
return TRUE;
- default:
- return FALSE;
}
- return gtk_container_focus (GTK_CONTAINER (widget), direction);
+
+ return FALSE;
}
static gint
@@ -1482,8 +1422,10 @@ gtk_notebook_get_child_arg (GtkContainer *container,
notebook = GTK_NOTEBOOK (container);
- if (!(list = g_list_find_custom (notebook->children, child,
- gtk_notebook_page_compare)))
+ arg->type = GTK_TYPE_INVALID;
+
+ list = CHECK_FIND_CHILD (notebook, child);
+ if (!list)
{
arg->type = GTK_TYPE_INVALID;
return;
@@ -1572,112 +1514,169 @@ gtk_notebook_remove (GtkContainer *container,
}
}
+static gboolean
+focus_tabs_in (GtkNotebook *notebook)
+{
+ if (notebook->cur_page)
+ {
+ gtk_widget_grab_focus (GTK_WIDGET (notebook));
+
+ gtk_notebook_switch_focus_tab (notebook,
+ g_list_find (notebook->children,
+ notebook->cur_page));
+
+ return TRUE;
+ }
+ else
+ return FALSE;
+}
+
+static gboolean
+focus_tabs_move (GtkNotebook *notebook,
+ GtkDirectionType direction,
+ gint search_direction)
+{
+ GList *new_page;
+
+ new_page = gtk_notebook_search_page (notebook, notebook->focus_tab,
+ search_direction, TRUE);
+ if (!new_page)
+ new_page = (search_direction == STEP_NEXT) ?
+ notebook->children :
+ g_list_last (notebook->children);
+
+ gtk_notebook_switch_focus_tab (notebook, new_page);
+
+ return TRUE;
+}
+
+static gboolean
+focus_child_in (GtkNotebook *notebook,
+ GtkDirectionType direction)
+{
+ if (GTK_WIDGET_DRAWABLE (notebook->cur_page->child) &&
+ GTK_WIDGET_IS_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))
+ {
+ gtk_widget_grab_focus (notebook->cur_page->child);
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+/* Focus in the notebook can either be on the pages, or on
+ * the tabs.
+ */
static gint
gtk_notebook_focus (GtkContainer *container,
GtkDirectionType direction)
{
+ GtkWidget *old_focus_child;
GtkNotebook *notebook;
- GtkNotebookPage *page = NULL;
- GtkNotebookPage *old_page = NULL;
+ GtkDirectionType effective_direction;
+
+ /* Remap the directions into the effective direction it would be for a
+ * GTK_POS_TOP notebook
+ */
+#define D(rest) GTK_DIR_##rest
+
+ static const GtkDirectionType translate_direction[4][6] = {
+ /* LEFT */ { D(TAB_FORWARD), D(TAB_BACKWARD), D(LEFT), D(RIGHT), D(UP), D(DOWN) },
+ /* RIGHT */ { D(TAB_BACKWARD), D(TAB_FORWARD), D(LEFT), D(RIGHT), D(DOWN), D(UP) },
+ /* TOP */ { D(TAB_FORWARD), D(TAB_BACKWARD), D(UP), D(DOWN), D(LEFT), D(RIGHT) },
+ /* BOTTOM */ { D(TAB_BACKWARD), D(TAB_FORWARD), D(DOWN), D(UP), D(LEFT), D(RIGHT) },
+ };
+
+#undef D
+
+ gboolean widget_is_focus;
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_IS_SENSITIVE (container) ||
- !notebook->children ||
- !notebook->cur_page)
- return FALSE;
+ widget_is_focus = gtk_widget_is_focus (GTK_WIDGET (container));
+ old_focus_child = container->focus_child;
- if (!notebook->show_tabs)
- {
- if (GTK_WIDGET_DRAWABLE (notebook->cur_page->child) &&
- GTK_WIDGET_IS_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 (!container->focus_child)
- {
- gtk_widget_grab_focus (notebook->cur_page->child);
- return TRUE;
- }
- }
- }
- return FALSE;
- }
+ effective_direction = translate_direction[notebook->tab_pos][direction];
- if (notebook->focus_tab)
- old_page = notebook->focus_tab->data;
+ if (old_focus_child &&
+ GTK_IS_CONTAINER (old_focus_child) &&
+ GTK_WIDGET_DRAWABLE (old_focus_child) &&
+ GTK_WIDGET_IS_SENSITIVE (old_focus_child) &&
+ gtk_container_focus (GTK_CONTAINER (old_focus_child), direction))
+ return TRUE;
- if (container->focus_child && old_page &&
- container->focus_child == old_page->child && notebook->child_has_focus)
+ if (old_focus_child) /* Focus on page child */
{
- if (GTK_WIDGET_DRAWABLE (container->focus_child))
+ switch (effective_direction)
{
- if (GTK_IS_CONTAINER (container->focus_child) &&
- !GTK_WIDGET_HAS_FOCUS (container->focus_child))
- {
- if (gtk_container_focus (GTK_CONTAINER (container->focus_child),
- direction))
- return TRUE;
- }
- gtk_widget_grab_focus (GTK_WIDGET(notebook));
- return TRUE;
+ case GTK_DIR_TAB_BACKWARD:
+ case GTK_DIR_UP:
+ /* Focus onto the tabs */
+ if (notebook->show_tabs)
+ return focus_tabs_in (notebook);
+ else
+ return FALSE;
+ case GTK_DIR_DOWN:
+ case GTK_DIR_TAB_FORWARD:
+ case GTK_DIR_LEFT:
+ case GTK_DIR_RIGHT:
+ return FALSE;
}
- notebook->focus_tab = NULL;
- return FALSE;
}
-
- if (!GTK_WIDGET_HAS_FOCUS (container))
- notebook->focus_tab = NULL;
-
- switch (direction)
+ else if (widget_is_focus) /* Focus was on tabs */
{
- 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;
+ switch (effective_direction)
+ {
+ case GTK_DIR_TAB_BACKWARD:
+ case GTK_DIR_UP:
+ return FALSE;
+ case GTK_DIR_TAB_FORWARD:
+ case GTK_DIR_DOWN:
+ return focus_child_in (notebook, direction);
+ case GTK_DIR_LEFT:
+ return focus_tabs_move (notebook, direction, STEP_PREV);
+ case GTK_DIR_RIGHT:
+ return focus_tabs_move (notebook, direction, STEP_NEXT);
+ }
}
-
- if (notebook->focus_tab)
+ else /* Focus was not on widget */
{
- 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
+ switch (effective_direction)
{
- gtk_notebook_pages_allocate (notebook,
- &(GTK_WIDGET (notebook)->allocation));
- gtk_notebook_expose_tabs (notebook);
+ case GTK_DIR_TAB_FORWARD:
+ case GTK_DIR_DOWN:
+ if (focus_tabs_in (notebook))
+ return TRUE;
+ if (focus_child_in (notebook, direction))
+ return TRUE;
+ return FALSE;
+ case GTK_DIR_TAB_BACKWARD:
+ case GTK_DIR_UP:
+ if (focus_child_in (notebook, direction))
+ return TRUE;
+ if (focus_tabs_in (notebook))
+ return TRUE;
+ return FALSE;
+ case GTK_DIR_LEFT:
+ case GTK_DIR_RIGHT:
+ return focus_child_in (notebook, direction);
}
- return TRUE;
}
- gtk_notebook_focus_changed (notebook, old_page);
+ g_assert_not_reached ();
return FALSE;
-}
-
+}
+
static void
gtk_notebook_set_focus_child (GtkContainer *container,
GtkWidget *child)
@@ -1754,7 +1753,7 @@ gtk_notebook_child_type (GtkContainer *container)
/* Private GtkNotebook Functions:
*
* gtk_notebook_panel_realize
- * gtk_notebook_expose_tabs
+ * gtk_notebook_redraw_tabs
* gtk_notebook_focus_changed
* gtk_notebook_real_remove
* gtk_notebook_update_labels
@@ -1808,11 +1807,11 @@ gtk_notebook_panel_realize (GtkNotebook *notebook)
}
static void
-gtk_notebook_expose_tabs (GtkNotebook *notebook)
+gtk_notebook_redraw_tabs (GtkNotebook *notebook)
{
GtkWidget *widget;
GtkNotebookPage *page;
- GdkEventExpose event;
+ GdkRectangle redraw_rect;
gint border;
widget = GTK_WIDGET (notebook);
@@ -1823,42 +1822,49 @@ gtk_notebook_expose_tabs (GtkNotebook *notebook)
page = notebook->first_tab->data;
- event.type = GDK_EXPOSE;
- event.window = widget->window;
- event.count = 0;
- event.area.x = border;
- event.area.y = border;
+ redraw_rect.x = border;
+ redraw_rect.y = border;
switch (notebook->tab_pos)
{
case GTK_POS_BOTTOM:
- event.area.y = (widget->allocation.height - border -
- page->allocation.height -
- widget->style->ythickness);
+ redraw_rect.y = (widget->allocation.height - border -
+ page->allocation.height -
+ widget->style->ythickness);
if (page != notebook->cur_page)
- event.area.y -= widget->style->ythickness;
+ redraw_rect.y -= widget->style->ythickness;
+ /* fall through */
case GTK_POS_TOP:
- event.area.width = widget->allocation.width - 2 * border;
- event.area.height = (page->allocation.height +
- widget->style->ythickness);
+ redraw_rect.width = widget->allocation.width - 2 * border;
+ redraw_rect.height = (page->allocation.height +
+ widget->style->ythickness);
if (page != notebook->cur_page)
- event.area.height += widget->style->ythickness;
+ redraw_rect.height += widget->style->ythickness;
break;
case GTK_POS_RIGHT:
- event.area.x = (widget->allocation.width - border -
- page->allocation.width -
- widget->style->xthickness);
+ redraw_rect.x = (widget->allocation.width - border -
+ page->allocation.width -
+ widget->style->xthickness);
if (page != notebook->cur_page)
- event.area.x -= widget->style->xthickness;
+ redraw_rect.x -= widget->style->xthickness;
+ /* fall through */
case GTK_POS_LEFT:
- event.area.width = (page->allocation.width +
- widget->style->xthickness);
- event.area.height = widget->allocation.height - 2 * border;
+ redraw_rect.width = (page->allocation.width +
+ widget->style->xthickness);
+ redraw_rect.height = widget->allocation.height - 2 * border;
if (page != notebook->cur_page)
- event.area.width += widget->style->xthickness;
+ redraw_rect.width += widget->style->xthickness;
break;
- }
- gtk_widget_event (widget, (GdkEvent *) &event);
+ }
+
+ gdk_window_invalidate_rect (widget->window, &redraw_rect, TRUE);
+}
+
+static void
+gtk_notebook_redraw_arrows (GtkNotebook *notebook)
+{
+ if (GTK_WIDGET_MAPPED (notebook) && notebook->panel)
+ gdk_window_invalidate_rect (notebook->panel, NULL, FALSE);
}
static void
@@ -1944,6 +1950,23 @@ gtk_notebook_page_compare (gconstpointer a,
return (((GtkNotebookPage *) a)->child != b);
}
+static GList *
+gtk_notebook_find_child (GtkNotebook *notebook,
+ GtkWidget *child,
+ const gchar *function)
+{
+ GList *list = g_list_find_custom (notebook->children, child,
+ gtk_notebook_page_compare);
+
+#ifndef G_DISABLE_CHECKS
+ if (!list)
+ g_warning ("child argument to '%s' does not refer to the contents of a notebook page",
+ function);
+#endif
+
+ return list;
+}
+
static void
gtk_notebook_real_remove (GtkNotebook *notebook,
GList *list)
@@ -2565,12 +2588,12 @@ gtk_notebook_set_shape (GtkNotebook *notebook)
* gtk_notebook_calc_tabs
*/
static void
-gtk_notebook_pages_allocate (GtkNotebook *notebook,
- GtkAllocation *allocation)
+gtk_notebook_pages_allocate (GtkNotebook *notebook)
{
- GtkWidget *widget;
- GtkContainer *container;
+ GtkWidget *widget = GTK_WIDGET (notebook);
+ GtkContainer *container = GTK_CONTAINER (notebook);
GtkNotebookPage *page = NULL;
+ GtkAllocation *allocation = &widget->allocation;
GtkAllocation child_allocation;
GList *children = NULL;
GList *last_child = NULL;
@@ -2587,9 +2610,6 @@ gtk_notebook_pages_allocate (GtkNotebook *notebook,
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;
@@ -2599,13 +2619,16 @@ gtk_notebook_pages_allocate (GtkNotebook *notebook,
child_allocation.y = (allocation->height -
notebook->cur_page->requisition.height -
container->border_width);
+ /* fall through */
case GTK_POS_TOP:
child_allocation.height = notebook->cur_page->requisition.height;
break;
+
case GTK_POS_RIGHT:
child_allocation.x = (allocation->width -
notebook->cur_page->requisition.width -
container->border_width);
+ /* fall through */
case GTK_POS_LEFT:
child_allocation.width = notebook->cur_page->requisition.width;
break;
@@ -2877,10 +2900,8 @@ gtk_notebook_pages_allocate (GtkNotebook *notebook,
{
if (children == last_child)
{
- gtk_notebook_set_shape (notebook);
- return;
- children = NULL;
- break;
+ /* FIXME double check */
+ goto done;
}
page = children->data;
@@ -3007,7 +3028,10 @@ gtk_notebook_pages_allocate (GtkNotebook *notebook,
}
}
}
+
+ done:
gtk_notebook_set_shape (notebook);
+ gtk_notebook_redraw_tabs (notebook);
}
static void
@@ -3305,9 +3329,11 @@ gtk_notebook_switch_page (GtkNotebook *notebook,
}
static gint
-gtk_notebook_page_select (GtkNotebook *notebook)
+gtk_notebook_page_select (GtkNotebook *notebook,
+ gboolean move_focus)
{
GtkNotebookPage *page;
+ GtkDirectionType dir = GTK_DIR_DOWN; /* Quiet GCC */
g_return_val_if_fail (notebook != NULL, FALSE);
g_return_val_if_fail (GTK_IS_NOTEBOOK (notebook), FALSE);
@@ -3318,18 +3344,37 @@ gtk_notebook_page_select (GtkNotebook *notebook)
page = notebook->focus_tab->data;
gtk_notebook_switch_page (notebook, page, -1);
- if (GTK_WIDGET_VISIBLE (page->child))
+ if (move_focus)
{
- if (GTK_IS_CONTAINER (page->child))
+ switch (notebook->tab_pos)
{
- if (gtk_container_focus (GTK_CONTAINER (page->child),
- GTK_DIR_TAB_FORWARD))
- return TRUE;
+ case GTK_POS_TOP:
+ dir = GTK_DIR_DOWN;
+ break;
+ case GTK_POS_BOTTOM:
+ dir = GTK_DIR_UP;
+ break;
+ case GTK_POS_LEFT:
+ dir = GTK_DIR_RIGHT;
+ break;
+ case GTK_POS_RIGHT:
+ dir = GTK_DIR_LEFT;
+ break;
}
- else if (GTK_WIDGET_CAN_FOCUS (page->child))
+
+ if (GTK_WIDGET_VISIBLE (page->child))
{
- gtk_widget_grab_focus (page->child);
- return TRUE;
+ if (GTK_IS_CONTAINER (page->child))
+ {
+ if (gtk_container_focus (GTK_CONTAINER (page->child),
+ dir))
+ return TRUE;
+ }
+ else if (GTK_WIDGET_CAN_FOCUS (page->child))
+ {
+ gtk_widget_grab_focus (page->child);
+ return TRUE;
+ }
}
}
return FALSE;
@@ -3353,44 +3398,7 @@ gtk_notebook_switch_focus_tab (GtkNotebook *notebook,
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);
- }
- }
- }
+ gtk_notebook_redraw_arrows (notebook);
if (!notebook->show_tabs || !notebook->focus_tab)
return;
@@ -3402,11 +3410,7 @@ gtk_notebook_switch_focus_tab (GtkNotebook *notebook,
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_pages_allocate (notebook);
gtk_notebook_set_shape (notebook);
}
@@ -3510,49 +3514,150 @@ gtk_notebook_menu_detacher (GtkWidget *widget,
* gtk_notebook_insert_page_menu
* gtk_notebook_remove_page
*/
+/**
+ * gtk_notebook_append_page:
+ * @notebook: a #GtkNotebook
+ * @child: the #GtkWidget to use as the contents of the page.
+ * @tab_label: the #GtkWidget to be used as the label for the page,
+ * or %NULL to use the default label, 'page N'.
+ *
+ * Appends a page to @notebook.
+ **/
void
gtk_notebook_append_page (GtkNotebook *notebook,
GtkWidget *child,
GtkWidget *tab_label)
{
+ g_return_if_fail (GTK_IS_NOTEBOOK (notebook));
+ g_return_if_fail (GTK_IS_WIDGET (child));
+ g_return_if_fail (tab_label == NULL || GTK_IS_WIDGET (tab_label));
+
gtk_notebook_insert_page_menu (notebook, child, tab_label, NULL, -1);
}
+/**
+ * gtk_notebook_append_page_menu:
+ * @notebook: a #GtkNotebook
+ * @child: the #GtkWidget to use as the contents of the page.
+ * @tab_label: the #GtkWidget to be used as the label for the page,
+ * or %NULL to use the default label, 'page N'.
+ * @menu_label: the widget to use as a label for the page-switch
+ * menu, if that is enabled. If %NULL, and @tab_label
+ * is a #GtkLabel or %NULL, then the menu label will be
+ * a newly created label with the same text as @tab_label;
+ * If @tab_label is not a #GtkLabel, @menu_label must be
+ * specified if the page-switch menu is to be used.
+ *
+ * Appends a page to @notebook, specifying the widget to use as the
+ * label in the popup menu.
+ **/
void
gtk_notebook_append_page_menu (GtkNotebook *notebook,
GtkWidget *child,
GtkWidget *tab_label,
GtkWidget *menu_label)
{
+ g_return_if_fail (GTK_IS_NOTEBOOK (notebook));
+ g_return_if_fail (GTK_IS_WIDGET (child));
+ g_return_if_fail (tab_label == NULL || GTK_IS_WIDGET (tab_label));
+ g_return_if_fail (menu_label == NULL || GTK_IS_WIDGET (menu_label));
+
gtk_notebook_insert_page_menu (notebook, child, tab_label, menu_label, -1);
}
+/**
+ * gtk_notebook_prepend_page:
+ * @notebook: a #GtkNotebook
+ * @child: the #GtkWidget to use as the contents of the page.
+ * @tab_label: the #GtkWidget to be used as the label for the page,
+ * or %NULL to use the default label, 'page N'.
+ *
+ * Prepends a page to @noteobook.
+ **/
void
gtk_notebook_prepend_page (GtkNotebook *notebook,
GtkWidget *child,
GtkWidget *tab_label)
{
+ g_return_if_fail (GTK_IS_NOTEBOOK (notebook));
+ g_return_if_fail (GTK_IS_WIDGET (child));
+ g_return_if_fail (tab_label == NULL || GTK_IS_WIDGET (tab_label));
+
gtk_notebook_insert_page_menu (notebook, child, tab_label, NULL, 0);
}
+/**
+ * gtk_notebook_prepend_page_menu:
+ * @notebook: a #GtkNotebook
+ * @child: the #GtkWidget to use as the contents of the page.
+ * @tab_label: the #GtkWidget to be used as the label for the page,
+ * or %NULL to use the default label, 'page N'.
+ * @menu_label: the widget to use as a label for the page-switch
+ * menu, if that is enabled. If %NULL, and @tab_label
+ * is a #GtkLabel or %NULL, then the menu label will be
+ * a newly created label with the same text as @tab_label;
+ * If @tab_label is not a #GtkLabel, @menu_label must be
+ * specified if the page-switch menu is to be used.
+ *
+ * Prepends a page to @notebook, specifying the widget to use as the
+ * label in the popup menu.
+ **/
void
gtk_notebook_prepend_page_menu (GtkNotebook *notebook,
GtkWidget *child,
GtkWidget *tab_label,
GtkWidget *menu_label)
{
+ g_return_if_fail (GTK_IS_NOTEBOOK (notebook));
+ g_return_if_fail (GTK_IS_WIDGET (child));
+ g_return_if_fail (tab_label == NULL || GTK_IS_WIDGET (tab_label));
+ g_return_if_fail (menu_label == NULL || GTK_IS_WIDGET (menu_label));
+
gtk_notebook_insert_page_menu (notebook, child, tab_label, menu_label, 0);
}
+/**
+ * gtk_notebook_insert_page:
+ * @notebook: a #GtkNotebook
+ * @child: the #GtkWidget to use as the contents of the page.
+ * @tab_label: the #GtkWidget to be used as the label for the page,
+ * or %NULL to use the default label, 'page N'.
+ * @position: the index (starting at 0) at which to insert the page,
+ * or -1 to append the page after all other pages.
+ *
+ * Insert a page into @notebook at the given position
+ **/
void
gtk_notebook_insert_page (GtkNotebook *notebook,
GtkWidget *child,
GtkWidget *tab_label,
gint position)
{
+ g_return_if_fail (GTK_IS_NOTEBOOK (notebook));
+ g_return_if_fail (GTK_IS_WIDGET (child));
+ g_return_if_fail (tab_label == NULL || GTK_IS_WIDGET (tab_label));
+
gtk_notebook_insert_page_menu (notebook, child, tab_label, NULL, position);
}
+/**
+ * gtk_notebook_insert_page_menu:
+ * @notebook: a #GtkNotebook
+ * @child: the #GtkWidget to use as the contents of the page.
+ * @tab_label: the #GtkWidget to be used as the label for the page,
+ * or %NULL to use the default label, 'page N'.
+ * @menu_label: the widget to use as a label for the page-switch
+ * menu, if that is enabled. If %NULL, and @tab_label
+ * is a #GtkLabel or %NULL, then the menu label will be
+ * a newly created label with the same text as @tab_label;
+ * If @tab_label is not a #GtkLabel, @menu_label must be
+ * specified if the page-switch menu is to be used.
+ * @position: the index (starting at 0) at which to insert the page,
+ * or -1 to append the page after all other pages.
+ *
+ * Insert a page into @notebook at the given position, specifying
+ * the widget to use as the label in the popup menu.
+ **/
void
gtk_notebook_insert_page_menu (GtkNotebook *notebook,
GtkWidget *child,
@@ -3563,9 +3668,10 @@ gtk_notebook_insert_page_menu (GtkNotebook *notebook,
GtkNotebookPage *page;
gint nchildren;
- 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));
+ g_return_if_fail (tab_label == NULL || GTK_IS_WIDGET (tab_label));
+ g_return_if_fail (menu_label == NULL || GTK_IS_WIDGET (menu_label));
page = g_new (GtkNotebookPage, 1);
page->child = child;
@@ -3601,7 +3707,7 @@ gtk_notebook_insert_page_menu (GtkNotebook *notebook,
else
{
gtk_widget_ref (page->menu_label);
- gtk_object_sink (GTK_OBJECT(page->menu_label));
+ gtk_object_sink (GTK_OBJECT (page->menu_label));
}
if (notebook->menu)
@@ -3659,6 +3765,16 @@ gtk_notebook_insert_page_menu (GtkNotebook *notebook,
}
}
+/**
+ * gtk_notebook_remove_page:
+ * @notebook: a #GtkNotebook.
+ * @page_num: the index of a notebook page, starting
+ * from 0. If -1, the last page will
+ * be removed.
+ *
+ * Removes a page from the notebook given its index
+ * in the notebook.
+ **/
void
gtk_notebook_remove_page (GtkNotebook *notebook,
gint page_num)
@@ -3689,10 +3805,19 @@ gtk_notebook_remove_page (GtkNotebook *notebook,
* gtk_notebook_next_page
* gtk_notebook_prev_page
*/
+/**
+ * gtk_notebook_get_current_page:
+ * @notebook: a #GtkNotebook
+ *
+ * Returns the page number of the current page.
+ *
+ * Return value: the index (starting from 0) of the current
+ * page in the notebook. If the notebook has no pages, then
+ * -1 will be returned.
+ **/
gint
gtk_notebook_get_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)
@@ -3701,13 +3826,22 @@ gtk_notebook_get_current_page (GtkNotebook *notebook)
return g_list_index (notebook->children, notebook->cur_page);
}
+/**
+ * gtk_notebook_get_nth_page:
+ * @notebook: a #GtkNotebook
+ * @page_num: the index of a page in the noteobok
+ *
+ * Returns the child widget contained in page number @page_num.
+ *
+ * Return value: the child widget, or %NULL if @page_num is
+ * out of bounds.
+ **/
GtkWidget*
gtk_notebook_get_nth_page (GtkNotebook *notebook,
gint page_num)
{
GtkNotebookPage *page;
- g_return_val_if_fail (notebook != NULL, NULL);
g_return_val_if_fail (GTK_IS_NOTEBOOK (notebook), NULL);
page = g_list_nth_data (notebook->children, page_num);
@@ -3718,6 +3852,17 @@ gtk_notebook_get_nth_page (GtkNotebook *notebook,
return NULL;
}
+/**
+ * gtk_notebook_page_num:
+ * @notebook: a #GtkNotebook
+ * @child: a #GtkWidget
+ *
+ * Finds the index of the page which contains the given child
+ * widget.
+ *
+ * Return value: the index of the page containing @child, or
+ * -1 if @child is not in the notebook.
+ **/
gint
gtk_notebook_page_num (GtkNotebook *notebook,
GtkWidget *child)
@@ -3725,16 +3870,14 @@ gtk_notebook_page_num (GtkNotebook *notebook,
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;
+ GtkNotebookPage *page = children->data;
+
if (page->child == child)
return num;
@@ -3745,32 +3888,46 @@ gtk_notebook_page_num (GtkNotebook *notebook,
return -1;
}
+/**
+ * gtk_notebook_set_page:
+ * @notebook: a #GtkNotebook
+ * @page_num: index of the page to switch to, starting from 0.
+ * If negative, or greater than the number of pages
+ * in the notebook the last page will be used.
+ *
+ * Switches to the page number @page_num.
+ **/
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;
- }
+ list = g_list_last (notebook->children);
+
+ page_num = g_list_index (notebook->children, list);
+
if (list)
gtk_notebook_switch_page (notebook, GTK_NOTEBOOK_PAGE (list), page_num);
}
+/**
+ * gtk_notebook_next_page:
+ * @notebook: a #GtkNotebook
+ *
+ * Switches to the next page. Nothing happens if the current page is
+ * the last page.
+ **/
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);
@@ -3784,12 +3941,18 @@ gtk_notebook_next_page (GtkNotebook *notebook)
gtk_notebook_switch_page (notebook, GTK_NOTEBOOK_PAGE (list), -1);
}
+/**
+ * gtk_notebook_prev_page:
+ * @notebook: a #GtkNotebook
+ *
+ * Switches to the previous page. Nothing happens if the current page
+ * is the first page.
+ **/
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);
@@ -3814,6 +3977,15 @@ gtk_notebook_prev_page (GtkNotebook *notebook)
* gtk_notebook_set_tab_vborder
* gtk_notebook_set_scrollable
*/
+/**
+ * gtk_notebook_set_show_border:
+ * @notebook: a #GtkNotebook
+ * @show_border: %TRUE if a bevel should be drawn around the notebook.
+ *
+ * Sets whether a bevel will be drawn around the notebook pages.
+ * this is only has an effect when the tabs are not shown.
+ * See gtk_notebook_set_show_tabs().
+ **/
void
gtk_notebook_set_show_border (GtkNotebook *notebook,
gboolean show_border)
@@ -3830,6 +4002,13 @@ gtk_notebook_set_show_border (GtkNotebook *notebook,
}
}
+/**
+ * gtk_notebook_set_show_tabs:
+ * @notebook: a #GtkNotebook
+ * @show_tabs: %TRUE if the tabs should be shown.
+ *
+ * Sets whether to show the tabs for the notebook or not.
+ **/
void
gtk_notebook_set_show_tabs (GtkNotebook *notebook,
gboolean show_tabs)
@@ -3876,11 +4055,18 @@ gtk_notebook_set_show_tabs (GtkNotebook *notebook,
gtk_widget_queue_resize (GTK_WIDGET (notebook));
}
+/**
+ * gtk_notebook_set_tab_pos:
+ * @notebook:
+ * @pos:
+ *
+ * Sets the edge at which the tabs for switching pages in the
+ * notebook are drawn.
+ **/
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)
@@ -3891,11 +4077,17 @@ gtk_notebook_set_tab_pos (GtkNotebook *notebook,
}
}
+/**
+ * gtk_notebook_set_homogeneous_tabs:
+ * @notebook: a #GtkNotebook
+ * @homogeneous: %TRUE if all tabs should be the same size.
+ *
+ * Sets whether the tabs must have all the same size or not.
+ **/
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)
@@ -3905,11 +4097,21 @@ gtk_notebook_set_homogeneous_tabs (GtkNotebook *notebook,
gtk_widget_queue_resize (GTK_WIDGET (notebook));
}
+/**
+ * gtk_notebook_set_tab_border:
+ * @notebook: a #GtkNotebook
+ * @tab_border: %TRUE if there should be a border around the
+ * tab labels.
+ *
+ * Sets whether there should be a border around the tab labels
+ * in a notebook. This is equivalent to calling
+ * gtk_notebook_set_tab_hborder (@notebook, @tab_border) followed
+ * by gtk_noteobok_set_tab_vborder (@notebook, @tab_border).
+ **/
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_hborder = tab_border;
@@ -3919,11 +4121,18 @@ gtk_notebook_set_tab_border (GtkNotebook *notebook,
gtk_widget_queue_resize (GTK_WIDGET (notebook));
}
+/**
+ * gtk_notebook_set_tab_hborder:
+ * @notebook: a #GtkNotebook
+ * @tab_vborder: %TRUE if the notebook tabs should have
+ * a vertical border.
+ *
+ * Sets whether the tabs should have a vertical border.
+ **/
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)
@@ -3935,11 +4144,18 @@ gtk_notebook_set_tab_hborder (GtkNotebook *notebook,
gtk_widget_queue_resize (GTK_WIDGET (notebook));
}
+/**
+ * gtk_notebook_set_tab_vborder:
+ * @notebook: a #GtkNotebook
+ * @tab_vborder: %TRUE if the notebook tabs should have
+ * a vertical border.
+ *
+ * Sets whether the tabs should have a vertical border.
+ **/
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)
@@ -3951,11 +4167,19 @@ gtk_notebook_set_tab_vborder (GtkNotebook *notebook,
gtk_widget_queue_resize (GTK_WIDGET (notebook));
}
+/**
+ * gtk_notebook_set_scrollable:
+ * @notebook: a #GtkNotebook
+ * @scrollable: %TRUE if scroll arrows should be added
+ *
+ * Sets whether the tab label area will have arrows for scrolling if
+ * there are too many tabs to fit in the area.
+
+ **/
void
gtk_notebook_set_scrollable (GtkNotebook *notebook,
gboolean scrollable)
{
- g_return_if_fail (notebook != NULL);
g_return_if_fail (GTK_IS_NOTEBOOK (notebook));
scrollable = (scrollable != FALSE);
@@ -3979,7 +4203,7 @@ gtk_notebook_set_scrollable (GtkNotebook *notebook,
}
if (GTK_WIDGET_VISIBLE (notebook))
- gtk_widget_queue_resize (GTK_WIDGET(notebook));
+ gtk_widget_queue_resize (GTK_WIDGET (notebook));
}
}
@@ -3988,12 +4212,20 @@ gtk_notebook_set_scrollable (GtkNotebook *notebook,
* gtk_notebook_popup_enable
* gtk_notebook_popup_disable
*/
+
+
+/**
+ * gtk_notebook_popup_enable:
+ * @notebook: a #GtkNotebook
+ *
+ * Enables the popup menu: if the user clicks with the right mouse button on
+ * the bookmarks, a menu with all the pages will be popped up.
+ **/
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)
@@ -4011,10 +4243,15 @@ gtk_notebook_popup_enable (GtkNotebook *notebook)
gtk_notebook_menu_detacher);
}
+/**
+ * gtk_notebook_popup_disable:
+ * @notebook: a #GtkNotebook
+ *
+ * Disables the popup menu.
+ **/
void
gtk_notebook_popup_disable (GtkNotebook *notebook)
{
- g_return_if_fail (notebook != NULL);
g_return_if_fail (GTK_IS_NOTEBOOK (notebook));
if (!notebook->menu)
@@ -4036,18 +4273,29 @@ gtk_notebook_popup_disable (GtkNotebook *notebook)
* gtk_notebook_set_tab_label_packing
* gtk_notebook_query_tab_label_packing
*/
+
+/**
+ * gtk_notebook_get_tab_label:
+ * @notebook: a #GtkNotebook
+ * @child: the page
+ *
+ * Returns the tab label widget for the page @child. %NULL is returned
+ * if @child is not in @notebook or if no tab label has specifically
+ * been set for @child.
+ *
+ * Return value: the tab label
+ **/
GtkWidget *
gtk_notebook_get_tab_label (GtkNotebook *notebook,
GtkWidget *child)
{
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)))
+ list = CHECK_FIND_CHILD (notebook, child);
+ if (!list)
return NULL;
if (GTK_NOTEBOOK_PAGE (list)->default_tab)
@@ -4056,6 +4304,16 @@ gtk_notebook_get_tab_label (GtkNotebook *notebook,
return GTK_NOTEBOOK_PAGE (list)->tab_label;
}
+/**
+ * gtk_notebook_set_tab_label:
+ * @notebook: a #GtkNotebook
+ * @child: the page
+ * @tab_label: the tab label widget to use, or %NULL for default tab
+ * label.
+ *
+ * Changes the tab label for @child. If %NULL is specified
+ * for @tab_label, then the page will have the label 'page N'.
+ **/
void
gtk_notebook_set_tab_label (GtkNotebook *notebook,
GtkWidget *child,
@@ -4064,18 +4322,16 @@ gtk_notebook_set_tab_label (GtkNotebook *notebook,
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;
+
+ list = CHECK_FIND_CHILD (notebook, child);
+ if (!list)
+ return;
/* a NULL pointer indicates a default_tab setting, otherwise
* we need to set the associated label
*/
-
page = list->data;
if (page->tab_label)
gtk_widget_unparent (page->tab_label);
@@ -4109,6 +4365,15 @@ gtk_notebook_set_tab_label (GtkNotebook *notebook,
}
}
+/**
+ * gtk_notebook_set_tab_label_text:
+ * @notebook: a #GtkNotebook
+ * @child: the page
+ * @tab_label: the label text
+ *
+ * Creates a new label and sets it as the tab label for the page
+ * containing @child.
+ **/
void
gtk_notebook_set_tab_label_text (GtkNotebook *notebook,
GtkWidget *child,
@@ -4116,24 +4381,36 @@ gtk_notebook_set_tab_label_text (GtkNotebook *notebook,
{
GtkWidget *tab_label = NULL;
+ g_return_if_fail (GTK_IS_NOTEBOOK (notebook));
+
if (tab_text)
tab_label = gtk_label_new (tab_text);
gtk_notebook_set_tab_label (notebook, child, tab_label);
}
+/**
+ * gtk_notebook_get_menu_label:
+ * @notebook: a #GtkNotebook
+ * @child: the page
+ *
+ * Returns the menu label of the page containing @child. NULL is
+ * returned if @child is not in @notebook or NULL if it has the
+ * default menu label.
+ *
+ * Return value: the menu label
+ **/
GtkWidget*
gtk_notebook_get_menu_label (GtkNotebook *notebook,
GtkWidget *child)
{
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;
+ list = CHECK_FIND_CHILD (notebook, child);
+ if (!list)
+ return NULL;
if (GTK_NOTEBOOK_PAGE (list)->default_menu)
return NULL;
@@ -4141,6 +4418,14 @@ gtk_notebook_get_menu_label (GtkNotebook *notebook,
return GTK_NOTEBOOK_PAGE (list)->menu_label;
}
+/**
+ * gtk_notebook_set_menu_label:
+ * @notebook: a #GtkNotebook
+ * @child: the child widget
+ * @menu_label: the menu label, or NULL for default
+ *
+ * Changes the menu label for the page containing @child.
+ **/
void
gtk_notebook_set_menu_label (GtkNotebook *notebook,
GtkWidget *child,
@@ -4153,19 +4438,17 @@ gtk_notebook_set_menu_label (GtkNotebook *notebook,
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;
+ list = CHECK_FIND_CHILD (notebook, child);
+ if (!list)
+ 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);
- }
+ gtk_container_remove (GTK_CONTAINER (notebook->menu),
+ page->menu_label->parent);
+
if (!page->default_menu)
gtk_widget_unref (page->menu_label);
}
@@ -4184,6 +4467,14 @@ gtk_notebook_set_menu_label (GtkNotebook *notebook,
gtk_notebook_menu_item_create (notebook, list);
}
+/**
+ * gtk_notebook_set_menu_label_text:
+ * @notebook: a #GtkNotebook
+ * @child: the child widget
+ * @menu_text: the label text
+ *
+ * Creates a new label and sets it as the menu label of @child.
+ **/
void
gtk_notebook_set_menu_label_text (GtkNotebook *notebook,
GtkWidget *child,
@@ -4191,11 +4482,44 @@ gtk_notebook_set_menu_label_text (GtkNotebook *notebook,
{
GtkWidget *menu_label = NULL;
+ g_return_if_fail (GTK_IS_NOTEBOOK (notebook));
+
if (menu_text)
menu_label = gtk_label_new (menu_text);
gtk_notebook_set_menu_label (notebook, child, menu_label);
}
+/* Helper function called when pages are reordered
+ */
+static void
+gtk_notebook_child_reordered (GtkNotebook *notebook,
+ GtkNotebookPage *page)
+{
+ 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, g_list_find (notebook->children, page));
+ }
+
+ gtk_notebook_update_labels (notebook);
+}
+
+/**
+ * gtk_notebook_set_tab_label_packing:
+ * @notebook: a #GtkNotebook
+ * @child: the child widget
+ * @expand: whether to expand the bookmark or not
+ * @fill: whether the bookmark should fill the allocated area or not
+ * @pack_type: the position of the bookmark
+ *
+ * Sets the packing parameters for the tab label of the page
+ * containing @child. See gtk_box_pack_start() for the exact meaning
+ * of the parameters.
+ **/
void
gtk_notebook_set_tab_label_packing (GtkNotebook *notebook,
GtkWidget *child,
@@ -4210,9 +4534,9 @@ gtk_notebook_set_tab_label_packing (GtkNotebook *notebook,
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;
+ list = CHECK_FIND_CHILD (notebook, child);
+ if (!list)
+ return;
page = list->data;
if (page->pack == pack_type && page->expand == expand && page->fill == fill)
@@ -4224,26 +4548,26 @@ gtk_notebook_set_tab_label_packing (GtkNotebook *notebook,
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);
+ gtk_notebook_child_reordered (notebook, page);
}
if (!notebook->show_tabs)
return;
- gtk_notebook_pages_allocate (notebook, &(GTK_WIDGET (notebook)->allocation));
- gtk_notebook_expose_tabs (notebook);
+ gtk_notebook_pages_allocate (notebook);
}
+/**
+ * gtk_notebook_query_tab_label_packing:
+ * @notebook: a #GtkNotebook
+ * @child: the page
+ * @expand: location to store the expand value (or NULL)
+ * @fill: location to store the fill value (or NULL)
+ * @pack_type: location to store the pack_type (or NULL)
+ *
+ * Query the packing attributes for the tab label of the page
+ * containing @child.
+ **/
void
gtk_notebook_query_tab_label_packing (GtkNotebook *notebook,
GtkWidget *child,
@@ -4253,13 +4577,12 @@ gtk_notebook_query_tab_label_packing (GtkNotebook *notebook,
{
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;
+ list = CHECK_FIND_CHILD (notebook, child);
+ if (!list)
+ return;
if (expand)
*expand = GTK_NOTEBOOK_PAGE (list)->expand;
@@ -4269,75 +4592,53 @@ gtk_notebook_query_tab_label_packing (GtkNotebook *notebook,
*pack_type = GTK_NOTEBOOK_PAGE (list)->pack;
}
+/**
+ * gtk_notebook_reorder_child:
+ * @notebook: a #GtkNotebook
+ * @child: the child to move
+ * @position: the new position
+ *
+ * Reorders the page containing @child, so that it appears in position
+ * @position. Out of bounds @position will be clamped.
+ **/
void
gtk_notebook_reorder_child (GtkNotebook *notebook,
GtkWidget *child,
gint position)
{
- GList *list;
- GList *work;
- GtkNotebookPage *page = NULL;
+ GList *list, *new_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;
- }
+ list = CHECK_FIND_CHILD (notebook, child);
+ if (!list)
+ return;
- if (!list || old_pos == position)
+ old_pos = g_list_position (notebook->children, list);
+
+ if (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;
- }
+ page = list->data;
+ notebook->children = g_list_delete_link (notebook->children, list);
- if (notebook->menu)
- {
- GtkWidget *menu_item;
+ position = CLAMP (position, 0, g_list_length (notebook->children));
- g_assert(page != NULL);
+ notebook->children = g_list_insert (notebook->children, page, position);
+ new_list = g_list_nth (notebook->children, position);
- 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);
- }
+ /* Fix up GList references in GtkNotebook structure */
+ if (notebook->first_tab == list)
+ notebook->first_tab = new_list;
+ if (notebook->focus_tab == list)
+ notebook->focus_tab = new_list;
- gtk_notebook_update_labels (notebook);
+ /* Move around the menu items if necesary */
+ gtk_notebook_child_reordered (notebook, page);
if (notebook->show_tabs)
- {
- gtk_notebook_pages_allocate (notebook,
- &(GTK_WIDGET (notebook)->allocation));
- gtk_notebook_expose_tabs (notebook);
- }
+ gtk_notebook_pages_allocate (notebook);
}
diff --git a/gtk/gtknotebook.h b/gtk/gtknotebook.h
index ffa575c508..8e110b6784 100644
--- a/gtk/gtknotebook.h
+++ b/gtk/gtknotebook.h
@@ -45,9 +45,6 @@ extern "C" {
#define GTK_NOTEBOOK_GET_CLASS(obj) (GTK_CHECK_GET_CLASS ((obj), GTK_TYPE_NOTEBOOK, GtkNotebookClass))
-#define GTK_NOTEBOOK_PAGE(_glist_) ((GtkNotebookPage *)((GList *)(_glist_))->data)
-
-
typedef struct _GtkNotebook GtkNotebook;
typedef struct _GtkNotebookClass GtkNotebookClass;
typedef struct _GtkNotebookPage GtkNotebookPage;
@@ -58,7 +55,7 @@ struct _GtkNotebook
GtkNotebookPage *cur_page;
GList *children;
- GList *first_tab;
+ GList *first_tab; /* The first tab visible (for scrolling notebooks) */
GList *focus_tab;
GtkWidget *menu;
@@ -91,22 +88,6 @@ struct _GtkNotebookClass
guint page_num);
};
-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 *
***********************************************************/
@@ -143,15 +124,15 @@ void gtk_notebook_remove_page (GtkNotebook *notebook,
* query, set current NoteebookPage *
***********************************************************/
-gint gtk_notebook_get_current_page (GtkNotebook *notebook);
-GtkWidget* gtk_notebook_get_nth_page (GtkNotebook *notebook,
- gint page_num);
-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);
+gint gtk_notebook_get_current_page (GtkNotebook *notebook);
+GtkWidget* gtk_notebook_get_nth_page (GtkNotebook *notebook,
+ gint page_num);
+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 *
diff --git a/gtk/gtktreeview.c b/gtk/gtktreeview.c
index 1262e94808..01371b801d 100644
--- a/gtk/gtktreeview.c
+++ b/gtk/gtktreeview.c
@@ -1418,10 +1418,7 @@ gtk_tree_view_header_focus (GtkTreeView *tree_view,
* I wonder if focussable is a real word...
*/
if (last_column == NULL)
- {
- gtk_container_set_focus_child (container, NULL);
- return FALSE;
- }
+ return FALSE;
/* First thing we want to handle is entering and leaving the headers.
*/
@@ -1431,7 +1428,6 @@ gtk_tree_view_header_focus (GtkTreeView *tree_view,
if (!focus_child)
{
focus_child = GTK_TREE_VIEW_COLUMN (last_column->data)->button;
- gtk_container_set_focus_child (container, focus_child);
gtk_widget_grab_focus (focus_child);
goto cleanup;
}
@@ -1446,7 +1442,6 @@ gtk_tree_view_header_focus (GtkTreeView *tree_view,
if (!focus_child)
{
focus_child = GTK_TREE_VIEW_COLUMN (first_column->data)->button;
- gtk_container_set_focus_child (container, focus_child);
gtk_widget_grab_focus (focus_child);
goto cleanup;
}
@@ -1461,7 +1456,6 @@ gtk_tree_view_header_focus (GtkTreeView *tree_view,
if (!focus_child)
{
focus_child = GTK_TREE_VIEW_COLUMN (last_column->data)->button;
- gtk_container_set_focus_child (container, focus_child);
gtk_widget_grab_focus (focus_child);
goto cleanup;
}
@@ -1476,7 +1470,6 @@ gtk_tree_view_header_focus (GtkTreeView *tree_view,
if (!focus_child)
{
focus_child = GTK_TREE_VIEW_COLUMN (first_column->data)->button;
- gtk_container_set_focus_child (container, focus_child);
gtk_widget_grab_focus (focus_child);
goto cleanup;
}
@@ -1491,7 +1484,6 @@ gtk_tree_view_header_focus (GtkTreeView *tree_view,
if (!focus_child)
{
focus_child = GTK_TREE_VIEW_COLUMN (first_column->data)->button;
- gtk_container_set_focus_child (container, focus_child);
gtk_widget_grab_focus (focus_child);
}
else
@@ -1504,7 +1496,6 @@ gtk_tree_view_header_focus (GtkTreeView *tree_view,
if (!focus_child)
{
focus_child = GTK_TREE_VIEW_COLUMN (first_column->data)->button;
- gtk_container_set_focus_child (container, focus_child);
gtk_widget_grab_focus (focus_child);
}
else
@@ -1550,7 +1541,6 @@ gtk_tree_view_header_focus (GtkTreeView *tree_view,
GTK_WIDGET_CAN_FOCUS (column->button))
{
focus_child = column->button;
- gtk_container_set_focus_child (container, column->button);
gtk_widget_grab_focus (column->button);
break;
}
@@ -1578,10 +1568,6 @@ gtk_tree_view_header_focus (GtkTreeView *tree_view,
focus_child->allocation.x);
}
}
- else
- {
- gtk_container_set_focus_child (container, NULL);
- }
return (focus_child != NULL);
}
@@ -1619,16 +1605,11 @@ gtk_tree_view_focus (GtkContainer *container,
case GTK_DIR_TAB_BACKWARD:
return (gtk_tree_view_header_focus (tree_view, direction));
case GTK_DIR_UP:
- gtk_container_set_focus_child (container, NULL);
return FALSE;
case GTK_DIR_TAB_FORWARD:
case GTK_DIR_RIGHT:
case GTK_DIR_DOWN:
- if (direction == GTK_DIR_DOWN)
- {
- gtk_container_set_focus_child (container, NULL);
- }
- else
+ if (direction != GTK_DIR_DOWN)
{
if (gtk_tree_view_header_focus (tree_view, direction))
return TRUE;
diff --git a/gtk/gtkwidget.c b/gtk/gtkwidget.c
index 001b1c8192..315b256d40 100644
--- a/gtk/gtkwidget.c
+++ b/gtk/gtkwidget.c
@@ -2857,6 +2857,32 @@ gtk_widget_real_grab_focus (GtkWidget *focus_widget)
}
/**
+ * gtk_widget_is_focus:
+ * @widget: a #GtkWidget
+ *
+ * Determines if the widget is the focus widget within its
+ * toplevel. (This does not mean that the HAS_FOCUS flag is
+ * necessarily set; HAS_FOCUS will only be set if the
+ * toplevel widget additionally has the global input focus.)
+ *
+ * Return value: %TRUE if the widget is the focus widget.
+ **/
+gboolean
+gtk_widget_is_focus (GtkWidget *widget)
+{
+ GtkWidget *toplevel;
+
+ g_return_if_fail (GTK_IS_WIDGET (widget));
+
+ toplevel = gtk_widget_get_toplevel (widget);
+
+ if (GTK_IS_WINDOW (toplevel))
+ return widget == GTK_WINDOW (toplevel)->focus_widget;
+ else
+ return FALSE;
+}
+
+/**
* gtk_widget_grab_default:
* @widget: a #GtkWidget
*
diff --git a/gtk/gtkwidget.h b/gtk/gtkwidget.h
index 0d86f3fe75..70bfd6b964 100644
--- a/gtk/gtkwidget.h
+++ b/gtk/gtkwidget.h
@@ -493,6 +493,7 @@ gboolean gtk_widget_intersect (GtkWidget *widget,
GdkRectangle *area,
GdkRectangle *intersection);
+gboolean gtk_widget_is_focus (GtkWidget *widget);
void gtk_widget_grab_focus (GtkWidget *widget);
void gtk_widget_grab_default (GtkWidget *widget);
diff --git a/gtk/gtkwindow.c b/gtk/gtkwindow.c
index 7860ef9379..bea9bb646a 100644
--- a/gtk/gtkwindow.c
+++ b/gtk/gtkwindow.c
@@ -126,6 +126,8 @@ static gint gtk_window_focus_out_event (GtkWidget *widget,
static gint gtk_window_client_event (GtkWidget *widget,
GdkEventClient *event);
static void gtk_window_check_resize (GtkContainer *container);
+static gint gtk_window_focus (GtkContainer *container,
+ GtkDirectionType direction);
static void gtk_window_real_set_focus (GtkWindow *window,
GtkWidget *focus);
@@ -261,6 +263,7 @@ gtk_window_class_init (GtkWindowClass *klass)
widget_class->expose_event = gtk_window_expose;
container_class->check_resize = gtk_window_check_resize;
+ container_class->focus = gtk_window_focus;
klass->set_focus = gtk_window_real_set_focus;
}
@@ -1579,6 +1582,60 @@ gtk_window_check_resize (GtkContainer *container)
gtk_window_move_resize (window);
}
+static gboolean
+gtk_window_focus (GtkContainer *container,
+ GtkDirectionType direction)
+{
+ GtkBin *bin = GTK_BIN (container);
+ GtkWindow *window = GTK_WINDOW (container);
+ GtkWidget *old_focus_child = container->focus_child;
+ GtkWidget *parent;
+
+ /* We need a special implementation here to deal properly with wrapping
+ * around in the tab chain without the danger of going into an
+ * infinite loop.
+ */
+ if (old_focus_child)
+ {
+ if (GTK_IS_CONTAINER (old_focus_child) &&
+ GTK_WIDGET_DRAWABLE (old_focus_child) &&
+ GTK_WIDGET_IS_SENSITIVE (old_focus_child) &&
+ gtk_container_focus (GTK_CONTAINER (old_focus_child), direction))
+ return TRUE;
+ }
+
+ if (window->focus_widget)
+ {
+ /* Wrapped off the end, clear the focus setting for the toplpevel */
+ parent = window->focus_widget->parent;
+ while (parent)
+ {
+ gtk_container_set_focus_child (GTK_CONTAINER (parent), NULL);
+ parent = GTK_WIDGET (parent)->parent;
+ }
+
+ gtk_window_set_focus (GTK_WINDOW (container), NULL);
+ }
+
+ /* Now try to focus the first widget in the window */
+ if (GTK_WIDGET_DRAWABLE (bin->child) &&
+ GTK_WIDGET_IS_SENSITIVE (bin->child))
+ {
+ if (GTK_IS_CONTAINER (bin->child))
+ {
+ if (gtk_container_focus (GTK_CONTAINER (bin->child), direction))
+ return TRUE;
+ }
+ else if (GTK_WIDGET_CAN_FOCUS (bin->child))
+ {
+ gtk_widget_grab_focus (bin->child);
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
static void
gtk_window_real_set_focus (GtkWindow *window,
GtkWidget *focus)
diff --git a/gtk/testgtk.c b/gtk/testgtk.c
index 555ac978b1..e6420d3653 100644
--- a/gtk/testgtk.c
+++ b/gtk/testgtk.c
@@ -6471,31 +6471,34 @@ GdkBitmap *book_closed_mask;
GtkWidget *sample_notebook;
static void
-page_switch (GtkWidget *widget, GtkNotebookPage *page, gint page_num)
+set_page_pixmaps (GtkNotebook *notebook, gint page_num,
+ GdkPixmap *pixmap, GdkPixmap *mask)
{
- GtkNotebookPage *oldpage;
+ GtkWidget *page_widget;
GtkWidget *pixwid;
- oldpage = GTK_NOTEBOOK (widget)->cur_page;
+ page_widget = gtk_notebook_get_nth_page (notebook, page_num);
+
+ pixwid = gtk_object_get_data (GTK_OBJECT (page_widget), "tab_pixmap");
+ gtk_pixmap_set (GTK_PIXMAP (pixwid), pixmap, mask);
+
+ pixwid = gtk_object_get_data (GTK_OBJECT (page_widget), "menu_pixmap");
+ gtk_pixmap_set (GTK_PIXMAP (pixwid), pixmap, mask);
+}
- if (page == oldpage)
+static void
+page_switch (GtkWidget *widget, GtkNotebookPage *page, gint page_num)
+{
+ GtkNotebook *notebook = GTK_NOTEBOOK (widget);
+ gint old_page_num = gtk_notebook_get_current_page (notebook);
+
+ if (page_num == old_page_num)
return;
- 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;
- gtk_pixmap_set (GTK_PIXMAP (pixwid), book_open, book_open_mask);
-
- if (oldpage)
- {
- 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;
- gtk_pixmap_set (GTK_PIXMAP (pixwid), book_closed, book_closed_mask);
- }
+
+ set_page_pixmaps (notebook, page_num, book_open, book_open_mask);
+
+ if (old_page_num != -1)
+ set_page_pixmaps (notebook, old_page_num, book_closed, book_closed_mask);
}
static void
@@ -6589,19 +6592,25 @@ create_pages (GtkNotebook *notebook, gint start, gint end)
label_box = gtk_hbox_new (FALSE, 0);
pixwid = gtk_pixmap_new (book_closed, book_closed_mask);
+ gtk_object_set_data (GTK_OBJECT (child), "tab_pixmap", pixwid);
+
gtk_box_pack_start (GTK_BOX (label_box), pixwid, FALSE, TRUE, 0);
gtk_misc_set_padding (GTK_MISC (pixwid), 3, 1);
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_object_set_data (GTK_OBJECT (child), "menu_pixmap", pixwid);
+
gtk_box_pack_start (GTK_BOX (menu_box), pixwid, FALSE, TRUE, 0);
gtk_misc_set_padding (GTK_MISC (pixwid), 3, 1);
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);
}
}
@@ -6628,6 +6637,7 @@ standard_notebook (GtkButton *button,
gint i;
gtk_notebook_set_show_tabs (notebook, TRUE);
+ gtk_notebook_set_show_border (notebook, TRUE);
gtk_notebook_set_scrollable (notebook, FALSE);
if (g_list_length (notebook->children) == 15)
for (i = 0; i < 10; i++)
@@ -6641,6 +6651,20 @@ notabs_notebook (GtkButton *button,
gint i;
gtk_notebook_set_show_tabs (notebook, FALSE);
+ gtk_notebook_set_show_border (notebook, TRUE);
+ if (g_list_length (notebook->children) == 15)
+ for (i = 0; i < 10; i++)
+ gtk_notebook_remove_page (notebook, 5);
+}
+
+static void
+borderless_notebook (GtkButton *button,
+ GtkNotebook *notebook)
+{
+ gint i;
+
+ gtk_notebook_set_show_tabs (notebook, FALSE);
+ gtk_notebook_set_show_border (notebook, FALSE);
if (g_list_length (notebook->children) == 15)
for (i = 0; i < 10; i++)
gtk_notebook_remove_page (notebook, 5);
@@ -6651,6 +6675,7 @@ scrollable_notebook (GtkButton *button,
GtkNotebook *notebook)
{
gtk_notebook_set_show_tabs (notebook, TRUE);
+ gtk_notebook_set_show_border (notebook, TRUE);
gtk_notebook_set_scrollable (notebook, TRUE);
if (g_list_length (notebook->children) == 5)
create_pages (notebook, 6, 15);
@@ -6689,7 +6714,8 @@ create_notebook (void)
{
{ "Standard", standard_notebook },
{ "No tabs", notabs_notebook },
- { "Scrollable", scrollable_notebook }
+ { "Borderless", borderless_notebook },
+ { "Scrollable", scrollable_notebook },
};
if (!window)
@@ -6753,7 +6779,7 @@ create_notebook (void)
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);
+ omenu = build_option_menu (items, G_N_ELEMENTS (items), 0, sample_notebook);
gtk_box_pack_start (GTK_BOX (box2), omenu, FALSE, TRUE, 0);
button = gtk_button_new_with_label ("Show all Pages");
diff --git a/tests/testgtk.c b/tests/testgtk.c
index 555ac978b1..e6420d3653 100644
--- a/tests/testgtk.c
+++ b/tests/testgtk.c
@@ -6471,31 +6471,34 @@ GdkBitmap *book_closed_mask;
GtkWidget *sample_notebook;
static void
-page_switch (GtkWidget *widget, GtkNotebookPage *page, gint page_num)
+set_page_pixmaps (GtkNotebook *notebook, gint page_num,
+ GdkPixmap *pixmap, GdkPixmap *mask)
{
- GtkNotebookPage *oldpage;
+ GtkWidget *page_widget;
GtkWidget *pixwid;
- oldpage = GTK_NOTEBOOK (widget)->cur_page;
+ page_widget = gtk_notebook_get_nth_page (notebook, page_num);
+
+ pixwid = gtk_object_get_data (GTK_OBJECT (page_widget), "tab_pixmap");
+ gtk_pixmap_set (GTK_PIXMAP (pixwid), pixmap, mask);
+
+ pixwid = gtk_object_get_data (GTK_OBJECT (page_widget), "menu_pixmap");
+ gtk_pixmap_set (GTK_PIXMAP (pixwid), pixmap, mask);
+}
- if (page == oldpage)
+static void
+page_switch (GtkWidget *widget, GtkNotebookPage *page, gint page_num)
+{
+ GtkNotebook *notebook = GTK_NOTEBOOK (widget);
+ gint old_page_num = gtk_notebook_get_current_page (notebook);
+
+ if (page_num == old_page_num)
return;
- 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;
- gtk_pixmap_set (GTK_PIXMAP (pixwid), book_open, book_open_mask);
-
- if (oldpage)
- {
- 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;
- gtk_pixmap_set (GTK_PIXMAP (pixwid), book_closed, book_closed_mask);
- }
+
+ set_page_pixmaps (notebook, page_num, book_open, book_open_mask);
+
+ if (old_page_num != -1)
+ set_page_pixmaps (notebook, old_page_num, book_closed, book_closed_mask);
}
static void
@@ -6589,19 +6592,25 @@ create_pages (GtkNotebook *notebook, gint start, gint end)
label_box = gtk_hbox_new (FALSE, 0);
pixwid = gtk_pixmap_new (book_closed, book_closed_mask);
+ gtk_object_set_data (GTK_OBJECT (child), "tab_pixmap", pixwid);
+
gtk_box_pack_start (GTK_BOX (label_box), pixwid, FALSE, TRUE, 0);
gtk_misc_set_padding (GTK_MISC (pixwid), 3, 1);
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_object_set_data (GTK_OBJECT (child), "menu_pixmap", pixwid);
+
gtk_box_pack_start (GTK_BOX (menu_box), pixwid, FALSE, TRUE, 0);
gtk_misc_set_padding (GTK_MISC (pixwid), 3, 1);
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);
}
}
@@ -6628,6 +6637,7 @@ standard_notebook (GtkButton *button,
gint i;
gtk_notebook_set_show_tabs (notebook, TRUE);
+ gtk_notebook_set_show_border (notebook, TRUE);
gtk_notebook_set_scrollable (notebook, FALSE);
if (g_list_length (notebook->children) == 15)
for (i = 0; i < 10; i++)
@@ -6641,6 +6651,20 @@ notabs_notebook (GtkButton *button,
gint i;
gtk_notebook_set_show_tabs (notebook, FALSE);
+ gtk_notebook_set_show_border (notebook, TRUE);
+ if (g_list_length (notebook->children) == 15)
+ for (i = 0; i < 10; i++)
+ gtk_notebook_remove_page (notebook, 5);
+}
+
+static void
+borderless_notebook (GtkButton *button,
+ GtkNotebook *notebook)
+{
+ gint i;
+
+ gtk_notebook_set_show_tabs (notebook, FALSE);
+ gtk_notebook_set_show_border (notebook, FALSE);
if (g_list_length (notebook->children) == 15)
for (i = 0; i < 10; i++)
gtk_notebook_remove_page (notebook, 5);
@@ -6651,6 +6675,7 @@ scrollable_notebook (GtkButton *button,
GtkNotebook *notebook)
{
gtk_notebook_set_show_tabs (notebook, TRUE);
+ gtk_notebook_set_show_border (notebook, TRUE);
gtk_notebook_set_scrollable (notebook, TRUE);
if (g_list_length (notebook->children) == 5)
create_pages (notebook, 6, 15);
@@ -6689,7 +6714,8 @@ create_notebook (void)
{
{ "Standard", standard_notebook },
{ "No tabs", notabs_notebook },
- { "Scrollable", scrollable_notebook }
+ { "Borderless", borderless_notebook },
+ { "Scrollable", scrollable_notebook },
};
if (!window)
@@ -6753,7 +6779,7 @@ create_notebook (void)
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);
+ omenu = build_option_menu (items, G_N_ELEMENTS (items), 0, sample_notebook);
gtk_box_pack_start (GTK_BOX (box2), omenu, FALSE, TRUE, 0);
button = gtk_button_new_with_label ("Show all Pages");