1. added abstract interface to wxHtmlWindow for use by wxHtmlWinParser and implemented it for wxHtmlListBox

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
This commit is contained in:
Václav Slavík
2006-04-13 22:08:28 +00:00
parent e0d5d9af8b
commit bc55e31bdc
17 changed files with 881 additions and 219 deletions

View File

@@ -13,6 +13,11 @@ INCOMPATIBLE CHANGES SINCE 2.6.x
- wxCHECK family of macros now must be followed by a semicolon - wxCHECK family of macros now must be followed by a semicolon
- wxMBConv::cMB2WC() and cWC2MB() take size of the input buffer and return - wxMBConv::cMB2WC() and cWC2MB() take size of the input buffer and return
length of the converted string in all cases now. 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 Deprecated methods since 2.6.x and their replacements
@@ -111,6 +116,8 @@ All (GUI):
- Added wxListBox::HitTest(). - Added wxListBox::HitTest().
- Added wxDisplay::GetClientArea(). - Added wxDisplay::GetClientArea().
- Indices and counts in wxControlWithItems derived API are unsigned. - 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: wxMSW:

View File

@@ -223,13 +223,14 @@ It must be called before displaying cells structure because
m\_PosX and m\_PosY are undefined (or invalid) m\_PosX and m\_PosY are undefined (or invalid)
before calling Layout. 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 This function is simple event handler. Each time the user clicks mouse button
within \helpref{wxHtmlWindow}{wxhtmlwindow} this method of that cell is called. Default behavior is over a cell within \helpref{wxHtmlWindow}{wxhtmlwindow} this method of that
that it calls \helpref{wxHtmlWindow::LoadPage}{wxhtmlwindowloadpage}. cell is called. Default behavior is to call
\helpref{wxHtmlWindow::LoadPage}{wxhtmlwindowloadpage}.
\wxheading{Note} \wxheading{Note}
@@ -238,12 +239,15 @@ you should use wxHtmlBinderCell instead.
\wxheading{Parameters} \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 \docparam{event}{mouse event that triggered the call}
button is pressed, false otherwise}
\wxheading{Return value}
\true if a link was clicked, \false otherwise.
\membersection{wxHtmlCell::SetId}\label{wxhtmlcellsetid} \membersection{wxHtmlCell::SetId}\label{wxhtmlcellsetid}

View File

@@ -127,3 +127,18 @@ for the given item.
This function may be overridden to decorate HTML returned by This function may be overridden to decorate HTML returned by
\helpref{OnGetItem()}{wxhtmllistboxongetitem}. \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}.

View File

@@ -197,7 +197,7 @@ false if an error occurred, true otherwise
\membersection{wxHtmlWindow::OnCellClicked}\label{wxhtmlwindowoncellclicked} \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. This method is called when a mouse button is clicked inside wxHtmlWindow.
The default behaviour is to call The default behaviour is to call
@@ -213,6 +213,10 @@ hypertext link.
\docparam{event}{The mouse event containing other information about the click} \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} \membersection{wxHtmlWindow::OnCellMouseHover}\label{wxhtmlwindowoncellmousehover}
\func{virtual void}{OnCellMouseHover}{\param{wxHtmlCell }{*cell}, \param{wxCoord }{x}, \param{wxCoord }{y}} \func{virtual void}{OnCellMouseHover}{\param{wxHtmlCell }{*cell}, \param{wxCoord }{x}, \param{wxCoord }{y}}

View File

@@ -32,10 +32,12 @@ The product of parsing is a wxHtmlCell (resp. wxHtmlContainer) object.
\func{}{wxHtmlWinParser}{\void} \func{}{wxHtmlWinParser}{\void}
\func{}{wxHtmlWinParser}{\param{wxHtmlWindow }{*wnd}} \func{}{wxHtmlWinParser}{\param{wxHtmlWindowInterface }{*wndIface}}
Constructor. Don't use the default one, use constructor with 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} \membersection{wxHtmlWinParser::AddModule}\label{wxhtmlwinparseraddmodule}

View File

@@ -20,6 +20,7 @@
#include "wx/window.h" #include "wx/window.h"
class WXDLLIMPEXP_HTML wxHtmlWindowInterface;
class WXDLLIMPEXP_HTML wxHtmlLinkInfo; class WXDLLIMPEXP_HTML wxHtmlLinkInfo;
class WXDLLIMPEXP_HTML wxHtmlCell; class WXDLLIMPEXP_HTML wxHtmlCell;
class WXDLLIMPEXP_HTML wxHtmlContainerCell; class WXDLLIMPEXP_HTML wxHtmlContainerCell;
@@ -244,12 +245,23 @@ public:
// returns pointer to anchor news // returns pointer to anchor news
virtual const wxHtmlCell* Find(int condition, const void* param) const; virtual const wxHtmlCell* Find(int condition, const void* param) const;
// This function is called when mouse button is clicked over the cell. // 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 // HINT: if this handling is not enough for you you should use
// wxHtmlWidgetCell // 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 // This method used to adjust pagebreak position. The parameter is variable
// that contains y-coordinate of page break (= horizontal line that should // that contains y-coordinate of page break (= horizontal line that should
@@ -283,8 +295,14 @@ public:
virtual wxHtmlCell *FindCellByPos(wxCoord x, wxCoord y, virtual wxHtmlCell *FindCellByPos(wxCoord x, wxCoord y,
unsigned flags = wxHTML_FIND_EXACT) const; unsigned flags = wxHTML_FIND_EXACT) const;
// Returns absolute position of the cell on HTML canvas // Returns absolute position of the cell on HTML canvas.
wxPoint GetAbsPos() const; // 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, // 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. // 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;} 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 wxHtmlLinkInfo* GetLink(int x = 0, int y = 0) const;
virtual const wxHtmlCell* Find(int condition, const void* param) 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; } virtual wxHtmlCell* GetFirstChild() const { return m_Cells; }
#if WXWIN_COMPATIBILITY_2_4 #if WXWIN_COMPATIBILITY_2_4

View File

@@ -38,15 +38,163 @@ class WXDLLIMPEXP_HTML wxHtmlWinAutoScrollTimer;
#define wxHW_DEFAULT_STYLE wxHW_SCROLLBAR_AUTO #define wxHW_DEFAULT_STYLE wxHW_SCROLLBAR_AUTO
/// Enum for wxHtmlWindow::OnOpeningURL and wxHtmlWindowInterface::OnOpeningURL
// enums for wxHtmlWindow::OnOpeningURL
enum wxHtmlOpeningStatus enum wxHtmlOpeningStatus
{ {
/// Open the requested URL
wxHTML_OPEN, wxHTML_OPEN,
/// Do not open the URL
wxHTML_BLOCK, wxHTML_BLOCK,
/// Redirect to another URL (returned from OnOpeningURL)
wxHTML_REDIRECT 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 // wxHtmlWindow
// (This is probably the only class you will directly use.) // (This is probably the only class you will directly use.)
@@ -58,18 +206,21 @@ enum wxHtmlOpeningStatus
// SetPage(text) or LoadPage(filename). // 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) DECLARE_DYNAMIC_CLASS(wxHtmlWindow)
friend class wxHtmlWinModule; friend class wxHtmlWinModule;
public: public:
wxHtmlWindow() { Init(); } wxHtmlWindow() : wxHtmlWindowMouseHelper(this) { Init(); }
wxHtmlWindow(wxWindow *parent, wxWindowID id = wxID_ANY, wxHtmlWindow(wxWindow *parent, wxWindowID id = wxID_ANY,
const wxPoint& pos = wxDefaultPosition, const wxPoint& pos = wxDefaultPosition,
const wxSize& size = wxDefaultSize, const wxSize& size = wxDefaultSize,
long style = wxHW_DEFAULT_STYLE, long style = wxHW_DEFAULT_STYLE,
const wxString& name = wxT("htmlWindow")) const wxString& name = wxT("htmlWindow"))
: wxHtmlWindowMouseHelper(this)
{ {
Init(); Init();
Create(parent, id, pos, size, style, name); Create(parent, id, pos, size, style, name);
@@ -178,16 +329,6 @@ public:
// (depending on the information passed to SetRelatedFrame() method) // (depending on the information passed to SetRelatedFrame() method)
virtual void OnSetTitle(const wxString& title); 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 // Called when user clicked on hypertext link. Default behavior is to
// call LoadPage(loc) // call LoadPage(loc)
virtual void OnLinkClicked(const wxHtmlLinkInfo& link); virtual void OnLinkClicked(const wxHtmlLinkInfo& link);
@@ -216,6 +357,7 @@ public:
virtual void OnInternalIdle(); virtual void OnInternalIdle();
protected: protected:
void Init(); void Init();
@@ -272,6 +414,20 @@ protected:
wxString DoSelectionToText(wxHtmlSelection *sel); wxString DoSelectionToText(wxHtmlSelection *sel);
private: 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() // implementation of SetPage()
bool DoSetPage(const wxString& source); bool DoSetPage(const wxString& source);
@@ -333,10 +489,6 @@ private:
wxPoint m_tmpSelFromPos; wxPoint m_tmpSelFromPos;
wxHtmlCell *m_tmpSelFromCell; 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 // if >0 contents of the window is not redrawn
// (in order to avoid ugly blinking) // (in order to avoid ugly blinking)
int m_tmpCanDrawLocks; int m_tmpCanDrawLocks;
@@ -356,10 +508,6 @@ private:
// if this FLAG is false, items are not added to history // if this FLAG is false, items are not added to history
bool m_HistoryOn; 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 // a flag set if we need to erase background in OnPaint() (otherwise this
// is supposed to have been done in OnEraseBackground()) // is supposed to have been done in OnEraseBackground())
bool m_eraseBgInOnPaint; bool m_eraseBgInOnPaint;

View File

@@ -20,10 +20,12 @@
#include "wx/encconv.h" #include "wx/encconv.h"
class WXDLLIMPEXP_HTML wxHtmlWindow; class WXDLLIMPEXP_HTML wxHtmlWindow;
class WXDLLIMPEXP_HTML wxHtmlWindowInterface;
class WXDLLIMPEXP_HTML wxHtmlWinParser; class WXDLLIMPEXP_HTML wxHtmlWinParser;
class WXDLLIMPEXP_HTML wxHtmlWinTagHandler; class WXDLLIMPEXP_HTML wxHtmlWinTagHandler;
class WXDLLIMPEXP_HTML wxHtmlTagsModule; class WXDLLIMPEXP_HTML wxHtmlTagsModule;
//-------------------------------------------------------------------------------- //--------------------------------------------------------------------------------
// wxHtmlWinParser // wxHtmlWinParser
// This class is derived from wxHtmlParser and its mail goal // This class is derived from wxHtmlParser and its mail goal
@@ -37,7 +39,8 @@ class WXDLLIMPEXP_HTML wxHtmlWinParser : public wxHtmlParser
friend class wxHtmlWindow; friend class wxHtmlWindow;
public: public:
wxHtmlWinParser(wxHtmlWindow *wnd = NULL); wxHtmlWinParser(wxHtmlWindowInterface *wndIface = NULL);
~wxHtmlWinParser(); ~wxHtmlWinParser();
virtual void InitParser(const wxString& source); virtual void InitParser(const wxString& source);
@@ -62,7 +65,10 @@ public:
// GetDC()->GetChar...() // GetDC()->GetChar...()
// returns associated wxWindow // 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). // 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); void SetFonts(const wxString& normal_face, const wxString& fixed_face, const int *sizes = NULL);
@@ -148,7 +154,7 @@ private:
wxChar *m_tmpStrBuf; wxChar *m_tmpStrBuf;
size_t m_tmpStrBufSize; size_t m_tmpStrBufSize;
// temporary variables used by AddText // temporary variables used by AddText
wxHtmlWindow *m_Window; wxHtmlWindowInterface *m_windowInterface;
// window we're parsing for // window we're parsing for
double m_PixelScale; double m_PixelScale;
wxDC *m_DC; wxDC *m_DC;

View File

@@ -13,6 +13,7 @@
#define _WX_HTMLLBOX_H_ #define _WX_HTMLLBOX_H_
#include "wx/vlbox.h" // base class #include "wx/vlbox.h" // base class
#include "wx/html/htmlwin.h"
#if wxUSE_FILESYSTEM #if wxUSE_FILESYSTEM
#include "wx/filesys.h" #include "wx/filesys.h"
@@ -27,7 +28,9 @@ class WXDLLIMPEXP_HTML wxHtmlListBoxStyle;
// wxHtmlListBox // wxHtmlListBox
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
class WXDLLIMPEXP_HTML wxHtmlListBox : public wxVListBox class WXDLLIMPEXP_HTML wxHtmlListBox : public wxVListBox,
public wxHtmlWindowInterface,
private wxHtmlWindowMouseHelper
{ {
DECLARE_ABSTRACT_CLASS(wxHtmlListBox) DECLARE_ABSTRACT_CLASS(wxHtmlListBox)
public: public:
@@ -35,7 +38,7 @@ public:
// --------------------- // ---------------------
// default constructor, you must call Create() later // default constructor, you must call Create() later
wxHtmlListBox() { Init(); } wxHtmlListBox();
// normal constructor which calls Create() internally // normal constructor which calls Create() internally
wxHtmlListBox(wxWindow *parent, wxHtmlListBox(wxWindow *parent,
@@ -43,12 +46,7 @@ public:
const wxPoint& pos = wxDefaultPosition, const wxPoint& pos = wxDefaultPosition,
const wxSize& size = wxDefaultSize, const wxSize& size = wxDefaultSize,
long style = 0, long style = 0,
const wxString& name = wxVListBoxNameStr) const wxString& name = wxVListBoxNameStr);
{
Init();
(void)Create(parent, id, pos, size, style, name);
}
// really creates the control and sets the initial number of items in it // really creates the control and sets the initial number of items in it
// (which may be changed later with SetItemCount()) // (which may be changed later with SetItemCount())
@@ -80,6 +78,8 @@ public:
const wxFileSystem& GetFileSystem() const { return m_filesystem; } const wxFileSystem& GetFileSystem() const { return m_filesystem; }
#endif // wxUSE_FILESYSTEM #endif // wxUSE_FILESYSTEM
virtual void OnInternalIdle();
protected: protected:
// this method must be implemented in the derived class and should return // 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 // 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 void OnDrawItem(wxDC& dc, const wxRect& rect, size_t n) const;
virtual wxCoord OnMeasureItem(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 // event handlers
void OnSize(wxSizeEvent& event); void OnSize(wxSizeEvent& event);
void OnMouseMove(wxMouseEvent& event);
void OnLeftDown(wxMouseEvent& event);
// common part of all ctors // common part of all ctors
@@ -119,6 +125,38 @@ protected:
// ensure that the given item is cached // ensure that the given item is cached
void CacheItem(size_t n) const; 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: private:
// this class caches the pre-parsed HTML to speed up display // this class caches the pre-parsed HTML to speed up display
wxHtmlListBoxCache *m_cache; wxHtmlListBoxCache *m_cache;
@@ -137,6 +175,7 @@ private:
// it calls our GetSelectedTextColour() and GetSelectedTextBgColour() // it calls our GetSelectedTextColour() and GetSelectedTextBgColour()
friend class wxHtmlListBoxStyle; friend class wxHtmlListBoxStyle;
friend class wxHtmlListBoxWinInterface;
DECLARE_EVENT_TABLE() DECLARE_EVENT_TABLE()

View File

@@ -77,6 +77,8 @@ protected:
virtual void OnDrawSeparator(wxDC& dc, wxRect& rect, size_t n) const; virtual void OnDrawSeparator(wxDC& dc, wxRect& rect, size_t n) const;
virtual wxColour GetSelectedTextColour(const wxColour& colFg) 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 // flag telling us whether we should use fg colour even for the selected
// item // item
@@ -85,6 +87,9 @@ protected:
// flag which we toggle to update the first items text in OnGetItem() // flag which we toggle to update the first items text in OnGetItem()
bool m_firstItemUpdated; 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 #ifdef USE_HTML_FILE
@@ -423,6 +428,7 @@ MyHtmlListBox::MyHtmlListBox(wxWindow *parent, bool multi)
{ {
m_change = true; m_change = true;
m_firstItemUpdated = false; m_firstItemUpdated = false;
m_linkClicked = false;
SetMargins(5, 5); SetMargins(5, 5);
@@ -469,7 +475,7 @@ wxString MyHtmlListBox::OnGetItem(size_t n) const
return s; return s;
#else #else
int level = n % 6 + 1; int level = n % 6 + 1;
return wxString::Format(_T("<h%d><font color=#%2x%2x%2x>") wxString label = wxString::Format(_T("<h%d><font color=#%2x%2x%2x>")
_T("Item</font> <b>%lu</b>") _T("Item</font> <b>%lu</b>")
_T("</h%d>"), _T("</h%d>"),
level, level,
@@ -477,6 +483,15 @@ wxString MyHtmlListBox::OnGetItem(size_t n) const
abs((int)n - 256) % 256, abs((int)n - 256) % 256,
abs((int)n - 128) % 256, abs((int)n - 128) % 256,
(unsigned long)n, level); (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 #endif
} }
@@ -492,3 +507,10 @@ void MyHtmlListBox::UpdateFirstItem()
RefreshLine(0); RefreshLine(0);
} }
void MyHtmlListBox::OnLinkClicked(size_t WXUNUSED(n),
const wxHtmlLinkInfo& WXUNUSED(link))
{
m_linkClicked = true;
RefreshLine(1);
}

View File

@@ -39,6 +39,13 @@
#include "wx/html/forcelnk.h" #include "wx/html/forcelnk.h"
FORCE_WXHTML_MODULES() FORCE_WXHTML_MODULES()
// ----------------------------------------------------------------------------
// constants
// ----------------------------------------------------------------------------
// small border always added to the cells:
static const wxCoord CELL_BORDER = 2;
// ============================================================================ // ============================================================================
// private classes // private classes
// ============================================================================ // ============================================================================
@@ -169,13 +176,14 @@ private:
DECLARE_NO_COPY_CLASS(wxHtmlListBoxStyle) DECLARE_NO_COPY_CLASS(wxHtmlListBoxStyle)
}; };
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// event tables // event tables
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
BEGIN_EVENT_TABLE(wxHtmlListBox, wxVListBox) BEGIN_EVENT_TABLE(wxHtmlListBox, wxVListBox)
EVT_SIZE(wxHtmlListBox::OnSize) EVT_SIZE(wxHtmlListBox::OnSize)
EVT_MOTION(wxHtmlListBox::OnMouseMove)
EVT_LEFT_DOWN(wxHtmlListBox::OnLeftDown)
END_EVENT_TABLE() END_EVENT_TABLE()
// ============================================================================ // ============================================================================
@@ -189,6 +197,26 @@ IMPLEMENT_ABSTRACT_CLASS(wxHtmlListBox, wxVListBox)
// wxHtmlListBox creation // 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() void wxHtmlListBox::Init()
{ {
m_htmlParser = NULL; m_htmlParser = NULL;
@@ -259,7 +287,7 @@ void wxHtmlListBox::CacheItem(size_t n) const
{ {
wxHtmlListBox *self = wxConstCast(this, wxHtmlListBox); wxHtmlListBox *self = wxConstCast(this, wxHtmlListBox);
self->m_htmlParser = new wxHtmlWinParser; self->m_htmlParser = new wxHtmlWinParser(self);
m_htmlParser->SetDC(new wxClientDC(self)); m_htmlParser->SetDC(new wxClientDC(self));
m_htmlParser->SetFS(&self->m_filesystem); m_htmlParser->SetFS(&self->m_filesystem);
@@ -271,6 +299,10 @@ void wxHtmlListBox::CacheItem(size_t n) const
Parse(OnGetItemMarkup(n)); Parse(OnGetItemMarkup(n));
wxCHECK_RET( cell, _T("wxHtmlParser::Parse() returned NULL?") ); 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); cell->Layout(GetClientSize().x - 2*GetMargins().x);
m_cache->Store(n, cell); 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 // 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 // even the visible cells part could be not drawn, so always draw the
// entire cell // 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 wxCoord wxHtmlListBox::OnMeasureItem(size_t n) const
@@ -354,5 +388,147 @@ wxCoord wxHtmlListBox::OnMeasureItem(size_t n) const
return cell->GetHeight() + cell->GetDescent() + 4; 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

View File

@@ -117,19 +117,85 @@ void wxHtmlCell::SetScriptMode(wxHtmlScriptMode mode, long previousBase)
m_Descent += m_ScriptBaseline; m_Descent += m_ScriptBaseline;
} }
void wxHtmlCell::OnMouseClick(wxWindow *parent, int x, int y, #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) const wxMouseEvent& event)
{ {
wxHtmlLinkInfo *lnk = GetLink(x, y); wxCHECK_MSG( window, false, _T("window interface must be provided") );
if (lnk != NULL)
#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)
{
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); wxHtmlLinkInfo lnk2(*lnk);
lnk2.SetEvent(&event); lnk2.SetEvent(&event);
lnk2.SetHtmlCell(this); lnk2.SetHtmlCell(this);
// note : this cast is legal because parent is *always* wxHtmlWindow window->OnHTMLLinkClicked(lnk2);
wxStaticCast(parent, wxHtmlWindow)->OnLinkClicked(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); 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.x += parent->m_PosX;
p.y += parent->m_PosY; p.y += parent->m_PosY;
@@ -214,6 +281,14 @@ wxPoint wxHtmlCell::GetAbsPos() const
return p; 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 wxHtmlCell::GetDepth() const
{ {
unsigned d = 0; 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 WXWIN_COMPATIBILITY_2_6
if ( cell ) wxHtmlCellOnMouseClickCompatHelper compat(window, pos, event);
cell->OnMouseClick(parent, x, y, 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 wxHtmlCell *wxHtmlContainerCell::GetFirstTerminal() const

View File

@@ -140,6 +140,104 @@ WX_DEFINE_OBJARRAY(wxHtmlHistoryArray)
WX_DECLARE_LIST(wxHtmlProcessor, wxHtmlProcessorList); WX_DECLARE_LIST(wxHtmlProcessor, wxHtmlProcessorList);
WX_DEFINE_LIST(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 // wxHtmlWindow
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@@ -147,9 +245,6 @@ WX_DEFINE_LIST(wxHtmlProcessorList)
void wxHtmlWindow::Init() void wxHtmlWindow::Init()
{ {
m_tmpMouseMoved = false;
m_tmpLastLink = NULL;
m_tmpLastCell = NULL;
m_tmpCanDrawLocks = 0; m_tmpCanDrawLocks = 0;
m_FS = new wxFileSystem(); m_FS = new wxFileSystem();
#if wxUSE_STATUSBAR #if wxUSE_STATUSBAR
@@ -836,21 +931,6 @@ void wxHtmlWindow::OnLinkClicked(const wxHtmlLinkInfo& link)
LoadPage(link.GetHref()); 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) void wxHtmlWindow::OnEraseBackground(wxEraseEvent& event)
{ {
if ( !m_bmpBg.Ok() ) if ( !m_bmpBg.Ok() )
@@ -994,7 +1074,7 @@ void wxHtmlWindow::OnSize(wxSizeEvent& event)
void wxHtmlWindow::OnMouseMove(wxMouseEvent& WXUNUSED(event)) void wxHtmlWindow::OnMouseMove(wxMouseEvent& WXUNUSED(event))
{ {
m_tmpMouseMoved = true; wxHtmlWindowMouseHelper::HandleMouseMoved();
} }
void wxHtmlWindow::OnMouseDown(wxMouseEvent& event) void wxHtmlWindow::OnMouseDown(wxMouseEvent& event)
@@ -1048,17 +1128,9 @@ void wxHtmlWindow::OnMouseUp(wxMouseEvent& event)
#endif // wxUSE_CLIPBOARD #endif // wxUSE_CLIPBOARD
SetFocus(); 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 wxPoint pos = CalcUnscrolledPosition(event.GetPosition());
// containers may have empty borders -- in this case NULL will be wxHtmlWindowMouseHelper::HandleMouseClick(m_Cell, pos, event);
// returned
if ( cell )
OnCellClicked(cell, pos.x, pos.y, event);
}
} }
@@ -1067,7 +1139,7 @@ void wxHtmlWindow::OnInternalIdle()
{ {
wxWindow::OnInternalIdle(); wxWindow::OnInternalIdle();
if (m_tmpMouseMoved && (m_Cell != NULL)) if (m_Cell != NULL && DidMouseMove())
{ {
#ifdef DEBUG_HTML_SELECTION #ifdef DEBUG_HTML_SELECTION
Refresh(); Refresh();
@@ -1184,44 +1256,14 @@ void wxHtmlWindow::OnInternalIdle()
} }
// handle cursor and status bar text changes: // handle cursor and status bar text changes:
if ( cell != m_tmpLastCell )
{ // NB: because we're passing in 'cell' and not 'm_Cell' (so that the
wxHtmlLinkInfo *lnk = cell ? cell->GetLink(x, y) : NULL; // leaf cell lookup isn't done twice), we need to adjust the
wxCursor cur; // position for the new root:
wxPoint posInCell(x, y);
if (cell) if (cell)
cur = cell->GetCursor(); posInCell -= cell->GetAbsPos();
else wxHtmlWindowMouseHelper::HandleIdle(cell, posInCell);
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;
} }
} }
@@ -1460,9 +1502,65 @@ BEGIN_EVENT_TABLE(wxHtmlWindow, wxScrolledWindow)
#endif // wxUSE_CLIPBOARD #endif // wxUSE_CLIPBOARD
END_EVENT_TABLE() 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 // A module to allow initialization/cleanup
// without calling these functions from app.cpp or from // without calling these functions from app.cpp or from

View File

@@ -45,7 +45,7 @@ wxHtmlDCRenderer::wxHtmlDCRenderer() : wxObject()
m_DC = NULL; m_DC = NULL;
m_Width = m_Height = 0; m_Width = m_Height = 0;
m_Cells = NULL; m_Cells = NULL;
m_Parser = new wxHtmlWinParser(NULL); m_Parser = new wxHtmlWinParser();
m_FS = new wxFileSystem(); m_FS = new wxFileSystem();
m_Parser->SetFS(m_FS); m_Parser->SetFS(m_FS);
} }

View File

@@ -286,7 +286,7 @@ const wxHtmlCell *wxHtmlImageMapCell::Find( int cond, const void *param ) const
class wxHtmlImageCell : public wxHtmlCell class wxHtmlImageCell : public wxHtmlCell
{ {
public: public:
wxHtmlImageCell(wxWindow *window, wxHtmlImageCell(wxHtmlWindowInterface *windowIface,
wxFSFile *input, int w = wxDefaultCoord, int h = wxDefaultCoord, wxFSFile *input, int w = wxDefaultCoord, int h = wxDefaultCoord,
double scale = 1.0, int align = wxHTML_ALIGN_BOTTOM, double scale = 1.0, int align = wxHTML_ALIGN_BOTTOM,
const wxString& mapname = wxEmptyString); const wxString& mapname = wxEmptyString);
@@ -305,7 +305,7 @@ private:
wxBitmap *m_bitmap; wxBitmap *m_bitmap;
int m_bmpW, m_bmpH; int m_bmpW, m_bmpH;
bool m_showFrame:1; bool m_showFrame:1;
wxScrolledWindow *m_window; wxHtmlWindowInterface *m_windowIface;
#if wxUSE_GIF && wxUSE_TIMER #if wxUSE_GIF && wxUSE_TIMER
wxGIFDecoder *m_gifDecoder; wxGIFDecoder *m_gifDecoder;
wxTimer *m_gifTimer; 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, int w, int h, double scale, int align,
const wxString& mapname) : wxHtmlCell() const wxString& mapname) : wxHtmlCell()
{ {
m_window = window ? wxStaticCast(window, wxScrolledWindow) : NULL; m_windowIface = windowIface;
m_scale = scale; m_scale = scale;
m_showFrame = false; m_showFrame = false;
m_bitmap = NULL; m_bitmap = NULL;
@@ -370,8 +371,9 @@ wxHtmlImageCell::wxHtmlImageCell(wxWindow *window, wxFSFile *input,
{ {
#if wxUSE_GIF && wxUSE_TIMER #if wxUSE_GIF && wxUSE_TIMER
bool readImg = true; bool readImg = true;
if ( (input->GetLocation().Matches(wxT("*.gif")) || if ( m_windowIface &&
input->GetLocation().Matches(wxT("*.GIF"))) && m_window ) (input->GetLocation().Matches(wxT("*.gif")) ||
input->GetLocation().Matches(wxT("*.GIF"))) )
{ {
m_gifDecoder = new wxGIFDecoder(s, true); m_gifDecoder = new wxGIFDecoder(s, true);
if ( m_gifDecoder->ReadGIF() == wxGIF_OK ) if ( m_gifDecoder->ReadGIF() == wxGIF_OK )
@@ -492,11 +494,12 @@ void wxHtmlImageCell::AdvanceAnimation(wxTimer *timer)
} }
} }
int x, y; wxWindow *win = m_windowIface->GetHTMLWindow();
m_window->CalcScrolledPosition(m_physX, m_physY, &x, &y); wxPoint pos =
wxRect rect(x, y, m_Width, m_Height); 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) ) m_gifDecoder->ConvertToImage(&img) )
{ {
#if !defined(__WXMSW__) || wxUSE_WXDIB #if !defined(__WXMSW__) || wxUSE_WXDIB
@@ -513,7 +516,7 @@ void wxHtmlImageCell::AdvanceAnimation(wxTimer *timer)
else else
#endif #endif
SetImage(img); SetImage(img);
m_window->Refresh(img.HasMask(), &rect); win->Refresh(img.HasMask(), &rect);
} }
timer->Start(m_gifDecoder->GetDelay(), true); timer->Start(m_gifDecoder->GetDelay(), true);
@@ -645,7 +648,7 @@ TAG_HANDLER_BEGIN(IMG, "IMG,MAP,AREA")
} }
} }
wxHtmlImageCell *cel = new wxHtmlImageCell( wxHtmlImageCell *cel = new wxHtmlImageCell(
m_WParser->GetWindow(), m_WParser->GetWindowInterface(),
str, w, h, str, w, h,
m_WParser->GetPixelScale(), m_WParser->GetPixelScale(),
al, mn); al, mn);

View File

@@ -289,10 +289,8 @@ TAG_HANDLER_BEGIN(TITLE, "TITLE")
TAG_HANDLER_PROC(tag) 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( wxString title = m_WParser->GetSource()->Mid(
tag.GetBeginPos(), tag.GetBeginPos(),
@@ -302,8 +300,8 @@ TAG_HANDLER_BEGIN(TITLE, "TITLE")
title = wxString(title.wc_str(conv), wxConvLocal); title = wxString(title.wc_str(conv), wxConvLocal);
#endif #endif
title = m_WParser->GetEntitiesParser()->Parse(title); title = m_WParser->GetEntitiesParser()->Parse(title);
wfr->OnSetTitle(title);
} winIface->SetHTMLWindowTitle(title);
} }
return true; return true;
} }
@@ -329,6 +327,11 @@ TAG_HANDLER_BEGIN(BODY, "BODY")
if (tag.GetParamAsColour(wxT("LINK"), &clr)) if (tag.GetParamAsColour(wxT("LINK"), &clr))
m_WParser->SetLinkColor(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"))) if (tag.HasParam(wxT("BACKGROUND")))
{ {
wxFSFile *fileBgImage = m_WParser->OpenURL wxFSFile *fileBgImage = m_WParser->OpenURL
@@ -344,7 +347,7 @@ TAG_HANDLER_BEGIN(BODY, "BODY")
#if !defined(__WXMSW__) || wxUSE_WXDIB #if !defined(__WXMSW__) || wxUSE_WXDIB
wxImage image(*is); wxImage image(*is);
if ( image.Ok() ) if ( image.Ok() )
m_WParser->GetWindow()->SetBackgroundImage(image); winIface->SetHTMLBackgroundImage(image);
#endif #endif
} }
} }
@@ -354,8 +357,7 @@ TAG_HANDLER_BEGIN(BODY, "BODY")
{ {
m_WParser->GetContainer()->InsertCell( m_WParser->GetContainer()->InsertCell(
new wxHtmlColourCell(clr, wxHTML_CLR_BACKGROUND)); new wxHtmlColourCell(clr, wxHTML_CLR_BACKGROUND));
if (m_WParser->GetWindow() != NULL) winIface->SetHTMLBackgroundColour(clr);
m_WParser->GetWindow()->SetBackgroundColour(clr);
} }
return false; return false;

View File

@@ -38,11 +38,11 @@ IMPLEMENT_ABSTRACT_CLASS(wxHtmlWinParser, wxHtmlParser)
wxList wxHtmlWinParser::m_Modules; wxList wxHtmlWinParser::m_Modules;
wxHtmlWinParser::wxHtmlWinParser(wxHtmlWindow *wnd) : wxHtmlParser() wxHtmlWinParser::wxHtmlWinParser(wxHtmlWindowInterface *wndIface)
{ {
m_tmpStrBuf = NULL; m_tmpStrBuf = NULL;
m_tmpStrBufSize = 0; m_tmpStrBufSize = 0;
m_Window = wnd; m_windowInterface = wndIface;
m_Container = NULL; m_Container = NULL;
m_DC = NULL; m_DC = NULL;
m_CharHeight = m_CharWidth = 0; m_CharHeight = m_CharWidth = 0;
@@ -212,11 +212,18 @@ void wxHtmlWinParser::InitParser(const wxString& source)
m_Container->InsertCell(new wxHtmlColourCell(m_ActualColor)); m_Container->InsertCell(new wxHtmlColourCell(m_ActualColor));
wxColour windowColour = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW) ; wxColour windowColour = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW) ;
m_Container->InsertCell(
new wxHtmlColourCell(GetWindow() ? m_Container->InsertCell
GetWindow()->GetBackgroundColour() : (
windowColour, new wxHtmlColourCell
wxHTML_CLR_BACKGROUND)); (
m_windowInterface
? m_windowInterface->GetHTMLBackgroundColour()
: windowColour,
wxHTML_CLR_BACKGROUND
)
);
m_Container->InsertCell(new wxHtmlFontCell(CreateCurrentFont())); m_Container->InsertCell(new wxHtmlFontCell(CreateCurrentFont()));
} }
@@ -229,6 +236,15 @@ void wxHtmlWinParser::DoneParser()
wxHtmlParser::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() wxObject* wxHtmlWinParser::GetProduct()
{ {
wxHtmlContainerCell *top; wxHtmlContainerCell *top;
@@ -246,8 +262,9 @@ wxObject* wxHtmlWinParser::GetProduct()
wxFSFile *wxHtmlWinParser::OpenURL(wxHtmlURLType type, wxFSFile *wxHtmlWinParser::OpenURL(wxHtmlURLType type,
const wxString& url) const const wxString& url) const
{ {
if ( m_Window ) if ( !m_windowInterface )
{ return wxHtmlParser::OpenURL(type, url);
wxString myurl(url); wxString myurl(url);
wxHtmlOpeningStatus status; wxHtmlOpeningStatus status;
for (;;) for (;;)
@@ -284,7 +301,7 @@ wxFSFile *wxHtmlWinParser::OpenURL(wxHtmlURLType type,
} }
wxString redirect; wxString redirect;
status = m_Window->OnOpeningURL(type, myfullurl, &redirect); status = m_windowInterface->OnHTMLOpeningURL(type, myfullurl, &redirect);
if ( status != wxHTML_REDIRECT ) if ( status != wxHTML_REDIRECT )
break; break;
@@ -297,9 +314,6 @@ wxFSFile *wxHtmlWinParser::OpenURL(wxHtmlURLType type,
return GetFS()->OpenFile(myurl); return GetFS()->OpenFile(myurl);
} }
return wxHtmlParser::OpenURL(type, url);
}
void wxHtmlWinParser::AddText(const wxChar* txt) void wxHtmlWinParser::AddText(const wxChar* txt)
{ {
size_t i = 0, size_t i = 0,