fixes to wxHTML selection code: corrected mouse navigation
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@21779 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -184,10 +184,10 @@ wxHtmlCell *wxHtmlCell::FindCellByPos(wxCoord x, wxCoord y,
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
if ((flags & wxHTML_FIND_NEAREST_AFTER) &&
|
if ((flags & wxHTML_FIND_NEAREST_AFTER) &&
|
||||||
(y < 0 || (y == 0 && x <= 0)))
|
(y < 0 || (y < 0+m_Height && x < 0+m_Width)))
|
||||||
return wxConstCast(this, wxHtmlCell);
|
return wxConstCast(this, wxHtmlCell);
|
||||||
else if ((flags & wxHTML_FIND_NEAREST_BEFORE) &&
|
else if ((flags & wxHTML_FIND_NEAREST_BEFORE) &&
|
||||||
(y > m_Height-1 || (y == m_Height-1 && x >= m_Width)))
|
(y >= 0+m_Height || (y >= 0 && x >= 0)))
|
||||||
return wxConstCast(this, wxHtmlCell);
|
return wxConstCast(this, wxHtmlCell);
|
||||||
else
|
else
|
||||||
return NULL;
|
return NULL;
|
||||||
@@ -284,6 +284,13 @@ void wxHtmlWordCell::Split(wxDC& dc,
|
|||||||
unsigned i = 0;
|
unsigned i = 0;
|
||||||
pos1 = 0;
|
pos1 = 0;
|
||||||
|
|
||||||
|
// adjust for cases when the start/end position is completely
|
||||||
|
// outside the cell:
|
||||||
|
if ( pt1.y < 0 )
|
||||||
|
pt1.x = 0;
|
||||||
|
if ( pt2.y >= m_Height )
|
||||||
|
pt2.x = m_Width;
|
||||||
|
|
||||||
// before selection:
|
// before selection:
|
||||||
while ( pt1.x > 0 && i < len )
|
while ( pt1.x > 0 && i < len )
|
||||||
{
|
{
|
||||||
@@ -971,14 +978,16 @@ wxHtmlCell *wxHtmlContainerCell::FindCellByPos(wxCoord x, wxCoord y,
|
|||||||
else if ( flags & wxHTML_FIND_NEAREST_AFTER )
|
else if ( flags & wxHTML_FIND_NEAREST_AFTER )
|
||||||
{
|
{
|
||||||
wxHtmlCell *c;
|
wxHtmlCell *c;
|
||||||
int y2;
|
|
||||||
for ( const wxHtmlCell *cell = m_Cells; cell; cell = cell->GetNext() )
|
for ( const wxHtmlCell *cell = m_Cells; cell; cell = cell->GetNext() )
|
||||||
{
|
{
|
||||||
y2 = cell->GetPosY() + cell->GetHeight() - 1;
|
if ( cell->IsFormattingCell() )
|
||||||
if (y2 < y || (y2 == y && cell->GetPosX()+cell->GetWidth()-1 < x))
|
|
||||||
continue;
|
continue;
|
||||||
c = cell->FindCellByPos(x - cell->GetPosX(), y - cell->GetPosY(),
|
int cellY = cell->GetPosY();
|
||||||
flags);
|
if (!( y < cellY || (y < cellY + cell->GetHeight() &&
|
||||||
|
x < cell->GetPosX() + cell->GetWidth()) ))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
c = cell->FindCellByPos(x - cell->GetPosX(), y - cellY, flags);
|
||||||
if (c) return c;
|
if (c) return c;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -987,11 +996,13 @@ wxHtmlCell *wxHtmlContainerCell::FindCellByPos(wxCoord x, wxCoord y,
|
|||||||
wxHtmlCell *c2, *c = NULL;
|
wxHtmlCell *c2, *c = NULL;
|
||||||
for ( const wxHtmlCell *cell = m_Cells; cell; cell = cell->GetNext() )
|
for ( const wxHtmlCell *cell = m_Cells; cell; cell = cell->GetNext() )
|
||||||
{
|
{
|
||||||
if (cell->GetPosY() > y ||
|
if ( cell->IsFormattingCell() )
|
||||||
(cell->GetPosY() == y && cell->GetPosX() > x))
|
continue;
|
||||||
|
int cellY = cell->GetPosY();
|
||||||
|
if (!( cellY + cell->GetHeight() <= y ||
|
||||||
|
(y >= cellY && x >= cell->GetPosX()) ))
|
||||||
break;
|
break;
|
||||||
c2 = cell->FindCellByPos(x - cell->GetPosX(), y - cell->GetPosY(),
|
c2 = cell->FindCellByPos(x - cell->GetPosX(), y - cellY, flags);
|
||||||
flags);
|
|
||||||
if (c2)
|
if (c2)
|
||||||
c = c2;
|
c = c2;
|
||||||
}
|
}
|
||||||
|
@@ -834,6 +834,35 @@ void wxHtmlWindow::OnPaint(wxPaintEvent& WXUNUSED(event))
|
|||||||
y * wxHTML_SCROLL_STEP + rect.GetTop(),
|
y * wxHTML_SCROLL_STEP + rect.GetTop(),
|
||||||
y * wxHTML_SCROLL_STEP + rect.GetBottom(),
|
y * wxHTML_SCROLL_STEP + rect.GetBottom(),
|
||||||
rinfo);
|
rinfo);
|
||||||
|
|
||||||
|
//#define DEBUG_HTML_SELECTION
|
||||||
|
#ifdef DEBUG_HTML_SELECTION
|
||||||
|
{
|
||||||
|
int xc, yc, x, y;
|
||||||
|
wxGetMousePosition(&xc, &yc);
|
||||||
|
ScreenToClient(&xc, &yc);
|
||||||
|
CalcUnscrolledPosition(xc, yc, &x, &y);
|
||||||
|
wxHtmlCell *at = m_Cell->FindCellByPos(x, y);
|
||||||
|
wxHtmlCell *before =
|
||||||
|
m_Cell->FindCellByPos(x, y, wxHTML_FIND_NEAREST_BEFORE);
|
||||||
|
wxHtmlCell *after =
|
||||||
|
m_Cell->FindCellByPos(x, y, wxHTML_FIND_NEAREST_AFTER);
|
||||||
|
|
||||||
|
dcm.SetBrush(*wxTRANSPARENT_BRUSH);
|
||||||
|
dcm.SetPen(*wxBLACK_PEN);
|
||||||
|
if (at)
|
||||||
|
dcm.DrawRectangle(at->GetAbsPos(),
|
||||||
|
wxSize(at->GetWidth(),at->GetHeight()));
|
||||||
|
dcm.SetPen(*wxGREEN_PEN);
|
||||||
|
if (before)
|
||||||
|
dcm.DrawRectangle(before->GetAbsPos().x+1, before->GetAbsPos().y+1,
|
||||||
|
before->GetWidth()-2,before->GetHeight()-2);
|
||||||
|
dcm.SetPen(*wxRED_PEN);
|
||||||
|
if (after)
|
||||||
|
dcm.DrawRectangle(after->GetAbsPos().x+2, after->GetAbsPos().y+2,
|
||||||
|
after->GetWidth()-4,after->GetHeight()-4);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
dcm.SetDeviceOrigin(0,0);
|
dcm.SetDeviceOrigin(0,0);
|
||||||
dc.Blit(0, rect.GetTop(),
|
dc.Blit(0, rect.GetTop(),
|
||||||
@@ -939,6 +968,9 @@ void wxHtmlWindow::OnIdle(wxIdleEvent& WXUNUSED(event))
|
|||||||
{
|
{
|
||||||
if (m_tmpMouseMoved && (m_Cell != NULL))
|
if (m_tmpMouseMoved && (m_Cell != NULL))
|
||||||
{
|
{
|
||||||
|
#ifdef DEBUG_HTML_SELECTION
|
||||||
|
Refresh();
|
||||||
|
#endif
|
||||||
int xc, yc, x, y;
|
int xc, yc, x, y;
|
||||||
wxGetMousePosition(&xc, &yc);
|
wxGetMousePosition(&xc, &yc);
|
||||||
ScreenToClient(&xc, &yc);
|
ScreenToClient(&xc, &yc);
|
||||||
@@ -949,12 +981,35 @@ void wxHtmlWindow::OnIdle(wxIdleEvent& WXUNUSED(event))
|
|||||||
// handle selection update:
|
// handle selection update:
|
||||||
if ( m_makingSelection )
|
if ( m_makingSelection )
|
||||||
{
|
{
|
||||||
bool goingDown = m_tmpSelFromPos.y < y ||
|
|
||||||
m_tmpSelFromPos.y == y && m_tmpSelFromPos.x < x;
|
|
||||||
|
|
||||||
if ( !m_tmpSelFromCell )
|
if ( !m_tmpSelFromCell )
|
||||||
m_tmpSelFromCell = m_Cell->FindCellByPos(
|
m_tmpSelFromCell = m_Cell->FindCellByPos(
|
||||||
m_tmpSelFromPos.x,m_tmpSelFromPos.y);
|
m_tmpSelFromPos.x,m_tmpSelFromPos.y);
|
||||||
|
|
||||||
|
// NB: a trick - we adjust selFromPos to be upper left or bottom
|
||||||
|
// right corner of the first cell of the selection depending
|
||||||
|
// on whether the mouse is moving to the right or to the left.
|
||||||
|
// This gives us more "natural" behaviour when selecting
|
||||||
|
// a line (specifically, first cell of the next line is not
|
||||||
|
// included if you drag selection from left to right over
|
||||||
|
// entire line):
|
||||||
|
wxPoint dirFromPos;
|
||||||
|
if ( !m_tmpSelFromCell )
|
||||||
|
{
|
||||||
|
dirFromPos = m_tmpSelFromPos;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
dirFromPos = m_tmpSelFromCell->GetAbsPos();
|
||||||
|
if ( x < m_tmpSelFromPos.x )
|
||||||
|
{
|
||||||
|
dirFromPos.x += m_tmpSelFromCell->GetWidth();
|
||||||
|
dirFromPos.y += m_tmpSelFromCell->GetHeight();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
bool goingDown = dirFromPos.y < y ||
|
||||||
|
(dirFromPos.y == y && dirFromPos.x < x);
|
||||||
|
|
||||||
|
// determine selection span:
|
||||||
if ( /*still*/ !m_tmpSelFromCell )
|
if ( /*still*/ !m_tmpSelFromCell )
|
||||||
{
|
{
|
||||||
if (goingDown)
|
if (goingDown)
|
||||||
@@ -981,14 +1036,14 @@ void wxHtmlWindow::OnIdle(wxIdleEvent& WXUNUSED(event))
|
|||||||
if (goingDown)
|
if (goingDown)
|
||||||
{
|
{
|
||||||
selcell = m_Cell->FindCellByPos(x, y,
|
selcell = m_Cell->FindCellByPos(x, y,
|
||||||
wxHTML_FIND_NEAREST_AFTER);
|
wxHTML_FIND_NEAREST_BEFORE);
|
||||||
if (!selcell)
|
if (!selcell)
|
||||||
selcell = m_Cell->GetLastTerminal();
|
selcell = m_Cell->GetLastTerminal();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
selcell = m_Cell->FindCellByPos(x, y,
|
selcell = m_Cell->FindCellByPos(x, y,
|
||||||
wxHTML_FIND_NEAREST_BEFORE);
|
wxHTML_FIND_NEAREST_AFTER);
|
||||||
if (!selcell)
|
if (!selcell)
|
||||||
selcell = m_Cell->GetFirstTerminal();
|
selcell = m_Cell->GetFirstTerminal();
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user