]> git.saurik.com Git - wxWidgets.git/commitdiff
Implemented wxHelpContext for wxGTK.
authorJulian Smart <julian@anthemion.co.uk>
Wed, 6 Sep 2000 16:44:17 +0000 (16:44 +0000)
committerJulian Smart <julian@anthemion.co.uk>
Wed, 6 Sep 2000 16:44:17 +0000 (16:44 +0000)
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@8276 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

include/wx/helpbase.h
src/common/helpbase.cpp

index 97e42f6e9a43d9d803173822ad3653d6085ebe91..5cfe17c0b23ffc7e91a0863202493ed70389d9eb 100644 (file)
@@ -100,9 +100,18 @@ public:
     bool ProcessHelpMessage(WXMSG* wxmsg, const wxCursor& cursor, wxWindow* win);
 #endif
 
+#ifdef __WXGTK__
+    void SetStatus(bool status, const wxPoint& pt) { m_status = status; m_mousePos = pt; }
+#endif
+
 protected:
 
     bool    m_inHelp;
+
+#ifdef __WXGTK__
+    bool    m_status; // The user left-clicked
+    wxPoint m_mousePos;
+#endif
 };
 
 #endif // wxUSE_HELP
index 1468954b39bdc0946db2d0dcea9472e493eef94b..d07256a2572ee353ff3b8e23dd0f966b5dfa9640 100644 (file)
 #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)
@@ -39,6 +46,24 @@ 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)
@@ -55,13 +80,41 @@ wxContextHelp::~wxContextHelp()
         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);
 
@@ -70,6 +123,80 @@ bool wxContextHelp::BeginContextHelp(wxWindow* win)
     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;
 }
@@ -101,11 +228,53 @@ bool wxContextHelp::EventLoop(const wxCursor& cursor, wxWindow* win)
         }
     }
     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)
 {