Countless (some half-finished) optimisations.
Started implementing selections. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@2106 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -15,27 +15,32 @@ BUGS
|
||||
|
||||
TODO
|
||||
=====================================================================
|
||||
|
||||
RECENTLY FIXED (?)
|
||||
- fix(simplify) cursor size calculation
|
||||
- delete in empty line doesn't work
|
||||
- fix horiz scrollbar size OK here, a Mahogany problem?
|
||||
|
||||
|
||||
|
||||
- update rectangle (needs support in wxllist and wxWindows)
|
||||
--> needs a bit of fixing still
|
||||
some code bits are commented out in wxlwindow.cpp
|
||||
offset handling seems a bit dodgy, white shadow to top/left of cursor
|
||||
|
||||
- replacement of llist in window
|
||||
- undo
|
||||
|
||||
- Selections!!!
|
||||
- font optimisations(!)
|
||||
- copy/cut/selections
|
||||
- occasionally wraps lines wongly (twice) ??
|
||||
- UNDO
|
||||
later:
|
||||
- DragNDrop ... broken in wxGTK at present
|
||||
- cut&paste ... broken in wxGTK at present, Paste already implemented
|
||||
- Selections
|
||||
|
||||
- More optimisations:
|
||||
|
||||
- let each line have a pointer to the last layoutcommand and let that
|
||||
one only store the settings that changed, then we no longer need to
|
||||
recalculate all the lines
|
||||
|
||||
- update rectangle (needs support in wxllist and wxWindows)
|
||||
|
||||
- fix(simplify) cursor size calculation: don't use icon cursor if there
|
||||
is no cursor object
|
||||
|
||||
- copy/cut/selections
|
||||
- UNDO
|
||||
|
||||
- cut&paste (paste is there but broken in wxGTK)
|
||||
The current paste in wxGTK is broken, support is there.
|
||||
Once selections are there, add copy (trivial).
|
||||
|
||||
- DragNDrop (waiting for wxGTK/gtk1.2 & GNOME 1.0 / Debian Slink)
|
||||
|
@@ -14,12 +14,14 @@
|
||||
#pragma implementation "wxllist.h"
|
||||
#endif
|
||||
|
||||
//#include "Mpch.h"
|
||||
|
||||
|
||||
#include "wx/wxprec.h"
|
||||
#ifdef __BORLANDC__
|
||||
# pragma hdrstop
|
||||
#endif
|
||||
|
||||
//#include "Mpch.h"
|
||||
#ifdef M_PREFIX
|
||||
# include "gui/wxllist.h"
|
||||
#else
|
||||
@@ -78,9 +80,16 @@ bool operator !=(wxPoint const &p1, wxPoint const &p2)
|
||||
return p1.x != p2.x || p1.y != p2.y;
|
||||
}
|
||||
|
||||
/// allows me to compare to wxPoints
|
||||
bool operator <=(wxPoint const &p1, wxPoint const &p2)
|
||||
{
|
||||
return p1.y < p2.y || (p1.y == p2.y && p1.x <= p2.x);
|
||||
}
|
||||
|
||||
/// grows a wxRect so that it includes the given point
|
||||
|
||||
static void GrowRect(wxRect &r, const wxPoint & p)
|
||||
static
|
||||
void GrowRect(wxRect &r, const wxPoint & p)
|
||||
{
|
||||
if(r.x > p.x)
|
||||
r.x = p.x;
|
||||
@@ -92,6 +101,13 @@ static void GrowRect(wxRect &r, const wxPoint & p)
|
||||
else if(r.y + r.height < p.y)
|
||||
r.height = p.y - r.y;
|
||||
}
|
||||
|
||||
/// returns true if the point is in the rectangle
|
||||
static
|
||||
bool Contains(const wxRect &r, const wxPoint &p)
|
||||
{
|
||||
return r.x <= p.x && r.y <= p.y && (r.x+r.width) >= p.x && (r.y + r.height) >= p.y;
|
||||
}
|
||||
//@}
|
||||
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
@@ -234,7 +250,7 @@ wxLayoutObjectIcon::GetSize(CoordType *top, CoordType *bottom) const
|
||||
|
||||
wxLayoutObjectCmd::wxLayoutObjectCmd(int size, int family, int style, int
|
||||
weight, bool underline,
|
||||
wxColour const *fg, wxColour const *bg)
|
||||
wxColour &fg, wxColour &bg)
|
||||
|
||||
{
|
||||
m_font = new wxFont(size,family,style,weight,underline);
|
||||
@@ -270,12 +286,12 @@ wxLayoutObjectCmd::GetStyle(wxLayoutStyleInfo *si) const
|
||||
si->underline = m_font->GetUnderlined();
|
||||
si->weight = m_font->GetWeight();
|
||||
|
||||
si->fg_red = m_ColourFG->Red();
|
||||
si->fg_green = m_ColourFG->Green();
|
||||
si->fg_blue = m_ColourFG->Blue();
|
||||
si->bg_red = m_ColourBG->Red();
|
||||
si->bg_green = m_ColourBG->Green();
|
||||
si->bg_blue = m_ColourBG->Blue();
|
||||
si->fg_red = m_ColourFG.Red();
|
||||
si->fg_green = m_ColourFG.Green();
|
||||
si->fg_blue = m_ColourFG.Blue();
|
||||
si->bg_red = m_ColourBG.Red();
|
||||
si->bg_green = m_ColourBG.Green();
|
||||
si->bg_blue = m_ColourBG.Blue();
|
||||
}
|
||||
|
||||
void
|
||||
@@ -283,10 +299,8 @@ wxLayoutObjectCmd::Draw(wxDC &dc, wxPoint const & /* coords */)
|
||||
{
|
||||
wxASSERT(m_font);
|
||||
dc.SetFont(*m_font);
|
||||
if(m_ColourFG)
|
||||
dc.SetTextForeground(*m_ColourFG);
|
||||
if(m_ColourBG)
|
||||
dc.SetTextBackground(*m_ColourBG);
|
||||
dc.SetTextForeground(m_ColourFG);
|
||||
dc.SetTextBackground(m_ColourBG);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -303,7 +317,7 @@ wxLayoutObjectCmd::Layout(wxDC &dc)
|
||||
|
||||
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||
|
||||
wxLayoutLine::wxLayoutLine(wxLayoutLine *prev)
|
||||
wxLayoutLine::wxLayoutLine(wxLayoutLine *prev, wxLayoutList *llist)
|
||||
{
|
||||
m_LineNumber = 0;
|
||||
m_Width = m_Height = 0;
|
||||
@@ -311,7 +325,7 @@ wxLayoutLine::wxLayoutLine(wxLayoutLine *prev)
|
||||
m_Dirty = true;
|
||||
m_Previous = prev;
|
||||
m_Next = NULL;
|
||||
RecalculatePosition();
|
||||
RecalculatePosition(llist);
|
||||
if(m_Previous)
|
||||
{
|
||||
m_LineNumber = m_Previous->GetLineNumber()+1;
|
||||
@@ -323,7 +337,7 @@ wxLayoutLine::wxLayoutLine(wxLayoutLine *prev)
|
||||
{
|
||||
m_Next->m_Previous = this;
|
||||
m_Next->MoveLines(+1);
|
||||
m_Next->RecalculatePositions(1);
|
||||
m_Next->RecalculatePositions(1,llist);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -333,33 +347,32 @@ wxLayoutLine::~wxLayoutLine()
|
||||
}
|
||||
|
||||
wxPoint
|
||||
wxLayoutLine::RecalculatePosition(void)
|
||||
wxLayoutLine::RecalculatePosition(wxLayoutList *llist)
|
||||
{
|
||||
if(m_Previous)
|
||||
m_Position = m_Previous->GetPosition() +
|
||||
wxPoint(0,m_Previous->GetHeight());
|
||||
else
|
||||
m_Position = wxPoint(0,0);
|
||||
llist->SetUpdateRect(m_Position);
|
||||
return m_Position;
|
||||
}
|
||||
|
||||
void
|
||||
wxLayoutLine::RecalculatePositions(int recurse)
|
||||
wxLayoutLine::RecalculatePositions(int recurse, wxLayoutList *llist)
|
||||
{
|
||||
wxASSERT(recurse >= 0);
|
||||
wxPoint pos = m_Position;
|
||||
CoordType height = m_Height;
|
||||
|
||||
// WXLO_TRACE("RecalculatePositions()");
|
||||
RecalculatePosition();
|
||||
RecalculatePosition(llist);
|
||||
if(m_Next)
|
||||
{
|
||||
if(recurse > 0)
|
||||
{
|
||||
if(m_Next) m_Next->RecalculatePositions(--recurse);
|
||||
}
|
||||
m_Next->RecalculatePositions(--recurse, llist);
|
||||
else if(pos != m_Position || m_Height != height)
|
||||
if(m_Next) m_Next->RecalculatePositions();
|
||||
m_Next->RecalculatePositions(0, llist);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -368,21 +381,29 @@ wxLayoutLine::FindObject(CoordType xpos, CoordType *offset) const
|
||||
{
|
||||
wxASSERT(xpos >= 0);
|
||||
wxASSERT(offset);
|
||||
wxLayoutObjectList::iterator i;
|
||||
wxLayoutObjectList::iterator
|
||||
i,
|
||||
found = NULLIT;
|
||||
CoordType x = 0, len;
|
||||
|
||||
|
||||
/* We search through the objects. As we don't like returning the
|
||||
object that the cursor is behind, we just remember such an
|
||||
object in "found" so we can return it if there is really no
|
||||
further object following it. */
|
||||
for(i = m_ObjectList.begin(); i != NULLIT; i++)
|
||||
{
|
||||
len = (**i).GetLength();
|
||||
if( x <= xpos && xpos <= x + len )
|
||||
{
|
||||
*offset = xpos-x;
|
||||
if(xpos == x + len) // is there another object behind?
|
||||
found = i;
|
||||
else // we are really inside this object
|
||||
return i;
|
||||
}
|
||||
x += (**i).GetLength();
|
||||
}
|
||||
return NULLIT;
|
||||
return found; // ==NULL if really none found
|
||||
}
|
||||
|
||||
wxLayoutObjectList::iterator
|
||||
@@ -586,14 +607,14 @@ wxLayoutLine::DeleteWord(CoordType xpos)
|
||||
}
|
||||
|
||||
wxLayoutLine *
|
||||
wxLayoutLine::DeleteLine(bool update)
|
||||
wxLayoutLine::DeleteLine(bool update, wxLayoutList *llist)
|
||||
{
|
||||
if(m_Next) m_Next->m_Previous = m_Previous;
|
||||
if(m_Previous) m_Previous->m_Next = m_Next;
|
||||
if(update)
|
||||
{
|
||||
m_Next->MoveLines(-1);
|
||||
m_Next->RecalculatePositions(1);
|
||||
m_Next->RecalculatePositions(1, llist);
|
||||
}
|
||||
wxLayoutLine *next = m_Next;
|
||||
delete this;
|
||||
@@ -601,7 +622,9 @@ wxLayoutLine::DeleteLine(bool update)
|
||||
}
|
||||
|
||||
void
|
||||
wxLayoutLine::Draw(wxDC &dc, const wxPoint & offset) const
|
||||
wxLayoutLine::Draw(wxDC &dc,
|
||||
wxLayoutList *llist,
|
||||
const wxPoint & offset) const
|
||||
{
|
||||
wxLayoutObjectList::iterator i;
|
||||
wxPoint pos = offset;
|
||||
@@ -617,7 +640,9 @@ wxLayoutLine::Draw(wxDC &dc, const wxPoint & offset) const
|
||||
}
|
||||
|
||||
void
|
||||
wxLayoutLine::Layout(wxDC &dc, wxPoint *cursorPos,
|
||||
wxLayoutLine::Layout(wxDC &dc,
|
||||
wxLayoutList *llist,
|
||||
wxPoint *cursorPos,
|
||||
wxPoint *cursorSize,
|
||||
int cx)
|
||||
{
|
||||
@@ -641,6 +666,7 @@ wxLayoutLine::Layout(wxDC &dc, wxPoint *cursorPos,
|
||||
if(cursorPos)
|
||||
{
|
||||
*cursorPos = m_Position;
|
||||
if(cursorSize) *cursorSize = wxPoint(0,0);
|
||||
}
|
||||
|
||||
for(i = m_ObjectList.begin(); i != NULLIT; i++)
|
||||
@@ -718,7 +744,7 @@ wxLayoutLine::Layout(wxDC &dc, wxPoint *cursorPos,
|
||||
|
||||
// tell next line about coordinate change
|
||||
if(m_Next && objHeight != oldHeight)
|
||||
m_Next->RecalculatePositions();
|
||||
m_Next->RecalculatePositions(0, llist);
|
||||
|
||||
// We need to check whether we found a valid cursor size:
|
||||
if(cursorPos)
|
||||
@@ -726,20 +752,12 @@ wxLayoutLine::Layout(wxDC &dc, wxPoint *cursorPos,
|
||||
// this might be the case if the cursor is at the end of the
|
||||
// line or on a command object:
|
||||
if(cursorSize->y < WXLO_MINIMUM_CURSOR_WIDTH)
|
||||
{
|
||||
if(m_BaseLine > 0)
|
||||
{
|
||||
cursorSize->y = m_BaseLine;
|
||||
if(cursorSize->x < WXLO_MINIMUM_CURSOR_WIDTH) cursorSize->x = WXLO_MINIMUM_CURSOR_WIDTH;
|
||||
}
|
||||
else // empty line
|
||||
{
|
||||
CoordType width, height, descent;
|
||||
dc.GetTextExtent(WXLO_CURSORCHAR, &width, &height, &descent);
|
||||
cursorSize->x = width;
|
||||
cursorSize->y = height;
|
||||
}
|
||||
}
|
||||
if(m_BaseLine >= cursorSize->y) // the normal case anyway
|
||||
cursorPos->y += m_BaseLine-cursorSize->y;
|
||||
}
|
||||
@@ -747,13 +765,13 @@ wxLayoutLine::Layout(wxDC &dc, wxPoint *cursorPos,
|
||||
|
||||
|
||||
wxLayoutLine *
|
||||
wxLayoutLine::Break(CoordType xpos)
|
||||
wxLayoutLine::Break(CoordType xpos, wxLayoutList *llist)
|
||||
{
|
||||
wxASSERT(xpos >= 0);
|
||||
|
||||
if(xpos == 0)
|
||||
{ // insert an empty line before this one
|
||||
wxLayoutLine *prev = new wxLayoutLine(m_Previous);
|
||||
wxLayoutLine *prev = new wxLayoutLine(m_Previous, llist);
|
||||
if(m_Previous == NULL)
|
||||
{ // We were in first line, need to link in new empty line
|
||||
// before this.
|
||||
@@ -763,7 +781,7 @@ wxLayoutLine::Break(CoordType xpos)
|
||||
}
|
||||
MoveLines(+1);
|
||||
if(m_Next)
|
||||
m_Next->RecalculatePositions(1);
|
||||
m_Next->RecalculatePositions(1, llist);
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -771,10 +789,10 @@ wxLayoutLine::Break(CoordType xpos)
|
||||
wxLOiterator i = FindObject(xpos, &offset);
|
||||
if(i == NULLIT)
|
||||
// must be at the end of the line then
|
||||
return new wxLayoutLine(this);
|
||||
return new wxLayoutLine(this, llist);
|
||||
// split this line:
|
||||
|
||||
wxLayoutLine *newLine = new wxLayoutLine(this);
|
||||
wxLayoutLine *newLine = new wxLayoutLine(this, llist);
|
||||
// split object at i:
|
||||
if((**i).GetType() == WXLO_TYPE_TEXT && offset != 0)
|
||||
{
|
||||
@@ -799,13 +817,13 @@ wxLayoutLine::Break(CoordType xpos)
|
||||
m_ObjectList.remove(i); // remove without deleting it
|
||||
}
|
||||
if(m_Next)
|
||||
m_Next->RecalculatePositions(2);
|
||||
m_Next->RecalculatePositions(2, llist);
|
||||
return newLine;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
wxLayoutLine::MergeNextLine(void)
|
||||
wxLayoutLine::MergeNextLine(wxLayoutList *llist)
|
||||
{
|
||||
wxASSERT(GetNextLine());
|
||||
wxLayoutObjectList &list = GetNextLine()->m_ObjectList;
|
||||
@@ -820,7 +838,7 @@ wxLayoutLine::MergeNextLine(void)
|
||||
wxLayoutLine *oldnext = GetNextLine();
|
||||
SetNext(GetNextLine()->GetNextLine());
|
||||
delete oldnext;
|
||||
RecalculatePositions(1);
|
||||
RecalculatePositions(1, llist);
|
||||
}
|
||||
|
||||
CoordType
|
||||
@@ -890,6 +908,8 @@ wxLayoutList::wxLayoutList()
|
||||
{
|
||||
m_DefaultSetting = NULL;
|
||||
m_FirstLine = NULL;
|
||||
m_ColourFG = *wxBLACK;
|
||||
m_ColourBG = *wxWHITE;
|
||||
InvalidateUpdateRect();
|
||||
Clear();
|
||||
}
|
||||
@@ -897,20 +917,21 @@ wxLayoutList::wxLayoutList()
|
||||
wxLayoutList::~wxLayoutList()
|
||||
{
|
||||
InternalClear();
|
||||
m_FirstLine->DeleteLine(false);
|
||||
m_FirstLine->DeleteLine(false, this);
|
||||
}
|
||||
|
||||
void
|
||||
wxLayoutList::Empty(void)
|
||||
{
|
||||
while(m_FirstLine)
|
||||
m_FirstLine = m_FirstLine->DeleteLine(false);
|
||||
m_FirstLine = m_FirstLine->DeleteLine(false, this);
|
||||
|
||||
m_CursorPos = wxPoint(0,0);
|
||||
m_CursorScreenPos = wxPoint(0,0);
|
||||
m_CursorSize = wxPoint(0,0);
|
||||
m_FirstLine = new wxLayoutLine(NULL); // empty first line
|
||||
m_FirstLine = new wxLayoutLine(NULL, this); // empty first line
|
||||
m_CursorLine = m_FirstLine;
|
||||
InvalidateUpdateRect();
|
||||
}
|
||||
|
||||
|
||||
@@ -927,8 +948,8 @@ wxLayoutList::InternalClear(void)
|
||||
|
||||
void
|
||||
wxLayoutList::SetFont(int family, int size, int style, int weight,
|
||||
int underline, wxColour const *fg,
|
||||
wxColour const *bg)
|
||||
int underline, wxColour *fg,
|
||||
wxColour *bg)
|
||||
{
|
||||
if(family != -1) m_FontFamily = family;
|
||||
if(size != -1) m_FontPtSize = size;
|
||||
@@ -936,8 +957,8 @@ wxLayoutList::SetFont(int family, int size, int style, int weight,
|
||||
if(weight != -1) m_FontWeight = weight;
|
||||
if(underline != -1) m_FontUnderline = underline != 0;
|
||||
|
||||
if(fg != NULL) m_ColourFG = fg;
|
||||
if(bg != NULL) m_ColourBG = bg;
|
||||
if(fg != NULL) m_ColourFG = *fg;
|
||||
if(bg != NULL) m_ColourBG = *bg;
|
||||
|
||||
Insert(
|
||||
new wxLayoutObjectCmd(m_FontPtSize,m_FontFamily,m_FontStyle,m_FontWeight,m_FontUnderline,
|
||||
@@ -949,7 +970,7 @@ wxLayoutList::SetFont(int family, int size, int style, int weight,
|
||||
int underline, char const *fg, char const *bg)
|
||||
|
||||
{
|
||||
wxColour const
|
||||
wxColour
|
||||
*cfg = NULL,
|
||||
*cbg = NULL;
|
||||
|
||||
@@ -963,7 +984,7 @@ wxLayoutList::SetFont(int family, int size, int style, int weight,
|
||||
|
||||
void
|
||||
wxLayoutList::Clear(int family, int size, int style, int weight,
|
||||
int /* underline */, char const *fg, char const *bg)
|
||||
int /* underline */, wxColour *fg, wxColour *bg)
|
||||
{
|
||||
InternalClear();
|
||||
|
||||
@@ -973,11 +994,11 @@ wxLayoutList::Clear(int family, int size, int style, int weight,
|
||||
m_FontFamily = family;
|
||||
m_FontStyle = style;
|
||||
m_FontWeight = weight;
|
||||
m_ColourFG = wxTheColourDatabase->FindColour(fg);
|
||||
m_ColourBG = wxTheColourDatabase->FindColour(bg);
|
||||
if(fg) m_ColourFG = *fg;
|
||||
if(bg) m_ColourBG = *bg;
|
||||
|
||||
if(! m_ColourFG) m_ColourFG = wxBLACK;
|
||||
if(! m_ColourBG) m_ColourBG = wxWHITE;
|
||||
m_ColourFG = *wxBLACK;
|
||||
m_ColourBG = *wxWHITE;
|
||||
|
||||
if(m_DefaultSetting)
|
||||
delete m_DefaultSetting;
|
||||
@@ -993,6 +1014,8 @@ wxLayoutList::Clear(int family, int size, int style, int weight,
|
||||
bool
|
||||
wxLayoutList::MoveCursorTo(wxPoint const &p)
|
||||
{
|
||||
SetUpdateRect(m_CursorScreenPos);
|
||||
SetUpdateRect(m_CursorScreenPos+m_CursorSize);
|
||||
wxLayoutLine *line = m_FirstLine;
|
||||
while(line && line->GetLineNumber() != p.y)
|
||||
line = line->GetNextLine();
|
||||
@@ -1018,6 +1041,9 @@ wxLayoutList::MoveCursorTo(wxPoint const &p)
|
||||
bool
|
||||
wxLayoutList::MoveCursorVertically(int n)
|
||||
{
|
||||
SetUpdateRect(m_CursorScreenPos);
|
||||
SetUpdateRect(m_CursorScreenPos+m_CursorSize);
|
||||
bool rc;
|
||||
if(n < 0) // move up
|
||||
{
|
||||
if(m_CursorLine == m_FirstLine) return false;
|
||||
@@ -1031,13 +1057,13 @@ wxLayoutList::MoveCursorVertically(int n)
|
||||
{
|
||||
m_CursorLine = m_FirstLine;
|
||||
m_CursorPos.y = 0;
|
||||
return false;
|
||||
rc = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(m_CursorPos.x > m_CursorLine->GetLength())
|
||||
m_CursorPos.x = m_CursorLine->GetLength();
|
||||
return true;
|
||||
rc = true;
|
||||
}
|
||||
}
|
||||
else // move down
|
||||
@@ -1054,20 +1080,23 @@ wxLayoutList::MoveCursorVertically(int n)
|
||||
{
|
||||
m_CursorLine = last;
|
||||
m_CursorPos.y ++;
|
||||
return false;
|
||||
rc = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(m_CursorPos.x > m_CursorLine->GetLength())
|
||||
m_CursorPos.x = m_CursorLine->GetLength();
|
||||
return true;
|
||||
rc = true;
|
||||
}
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
bool
|
||||
wxLayoutList::MoveCursorHorizontally(int n)
|
||||
{
|
||||
SetUpdateRect(m_CursorScreenPos);
|
||||
SetUpdateRect(m_CursorScreenPos+m_CursorSize);
|
||||
int move;
|
||||
while(n < 0)
|
||||
{
|
||||
@@ -1107,6 +1136,8 @@ bool
|
||||
wxLayoutList::Insert(wxString const &text)
|
||||
{
|
||||
wxASSERT(m_CursorLine);
|
||||
SetUpdateRect(m_CursorScreenPos);
|
||||
SetUpdateRect(m_CursorScreenPos+m_CursorSize);
|
||||
m_CursorLine->Insert(m_CursorPos.x, text);
|
||||
m_CursorPos.x += text.Length();
|
||||
return true;
|
||||
@@ -1116,6 +1147,8 @@ bool
|
||||
wxLayoutList::Insert(wxLayoutObject *obj)
|
||||
{
|
||||
wxASSERT(m_CursorLine);
|
||||
SetUpdateRect(m_CursorScreenPos);
|
||||
SetUpdateRect(m_CursorScreenPos+m_CursorSize);
|
||||
m_CursorLine->Insert(m_CursorPos.x, obj);
|
||||
m_CursorPos.x += obj->GetLength();
|
||||
return true;
|
||||
@@ -1125,9 +1158,10 @@ bool
|
||||
wxLayoutList::LineBreak(void)
|
||||
{
|
||||
wxASSERT(m_CursorLine);
|
||||
|
||||
bool setFirst = (m_CursorLine == m_FirstLine && m_CursorPos.x == 0);
|
||||
m_CursorLine = m_CursorLine->Break(m_CursorPos.x);
|
||||
SetUpdateRect(m_CursorScreenPos);
|
||||
SetUpdateRect(m_CursorScreenPos+m_CursorSize);
|
||||
m_CursorLine = m_CursorLine->Break(m_CursorPos.x, this);
|
||||
if(setFirst) // we were at beginning of first line
|
||||
m_FirstLine = m_CursorLine->GetPreviousLine();
|
||||
m_CursorPos.y++;
|
||||
@@ -1148,6 +1182,8 @@ wxLayoutList::WrapLine(CoordType column)
|
||||
//else:
|
||||
CoordType newpos = m_CursorPos.x - xpos - 1;
|
||||
m_CursorPos.x = xpos;
|
||||
SetUpdateRect(m_CursorScreenPos);
|
||||
SetUpdateRect(m_CursorScreenPos+m_CursorSize);
|
||||
LineBreak();
|
||||
Delete(1); // delete the space
|
||||
m_CursorPos.x = newpos;
|
||||
@@ -1159,6 +1195,8 @@ bool
|
||||
wxLayoutList::Delete(CoordType npos)
|
||||
{
|
||||
wxASSERT(m_CursorLine);
|
||||
SetUpdateRect(m_CursorScreenPos);
|
||||
SetUpdateRect(m_CursorScreenPos+m_CursorSize);
|
||||
CoordType left;
|
||||
do
|
||||
{
|
||||
@@ -1184,7 +1222,7 @@ wxLayoutList::Delete(CoordType npos)
|
||||
break; // cannot
|
||||
else
|
||||
{
|
||||
m_CursorLine->MergeNextLine();
|
||||
m_CursorLine->MergeNextLine(this);
|
||||
left--;
|
||||
}
|
||||
}
|
||||
@@ -1198,6 +1236,8 @@ wxLayoutList::DeleteLines(int n)
|
||||
{
|
||||
wxASSERT(m_CursorLine);
|
||||
wxLayoutLine *line;
|
||||
SetUpdateRect(m_CursorScreenPos);
|
||||
SetUpdateRect(m_CursorScreenPos+m_CursorSize);
|
||||
while(n > 0)
|
||||
{
|
||||
if(!m_CursorLine->GetNextLine())
|
||||
@@ -1208,18 +1248,18 @@ wxLayoutList::DeleteLines(int n)
|
||||
}
|
||||
//else:
|
||||
line = m_CursorLine;
|
||||
m_CursorLine = m_CursorLine->DeleteLine(true);
|
||||
m_CursorLine = m_CursorLine->DeleteLine(true, this);
|
||||
n--;
|
||||
if(line == m_FirstLine) m_FirstLine = m_CursorLine;
|
||||
wxASSERT(m_FirstLine);
|
||||
wxASSERT(m_CursorLine);
|
||||
}
|
||||
m_CursorLine->RecalculatePositions(2);
|
||||
m_CursorLine->RecalculatePositions(2, this);
|
||||
return n;
|
||||
}
|
||||
|
||||
void
|
||||
wxLayoutList::Recalculate(wxDC &dc, CoordType bottom) const
|
||||
wxLayoutList::Recalculate(wxDC &dc, CoordType bottom)
|
||||
{
|
||||
wxLayoutLine *line = m_FirstLine;
|
||||
|
||||
@@ -1228,7 +1268,7 @@ wxLayoutList::Recalculate(wxDC &dc, CoordType bottom) const
|
||||
m_DefaultSetting->Layout(dc);
|
||||
while(line)
|
||||
{
|
||||
line->RecalculatePosition(); // so we don't need to do it all the time
|
||||
line->RecalculatePosition(this); // so we don't need to do it all the time
|
||||
// little condition to speed up redrawing:
|
||||
if(bottom != -1 && line->GetPosition().y > bottom) break;
|
||||
line = line->GetNextLine();
|
||||
@@ -1236,7 +1276,21 @@ wxLayoutList::Recalculate(wxDC &dc, CoordType bottom) const
|
||||
}
|
||||
|
||||
void
|
||||
wxLayoutList::Layout(wxDC &dc, CoordType bottom) const
|
||||
wxLayoutList::UpdateCursorScreenPos(wxDC &dc)
|
||||
{
|
||||
wxASSERT(m_CursorLine);
|
||||
m_CursorLine->Layout(dc, this, (wxPoint *)&m_CursorScreenPos, (wxPoint *)&m_CursorSize, m_CursorPos.x);
|
||||
}
|
||||
|
||||
wxPoint
|
||||
wxLayoutList::GetCursorScreenPos(wxDC &dc)
|
||||
{
|
||||
UpdateCursorScreenPos(dc);
|
||||
return m_CursorScreenPos;
|
||||
}
|
||||
|
||||
void
|
||||
wxLayoutList::Layout(wxDC &dc, CoordType bottom)
|
||||
{
|
||||
wxLayoutLine *line = m_FirstLine;
|
||||
|
||||
@@ -1246,9 +1300,9 @@ wxLayoutList::Layout(wxDC &dc, CoordType bottom) const
|
||||
while(line)
|
||||
{
|
||||
if(line == m_CursorLine)
|
||||
line->Layout(dc, (wxPoint *)&m_CursorScreenPos, (wxPoint *)&m_CursorSize, m_CursorPos.x);
|
||||
line->Layout(dc, this, (wxPoint *)&m_CursorScreenPos, (wxPoint *)&m_CursorSize, m_CursorPos.x);
|
||||
else
|
||||
line->Layout(dc);
|
||||
line->Layout(dc, this);
|
||||
// little condition to speed up redrawing:
|
||||
if(bottom != -1 && line->GetPosition().y > bottom) break;
|
||||
line = line->GetNextLine();
|
||||
@@ -1261,25 +1315,26 @@ wxLayoutList::Layout(wxDC &dc, CoordType bottom) const
|
||||
m_CursorLine->GetNextLine() == NULL &&
|
||||
m_CursorLine == m_FirstLine));
|
||||
#endif
|
||||
SetUpdateRect(m_CursorScreenPos);
|
||||
SetUpdateRect(m_CursorScreenPos+m_CursorSize);
|
||||
}
|
||||
|
||||
void
|
||||
wxLayoutList::Draw(wxDC &dc, wxPoint const &offset,
|
||||
CoordType top, CoordType bottom) const
|
||||
CoordType top, CoordType bottom)
|
||||
{
|
||||
wxLayoutLine *line = m_FirstLine;
|
||||
|
||||
Layout(dc, bottom);
|
||||
m_DefaultSetting->Draw(dc, wxPoint(0,0));
|
||||
wxBrush *brush = new wxBrush(*m_ColourBG, wxSOLID);
|
||||
dc.SetBrush(*brush);
|
||||
delete brush;
|
||||
wxBrush brush(m_ColourBG, wxSOLID);
|
||||
dc.SetBrush(brush);
|
||||
|
||||
while(line)
|
||||
{
|
||||
// only draw if between top and bottom:
|
||||
if((top == -1 || line->GetPosition().y >= top))
|
||||
line->Draw(dc, offset);
|
||||
line->Draw(dc, this, offset);
|
||||
// little condition to speed up redrawing:
|
||||
if(bottom != -1 && line->GetPosition().y + line->GetHeight() > bottom) break;
|
||||
line = line->GetNextLine();
|
||||
@@ -1288,6 +1343,7 @@ wxLayoutList::Draw(wxDC &dc, wxPoint const &offset,
|
||||
wxASSERT(m_CursorSize.x != 0 || (m_CursorLine &&
|
||||
m_CursorLine->GetNextLine() == NULL &&
|
||||
m_CursorLine == m_FirstLine));
|
||||
InvalidateUpdateRect();
|
||||
}
|
||||
|
||||
wxLayoutObject *
|
||||
@@ -1304,7 +1360,7 @@ wxLayoutList::FindObjectScreen(wxDC &dc, wxPoint const pos, wxPoint *cursorPos)
|
||||
p = line->GetPosition();
|
||||
if(p.y <= pos.y && p.y+line->GetHeight() >= pos.y)
|
||||
break;
|
||||
line->Layout(dc);
|
||||
line->Layout(dc, this);
|
||||
line = line->GetNextLine();
|
||||
}
|
||||
if(line == NULL) return NULL; // not found
|
||||
@@ -1387,6 +1443,27 @@ wxLayoutList::SetUpdateRect(const wxPoint &p)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
wxLayoutList::StartSelection(void)
|
||||
{
|
||||
wxLogDebug("Starting selection at %ld/%ld", m_CursorPos.x, m_CursorPos.y);
|
||||
m_Selection.m_CursorA = m_CursorPos;
|
||||
}
|
||||
|
||||
void
|
||||
wxLayoutList::EndSelection(void)
|
||||
{
|
||||
wxLogDebug("Ending selection at %ld/%ld", m_CursorPos.x, m_CursorPos.y);
|
||||
m_Selection.m_CursorB = m_CursorPos;
|
||||
}
|
||||
|
||||
bool
|
||||
wxLayoutList::IsSelected(const wxPoint &cursor)
|
||||
{
|
||||
return m_Selection.m_CursorA <= cursor
|
||||
&& cursor <= m_Selection.m_CursorB;
|
||||
}
|
||||
|
||||
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
|
||||
|
@@ -291,12 +291,12 @@ public:
|
||||
virtual void Draw(wxDC &dc, wxPoint const &coords);
|
||||
wxLayoutObjectCmd(int size, int family, int style, int weight,
|
||||
bool underline,
|
||||
wxColour const *fg, wxColour const *bg);
|
||||
wxColour &fg, wxColour &bg);
|
||||
~wxLayoutObjectCmd();
|
||||
/** Stores the current style in the styleinfo structure */
|
||||
void GetStyle(wxLayoutStyleInfo *si) const;
|
||||
/// return the background colour for setting colour of window
|
||||
wxColour const *GetBGColour(void) const { return m_ColourBG; }
|
||||
wxColour &GetBGColour(void) { return m_ColourBG; }
|
||||
/** Makes a copy of this object.
|
||||
*/
|
||||
virtual wxLayoutObject *Copy(void);
|
||||
@@ -304,9 +304,9 @@ private:
|
||||
/// the font to use
|
||||
wxFont *m_font;
|
||||
/// foreground colour
|
||||
wxColour const *m_ColourFG;
|
||||
wxColour m_ColourFG;
|
||||
/// background colour
|
||||
wxColour const *m_ColourBG;
|
||||
wxColour m_ColourBG;
|
||||
};
|
||||
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
@@ -315,6 +315,9 @@ private:
|
||||
|
||||
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||
|
||||
/// forward declaration
|
||||
class wxLayoutList;
|
||||
|
||||
/** This class represents a single line of objects to be displayed.
|
||||
It knows its height and total size and whether it needs to be
|
||||
redrawn or not.
|
||||
@@ -327,8 +330,9 @@ public:
|
||||
/** Constructor.
|
||||
@param prev pointer to previous line or NULL
|
||||
@param next pointer to following line or NULL
|
||||
@param llist pointer to layout list
|
||||
*/
|
||||
wxLayoutLine(wxLayoutLine *prev);
|
||||
wxLayoutLine(wxLayoutLine *prev, wxLayoutList *llist);
|
||||
/** This function inserts a new object at cursor position xpos.
|
||||
@param xpos where to insert new object
|
||||
@param obj the object to insert
|
||||
@@ -356,7 +360,7 @@ public:
|
||||
/** This function appens the next line to this, i.e. joins the two
|
||||
lines into one.
|
||||
*/
|
||||
void MergeNextLine(void);
|
||||
void MergeNextLine(wxLayoutList *llist);
|
||||
|
||||
/** This function deletes npos cursor positions from position xpos.
|
||||
@param xpos where to delete
|
||||
@@ -369,7 +373,7 @@ public:
|
||||
@param xpos where to break it
|
||||
@return pointer to the new line object replacing the old one
|
||||
*/
|
||||
wxLayoutLine *Break(CoordType xpos);
|
||||
wxLayoutLine *Break(CoordType xpos, wxLayoutList *llist);
|
||||
|
||||
/** Deletes the next word from this position, including leading
|
||||
whitespace.
|
||||
@@ -423,7 +427,7 @@ public:
|
||||
/** Deletes this line, returns pointer to next line.
|
||||
@param update If true, update all following lines.
|
||||
*/
|
||||
wxLayoutLine *DeleteLine(bool update);
|
||||
wxLayoutLine *DeleteLine(bool update, wxLayoutList *llist);
|
||||
|
||||
/**@name Cursor Management */
|
||||
//@{
|
||||
@@ -441,18 +445,23 @@ public:
|
||||
//@{
|
||||
/** Draws the line on a wxDC.
|
||||
@param dc the wxDC to draw on
|
||||
@param llist the wxLayoutList
|
||||
@param offset an optional offset to shift printout
|
||||
*/
|
||||
void Draw(wxDC &dc, const wxPoint &offset = wxPoint(0,0)) const;
|
||||
void Draw(wxDC &dc,
|
||||
wxLayoutList *llist,
|
||||
const wxPoint &offset = wxPoint(0,0)) const;
|
||||
|
||||
/** Recalculates the positions of objects and the height of the
|
||||
line.
|
||||
@param dc the wxDC to draw on
|
||||
@param llist th e wxLayoutList
|
||||
@param cursorPos if not NULL, set cursor screen position in there
|
||||
@param cursorSize if not cursorPos != NULL, set cursor size in there
|
||||
@param cx if cursorPos != NULL, the cursor x position
|
||||
*/
|
||||
void Layout(wxDC &dc,
|
||||
wxLayoutList *llist,
|
||||
wxPoint *cursorPos = NULL,
|
||||
wxPoint *cursorSize = NULL,
|
||||
int cx = 0);
|
||||
@@ -493,9 +502,9 @@ public:
|
||||
minimum(!) recursion level, continue with all lines till the end of
|
||||
the list or until the coordinates no longer changed.
|
||||
*/
|
||||
void RecalculatePositions(int recurse = 0);
|
||||
void RecalculatePositions(int recurse, wxLayoutList *llist);
|
||||
/// Recalculates the position of this line on the canvas.
|
||||
wxPoint RecalculatePosition(void);
|
||||
wxPoint RecalculatePosition(wxLayoutList *llist);
|
||||
private:
|
||||
/// Destructor is private. Use DeleteLine() to remove it.
|
||||
~wxLayoutLine();
|
||||
@@ -506,8 +515,8 @@ private:
|
||||
dirty.
|
||||
@param height new height
|
||||
*/
|
||||
void SetHeight(CoordType height)
|
||||
{ m_Height = height; RecalculatePositions(true); }
|
||||
void SetHeight(CoordType height, wxLayoutList *llist)
|
||||
{ m_Height = height; RecalculatePositions(true, llist); }
|
||||
|
||||
/** Moves the linenumbers one on, because a line has been inserted
|
||||
or deleted.
|
||||
@@ -542,6 +551,8 @@ private:
|
||||
wxLayoutLine *m_Next;
|
||||
/// Just to suppress gcc compiler warnings.
|
||||
friend class dummy;
|
||||
private:
|
||||
wxLayoutLine(const wxLayoutLine &);
|
||||
};
|
||||
|
||||
|
||||
@@ -568,8 +579,8 @@ public:
|
||||
int style=wxNORMAL,
|
||||
int weight=wxNORMAL,
|
||||
int underline=0,
|
||||
char const *fg="black",
|
||||
char const *bg="white");
|
||||
wxColour *fg=NULL,
|
||||
wxColour *bg=NULL);
|
||||
/// Empty: clear the list but leave font settings.
|
||||
void Empty(void);
|
||||
|
||||
@@ -603,7 +614,7 @@ public:
|
||||
{ MoveCursorHorizontally(-m_CursorPos.x); }
|
||||
|
||||
/// Returns current cursor position.
|
||||
wxPoint GetCursorPos(void) const { return m_CursorPos; }
|
||||
wxPoint GetCursorPos(wxDC &dc) const { return m_CursorPos; }
|
||||
//@}
|
||||
|
||||
/**@name Editing functions.
|
||||
@@ -669,8 +680,8 @@ public:
|
||||
/// sets font parameters
|
||||
void SetFont(int family, int size, int style,
|
||||
int weight, int underline,
|
||||
wxColour const *fg,
|
||||
wxColour const *bg);
|
||||
wxColour *fg,
|
||||
wxColour *bg);
|
||||
/// sets font parameters, colours by name
|
||||
void SetFont(int family=-1, int size = -1, int style=-1,
|
||||
int weight=-1, int underline = -1,
|
||||
@@ -701,7 +712,7 @@ public:
|
||||
anywhere.
|
||||
@return the default settings of the list
|
||||
*/
|
||||
wxLayoutObjectCmd const *GetDefaults(void) const { return m_DefaultSetting ; }
|
||||
wxLayoutObjectCmd *GetDefaults(void) { return m_DefaultSetting ; }
|
||||
//@}
|
||||
|
||||
/**@name Drawing */
|
||||
@@ -713,21 +724,21 @@ public:
|
||||
@param bottom optional y coordinate where to stop drawing
|
||||
*/
|
||||
void Draw(wxDC &dc, const wxPoint &offset = wxPoint(0,0),
|
||||
CoordType top = -1, CoordType bottom = -1) const;
|
||||
CoordType top = -1, CoordType bottom = -1);
|
||||
|
||||
/** Calculates new layout for the list, like Draw() but does not
|
||||
actually draw it.
|
||||
@param dc the wxDC to draw on
|
||||
@param bottom optional y coordinate where to stop calculating
|
||||
*/
|
||||
void Layout(wxDC &dc, CoordType bottom = -1) const;
|
||||
void Layout(wxDC &dc, CoordType bottom = -1);
|
||||
|
||||
/** Calculates new sizes for everything in the list, like Layout()
|
||||
but this is needed after the list got changed.
|
||||
@param dc the wxDC to draw on
|
||||
@param bottom optional y coordinate where to stop calculating
|
||||
*/
|
||||
void Recalculate(wxDC &dc, CoordType bottom = -1) const;
|
||||
void Recalculate(wxDC &dc, CoordType bottom = -1);
|
||||
|
||||
/** Returns the size of the list in screen coordinates.
|
||||
The return value only makes sense after the list has been
|
||||
@@ -740,8 +751,7 @@ public:
|
||||
/** Returns the cursor position on the screen.
|
||||
@return cursor position in pixels
|
||||
*/
|
||||
wxPoint GetCursorScreenPos(void) const
|
||||
{ return m_CursorScreenPos; }
|
||||
wxPoint GetCursorScreenPos(wxDC &dc);
|
||||
|
||||
/** Draws the cursor.
|
||||
@param active If true, draw a bold cursor to mark window as
|
||||
@@ -781,9 +791,17 @@ public:
|
||||
return m_FirstLine;
|
||||
}
|
||||
//@}
|
||||
|
||||
void StartSelection(void);
|
||||
void EndSelection(void);
|
||||
bool IsSelected(const wxPoint &cursor);
|
||||
|
||||
private:
|
||||
/// Clear the list.
|
||||
void InternalClear(void);
|
||||
/** Calculates the cursor position on the screen.
|
||||
*/
|
||||
void UpdateCursorScreenPos(wxDC &dc);
|
||||
|
||||
/// The list of lines.
|
||||
wxLayoutLine *m_FirstLine;
|
||||
@@ -803,14 +821,20 @@ private:
|
||||
wxLayoutLine *m_CursorLine;
|
||||
//@}
|
||||
|
||||
/// A structure for the selection.
|
||||
struct
|
||||
{
|
||||
bool m_valid;
|
||||
wxPoint m_CursorA, m_CursorB;
|
||||
}m_Selection;
|
||||
/** @name Font parameters. */
|
||||
//@{
|
||||
int m_FontFamily, m_FontStyle, m_FontWeight;
|
||||
int m_FontPtSize;
|
||||
bool m_FontUnderline;
|
||||
/// colours:
|
||||
wxColour const * m_ColourFG;
|
||||
wxColour const * m_ColourBG;
|
||||
wxColour m_ColourFG;
|
||||
wxColour m_ColourBG;
|
||||
/// the default setting:
|
||||
wxLayoutObjectCmd *m_DefaultSetting;
|
||||
//@}
|
||||
|
@@ -78,11 +78,13 @@ wxLayoutWindow::wxLayoutWindow(wxWindow *parent)
|
||||
m_bitmapSize = wxPoint(4,4);
|
||||
m_llist = new wxLayoutList();
|
||||
m_BGbitmap = NULL;
|
||||
m_ScrollToCursor = false;
|
||||
SetWrapMargin(0);
|
||||
wxPoint max = m_llist->GetSize();
|
||||
SetScrollbars(10, 20 /*lineHeight*/, max.x/10+1, max.y/20+1);
|
||||
EnableScrolling(true,true);
|
||||
m_maxx = max.x; m_maxy = max.y;
|
||||
m_Selecting = false;
|
||||
SetCursor(wxCURSOR_IBEAM);
|
||||
SetDirty();
|
||||
}
|
||||
@@ -144,7 +146,7 @@ wxLayoutWindow::OnMouse(int eventId, wxMouseEvent& event)
|
||||
if(obj && eventId == WXLOWIN_MENU_LCLICK)
|
||||
{
|
||||
m_llist->MoveCursorTo(cursorPos);
|
||||
DoPaint(false);
|
||||
m_ScrollToCursor = true; //FIXME: needed? DoPaint(m_llist->GetUpdateRect());
|
||||
}
|
||||
if(!m_doSendEvents) // nothing to do
|
||||
return;
|
||||
@@ -181,11 +183,18 @@ wxLayoutWindow::OnChar(wxKeyEvent& event)
|
||||
}
|
||||
|
||||
long keyCode = event.KeyCode();
|
||||
|
||||
if(event.ShiftDown())
|
||||
m_Selecting = true;
|
||||
else
|
||||
{
|
||||
if(m_Selecting)
|
||||
m_llist->EndSelection();
|
||||
m_Selecting = false;
|
||||
}
|
||||
/* First, handle control keys */
|
||||
if(event.ControlDown() && ! event.AltDown())
|
||||
{
|
||||
switch(event.KeyCode())
|
||||
switch(keyCode)
|
||||
{
|
||||
case WXK_DELETE :
|
||||
case 'd':
|
||||
@@ -215,7 +224,7 @@ wxLayoutWindow::OnChar(wxKeyEvent& event)
|
||||
// ALT only:
|
||||
else if( event.AltDown() && ! event.ControlDown() )
|
||||
{
|
||||
switch(event.KeyCode())
|
||||
switch(keyCode)
|
||||
{
|
||||
case WXK_DELETE:
|
||||
case 'd':
|
||||
@@ -228,30 +237,38 @@ wxLayoutWindow::OnChar(wxKeyEvent& event)
|
||||
// no control keys:
|
||||
else if ( ! event.AltDown() && ! event.ControlDown())
|
||||
{
|
||||
switch(event.KeyCode())
|
||||
switch(keyCode)
|
||||
{
|
||||
case WXK_RIGHT:
|
||||
if(m_Selecting) m_llist->StartSelection();
|
||||
m_llist->MoveCursorHorizontally(1);
|
||||
break;
|
||||
case WXK_LEFT:
|
||||
if(m_Selecting) m_llist->StartSelection();
|
||||
m_llist->MoveCursorHorizontally(-1);
|
||||
break;
|
||||
case WXK_UP:
|
||||
if(m_Selecting) m_llist->StartSelection();
|
||||
m_llist->MoveCursorVertically(-1);
|
||||
break;
|
||||
case WXK_DOWN:
|
||||
if(m_Selecting) m_llist->StartSelection();
|
||||
m_llist->MoveCursorVertically(1);
|
||||
break;
|
||||
case WXK_PRIOR:
|
||||
if(m_Selecting) m_llist->StartSelection();
|
||||
m_llist->MoveCursorVertically(-20);
|
||||
break;
|
||||
case WXK_NEXT:
|
||||
if(m_Selecting) m_llist->StartSelection();
|
||||
m_llist->MoveCursorVertically(20);
|
||||
break;
|
||||
case WXK_HOME:
|
||||
if(m_Selecting) m_llist->StartSelection();
|
||||
m_llist->MoveCursorToBeginOfLine();
|
||||
break;
|
||||
case WXK_END:
|
||||
if(m_Selecting) m_llist->StartSelection();
|
||||
m_llist->MoveCursorToEndOfLine();
|
||||
break;
|
||||
case WXK_DELETE :
|
||||
@@ -281,29 +298,32 @@ wxLayoutWindow::OnChar(wxKeyEvent& event)
|
||||
}
|
||||
SetDirty();
|
||||
SetModified();
|
||||
DoPaint(true); // paint and scroll to cursor
|
||||
m_ScrollToCursor = true;
|
||||
//DoPaint(true); // paint and scroll to cursor
|
||||
wxRect r = *m_llist->GetUpdateRect();
|
||||
r.x -= WXLO_XOFFSET; r.y -= WXLO_YOFFSET;
|
||||
Refresh( FALSE, &r);
|
||||
}
|
||||
|
||||
void
|
||||
wxLayoutWindow::OnPaint( wxPaintEvent &WXUNUSED(event)) // or: OnDraw(wxDC& dc)
|
||||
{
|
||||
m_ScrollToCursor = false;
|
||||
InternalPaint();
|
||||
wxRect region = GetUpdateRegion().GetBox();
|
||||
InternalPaint(& region);
|
||||
}
|
||||
|
||||
void
|
||||
wxLayoutWindow::DoPaint(bool scrollToCursor)
|
||||
wxLayoutWindow::DoPaint(const wxRect *updateRect)
|
||||
{
|
||||
m_ScrollToCursor = scrollToCursor;
|
||||
#ifdef __WXGTK__
|
||||
InternalPaint();
|
||||
InternalPaint(updateRect);
|
||||
#else
|
||||
Refresh(FALSE); // Causes bad flicker under wxGTK!!!
|
||||
Refresh(FALSE, updateRect); // Causes bad flicker under wxGTK!!!
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
wxLayoutWindow::InternalPaint(void)
|
||||
wxLayoutWindow::InternalPaint(const wxRect *updateRect)
|
||||
{
|
||||
wxPaintDC dc( this );
|
||||
PrepareDC( dc );
|
||||
@@ -324,12 +344,26 @@ wxLayoutWindow::InternalPaint(void)
|
||||
if(x1 > m_maxx) m_maxx = x1;
|
||||
if(y1 > m_maxy) m_maxy = y1;
|
||||
|
||||
|
||||
m_llist->InvalidateUpdateRect();
|
||||
const wxRect *r = m_llist->GetUpdateRect();
|
||||
wxLogDebug("Update rect before calling Layout: %ld,%ld / %ld,%ld",
|
||||
r->x, r->y, r->x+r->width, r->y+r->height);
|
||||
|
||||
#if 0
|
||||
//FIXME: we should never need to call Layout at all because the
|
||||
// list does it automatically.
|
||||
// Maybe we need to change the scrollbar sizes or positions,
|
||||
// so layout the list and check:
|
||||
if(IsDirty())
|
||||
m_llist->Layout(dc);
|
||||
wxLogDebug("Update rect after calling Layout: %ld,%ld / %ld,%ld",
|
||||
r->x, r->y, r->x+r->width, r->y+r->height);
|
||||
// this is needed even when only the cursor moved
|
||||
m_llist->Layout(dc,y0+y1);
|
||||
wxLogDebug("Update rect after calling Layout again: %ld,%ld / %ld,%ld",
|
||||
r->x, r->y, r->x+r->width, r->y+r->height);
|
||||
#endif
|
||||
|
||||
if(IsDirty())
|
||||
ResizeScrollbars();
|
||||
@@ -337,9 +371,10 @@ wxLayoutWindow::InternalPaint(void)
|
||||
/* Make sure that the scrollbars are at a position so that the
|
||||
cursor is visible if we are editing. */
|
||||
/** Scroll so that cursor is visible! */
|
||||
wxLogDebug("m_ScrollToCursor = %d", (int) m_ScrollToCursor);
|
||||
if(IsEditable() && m_ScrollToCursor)
|
||||
{
|
||||
wxPoint cc = m_llist->GetCursorScreenPos();
|
||||
wxPoint cc = m_llist->GetCursorScreenPos(*m_memDC);
|
||||
if(cc.x < x0 || cc.y < y0
|
||||
|| cc.x >= x0+(9*x1)/10 || cc.y >= y0+(9*y1/10)) // (9*x)/10 == 90%
|
||||
{
|
||||
@@ -368,8 +403,8 @@ wxLayoutWindow::InternalPaint(void)
|
||||
// with the translate parameter of Draw().
|
||||
m_memDC->SetDeviceOrigin(0,0);
|
||||
m_memDC->SetBackgroundMode(wxTRANSPARENT);
|
||||
m_memDC->SetBrush(wxBrush(*m_llist->GetDefaults()->GetBGColour(), wxSOLID));
|
||||
m_memDC->SetPen(wxPen(*m_llist->GetDefaults()->GetBGColour(),0,wxTRANSPARENT));
|
||||
m_memDC->SetBrush(wxBrush(m_llist->GetDefaults()->GetBGColour(), wxSOLID));
|
||||
m_memDC->SetPen(wxPen(m_llist->GetDefaults()->GetBGColour(),0,wxTRANSPARENT));
|
||||
m_memDC->SetLogicalFunction(wxCOPY);
|
||||
if(m_BGbitmap)
|
||||
{
|
||||
@@ -391,15 +426,23 @@ wxLayoutWindow::InternalPaint(void)
|
||||
m_llist->DrawCursor(*m_memDC,m_HaveFocus,offset);
|
||||
|
||||
// Now copy everything to the screen:
|
||||
#if 0
|
||||
//FIXME:
|
||||
// 1. the update region as calculated by the list is wrong
|
||||
// 2. we get wrong values here
|
||||
// 3. how about the offset?
|
||||
wxRegionIterator ri ( GetUpdateRegion() );
|
||||
if(ri)
|
||||
while(ri)
|
||||
{
|
||||
wxLogDebug("UpdateRegion: %ld,%ld, %ld,%ld",
|
||||
ri.GetX(),ri.GetY(),ri.GetW(),ri.GetH());
|
||||
dc.Blit(x0+ri.GetX(),y0+ri.GetY(),ri.GetW(),ri.GetH(),
|
||||
m_memDC,ri.GetX(),ri.GetY(),wxCOPY,FALSE);
|
||||
ri++;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
// If there are no update rectangles, we got called to reflect
|
||||
// a change in the list. Currently there is no mechanism to
|
||||
// easily find out which bits need updating, so we update
|
||||
@@ -408,6 +451,7 @@ wxLayoutWindow::InternalPaint(void)
|
||||
dc.Blit(x0,y0,x1,y1,m_memDC,0,0,wxCOPY,FALSE);
|
||||
|
||||
ResetDirty();
|
||||
m_ScrollToCursor = false;
|
||||
}
|
||||
|
||||
// change the range and position of scroll bars
|
||||
@@ -522,12 +566,12 @@ void
|
||||
wxLayoutWindow::OnSetFocus(wxFocusEvent &ev)
|
||||
{
|
||||
m_HaveFocus = true;
|
||||
DoPaint(); // to repaint the cursor
|
||||
//FIXME DoPaint(); // to repaint the cursor
|
||||
}
|
||||
|
||||
void
|
||||
wxLayoutWindow::OnKillFocus(wxFocusEvent &ev)
|
||||
{
|
||||
m_HaveFocus = false;
|
||||
DoPaint(); // to repaint the cursor
|
||||
//FIXME DoPaint(); // to repaint the cursor
|
||||
}
|
||||
|
@@ -63,15 +63,20 @@ public:
|
||||
int style=wxNORMAL,
|
||||
int weight=wxNORMAL,
|
||||
int underline=0,
|
||||
char const *fg="black",
|
||||
char const *bg="white")
|
||||
wxColour *fg=NULL,
|
||||
wxColour *bg=NULL)
|
||||
{
|
||||
GetLayoutList()->Clear(family,size,style,weight,underline,fg,bg);
|
||||
SetBackgroundColour(*GetLayoutList()->GetDefaults()->GetBGColour());
|
||||
SetBackgroundColour(GetLayoutList()->GetDefaults()->GetBGColour());
|
||||
ResizeScrollbars(true);
|
||||
SetDirty();
|
||||
SetModified(false);
|
||||
DoPaint();
|
||||
wxRect r;
|
||||
int w,h;
|
||||
r.x = r.y = 0; GetSize(&w,&h);
|
||||
r.width = w;
|
||||
r.height = h;
|
||||
DoPaint(&r);
|
||||
}
|
||||
/** Sets a background image, only used on screen, not on printouts.
|
||||
@param bitmap a pointer to a wxBitmap or NULL to remove it
|
||||
@@ -100,10 +105,8 @@ public:
|
||||
/** Redraws the window.
|
||||
Internally, this stores the parameter and calls a refresh on
|
||||
wxMSW, draws directly on wxGTK.
|
||||
@param scrollToCursor if true, scroll the window so that the
|
||||
cursor becomes visible
|
||||
*/
|
||||
void DoPaint(bool scrollToCursor = false);
|
||||
void DoPaint(const wxRect *updateRect);
|
||||
|
||||
#ifdef __WXMSW__
|
||||
virtual long MSWGetDlgCode();
|
||||
@@ -144,7 +147,7 @@ public:
|
||||
void ResetDirty(void) { m_Dirty = false; }
|
||||
//@}
|
||||
/// Redraws the window, used by DoPaint() or OnPaint().
|
||||
void InternalPaint(void);
|
||||
void InternalPaint(const wxRect *updateRect);
|
||||
|
||||
/// Has list been modified/edited?
|
||||
bool IsModified(void) const { return m_Modified; }
|
||||
@@ -180,6 +183,8 @@ private:
|
||||
wxLayoutList *m_llist;
|
||||
/// Can user edit the window?
|
||||
bool m_Editable;
|
||||
/// Are we currently building a selection with the keyboard?
|
||||
bool m_Selecting;
|
||||
/// wrap margin
|
||||
CoordType m_WrapMargin;
|
||||
/// Is list dirty (for redraws, internal use)?
|
||||
|
Reference in New Issue
Block a user