#include "wx/settings.h"
#include <stdlib.h>
+//-----------------------------------------------------------------------------
+// Helper classes
+//-----------------------------------------------------------------------------
+
+void wxHtmlSelection::Set(const wxPoint& fromPos, wxHtmlCell *fromCell,
+ const wxPoint& toPos, wxHtmlCell *toCell)
+{
+ m_fromCell = fromCell;
+ m_toCell = toCell;
+ m_fromPos = fromPos;
+ m_toPos = toPos;
+}
+
+void wxHtmlSelection::Set(wxHtmlCell *fromCell, wxHtmlCell *toCell)
+{
+ wxPoint p1 = fromCell ? fromCell->GetAbsPos() : wxDefaultPosition;
+ wxPoint p2 = toCell ? toCell->GetAbsPos() : wxDefaultPosition;
+ if ( toCell )
+ {
+ p2.x += toCell->GetWidth()-1;
+ p2.y += toCell->GetHeight()-1;
+ }
+ Set(p1, fromCell, p2, toCell);
+}
//-----------------------------------------------------------------------------
// wxHtmlCell
wxHtmlCell *wxHtmlCell::FindCellByPos(wxCoord x, wxCoord y,
unsigned flags) const
{
- if ( (flags & wxHTML_FIND_TERMINAL) &&
- x >= 0 && x < m_Width && y >= 0 && y < m_Height )
+ if ( x >= 0 && x < m_Width && y >= 0 && y < m_Height )
{
return wxConstCast(this, wxHtmlCell);
}
- return NULL;
+ else
+ {
+ if ((flags & wxHTML_FIND_NEAREST_AFTER) &&
+ (y < 0 || (y == 0 && x <= 0)))
+ return wxConstCast(this, wxHtmlCell);
+ else if ((flags & wxHTML_FIND_NEAREST_BEFORE) &&
+ (y > m_Height-1 || (y == m_Height-1 && x >= m_Width)))
+ return wxConstCast(this, wxHtmlCell);
+ else
+ return NULL;
+ }
+}
+
+
+wxPoint wxHtmlCell::GetAbsPos() const
+{
+ wxPoint p(m_PosX, m_PosY);
+ for (wxHtmlCell *parent = m_Parent; parent; parent = parent->m_Parent)
+ {
+ p.x += parent->m_PosX;
+ p.y += parent->m_PosY;
+ }
+ return p;
+}
+
+unsigned wxHtmlCell::GetDepth() const
+{
+ unsigned d = 0;
+ for (wxHtmlCell *p = m_Parent; p; p = p->m_Parent)
+ d++;
+ return d;
+}
+
+bool wxHtmlCell::IsBefore(wxHtmlCell *cell) const
+{
+ const wxHtmlCell *c1 = this;
+ const wxHtmlCell *c2 = cell;
+ unsigned d1 = GetDepth();
+ unsigned d2 = cell->GetDepth();
+
+ if ( d1 > d2 )
+ for (; d1 != d2; d1-- )
+ c1 = c1->m_Parent;
+ else if ( d1 < d2 )
+ for (; d1 != d2; d2-- )
+ c2 = c2->m_Parent;
+
+ if ( cell == this )
+ return true;
+
+ while ( c1 && c2 )
+ {
+ if ( c1->m_Parent == c2->m_Parent )
+ {
+ while ( c1 )
+ {
+ if ( c1 == c2 )
+ return true;
+ c1 = c1->GetNext();
+ }
+ return false;
+ }
+ else
+ {
+ c1 = c1->m_Parent;
+ c2 = c2->m_Parent;
+ }
+ }
+
+ wxFAIL_MSG(_T("Cells are in different trees"));
+ return false;
}
int WXUNUSED(view_y1), int WXUNUSED(view_y2),
wxHtmlRenderingState& state)
{
- if (state.GetSelectionState() == wxHTML_SEL_IN &&
+ if (state.GetSelectionState() != wxHTML_SEL_OUT &&
dc.GetBackgroundMode() != wxSOLID)
{
dc.SetBackgroundMode(wxSOLID);
dc.SetTextBackground(state.GetBgColour());
}
+ // FIXME - use selection
dc.DrawText(m_Word, x + m_PosX, y + m_PosY);
}
+
+
+wxString wxHtmlWordCell::ConvertToText(wxHtmlSelection *sel) const
+{
+ // FIXME - use selection
+ return m_Word;
+}
else
{
- wxHtmlCell *c = GetFirstCell();
+ wxHtmlCell *c = GetFirstChild();
bool rt = FALSE;
int pbrk = *pagebreak - m_PosY;
{
wxHtmlSelection *s = state.GetSelection();
if (!s) return;
- if (s->GetFromCell() == cell)
- state.SetSelectionState(wxHTML_SEL_IN);
- else if (s->GetToCell() == cell)
+ if (s->GetToCell() == cell)
state.SetSelectionState(wxHTML_SEL_OUT);
+ else if (s->GetFromCell() == cell)
+ state.SetSelectionState(wxHTML_SEL_IN);
}
#define mMin(a, b) (((a) < (b)) ? (a) : (b))
wxHtmlCell *wxHtmlContainerCell::FindCellByPos(wxCoord x, wxCoord y,
unsigned flags) const
{
- for ( const wxHtmlCell *cell = m_Cells; cell; cell = cell->GetNext() )
+ if ( flags & wxHTML_FIND_EXACT )
{
- int cx = cell->GetPosX(),
- cy = cell->GetPosY();
+ 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) )
+ if ( (cx <= x) && (cx + cell->GetWidth() > x) &&
+ (cy <= y) && (cy + cell->GetHeight() > y) )
+ {
+ return cell->FindCellByPos(x - cx, y - cy, flags);
+ }
+ }
+ }
+ else if ( flags & wxHTML_FIND_NEAREST_AFTER )
+ {
+ wxHtmlCell *c;
+ int y2;
+ for ( const wxHtmlCell *cell = m_Cells; cell; cell = cell->GetNext() )
{
- wxHtmlCell *c = cell->FindCellByPos(x - cx, y - cy, flags);
- if (c == NULL && (flags & wxHTML_FIND_NONTERMINAL))
- return wxConstCast(this, wxHtmlContainerCell);
- else
- return c;
+ y2 = cell->GetPosY() + cell->GetHeight() - 1;
+ if (y2 < y || (y2 == y && cell->GetPosX()+cell->GetWidth()-1 < x))
+ continue;
+ c = cell->FindCellByPos(x - cell->GetPosX(), y - cell->GetPosY(),
+ flags);
+ if (c) return c;
+ }
+ }
+ else if ( flags & wxHTML_FIND_NEAREST_BEFORE )
+ {
+ wxHtmlCell *c;
+ for ( const wxHtmlCell *cell = m_Cells; cell; cell = cell->GetNext() )
+ {
+ if (cell->GetPosY() > y ||
+ (cell->GetPosY() == y && cell->GetPosX() > x))
+ break;
+ c = cell->FindCellByPos(x - cell->GetPosX(), y - cell->GetPosY(),
+ flags);
+ if (c) return c;
}
}
- return (flags & wxHTML_FIND_NONTERMINAL) ?
- wxConstCast(this, wxHtmlContainerCell) : NULL;
+ return NULL;
}
*right = cright;
}
+
+wxHtmlCell *wxHtmlContainerCell::GetFirstTerminal() const
+{
+ if ( m_Cells )
+ {
+ wxHtmlCell *c2;
+ for (wxHtmlCell *c = m_Cells; c; c = c->GetNext())
+ {
+ c2 = c->GetFirstTerminal();
+ if ( c2 )
+ return c2;
+ }
+ }
+ return NULL;
+}
+
+wxHtmlCell *wxHtmlContainerCell::GetLastTerminal() const
+{
+ if ( m_Cells )
+ {
+ wxHtmlCell *c, *c2 = NULL;
+ // most common case first:
+ c = m_LastCell->GetLastTerminal();
+ if ( c )
+ return c;
+ for (wxHtmlCell *c = m_Cells; c; c = c->GetNext())
+ c2 = c->GetLastTerminal();
+ return c2;
+ }
+ else
+ return NULL;
+}
wxHtmlCell::Layout(w);
}
+
+
+// ----------------------------------------------------------------------------
+// wxHtmlTerminalCellsInterator
+// ----------------------------------------------------------------------------
+
+const wxHtmlCell* wxHtmlTerminalCellsInterator::operator++()
+{
+ if ( !m_pos )
+ return NULL;
+
+ do
+ {
+ if ( m_pos == m_to )
+ {
+ m_pos = NULL;
+ return NULL;
+ }
+
+ if ( m_pos->GetNext() )
+ m_pos = m_pos->GetNext();
+ else
+ {
+ // we must go up the hierarchy until we reach container where this
+ // is not the last child, and then go down to first terminal cell:
+ while ( m_pos->GetNext() == NULL )
+ {
+ m_pos = m_pos->GetParent();
+ if ( !m_pos )
+ return NULL;
+ }
+ m_pos = m_pos->GetNext();
+ }
+ while ( m_pos->GetFirstChild() != NULL )
+ m_pos = m_pos->GetFirstChild();
+ } while ( !m_pos->IsTerminalCell() );
+
+ return m_pos;
+}
+
#endif