]> git.saurik.com Git - wxWidgets.git/commitdiff
1. added abstract interface to wxHtmlWindow for use by wxHtmlWinParser and implemente...
authorVáclav Slavík <vslavik@fastmail.fm>
Thu, 13 Apr 2006 22:08:28 +0000 (22:08 +0000)
committerVáclav Slavík <vslavik@fastmail.fm>
Thu, 13 Apr 2006 22:08:28 +0000 (22:08 +0000)
2. used the above to implement clickable links support in wxHtmlListBox

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@38701 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

17 files changed:
docs/changes.txt
docs/latex/wx/htcell.tex
docs/latex/wx/htmllbox.tex
docs/latex/wx/htwindow.tex
docs/latex/wx/htwinprs.tex
include/wx/html/htmlcell.h
include/wx/html/htmlwin.h
include/wx/html/winpars.h
include/wx/htmllbox.h
samples/htlbox/htlbox.cpp
src/generic/htmllbox.cpp
src/html/htmlcell.cpp
src/html/htmlwin.cpp
src/html/htmprint.cpp
src/html/m_image.cpp
src/html/m_layout.cpp
src/html/winpars.cpp

index f21436a89343099e6e7c2f85bf09f5ad56d7c3f3..1a340978294695e0fe2386bb3fecfa6f9c3bca19 100644 (file)
@@ -13,6 +13,11 @@ INCOMPATIBLE CHANGES SINCE 2.6.x
 - wxCHECK family of macros now must be followed by a semicolon
 - wxMBConv::cMB2WC() and cWC2MB() take size of the input buffer and return
   length of the converted string in all cases now.
+- wxHtmlWindow::OnCellClicked() now returns bool.
+- wxHtmlCell::OnMouseClick() was deprecated and replaced with
+  wxHtmlCell::ProcessMouseClick(); old code overriding OnMouseClick() will
+  continue to work with WXWIN_COMPATIBILITY_2_6, but should be rewritten to
+  use ProcessMouseClick().
 
 
 Deprecated methods since 2.6.x and their replacements
@@ -111,6 +116,8 @@ All (GUI):
 - Added wxListBox::HitTest().
 - Added wxDisplay::GetClientArea().
 - Indices and counts in wxControlWithItems derived API are unsigned.
+- Added support for links to wxHtmlListBox; use code has to override
+  wxHtmlListBox::OnLinkClicked() to take advantage of it.
 
 wxMSW:
 
index 71ade362eef1abc9928551e84ac3b368e089cf02..a627e84ec05f978ba3508f3d57439132e00e087b 100644 (file)
@@ -223,13 +223,14 @@ It must be called before displaying cells structure because
 m\_PosX and m\_PosY are undefined (or invalid)
 before calling Layout.
 
-\membersection{wxHtmlCell::OnMouseClick}\label{wxhtmlcellonmouseclick}
+\membersection{wxHtmlCell::ProcessMouseClick}\label{wxhtmlcellprocessmouseclick}
 
-\func{virtual void}{OnMouseClick}{\param{wxWindow* }{parent}, \param{int}{x}, \param{int }{y}, \param{const wxMouseEvent\& }{event}}
+\func{virtual bool}{ProcessMouseClick}{\param{wxHtmlWindowInterface* }{window}, \param{const wxPoint\& }{pos}, \param{const wxMouseEvent\& }{event}}
 
-This function is simple event handler. Each time the user clicks mouse button over a cell
-within \helpref{wxHtmlWindow}{wxhtmlwindow} this method of that cell is called. Default behavior is
-that it calls \helpref{wxHtmlWindow::LoadPage}{wxhtmlwindowloadpage}.
+This function is simple event handler. Each time the user clicks mouse button
+over a cell within \helpref{wxHtmlWindow}{wxhtmlwindow} this method of that
+cell is called. Default behavior is to call
+\helpref{wxHtmlWindow::LoadPage}{wxhtmlwindowloadpage}.
 
 \wxheading{Note}
 
@@ -238,12 +239,15 @@ you should use wxHtmlBinderCell instead.
 
 \wxheading{Parameters}
 
-\docparam{parent}{parent window (always wxHtmlWindow!)}
+\docparam{window}{interface to the parent HTML window}
 
-\docparam{x, y}{coordinates of mouse click (this is relative to cell's origin}
+\docparam{pos}{coordinates of mouse click (this is relative to cell's origin}
 
-\docparam{left, middle, right}{boolean flags for mouse buttons. true if the left/middle/right
-button is pressed, false otherwise}
+\docparam{event}{mouse event that triggered the call}
+
+\wxheading{Return value}
+
+\true if a link was clicked, \false otherwise.
 
 \membersection{wxHtmlCell::SetId}\label{wxhtmlcellsetid}
 
index e56d1b6d1a2bc8adc0d646b4d7204c3c7b2de9c7..257611d03914b80226e482ac1bf0ac85f8641e1f 100644 (file)
@@ -127,3 +127,18 @@ for the given item.
 This function may be overridden to decorate HTML returned by
 \helpref{OnGetItem()}{wxhtmllistboxongetitem}.
 
+\membersection{wxHtmlListBox::OnLinkClicked}\label{wxhtmlistboxonlinkclicked}
+
+\func{virtual void}{OnLinkClicked}{\param{size\_t }{n}, \param{const wxHtmlLinkInfo\& }{link}}
+
+Called when the user clicks on hypertext link. Does nothing by default.
+
+\wxheading{Parameters}
+
+\docparam{n}{Index of the item containing the link.}
+
+\docparam{link}{Description of the link.}
+
+\wxheading{See also}
+
+See also \helpref{wxHtmlLinkInfo}{wxhtmllinkinfo}.
index 01c50a92238c5153309b6788986d7009a0847184..190551eee7e925dbc573f675c084292430d12eb0 100644 (file)
@@ -197,7 +197,7 @@ false if an error occurred, true otherwise
 
 \membersection{wxHtmlWindow::OnCellClicked}\label{wxhtmlwindowoncellclicked}
 
-\func{virtual void}{OnCellClicked}{\param{wxHtmlCell }{*cell}, \param{wxCoord }{x}, \param{wxCoord }{y}, \param{const wxMouseEvent\& }{event}}
+\func{virtual bool}{OnCellClicked}{\param{wxHtmlCell }{*cell}, \param{wxCoord }{x}, \param{wxCoord }{y}, \param{const wxMouseEvent\& }{event}}
 
 This method is called when a mouse button is clicked inside wxHtmlWindow.
 The default behaviour is to call 
@@ -213,6 +213,10 @@ hypertext link.
 
 \docparam{event}{The mouse event containing other information about the click}
 
+\wxheading{Return value}
+
+\true if a link was clicked, \false otherwise.
+
 \membersection{wxHtmlWindow::OnCellMouseHover}\label{wxhtmlwindowoncellmousehover}
 
 \func{virtual void}{OnCellMouseHover}{\param{wxHtmlCell }{*cell}, \param{wxCoord }{x}, \param{wxCoord }{y}}
index 5a24cf285bf0e79869956ae374570da441e8d392..930306a5afc36cfacd859ad2f7bfa9086c2d1ec8 100644 (file)
@@ -32,10 +32,12 @@ The product of parsing is a wxHtmlCell (resp. wxHtmlContainer) object.
 
 \func{}{wxHtmlWinParser}{\void}
 
-\func{}{wxHtmlWinParser}{\param{wxHtmlWindow }{*wnd}}
+\func{}{wxHtmlWinParser}{\param{wxHtmlWindowInterface }{*wndIface}}
 
 Constructor. Don't use the default one, use constructor with
-{\it wnd} parameter ({\it wnd} is pointer to associated \helpref{wxHtmlWindow}{wxhtmlwindow})
+{\it wndIface} parameter ({\it wndIface} is a pointer to interface object for
+the associated \helpref{wxHtmlWindow}{wxhtmlwindow} or other HTML rendering
+window such as \helpref{wxHtmlListBox}{wxhtmllistbox}).
 
 \membersection{wxHtmlWinParser::AddModule}\label{wxhtmlwinparseraddmodule}
 
index 62afdebae42b1afd7825265f0247352c04a8d05a..0b32fe4fb24ce24fc0213b515bf0d06b6948ae4e 100644 (file)
@@ -20,6 +20,7 @@
 #include "wx/window.h"
 
 
+class WXDLLIMPEXP_HTML wxHtmlWindowInterface;
 class WXDLLIMPEXP_HTML wxHtmlLinkInfo;
 class WXDLLIMPEXP_HTML wxHtmlCell;
 class WXDLLIMPEXP_HTML wxHtmlContainerCell;
@@ -244,12 +245,23 @@ public:
     //   returns pointer to anchor news
     virtual const wxHtmlCell* Find(int condition, const void* param) const;
 
+
     // This function is called when mouse button is clicked over the cell.
+    // Returns true if a link is clicked, false otherwise.
     //
-    // Parent is pointer to wxHtmlWindow that generated the event
+    // 'window' is pointer to wxHtmlWindowInterface of the window which
+    // generated the event.
     // HINT: if this handling is not enough for you you should use
     //       wxHtmlWidgetCell
-    virtual void OnMouseClick(wxWindow *parent, int x, int y, const wxMouseEvent& event);
+    virtual bool ProcessMouseClick(wxHtmlWindowInterface *window,
+                                   const wxPoint& pos,
+                                   const wxMouseEvent& event);
+
+#if WXWIN_COMPATIBILITY_2_6
+    // this was replaced by ProcessMouseClick, don't use in new code!
+    virtual void OnMouseClick(wxWindow *window,
+                              int x, int y, const wxMouseEvent& event);
+#endif
 
     // This method used to adjust pagebreak position. The parameter is variable
     // that contains y-coordinate of page break (= horizontal line that should
@@ -283,8 +295,14 @@ public:
     virtual wxHtmlCell *FindCellByPos(wxCoord x, wxCoord y,
                                   unsigned flags = wxHTML_FIND_EXACT) const;
 
-    // Returns absolute position of the cell on HTML canvas
-    wxPoint GetAbsPos() const;
+    // Returns absolute position of the cell on HTML canvas.
+    // If rootCell is provided, then it's considered to be the root of the
+    // hierarchy and the returned value is relative to it.
+    wxPoint GetAbsPos(wxHtmlCell *rootCell = NULL) const;
+
+    // Returns root cell of the hierarchy (i.e. grand-grand-...-parent that
+    // doesn't have a parent itself)
+    wxHtmlCell *GetRootCell() const;
 
     // Returns first (last) terminal cell inside this cell. It may return NULL,
     // but it is rare -- only if there are no terminals in the tree.
@@ -424,7 +442,15 @@ public:
     void SetBorder(const wxColour& clr1, const wxColour& clr2) {m_UseBorder = true; m_BorderColour1 = clr1, m_BorderColour2 = clr2;}
     virtual wxHtmlLinkInfo* GetLink(int x = 0, int y = 0) const;
     virtual const wxHtmlCell* Find(int condition, const void* param) const;
-    virtual void OnMouseClick(wxWindow *parent, int x, int y, const wxMouseEvent& event);
+
+#if WXWIN_COMPATIBILITY_2_6
+    // this was replaced by ProcessMouseClick, don't use in new code!
+    virtual void OnMouseClick(wxWindow *window,
+                              int x, int y, const wxMouseEvent& event);
+#endif
+    virtual bool ProcessMouseClick(wxHtmlWindowInterface *window,
+                                   const wxPoint& pos,
+                                   const wxMouseEvent& event);
 
     virtual wxHtmlCell* GetFirstChild() const { return m_Cells; }
 #if WXWIN_COMPATIBILITY_2_4
index 719173bedbaf763cd890b3a9608dc83542465bb1..ea22e30601f2357e11870002f35858cef2a69eaa 100644 (file)
@@ -38,15 +38,163 @@ class WXDLLIMPEXP_HTML wxHtmlWinAutoScrollTimer;
 
 #define wxHW_DEFAULT_STYLE      wxHW_SCROLLBAR_AUTO
 
-
-// enums for wxHtmlWindow::OnOpeningURL
+/// Enum for wxHtmlWindow::OnOpeningURL and wxHtmlWindowInterface::OnOpeningURL
 enum wxHtmlOpeningStatus
 {
+    /// Open the requested URL
     wxHTML_OPEN,
+    /// Do not open the URL
     wxHTML_BLOCK,
+    /// Redirect to another URL (returned from OnOpeningURL)
     wxHTML_REDIRECT
 };
 
+/**
+    Abstract interface to a HTML rendering window (such as wxHtmlWindow or
+    wxHtmlListBox) that is passed to wxHtmlWinParser. It encapsulates all
+    communication from the parser to the window.
+ */
+class WXDLLIMPEXP_HTML wxHtmlWindowInterface
+{
+public:
+    /// Ctor
+    wxHtmlWindowInterface() {}
+    virtual ~wxHtmlWindowInterface() {}
+
+    /**
+        Called by the parser to set window's title to given text.
+     */
+    virtual void SetHTMLWindowTitle(const wxString& title) = 0;
+
+    /**
+        Called when a link is clicked.
+
+        @param link information about the clicked link
+     */
+    virtual void OnHTMLLinkClicked(const wxHtmlLinkInfo& link) = 0;
+
+    /**
+        Called when the parser needs to open another URL (e.g. an image).
+
+        @param type     Type of the URL request (e.g. image)
+        @param url      URL the parser wants to open
+        @param redirect If the return value is wxHTML_REDIRECT, then the
+                        URL to redirect to will be stored in this variable
+                        (the pointer must never be NULL)
+
+        @return indicator of how to treat the request
+     */
+    virtual wxHtmlOpeningStatus OnHTMLOpeningURL(wxHtmlURLType type,
+                                                 const wxString& url,
+                                                 wxString *redirect) const = 0;
+
+    /**
+        Converts coordinates @a pos relative to given @a cell to
+        physical coordinates in the window.
+     */
+    virtual wxPoint HTMLCoordsToWindow(wxHtmlCell *cell,
+                                       const wxPoint& pos) const = 0;
+
+    /// Returns the window used for rendering (may be NULL).
+    virtual wxWindow* GetHTMLWindow() = 0;
+
+    /// Returns background colour to use by default.
+    virtual wxColour GetHTMLBackgroundColour() const = 0;
+
+    /// Sets window's background to colour @a clr.
+    virtual void SetHTMLBackgroundColour(const wxColour& clr) = 0;
+
+    /// Sets window's background to given bitmap.
+    virtual void SetHTMLBackgroundImage(const wxBitmap& bmpBg) = 0;
+
+    /// Sets status bar text.
+    virtual void SetHTMLStatusText(const wxString& text) = 0;
+};
+
+/**
+    Helper class that implements part of mouse handling for wxHtmlWindow and
+    wxHtmlListBox. Cursor changes and clicking on links are handled, text
+    selection is not.
+ */
+class WXDLLIMPEXP_HTML wxHtmlWindowMouseHelper
+{
+public:
+    /**
+        Ctor.
+
+        @param iface Interface to the owner window.
+     */
+    wxHtmlWindowMouseHelper(wxHtmlWindowInterface *iface);
+
+    /// Returns true if the mouse moved since the last call to HandleIdle
+    bool DidMouseMove() const { return m_tmpMouseMoved; }
+
+    /// Call this from EVT_MOTION event handler
+    void HandleMouseMoved();
+
+    /**
+        Call this from EVT_LEFT_UP handler (or, alternatively, EVT_LEFT_DOWN).
+
+        @param rootCell HTML cell inside which the click occured. This doesn't
+                        have to be the leaf cell, it can be e.g. toplevel
+                        container, but the mouse must be inside the container's
+                        area, otherwise the event would be ignored.
+        @param pos      Mouse position in coordinates relative to @a cell
+        @param event    The event that triggered the call
+     */
+    bool HandleMouseClick(wxHtmlCell *rootCell,
+                          const wxPoint& pos, const wxMouseEvent& event);
+
+    /**
+        Call this from OnInternalIdle of the HTML displaying window. Handles
+        mouse movements and must be used together with HandleMouseMoved.
+
+        @param rootCell HTML cell inside which the click occured. This doesn't
+                        have to be the leaf cell, it can be e.g. toplevel
+                        container, but the mouse must be inside the container's
+                        area, otherwise the event would be ignored.
+        @param pos      Current mouse position in coordinates relative to
+                        @a cell
+     */
+    void HandleIdle(wxHtmlCell *rootCell, const wxPoint& pos);
+
+    /**
+        Called by HandleIdle when the mouse hovers over a cell. Default
+        behaviour is to do nothing.
+
+        @param cell   the cell the mouse is over
+        @param x, y   coordinates of mouse relative to the cell
+     */
+    virtual void OnCellMouseHover(wxHtmlCell *cell, wxCoord x, wxCoord y);
+
+    /**
+        Called by HandleMouseClick when the user clicks on a cell.
+        Default behavior is to call wxHtmlWindowInterface::OnLinkClicked()
+        if this cell corresponds to a hypertext link.
+
+        @param cell   the cell the mouse is over
+        @param x, y   coordinates of mouse relative to the cell
+        @param event    The event that triggered the call
+
+
+        @return true if a link was clicked, false otherwise.
+     */
+    virtual bool OnCellClicked(wxHtmlCell *cell,
+                               wxCoord x, wxCoord y,
+                               const wxMouseEvent& event);
+
+protected:
+    // this flag indicates if the mouse moved (used by HandleIdle)
+    bool m_tmpMouseMoved;
+    // contains last link name
+    wxHtmlLinkInfo *m_tmpLastLink;
+    // contains the last (terminal) cell which contained the mouse
+    wxHtmlCell *m_tmpLastCell;
+
+private:
+    wxHtmlWindowInterface *m_interface;
+};
+
 // ----------------------------------------------------------------------------
 // wxHtmlWindow
 //                  (This is probably the only class you will directly use.)
@@ -58,18 +206,21 @@ enum wxHtmlOpeningStatus
 //                  SetPage(text) or LoadPage(filename).
 // ----------------------------------------------------------------------------
 
-class WXDLLIMPEXP_HTML wxHtmlWindow : public wxScrolledWindow
+class WXDLLIMPEXP_HTML wxHtmlWindow : public wxScrolledWindow,
+                                      public wxHtmlWindowInterface,
+                                      private wxHtmlWindowMouseHelper
 {
     DECLARE_DYNAMIC_CLASS(wxHtmlWindow)
     friend class wxHtmlWinModule;
 
 public:
-    wxHtmlWindow() { Init(); }
+    wxHtmlWindow() : wxHtmlWindowMouseHelper(this) { Init(); }
     wxHtmlWindow(wxWindow *parent, wxWindowID id = wxID_ANY,
                  const wxPoint& pos = wxDefaultPosition,
                  const wxSize& size = wxDefaultSize,
                  long style = wxHW_DEFAULT_STYLE,
                  const wxString& name = wxT("htmlWindow"))
+        : wxHtmlWindowMouseHelper(this)
     {
         Init();
         Create(parent, id, pos, size, style, name);
@@ -178,16 +329,6 @@ public:
     // (depending on the information passed to SetRelatedFrame() method)
     virtual void OnSetTitle(const wxString& title);
 
-    // Called when the mouse hovers over a cell: (x, y) are logical coords
-    // Default behaviour is to do nothing at all
-    virtual void OnCellMouseHover(wxHtmlCell *cell, wxCoord x, wxCoord y);
-
-    // Called when user clicks on a cell. Default behavior is to call
-    // OnLinkClicked() if this cell corresponds to a hypertext link
-    virtual void OnCellClicked(wxHtmlCell *cell,
-                               wxCoord x, wxCoord y,
-                               const wxMouseEvent& event);
-
     // Called when user clicked on hypertext link. Default behavior is to
     // call LoadPage(loc)
     virtual void OnLinkClicked(const wxHtmlLinkInfo& link);
@@ -216,6 +357,7 @@ public:
 
     virtual void OnInternalIdle();
 
+
 protected:
     void Init();
 
@@ -272,6 +414,20 @@ protected:
     wxString DoSelectionToText(wxHtmlSelection *sel);
 
 private:
+    // wxHtmlWindowInterface methods:
+    virtual void SetHTMLWindowTitle(const wxString& title);
+    virtual void OnHTMLLinkClicked(const wxHtmlLinkInfo& link);
+    virtual wxHtmlOpeningStatus OnHTMLOpeningURL(wxHtmlURLType type,
+                                                 const wxString& url,
+                                                 wxString *redirect) const;
+    virtual wxPoint HTMLCoordsToWindow(wxHtmlCell *cell,
+                                       const wxPoint& pos) const;
+    virtual wxWindow* GetHTMLWindow();
+    virtual wxColour GetHTMLBackgroundColour() const;
+    virtual void SetHTMLBackgroundColour(const wxColour& clr);
+    virtual void SetHTMLBackgroundImage(const wxBitmap& bmpBg);
+    virtual void SetHTMLStatusText(const wxString& text);
+
     // implementation of SetPage()
     bool DoSetPage(const wxString& source);
 
@@ -333,10 +489,6 @@ private:
     wxPoint     m_tmpSelFromPos;
     wxHtmlCell *m_tmpSelFromCell;
 
-    // contains last link name
-    wxHtmlLinkInfo *m_tmpLastLink;
-    // contains the last (terminal) cell which contained the mouse
-    wxHtmlCell *m_tmpLastCell;
     // if >0 contents of the window is not redrawn
     // (in order to avoid ugly blinking)
     int m_tmpCanDrawLocks;
@@ -356,10 +508,6 @@ private:
     // if this FLAG is false, items are not added to history
     bool m_HistoryOn;
 
-    // a flag indicated if mouse moved
-    // (if true we will try to change cursor in last call to OnIdle)
-    bool m_tmpMouseMoved;
-
     // a flag set if we need to erase background in OnPaint() (otherwise this
     // is supposed to have been done in OnEraseBackground())
     bool m_eraseBgInOnPaint;
index 12893b888bd379047b8986862f7e6e6f3335995b..965738d542374c7262a3d469a5368f67976ae3a5 100644 (file)
 #include "wx/encconv.h"
 
 class WXDLLIMPEXP_HTML wxHtmlWindow;
+class WXDLLIMPEXP_HTML wxHtmlWindowInterface;
 class WXDLLIMPEXP_HTML wxHtmlWinParser;
 class WXDLLIMPEXP_HTML wxHtmlWinTagHandler;
 class WXDLLIMPEXP_HTML wxHtmlTagsModule;
 
+
 //--------------------------------------------------------------------------------
 // wxHtmlWinParser
 //                  This class is derived from wxHtmlParser and its mail goal
@@ -37,7 +39,8 @@ class WXDLLIMPEXP_HTML wxHtmlWinParser : public wxHtmlParser
     friend class wxHtmlWindow;
 
 public:
-    wxHtmlWinParser(wxHtmlWindow *wnd = NULL);
+    wxHtmlWinParser(wxHtmlWindowInterface *wndIface = NULL);
+
     ~wxHtmlWinParser();
 
     virtual void InitParser(const wxString& source);
@@ -62,7 +65,10 @@ public:
     // GetDC()->GetChar...()
 
     // returns associated wxWindow
-    wxHtmlWindow *GetWindow() {return m_Window;}
+    wxHtmlWindowInterface *GetWindowInterface() {return m_windowInterface;}
+#if WXWIN_COMPATIBILITY_2_6
+    wxDEPRECATED( wxHtmlWindow *GetWindow() );
+#endif
 
     // Sets fonts to be used when displaying HTML page. (if size null then default sizes used).
     void SetFonts(const wxString& normal_face, const wxString& fixed_face, const int *sizes = NULL);
@@ -148,7 +154,7 @@ private:
     wxChar *m_tmpStrBuf;
     size_t  m_tmpStrBufSize;
         // temporary variables used by AddText
-    wxHtmlWindow *m_Window;
+    wxHtmlWindowInterface *m_windowInterface;
             // window we're parsing for
     double m_PixelScale;
     wxDC *m_DC;
index bf0d295bde861249b5d8d5391a6a60a72c8725ce..6c37476ace42552c38a828c69a5b9956a06e8183 100644 (file)
@@ -13,6 +13,7 @@
 #define _WX_HTMLLBOX_H_
 
 #include "wx/vlbox.h"               // base class
+#include "wx/html/htmlwin.h"
 
 #if wxUSE_FILESYSTEM
     #include "wx/filesys.h"
@@ -27,7 +28,9 @@ class WXDLLIMPEXP_HTML wxHtmlListBoxStyle;
 // wxHtmlListBox
 // ----------------------------------------------------------------------------
 
-class WXDLLIMPEXP_HTML wxHtmlListBox : public wxVListBox
+class WXDLLIMPEXP_HTML wxHtmlListBox : public wxVListBox,
+                                       public wxHtmlWindowInterface,
+                                       private wxHtmlWindowMouseHelper
 {
     DECLARE_ABSTRACT_CLASS(wxHtmlListBox)
 public:
@@ -35,7 +38,7 @@ public:
     // ---------------------
 
     // default constructor, you must call Create() later
-    wxHtmlListBox() { Init(); }
+    wxHtmlListBox();
 
     // normal constructor which calls Create() internally
     wxHtmlListBox(wxWindow *parent,
@@ -43,12 +46,7 @@ public:
                   const wxPoint& pos = wxDefaultPosition,
                   const wxSize& size = wxDefaultSize,
                   long style = 0,
-                  const wxString& name = wxVListBoxNameStr)
-    {
-        Init();
-
-        (void)Create(parent, id, pos, size, style, name);
-    }
+                  const wxString& name = wxVListBoxNameStr);
 
     // really creates the control and sets the initial number of items in it
     // (which may be changed later with SetItemCount())
@@ -80,6 +78,8 @@ public:
     const wxFileSystem& GetFileSystem() const { return m_filesystem; }
 #endif // wxUSE_FILESYSTEM
 
+    virtual void OnInternalIdle();
+
 protected:
     // this method must be implemented in the derived class and should return
     // the body (i.e. without <html>) of the HTML for the given item
@@ -108,9 +108,15 @@ protected:
     virtual void OnDrawItem(wxDC& dc, const wxRect& rect, size_t n) const;
     virtual wxCoord OnMeasureItem(size_t n) const;
 
+    // This method may be overriden to handle clicking on a link in
+    // the listbox. By default, clicking links is ignored.
+    virtual void OnLinkClicked(size_t WXUNUSED(n),
+                               const wxHtmlLinkInfo& WXUNUSED(link)) {}
 
     // event handlers
     void OnSize(wxSizeEvent& event);
+    void OnMouseMove(wxMouseEvent& event);
+    void OnLeftDown(wxMouseEvent& event);
 
 
     // common part of all ctors
@@ -119,6 +125,38 @@ protected:
     // ensure that the given item is cached
     void CacheItem(size_t n) const;
 
+private:
+    // wxHtmlWindowInterface methods:
+    virtual void SetHTMLWindowTitle(const wxString& title);
+    virtual void OnHTMLLinkClicked(const wxHtmlLinkInfo& link);
+    virtual wxHtmlOpeningStatus OnHTMLOpeningURL(wxHtmlURLType type,
+                                                 const wxString& url,
+                                                 wxString *redirect) const;
+    virtual wxPoint HTMLCoordsToWindow(wxHtmlCell *cell,
+                                       const wxPoint& pos) const;
+    virtual wxWindow* GetHTMLWindow();
+    virtual wxColour GetHTMLBackgroundColour() const;
+    virtual void SetHTMLBackgroundColour(const wxColour& clr);
+    virtual void SetHTMLBackgroundImage(const wxBitmap& bmpBg);
+    virtual void SetHTMLStatusText(const wxString& text);
+
+    // returns index of item that contains given HTML cell
+    size_t GetItemForCell(const wxHtmlCell *cell) const;
+
+    // return physical coordinates of root wxHtmlCell of n-th item
+    wxPoint GetRootCellCoords(size_t n) const;
+
+    // Converts physical coordinates stored in @a pos into coordinates
+    // relative to the root cell of the item under mouse cursor, if any. If no
+    // cell is found under the cursor, returns false.  Otherwise stores the new
+    // coordinates back into @a pos and pointer to the cell under cursor into
+    // @a cell and returns true.
+    bool PhysicalCoordsToCell(wxPoint& pos, wxHtmlCell*& cell) const;
+
+    // The opposite of PhysicalCoordsToCell: converts coordinates relative to
+    // given cell to physical coordinates in the window
+    wxPoint CellCoordsToPhysical(const wxPoint& pos, wxHtmlCell *cell) const;
+
 private:
     // this class caches the pre-parsed HTML to speed up display
     wxHtmlListBoxCache *m_cache;
@@ -137,6 +175,7 @@ private:
 
     // it calls our GetSelectedTextColour() and GetSelectedTextBgColour()
     friend class wxHtmlListBoxStyle;
+    friend class wxHtmlListBoxWinInterface;
 
 
     DECLARE_EVENT_TABLE()
index 419def086c366901d807e35190d8bced58af3968..0522932c5ec88584932985be2d390e99c95b1ec1 100644 (file)
@@ -77,6 +77,8 @@ protected:
     virtual void OnDrawSeparator(wxDC& dc, wxRect& rect, size_t n) const;
     virtual wxColour GetSelectedTextColour(const wxColour& colFg) const;
 
+    // override this method to handle mouse clicks
+    virtual void OnLinkClicked(size_t n, const wxHtmlLinkInfo& link);
 
     // flag telling us whether we should use fg colour even for the selected
     // item
@@ -85,6 +87,9 @@ protected:
     // flag which we toggle to update the first items text in OnGetItem()
     bool m_firstItemUpdated;
 
+    // flag which we toggle when the user clicks on the link in 2nd item
+    // to change 2nd item's text
+    bool m_linkClicked;
 
 
 #ifdef USE_HTML_FILE
@@ -423,6 +428,7 @@ MyHtmlListBox::MyHtmlListBox(wxWindow *parent, bool multi)
 {
     m_change = true;
     m_firstItemUpdated = false;
+    m_linkClicked = false;
 
 
     SetMargins(5, 5);
@@ -469,14 +475,23 @@ wxString MyHtmlListBox::OnGetItem(size_t n) const
     return s;
 #else
     int level = n % 6 + 1;
-    return wxString::Format(_T("<h%d><font color=#%2x%2x%2x>")
-                            _T("Item</font> <b>%lu</b>")
-                            _T("</h%d>"),
-                            level,
-                            abs((int)n - 192) % 256,
-                            abs((int)n - 256) % 256,
-                            abs((int)n - 128) % 256,
-                            (unsigned long)n, level);
+    wxString label = wxString::Format(_T("<h%d><font color=#%2x%2x%2x>")
+                                      _T("Item</font> <b>%lu</b>")
+                                      _T("</h%d>"),
+                                      level,
+                                      abs((int)n - 192) % 256,
+                                      abs((int)n - 256) % 256,
+                                      abs((int)n - 128) % 256,
+                                      (unsigned long)n, level);
+    if ( n == 1 )
+    {
+        if ( !m_linkClicked )
+            label += _T("<a href='1'>Click here...</a>");
+        else
+            label += _T("<font color='#9999ff'>Clicked here...</font>");
+    }
+
+    return label;
 #endif
 }
 
@@ -492,3 +507,10 @@ void MyHtmlListBox::UpdateFirstItem()
     RefreshLine(0);
 }
 
+void MyHtmlListBox::OnLinkClicked(size_t WXUNUSED(n),
+                                  const wxHtmlLinkInfo& WXUNUSED(link))
+{
+    m_linkClicked = true;
+
+    RefreshLine(1);
+}
index f6669cbfe978bf69d1043689dab60812500d0acd..c70d7b85f42e4dcfc1f0aba25a4bd20b75cb1423 100644 (file)
 #include "wx/html/forcelnk.h"
 FORCE_WXHTML_MODULES()
 
+// ----------------------------------------------------------------------------
+// constants
+// ----------------------------------------------------------------------------
+
+// small border always added to the cells:
+static const wxCoord CELL_BORDER = 2;
+
 // ============================================================================
 // private classes
 // ============================================================================
@@ -169,13 +176,14 @@ private:
     DECLARE_NO_COPY_CLASS(wxHtmlListBoxStyle)
 };
 
-
 // ----------------------------------------------------------------------------
 // event tables
 // ----------------------------------------------------------------------------
 
 BEGIN_EVENT_TABLE(wxHtmlListBox, wxVListBox)
     EVT_SIZE(wxHtmlListBox::OnSize)
+    EVT_MOTION(wxHtmlListBox::OnMouseMove)
+    EVT_LEFT_DOWN(wxHtmlListBox::OnLeftDown)
 END_EVENT_TABLE()
 
 // ============================================================================
@@ -189,6 +197,26 @@ IMPLEMENT_ABSTRACT_CLASS(wxHtmlListBox, wxVListBox)
 // wxHtmlListBox creation
 // ----------------------------------------------------------------------------
 
+wxHtmlListBox::wxHtmlListBox()
+    : wxHtmlWindowMouseHelper(this)
+{
+    Init();
+}
+
+// normal constructor which calls Create() internally
+wxHtmlListBox::wxHtmlListBox(wxWindow *parent,
+                             wxWindowID id,
+                             const wxPoint& pos,
+                             const wxSize& size,
+                             long style,
+                             const wxString& name)
+    : wxHtmlWindowMouseHelper(this)
+{
+    Init();
+
+    (void)Create(parent, id, pos, size, style, name);
+}
+
 void wxHtmlListBox::Init()
 {
     m_htmlParser = NULL;
@@ -259,7 +287,7 @@ void wxHtmlListBox::CacheItem(size_t n) const
         {
             wxHtmlListBox *self = wxConstCast(this, wxHtmlListBox);
 
-            self->m_htmlParser = new wxHtmlWinParser;
+            self->m_htmlParser = new wxHtmlWinParser(self);
             m_htmlParser->SetDC(new wxClientDC(self));
             m_htmlParser->SetFS(&self->m_filesystem);
 
@@ -271,6 +299,10 @@ void wxHtmlListBox::CacheItem(size_t n) const
                 Parse(OnGetItemMarkup(n));
         wxCHECK_RET( cell, _T("wxHtmlParser::Parse() returned NULL?") );
 
+        // set the cell's ID to item's index so that CellCoordsToPhysical()
+        // can quickly find the item:
+        cell->SetId(wxString::Format(_T("%u"), n));
+
         cell->Layout(GetClientSize().x - 2*GetMargins().x);
 
         m_cache->Store(n, cell);
@@ -341,7 +373,9 @@ void wxHtmlListBox::OnDrawItem(wxDC& dc, const wxRect& rect, size_t n) const
     // note that we can't stop drawing exactly at the window boundary as then
     // even the visible cells part could be not drawn, so always draw the
     // entire cell
-    cell->Draw(dc, rect.x+2, rect.y+2, 0, INT_MAX, htmlRendInfo);
+    cell->Draw(dc,
+               rect.x + CELL_BORDER, rect.y + CELL_BORDER,
+               0, INT_MAX, htmlRendInfo);
 }
 
 wxCoord wxHtmlListBox::OnMeasureItem(size_t n) const
@@ -354,5 +388,147 @@ wxCoord wxHtmlListBox::OnMeasureItem(size_t n) const
     return cell->GetHeight() + cell->GetDescent() + 4;
 }
 
-#endif // wxUSE_HTML
+// ----------------------------------------------------------------------------
+// wxHtmlListBox implementation of wxHtmlListBoxWinInterface
+// ----------------------------------------------------------------------------
+
+void wxHtmlListBox::SetHTMLWindowTitle(const wxString& WXUNUSED(title))
+{
+    // nothing to do
+}
+
+void wxHtmlListBox::OnHTMLLinkClicked(const wxHtmlLinkInfo& link)
+{
+    OnLinkClicked(GetItemForCell(link.GetHtmlCell()), link);
+}
+
+wxHtmlOpeningStatus
+wxHtmlListBox::OnHTMLOpeningURL(wxHtmlURLType WXUNUSED(type),
+                                const wxString& WXUNUSED(url),
+                                wxString *WXUNUSED(redirect)) const
+{
+    return wxHTML_OPEN;
+}
+
+wxPoint wxHtmlListBox::HTMLCoordsToWindow(wxHtmlCell *cell,
+                                          const wxPoint& pos) const
+{
+    return CellCoordsToPhysical(pos, cell);
+}
+
+wxWindow* wxHtmlListBox::GetHTMLWindow() { return this; }
+
+wxColour wxHtmlListBox::GetHTMLBackgroundColour() const
+{
+    return GetBackgroundColour();
+}
+
+void wxHtmlListBox::SetHTMLBackgroundColour(const wxColour& WXUNUSED(clr))
+{
+    // nothing to do
+}
+
+void wxHtmlListBox::SetHTMLBackgroundImage(const wxBitmap& WXUNUSED(bmpBg))
+{
+    // nothing to do
+}
+
+void wxHtmlListBox::SetHTMLStatusText(const wxString& WXUNUSED(text))
+{
+    // nothing to do
+}
+
+// ----------------------------------------------------------------------------
+// wxHtmlListBox handling of HTML links
+// ----------------------------------------------------------------------------
 
+wxPoint wxHtmlListBox::GetRootCellCoords(size_t n) const
+{
+    wxPoint pos(CELL_BORDER, CELL_BORDER);
+    pos += GetMargins();
+    pos.y += GetLinesHeight(GetFirstVisibleLine(), n);
+    return pos;
+}
+
+bool wxHtmlListBox::PhysicalCoordsToCell(wxPoint& pos, wxHtmlCell*& cell) const
+{
+    int n = HitTest(pos);
+    if ( n == wxNOT_FOUND )
+        return false;
+
+    // convert mouse coordinates to coords relative to item's wxHtmlCell:
+    pos -= GetRootCellCoords(n);
+
+    CacheItem(n);
+    cell = m_cache->Get(n);
+
+    return true;
+}
+
+size_t wxHtmlListBox::GetItemForCell(const wxHtmlCell *cell) const
+{
+    wxCHECK_MSG( cell, 0, _T("no cell") );
+
+    cell = cell->GetRootCell();
+
+    wxCHECK_MSG( cell, 0, _T("no root cell") );
+
+    // the cell's ID contains item index, see CacheItem():
+    unsigned long n;
+    if ( !cell->GetId().ToULong(&n) )
+    {
+        wxFAIL_MSG( _T("unexpected root cell's ID") );
+        return 0;
+    }
+
+    return n;
+}
+
+wxPoint
+wxHtmlListBox::CellCoordsToPhysical(const wxPoint& pos, wxHtmlCell *cell) const
+{
+    return pos + GetRootCellCoords(GetItemForCell(cell));
+}
+
+void wxHtmlListBox::OnInternalIdle()
+{
+    wxVListBox::OnInternalIdle();
+
+    if ( wxHtmlWindowMouseHelper::DidMouseMove() )
+    {
+        wxPoint pos = ScreenToClient(wxGetMousePosition());
+        wxHtmlCell *cell;
+
+        if ( !PhysicalCoordsToCell(pos, cell) )
+            return;
+
+        wxHtmlWindowMouseHelper::HandleIdle(cell, pos);
+    }
+}
+
+void wxHtmlListBox::OnMouseMove(wxMouseEvent& event)
+{
+    wxHtmlWindowMouseHelper::HandleMouseMoved();
+    event.Skip();
+}
+
+void wxHtmlListBox::OnLeftDown(wxMouseEvent& event)
+{
+    wxPoint pos = event.GetPosition();
+    wxHtmlCell *cell;
+
+    if ( !PhysicalCoordsToCell(pos, cell) )
+    {
+        event.Skip();
+        return;
+    }
+
+    if ( !wxHtmlWindowMouseHelper::HandleMouseClick(cell, pos, event) )
+    {
+        // no link was clicked, so let the listbox code handle the click (e.g.
+        // by selecting another item in the list):
+        event.Skip();
+    }
+}
+
+#endif // wxUSE_HTML
index 114097e2fae2d7d956f740a2fd333766bb1c6f3b..1b111b9aca04a98312dbe2d57f4415a8d46c299e 100644 (file)
@@ -117,19 +117,85 @@ void wxHtmlCell::SetScriptMode(wxHtmlScriptMode mode, long previousBase)
     m_Descent += m_ScriptBaseline;
 }
 
-void wxHtmlCell::OnMouseClick(wxWindow *parent, int x, int y,
-                              const wxMouseEvent& event)
+#if WXWIN_COMPATIBILITY_2_6
+
+struct wxHtmlCellOnMouseClickCompatHelper;
+
+static wxHtmlCellOnMouseClickCompatHelper *gs_helperOnMouseClick = NULL;
+
+// helper for routing calls to new ProcessMouseClick() method to deprecated
+// OnMouseClick() method
+struct wxHtmlCellOnMouseClickCompatHelper
+{
+    wxHtmlCellOnMouseClickCompatHelper(wxHtmlWindowInterface *window_,
+                                       const wxPoint& pos_,
+                                       const wxMouseEvent& event_)
+        : window(window_), pos(pos_), event(event_), retval(false)
+    {
+    }
+
+    bool CallOnMouseClick(wxHtmlCell *cell)
+    {
+        wxHtmlCellOnMouseClickCompatHelper *oldHelper = gs_helperOnMouseClick;
+        gs_helperOnMouseClick = this;
+        cell->OnMouseClick
+              (
+                window ? window->GetHTMLWindow() : NULL,
+                pos.x, pos.y,
+                event
+              );
+        gs_helperOnMouseClick = oldHelper;
+        return retval;
+    }
+
+    wxHtmlWindowInterface *window;
+    const wxPoint& pos;
+    const wxMouseEvent& event;
+    bool retval;
+};
+#endif // WXWIN_COMPATIBILITY_2_6
+
+bool wxHtmlCell::ProcessMouseClick(wxHtmlWindowInterface *window,
+                                   const wxPoint& pos,
+                                   const wxMouseEvent& event)
+{
+    wxCHECK_MSG( window, false, _T("window interface must be provided") );
+
+#if WXWIN_COMPATIBILITY_2_6
+    // NB: this hack puts the body of ProcessMouseClick() into OnMouseClick()
+    //     (for which it has to pass the arguments and return value via a
+    //     helper variable because these two methods have different
+    //     signatures), so that old code overriding OnMouseClick will continue
+    //     to work
+    wxHtmlCellOnMouseClickCompatHelper compat(window, pos, event);
+    return compat.CallOnMouseClick(this);
+}
+
+void wxHtmlCell::OnMouseClick(wxWindow *, int, int, const wxMouseEvent& event)
 {
-    wxHtmlLinkInfo *lnk = GetLink(x, y);
-    if (lnk != NULL)
+    wxCHECK_RET( gs_helperOnMouseClick, _T("unexpected call to OnMouseClick") );
+    wxHtmlWindowInterface *window = gs_helperOnMouseClick->window;
+    const wxPoint& pos = gs_helperOnMouseClick->pos;
+#endif // WXWIN_COMPATIBILITY_2_6
+
+    wxHtmlLinkInfo *lnk = GetLink(pos.x, pos.y);
+    bool retval = false;
+
+    if (lnk)
     {
         wxHtmlLinkInfo lnk2(*lnk);
         lnk2.SetEvent(&event);
         lnk2.SetHtmlCell(this);
 
-        // note : this cast is legal because parent is *always* wxHtmlWindow
-        wxStaticCast(parent, wxHtmlWindow)->OnLinkClicked(lnk2);
+        window->OnHTMLLinkClicked(lnk2);
+        retval = true;
     }
+
+#if WXWIN_COMPATIBILITY_2_6
+    gs_helperOnMouseClick->retval = retval;
+#else
+    return retval;
+#endif // WXWIN_COMPATIBILITY_2_6
 }
 
 
@@ -203,10 +269,11 @@ wxHtmlCell *wxHtmlCell::FindCellByPos(wxCoord x, wxCoord y,
 }
 
 
-wxPoint wxHtmlCell::GetAbsPos() const
+wxPoint wxHtmlCell::GetAbsPos(wxHtmlCell *rootCell) const
 {
     wxPoint p(m_PosX, m_PosY);
-    for (wxHtmlCell *parent = m_Parent; parent; parent = parent->m_Parent)
+    for (wxHtmlCell *parent = m_Parent; parent && parent != rootCell;
+         parent = parent->m_Parent)
     {
         p.x += parent->m_PosX;
         p.y += parent->m_PosY;
@@ -214,6 +281,14 @@ wxPoint wxHtmlCell::GetAbsPos() const
     return p;
 }
 
+wxHtmlCell *wxHtmlCell::GetRootCell() const
+{
+    wxHtmlCell *c = wxConstCast(this, wxHtmlCell);
+    while ( c->m_Parent )
+        c = c->m_Parent;
+    return c;
+}
+
 unsigned wxHtmlCell::GetDepth() const
 {
     unsigned d = 0;
@@ -1150,13 +1225,34 @@ wxHtmlCell *wxHtmlContainerCell::FindCellByPos(wxCoord x, wxCoord y,
 }
 
 
-void wxHtmlContainerCell::OnMouseClick(wxWindow *parent, int x, int y, const wxMouseEvent& event)
+bool wxHtmlContainerCell::ProcessMouseClick(wxHtmlWindowInterface *window,
+                                            const wxPoint& pos,
+                                            const wxMouseEvent& event)
 {
-    wxHtmlCell *cell = FindCellByPos(x, y);
-    if ( cell )
-        cell->OnMouseClick(parent, x, y, event);
+#if WXWIN_COMPATIBILITY_2_6
+    wxHtmlCellOnMouseClickCompatHelper compat(window, pos, event);
+    return compat.CallOnMouseClick(this);
 }
 
+void wxHtmlContainerCell::OnMouseClick(wxWindow*,
+                                       int, int, const wxMouseEvent& event)
+{
+    wxCHECK_RET( gs_helperOnMouseClick, _T("unexpected call to OnMouseClick") );
+    wxHtmlWindowInterface *window = gs_helperOnMouseClick->window;
+    const wxPoint& pos = gs_helperOnMouseClick->pos;
+#endif // WXWIN_COMPATIBILITY_2_6
+
+    bool retval = false;
+    wxHtmlCell *cell = FindCellByPos(pos.x, pos.y);
+    if ( cell )
+        retval = cell->ProcessMouseClick(window, pos, event);
+
+#if WXWIN_COMPATIBILITY_2_6
+    gs_helperOnMouseClick->retval = retval;
+#else
+    return retval;
+#endif // WXWIN_COMPATIBILITY_2_6
+}
 
 
 wxHtmlCell *wxHtmlContainerCell::GetFirstTerminal() const
index 7d71dd82d704afe31b391cd33ffe95ee870aac48..741e10fb62eab92a2736eee9d658166269192c45 100644 (file)
@@ -140,6 +140,104 @@ WX_DEFINE_OBJARRAY(wxHtmlHistoryArray)
 WX_DECLARE_LIST(wxHtmlProcessor, wxHtmlProcessorList);
 WX_DEFINE_LIST(wxHtmlProcessorList)
 
+//-----------------------------------------------------------------------------
+// wxHtmlWindowMouseHelper
+//-----------------------------------------------------------------------------
+
+wxHtmlWindowMouseHelper::wxHtmlWindowMouseHelper(wxHtmlWindowInterface *iface)
+    : m_tmpMouseMoved(false),
+      m_tmpLastLink(NULL),
+      m_tmpLastCell(NULL),
+      m_interface(iface)
+{
+}
+
+void wxHtmlWindowMouseHelper::HandleMouseMoved()
+{
+    m_tmpMouseMoved = true;
+}
+
+bool wxHtmlWindowMouseHelper::HandleMouseClick(wxHtmlCell *rootCell,
+                                               const wxPoint& pos,
+                                               const wxMouseEvent& event)
+{
+    if (!rootCell)
+        return false;
+
+    wxHtmlCell *cell = rootCell->FindCellByPos(pos.x, pos.y);
+    // this check is needed because FindCellByPos returns terminal cell and
+    // containers may have empty borders -- in this case NULL will be
+    // returned
+    if (!cell)
+        return false;
+
+    // adjust the coordinates to be relative to this cell:
+    wxPoint relpos = pos - cell->GetAbsPos(rootCell);
+
+    return OnCellClicked(cell, relpos.x, relpos.y, event);
+}
+
+void wxHtmlWindowMouseHelper::HandleIdle(wxHtmlCell *rootCell,
+                                         const wxPoint& pos)
+{
+    wxHtmlCell *cell = rootCell ? rootCell->FindCellByPos(pos.x, pos.y) : NULL;
+
+    if (cell != m_tmpLastCell)
+    {
+        wxHtmlLinkInfo *lnk = NULL;
+        if (cell)
+        {
+            // adjust the coordinates to be relative to this cell:
+            wxPoint relpos = pos - cell->GetAbsPos(rootCell);
+            lnk = cell->GetLink(relpos.x, relpos.y);
+        }
+
+        wxCursor cur;
+        if (cell)
+            cur = cell->GetCursor();
+        else
+            cur = *wxSTANDARD_CURSOR;
+        m_interface->GetHTMLWindow()->SetCursor(cur);
+
+        if (lnk != m_tmpLastLink)
+        {
+            if (lnk)
+                m_interface->SetHTMLStatusText(lnk->GetHref());
+            else
+                m_interface->SetHTMLStatusText(wxEmptyString);
+
+            m_tmpLastLink = lnk;
+        }
+
+        m_tmpLastCell = cell;
+    }
+    else // mouse moved but stayed in the same cell
+    {
+        if ( cell )
+        {
+            OnCellMouseHover(cell, pos.x, pos.y);
+        }
+    }
+
+    m_tmpMouseMoved = false;
+}
+
+bool wxHtmlWindowMouseHelper::OnCellClicked(wxHtmlCell *cell,
+                                            wxCoord x, wxCoord y,
+                                            const wxMouseEvent& event)
+{
+    wxCHECK_MSG( cell, false, _T("can't be called with NULL cell") );
+
+    return cell->ProcessMouseClick(m_interface, wxPoint(x, y), event);
+}
+
+void wxHtmlWindowMouseHelper::OnCellMouseHover(wxHtmlCell * WXUNUSED(cell),
+                                               wxCoord WXUNUSED(x),
+                                               wxCoord WXUNUSED(y))
+{
+    // do nothing here
+}
+
 //-----------------------------------------------------------------------------
 // wxHtmlWindow
 //-----------------------------------------------------------------------------
@@ -147,9 +245,6 @@ WX_DEFINE_LIST(wxHtmlProcessorList)
 
 void wxHtmlWindow::Init()
 {
-    m_tmpMouseMoved = false;
-    m_tmpLastLink = NULL;
-    m_tmpLastCell = NULL;
     m_tmpCanDrawLocks = 0;
     m_FS = new wxFileSystem();
 #if wxUSE_STATUSBAR
@@ -836,21 +931,6 @@ void wxHtmlWindow::OnLinkClicked(const wxHtmlLinkInfo& link)
         LoadPage(link.GetHref());
 }
 
-void wxHtmlWindow::OnCellClicked(wxHtmlCell *cell,
-                                 wxCoord x, wxCoord y,
-                                 const wxMouseEvent& event)
-{
-    wxCHECK_RET( cell, _T("can't be called with NULL cell") );
-
-    cell->OnMouseClick(this, x, y, event);
-}
-
-void wxHtmlWindow::OnCellMouseHover(wxHtmlCell * WXUNUSED(cell),
-                                    wxCoord WXUNUSED(x), wxCoord WXUNUSED(y))
-{
-    // do nothing here
-}
-
 void wxHtmlWindow::OnEraseBackground(wxEraseEvent& event)
 {
     if ( !m_bmpBg.Ok() )
@@ -994,7 +1074,7 @@ void wxHtmlWindow::OnSize(wxSizeEvent& event)
 
 void wxHtmlWindow::OnMouseMove(wxMouseEvent& WXUNUSED(event))
 {
-    m_tmpMouseMoved = true;
+    wxHtmlWindowMouseHelper::HandleMouseMoved();
 }
 
 void wxHtmlWindow::OnMouseDown(wxMouseEvent& event)
@@ -1048,17 +1128,9 @@ void wxHtmlWindow::OnMouseUp(wxMouseEvent& event)
 #endif // wxUSE_CLIPBOARD
 
     SetFocus();
-    if ( m_Cell )
-    {
-        wxPoint pos = CalcUnscrolledPosition(event.GetPosition());
-        wxHtmlCell *cell = m_Cell->FindCellByPos(pos.x, pos.y);
 
-        // check is needed because FindCellByPos returns terminal cell and
-        // containers may have empty borders -- in this case NULL will be
-        // returned
-        if ( cell )
-            OnCellClicked(cell, pos.x, pos.y, event);
-    }
+    wxPoint pos = CalcUnscrolledPosition(event.GetPosition());
+    wxHtmlWindowMouseHelper::HandleMouseClick(m_Cell, pos, event);
 }
 
 
@@ -1067,7 +1139,7 @@ void wxHtmlWindow::OnInternalIdle()
 {
     wxWindow::OnInternalIdle();
 
-    if (m_tmpMouseMoved && (m_Cell != NULL))
+    if (m_Cell != NULL && DidMouseMove())
     {
 #ifdef DEBUG_HTML_SELECTION
         Refresh();
@@ -1184,44 +1256,14 @@ void wxHtmlWindow::OnInternalIdle()
         }
 
         // handle cursor and status bar text changes:
-        if ( cell != m_tmpLastCell )
-        {
-            wxHtmlLinkInfo *lnk = cell ? cell->GetLink(x, y) : NULL;
-            wxCursor cur;
-            if (cell)
-                cur = cell->GetCursor();
-            else
-                cur = *wxSTANDARD_CURSOR;
-            SetCursor(cur);
-
-            if (lnk != m_tmpLastLink)
-            {
-#if wxUSE_STATUSBAR
-                if (lnk == NULL)
-                {
-                    if (m_RelatedStatusBar != -1)
-                        m_RelatedFrame->SetStatusText(wxEmptyString,
-                                                      m_RelatedStatusBar);
-                }
-                else
-                {
-                    if (m_RelatedStatusBar != -1)
-                        m_RelatedFrame->SetStatusText(lnk->GetHref(),
-                                                      m_RelatedStatusBar);
-                }
-#endif // wxUSE_STATUSBAR
-                m_tmpLastLink = lnk;
-            }
-
-            m_tmpLastCell = cell;
-        }
-        else // mouse moved but stayed in the same cell
-        {
-            if ( cell )
-                OnCellMouseHover(cell, x, y);
-        }
 
-        m_tmpMouseMoved = false;
+        // NB: because we're passing in 'cell' and not 'm_Cell' (so that the
+        //     leaf cell lookup isn't done twice), we need to adjust the
+        //     position for the new root:
+        wxPoint posInCell(x, y);
+        if (cell)
+            posInCell -= cell->GetAbsPos();
+        wxHtmlWindowMouseHelper::HandleIdle(cell, posInCell);
     }
 }
 
@@ -1460,9 +1502,65 @@ BEGIN_EVENT_TABLE(wxHtmlWindow, wxScrolledWindow)
 #endif // wxUSE_CLIPBOARD
 END_EVENT_TABLE()
 
+//-----------------------------------------------------------------------------
+// wxHtmlWindowInterface implementation in wxHtmlWindow
+//-----------------------------------------------------------------------------
+
+void wxHtmlWindow::SetHTMLWindowTitle(const wxString& title)
+{
+    OnSetTitle(title);
+}
+
+void wxHtmlWindow::OnHTMLLinkClicked(const wxHtmlLinkInfo& link)
+{
+    OnLinkClicked(link);
+}
+
+wxHtmlOpeningStatus wxHtmlWindow::OnHTMLOpeningURL(wxHtmlURLType type,
+                                                   const wxString& url,
+                                                   wxString *redirect) const
+{
+    return OnOpeningURL(type, url, redirect);
+}
+
+wxPoint wxHtmlWindow::HTMLCoordsToWindow(wxHtmlCell *WXUNUSED(cell),
+                                         const wxPoint& pos) const
+{
+    return CalcScrolledPosition(pos);
+}
+
+wxWindow* wxHtmlWindow::GetHTMLWindow()
+{
+    return this;
+}
+
+wxColour wxHtmlWindow::GetHTMLBackgroundColour() const
+{
+    return GetBackgroundColour();
+}
+
+void wxHtmlWindow::SetHTMLBackgroundColour(const wxColour& clr)
+{
+    SetBackgroundColour(clr);
+}
+
+void wxHtmlWindow::SetHTMLBackgroundImage(const wxBitmap& bmpBg)
+{
+    SetBackgroundImage(bmpBg);
+}
 
+void wxHtmlWindow::SetHTMLStatusText(const wxString& text)
+{
+#if wxUSE_STATUSBAR
+    if (m_RelatedStatusBar != -1)
+        m_RelatedFrame->SetStatusText(text, m_RelatedStatusBar);
+#endif // wxUSE_STATUSBAR
+}
 
 
+//-----------------------------------------------------------------------------
+// wxHtmlWinModule
+//-----------------------------------------------------------------------------
 
 // A module to allow initialization/cleanup
 // without calling these functions from app.cpp or from
index b6a1bc636dc3123e08a8ce6ea9976c7736961e18..63054b25448177cf1e0e70023a805c17409dcc33 100644 (file)
@@ -45,7 +45,7 @@ wxHtmlDCRenderer::wxHtmlDCRenderer() : wxObject()
     m_DC = NULL;
     m_Width = m_Height = 0;
     m_Cells = NULL;
-    m_Parser = new wxHtmlWinParser(NULL);
+    m_Parser = new wxHtmlWinParser();
     m_FS = new wxFileSystem();
     m_Parser->SetFS(m_FS);
 }
index 9574b94d419f67bff8df8aec43db7a7de550653d..3182825232c8a74555aeab252888dcb6b59aaea8 100644 (file)
@@ -286,7 +286,7 @@ const wxHtmlCell *wxHtmlImageMapCell::Find( int cond, const void *param ) const
 class wxHtmlImageCell : public wxHtmlCell
 {
 public:
-    wxHtmlImageCell(wxWindow *window,
+    wxHtmlImageCell(wxHtmlWindowInterface *windowIface,
                     wxFSFile *input, int w = wxDefaultCoord, int h = wxDefaultCoord,
                     double scale = 1.0, int align = wxHTML_ALIGN_BOTTOM,
                     const wxString& mapname = wxEmptyString);
@@ -305,7 +305,7 @@ private:
     wxBitmap           *m_bitmap;
     int                 m_bmpW, m_bmpH;
     bool                m_showFrame:1;
-    wxScrolledWindow   *m_window;
+    wxHtmlWindowInterface *m_windowIface;
 #if wxUSE_GIF && wxUSE_TIMER
     wxGIFDecoder       *m_gifDecoder;
     wxTimer            *m_gifTimer;
@@ -341,11 +341,12 @@ class wxGIFTimer : public wxTimer
 //----------------------------------------------------------------------------
 
 
-wxHtmlImageCell::wxHtmlImageCell(wxWindow *window, wxFSFile *input,
+wxHtmlImageCell::wxHtmlImageCell(wxHtmlWindowInterface *windowIface,
+                                 wxFSFile *input,
                                  int w, int h, double scale, int align,
                                  const wxString& mapname) : wxHtmlCell()
 {
-    m_window = window ? wxStaticCast(window, wxScrolledWindow) : NULL;
+    m_windowIface = windowIface;
     m_scale = scale;
     m_showFrame = false;
     m_bitmap = NULL;
@@ -370,8 +371,9 @@ wxHtmlImageCell::wxHtmlImageCell(wxWindow *window, wxFSFile *input,
             {
 #if wxUSE_GIF && wxUSE_TIMER
                 bool readImg = true;
-                if ( (input->GetLocation().Matches(wxT("*.gif")) ||
-                      input->GetLocation().Matches(wxT("*.GIF"))) && m_window )
+                if ( m_windowIface &&
+                     (input->GetLocation().Matches(wxT("*.gif")) ||
+                      input->GetLocation().Matches(wxT("*.GIF"))) )
                 {
                     m_gifDecoder = new wxGIFDecoder(s, true);
                     if ( m_gifDecoder->ReadGIF() == wxGIF_OK )
@@ -492,11 +494,12 @@ void wxHtmlImageCell::AdvanceAnimation(wxTimer *timer)
         }
     }
 
-    int x, y;
-    m_window->CalcScrolledPosition(m_physX, m_physY, &x, &y);
-    wxRect rect(x, y, m_Width, m_Height);
+    wxWindow *win = m_windowIface->GetHTMLWindow();
+    wxPoint pos =
+        m_windowIface->HTMLCoordsToWindow(this, wxPoint(m_physX, m_physY));
+    wxRect rect(pos, wxSize(m_Width, m_Height));
 
-    if ( m_window->GetClientRect().Intersects(rect) &&
+    if ( win->GetClientRect().Intersects(rect) &&
          m_gifDecoder->ConvertToImage(&img) )
     {
 #if !defined(__WXMSW__) || wxUSE_WXDIB
@@ -511,9 +514,9 @@ void wxHtmlImageCell::AdvanceAnimation(wxTimer *timer)
                           true /* use mask */);
         }
         else
-#endif            
+#endif
             SetImage(img);
-        m_window->Refresh(img.HasMask(), &rect);
+        win->Refresh(img.HasMask(), &rect);
     }
 
     timer->Start(m_gifDecoder->GetDelay(), true);
@@ -645,7 +648,7 @@ TAG_HANDLER_BEGIN(IMG, "IMG,MAP,AREA")
                     }
                 }
                 wxHtmlImageCell *cel = new wxHtmlImageCell(
-                                          m_WParser->GetWindow(),
+                                          m_WParser->GetWindowInterface(),
                                           str, w, h,
                                           m_WParser->GetPixelScale(),
                                           al, mn);
index d9d76f6f6ffe1769010a184ab1595afc99138bbc..0bc14503f754b3c70c4ed522d31a531bc6061373 100644 (file)
@@ -289,21 +289,19 @@ TAG_HANDLER_BEGIN(TITLE, "TITLE")
 
     TAG_HANDLER_PROC(tag)
     {
-        if (m_WParser->GetWindow())
+        wxHtmlWindowInterface *winIface = m_WParser->GetWindowInterface();
+        if (winIface)
         {
-            wxHtmlWindow *wfr = (wxHtmlWindow*)(m_WParser->GetWindow());
-            if (wfr)
-            {
-                wxString title = m_WParser->GetSource()->Mid(
-                                        tag.GetBeginPos(),
-                                        tag.GetEndPos1()-tag.GetBeginPos());
+            wxString title = m_WParser->GetSource()->Mid(
+                                    tag.GetBeginPos(),
+                                    tag.GetEndPos1()-tag.GetBeginPos());
 #if !wxUSE_UNICODE && wxUSE_WCHAR_T
-                wxCSConv conv(m_WParser->GetInputEncoding());
-                title = wxString(title.wc_str(conv), wxConvLocal);
+            wxCSConv conv(m_WParser->GetInputEncoding());
+            title = wxString(title.wc_str(conv), wxConvLocal);
 #endif
-                title = m_WParser->GetEntitiesParser()->Parse(title);
-                wfr->OnSetTitle(title);
-            }
+            title = m_WParser->GetEntitiesParser()->Parse(title);
+
+            winIface->SetHTMLWindowTitle(title);
         }
         return true;
     }
@@ -329,6 +327,11 @@ TAG_HANDLER_BEGIN(BODY, "BODY")
         if (tag.GetParamAsColour(wxT("LINK"), &clr))
             m_WParser->SetLinkColor(clr);
 
+        wxHtmlWindowInterface *winIface = m_WParser->GetWindowInterface();
+        // the rest of this function requires a window:
+        if ( !winIface )
+            return false;
+
         if (tag.HasParam(wxT("BACKGROUND")))
         {
             wxFSFile *fileBgImage = m_WParser->OpenURL
@@ -344,8 +347,8 @@ TAG_HANDLER_BEGIN(BODY, "BODY")
 #if !defined(__WXMSW__) || wxUSE_WXDIB
                     wxImage image(*is);
                     if ( image.Ok() )
-                        m_WParser->GetWindow()->SetBackgroundImage(image);
-#endif                    
+                        winIface->SetHTMLBackgroundImage(image);
+#endif
                 }
             }
         }
@@ -354,8 +357,7 @@ TAG_HANDLER_BEGIN(BODY, "BODY")
         {
             m_WParser->GetContainer()->InsertCell(
                 new wxHtmlColourCell(clr, wxHTML_CLR_BACKGROUND));
-            if (m_WParser->GetWindow() != NULL)
-                m_WParser->GetWindow()->SetBackgroundColour(clr);
+            winIface->SetHTMLBackgroundColour(clr);
         }
 
         return false;
index 265572a844d0748004df5bd22033cd9d10548790..352ba3e0cc52f560198e46915b4b83d85419f012 100644 (file)
@@ -38,11 +38,11 @@ IMPLEMENT_ABSTRACT_CLASS(wxHtmlWinParser, wxHtmlParser)
 
 wxList wxHtmlWinParser::m_Modules;
 
-wxHtmlWinParser::wxHtmlWinParser(wxHtmlWindow *wnd) : wxHtmlParser()
+wxHtmlWinParser::wxHtmlWinParser(wxHtmlWindowInterface *wndIface)
 {
     m_tmpStrBuf = NULL;
     m_tmpStrBufSize = 0;
-    m_Window = wnd;
+    m_windowInterface = wndIface;
     m_Container = NULL;
     m_DC = NULL;
     m_CharHeight = m_CharWidth = 0;
@@ -212,11 +212,18 @@ void wxHtmlWinParser::InitParser(const wxString& source)
 
     m_Container->InsertCell(new wxHtmlColourCell(m_ActualColor));
     wxColour windowColour = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW) ;
-    m_Container->InsertCell(
-            new wxHtmlColourCell(GetWindow() ?
-                                     GetWindow()->GetBackgroundColour() :
-                                     windowColour,
-                                 wxHTML_CLR_BACKGROUND));
+
+    m_Container->InsertCell
+                 (
+                   new wxHtmlColourCell
+                       (
+                         m_windowInterface
+                            ? m_windowInterface->GetHTMLBackgroundColour()
+                            : windowColour,
+                         wxHTML_CLR_BACKGROUND
+                       )
+                  );
+
     m_Container->InsertCell(new wxHtmlFontCell(CreateCurrentFont()));
 }
 
@@ -229,6 +236,15 @@ void wxHtmlWinParser::DoneParser()
     wxHtmlParser::DoneParser();
 }
 
+#if WXWIN_COMPATIBILITY_2_6
+wxHtmlWindow *wxHtmlWinParser::GetWindow()
+{
+    if (!m_windowInterface)
+        return NULL;
+    return wxDynamicCast(m_windowInterface->GetHTMLWindow(), wxHtmlWindow);
+}
+#endif
+
 wxObject* wxHtmlWinParser::GetProduct()
 {
     wxHtmlContainerCell *top;
@@ -246,58 +262,56 @@ wxObject* wxHtmlWinParser::GetProduct()
 wxFSFile *wxHtmlWinParser::OpenURL(wxHtmlURLType type,
                                    const wxString& url) const
 {
-    if ( m_Window )
+    if ( !m_windowInterface )
+        return wxHtmlParser::OpenURL(type, url);
+
+    wxString myurl(url);
+    wxHtmlOpeningStatus status;
+    for (;;)
     {
-        wxString myurl(url);
-        wxHtmlOpeningStatus status;
-        for (;;)
-        {
-            wxString myfullurl(myurl);
+        wxString myfullurl(myurl);
 
-            // consider url as absolute path first
-            wxURI current(myurl);
-            myfullurl = current.BuildUnescapedURI();
+        // consider url as absolute path first
+        wxURI current(myurl);
+        myfullurl = current.BuildUnescapedURI();
 
-            // if not absolute then ...
-            if( current.IsReference() )
-            {
-                wxString basepath = GetFS()->GetPath();
-                wxURI base(basepath);
+        // if not absolute then ...
+        if( current.IsReference() )
+        {
+            wxString basepath = GetFS()->GetPath();
+            wxURI base(basepath);
 
-                // ... try to apply base path if valid ...
-                if( !base.IsReference() )
-                {
-                    wxURI path(myfullurl);
-                    path.Resolve( base );
-                    myfullurl = path.BuildUnescapedURI();
-                }
-                else
+            // ... try to apply base path if valid ...
+            if( !base.IsReference() )
+            {
+                wxURI path(myfullurl);
+                path.Resolve( base );
+                myfullurl = path.BuildUnescapedURI();
+            }
+            else
+            {
+                // ... or force such addition if not included already
+                if( !current.GetPath().Contains(base.GetPath()) )
                 {
-                    // ... or force such addition if not included already
-                    if( !current.GetPath().Contains(base.GetPath()) )
-                    {
-                        basepath += myurl;
-                        wxURI connected( basepath );
-                        myfullurl = connected.BuildUnescapedURI();
-                    }
+                    basepath += myurl;
+                    wxURI connected( basepath );
+                    myfullurl = connected.BuildUnescapedURI();
                 }
             }
-
-            wxString redirect;
-            status = m_Window->OnOpeningURL(type, myfullurl, &redirect);
-            if ( status != wxHTML_REDIRECT )
-                break;
-
-            myurl = redirect;
         }
 
-        if ( status == wxHTML_BLOCK )
-            return NULL;
+        wxString redirect;
+        status = m_windowInterface->OnHTMLOpeningURL(type, myfullurl, &redirect);
+        if ( status != wxHTML_REDIRECT )
+            break;
 
-        return GetFS()->OpenFile(myurl);
+        myurl = redirect;
     }
 
-    return wxHtmlParser::OpenURL(type, url);
+    if ( status == wxHTML_BLOCK )
+        return NULL;
+
+    return GetFS()->OpenFile(myurl);
 }
 
 void wxHtmlWinParser::AddText(const wxChar* txt)