Updated from Mahogany source
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/branches/WX_2_2_BRANCH@7378 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -10,6 +10,14 @@ by Karsten Ballueder <ballueder@usa.net>.
|
|||||||
This is still work in progress, so if you want to make any significant
|
This is still work in progress, so if you want to make any significant
|
||||||
changes, please get in touch with me before.
|
changes, please get in touch with me before.
|
||||||
|
|
||||||
|
|
||||||
|
*** THIS SOURCE IS USUALLY OUTDATED AND FOR DEMONSTRATION ONLY ***
|
||||||
|
*** GET THE VERY LATEST VERSION OF THE WXLAYOUT CLASSES FROM ***
|
||||||
|
*** THE SOURCE OF THE MAHOGANY MAIL/NEWS CLIENT, AVAILABLE FROM ***
|
||||||
|
*** http://www.wxwindows.org/Mahogany/ ***
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
There are three building blocks for rich text editing:
|
There are three building blocks for rich text editing:
|
||||||
|
|
||||||
wxllist :
|
wxllist :
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
/*-*- c++ -*-********************************************************
|
/*-*- c++ -*-********************************************************
|
||||||
* wxllist: wxLayoutList, a layout engine for text and graphics *
|
* wxllist: wxLayoutList, a layout engine for text and graphics *
|
||||||
* *
|
* *
|
||||||
* (C) 1998-1999 by Karsten Ball<6C>der (Ballueder@usa.net) *
|
* (C) 1998-2000 by Karsten Ball<6C>der (Ballueder@gmx.net) *
|
||||||
* *
|
* *
|
||||||
* $Id$
|
* $Id$
|
||||||
*******************************************************************/
|
*******************************************************************/
|
||||||
@@ -60,6 +60,7 @@
|
|||||||
|
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
|
||||||
|
|
||||||
/// This should never really get created
|
/// This should never really get created
|
||||||
#define WXLLIST_TEMPFILE "__wxllist.tmp"
|
#define WXLLIST_TEMPFILE "__wxllist.tmp"
|
||||||
|
|
||||||
@@ -72,16 +73,19 @@
|
|||||||
{
|
{
|
||||||
"invalid", "text", "cmd", "icon"
|
"invalid", "text", "cmd", "icon"
|
||||||
};
|
};
|
||||||
void
|
wxString
|
||||||
wxLayoutObject::Debug(void)
|
wxLayoutObject::DebugDump(void) const
|
||||||
{
|
{
|
||||||
WXLO_DEBUG(("%s",g_aTypeStrings[GetType()]));
|
wxString str;
|
||||||
|
str.Printf("%s",g_aTypeStrings[GetType()]);
|
||||||
|
return str;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
# define TypeString(t) ""
|
# define TypeString(t) ""
|
||||||
# define WXLO_DEBUG(x)
|
# define WXLO_DEBUG(x)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
// FIXME under MSW, this constant is needed to make the thing properly redraw
|
// FIXME under MSW, this constant is needed to make the thing properly redraw
|
||||||
// itself - I don't know where the size calculation error is and I can't
|
// itself - I don't know where the size calculation error is and I can't
|
||||||
// waste time looking for it right now. Search for occurences of
|
// waste time looking for it right now. Search for occurences of
|
||||||
@@ -165,6 +169,7 @@ bool Contains(const wxRect &r, const wxPoint &p)
|
|||||||
//@}
|
//@}
|
||||||
|
|
||||||
|
|
||||||
|
static
|
||||||
void ReadString(wxString &to, wxString &from)
|
void ReadString(wxString &to, wxString &from)
|
||||||
{
|
{
|
||||||
to = "";
|
to = "";
|
||||||
@@ -187,7 +192,7 @@ wxLayoutObject::Read(wxString &istr)
|
|||||||
{
|
{
|
||||||
wxString tmp;
|
wxString tmp;
|
||||||
ReadString(tmp, istr);
|
ReadString(tmp, istr);
|
||||||
int type = -1;
|
int type = WXLO_TYPE_INVALID;
|
||||||
sscanf(tmp.c_str(),"%d", &type);
|
sscanf(tmp.c_str(),"%d", &type);
|
||||||
|
|
||||||
switch(type)
|
switch(type)
|
||||||
@@ -370,11 +375,14 @@ wxLayoutObjectText::Layout(wxDC &dc, class wxLayoutList *llist)
|
|||||||
|
|
||||||
|
|
||||||
#ifdef WXLAYOUT_DEBUG
|
#ifdef WXLAYOUT_DEBUG
|
||||||
void
|
wxString
|
||||||
wxLayoutObjectText::Debug(void)
|
wxLayoutObjectText::DebugDump(void) const
|
||||||
{
|
{
|
||||||
wxLayoutObject::Debug();
|
wxString str;
|
||||||
WXLO_DEBUG((" `%s`", m_Text.c_str()));
|
str = wxLayoutObject::DebugDump();
|
||||||
|
wxString str2;
|
||||||
|
str2.Printf(" `%s`", m_Text.c_str());
|
||||||
|
return str+str2;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -412,7 +420,7 @@ wxLayoutObjectIcon::Write(wxString &ostr)
|
|||||||
|
|
||||||
wxString file = wxGetTempFileName("wxloexport");
|
wxString file = wxGetTempFileName("wxloexport");
|
||||||
|
|
||||||
ostr << WXLO_TYPE_ICON << '\n'
|
ostr << (int) WXLO_TYPE_ICON << '\n'
|
||||||
<< file << '\n';
|
<< file << '\n';
|
||||||
m_Icon->SaveFile(file, WXLO_BITMAP_FORMAT);
|
m_Icon->SaveFile(file, WXLO_BITMAP_FORMAT);
|
||||||
}
|
}
|
||||||
@@ -449,11 +457,7 @@ wxLayoutObjectIcon::wxLayoutObjectIcon(wxBitmap *icon)
|
|||||||
{
|
{
|
||||||
m_Icon = icon;
|
m_Icon = icon;
|
||||||
if(! m_Icon)
|
if(! m_Icon)
|
||||||
#if wxICON_IS_BITMAP
|
|
||||||
m_Icon = new wxIcon;
|
|
||||||
#else
|
|
||||||
m_Icon = new wxBitmap;
|
m_Icon = new wxBitmap;
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -557,25 +561,25 @@ wxLayoutObjectCmd::Copy(void)
|
|||||||
void
|
void
|
||||||
wxLayoutObjectCmd::Write(wxString &ostr)
|
wxLayoutObjectCmd::Write(wxString &ostr)
|
||||||
{
|
{
|
||||||
ostr << WXLO_TYPE_CMD << '\n'
|
ostr << (int) WXLO_TYPE_CMD << '\n'
|
||||||
<< m_StyleInfo->family << '\n'
|
<< (int) m_StyleInfo->family << '\n'
|
||||||
<< m_StyleInfo->size << '\n'
|
<< (int) m_StyleInfo->size << '\n'
|
||||||
<< m_StyleInfo->style << '\n'
|
<< (int) m_StyleInfo->style << '\n'
|
||||||
<< m_StyleInfo->weight << '\n'
|
<< (int) m_StyleInfo->weight << '\n'
|
||||||
<< m_StyleInfo->underline << '\n'
|
<< (int) m_StyleInfo->underline << '\n'
|
||||||
<< m_StyleInfo->m_fg_valid << '\n'
|
<< (int) m_StyleInfo->m_fg_valid << '\n'
|
||||||
<< m_StyleInfo->m_bg_valid << '\n';
|
<< (int) m_StyleInfo->m_bg_valid << '\n';
|
||||||
if(m_StyleInfo->m_fg_valid)
|
if(m_StyleInfo->m_fg_valid)
|
||||||
{
|
{
|
||||||
ostr << m_StyleInfo->m_fg.Red() << '\n'
|
ostr << (int) m_StyleInfo->m_fg.Red() << '\n'
|
||||||
<< m_StyleInfo->m_fg.Green() << '\n'
|
<< (int) m_StyleInfo->m_fg.Green() << '\n'
|
||||||
<< m_StyleInfo->m_fg.Blue() << '\n';
|
<< (int) m_StyleInfo->m_fg.Blue() << '\n';
|
||||||
}
|
}
|
||||||
if(m_StyleInfo->m_bg_valid)
|
if(m_StyleInfo->m_bg_valid)
|
||||||
{
|
{
|
||||||
ostr << m_StyleInfo->m_bg.Red() << '\n'
|
ostr << (int) m_StyleInfo->m_bg.Red() << '\n'
|
||||||
<< m_StyleInfo->m_bg.Green() << '\n'
|
<< (int) m_StyleInfo->m_bg.Green() << '\n'
|
||||||
<< m_StyleInfo->m_bg.Blue() << '\n';
|
<< (int) m_StyleInfo->m_bg.Blue() << '\n';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* static */
|
/* static */
|
||||||
@@ -665,10 +669,9 @@ wxLayoutLine::wxLayoutLine(wxLayoutLine *prev, wxLayoutList *llist)
|
|||||||
m_Length = 0;
|
m_Length = 0;
|
||||||
|
|
||||||
m_updateLeft = -1;
|
m_updateLeft = -1;
|
||||||
MarkDirty(0);
|
|
||||||
|
|
||||||
m_Previous = prev;
|
m_Previous = prev;
|
||||||
m_Next = NULL;
|
m_Next = NULL;
|
||||||
|
MarkDirty(0);
|
||||||
|
|
||||||
m_LineNumber = 0;
|
m_LineNumber = 0;
|
||||||
RecalculatePosition(llist);
|
RecalculatePosition(llist);
|
||||||
@@ -1273,7 +1276,9 @@ wxLayoutLine::Break(CoordType xpos, wxLayoutList *llist)
|
|||||||
|
|
||||||
wxLayoutLine *newLine = new wxLayoutLine(this, llist);
|
wxLayoutLine *newLine = new wxLayoutLine(this, llist);
|
||||||
// split object at i:
|
// split object at i:
|
||||||
if((**i).GetType() == WXLO_TYPE_TEXT && offset != 0)
|
if((**i).GetType() == WXLO_TYPE_TEXT
|
||||||
|
&& offset != 0
|
||||||
|
&& offset != (**i).GetLength() )
|
||||||
{
|
{
|
||||||
wxString left, right;
|
wxString left, right;
|
||||||
wxLayoutObjectText *tobj = (wxLayoutObjectText *) *i;
|
wxLayoutObjectText *tobj = (wxLayoutObjectText *) *i;
|
||||||
@@ -1304,6 +1309,130 @@ wxLayoutLine::Break(CoordType xpos, wxLayoutList *llist)
|
|||||||
return newLine;
|
return newLine;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
wxLayoutLine::Wrap(CoordType wrapmargin, wxLayoutList *llist)
|
||||||
|
{
|
||||||
|
if(GetLength() < wrapmargin)
|
||||||
|
return FALSE; // nothing to do
|
||||||
|
|
||||||
|
// find the object which covers the wrapmargin:
|
||||||
|
CoordType offset;
|
||||||
|
wxLOiterator i = FindObject(wrapmargin, &offset);
|
||||||
|
wxCHECK_MSG( i != NULLIT, FALSE, "Cannot find object covering wrapmargin.");
|
||||||
|
|
||||||
|
// from this object on, the rest of the line must be copied to the
|
||||||
|
// next one:
|
||||||
|
wxLOiterator copyObject = NULLIT;
|
||||||
|
// if we split a text-object, we must pre-pend some text to the
|
||||||
|
// next line later on, remember it here:
|
||||||
|
wxString prependText = "";
|
||||||
|
// we might need to adjust the cursor position later, so remember it
|
||||||
|
size_t xpos = llist->GetCursorPos().x;
|
||||||
|
// by how much did we shorten the current line:
|
||||||
|
size_t shorter = 0;
|
||||||
|
// remember cursor location of object
|
||||||
|
size_t objectCursorPos = 0;
|
||||||
|
|
||||||
|
size_t breakpos = offset;
|
||||||
|
|
||||||
|
if( (**i).GetType() != WXLO_TYPE_TEXT )
|
||||||
|
{
|
||||||
|
// break before a non-text object
|
||||||
|
copyObject = i;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
bool foundSpace = FALSE;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
// while(i != NULLIT && (**i).GetType() != WXLO_TYPE_TEXT)
|
||||||
|
// i--;
|
||||||
|
// try to find a suitable place to split the object:
|
||||||
|
wxLayoutObjectText *tobj = (wxLayoutObjectText *)*i;
|
||||||
|
if((**i).GetType() == WXLO_TYPE_TEXT
|
||||||
|
&& tobj->GetText().Length() >= breakpos)
|
||||||
|
{
|
||||||
|
do
|
||||||
|
{
|
||||||
|
foundSpace = isspace(tobj->GetText()[breakpos]) != 0;
|
||||||
|
if ( foundSpace )
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
while ( breakpos-- > 0 );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
breakpos = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(! foundSpace) // breakpos == 0!
|
||||||
|
{
|
||||||
|
if(i == m_ObjectList.begin())
|
||||||
|
return FALSE; // could not break line
|
||||||
|
else
|
||||||
|
{
|
||||||
|
i--;
|
||||||
|
while(i != m_ObjectList.begin()
|
||||||
|
&& (**i).GetType() != WXLO_TYPE_TEXT )
|
||||||
|
{
|
||||||
|
i--;
|
||||||
|
}
|
||||||
|
breakpos = (**i).GetLength();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}while(! foundSpace);
|
||||||
|
// before we actually break the object, we need to know at which
|
||||||
|
// cursorposition it starts, so we can restore the cursor if needed:
|
||||||
|
if( this == llist->GetCursorLine() && xpos >= breakpos )
|
||||||
|
{
|
||||||
|
for(wxLOiterator j = m_ObjectList.begin();
|
||||||
|
j != NULLIT && j != i; j++)
|
||||||
|
objectCursorPos += (**j).GetLength();
|
||||||
|
}
|
||||||
|
// now we know where to break it:
|
||||||
|
wxLayoutObjectText *tobj = (wxLayoutObjectText *)*i;
|
||||||
|
shorter = tobj->GetLength() - breakpos;
|
||||||
|
// remember text to copy from this object
|
||||||
|
prependText = tobj->GetText().Mid(breakpos+1);
|
||||||
|
tobj->SetText(tobj->GetText().Left(breakpos));
|
||||||
|
// copy every following object:
|
||||||
|
copyObject = i; copyObject ++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// make sure there is an empty m_Next line:
|
||||||
|
(void) new wxLayoutLine(this, llist);
|
||||||
|
wxASSERT(m_Next);
|
||||||
|
// We need to move this and all following objects to the next
|
||||||
|
// line. Starting from the end of line, to keep the order right.
|
||||||
|
if(copyObject != NULLIT)
|
||||||
|
{
|
||||||
|
wxLOiterator j;
|
||||||
|
for(j = m_ObjectList.tail(); j != copyObject; j--)
|
||||||
|
m_Next->Prepend(*j);
|
||||||
|
m_Next->Prepend(*copyObject);
|
||||||
|
// and now remove them from this list:
|
||||||
|
while( copyObject != m_ObjectList.end() )
|
||||||
|
{
|
||||||
|
shorter += (**copyObject).GetLength();
|
||||||
|
m_ObjectList.remove(copyObject); // remove without deleting it
|
||||||
|
}
|
||||||
|
}
|
||||||
|
m_Length -= shorter;
|
||||||
|
|
||||||
|
if(prependText.Length() > 0)
|
||||||
|
m_Next->Insert(0, prependText);
|
||||||
|
|
||||||
|
// do we need to adjust the cursor position?
|
||||||
|
if( this == llist->GetCursorLine() && xpos >= breakpos)
|
||||||
|
{
|
||||||
|
xpos = objectCursorPos + (xpos - objectCursorPos - breakpos -
|
||||||
|
((xpos > breakpos) ? 1 : 0 ));
|
||||||
|
wxASSERT(xpos >= 0);
|
||||||
|
llist->MoveCursorTo( wxPoint( xpos, m_Next->GetLineNumber()) );
|
||||||
|
}
|
||||||
|
return TRUE; // we wrapped the line
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
wxLayoutLine::ReNumber(void)
|
wxLayoutLine::ReNumber(void)
|
||||||
{
|
{
|
||||||
@@ -1389,7 +1518,7 @@ wxLayoutLine::GetWrapPosition(CoordType column)
|
|||||||
{
|
{
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
if( isspace(((wxLayoutObjectText*)*i)->GetText().c_str()[(size_t)offset]))
|
if(isspace(((wxLayoutObjectText*)*i)->GetText().c_str()[(size_t)offset]))
|
||||||
return column;
|
return column;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -1418,25 +1547,23 @@ wxLayoutLine::GetWrapPosition(CoordType column)
|
|||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
if(i == NULLIT) return -1; //why should this happen?
|
if(i == NULLIT) return -1; //why should this happen?
|
||||||
|
|
||||||
|
// now we are behind the one long text object and need to find the
|
||||||
|
// first space in it
|
||||||
|
for(offset = 0; offset < (**i).GetLength(); offset++)
|
||||||
|
if( isspace(((wxLayoutObjectText*)*i)->GetText().c_str()[(size_t)offset]))
|
||||||
|
{
|
||||||
|
return pos+offset;
|
||||||
|
}
|
||||||
pos += (**i).GetLength();
|
pos += (**i).GetLength();
|
||||||
i++;
|
return pos;
|
||||||
while(i != NULLIT && (**i).GetType() != WXLO_TYPE_TEXT)
|
|
||||||
{
|
|
||||||
pos += (**i).GetLength();
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
if(i == NULLIT) return -1; //this is possible, if there is only one text object
|
|
||||||
// now we are at the second text object:
|
|
||||||
pos -= (**i).GetLength();
|
|
||||||
return pos; // in front of it
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifdef WXLAYOUT_DEBUG
|
#ifdef WXLAYOUT_DEBUG
|
||||||
void
|
void
|
||||||
wxLayoutLine::Debug(void)
|
wxLayoutLine::Debug(void) const
|
||||||
{
|
{
|
||||||
wxString tmp;
|
|
||||||
wxPoint pos = GetPosition();
|
wxPoint pos = GetPosition();
|
||||||
WXLO_DEBUG(("Line %ld, Pos (%ld,%ld), Height %ld, BL %ld, Font: %d",
|
WXLO_DEBUG(("Line %ld, Pos (%ld,%ld), Height %ld, BL %ld, Font: %d",
|
||||||
(long int) GetLineNumber(),
|
(long int) GetLineNumber(),
|
||||||
@@ -1445,7 +1572,9 @@ wxLayoutLine::Debug(void)
|
|||||||
(long int) m_BaseLine,
|
(long int) m_BaseLine,
|
||||||
(int) m_StyleInfo.family));
|
(int) m_StyleInfo.family));
|
||||||
if(m_ObjectList.begin() != NULLIT)
|
if(m_ObjectList.begin() != NULLIT)
|
||||||
(**m_ObjectList.begin()).Debug();
|
{
|
||||||
|
WXLO_DEBUG(((**m_ObjectList.begin()).DebugDump().c_str()));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -1592,9 +1721,22 @@ wxLayoutList::Read(wxString &istr)
|
|||||||
|
|
||||||
while(istr.Length())
|
while(istr.Length())
|
||||||
{
|
{
|
||||||
wxLayoutObject *obj = wxLayoutObject::Read(istr);
|
// check for a linebreak:
|
||||||
if(obj)
|
wxString tmp;
|
||||||
Insert(obj);
|
tmp = istr.BeforeFirst('\n');
|
||||||
|
int type = WXLO_TYPE_INVALID;
|
||||||
|
sscanf(tmp.c_str(),"%d", &type);
|
||||||
|
if(type == WXLO_TYPE_LINEBREAK)
|
||||||
|
{
|
||||||
|
LineBreak();
|
||||||
|
istr = istr.AfterFirst('\n');
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
wxLayoutObject *obj = wxLayoutObject::Read(istr);
|
||||||
|
if(obj)
|
||||||
|
Insert(obj);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
/* Now we use the current_si to restore our last font settings: */
|
/* Now we use the current_si to restore our last font settings: */
|
||||||
Insert(new wxLayoutObjectCmd(current_si));
|
Insert(new wxLayoutObjectCmd(current_si));
|
||||||
@@ -1746,6 +1888,7 @@ wxLayoutList::MoveCursorVertically(int n)
|
|||||||
{
|
{
|
||||||
n--;
|
n--;
|
||||||
m_CursorPos.y ++;
|
m_CursorPos.y ++;
|
||||||
|
last = m_CursorLine;
|
||||||
m_CursorLine = m_CursorLine->GetNextLine();
|
m_CursorLine = m_CursorLine->GetNextLine();
|
||||||
}
|
}
|
||||||
if(! m_CursorLine)
|
if(! m_CursorLine)
|
||||||
@@ -1983,9 +2126,10 @@ wxLayoutList::Insert(wxString const &text)
|
|||||||
|
|
||||||
AddCursorPosToUpdateRect();
|
AddCursorPosToUpdateRect();
|
||||||
|
|
||||||
|
wxASSERT(m_CursorLine->GetLength() >= m_CursorPos.x);
|
||||||
|
|
||||||
if ( !m_CursorLine->Insert(m_CursorPos.x, text) )
|
if ( !m_CursorLine->Insert(m_CursorPos.x, text) )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
m_CursorPos.x += text.Length();
|
m_CursorPos.x += text.Length();
|
||||||
|
|
||||||
m_movedCursor = true;
|
m_movedCursor = true;
|
||||||
@@ -2076,29 +2220,22 @@ wxLayoutList::LineBreak(void)
|
|||||||
bool
|
bool
|
||||||
wxLayoutList::WrapLine(CoordType column)
|
wxLayoutList::WrapLine(CoordType column)
|
||||||
{
|
{
|
||||||
if(m_CursorPos.x <= column || column < 1)
|
return m_CursorLine->Wrap(column, this);
|
||||||
return false; // do nothing yet
|
}
|
||||||
else
|
|
||||||
|
bool
|
||||||
|
wxLayoutList::WrapAll(CoordType column)
|
||||||
|
{
|
||||||
|
wxLayoutLine *line = m_FirstLine;
|
||||||
|
if(! line)
|
||||||
|
return FALSE;
|
||||||
|
bool rc = TRUE;
|
||||||
|
while(line && rc)
|
||||||
{
|
{
|
||||||
CoordType xpos = m_CursorLine->GetWrapPosition(column);
|
rc &= line->Wrap(column, this);
|
||||||
if(xpos == -1)
|
line = line->GetNextLine();
|
||||||
return false; // cannot break line
|
|
||||||
//else:
|
|
||||||
CoordType newpos = m_CursorPos.x - xpos - 1;
|
|
||||||
m_CursorPos.x = xpos;
|
|
||||||
|
|
||||||
AddCursorPosToUpdateRect();
|
|
||||||
|
|
||||||
LineBreak();
|
|
||||||
Delete(1); // delete the space
|
|
||||||
m_CursorPos.x = newpos;
|
|
||||||
|
|
||||||
m_CursorLine->MarkDirty();
|
|
||||||
|
|
||||||
m_movedCursor = true;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
@@ -2262,6 +2399,9 @@ wxLayoutList::Layout(wxDC &dc, CoordType bottom, bool forceAll,
|
|||||||
// If one line was dirty, we need to re-calculate all
|
// If one line was dirty, we need to re-calculate all
|
||||||
// following lines, too.
|
// following lines, too.
|
||||||
bool wasDirty = forceAll;
|
bool wasDirty = forceAll;
|
||||||
|
// we need to layout until we reach at least the cursor line,
|
||||||
|
// otherwise we won't be able to scroll to it
|
||||||
|
bool cursorReached = false;
|
||||||
wxLayoutLine *line = m_FirstLine;
|
wxLayoutLine *line = m_FirstLine;
|
||||||
while(line)
|
while(line)
|
||||||
{
|
{
|
||||||
@@ -2271,6 +2411,8 @@ wxLayoutList::Layout(wxDC &dc, CoordType bottom, bool forceAll,
|
|||||||
// if any previous line was dirty, we need to layout all
|
// if any previous line was dirty, we need to layout all
|
||||||
// following lines:
|
// following lines:
|
||||||
wasDirty
|
wasDirty
|
||||||
|
// go on until we find the cursorline
|
||||||
|
|| ! cursorReached
|
||||||
// layout dirty lines:
|
// layout dirty lines:
|
||||||
|| line->IsDirty()
|
|| line->IsDirty()
|
||||||
// always layout the cursor line toupdate the cursor
|
// always layout the cursor line toupdate the cursor
|
||||||
@@ -2278,6 +2420,9 @@ wxLayoutList::Layout(wxDC &dc, CoordType bottom, bool forceAll,
|
|||||||
|| line == m_CursorLine
|
|| line == m_CursorLine
|
||||||
// or if it's the line we are asked to look for:
|
// or if it's the line we are asked to look for:
|
||||||
|| (cpos && line->GetLineNumber() == cpos->y)
|
|| (cpos && line->GetLineNumber() == cpos->y)
|
||||||
|
// layout at least the desired region:
|
||||||
|
|| (bottom == -1 )
|
||||||
|
|| (line->GetPosition().y <= bottom)
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
if(line->IsDirty())
|
if(line->IsDirty())
|
||||||
@@ -2299,17 +2444,20 @@ wxLayoutList::Layout(wxDC &dc, CoordType bottom, bool forceAll,
|
|||||||
if ( csize )
|
if ( csize )
|
||||||
*csize = m_CursorSize;
|
*csize = m_CursorSize;
|
||||||
}
|
}
|
||||||
|
cursorReached = TRUE;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
if(cpos && line->GetLineNumber() == cpos->y)
|
if(cpos && line->GetLineNumber() == cpos->y)
|
||||||
|
{
|
||||||
line->Layout(dc, this,
|
line->Layout(dc, this,
|
||||||
cpos,
|
cpos,
|
||||||
csize, NULL, cpos->x);
|
csize, NULL, cpos->x);
|
||||||
else
|
cursorReached = TRUE;
|
||||||
line->Layout(dc, this);
|
}
|
||||||
// little condition to speed up redrawing:
|
else
|
||||||
if(bottom != -1 && line->GetPosition().y > bottom)
|
line->Layout(dc, this);
|
||||||
break;
|
}
|
||||||
}
|
}
|
||||||
line = line->GetNextLine();
|
line = line->GetNextLine();
|
||||||
}
|
}
|
||||||
@@ -2385,7 +2533,7 @@ wxLayoutList::Draw(wxDC &dc,
|
|||||||
}
|
}
|
||||||
InvalidateUpdateRect();
|
InvalidateUpdateRect();
|
||||||
|
|
||||||
WXLO_DEBUG(("Selection is %s : l%d,%ld/%ld,%ld",
|
WXLO_DEBUG(("Selection is %s : %ld,%ld/%ld,%ld",
|
||||||
m_Selection.m_valid ? "valid" : "invalid",
|
m_Selection.m_valid ? "valid" : "invalid",
|
||||||
m_Selection.m_CursorA.x, m_Selection.m_CursorA.y,
|
m_Selection.m_CursorA.x, m_Selection.m_CursorA.y,
|
||||||
m_Selection.m_CursorB.x, m_Selection.m_CursorB.y));
|
m_Selection.m_CursorB.x, m_Selection.m_CursorB.y));
|
||||||
@@ -2500,7 +2648,7 @@ wxLayoutList::DrawCursor(wxDC &dc, bool active, wxPoint const &translate)
|
|||||||
#ifdef WXLAYOUT_DEBUG
|
#ifdef WXLAYOUT_DEBUG
|
||||||
WXLO_DEBUG(("Drawing cursor (%ld,%ld) at %ld,%ld, size %ld,%ld, line: %ld, len %ld",
|
WXLO_DEBUG(("Drawing cursor (%ld,%ld) at %ld,%ld, size %ld,%ld, line: %ld, len %ld",
|
||||||
(long)m_CursorPos.x, (long)m_CursorPos.y,
|
(long)m_CursorPos.x, (long)m_CursorPos.y,
|
||||||
(long)coords.x, (long)coords.y,
|
(long)coords.x, (long)coords.y,
|
||||||
(long)m_CursorSize.x, (long)m_CursorSize.y,
|
(long)m_CursorSize.x, (long)m_CursorSize.y,
|
||||||
(long)m_CursorLine->GetLineNumber(),
|
(long)m_CursorLine->GetLineNumber(),
|
||||||
(long)m_CursorLine->GetLength()));
|
(long)m_CursorLine->GetLength()));
|
||||||
@@ -2522,7 +2670,8 @@ wxLayoutList::DrawCursor(wxDC &dc, bool active, wxPoint const &translate)
|
|||||||
dc.DrawRectangle(coords.x, coords.y,
|
dc.DrawRectangle(coords.x, coords.y,
|
||||||
m_CursorSize.x, m_CursorSize.y);
|
m_CursorSize.x, m_CursorSize.y);
|
||||||
SetUpdateRect(coords.x, coords.y);
|
SetUpdateRect(coords.x, coords.y);
|
||||||
SetUpdateRect(coords.x+m_CursorSize.x, coords.y+m_CursorSize.y);
|
SetUpdateRect(coords.x+m_CursorSize.x,
|
||||||
|
coords.y+m_CursorSize.y);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -2883,7 +3032,7 @@ wxLayoutList::GetSelection(wxLayoutDataObject *wxlo, bool invalidate)
|
|||||||
while((exp = wxLayoutExport( &status, WXLO_EXPORT_AS_OBJECTS)) != NULL)
|
while((exp = wxLayoutExport( &status, WXLO_EXPORT_AS_OBJECTS)) != NULL)
|
||||||
{
|
{
|
||||||
if(exp->type == WXLO_EXPORT_EMPTYLINE)
|
if(exp->type == WXLO_EXPORT_EMPTYLINE)
|
||||||
; //FIXME missing support for linebreaks in string format
|
string << (int) WXLO_TYPE_LINEBREAK << '\n';
|
||||||
else
|
else
|
||||||
exp->content.object->Write(string);
|
exp->content.object->Write(string);
|
||||||
delete exp;
|
delete exp;
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
/*-*- c++ -*-********************************************************
|
/*-*- c++ -*-********************************************************
|
||||||
* wxLayoutList.h - a formatted text rendering engine for wxWindows *
|
* wxLayoutList.h - a formatted text rendering engine for wxWindows *
|
||||||
* *
|
* *
|
||||||
* (C) 1999 by Karsten Ball<6C>der (ballueder@gmx.net) *
|
* (C) 1999-2000 by Karsten Ball<6C>der (ballueder@gmx.net) *
|
||||||
* *
|
* *
|
||||||
* $Id$
|
* $Id$
|
||||||
*******************************************************************/
|
*******************************************************************/
|
||||||
@@ -38,17 +38,38 @@
|
|||||||
# define WXLAYOUT_USE_CARET 1
|
# define WXLAYOUT_USE_CARET 1
|
||||||
#endif // __WXMSW__
|
#endif // __WXMSW__
|
||||||
|
|
||||||
// do not enable debug mode within Mahogany
|
// do not enable debug mode within Mahogany unless in debug mode
|
||||||
#if defined(__WXDEBUG__) && ! defined(M_BASEDIR)
|
#if defined(__WXDEBUG__) && (( ! defined(M_BASEDIR) )|| defined(DEBUG))
|
||||||
# define WXLAYOUT_DEBUG
|
# define WXLAYOUT_DEBUG
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef WXLAYOUT_DEBUG
|
#ifdef WXLAYOUT_DEBUG
|
||||||
# define WXLO_TRACE(x) wxLogDebug(x)
|
# define WXLO_TRACE(x) wxLogDebug(x)
|
||||||
|
// activate profiling: # define WXLO_PROFILE
|
||||||
#else
|
#else
|
||||||
# define WXLO_TRACE(x)
|
# define WXLO_TRACE(x)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* Some profiling code: */
|
||||||
|
#if defined (WXLO_PROFILE)
|
||||||
|
#include <sys/time.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
# define WXLO_TIMER_DEFINE(x) static struct timeval x
|
||||||
|
# define WXLO_TIMER_START(x) gettimeofday(&x,NULL)
|
||||||
|
# define WXLO_TIMER_STOP(x) { struct timeval y; \
|
||||||
|
gettimeofday(&y,NULL); \
|
||||||
|
x.tv_sec -= y.tv_sec; x.tv_usec -= y.tv_usec; }
|
||||||
|
# define WXLO_TIMER_PRINT(x) wxLogDebug("Timer " #x " elapsed: %ld", \
|
||||||
|
(long)(x.tv_sec * -1000 - x.tv_usec));
|
||||||
|
#else
|
||||||
|
# define WXLO_TIMER_DEFINE(x)
|
||||||
|
# define WXLO_TIMER_START(x)
|
||||||
|
# define WXLO_TIMER_STOP(x)
|
||||||
|
# define WXLO_TIMER_PRINT(x)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#define WXLO_DEBUG_URECT 0
|
#define WXLO_DEBUG_URECT 0
|
||||||
|
|
||||||
#ifndef WXLO_DEFAULTFONTSIZE
|
#ifndef WXLO_DEFAULTFONTSIZE
|
||||||
@@ -71,7 +92,9 @@ enum wxLayoutObjectType
|
|||||||
/// command object, containing font or colour changes
|
/// command object, containing font or colour changes
|
||||||
WXLO_TYPE_CMD,
|
WXLO_TYPE_CMD,
|
||||||
/// icon object, any kind of image
|
/// icon object, any kind of image
|
||||||
WXLO_TYPE_ICON
|
WXLO_TYPE_ICON,
|
||||||
|
/// a linebreak, does not exist as an object
|
||||||
|
WXLO_TYPE_LINEBREAK
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Type used for coordinates in drawing. Must be signed.
|
/// Type used for coordinates in drawing. Must be signed.
|
||||||
@@ -171,7 +194,7 @@ public:
|
|||||||
virtual ~wxLayoutObject() { if(m_UserData) m_UserData->DecRef(); }
|
virtual ~wxLayoutObject() { if(m_UserData) m_UserData->DecRef(); }
|
||||||
|
|
||||||
#ifdef WXLAYOUT_DEBUG
|
#ifdef WXLAYOUT_DEBUG
|
||||||
virtual void Debug(void);
|
virtual wxString DebugDump(void) const;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/** Tells the object about some user data. This data is associated
|
/** Tells the object about some user data. This data is associated
|
||||||
@@ -266,7 +289,7 @@ public:
|
|||||||
static wxLayoutObjectText *Read(wxString &istr);
|
static wxLayoutObjectText *Read(wxString &istr);
|
||||||
|
|
||||||
#ifdef WXLAYOUT_DEBUG
|
#ifdef WXLAYOUT_DEBUG
|
||||||
virtual void Debug(void);
|
virtual wxString DebugDump(void) const;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
virtual CoordType GetLength(void) const { return strlen(m_Text.c_str()); }
|
virtual CoordType GetLength(void) const { return strlen(m_Text.c_str()); }
|
||||||
@@ -475,11 +498,18 @@ public:
|
|||||||
void Append(wxLayoutObject * obj)
|
void Append(wxLayoutObject * obj)
|
||||||
{
|
{
|
||||||
wxASSERT(obj);
|
wxASSERT(obj);
|
||||||
|
|
||||||
m_ObjectList.push_back(obj);
|
m_ObjectList.push_back(obj);
|
||||||
m_Length += obj->GetLength();
|
m_Length += obj->GetLength();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** This function prepends an object to the line. */
|
||||||
|
void Prepend(wxLayoutObject * obj)
|
||||||
|
{
|
||||||
|
wxASSERT(obj);
|
||||||
|
m_ObjectList.push_front(obj);
|
||||||
|
m_Length += obj->GetLength();
|
||||||
|
}
|
||||||
|
|
||||||
/** This function appens the next line to this, i.e. joins the two
|
/** This function appens the next line to this, i.e. joins the two
|
||||||
lines into one.
|
lines into one.
|
||||||
*/
|
*/
|
||||||
@@ -498,6 +528,13 @@ public:
|
|||||||
*/
|
*/
|
||||||
wxLayoutLine *Break(CoordType xpos, wxLayoutList *llist);
|
wxLayoutLine *Break(CoordType xpos, wxLayoutList *llist);
|
||||||
|
|
||||||
|
/** This function wraps the line: breaks it at a suitable point
|
||||||
|
and merges it with the next.
|
||||||
|
@param wrapmargin
|
||||||
|
@return TRUE if broken
|
||||||
|
*/
|
||||||
|
bool Wrap(CoordType wrapmargin, wxLayoutList *llist);
|
||||||
|
|
||||||
/** Deletes the next word from this position, including leading
|
/** Deletes the next word from this position, including leading
|
||||||
whitespace.
|
whitespace.
|
||||||
This function does not delete over font changes, i.e. a word
|
This function does not delete over font changes, i.e. a word
|
||||||
@@ -662,7 +699,7 @@ public:
|
|||||||
CoordType to = -1);
|
CoordType to = -1);
|
||||||
|
|
||||||
#ifdef WXLAYOUT_DEBUG
|
#ifdef WXLAYOUT_DEBUG
|
||||||
void Debug(void);
|
void Debug(void) const;
|
||||||
#endif
|
#endif
|
||||||
wxLayoutStyleInfo const & GetStyleInfo() const { return m_StyleInfo; }
|
wxLayoutStyleInfo const & GetStyleInfo() const { return m_StyleInfo; }
|
||||||
|
|
||||||
@@ -680,6 +717,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
m_Dirty = true;
|
m_Dirty = true;
|
||||||
|
if(m_Next) m_Next->MarkDirty();
|
||||||
}
|
}
|
||||||
/// Reset the dirty flag
|
/// Reset the dirty flag
|
||||||
void MarkClean() { m_Dirty = false; m_updateLeft = -1; }
|
void MarkClean() { m_Dirty = false; m_updateLeft = -1; }
|
||||||
@@ -815,7 +853,8 @@ public:
|
|||||||
/// Returns current cursor position.
|
/// Returns current cursor position.
|
||||||
const wxPoint &GetCursorPos(wxDC &dc) const { return m_CursorPos; }
|
const wxPoint &GetCursorPos(wxDC &dc) const { return m_CursorPos; }
|
||||||
const wxPoint &GetCursorPos() const { return m_CursorPos; }
|
const wxPoint &GetCursorPos() const { return m_CursorPos; }
|
||||||
|
wxLayoutLine * GetCursorLine(void) { return m_CursorLine; }
|
||||||
|
|
||||||
/// move cursor to the end of text
|
/// move cursor to the end of text
|
||||||
void MoveCursorToEnd(void)
|
void MoveCursorToEnd(void)
|
||||||
{
|
{
|
||||||
@@ -845,6 +884,12 @@ public:
|
|||||||
@return true if line got broken
|
@return true if line got broken
|
||||||
*/
|
*/
|
||||||
bool WrapLine(CoordType column);
|
bool WrapLine(CoordType column);
|
||||||
|
|
||||||
|
/** Wraps the complete buffer.
|
||||||
|
@param column the break position for the line, maximum length
|
||||||
|
@return true if line got broken
|
||||||
|
*/
|
||||||
|
bool WrapAll(CoordType column);
|
||||||
/** This function deletes npos cursor positions.
|
/** This function deletes npos cursor positions.
|
||||||
@param npos how many positions
|
@param npos how many positions
|
||||||
@return true if everything got deleted
|
@return true if everything got deleted
|
||||||
@@ -1142,7 +1187,8 @@ public:
|
|||||||
/// get the line by number
|
/// get the line by number
|
||||||
wxLayoutLine *GetLine(CoordType index) const;
|
wxLayoutLine *GetLine(CoordType index) const;
|
||||||
|
|
||||||
/** Reads objects from a string and inserts them.
|
/** Reads objects from a string and inserts them. Returns NULL if
|
||||||
|
string is empty or a linebreak was found.
|
||||||
@param istr stream to read from, will bee changed
|
@param istr stream to read from, will bee changed
|
||||||
*/
|
*/
|
||||||
void Read(wxString &istr);
|
void Read(wxString &istr);
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
/*-*- c++ -*-********************************************************
|
/*-*- c++ -*-********************************************************
|
||||||
* wxLwindow.h : a scrolled Window for displaying/entering rich text*
|
* wxLwindow.h : a scrolled Window for displaying/entering rich text*
|
||||||
* *
|
* *
|
||||||
* (C) 1998, 1999 by Karsten Ball<6C>der (karsten@phy.hw.ac.uk) *
|
* (C) 1998-2000 by Karsten Ball<6C>der (ballueder@gmx.net) *
|
||||||
* *
|
* *
|
||||||
* $Id$
|
* $Id$
|
||||||
*******************************************************************/
|
*******************************************************************/
|
||||||
@@ -56,6 +56,7 @@
|
|||||||
|
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// macros
|
// macros
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
@@ -66,6 +67,13 @@
|
|||||||
# define WXLO_DEBUG(x)
|
# define WXLO_DEBUG(x)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// for profiling in debug mode:
|
||||||
|
WXLO_TIMER_DEFINE(UpdateTimer);
|
||||||
|
WXLO_TIMER_DEFINE(BlitTimer);
|
||||||
|
WXLO_TIMER_DEFINE(LayoutTimer);
|
||||||
|
WXLO_TIMER_DEFINE(TmpTimer);
|
||||||
|
WXLO_TIMER_DEFINE(DrawTimer);
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// constants
|
// constants
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
@@ -160,6 +168,7 @@ wxLayoutWindow::wxLayoutWindow(wxWindow *parent)
|
|||||||
#ifndef __WXMSW__
|
#ifndef __WXMSW__
|
||||||
m_FocusFollowMode = false;
|
m_FocusFollowMode = false;
|
||||||
#endif
|
#endif
|
||||||
|
SetWordWrap(false);
|
||||||
SetWrapMargin(0);
|
SetWrapMargin(0);
|
||||||
|
|
||||||
// no scrollbars initially
|
// no scrollbars initially
|
||||||
@@ -230,10 +239,11 @@ wxLayoutWindow::OnMouse(int eventId, wxMouseEvent& event)
|
|||||||
{
|
{
|
||||||
wxClientDC dc( this );
|
wxClientDC dc( this );
|
||||||
PrepareDC( dc );
|
PrepareDC( dc );
|
||||||
if ( eventId != WXLOWIN_MENU_MOUSEMOVE
|
if ( (eventId != WXLOWIN_MENU_MOUSEMOVE
|
||||||
#ifndef __WXMSW__
|
#ifndef __WXMSW__
|
||||||
|| m_FocusFollowMode
|
|| m_FocusFollowMode
|
||||||
#endif
|
#endif
|
||||||
|
) && (wxWindow::FindFocus() != this)
|
||||||
)
|
)
|
||||||
SetFocus();
|
SetFocus();
|
||||||
|
|
||||||
@@ -479,6 +489,7 @@ wxLayoutWindow::OnChar(wxKeyEvent& event)
|
|||||||
bool deletedSelection = false;
|
bool deletedSelection = false;
|
||||||
// pressing any non-arrow key optionally replaces the selection:
|
// pressing any non-arrow key optionally replaces the selection:
|
||||||
if(m_AutoDeleteSelection
|
if(m_AutoDeleteSelection
|
||||||
|
&& IsEditable()
|
||||||
&& !m_Selecting
|
&& !m_Selecting
|
||||||
&& m_llist->HasSelection()
|
&& m_llist->HasSelection()
|
||||||
&& ! IsDirectionKey(keyCode)
|
&& ! IsDirectionKey(keyCode)
|
||||||
@@ -635,10 +646,21 @@ wxLayoutWindow::OnChar(wxKeyEvent& event)
|
|||||||
case 'x':
|
case 'x':
|
||||||
Cut();
|
Cut();
|
||||||
break;
|
break;
|
||||||
|
case 'w':
|
||||||
|
if(m_WrapMargin > 0)
|
||||||
|
m_llist->WrapLine(m_WrapMargin);
|
||||||
|
break;
|
||||||
|
case 'q':
|
||||||
|
if(m_WrapMargin > 0)
|
||||||
|
m_llist->WrapAll(m_WrapMargin);
|
||||||
|
break;
|
||||||
#ifdef WXLAYOUT_DEBUG
|
#ifdef WXLAYOUT_DEBUG
|
||||||
case WXK_F1:
|
case WXK_F1:
|
||||||
m_llist->SetFont(-1,-1,-1,-1,true); // underlined
|
m_llist->SetFont(-1,-1,-1,-1,true); // underlined
|
||||||
break;
|
break;
|
||||||
|
case 'l':
|
||||||
|
Refresh(TRUE);
|
||||||
|
break;
|
||||||
#endif
|
#endif
|
||||||
default:
|
default:
|
||||||
// we don't handle it, maybe an accelerator?
|
// we don't handle it, maybe an accelerator?
|
||||||
@@ -688,7 +710,9 @@ wxLayoutWindow::OnChar(wxKeyEvent& event)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case WXK_RETURN:
|
case WXK_RETURN:
|
||||||
if(m_WrapMargin > 0)
|
if(m_DoWordWrap &&
|
||||||
|
m_WrapMargin > 0
|
||||||
|
&& m_llist->GetCursorPos().x > m_WrapMargin)
|
||||||
m_llist->WrapLine(m_WrapMargin);
|
m_llist->WrapLine(m_WrapMargin);
|
||||||
m_llist->LineBreak();
|
m_llist->LineBreak();
|
||||||
SetDirty();
|
SetDirty();
|
||||||
@@ -706,23 +730,19 @@ wxLayoutWindow::OnChar(wxKeyEvent& event)
|
|||||||
SetDirty();
|
SetDirty();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
if((!(event.ControlDown() || event.AltDown()
|
if((!(event.ControlDown() || event.AltDown()
|
||||||
))
|
))
|
||||||
&& (keyCode < 256 && keyCode >= 32)
|
&& (keyCode < 256 && keyCode >= 32)
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
if(m_WrapMargin > 0 && isspace(keyCode))
|
if(m_DoWordWrap
|
||||||
{
|
&& m_WrapMargin > 0
|
||||||
bool wrapped = m_llist->WrapLine(m_WrapMargin);
|
&& m_llist->GetCursorPos().x > m_WrapMargin
|
||||||
// don<6F>t insert space as first thing in line
|
&& isspace(keyCode))
|
||||||
// after wrapping:
|
m_llist->WrapLine(m_WrapMargin);
|
||||||
if(! wrapped || m_llist->GetCursorPos().x != 0)
|
m_llist->Insert((char)keyCode);
|
||||||
m_llist->Insert((char)keyCode);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
m_llist->Insert((char)keyCode);
|
|
||||||
SetDirty();
|
SetDirty();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -765,7 +785,10 @@ wxLayoutWindow::ScrollToCursor(void)
|
|||||||
{
|
{
|
||||||
//is always needed to make sure we know where the cursor is
|
//is always needed to make sure we know where the cursor is
|
||||||
//if(IsDirty())
|
//if(IsDirty())
|
||||||
RequestUpdate(m_llist->GetUpdateRect());
|
//RequestUpdate(m_llist->GetUpdateRect());
|
||||||
|
|
||||||
|
|
||||||
|
ResizeScrollbars();
|
||||||
|
|
||||||
int x0,y0,x1,y1, dx, dy;
|
int x0,y0,x1,y1, dx, dy;
|
||||||
|
|
||||||
@@ -802,7 +825,7 @@ wxLayoutWindow::ScrollToCursor(void)
|
|||||||
ny = 0;
|
ny = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( nx != -1 || ny != -1 )
|
if( nx != -1 || ny != -1 )
|
||||||
{
|
{
|
||||||
// set new view start
|
// set new view start
|
||||||
Scroll(nx == -1 ? -1 : (nx+dx-1)/dx, ny == -1 ? -1 : (ny+dy-1)/dy);
|
Scroll(nx == -1 ? -1 : (nx+dx-1)/dx, ny == -1 ? -1 : (ny+dy-1)/dy);
|
||||||
@@ -836,6 +859,7 @@ wxLayoutWindow::RequestUpdate(const wxRect *updateRect)
|
|||||||
void
|
void
|
||||||
wxLayoutWindow::InternalPaint(const wxRect *updateRect)
|
wxLayoutWindow::InternalPaint(const wxRect *updateRect)
|
||||||
{
|
{
|
||||||
|
|
||||||
wxPaintDC dc( this );
|
wxPaintDC dc( this );
|
||||||
PrepareDC( dc );
|
PrepareDC( dc );
|
||||||
|
|
||||||
@@ -864,9 +888,9 @@ wxLayoutWindow::InternalPaint(const wxRect *updateRect)
|
|||||||
updateRect->y+updateRect->height));
|
updateRect->y+updateRect->height));
|
||||||
}
|
}
|
||||||
|
|
||||||
ResizeScrollbars();
|
ResizeScrollbars(true);
|
||||||
|
|
||||||
|
WXLO_TIMER_START(TmpTimer);
|
||||||
/* Check whether the window has grown, if so, we need to reallocate
|
/* Check whether the window has grown, if so, we need to reallocate
|
||||||
the bitmap to be larger. */
|
the bitmap to be larger. */
|
||||||
if(x1 > m_bitmapSize.x || y1 > m_bitmapSize.y)
|
if(x1 > m_bitmapSize.x || y1 > m_bitmapSize.y)
|
||||||
@@ -887,7 +911,8 @@ wxLayoutWindow::InternalPaint(const wxRect *updateRect)
|
|||||||
0,wxTRANSPARENT));
|
0,wxTRANSPARENT));
|
||||||
m_memDC->SetLogicalFunction(wxCOPY);
|
m_memDC->SetLogicalFunction(wxCOPY);
|
||||||
m_memDC->Clear();
|
m_memDC->Clear();
|
||||||
|
WXLO_TIMER_STOP(TmpTimer);
|
||||||
|
|
||||||
// fill the background with the background bitmap
|
// fill the background with the background bitmap
|
||||||
if(m_BGbitmap)
|
if(m_BGbitmap)
|
||||||
{
|
{
|
||||||
@@ -922,7 +947,7 @@ wxLayoutWindow::InternalPaint(const wxRect *updateRect)
|
|||||||
// update rectangle (although they are drawn on the memDC, this is
|
// update rectangle (although they are drawn on the memDC, this is
|
||||||
// needed to erase it):
|
// needed to erase it):
|
||||||
m_llist->InvalidateUpdateRect();
|
m_llist->InvalidateUpdateRect();
|
||||||
if(m_CursorVisibility != 0)
|
if(m_CursorVisibility == 1)
|
||||||
{
|
{
|
||||||
// draw a thick cursor for editable windows with focus
|
// draw a thick cursor for editable windows with focus
|
||||||
m_llist->DrawCursor(*m_memDC,
|
m_llist->DrawCursor(*m_memDC,
|
||||||
@@ -930,6 +955,7 @@ wxLayoutWindow::InternalPaint(const wxRect *updateRect)
|
|||||||
offset);
|
offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
WXLO_TIMER_START(BlitTimer);
|
||||||
// Now copy everything to the screen:
|
// Now copy everything to the screen:
|
||||||
#if 0
|
#if 0
|
||||||
// This somehow doesn't work, but even the following bit with the
|
// This somehow doesn't work, but even the following bit with the
|
||||||
@@ -955,6 +981,8 @@ wxLayoutWindow::InternalPaint(const wxRect *updateRect)
|
|||||||
// y1 += WXLO_YOFFSET; //FIXME might not be needed
|
// y1 += WXLO_YOFFSET; //FIXME might not be needed
|
||||||
dc.Blit(x0,y0,x1,y1,m_memDC,0,0,wxCOPY,FALSE);
|
dc.Blit(x0,y0,x1,y1,m_memDC,0,0,wxCOPY,FALSE);
|
||||||
}
|
}
|
||||||
|
WXLO_TIMER_STOP(BlitTimer);
|
||||||
|
|
||||||
|
|
||||||
#ifdef WXLAYOUT_USE_CARET
|
#ifdef WXLAYOUT_USE_CARET
|
||||||
// show the caret back after everything is redrawn
|
// show the caret back after everything is redrawn
|
||||||
@@ -979,6 +1007,10 @@ wxLayoutWindow::InternalPaint(const wxRect *updateRect)
|
|||||||
m_StatusBar->SetStatusText(label, m_StatusFieldCursor);
|
m_StatusBar->SetStatusText(label, m_StatusFieldCursor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
WXLO_TIMER_PRINT(LayoutTimer);
|
||||||
|
WXLO_TIMER_PRINT(BlitTimer);
|
||||||
|
WXLO_TIMER_PRINT(TmpTimer);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -999,14 +1031,20 @@ as needed.
|
|||||||
void
|
void
|
||||||
wxLayoutWindow::ResizeScrollbars(bool exact)
|
wxLayoutWindow::ResizeScrollbars(bool exact)
|
||||||
{
|
{
|
||||||
|
|
||||||
if(! IsDirty())
|
|
||||||
return;
|
|
||||||
|
|
||||||
wxClientDC dc( this );
|
wxClientDC dc( this );
|
||||||
PrepareDC( dc );
|
PrepareDC( dc );
|
||||||
// m_llist->ForceTotalLayout();
|
// m_llist->ForceTotalLayout();
|
||||||
m_llist->Layout(dc);
|
|
||||||
|
if(! IsDirty())
|
||||||
|
{
|
||||||
|
// we are laying out just the minimum, but always up to the
|
||||||
|
// cursor line, so the cursor position is updated.
|
||||||
|
m_llist->Layout(dc, 0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
WXLO_TIMER_START(LayoutTimer);
|
||||||
|
m_llist->Layout(dc, -1);
|
||||||
|
WXLO_TIMER_STOP(LayoutTimer);
|
||||||
ResetDirty();
|
ResetDirty();
|
||||||
|
|
||||||
wxPoint max = m_llist->GetSize();
|
wxPoint max = m_llist->GetSize();
|
||||||
@@ -1025,8 +1063,8 @@ wxLayoutWindow::ResizeScrollbars(bool exact)
|
|||||||
// TODO why do we set both at once? they're independent...
|
// TODO why do we set both at once? they're independent...
|
||||||
if( max.x > m_maxx - WXLO_ROFFSET
|
if( max.x > m_maxx - WXLO_ROFFSET
|
||||||
|| max.y > m_maxy - WXLO_BOFFSET
|
|| max.y > m_maxy - WXLO_BOFFSET
|
||||||
|| max.x < m_maxx - X_SCROLL_PAGE
|
|| (max.x < m_maxx - X_SCROLL_PAGE)
|
||||||
|| max.y < m_maxy - Y_SCROLL_PAGE
|
|| (max.y < m_maxy - Y_SCROLL_PAGE)
|
||||||
|| exact )
|
|| exact )
|
||||||
{
|
{
|
||||||
// text became too large
|
// text became too large
|
||||||
@@ -1038,31 +1076,36 @@ wxLayoutWindow::ResizeScrollbars(bool exact)
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool done = FALSE;
|
bool done = FALSE;
|
||||||
if(max.x < X_SCROLL_PAGE)
|
if(max.x < X_SCROLL_PAGE && m_hasHScrollbar)
|
||||||
{
|
{
|
||||||
SetScrollbars(0,-1,0,-1,0,-1,true);
|
SetScrollbars(0,-1,0,-1,0,-1,true);
|
||||||
m_hasHScrollbar = FALSE;
|
m_hasHScrollbar = FALSE;
|
||||||
done = TRUE;
|
done = TRUE;
|
||||||
}
|
}
|
||||||
if(max.y < Y_SCROLL_PAGE)
|
if(max.y < Y_SCROLL_PAGE && m_hasVScrollbar)
|
||||||
{
|
{
|
||||||
SetScrollbars(-1,0,-1,0,-1,0,true);
|
SetScrollbars(-1,0,-1,0,-1,0,true);
|
||||||
m_hasVScrollbar = FALSE;
|
m_hasVScrollbar = FALSE;
|
||||||
done = TRUE;
|
done = TRUE;
|
||||||
}
|
}
|
||||||
if(! done)
|
if(! done &&
|
||||||
|
// (max.x > X_SCROLL_PAGE || max.y > Y_SCROLL_PAGE)
|
||||||
|
(max.x > size.x - X_SCROLL_PAGE|| max.y > size.y - Y_SCROLL_PAGE)
|
||||||
|
)
|
||||||
{
|
{
|
||||||
ViewStart(&m_ViewStartX, &m_ViewStartY);
|
ViewStart(&m_ViewStartX, &m_ViewStartY);
|
||||||
SetScrollbars(X_SCROLL_PAGE,
|
SetScrollbars(X_SCROLL_PAGE,
|
||||||
Y_SCROLL_PAGE,
|
Y_SCROLL_PAGE,
|
||||||
max.x / X_SCROLL_PAGE + 1,
|
max.x / X_SCROLL_PAGE + 2,
|
||||||
max.y / Y_SCROLL_PAGE + 1,
|
max.y / Y_SCROLL_PAGE + 2,
|
||||||
m_ViewStartX, m_ViewStartY,
|
m_ViewStartX,
|
||||||
|
m_ViewStartY,
|
||||||
true);
|
true);
|
||||||
m_hasHScrollbar =
|
m_hasHScrollbar =
|
||||||
m_hasVScrollbar = true;
|
m_hasVScrollbar = true;
|
||||||
|
// ScrollToCursor();
|
||||||
}
|
}
|
||||||
|
|
||||||
m_maxx = max.x + X_SCROLL_PAGE;
|
m_maxx = max.x + X_SCROLL_PAGE;
|
||||||
m_maxy = max.y + Y_SCROLL_PAGE;
|
m_maxy = max.y + Y_SCROLL_PAGE;
|
||||||
}
|
}
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
/*-*- c++ -*-********************************************************
|
/*-*- c++ -*-********************************************************
|
||||||
* wxLwindow.h : a scrolled Window for displaying/entering rich text*
|
* wxLwindow.h : a scrolled Window for displaying/entering rich text*
|
||||||
* *
|
* *
|
||||||
* (C) 1998-1999 by Karsten Ball<6C>der (karsten@phy.hw.ac.uk) *
|
* (C) 1998-2000 by Karsten Ball<6C>der (ballueder@gmx.net) *
|
||||||
* *
|
* *
|
||||||
* $Id$
|
* $Id$
|
||||||
*******************************************************************/
|
*******************************************************************/
|
||||||
@@ -118,6 +118,11 @@ public:
|
|||||||
*/
|
*/
|
||||||
void SetWrapMargin(CoordType margin) { m_WrapMargin = margin; }
|
void SetWrapMargin(CoordType margin) { m_WrapMargin = margin; }
|
||||||
|
|
||||||
|
/** Toggle wordwrap as we type.
|
||||||
|
@param on true to activate word wrap
|
||||||
|
*/
|
||||||
|
void SetWordWrap(bool on = true) { m_DoWordWrap = on; }
|
||||||
|
|
||||||
/** Redraws the window.
|
/** Redraws the window.
|
||||||
Internally, this stores the parameter and calls a refresh on
|
Internally, this stores the parameter and calls a refresh on
|
||||||
wxMSW, draws directly on wxGTK.
|
wxMSW, draws directly on wxGTK.
|
||||||
@@ -230,6 +235,10 @@ protected:
|
|||||||
int m_maxx;
|
int m_maxx;
|
||||||
int m_maxy;
|
int m_maxy;
|
||||||
int m_lineHeight;
|
int m_lineHeight;
|
||||||
|
/// do we want automatic word wrap?
|
||||||
|
bool m_DoWordWrap;
|
||||||
|
/// wrap margin
|
||||||
|
CoordType m_WrapMargin;
|
||||||
|
|
||||||
/// do we have the corresponding scrollbar?
|
/// do we have the corresponding scrollbar?
|
||||||
bool m_hasHScrollbar,
|
bool m_hasHScrollbar,
|
||||||
@@ -253,8 +262,6 @@ private:
|
|||||||
bool m_Editable;
|
bool m_Editable;
|
||||||
/// Are we currently building a selection with the keyboard?
|
/// Are we currently building a selection with the keyboard?
|
||||||
bool m_Selecting;
|
bool m_Selecting;
|
||||||
/// wrap margin
|
|
||||||
CoordType m_WrapMargin;
|
|
||||||
/// Has list changed since last redraw, e.g. in size?
|
/// Has list changed since last redraw, e.g. in size?
|
||||||
bool m_Dirty;
|
bool m_Dirty;
|
||||||
/// Has the list ever been modified?
|
/// Has the list ever been modified?
|
||||||
|
Reference in New Issue
Block a user