#include "wx/msw/private.h"
#endif
+#ifdef __WXGTK__
+#include <gtk/gtk.h>
+#include <gtk/gtkprivate.h>
+#include "wx/gtk/win_gtk.h"
+#include "wx/msgdlg.h"
+#endif
+
#if wxUSE_HELP
IMPLEMENT_CLASS(wxHelpControllerBase, wxObject)
* Invokes context-sensitive help
*/
+#ifdef __WXGTK__
+ // This class exists in order to eat events until the left mouse
+ // button is pressed
+class wxContextHelpEvtHandler: public wxEvtHandler
+{
+public:
+ wxContextHelpEvtHandler(wxContextHelp* contextHelp)
+ {
+ m_contextHelp = contextHelp;
+ }
+
+ virtual bool ProcessEvent(wxEvent& event);
+
+//// Data
+ wxContextHelp* m_contextHelp;
+};
+#endif
+
IMPLEMENT_DYNAMIC_CLASS(wxContextHelp, wxObject)
wxContextHelp::wxContextHelp(wxWindow* win, bool beginHelp)
EndContextHelp();
}
+#ifdef __WXGTK__
+wxWindow* wxFindWindowForGdkWindow(wxWindow* win, GdkWindow* gdkWindow)
+{
+ GdkWindow* thisGdkWindow1 = 0;
+ GdkWindow* thisGdkWindow2 = 0;
+
+ if (win->m_wxwindow)
+ thisGdkWindow1 = GTK_PIZZA(win->m_wxwindow)->bin_window;
+
+ thisGdkWindow2 = win->m_widget->window;
+
+ if (gdkWindow == thisGdkWindow1 || gdkWindow == thisGdkWindow2)
+ return win;
+
+ wxNode* node = win->GetChildren().First();
+ while (node)
+ {
+ wxWindow* child = (wxWindow*) node->Data();
+ wxWindow* found = wxFindWindowForGdkWindow(child, gdkWindow);
+ if (found)
+ return found;
+
+ node = node->Next();
+ }
+ return NULL;
+}
+#endif
+
bool wxContextHelp::BeginContextHelp(wxWindow* win)
{
if (!win)
win = wxTheApp->GetTopWindow();
if (!win)
return FALSE;
-
+#ifdef __WXMSW__
wxCursor cursor(wxCURSOR_QUESTION_ARROW);
wxSetCursor(cursor);
EventLoop(cursor, win);
win->ReleaseMouse();
+#endif
+
+#ifdef __WXGTK__
+ m_status = FALSE;
+ GdkCursor* query_cursor = gdk_cursor_new (GDK_QUESTION_ARROW);
+
+ GdkWindow* gdkWindow = 0;
+ GtkWidget* gtkWidget = 0;
+
+ if (win->m_wxwindow)
+ {
+ gtkWidget = win->m_wxwindow;
+ gdkWindow = GTK_PIZZA(win->m_wxwindow)->bin_window;
+ }
+ else
+ {
+ gtkWidget = win->m_widget;
+ gdkWindow = win->m_widget->window;
+ }
+
+ gint failure = gdk_pointer_grab (gdkWindow,
+ FALSE,
+ GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK |
+ GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK,
+ NULL,
+ query_cursor,
+ GDK_CURRENT_TIME);
+ if (failure)
+ {
+ gdk_cursor_destroy (query_cursor);
+ query_cursor = NULL;
+ }
+ gdk_keyboard_grab (gdkWindow, FALSE, GDK_CURRENT_TIME);
+ gtk_grab_add (gtkWidget);
+
+ win->PushEventHandler(new wxContextHelpEvtHandler(this));
+
+ // wxLogDebug("Entering loop.");
+
+ EventLoop(wxNullCursor, win);
+
+ // wxLogDebug("Exiting loop.");
+
+ win->PopEventHandler(TRUE);
+
+ gtk_grab_remove (gtkWidget);
+ gdk_keyboard_ungrab (GDK_CURRENT_TIME);
+ if (query_cursor)
+ {
+ gdk_pointer_ungrab (GDK_CURRENT_TIME);
+ gdk_cursor_destroy (query_cursor);
+ query_cursor = NULL;
+ }
+
+ if (m_status)
+ {
+ //wxMessageBox("Left-clicked");
+ //wxPoint screenPt = win->ClientToScreen(m_mousePos);
+ int x, y;
+ GdkWindow* windowAtPtr = gdk_window_at_pointer(& x, & y);
+ if (windowAtPtr)
+ {
+ wxWindow* wxWinAtPtr = wxFindWindowForGdkWindow(win, windowAtPtr);
+ if (wxWinAtPtr)
+ {
+ DispatchEvent(wxWinAtPtr, wxPoint(x, y));
+ }
+ }
+ }
+ else
+ {
+ //wxMessageBox("Cancelled");
+ }
+#endif
return TRUE;
}
}
}
return TRUE;
+#elif defined(__WXGTK__)
+ m_inHelp = TRUE;
+ while ( m_inHelp )
+ {
+ if (wxTheApp->Pending())
+ {
+ wxTheApp->Dispatch();
+ }
+ else
+ {
+ wxTheApp->ProcessIdle();
+ }
+ }
+ return TRUE;
#else
return FALSE;
#endif
}
+// PROBLEM: If you click on the panel or other descendant of the
+// given window, then it doesn't go to this handler, even though
+// there's a grab.
+bool wxContextHelpEvtHandler::ProcessEvent(wxEvent& event)
+{
+ //wxLogDebug("Got event");
+
+ if (event.GetEventType() == wxEVT_LEFT_DOWN)
+ {
+ //wxLogDebug("Mouse event");
+ wxMouseEvent& mouseEvent = (wxMouseEvent&) event;
+ m_contextHelp->SetStatus(TRUE, mouseEvent.GetPosition());
+ m_contextHelp->EndContextHelp();
+ }
+ // Don't know why these aren't being caught
+ else if (event.GetEventType() == wxEVT_CHAR || event.GetEventType() == wxEVT_KEY_DOWN)
+ {
+ //wxKeyEvent& keyEvent = (wxKeyEvent&) event;
+ if (TRUE) // keyEvent.GetKeyCode() == WXK_ESCAPE)
+ {
+ m_contextHelp->SetStatus(FALSE, wxPoint(0, 0));
+ m_contextHelp->EndContextHelp();
+ }
+ }
+
+ return TRUE;
+}
+
#ifdef __WXMSW__
bool wxContextHelp::ProcessHelpMessage(WXMSG* wxmsg, const wxCursor& cursor, wxWindow* winInQuestion)
{