]> git.saurik.com Git - wxWidgets.git/blobdiff - src/gtk/notebook.cpp
Return NULL from wxWindow::GetCapture() when the capture is being lost.
[wxWidgets.git] / src / gtk / notebook.cpp
index 60fe23a01fb76af158681a3910072fe2e37acdce..71ebdcf3a9290a92e3332e3c983728d34811c9eb 100644 (file)
@@ -2,7 +2,6 @@
 // Name:        src/gtk/notebook.cpp
 // Purpose:
 // Author:      Robert Roebling
 // Name:        src/gtk/notebook.cpp
 // Purpose:
 // Author:      Robert Roebling
-// Id:          $Id$
 // Copyright:   (c) 1998 Robert Roebling, Vadim Zeitlin
 // Licence:     wxWindows licence
 /////////////////////////////////////////////////////////////////////////////
 // Copyright:   (c) 1998 Robert Roebling, Vadim Zeitlin
 // Licence:     wxWindows licence
 /////////////////////////////////////////////////////////////////////////////
@@ -25,7 +24,9 @@
 #include "wx/imaglist.h"
 #include "wx/fontutil.h"
 
 #include "wx/imaglist.h"
 #include "wx/fontutil.h"
 
+#include <gtk/gtk.h>
 #include "wx/gtk/private.h"
 #include "wx/gtk/private.h"
+#include "wx/gtk/private/gtk2-compat.h"
 
 //-----------------------------------------------------------------------------
 // wxGtkNotebookPage
 
 //-----------------------------------------------------------------------------
 // wxGtkNotebookPage
@@ -61,10 +62,11 @@ static void event_after(GtkNotebook*, GdkEvent*, wxNotebook*);
 
 extern "C" {
 static void
 
 extern "C" {
 static void
-switch_page_after(GtkWidget* widget, GtkNotebookPage*, guint, wxNotebook* win)
+switch_page_after(GtkNotebook* widget, GtkNotebookPage*, guint, wxNotebook* win)
 {
     g_signal_handlers_block_by_func(widget, (void*)switch_page_after, win);
 {
     g_signal_handlers_block_by_func(widget, (void*)switch_page_after, win);
-    win->SendPageChangedEvent(win->m_oldSelection);
+
+    win->GTKOnPageChanged();
 }
 }
 
 }
 }
 
@@ -104,7 +106,7 @@ static void event_after(GtkNotebook* widget, GdkEvent*, wxNotebook* win)
 // InsertChild callback for wxNotebook
 //-----------------------------------------------------------------------------
 
 // InsertChild callback for wxNotebook
 //-----------------------------------------------------------------------------
 
-static void wxInsertChildInNotebook(wxWindow* parent, wxWindow* child)
+void wxNotebook::AddChildGTK(wxWindowGTK* child)
 {
     // Hack Alert! (Part I): This sets the notebook as the parent of the child
     // widget, and takes care of some details such as updating the state and
 {
     // Hack Alert! (Part I): This sets the notebook as the parent of the child
     // widget, and takes care of some details such as updating the state and
@@ -114,7 +116,7 @@ static void wxInsertChildInNotebook(wxWindow* parent, wxWindow* child)
     // incorrect sizes since the widget's style context is not fully known.
     // See bug #901694 for details
     // (http://sourceforge.net/tracker/?func=detail&aid=901694&group_id=9863&atid=109863)
     // incorrect sizes since the widget's style context is not fully known.
     // See bug #901694 for details
     // (http://sourceforge.net/tracker/?func=detail&aid=901694&group_id=9863&atid=109863)
-    gtk_widget_set_parent(child->m_widget, parent->m_widget);
+    gtk_widget_set_parent(child->m_widget, m_widget);
 
     // NOTE: This should be considered a temporary workaround until we can
     // work out the details and implement delaying the setting of the initial
 
     // NOTE: This should be considered a temporary workaround until we can
     // work out the details and implement delaying the setting of the initial
@@ -125,8 +127,6 @@ static void wxInsertChildInNotebook(wxWindow* parent, wxWindow* child)
 // wxNotebook
 //-----------------------------------------------------------------------------
 
 // wxNotebook
 //-----------------------------------------------------------------------------
 
-IMPLEMENT_DYNAMIC_CLASS(wxNotebook,wxBookCtrlBase)
-
 BEGIN_EVENT_TABLE(wxNotebook, wxBookCtrlBase)
     EVT_NAVIGATION_KEY(wxNotebook::OnNavigationKey)
 END_EVENT_TABLE()
 BEGIN_EVENT_TABLE(wxNotebook, wxBookCtrlBase)
     EVT_NAVIGATION_KEY(wxNotebook::OnNavigationKey)
 END_EVENT_TABLE()
@@ -160,8 +160,6 @@ bool wxNotebook::Create(wxWindow *parent, wxWindowID id,
                         const wxPoint& pos, const wxSize& size,
                         long style, const wxString& name )
 {
                         const wxPoint& pos, const wxSize& size,
                         long style, const wxString& name )
 {
-    m_insertCallback = wxInsertChildInNotebook;
-
     if ( (style & wxBK_ALIGN_MASK) == wxBK_DEFAULT )
         style |= wxBK_TOP;
 
     if ( (style & wxBK_ALIGN_MASK) == wxBK_DEFAULT )
         style |= wxBK_TOP;
 
@@ -204,7 +202,7 @@ bool wxNotebook::Create(wxWindow *parent, wxWindowID id,
 
 int wxNotebook::GetSelection() const
 {
 
 int wxNotebook::GetSelection() const
 {
-    wxCHECK_MSG( m_widget != NULL, -1, wxT("invalid notebook") );
+    wxCHECK_MSG( m_widget != NULL, wxNOT_FOUND, wxT("invalid notebook") );
 
     return gtk_notebook_get_current_page( GTK_NOTEBOOK(m_widget) );
 }
 
     return gtk_notebook_get_current_page( GTK_NOTEBOOK(m_widget) );
 }
@@ -219,7 +217,7 @@ wxString wxNotebook::GetPageText( size_t page ) const
 
 int wxNotebook::GetPageImage( size_t page ) const
 {
 
 int wxNotebook::GetPageImage( size_t page ) const
 {
-    wxCHECK_MSG(page < GetPageCount(), -1, "invalid notebook index");
+    wxCHECK_MSG(page < GetPageCount(), wxNOT_FOUND, "invalid notebook index");
 
     return GetNotebookPage(page)->m_imageIndex;
 }
 
     return GetNotebookPage(page)->m_imageIndex;
 }
@@ -231,7 +229,7 @@ wxGtkNotebookPage* wxNotebook::GetNotebookPage( int page ) const
 
 int wxNotebook::DoSetSelection( size_t page, int flags )
 {
 
 int wxNotebook::DoSetSelection( size_t page, int flags )
 {
-    wxCHECK_MSG(page < GetPageCount(), -1, "invalid notebook index");
+    wxCHECK_MSG(page < GetPageCount(), wxNOT_FOUND, "invalid notebook index");
 
     int selOld = GetSelection();
 
 
     int selOld = GetSelection();
 
@@ -247,6 +245,8 @@ int wxNotebook::DoSetSelection( size_t page, int flags )
         g_signal_handlers_unblock_by_func(m_widget, (void*)switch_page, this);
     }
 
         g_signal_handlers_unblock_by_func(m_widget, (void*)switch_page, this);
     }
 
+    m_selection = page;
+
     wxNotebookPage *client = GetPage(page);
     if ( client )
         client->SetFocus();
     wxNotebookPage *client = GetPage(page);
     if ( client )
         client->SetFocus();
@@ -254,6 +254,13 @@ int wxNotebook::DoSetSelection( size_t page, int flags )
     return selOld;
 }
 
     return selOld;
 }
 
+void wxNotebook::GTKOnPageChanged()
+{
+    m_selection = gtk_notebook_get_current_page(GTK_NOTEBOOK(m_widget));
+
+    SendPageChangedEvent(m_oldSelection);
+}
+
 bool wxNotebook::SetPageText( size_t page, const wxString &text )
 {
     wxCHECK_MSG(page < GetPageCount(), false, "invalid notebook index");
 bool wxNotebook::SetPageText( size_t page, const wxString &text )
 {
     wxCHECK_MSG(page < GetPageCount(), false, "invalid notebook index");
@@ -271,8 +278,8 @@ bool wxNotebook::SetPageImage( size_t page, int image )
     wxGtkNotebookPage* pageData = GetNotebookPage(page);
     if (image >= 0)
     {
     wxGtkNotebookPage* pageData = GetNotebookPage(page);
     if (image >= 0)
     {
-        wxCHECK_MSG(m_imageList, false, "invalid notebook imagelist");
-        const wxBitmap* bitmap = m_imageList->GetBitmapPtr(image);
+        wxCHECK_MSG(HasImageList(), false, "invalid notebook imagelist");
+        const wxBitmap* bitmap = GetImageList()->GetBitmapPtr(image);
         if (bitmap == NULL)
             return false;
         if (pageData->m_image)
         if (bitmap == NULL)
             return false;
         if (pageData->m_image)
@@ -298,9 +305,34 @@ bool wxNotebook::SetPageImage( size_t page, int image )
     return true;
 }
 
     return true;
 }
 
-void wxNotebook::SetPageSize( const wxSize &WXUNUSED(size) )
+wxSize wxNotebook::CalcSizeFromPage(const wxSize& sizePage) const
 {
 {
-    wxFAIL_MSG( wxT("wxNotebook::SetPageSize not implemented") );
+    // Compute the max size of the tab labels.
+    wxSize sizeTabMax;
+    const size_t pageCount = GetPageCount();
+    for ( size_t n = 0; n < pageCount; n++ )
+    {
+        GtkRequisition req;
+        gtk_widget_get_preferred_size(GetNotebookPage(n)->m_box, NULL, &req);
+        sizeTabMax.IncTo(wxSize(req.width, req.height));
+    }
+
+    // Unfortunately this doesn't account for the real tab size and I don't
+    // know how to find it, e.g. where do the margins below come from.
+    const int PAGE_MARGIN = 3;
+    const int TAB_MARGIN = 4;
+
+    sizeTabMax.IncBy(3*TAB_MARGIN);
+
+    wxSize sizeFull(sizePage);
+    if ( IsVertical() )
+        sizeFull.y += sizeTabMax.y;
+    else
+        sizeFull.x += sizeTabMax.x;
+
+    sizeFull.IncBy(2*PAGE_MARGIN);
+
+    return sizeFull;
 }
 
 void wxNotebook::SetPadding( const wxSize &padding )
 }
 
 void wxNotebook::SetPadding( const wxSize &padding )
@@ -346,8 +378,6 @@ wxNotebookPage *wxNotebook::DoRemovePage( size_t page )
     if ( !client )
         return NULL;
 
     if ( !client )
         return NULL;
 
-    gtk_widget_unrealize( client->m_widget );
-
     // we don't need to unparent the client->m_widget; GTK+ will do
     // that for us (and will throw a warning if we do it!)
     gtk_notebook_remove_page( GTK_NOTEBOOK(m_widget), page );
     // we don't need to unparent the client->m_widget; GTK+ will do
     // that for us (and will throw a warning if we do it!)
     gtk_notebook_remove_page( GTK_NOTEBOOK(m_widget), page );
@@ -359,7 +389,7 @@ wxNotebookPage *wxNotebook::DoRemovePage( size_t page )
     wxGtkNotebookPage* p = GetNotebookPage(page);
     m_pagesData.DeleteObject(p);
     delete p;
     wxGtkNotebookPage* p = GetNotebookPage(page);
     m_pagesData.DeleteObject(p);
     delete p;
-    
+
     return client;
 }
 
     return client;
 }
 
@@ -375,9 +405,9 @@ bool wxNotebook::InsertPage( size_t position,
                wxT("Can't add a page whose parent is not the notebook!") );
 
     wxCHECK_MSG( position <= GetPageCount(), false,
                wxT("Can't add a page whose parent is not the notebook!") );
 
     wxCHECK_MSG( position <= GetPageCount(), false,
-                 _T("invalid page index in wxNotebookPage::InsertPage()") );
+                 wxT("invalid page index in wxNotebookPage::InsertPage()") );
 
 
-    // Hack Alert! (Part II): See above in wxInsertChildInNotebook callback
+    // Hack Alert! (Part II): See above in wxNotebook::AddChildGTK
     // why this has to be done.
     gtk_widget_unparent(win->m_widget);
 
     // why this has to be done.
     gtk_widget_unparent(win->m_widget);
 
@@ -398,21 +428,23 @@ bool wxNotebook::InsertPage( size_t position,
     // first page.
     pageData->m_imageIndex = imageId;
 
     // first page.
     pageData->m_imageIndex = imageId;
 
-    pageData->m_box = gtk_hbox_new(false, 1);
+    pageData->m_box = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 1);
     gtk_container_set_border_width(GTK_CONTAINER(pageData->m_box), 2);
 
     pageData->m_image = NULL;
     if (imageId != -1)
     {
     gtk_container_set_border_width(GTK_CONTAINER(pageData->m_box), 2);
 
     pageData->m_image = NULL;
     if (imageId != -1)
     {
-        if (m_imageList)
+        if (HasImageList())
         {
         {
-            const wxBitmap* bitmap = m_imageList->GetBitmapPtr(imageId);
+            const wxBitmap* bitmap = GetImageList()->GetBitmapPtr(imageId);
             pageData->m_image = gtk_image_new_from_pixbuf(bitmap->GetPixbuf());
             gtk_box_pack_start(GTK_BOX(pageData->m_box),
                 pageData->m_image, false, false, m_padding);
         }
         else
             pageData->m_image = gtk_image_new_from_pixbuf(bitmap->GetPixbuf());
             gtk_box_pack_start(GTK_BOX(pageData->m_box),
                 pageData->m_image, false, false, m_padding);
         }
         else
+        {
             wxFAIL_MSG("invalid notebook imagelist");
             wxFAIL_MSG("invalid notebook imagelist");
+        }
     }
 
     /* set the label text */
     }
 
     /* set the label text */
@@ -424,12 +456,16 @@ bool wxNotebook::InsertPage( size_t position,
     gtk_notebook_insert_page(notebook, win->m_widget, pageData->m_box, position);
 
     /* apply current style */
     gtk_notebook_insert_page(notebook, win->m_widget, pageData->m_box, position);
 
     /* apply current style */
-    GtkRcStyle *style = CreateWidgetStyle();
+#ifdef __WXGTK3__
+    GTKApplyStyle(pageData->m_label, NULL);
+#else
+    GtkRcStyle *style = GTKCreateWidgetStyle();
     if ( style )
     {
         gtk_widget_modify_style(pageData->m_label, style);
     if ( style )
     {
         gtk_widget_modify_style(pageData->m_label, style);
-        gtk_rc_style_unref(style);
+        g_object_unref(style);
     }
     }
+#endif
 
     if (select && GetPageCount() > 1)
     {
 
     if (select && GetPageCount() > 1)
     {
@@ -447,24 +483,30 @@ static bool
 IsPointInsideWidget(const wxPoint& pt, GtkWidget *w,
                     gint x, gint y, gint border = 0)
 {
 IsPointInsideWidget(const wxPoint& pt, GtkWidget *w,
                     gint x, gint y, gint border = 0)
 {
+    GtkAllocation a;
+    gtk_widget_get_allocation(w, &a);
     return
     return
-        (pt.x >= w->allocation.x - x - border) &&
-        (pt.x <= w->allocation.x - x + border + w->allocation.width) &&
-        (pt.y >= w->allocation.y - y - border) &&
-        (pt.y <= w->allocation.y - y + border + w->allocation.height);
+        (pt.x >= a.x - x - border) &&
+        (pt.x <= a.x - x + border + a.width) &&
+        (pt.y >= a.y - y - border) &&
+        (pt.y <= a.y - y + border + a.height);
 }
 
 int wxNotebook::HitTest(const wxPoint& pt, long *flags) const
 {
 }
 
 int wxNotebook::HitTest(const wxPoint& pt, long *flags) const
 {
-    const gint x = m_widget->allocation.x;
-    const gint y = m_widget->allocation.y;
+    GtkAllocation a;
+    gtk_widget_get_allocation(m_widget, &a);
+    const int x = a.x;
+    const int y = a.y;
 
     const size_t count = GetPageCount();
     size_t i = 0;
 
 
     const size_t count = GetPageCount();
     size_t i = 0;
 
+#ifndef __WXGTK3__
     GtkNotebook * notebook = GTK_NOTEBOOK(m_widget);
     if (gtk_notebook_get_scrollable(notebook))
         i = g_list_position( notebook->children, notebook->first_tab );
     GtkNotebook * notebook = GTK_NOTEBOOK(m_widget);
     if (gtk_notebook_get_scrollable(notebook))
         i = g_list_position( notebook->children, notebook->first_tab );
+#endif
 
     for ( ; i < count; i++ )
     {
 
     for ( ; i < count; i++ )
     {
@@ -543,15 +585,19 @@ bool wxNotebook::DoPhase( int WXUNUSED(nPhase) )
 
 void wxNotebook::DoApplyWidgetStyle(GtkRcStyle *style)
 {
 
 void wxNotebook::DoApplyWidgetStyle(GtkRcStyle *style)
 {
-    gtk_widget_modify_style(m_widget, style);
+    GTKApplyStyle(m_widget, style);
     for (size_t i = GetPageCount(); i--;)
     for (size_t i = GetPageCount(); i--;)
-        gtk_widget_modify_style(GetNotebookPage(i)->m_label, style);
+        GTKApplyStyle(GetNotebookPage(i)->m_label, style);
 }
 
 GdkWindow *wxNotebook::GTKGetWindow(wxArrayGdkWindows& windows) const
 {
 }
 
 GdkWindow *wxNotebook::GTKGetWindow(wxArrayGdkWindows& windows) const
 {
-    windows.push_back(m_widget->window);
+    windows.push_back(gtk_widget_get_window(m_widget));
+#ifdef __WXGTK3__
+    // no access to internal GdkWindows
+#else
     windows.push_back(GTK_NOTEBOOK(m_widget)->event_window);
     windows.push_back(GTK_NOTEBOOK(m_widget)->event_window);
+#endif
 
     return NULL;
 }
 
     return NULL;
 }
@@ -560,7 +606,7 @@ GdkWindow *wxNotebook::GTKGetWindow(wxArrayGdkWindows& windows) const
 wxVisualAttributes
 wxNotebook::GetClassDefaultAttributes(wxWindowVariant WXUNUSED(variant))
 {
 wxVisualAttributes
 wxNotebook::GetClassDefaultAttributes(wxWindowVariant WXUNUSED(variant))
 {
-    return GetDefaultAttributesFromGTKWidget(gtk_notebook_new);
+    return GetDefaultAttributesFromGTKWidget(gtk_notebook_new());
 }
 
 #endif
 }
 
 #endif