From f6010d8fad702475237ea69a766e8d763e2cf53d Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Fri, 31 Aug 2001 21:19:23 +0000 Subject: [PATCH] implemented and documented wxHtmlWindow::OnCellMouseHover() and OnCellClick() git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@11525 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- docs/latex/wx/htwindow.tex | 31 +++++++++++++++ include/wx/html/htmlcell.h | 24 +++++++++--- include/wx/html/htmlwin.h | 15 +++++++- src/html/htmlcell.cpp | 60 ++++++++++++++++------------- src/html/htmlwin.cpp | 77 ++++++++++++++++++++++++++++---------- 5 files changed, 154 insertions(+), 53 deletions(-) diff --git a/docs/latex/wx/htwindow.tex b/docs/latex/wx/htwindow.tex index e386da35f9..884d185105 100644 --- a/docs/latex/wx/htwindow.tex +++ b/docs/latex/wx/htwindow.tex @@ -144,6 +144,37 @@ htmlwin -> SetPage("help/myproject/index.htm"); 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}} + +This method is called when a mouse button is clicked inside wxHtmlWindow. +The default behaviour is to call +\helpref{OnLinkClicked}{wxhtmlwindowonlinkclicked} if the cell contains a +hypertext link. + +\wxheading{Parameters} + +\docparam{cell}{The cell inside which the mouse was clicked, always a simple +(i.e. non container) cell} + +\docparam{x, y}{The logical coordinates of the click point} + +\docparam{event}{The mouse event containing other information about the click} + +\membersection{wxHtmlWindow::OnCellMouseHover}\label{wxhtmlwindowoncellmousehover} + +\func{virtual void}{OnCellMouseHover}{\param{wxHtmlCell }{*cell}, \param{wxCoord }{x}, \param{wxCoord }{y}} + +This method is called when a mouse moves over an HTML cell. + +\wxheading{Parameters} + +\docparam{cell}{The cell inside which the mouse is currently, always a simple +(i.e. non container) cell} + +\docparam{x, y}{The logical coordinates of the click point} + \membersection{wxHtmlWindow::OnLinkClicked}\label{wxhtmlwindowonlinkclicked} \func{virtual void}{OnLinkClicked}{\param{const wxHtmlLinkInfo\& }{link}} diff --git a/include/wx/html/htmlcell.h b/include/wx/html/htmlcell.h index 166f9be9d9..55016f205d 100644 --- a/include/wx/html/htmlcell.h +++ b/include/wx/html/htmlcell.h @@ -60,7 +60,7 @@ public: // members access methods wxHtmlCell *GetNext() const {return m_Next;} - // members writin methods + // members writing methods virtual void SetPos(int x, int y) {m_PosX = x, m_PosY = y;} void SetLink(const wxHtmlLinkInfo& link); void SetNext(wxHtmlCell *cell) {m_Next = cell;} @@ -91,8 +91,7 @@ public: virtual const wxHtmlCell* Find(int condition, const void* param) const; // This function is called when mouse button is clicked over the cell. - // left, middle, right are flags indicating whether the button was or wasn't - // pressed. + // // Parent is pointer to wxHtmlWindow that generated the event // HINT: if this handling is not enough for you you should use // wxHtmlBinderCell @@ -118,18 +117,28 @@ public: // called Layout() before! virtual void GetHorizontalConstraints(int *left, int *right) const; + // Returns true for simple == terminal cells, i.e. not composite ones. + // This if for internal usage only and may disappear in future versions! + virtual bool IsTerminalCell() const { return true; } + + // Find the terminal cell inside this cell at the given position (relative + // to this cell) + // + // Returns NULL if not found + virtual wxHtmlCell *FindCellByPos(wxCoord x, wxCoord y) const; + protected: wxHtmlCell *m_Next; // pointer to the next cell wxHtmlContainerCell *m_Parent; - // pointer to parent cell + // pointer to parent cell long m_Width, m_Height, m_Descent; // dimensions of fragment // m_Descent is used to position text&images.. long m_PosX, m_PosY; // position where the fragment is drawn wxHtmlLinkInfo *m_Link; - // destination address if this fragment is hypertext link, "" otherwise + // destination address if this fragment is hypertext link, NULL otherwise bool m_CanLiveOnPagebreak; // true if this cell can be placed on pagebreak, false otherwise }; @@ -214,6 +223,11 @@ public: // returns pointer to the first cell in container or NULL wxHtmlCell* GetFirstCell() const {return m_Cells;} + // see comment in wxHtmlCell about this method + virtual bool IsTerminalCell() const { return false; } + + virtual wxHtmlCell *FindCellByPos(wxCoord x, wxCoord y) const; + protected: int m_IndentLeft, m_IndentRight, m_IndentTop, m_IndentBottom; // indentation of subcells. There is always m_Indent pixels diff --git a/include/wx/html/htmlwin.h b/include/wx/html/htmlwin.h index 90544db787..3f6aab815c 100644 --- a/include/wx/html/htmlwin.h +++ b/include/wx/html/htmlwin.h @@ -123,7 +123,18 @@ public: // Adds input filter static void AddFilter(wxHtmlFilter *filter); - // Called when users clicked on hypertext link. Default behavior is to + // 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); @@ -195,6 +206,8 @@ private: bool m_tmpMouseMoved; // 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; diff --git a/src/html/htmlcell.cpp b/src/html/htmlcell.cpp index cb0ce6904c..909584da20 100644 --- a/src/html/htmlcell.cpp +++ b/src/html/htmlcell.cpp @@ -115,6 +115,14 @@ const wxHtmlCell* wxHtmlCell::Find(int WXUNUSED(condition), const void* WXUNUSED } +wxHtmlCell *wxHtmlCell::FindCellByPos(wxCoord x, wxCoord y) const +{ + if ( x >= 0 && x < m_Width && y >= 0 && y < m_Height ) + return wxConstCast(this, wxHtmlCell); + + return NULL; +} + //----------------------------------------------------------------------------- // wxHtmlWordCell @@ -460,18 +468,12 @@ void wxHtmlContainerCell::DrawInvisible(wxDC& dc, int x, int y) wxHtmlLinkInfo *wxHtmlContainerCell::GetLink(int x, int y) const { - wxHtmlCell *c = m_Cells; - int cx, cy, cw, ch; + wxHtmlCell *cell = FindCellByPos(x, y); - while (c) - { - cx = c->GetPosX(), cy = c->GetPosY(); - cw = c->GetWidth(), ch = c->GetHeight(); - if ((x >= cx) && (x < cx + cw) && (y >= cy) && (y < cy + ch)) - return c->GetLink(x - cx, y - cy); - c = c->GetNext(); - } - return NULL; + // VZ: I don't know if we should pass absolute or relative coords to + // wxHtmlCell::GetLink()? As the base class version just ignores them + // anyhow, it hardly matters right now but should still be clarified + return cell ? cell->GetLink(x, y) : NULL; } @@ -550,25 +552,29 @@ const wxHtmlCell* wxHtmlContainerCell::Find(int condition, const void* param) co } +wxHtmlCell *wxHtmlContainerCell::FindCellByPos(wxCoord x, wxCoord y) const +{ + for ( const wxHtmlCell *cell = m_Cells; cell; cell = cell->GetNext() ) + { + int cx = cell->GetPosX(), + cy = cell->GetPosY(); + + if ( (cx <= x) && (cx + cell->GetWidth() > x) && + (cy <= y) && (cy + cell->GetHeight() > y) ) + { + return cell->FindCellByPos(x - cx, y - cy); + } + } + + return NULL; +} + void wxHtmlContainerCell::OnMouseClick(wxWindow *parent, int x, int y, const wxMouseEvent& event) { - if (m_Cells) - { - wxHtmlCell *c = m_Cells; - while (c) - { - if ( (c->GetPosX() <= x) && - (c->GetPosY() <= y) && - (c->GetPosX() + c->GetWidth() > x) && - (c->GetPosY() + c->GetHeight() > y)) - { - c->OnMouseClick(parent, x - c->GetPosX(), y - c->GetPosY(), event); - break; - } - c = c->GetNext(); - } - } + wxHtmlCell *cell = FindCellByPos(x, y); + if ( cell ) + cell->OnMouseClick(parent, x, y, event); } diff --git a/src/html/htmlwin.cpp b/src/html/htmlwin.cpp index 147e763613..1eb0d2a166 100644 --- a/src/html/htmlwin.cpp +++ b/src/html/htmlwin.cpp @@ -78,6 +78,7 @@ wxHtmlWindow::wxHtmlWindow(wxWindow *parent, wxWindowID id, const wxPoint& pos, { m_tmpMouseMoved = FALSE; m_tmpLastLink = NULL; + m_tmpLastCell = NULL; m_tmpCanDrawLocks = 0; m_FS = new wxFileSystem(); m_RelatedStatusBar = -1; @@ -611,7 +612,20 @@ 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::OnDraw(wxDC& dc) { @@ -658,15 +672,23 @@ void wxHtmlWindow::OnMouseEvent(wxMouseEvent& event) if (event.ButtonDown()) { - int sx, sy; - GetViewStart(&sx, &sy); - sx *= wxHTML_SCROLL_STEP; - sy *= wxHTML_SCROLL_STEP; + if ( m_Cell ) + { + int sx, sy; + GetViewStart(&sx, &sy); + sx *= wxHTML_SCROLL_STEP; + sy *= wxHTML_SCROLL_STEP; - wxPoint pos = event.GetPosition(); + wxPoint pos = event.GetPosition(); + pos.x += sx; + pos.y += sy; - if (m_Cell) - m_Cell->OnMouseClick(this, sx + pos.x, sy + pos.y, event); + wxHtmlCell *cell = m_Cell->FindCellByPos(pos.x, pos.y); + + // VZ: is it possible that we don't find anything at all? + if ( cell ) + OnCellClicked(cell, pos.x, pos.y, event); + } } } @@ -690,24 +712,39 @@ void wxHtmlWindow::OnIdle(wxIdleEvent& WXUNUSED(event)) int x, y; wxGetMousePosition(&x, &y); ScreenToClient(&x, &y); + x += sx; + y += sy; - wxHtmlLinkInfo *lnk = m_Cell->GetLink(sx + x, sy + y); - - if (lnk != m_tmpLastLink) + wxHtmlCell *cell = m_Cell->FindCellByPos(x, y); + if ( cell != m_tmpLastCell ) { - if (lnk == NULL) + wxHtmlLinkInfo *lnk = cell ? cell->GetLink(x, y) : NULL; + + if (lnk != m_tmpLastLink) { - SetCursor(*s_cur_arrow); - if (m_RelatedStatusBar != -1) m_RelatedFrame->SetStatusText(wxEmptyString, m_RelatedStatusBar); + if (lnk == NULL) + { + SetCursor(*s_cur_arrow); + if (m_RelatedStatusBar != -1) + m_RelatedFrame->SetStatusText(wxEmptyString, m_RelatedStatusBar); + } + else + { + SetCursor(*s_cur_hand); + if (m_RelatedStatusBar != -1) + m_RelatedFrame->SetStatusText(lnk->GetHref(), m_RelatedStatusBar); + } + m_tmpLastLink = lnk; } - else - { - SetCursor(*s_cur_hand); - if (m_RelatedStatusBar != -1) - m_RelatedFrame->SetStatusText(lnk->GetHref(), m_RelatedStatusBar); - } - m_tmpLastLink = lnk; + + m_tmpLastCell = cell; } + else // mouse moved but stayed in the same cell + { + if ( cell ) + OnCellMouseHover(cell, x, y); + } + m_tmpMouseMoved = FALSE; } }