#include <pango/pangox.h>
#endif
-#ifdef __WXGTK20__
- #define SET_CONTAINER_FOCUS(w, d) gtk_widget_child_focus((w), (d))
-#else
- #define SET_CONTAINER_FOCUS(w, d) gtk_container_focus(GTK_CONTAINER(w), (d))
-#endif
#ifdef __WXGTK20__
#ifdef HAVE_XIM
#ifndef __WXUNIVERSAL__
GtkPizza *pizza = GTK_PIZZA (widget);
- if (win->GetThemeEnabled())
+ if (win->GetThemeEnabled() && win->GetBackgroundStyle() == wxBG_STYLE_SYSTEM)
{
wxWindow *parent = win->GetParent();
while (parent && !parent->IsTopLevel())
}
#if wxUSE_UNICODE
- event.m_uniChar = g_utf8_get_char( str );
-
- // Backward compatible for ISO-8859
- if (event.m_uniChar < 256)
- event.m_keyCode = event.m_uniChar;
- wxLogTrace(TRACE_KEYS, _T("IM sent character '%c'"), event.m_uniChar);
+ const wxWCharBuffer data = wxConvUTF8.cMB2WC( (char*)str );
#else
- wchar_t unistr[2];
- unistr[0] = g_utf8_get_char(str);
- unistr[1] = 0;
- wxCharBuffer ansistr(wxConvLocal.cWC2MB(unistr));
- // We cannot handle characters that cannot be represented in
- // current locale's charset in non-Unicode mode:
- if (ansistr.data() == NULL)
- return;
- event.m_keyCode = ansistr[0u];
- wxLogTrace(TRACE_KEYS, _T("IM sent character '%c'"), event.m_keyCode);
+ const wxWCharBuffer wdata = wxConvUTF8.cMB2WC( (char*)str );
+ const wxCharBuffer data = wxConvLocal.cWC2MB( wdata );
#endif // wxUSE_UNICODE
+ if( !(const wxChar*)data )
+ return;
bool ret = false;
wxWindow *parent = window;
while (parent && !parent->IsTopLevel())
parent = parent->GetParent();
- if (parent)
- {
- event.SetEventType( wxEVT_CHAR_HOOK );
- ret = parent->GetEventHandler()->ProcessEvent( event );
- }
- if (!ret)
+ for( const wxChar* pstr = data; *pstr; pstr++ )
{
- event.SetEventType(wxEVT_CHAR);
- ret = window->GetEventHandler()->ProcessEvent( event );
+#if wxUSE_UNICODE
+ event.m_uniChar = *pstr;
+ // Backward compatible for ISO-8859
+ event.m_keyCode = *pstr < 256 ? event.m_uniChar : 0;
+ wxLogTrace(TRACE_KEYS, _T("IM sent character '%c'"), event.m_uniChar);
+#else
+ event.m_keyCode = *pstr;
+#endif // wxUSE_UNICODE
+ if (parent)
+ {
+ event.SetEventType( wxEVT_CHAR_HOOK );
+ ret = parent->GetEventHandler()->ProcessEvent( event );
+ }
+
+ if (!ret)
+ {
+ event.SetEventType(wxEVT_CHAR);
+ ret = window->GetEventHandler()->ProcessEvent( event );
+ }
}
}
#endif
if (event.GetEventType() == wxEVT_MOUSEWHEEL)
{
event.m_linesPerAction = 3;
+ event.m_wheelDelta = 120;
if (((GdkEventButton*)gdk_event)->button == 4)
event.m_wheelRotation = 120;
else if (((GdkEventButton*)gdk_event)->button == 5)
// a chance to correct this
win->FixUpMouseEvent(widget, event.m_x, event.m_y);
+ if ( event_type == wxEVT_RIGHT_DOWN )
+ {
+ // generate a "context menu" event: this is similar to right mouse
+ // click under many GUIs except that it is generated differently
+ // (right up under MSW, ctrl-click under Mac, right down here) and
+ //
+ // (a) it's a command event and so is propagated to the parent
+ // (b) under MSW it can be generated from kbd too
+ // (c) it uses screen coords (because of (a))
+ wxContextMenuEvent evtCtx(wxEVT_CONTEXT_MENU,
+ win->GetId(),
+ win->ClientToScreen(event.GetPosition()));
+ (void)win->GetEventHandler()->ProcessEvent(evtCtx);
+ }
+
// find the correct window to send the event too: it may be a different one
// from the one which got it at GTK+ level because some control don't have
// their own X window and thus cannot get any events.
gs_timeLastClick = gdk_event->time;
-/*
- wxPrintf( wxT("2) OnButtonPress from ") );
- if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
- wxPrintf( win->GetClassInfo()->GetClassName() );
- wxPrintf( wxT(".\n") );
-*/
-
#ifndef __WXGTK20__
if (event_type == wxEVT_LEFT_DCLICK)
{
// same wxListBox hack as above
win->FixUpMouseEvent(widget, event.m_x, event.m_y);
- if ( event_type == wxEVT_RIGHT_UP )
- {
- // generate a "context menu" event: this is similar to wxEVT_RIGHT_UP
- // except that:
- //
- // (a) it's a command event and so is propagated to the parent
- // (b) under MSW it can be generated from kbd too
- // (c) it uses screen coords (because of (a))
- wxContextMenuEvent evtCtx(wxEVT_CONTEXT_MENU,
- win->GetId(),
- win->ClientToScreen(event.GetPosition()));
- (void)win->GetEventHandler()->ProcessEvent(evtCtx);
- }
-
if ( !g_captureWindow )
win = FindWindowForMouseEvent(win, event.m_x, event.m_y);
event.m_middleDown = (gdk_event->state & GDK_BUTTON2_MASK);
event.m_rightDown = (gdk_event->state & GDK_BUTTON3_MASK);
event.m_linesPerAction = 3;
+ event.m_wheelDelta = 120;
if (gdk_event->direction == GDK_SCROLL_UP)
event.m_wheelRotation = 120;
else
m_clipPaintRegion = FALSE;
+ m_needsStyleChange = false;
+
m_cursor = *wxSTANDARD_CURSOR;
#ifdef __WXGTK20__
m_imData = NULL;
m_x11Context = NULL;
+ m_dirtyTabOrder = false;
#else
#ifdef HAVE_XIM
m_ic = (GdkIC*) NULL;
(gpointer) this );
}
+ InheritAttributes();
+
m_hasVMT = TRUE;
// unless the window was created initially hidden (i.e. Hide() had been
void wxWindowGTK::OnInternalIdle()
{
+#ifdef __WXGTK20__
+ if ( m_dirtyTabOrder )
+ RealizeTabOrder();
+#endif
+ // Update style if the window was not yet realized
+ // and SetBackgroundStyle(wxBG_STYLE_CUSTOM) was called
+ if (m_needsStyleChange)
+ {
+ SetBackgroundStyle(GetBackgroundStyle());
+ m_needsStyleChange = false;
+ }
+
// Update invalidated regions.
GtkUpdate();
g_object_unref( G_OBJECT( layout ) );
- return (int) (rect.height / PANGO_SCALE);
+ return (int) PANGO_PIXELS(rect.height);
#else
GdkFont *gfont = font.GetInternalFont( 1.0 );
g_object_unref( G_OBJECT( layout ) );
- return (int) (rect.width / PANGO_SCALE);
+ return (int) PANGO_PIXELS(rect.width);
#else
GdkFont *gfont = font.GetInternalFont( 1.0 );
pango_layout_set_text(layout, (const char*) data, strlen( (const char*) data ));
#endif
}
- PangoLayoutLine *line = (PangoLayoutLine *)pango_layout_get_lines(layout)->data;
PangoRectangle rect;
- pango_layout_line_get_extents(line, NULL, &rect);
+ pango_layout_get_extents(layout, NULL, &rect);
- if (x) (*x) = (wxCoord) (rect.width / PANGO_SCALE);
- if (y) (*y) = (wxCoord) (rect.height / PANGO_SCALE);
+ if (x) (*x) = (wxCoord) PANGO_PIXELS(rect.width);
+ if (y) (*y) = (wxCoord) PANGO_PIXELS(rect.height);
if (descent)
{
- // Do something about metrics here
- (*descent) = 0;
+ PangoLayoutIter *iter = pango_layout_get_iter(layout);
+ int baseline = pango_layout_iter_get_baseline(iter);
+ pango_layout_iter_free(iter);
+ *descent = *y - PANGO_PIXELS(baseline);
}
if (externalLeading) (*externalLeading) = 0; // ??
void wxWindowGTK::SetFocus()
{
wxCHECK_RET( m_widget != NULL, wxT("invalid window") );
-
if ( m_hasFocus )
{
// don't do anything if we already have focus
}
else if (m_widget)
{
+#ifdef __WXGTK20__
+ if (GTK_IS_CONTAINER(m_widget))
+ {
+ gtk_widget_child_focus( m_widget, GTK_DIR_TAB_FORWARD );
+ }
+ else
+#endif
if (GTK_WIDGET_CAN_FOCUS(m_widget) && !GTK_WIDGET_HAS_FOCUS (m_widget) )
{
+
if (!GTK_WIDGET_REALIZED(m_widget))
{
// we can't set the focus to the widget now so we remember that
gtk_widget_grab_focus (m_widget);
}
}
- else if (GTK_IS_CONTAINER(m_widget))
+ else
+#ifndef __WXGTK20__
+ if (GTK_IS_CONTAINER(m_widget))
{
- SET_CONTAINER_FOCUS( m_widget, GTK_DIR_TAB_FORWARD );
+ gtk_container_focus( GTK_CONTAINER(m_widget), GTK_DIR_TAB_FORWARD );
}
else
+#endif
{
wxLogTrace(TRACE_FOCUS,
_T("Can't set focus to %s(%s)"),
(*m_insertCallback)(this, child);
}
+#ifdef __WXGTK20__
+
+void wxWindowGTK::AddChild(wxWindowBase *child)
+{
+ wxWindowBase::AddChild(child);
+ m_dirtyTabOrder = true;
+ if (g_isIdle)
+ wxapp_install_idle_handler();
+}
+
+void wxWindowGTK::RemoveChild(wxWindowBase *child)
+{
+ wxWindowBase::RemoveChild(child);
+ m_dirtyTabOrder = true;
+ if (g_isIdle)
+ wxapp_install_idle_handler();
+}
+
+void wxWindowGTK::DoMoveInTabOrder(wxWindow *win, MoveKind move)
+{
+ wxWindowBase::DoMoveInTabOrder(win, move);
+ m_dirtyTabOrder = true;
+ if (g_isIdle)
+ wxapp_install_idle_handler();
+}
+
+void wxWindowGTK::RealizeTabOrder()
+{
+ if (m_wxwindow)
+ {
+ if (m_children.size() > 0)
+ {
+ GList *chain = NULL;
+
+ for (wxWindowList::const_iterator i = m_children.begin();
+ i != m_children.end(); ++i)
+ {
+ chain = g_list_prepend(chain, (*i)->m_widget);
+ }
+
+ chain = g_list_reverse(chain);
+
+ gtk_container_set_focus_chain(GTK_CONTAINER(m_wxwindow), chain);
+ g_list_free(chain);
+ }
+ else
+ {
+ gtk_container_unset_focus_chain(GTK_CONTAINER(m_wxwindow));
+ }
+ }
+
+ m_dirtyTabOrder = false;
+}
+
+#endif // __WXGTK20__
+
void wxWindowGTK::Raise()
{
wxCHECK_RET( (m_widget != NULL), wxT("invalid window") );
// widget to draw on
GtkPizza *pizza = GTK_PIZZA (m_wxwindow);
- if (GetThemeEnabled())
+ if (GetThemeEnabled() && GetBackgroundStyle() == wxBG_STYLE_SYSTEM)
{
// find ancestor from which to steal background
wxWindow *parent = GetParent();
wxEraseEvent erase_event( GetId(), &dc );
erase_event.SetEventObject( this );
- if (!GetEventHandler()->ProcessEvent(erase_event))
+ if (!GetEventHandler()->ProcessEvent(erase_event) && GetBackgroundStyle() != wxBG_STYLE_CUSTOM)
{
if (!g_eraseGC)
{
}
// apply style change (forceStyle=true so that new style is applied
- // even if the bg colour changed from valid to wxNullColour):
- ApplyWidgetStyle(true);
+ // even if the bg colour changed from valid to wxNullColour)
+ if (GetBackgroundStyle() != wxBG_STYLE_CUSTOM)
+ ApplyWidgetStyle(true);
return true;
}
DoApplyWidgetStyle(style);
gtk_rc_style_unref(style);
}
+
+ // Style change may affect GTK+'s size calculation:
+ InvalidateBestSize();
}
void wxWindowGTK::DoApplyWidgetStyle(GtkRcStyle *style)
{
if (m_wxwindow)
- // should we also do m_widget in this case?
gtk_widget_modify_style(m_wxwindow, style);
- else
- gtk_widget_modify_style(m_widget, style);
+ gtk_widget_modify_style(m_widget, style);
}
+bool wxWindowGTK::SetBackgroundStyle(wxBackgroundStyle style)
+{
+ wxWindowBase::SetBackgroundStyle(style);
+
+ if (style == wxBG_STYLE_CUSTOM)
+ {
+ GdkWindow *window = (GdkWindow*) NULL;
+ if (m_wxwindow)
+ window = GTK_PIZZA(m_wxwindow)->bin_window;
+ else
+ window = GetConnectWidget()->window;
+
+ if (window)
+ {
+ // Make sure GDK/X11 doesn't refresh the window
+ // automatically.
+ gdk_window_set_back_pixmap( window, None, False );
+#ifdef __X__
+ Display* display = GDK_WINDOW_DISPLAY(window);
+ XFlush(display);
+#endif
+ m_needsStyleChange = false;
+ }
+ else
+ // Do in OnIdle, because the window is not yet available
+ m_needsStyleChange = true;
+
+ // Don't apply widget style, or we get a grey background
+ }
+ else
+ {
+ // apply style change (forceStyle=true so that new style is applied
+ // even if the bg colour changed from valid to wxNullColour):
+ ApplyWidgetStyle(true);
+ }
+ return true;
+}
//-----------------------------------------------------------------------------
// Pop-up menu stuff
bool is_waiting = true;
- gtk_signal_connect( GTK_OBJECT(menu->m_menu),
- "hide",
- GTK_SIGNAL_FUNC(gtk_pop_hide_callback),
- (gpointer)&is_waiting );
+ gulong handler = gtk_signal_connect( GTK_OBJECT(menu->m_menu),
+ "hide",
+ GTK_SIGNAL_FUNC(gtk_pop_hide_callback),
+ (gpointer)&is_waiting );
wxPoint pos;
gpointer userdata;
gtk_main_iteration();
}
+ gtk_signal_disconnect(GTK_OBJECT(menu->m_menu), handler);
+
return true;
}