]> git.saurik.com Git - wxWidgets.git/blobdiff - src/gtk1/window.cpp
Add generic dialogs in non wxUniversal builds. Regenerated makefiles.
[wxWidgets.git] / src / gtk1 / window.cpp
index d468e1b8e80de38db5848f694654bf343f29e5f3..13d9f19cd60ba214548cb5e449b6850888ea7fde 100644 (file)
@@ -267,10 +267,6 @@ extern bool g_mainThreadLocked;
 // debug
 //-----------------------------------------------------------------------------
 
-#ifndef __WXGTK20__
-#define DISABLE_STYLE_IF_BROKEN_THEME 0
-#endif
-
 #ifdef __WXDEBUG__
 
 #if wxUSE_THREADS
@@ -1347,39 +1343,36 @@ static gint gtk_window_key_release_callback( GtkWidget *widget,
 // mouse event processing helpers
 // ----------------------------------------------------------------------------
 
-// init wxMouseEvent with the info from gdk_event
-//
-// NB: this has to be a macro as gdk_event type is different for different
-//     events we're used with
-#define InitMouseEvent(/* wxWindowGTK * */ win,                               \
-                       /* wxMouseEvent& */ event,                             \
-                       /* GdkEventXXX * */ gdk_event)                         \
-{                                                                             \
-    event.SetTimestamp( gdk_event->time );                                    \
-    event.m_shiftDown = (gdk_event->state & GDK_SHIFT_MASK);                  \
-    event.m_controlDown = (gdk_event->state & GDK_CONTROL_MASK);              \
-    event.m_altDown = (gdk_event->state & GDK_MOD1_MASK);                     \
-    event.m_metaDown = (gdk_event->state & GDK_MOD2_MASK);                    \
-    event.m_leftDown = (gdk_event->state & GDK_BUTTON1_MASK);                 \
-    event.m_middleDown = (gdk_event->state & GDK_BUTTON2_MASK);               \
-    event.m_rightDown = (gdk_event->state & GDK_BUTTON3_MASK);                \
-    if (event.GetEventType()==wxEVT_MOUSEWHEEL)                               \
-    {                                                                         \
-       event.m_linesPerAction = 3;                                            \
-       if (((GdkEventButton*)gdk_event)->button == 4)                         \
-           event.m_wheelRotation = 120;                                       \
-       else if (((GdkEventButton*)gdk_event)->button == 5)                    \
-           event.m_wheelRotation = -120;                                      \
-    }                                                                         \
-                                                                              \
-    wxPoint pt = win->GetClientAreaOrigin();                                  \
-    event.m_x = (wxCoord)gdk_event->x - pt.x;                                 \
-    event.m_y = (wxCoord)gdk_event->y - pt.y;                                 \
-                                                                              \
-    event.SetEventObject( win );                                              \
-    event.SetId( win->GetId() );                                              \
-    event.SetTimestamp( gdk_event->time );                                    \
-}                                                                             \
+// init wxMouseEvent with the info from GdkEventXXX struct
+template<typename T> void InitMouseEvent(wxWindowGTK *win,
+                                         wxMouseEvent& event,
+                                         T *gdk_event)
+{
+    event.SetTimestamp( gdk_event->time );
+    event.m_shiftDown = (gdk_event->state & GDK_SHIFT_MASK);
+    event.m_controlDown = (gdk_event->state & GDK_CONTROL_MASK);
+    event.m_altDown = (gdk_event->state & GDK_MOD1_MASK);
+    event.m_metaDown = (gdk_event->state & GDK_MOD2_MASK);
+    event.m_leftDown = (gdk_event->state & GDK_BUTTON1_MASK);
+    event.m_middleDown = (gdk_event->state & GDK_BUTTON2_MASK);
+    event.m_rightDown = (gdk_event->state & GDK_BUTTON3_MASK);
+    if (event.GetEventType() == wxEVT_MOUSEWHEEL)
+    {
+       event.m_linesPerAction = 3;
+       if (((GdkEventButton*)gdk_event)->button == 4)
+           event.m_wheelRotation = 120;
+       else if (((GdkEventButton*)gdk_event)->button == 5)
+           event.m_wheelRotation = -120;
+    }
+
+    wxPoint pt = win->GetClientAreaOrigin();
+    event.m_x = (wxCoord)gdk_event->x - pt.x;
+    event.m_y = (wxCoord)gdk_event->y - pt.y;
+
+    event.SetEventObject( win );
+    event.SetId( win->GetId() );
+    event.SetTimestamp( gdk_event->time );
+}
 
 static void AdjustEventButtonState(wxMouseEvent& event)
 {
@@ -2569,7 +2562,6 @@ void wxWindowGTK::Init()
     m_oldClientHeight = 0;
 
     m_resizing = FALSE;
-    m_widgetStyle = (GtkStyle*) NULL;
 
     m_insertCallback = (wxInsertChildFunction) NULL;
 
@@ -2763,16 +2755,6 @@ wxWindowGTK::~wxWindowGTK()
         gdk_ic_attr_destroy (m_icattr);
 #endif
 
-    if (m_widgetStyle)
-    {
-#if DISABLE_STYLE_IF_BROKEN_THEME
-        // don't delete if it's a pixmap theme style
-        if (!m_widgetStyle->engine_data)
-            gtk_style_unref( m_widgetStyle );
-#endif
-        m_widgetStyle = (GtkStyle*) NULL;
-    }
-
     if (m_wxwindow)
     {
         gtk_widget_destroy( m_wxwindow );
@@ -3822,11 +3804,9 @@ void wxWindowGTK::GtkSendPaintEvents()
     // Clip to paint region in wxClientDC
     m_clipPaintRegion = TRUE;
 
-#ifndef __WXGTK20__
     // widget to draw on
     GtkPizza *pizza = GTK_PIZZA (m_wxwindow);
 
-    // later for GTK 2.0, too.
     if (GetThemeEnabled())
     {
         // find ancestor from which to steal background
@@ -3847,7 +3827,7 @@ void wxWindowGTK::GtkSendPaintEvents()
 
             gtk_paint_flat_box( parent->m_widget->style,
                         pizza->bin_window,
-                        GTK_STATE_NORMAL,
+                        (GtkStateType)GTK_WIDGET_STATE(m_wxwindow),
                         GTK_SHADOW_NONE,
                         &rect,
                         parent->m_widget,
@@ -3858,7 +3838,6 @@ void wxWindowGTK::GtkSendPaintEvents()
         }
     }
     else
-#endif
 
 #ifdef __WXGTK20__
     {
@@ -4103,131 +4082,69 @@ PangoContext *wxWindowGTK::GtkGetPangoX11Context()
     return m_x11Context;
 }
 #endif
-
-GtkStyle *wxWindowGTK::GetWidgetStyle()
-{
-    if (m_widgetStyle)
-    {
-        GtkStyle *remake = gtk_style_copy( m_widgetStyle );
-
-        // FIXME: no more klass in 2.0
-#ifndef __WXGTK20__
-        remake->klass = m_widgetStyle->klass;
-#endif
-
-        gtk_style_unref( m_widgetStyle );
-        m_widgetStyle = remake;
-    }
-    else
-    {
-        GtkStyle *def = gtk_rc_get_style( m_widget );
-
-        if (!def)
-            def = gtk_widget_get_default_style();
-
-        m_widgetStyle = gtk_style_copy( def );
-
-        // FIXME: no more klass in 2.0
-#ifndef __WXGTK20__
-        m_widgetStyle->klass = def->klass;
-#endif
-    }
-
-    return m_widgetStyle;
-}
-
-void wxWindowGTK::SetWidgetStyle()
+GtkRcStyle *wxWindowGTK::CreateWidgetStyle()
 {
-#if DISABLE_STYLE_IF_BROKEN_THEME
-    if (m_widget->style->engine_data)
+    // do we need to apply any changes at all?
+    if ( !m_hasFont && !m_hasFgCol &&
+         (!m_hasBgCol || !m_backgroundColour.Ok()) )
     {
-        static bool s_warningPrinted = FALSE;
-        if (!s_warningPrinted)
-        {
-            printf( "wxWidgets warning: Widget styles disabled due to buggy GTK theme.\n" );
-            s_warningPrinted = TRUE;
-        }
-        m_widgetStyle = m_widget->style;
-        return;
+        return NULL;
     }
-#endif
 
-    GtkStyle *style = GetWidgetStyle();
+    GtkRcStyle *style = gtk_rc_style_new();
 
     if ( m_hasFont )
     {
 #ifdef __WXGTK20__
-        pango_font_description_free( style->font_desc );
-        style->font_desc = pango_font_description_copy( m_font.GetNativeFontInfo()->description );
+        style->font_desc = 
+            pango_font_description_copy( m_font.GetNativeFontInfo()->description );
 #else
-        gdk_font_unref( style->font );
-        style->font = gdk_font_ref( m_font.GetInternalFont( 1.0 ) );
+        wxString xfontname = m_font.GetNativeFontInfo()->GetXFontName();
+        style->fontset_name = g_strdup(xfontname.c_str());
 #endif
     }
 
     if ( m_hasFgCol )
     {
         m_foregroundColour.CalcPixel( gtk_widget_get_colormap( m_widget ) );
-        if (m_foregroundColour != wxSystemSettings::GetColour(wxSYS_COLOUR_BTNTEXT))
-        {
-            style->fg[GTK_STATE_NORMAL] = *m_foregroundColour.GetColor();
-            style->fg[GTK_STATE_PRELIGHT] = *m_foregroundColour.GetColor();
-            style->fg[GTK_STATE_ACTIVE] = *m_foregroundColour.GetColor();
-        }
-        else
-        {
-            // Try to restore the gtk default style.  This is still a little
-            // oversimplified for what is probably really needed here for controls
-            // other than buttons, but is better than not being able to (re)set a
-            // control's foreground colour to *wxBLACK -- RL
-            GtkStyle *def = gtk_rc_get_style( m_widget );
-
-            if (!def)
-                def = gtk_widget_get_default_style();
-
-            style->fg[GTK_STATE_NORMAL] = def->fg[GTK_STATE_NORMAL];
-            style->fg[GTK_STATE_PRELIGHT] = def->fg[GTK_STATE_PRELIGHT];
-            style->fg[GTK_STATE_ACTIVE] = def->fg[GTK_STATE_ACTIVE];
-        }
+        
+        style->fg[GTK_STATE_NORMAL] = *m_foregroundColour.GetColor();
+        style->color_flags[GTK_STATE_NORMAL] = GTK_RC_FG;
+        
+        style->fg[GTK_STATE_PRELIGHT] = *m_foregroundColour.GetColor();
+        style->color_flags[GTK_STATE_PRELIGHT] = GTK_RC_FG;
+        
+        style->fg[GTK_STATE_ACTIVE] = *m_foregroundColour.GetColor();
+        style->color_flags[GTK_STATE_ACTIVE] = GTK_RC_FG;
     }
 
     if ( m_hasBgCol && m_backgroundColour.Ok() )
     {
         m_backgroundColour.CalcPixel( gtk_widget_get_colormap( m_widget ) );
-        if (m_backgroundColour != wxSystemSettings::GetColour(wxSYS_COLOUR_BTNFACE))
-        {
-            style->bg[GTK_STATE_NORMAL] = *m_backgroundColour.GetColor();
-            style->base[GTK_STATE_NORMAL] = *m_backgroundColour.GetColor();
-            style->bg[GTK_STATE_PRELIGHT] = *m_backgroundColour.GetColor();
-            style->base[GTK_STATE_PRELIGHT] = *m_backgroundColour.GetColor();
-            style->bg[GTK_STATE_ACTIVE] = *m_backgroundColour.GetColor();
-            style->base[GTK_STATE_ACTIVE] = *m_backgroundColour.GetColor();
-            style->bg[GTK_STATE_INSENSITIVE] = *m_backgroundColour.GetColor();
-            style->base[GTK_STATE_INSENSITIVE] = *m_backgroundColour.GetColor();
-        }
-        else
-        {
-            // Try to restore the gtk default style.  This is still a little
-            // oversimplified for what is probably really needed here for controls
-            // other than buttons, but is better than not being able to (re)set a
-            // control's background colour to default grey and means resetting a
-            // button to wxSYS_COLOUR_BTNFACE will restore its usual highlighting
-            // behavior -- RL
-            GtkStyle *def = gtk_rc_get_style( m_widget );
-
-            if (!def)
-                def = gtk_widget_get_default_style();
-
-            style->bg[GTK_STATE_NORMAL] = def->bg[GTK_STATE_NORMAL];
-            style->base[GTK_STATE_NORMAL] = def->base[GTK_STATE_NORMAL];
-            style->bg[GTK_STATE_PRELIGHT] = def->bg[GTK_STATE_PRELIGHT];
-            style->base[GTK_STATE_PRELIGHT] = def->base[GTK_STATE_PRELIGHT];
-            style->bg[GTK_STATE_ACTIVE] = def->bg[GTK_STATE_ACTIVE];
-            style->base[GTK_STATE_ACTIVE] = def->base[GTK_STATE_ACTIVE];
-            style->bg[GTK_STATE_INSENSITIVE] = def->bg[GTK_STATE_INSENSITIVE];
-            style->base[GTK_STATE_INSENSITIVE] = def->base[GTK_STATE_INSENSITIVE];
-        }
+        
+        style->bg[GTK_STATE_NORMAL] = *m_backgroundColour.GetColor();
+        style->base[GTK_STATE_NORMAL] = *m_backgroundColour.GetColor();
+        style->color_flags[GTK_STATE_NORMAL] = (GtkRcFlags)
+            (style->color_flags[GTK_STATE_NORMAL] | GTK_RC_BG | GTK_RC_BASE);
+        
+        style->bg[GTK_STATE_PRELIGHT] = *m_backgroundColour.GetColor();
+        style->base[GTK_STATE_PRELIGHT] = *m_backgroundColour.GetColor();
+        style->color_flags[GTK_STATE_PRELIGHT] = (GtkRcFlags)
+            (style->color_flags[GTK_STATE_PRELIGHT] | GTK_RC_BG | GTK_RC_BASE);
+        
+        style->bg[GTK_STATE_ACTIVE] = *m_backgroundColour.GetColor();
+        style->base[GTK_STATE_ACTIVE] = *m_backgroundColour.GetColor();
+        style->color_flags[GTK_STATE_ACTIVE] = (GtkRcFlags)
+            (style->color_flags[GTK_STATE_ACTIVE] | GTK_RC_BG | GTK_RC_BASE);
+        
+        style->bg[GTK_STATE_INSENSITIVE] = *m_backgroundColour.GetColor();
+        style->base[GTK_STATE_INSENSITIVE] = *m_backgroundColour.GetColor();
+        style->color_flags[GTK_STATE_INSENSITIVE] = (GtkRcFlags)
+            (style->color_flags[GTK_STATE_INSENSITIVE] | GTK_RC_BG | GTK_RC_BASE);
     }
+    
+    return style;
 }
 
 void wxWindowGTK::ApplyWidgetStyle()
@@ -4285,30 +4202,44 @@ extern "C" void wxPopupMenuPositionCallback( GtkMenu *menu,
 
 bool wxWindowGTK::DoPopupMenu( wxMenu *menu, int x, int y )
 {
-    wxCHECK_MSG( m_widget != NULL, FALSE, wxT("invalid window") );
+    wxCHECK_MSG( m_widget != NULL, false, wxT("invalid window") );
 
-    wxCHECK_MSG( menu != NULL, FALSE, wxT("invalid popup-menu") );
+    wxCHECK_MSG( menu != NULL, false, wxT("invalid popup-menu") );
 
     SetInvokingWindow( menu, this );
 
     menu->UpdateUI();
 
-    wxPoint pos(ClientToScreen(wxPoint(x, y)));
-
-    bool is_waiting = TRUE;
+    bool is_waiting = true;
 
     gtk_signal_connect( GTK_OBJECT(menu->m_menu),
                         "hide",
                         GTK_SIGNAL_FUNC(gtk_pop_hide_callback),
                         (gpointer)&is_waiting );
 
+    wxPoint pos;
+    gpointer userdata;
+    GtkMenuPositionFunc posfunc;
+    if ( x == -1 && y == -1 )
+    {
+        // use GTK's default positioning algorithm
+        userdata = NULL;
+        posfunc = NULL;
+    }
+    else
+    {
+        pos = ClientToScreen(wxPoint(x, y));
+        userdata = &pos;
+        posfunc = wxPopupMenuPositionCallback;
+    }
+
     gtk_menu_popup(
                   GTK_MENU(menu->m_menu),
                   (GtkWidget *) NULL,           // parent menu shell
                   (GtkWidget *) NULL,           // parent menu item
-                  wxPopupMenuPositionCallback,  // function to position it
-                  &pos,                         // client data
-                  0 /* FIXME! */,               // button used to activate it
+                  posfunc,                      // function to position it
+                  userdata,                     // client data
+                  0,                            // button used to activate it
 #ifdef __WXGTK20__
                   gtk_get_current_event_time()
 #else
@@ -4321,7 +4252,7 @@ bool wxWindowGTK::DoPopupMenu( wxMenu *menu, int x, int y )
         gtk_main_iteration();
     }
 
-    return TRUE;
+    return true;
 }
 
 #endif // wxUSE_MENUS_NATIVE