#include "wx/window.h"
#ifndef WX_PRECOMP
- #include "wx/intl.h"
#include "wx/log.h"
#include "wx/app.h"
- #include "wx/utils.h"
#include "wx/frame.h"
#include "wx/dcclient.h"
#include "wx/menu.h"
- #include "wx/dialog.h"
#include "wx/settings.h"
#include "wx/msgdlg.h"
#include "wx/textctrl.h"
+ #include "wx/radiobut.h"
#include "wx/toolbar.h"
#include "wx/combobox.h"
#include "wx/layout.h"
- #include "wx/statusbr.h"
#include "wx/math.h"
- #include "wx/module.h"
#endif
-#if wxUSE_DRAG_AND_DROP
- #include "wx/dnd.h"
-#endif
-
-#if wxUSE_TOOLTIPS
- #include "wx/tooltip.h"
-#endif
-
-#if wxUSE_CARET
- #include "wx/caret.h"
-#endif // wxUSE_CARET
-
+#include "wx/dnd.h"
+#include "wx/tooltip.h"
+#include "wx/caret.h"
#include "wx/fontutil.h"
#ifdef __WXDEBUG__
// FIXME: Due to a hack we use GtkCombo in here, which is deprecated since gtk2.3.0
#include <gtk/gtkversion.h>
#if defined(GTK_DISABLE_DEPRECATED) && GTK_CHECK_VERSION(2,3,0)
-#undef GTK_DISABLE_DEPRECATED
+ #undef GTK_DISABLE_DEPRECATED
+ #include <gtk/gtkcombo.h>
+ #define GTK_DISABLE_DEPRECATED
#endif
#include "wx/gtk/private.h"
-#include <gdk/gdkprivate.h>
+#include "wx/gtk/win_gtk.h"
#include <gdk/gdkkeysyms.h>
#include <gdk/gdkx.h>
-#include <gtk/gtk.h>
-#include <gtk/gtkprivate.h>
-
-#include "wx/gtk/win_gtk.h"
-
-#include <pango/pangox.h>
-
-#ifdef HAVE_XIM
- #undef HAVE_XIM
-#endif
-
//-----------------------------------------------------------------------------
// documentation on internals
//-----------------------------------------------------------------------------
// yet, defer setting the focus to idle time.
wxWindowGTK *g_delayedFocus = (wxWindowGTK*) NULL;
+// global variables because GTK+ DnD want to have the
+// mouse event that caused it
+GdkEvent *g_lastMouseEvent = (GdkEvent*) NULL;
+int g_lastButtonNumber = 0;
+
extern bool g_mainThreadLocked;
//-----------------------------------------------------------------------------
int x = dx;
int y = dy;
-
+
int dw = 0;
int dh = 0;
if (win->m_hasScrolling)
{
GetScrollbarWidth(widget, dw, dh);
-
+
if (win->GetLayoutDirection() == wxLayout_RightToLeft)
{
// This is actually wrong for old GTK+ version
GtkRequisition entry_req;
entry_req.width = 2;
entry_req.height = 2;
+ (* GTK_WIDGET_CLASS( GTK_OBJECT_GET_CLASS(gcombo->entry) )->size_request )
+ (gcombo->entry, &entry_req );
+
+ GtkRequisition button_req;
+ button_req.width = 2;
+ button_req.height = 2;
(* GTK_WIDGET_CLASS( GTK_OBJECT_GET_CLASS(gcombo->button) )->size_request )
- (gcombo->button, &entry_req );
+ (gcombo->button, &button_req );
- requisition->width = w - entry_req.width;
+ requisition->width = w - button_req.width;
requisition->height = entry_req.height;
}
}
// time anymore.
GtkPizza *pizza = GTK_PIZZA( widget );
- if (gdk_event->window != pizza->bin_window) return FALSE;
+ if (gdk_event->window != pizza->bin_window)
+ {
+ // block expose events on GTK_WIDGET(pizza)->window,
+ // all drawing is done on pizza->bin_window
+ return true;
+ }
#if 0
wxPoint pt = win->GetClientAreaOrigin();
event.m_x = (wxCoord)gdk_event->x - pt.x;
event.m_y = (wxCoord)gdk_event->y - pt.y;
-
+
if ((win->m_wxwindow) && (win->GetLayoutDirection() == wxLayout_RightToLeft))
{
// origin in the upper right corner
{
wxCOMMON_CALLBACK_PROLOGUE(gdk_event, win);
+ g_lastButtonNumber = gdk_event->button;
+
if (win->m_wxwindow && (g_focusWindow != win) && win->AcceptsFocus())
{
gtk_widget_grab_focus( win->m_wxwindow );
// GDK sends surplus button down events
// before a double click event. We
// need to filter these out.
- if (gdk_event->type == GDK_BUTTON_PRESS)
+ if ((gdk_event->type == GDK_BUTTON_PRESS) && (win->m_wxwindow))
{
GdkEvent *peek_event = gdk_event_peek();
if (peek_event)
return FALSE;
}
+ g_lastMouseEvent = (GdkEvent*) gdk_event;
+
wxMouseEvent event( event_type );
InitMouseEvent( win, event, gdk_event );
event.SetEventObject( win );
event.SetId( win->GetId() );
- if (win->GTKProcessEvent( event ))
- {
+ bool ret = win->GTKProcessEvent( event );
+ g_lastMouseEvent = NULL;
+ if ( ret )
return TRUE;
- }
if (event_type == wxEVT_RIGHT_DOWN)
{
{
wxCOMMON_CALLBACK_PROLOGUE(gdk_event, win);
+ g_lastButtonNumber = 0;
+
wxEventType event_type = wxEVT_NULL;
switch (gdk_event->button)
return FALSE;
}
+ g_lastMouseEvent = (GdkEvent*) gdk_event;
+
wxMouseEvent event( event_type );
InitMouseEvent( win, event, gdk_event );
gdk_event->y = y;
}
+ g_lastMouseEvent = (GdkEvent*) gdk_event;
+
wxMouseEvent event( wxEVT_MOTION );
InitMouseEvent(win, event, gdk_event);
}
}
- return win->GTKProcessEvent(event);
+ bool ret = win->GTKProcessEvent(event);
+
+ g_lastMouseEvent = NULL;
+
+ return ret;
}
//-----------------------------------------------------------------------------
wxLogTrace(TRACE_FOCUS,
_T("%s: focus in"), win->GetName().c_str());
-#ifdef HAVE_XIM
- if (win->m_ic)
- gdk_im_begin(win->m_ic, win->m_wxwindow->window);
-#endif
-
#if wxUSE_CARET
// caret needs to be informed about focus change
wxCaret *caret = win->GetCaret();
g_focusWindow = (wxWindowGTK *)NULL;
-#ifdef HAVE_XIM
- if (win->m_ic)
- gdk_im_end();
-#endif
-
#if wxUSE_CARET
// caret needs to be informed about focus change
wxCaret *caret = win->GetCaret();
wxWindowGTK::ScrollDir dir = win->ScrollDirFromRange(range);
// generate the corresponding wx event
- const int orient = win->OrientFromScrollDir(dir);
+ const int orient = wxWindow::OrientFromScrollDir(dir);
wxScrollWinEvent event(eventType, win->GetScrollPos(orient), orient);
event.SetEventObject(win);
{
g_signal_handlers_block_by_func(range, (void*)gtk_scrollbar_event_after, win);
- const int orient = win->OrientFromScrollDir(
+ const int orient = wxWindow::OrientFromScrollDir(
win->ScrollDirFromRange(range));
wxScrollWinEvent event(wxEVT_SCROLLWIN_THUMBRELEASE, win->GetScrollPos(orient), orient);
event.SetEventObject(win);
alloc->width,
alloc->height );
#endif
-
- GTK_PIZZA(win->m_wxwindow)->m_width = win->GetClientSize().x;
win->m_oldClientWidth = client_width;
win->m_oldClientHeight = client_height;
}
}
-
-#ifdef HAVE_XIM
- #define WXUNUSED_UNLESS_XIM(param) param
-#else
- #define WXUNUSED_UNLESS_XIM(param) WXUNUSED(param)
-#endif
-
-/* Resize XIM window */
-static
-void gtk_wxwindow_size_callback( GtkWidget* WXUNUSED_UNLESS_XIM(widget),
- GtkAllocation* WXUNUSED_UNLESS_XIM(alloc),
- wxWindowGTK* WXUNUSED_UNLESS_XIM(win) )
-{
- if (g_isIdle)
- wxapp_install_idle_handler();
-
-#ifdef HAVE_XIM
- if (!win->m_ic)
- return;
-
- if (gdk_ic_get_style (win->m_ic) & GDK_IM_PREEDIT_POSITION)
- {
- gint width, height;
-
- gdk_drawable_get_size (widget->window, &width, &height);
- win->m_icattr->preedit_area.width = width;
- win->m_icattr->preedit_area.height = height;
- gdk_ic_set_attr (win->m_ic, win->m_icattr, GDK_IC_PREEDIT_AREA);
- }
-#endif // HAVE_XIM
-}
-
-//-----------------------------------------------------------------------------
-// "realize" from m_wxwindow
-//-----------------------------------------------------------------------------
-
-/* Initialize XIM support */
-
-static void
-gtk_wxwindow_realized_callback( GtkWidget * WXUNUSED_UNLESS_XIM(widget),
- wxWindowGTK * WXUNUSED_UNLESS_XIM(win) )
-{
- if (g_isIdle)
- wxapp_install_idle_handler();
-
-#ifdef HAVE_XIM
- if (win->m_ic) return;
- if (!widget) return;
- if (!gdk_im_ready()) return;
-
- win->m_icattr = gdk_ic_attr_new();
- if (!win->m_icattr) return;
-
- gint width, height;
- GdkEventMask mask;
- GdkColormap *colormap;
- GdkICAttr *attr = win->m_icattr;
- unsigned attrmask = GDK_IC_ALL_REQ;
- GdkIMStyle style;
- GdkIMStyle supported_style = (GdkIMStyle)
- (GDK_IM_PREEDIT_NONE |
- GDK_IM_PREEDIT_NOTHING |
- GDK_IM_PREEDIT_POSITION |
- GDK_IM_STATUS_NONE |
- GDK_IM_STATUS_NOTHING);
-
- if (widget->style && widget->style->font->type != GDK_FONT_FONTSET)
- supported_style = (GdkIMStyle)(supported_style & ~GDK_IM_PREEDIT_POSITION);
-
- attr->style = style = gdk_im_decide_style (supported_style);
- attr->client_window = widget->window;
-
- if ((colormap = gtk_widget_get_colormap (widget)) !=
- gtk_widget_get_default_colormap ())
- {
- attrmask |= GDK_IC_PREEDIT_COLORMAP;
- attr->preedit_colormap = colormap;
- }
-
- attrmask |= GDK_IC_PREEDIT_FOREGROUND;
- attrmask |= GDK_IC_PREEDIT_BACKGROUND;
- attr->preedit_foreground = widget->style->fg[GTK_STATE_NORMAL];
- attr->preedit_background = widget->style->base[GTK_STATE_NORMAL];
-
- switch (style & GDK_IM_PREEDIT_MASK)
- {
- case GDK_IM_PREEDIT_POSITION:
- if (widget->style && widget->style->font->type != GDK_FONT_FONTSET)
- {
- g_warning ("over-the-spot style requires fontset");
- break;
- }
-
- gdk_drawable_get_size (widget->window, &width, &height);
-
- attrmask |= GDK_IC_PREEDIT_POSITION_REQ;
- attr->spot_location.x = 0;
- attr->spot_location.y = height;
- attr->preedit_area.x = 0;
- attr->preedit_area.y = 0;
- attr->preedit_area.width = width;
- attr->preedit_area.height = height;
- attr->preedit_fontset = widget->style->font;
-
- break;
- }
-
- win->m_ic = gdk_ic_new (attr, (GdkICAttributesType)attrmask);
-
- if (win->m_ic == NULL)
- g_warning ("Can't create input context.");
- else
- {
- mask = gdk_window_get_events (widget->window);
- mask = (GdkEventMask)(mask | gdk_ic_get_events (win->m_ic));
- gdk_window_set_events (widget->window, mask);
-
- if (GTK_WIDGET_HAS_FOCUS(widget))
- gdk_im_begin (win->m_ic, widget->window);
- }
-#endif // HAVE_XIM
-}
-
} // extern "C"
// ----------------------------------------------------------------------------
GtkScrolledWindowClass *scroll_class = GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT_GET_CLASS(m_widget) );
scroll_class->scrollbar_spacing = 0;
- gtk_scrolled_window_set_policy( scrolledWindow, GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC );
+ if (HasFlag(wxALWAYS_SHOW_SB))
+ {
+ gtk_scrolled_window_set_policy( scrolledWindow, GTK_POLICY_ALWAYS, GTK_POLICY_ALWAYS );
+
+ scrolledWindow->hscrollbar_visible = TRUE;
+ scrolledWindow->vscrollbar_visible = TRUE;
+ }
+ else
+ {
+ gtk_scrolled_window_set_policy( scrolledWindow, GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC );
+ }
m_scrollBar[ScrollDir_Horz] = GTK_RANGE(scrolledWindow->hscrollbar);
m_scrollBar[ScrollDir_Vert] = GTK_RANGE(scrolledWindow->vscrollbar);
m_wxwindow = gtk_pizza_new();
#ifndef __WXUNIVERSAL__
- GtkPizza *pizza = GTK_PIZZA(m_wxwindow);
-
- if (HasFlag(wxRAISED_BORDER))
- {
- gtk_pizza_set_shadow_type( pizza, GTK_MYSHADOW_OUT );
- }
- else if (HasFlag(wxSUNKEN_BORDER))
- {
- gtk_pizza_set_shadow_type( pizza, GTK_MYSHADOW_IN );
- }
- else if (HasFlag(wxSIMPLE_BORDER))
- {
- gtk_pizza_set_shadow_type( pizza, GTK_MYSHADOW_THIN );
- }
- else
- {
- gtk_pizza_set_shadow_type( pizza, GTK_MYSHADOW_NONE );
- }
+ if (HasFlag(wxSIMPLE_BORDER))
+ gtk_container_set_border_width((GtkContainer*)m_wxwindow, 1);
+ else if (HasFlag(wxRAISED_BORDER) || HasFlag(wxSUNKEN_BORDER))
+ gtk_container_set_border_width((GtkContainer*)m_wxwindow, 2);
#endif // __WXUNIVERSAL__
gtk_container_add( GTK_CONTAINER(m_widget), m_wxwindow );
if (m_widget)
Show( false );
-#ifdef HAVE_XIM
- if (m_ic)
- gdk_ic_destroy (m_ic);
- if (m_icattr)
- gdk_ic_attr_destroy (m_icattr);
-#endif
-
// delete before the widgets to avoid a crash on solaris
delete m_imData;
// Catch native resize events
g_signal_connect (m_wxwindow, "size_allocate",
G_CALLBACK (gtk_window_size_callback), this);
-
- // Initialize XIM support
- g_signal_connect (m_wxwindow, "realize",
- G_CALLBACK (gtk_wxwindow_realized_callback), this);
-
- // And resize XIM window
- g_signal_connect (m_wxwindow, "size_allocate",
- G_CALLBACK (gtk_wxwindow_size_callback), this);
}
if (GTK_IS_COMBO(m_widget))
{
// inform the parent to perform the move
gtk_pizza_set_size( GTK_PIZZA(m_parent->m_wxwindow), m_widget, x, y, width, height );
-
+
}
void wxWindowGTK::DoSetSize( int x, int y, int width, int height, int sizeFlags )
GetScrollbarWidth(m_widget, dw, dh);
}
-#ifndef __WXUNIVERSAL__
- if (HasFlag(wxRAISED_BORDER) || HasFlag(wxSUNKEN_BORDER))
- {
- // shadow border size is 2
- dw += 2 * 2;
- dh += 2 * 2;
- }
- if (HasFlag(wxSIMPLE_BORDER))
- {
- // simple border size is 1
- dw += 1 * 2;
- dh += 1 * 2;
- }
-#endif // __WXUNIVERSAL__
+ const int border = GTK_CONTAINER(m_wxwindow)->border_width;
+ dw += 2 * border;
+ dh += 2 * border;
width += dw;
height += dh;
if (m_hasScrolling)
GetScrollbarWidth(m_widget, dw, dh);
-#ifndef __WXUNIVERSAL__
- if (HasFlag(wxRAISED_BORDER) || HasFlag(wxSUNKEN_BORDER))
- {
- // shadow border size is 2
- dw += 2 * 2;
- dh += 2 * 2;
- }
- if (HasFlag(wxSIMPLE_BORDER))
- {
- // simple border size is 1
- dw += 1 * 2;
- dh += 1 * 2;
- }
-#endif // __WXUNIVERSAL__
+ const int border = GTK_CONTAINER(m_wxwindow)->border_width;
+ dw += 2 * border;
+ dh += 2 * border;
w -= dw;
h -= dh;
if (GetParent())
GetParent()->ScreenToClient(&org_x, &org_y);
- ((wxWindowGTK*) this)->m_x = org_x;
- ((wxWindowGTK*) this)->m_y = org_y;
- }
+ wx_const_cast(wxWindowGTK*, this)->m_x = org_x;
+ wx_const_cast(wxWindowGTK*, this)->m_y = org_y;
+ }
}
if (x) (*x) = m_x - dx;
{
if (GetLayoutDirection() == wxLayout_RightToLeft)
*x = (GetClientSize().x - *x) + org_x;
- else
+ else
*x += org_x;
}
-
+
if (y) *y += org_y;
}
{
if (GetLayoutDirection() == wxLayout_RightToLeft)
*x = (GetClientSize().x - *x) - org_x;
- else
+ else
*x -= org_x;
}
if (y) *y -= org_y;
{
if (GTK_IS_CONTAINER(m_widget))
{
+ if (IsKindOf(CLASSINFO(wxRadioButton)))
+ {
+ gtk_widget_grab_focus (m_widget);
+ return;
+ }
+
gtk_widget_child_focus( m_widget, GTK_DIR_TAB_FORWARD );
}
else
return;
GTKSetLayout(m_widget, dir);
-
+
if (m_wxwindow)
GTKSetLayout(m_wxwindow, dir);
}
{
p = NULL;
}
-
+
gdk_window_invalidate_rect( GTK_PIZZA(m_wxwindow)->bin_window, p, TRUE );
}
}
bool wxWindowGTK::DoIsExposed( int x, int y, int w, int h ) const
{
-#if 0
if (GetLayoutDirection() == wxLayout_RightToLeft)
return m_updateRegion.Contains(x-w, y, w, h) != wxOutRegion;
else
-#endif
return m_updateRegion.Contains(x, y, w, h) != wxOutRegion;
}
{
// Transform m_updateRegion under RTL
m_updateRegion.Clear();
-
+
gint width;
gdk_window_get_geometry( GTK_PIZZA(m_wxwindow)->bin_window,
NULL, NULL, &width, NULL, NULL );
-
+
wxRegionIterator upd( m_nativeUpdateRegion );
while (upd)
{
rect.y = upd.GetY();
rect.width = upd.GetWidth();
rect.height = upd.GetHeight();
-
+
rect.x = width - rect.x - rect.width;
m_updateRegion.Union( rect );
-
+
++upd;
}
}
-
+
// widget to draw on
GtkPizza *pizza = GTK_PIZZA (m_wxwindow);
gtk_widget_set_double_buffered( m_wxwindow, on );
}
+bool wxWindowGTK::IsDoubleBuffered() const
+{
+ return GTK_WIDGET_DOUBLE_BUFFERED( m_wxwindow );
+}
+
void wxWindowGTK::ClearBackground()
{
wxCHECK_RET( m_widget != NULL, wxT("invalid window") );
void wxWindowGTK::ApplyToolTip( GtkTooltips *tips, const wxChar *tip )
{
- wxString tmp( tip );
- gtk_tooltips_set_tip( tips, GetConnectWidget(), wxGTK_CONV(tmp), (gchar*) NULL );
+ if (tip)
+ {
+ wxString tmp( tip );
+ gtk_tooltips_set_tip( tips, GetConnectWidget(), wxGTK_CONV(tmp), (gchar*) NULL );
+ }
+ else
+ {
+ gtk_tooltips_set_tip( tips, GetConnectWidget(), NULL, NULL);
+ }
}
#endif // wxUSE_TOOLTIPS
if (pos < 0)
pos = 0;
m_scrollPos[dir] = adj->value = pos;
-
+
// If a "value_changed" signal emission is not already in progress
if (!m_blockValueChanged[dir])
{
const int barIndex = range == m_scrollBar[1];
GtkAdjustment* adj = range->adjustment;
-
+
const int value = int(adj->value + 0.5);
-
+
// save previous position
const double oldPos = m_scrollPos[barIndex];
// update current position
gtk_pizza_scroll( GTK_PIZZA(m_wxwindow), -dx, -dy );
m_clipPaintRegion = false;
+
+#if wxUSE_CARET
+ bool restoreCaret = (GetCaret() != NULL && GetCaret()->IsVisible());
+ if (restoreCaret)
+ {
+ wxRect caretRect(GetCaret()->GetPosition(), GetCaret()->GetSize());
+ if (dx > 0)
+ caretRect.width += dx;
+ else
+ {
+ caretRect.x += dx; caretRect.width -= dx;
+ }
+ if (dy > 0)
+ caretRect.height += dy;
+ else
+ {
+ caretRect.y += dy; caretRect.height -= dy;
+ }
+
+ RefreshRect(caretRect);
+ }
+#endif // wxUSE_CARET
}
void wxWindowGTK::GtkScrolledWindowSetBorder(GtkWidget* w, int wxstyle)