Should work very well now.

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@1928 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Karsten Ballüder 1999-03-14 16:04:57 +00:00
parent 86a9c8e02f
commit 77c630ca85
6 changed files with 288 additions and 93 deletions

View File

@ -2,24 +2,12 @@
BUGS
=====================================================================
- Delete():
1 - occasionally delete deletes too much, maybe when at begin of
line?
2 - when in an empty line, Delete() doesn't always merge lines
3 - line numbers aren't updated properly, may be related to 2.
4 - deleting lines leaves later parts of the list unaffected
--> just redrawing at least the next two lines doesn't seem
enough, strange, don't positions change?
- dmalloc shows duplicate deletion after merging two lines and
deleting the second half
TODO
=====================================================================
- Add word wrap to wxlwindow/wxllist.
- Cursor to mouseclick
- Focus feedback for cursor
- Selections
- More optimisations

View File

@ -99,6 +99,7 @@ MyFrame::MyFrame(void) :
m_lwin = new wxLayoutWindow(this);
m_lwin->SetMouseTracking(true);
m_lwin->SetEditable(true);
m_lwin->SetWrapMargin(40);
m_lwin->Clear(wxROMAN,16,wxNORMAL,wxNORMAL, false);
m_lwin->SetFocus();
};
@ -133,14 +134,13 @@ MyFrame::AddSampleText(wxLayoutList *llist)
llist->Insert("italics ");
llist->SetFont(-1,-1,wxNORMAL);
llist->LineBreak();
llist->Insert("and ");
llist->SetFont(-1,-1,wxSLANT);
llist->Insert("slanted");
llist->SetFont(-1,-1,wxNORMAL);
llist->Insert(" text.");
llist->LineBreak();
llist->Insert("and ");
llist->SetFont(-1,-1,-1,-1,-1,"blue");
llist->Insert("blue");
@ -211,8 +211,7 @@ void MyFrame::OnCommand( wxCommandEvent &event )
break;
case ID_NOWRAP:
case ID_WRAP:
//// m_lwin->GetLayoutList()->SetWrapMargin(
//// event.GetId() == ID_NOWRAP ? -1 : 40);
m_lwin->SetWrapMargin(event.GetId() == ID_NOWRAP ? 0 : 40);
break;
case ID_ADD_SAMPLE:
AddSampleText(m_lwin->GetLayoutList());

View File

@ -102,6 +102,30 @@ wxLayoutObjectText::Draw(wxDC &dc, wxPoint const &coords)
dc.DrawText(m_Text, coords.x, coords.y-m_Top);
}
CoordType
wxLayoutObjectText::GetOffsetScreen(wxDC &dc, CoordType xpos) const
{
CoordType
offs = 1,
maxlen = m_Text.Length();
long
width = 0,
height, descent = 0l;
if(xpos == 0) return 0; // easy
while(width < xpos && offs < maxlen)
{
dc.GetTextExtent(m_Text.substr(0,offs),
&width, &height, &descent);
offs++;
}
/* We have to substract 1 to compensate for the offs++, and another
one because we don't want to position the cursor behind the
object what we clicked on, but before - otherwise it looks
funny. */
return (xpos > 2) ? offs-2 : 0;
}
void
wxLayoutObjectText::Layout(wxDC &dc)
@ -202,8 +226,10 @@ 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);
if(m_ColourFG)
dc.SetTextForeground(*m_ColourFG);
if(m_ColourBG)
dc.SetTextBackground(*m_ColourBG);
}
void
@ -253,7 +279,7 @@ wxPoint
wxLayoutLine::RecalculatePosition(void)
{
if(m_Previous)
m_Position = m_Previous->RecalculatePosition() +
m_Position = m_Previous->GetPosition() +
wxPoint(0,m_Previous->GetHeight());
else
m_Position = wxPoint(0,0);
@ -263,20 +289,21 @@ wxLayoutLine::RecalculatePosition(void)
void
wxLayoutLine::RecalculatePositions(int recurse)
{
wxPoint pos = RecalculatePosition();
if(pos != m_Position)
wxASSERT(recurse >= 0);
wxPoint pos = m_Position;
CoordType height = m_Height;
// WXLO_TRACE("RecalculatePositions()");
RecalculatePosition();
if(m_Next)
{
m_Position = pos;
if(m_Next) m_Next->RecalculatePositions(--recurse);
if(recurse > 0)
{
if(m_Next) m_Next->RecalculatePositions(--recurse);
}
else if(pos != m_Position || m_Height != height)
if(m_Next) m_Next->RecalculatePositions();
}
else
{
m_Position = pos;
if(recurse && m_Next)
m_Next->RecalculatePositions(--recurse);
}
}
wxLayoutObjectList::iterator
@ -287,6 +314,7 @@ wxLayoutLine::FindObject(CoordType xpos, CoordType *offset) const
wxLayoutObjectList::iterator i;
CoordType x = 0, len;
for(i = m_ObjectList.begin(); i != NULLIT; i++)
{
len = (**i).GetLength();
@ -300,6 +328,32 @@ wxLayoutLine::FindObject(CoordType xpos, CoordType *offset) const
return NULLIT;
}
wxLayoutObjectList::iterator
wxLayoutLine::FindObjectScreen(wxDC &dc, CoordType xpos, CoordType *cxpos) const
{
wxASSERT(cxpos);
wxASSERT(xpos);
wxLayoutObjectList::iterator i;
CoordType x = 0, cx = 0, width;
for(i = m_ObjectList.begin(); i != NULLIT; i++)
{
(**i).Layout(dc);
width = (**i).GetWidth();
if( x <= xpos && xpos <= x + width )
{
*cxpos = cx + (**i).GetOffsetScreen(dc, xpos-x);
wxLogDebug("wxLayoutLine::FindObjectScreen: cursor xpos = %ld", *cxpos);
return i;
}
x += (**i).GetWidth();
cx += (**i).GetLength();
}
// behind last object:
*cxpos = cx;
return m_ObjectList.tail();
}
bool
wxLayoutLine::Insert(CoordType xpos, wxLayoutObject *obj)
{
@ -329,16 +383,13 @@ wxLayoutLine::Insert(CoordType xpos, wxLayoutObject *obj)
if(offset == len )
{
if( i == m_ObjectList.tail()) // last object?
{
m_ObjectList.push_back(obj);
m_Length += obj->GetLength();
}
else
{ // insert after current object
i++;
m_ObjectList.insert(i,obj);
m_Length += obj->GetLength();
}
m_Length += obj->GetLength();
return true;
}
/* Otherwise we need to split the current object.
@ -379,22 +430,23 @@ wxLayoutLine::Insert(CoordType xpos, wxString text)
CoordType
wxLayoutLine::Delete(CoordType xpos, CoordType npos)
{
CoordType offset;
CoordType offset, len;
wxASSERT(xpos >= 0);
wxASSERT(npos >= 0);
wxLOiterator i = FindObject(xpos, &offset);
while(npos > 0)
{
if(i == NULLIT) return false; // FIXME
if(i == NULLIT) return npos;
// now delete from that object:
if((**i).GetType() != WXLO_TYPE_TEXT)
{
if(offset != 0) // at end of line after a non-text object
return npos;
// always len == 1:
m_Length -= (**i).GetLength();
npos -= m_Length;
len = (**i).GetLength();
m_Length -= len;
npos -= len;
m_ObjectList.erase(i);
}
else
@ -508,8 +560,8 @@ wxLayoutLine::Draw(wxDC &dc, const wxPoint & offset) const
}
void
wxLayoutLine::Layout(wxDC &dc, wxPoint *cursorPos, wxPoint
*cursorSize,
wxLayoutLine::Layout(wxDC &dc, wxPoint *cursorPos,
wxPoint *cursorSize,
int cx)
{
wxLayoutObjectList::iterator i;
@ -635,21 +687,6 @@ wxLayoutLine::Layout(wxDC &dc, wxPoint *cursorPos, wxPoint
}
}
wxLayoutObject *
wxLayoutLine::FindObject(CoordType xpos)
{
wxASSERT(xpos >= 0);
if(xpos > GetWidth()) return NULL;
CoordType x = 0;
for(wxLOiterator i = m_ObjectList.begin(); i != NULLIT; i++)
{
x += (**i).GetWidth();
if(x > xpos) // we just crossed it
return *i;
}
return NULL;
}
wxLayoutLine *
wxLayoutLine::Break(CoordType xpos)
@ -690,7 +727,7 @@ wxLayoutLine::Break(CoordType xpos)
// current text object gets set to left half
tobj->GetText() = left; // set new text
newLine->Append(new wxLayoutObjectText(right));
m_Length -= m_Length - offset;
m_Length -= right.Length();
i++; // don't move this object to the new list
}
else
@ -728,6 +765,38 @@ wxLayoutLine::MergeNextLine(void)
RecalculatePositions(1);
}
CoordType
wxLayoutLine::GetWrapPosition(CoordType column)
{
CoordType offset;
wxLOiterator i = FindObject(column, &offset);
if(i == NULLIT) return -1; // cannot wrap
// go backwards through the list and look for space in text objects
do
{
if((**i).GetType() == WXLO_TYPE_TEXT)
{
do
{
if( isspace(((wxLayoutObjectText*)*i)->GetText()[offset]))
return column;
else
{
offset--;
column--;
}
}while(offset != -1);
}
else
column -= (**i).GetLength();
// This is both "else" and what has to be done after checking
// all positions of the text object:
i--;
offset = (**i).GetLength();
}while(i != NULLIT);
return -1;
}
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
@ -977,6 +1046,26 @@ wxLayoutList::LineBreak(void)
return true;
}
bool
wxLayoutList::WrapLine(CoordType column)
{
if(m_CursorPos.x <= column || column < 1)
return false; // do nothing yet
else
{
CoordType xpos = m_CursorLine->GetWrapPosition(column);
if(xpos == -1)
return false; // cannot break line
//else:
CoordType newpos = m_CursorPos.x - xpos - 1;
m_CursorPos.x = xpos;
LineBreak();
Delete(1); // delete the space
m_CursorPos.x = newpos;
return true;
}
}
bool
wxLayoutList::Delete(CoordType npos)
{
@ -991,7 +1080,12 @@ wxLayoutList::Delete(CoordType npos)
// First, check if line is empty:
if(m_CursorLine->GetLength() == 0)
{ // in this case, updating could probably be optimised
m_CursorLine = m_CursorLine->DeleteLine(true);
#ifdef WXLO_DEBUG
wxASSERT(DeleteLines(1) == 0);
#else
DeleteLines(1);
#endif
left--;
}
else
@ -1035,6 +1129,23 @@ wxLayoutList::DeleteLines(int n)
return n;
}
void
wxLayoutList::Recalculate(wxDC &dc, CoordType bottom) const
{
wxLayoutLine *line = m_FirstLine;
// first, make sure everything is calculated - this might not be
// needed, optimise it later
m_DefaultSetting->Layout(dc);
while(line)
{
line->RecalculatePosition(); // 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();
}
}
void
wxLayoutList::Layout(wxDC &dc, CoordType bottom) const
{
@ -1083,22 +1194,27 @@ wxLayoutList::Draw(wxDC &dc, wxPoint const &offset,
}
wxLayoutObject *
wxLayoutList::FindObject(wxPoint const pos)
wxLayoutList::FindObjectScreen(wxDC &dc, wxPoint const pos, wxPoint *cursorPos)
{
// First, find the right line:
wxLayoutLine *line = m_FirstLine;
wxPoint p;
// we need to run a layout here to get font sizes right :-(
m_DefaultSetting->Layout(dc);
while(line)
{
p = line->GetPosition();
if(p.y <= pos.y && p.y+line->GetHeight() >= pos.y)
break;
line->Layout(dc);
line = line->GetNextLine();
}
if(! line) return NULL; // not found
if(line == NULL) return NULL; // not found
if(cursorPos) cursorPos->y = line->GetLineNumber();
// Now, find the object in the line:
return line->FindObject(pos.x);
wxLOiterator i = line->FindObjectScreen(dc, pos.x, & cursorPos->x);
return (i == NULLIT) ? NULL : *i;
}
@ -1142,11 +1258,16 @@ wxLayoutList::DrawCursor(wxDC &dc, bool active, wxPoint const &translate)
(long)m_CursorLine->GetLength()));
#endif
if(active)
dc.SetBrush(*wxBLACK_BRUSH);
dc.SetBrush(*wxBLACK_BRUSH);
dc.SetLogicalFunction(wxXOR);
dc.SetPen(wxPen(*wxBLACK,1,wxSOLID));
dc.SetLogicalFunction(wxXOR);
dc.DrawRectangle(coords.x, coords.y, m_CursorSize.x, m_CursorSize.y);
if(active)
dc.DrawRectangle(coords.x, coords.y, m_CursorSize.x,
m_CursorSize.y);
else
dc.DrawLine(coords.x, coords.y+m_CursorSize.y-1,
coords.x+m_CursorSize.x, coords.y+m_CursorSize.y-1);
dc.SetLogicalFunction(wxCOPY);
dc.SetBrush(wxNullBrush);
}

View File

@ -33,10 +33,19 @@
# define WXLAYOUT_DEBUG
#endif
#ifdef WXLAYOUT_DEBUG
# define WXLO_TRACE(x) wxLogDebug(x)
#else
# define WXLO_TRACE(x)
#endif
#ifndef WXLO_DEFAULTFONTSIZE
# define WXLO_DEFAULTFONTSIZE 12
#endif
/// Types of currently supported layout objects.
enum wxLayoutObjectType
{
@ -105,6 +114,13 @@ public:
virtual CoordType GetWidth(void) const { return 0; }
/// returns the number of cursor positions occupied by this object
virtual CoordType GetLength(void) const { return 1; }
/** Returns the cursor offset relating to the screen x position
relative to begin of object.
@param dc the wxDC to use for calculations
@param xpos relative x position from head of object
@return cursor coordinate offset
*/
virtual CoordType GetOffsetScreen(wxDC &dc, CoordType xpos) const { return 0; }
/// constructor
wxLayoutObject() { m_UserData = NULL; }
@ -158,6 +174,14 @@ public:
virtual wxPoint GetSize(CoordType * top, CoordType *bottom) const;
/// Return just the width of the object on the screen.
virtual CoordType GetWidth(void) const { return m_Width; }
/** Returns the cursor offset relating to the screen x position
relative to begin of object.
@param dc the wxDC to use for calculations
@param xpos relative x position from head of object
@return cursor coordinate offset
*/
virtual CoordType GetOffsetScreen(wxDC &dc, CoordType xpos) const;
#ifdef WXLAYOUT_DEBUG
virtual void Debug(void);
@ -326,6 +350,13 @@ public:
@return true if a word was deleted
*/
bool DeleteWord(CoordType npos);
/** Finds a suitable position left to the given column to break the
line.
@param column we want to break the line to the left of this
@return column for breaking line or -1 if no suitable location found
*/
CoordType GetWrapPosition(CoordType column);
/** Finds the object which covers the cursor position xpos in this
line.
@ -337,6 +368,18 @@ public:
wxLayoutObjectList::iterator FindObject(CoordType xpos, CoordType
*offset) const ;
/** Finds the object which covers the screen position xpos in this
line.
@param dc the wxDC to use for calculations
@param xpos the screen x coordinate
@param offset where to store the difference between xpos and
the object's head
@return iterator to the object or NULLIT
*/
wxLayoutObjectList::iterator FindObjectScreen(wxDC &dc,
CoordType xpos,
CoordType *offset) const ;
/** Get the first object in the list. This is used by the wxlparser
functions to export the list.
@return iterator to the first object
@ -384,10 +427,11 @@ public:
int cx = 0);
/** This function finds an object belonging to a given cursor
position. It assumes that Layout() has been called before.
@param dc the wxDC to use for calculations
@param xpos screen x position
@return pointer to the object
*/
wxLayoutObject * FindObject(CoordType xpos);
wxLayoutObject * FindObjectScreen(wxDC &dc, CoordType xpos);
//@}
/**@name List traversal */
@ -419,6 +463,8 @@ public:
the list or until the coordinates no longer changed.
*/
void RecalculatePositions(int recurse = 0);
/// Recalculates the position of this line on the canvas.
wxPoint RecalculatePosition(void);
private:
/// Destructor is private. Use DeleteLine() to remove it.
~wxLayoutLine();
@ -431,8 +477,6 @@ private:
*/
void SetHeight(CoordType height)
{ m_Height = height; RecalculatePositions(true); }
/// Recalculates the position of this line on the canvas.
wxPoint RecalculatePosition(void);
/** Moves the linenumbers one on, because a line has been inserted
or deleted.
@ -539,6 +583,13 @@ public:
bool Insert(wxLayoutObject *obj);
/// Inserts a linebreak at current cursor position.
bool LineBreak(void);
/** Wraps the current line. Searches to the left of the cursor to
break the line. Does nothing if the cursor position is before
the break position parameter.
@param column the break position for the line, maximum length
@return true if line got broken
*/
bool WrapLine(CoordType column);
/** This function deletes npos cursor positions.
@param npos how many positions
@return true if everything got deleted
@ -637,6 +688,14 @@ public:
@param bottom optional y coordinate where to stop calculating
*/
void Layout(wxDC &dc, CoordType bottom = -1) const;
/** 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;
/** Returns the size of the list in screen coordinates.
The return value only makes sense after the list has been
drawn.
@ -660,12 +719,15 @@ public:
bool active = true,
const wxPoint & translate = wxPoint(0,0));
/** This function finds an object belonging to a given cursor
/** This function finds an object belonging to a given screen
position. It assumes that Layout() has been called before.
@param pos screen position
@param cursorPos if non NULL, store cursor position in there
@return pointer to the object
*/
wxLayoutObject * FindObject(wxPoint const pos);
wxLayoutObject * FindObjectScreen(wxDC &dc,
wxPoint const pos,
wxPoint *cursorPos = NULL);
//@}

View File

@ -29,6 +29,12 @@
# include "wxlwindow.h"
#endif
#include <ctype.h>
#define WXLO_XOFFSET 4
#define WXLO_YOFFSET 4
BEGIN_EVENT_TABLE(wxLayoutWindow,wxScrolledWindow)
EVT_PAINT (wxLayoutWindow::OnPaint)
EVT_CHAR (wxLayoutWindow::OnChar)
@ -39,20 +45,6 @@ BEGIN_EVENT_TABLE(wxLayoutWindow,wxScrolledWindow)
EVT_SET_FOCUS(wxLayoutWindow::OnSetFocus)
EVT_KILL_FOCUS(wxLayoutWindow::OnKillFocus)
END_EVENT_TABLE()
/*
EVT_MENU(WXLOWIN_MENU_LARGER, wxLayoutWindow::OnMenu)
EVT_MENU(WXLOWIN_MENU_SMALLER, wxLayoutWindow::OnMenu)
EVT_MENU(WXLOWIN_MENU_UNDERLINE_ON, wxLayoutWindow::OnMenu)
EVT_MENU(WXLOWIN_MENU_UNDERLINE_OFF, wxLayoutWindow::OnMenu)
EVT_MENU(WXLOWIN_MENU_BOLD_ON, wxLayoutWindow::OnMenu)
EVT_MENU(WXLOWIN_MENU_BOLD_OFF, wxLayoutWindow::OnMenu)
EVT_MENU(WXLOWIN_MENU_ITALICS_ON, wxLayoutWindow::OnMenu)
EVT_MENU(WXLOWIN_MENU_ITALICS_OFF, wxLayoutWindow::OnMenu)
EVT_MENU(WXLOWIN_MENU_ROMAN, wxLayoutWindow::OnMenu)
EVT_MENU(WXLOWIN_MENU_TYPEWRITER, wxLayoutWindow::OnMenu)
EVT_MENU(WXLOWIN_MENU_SANSSERIF, wxLayoutWindow::OnMenu)
*/
wxLayoutWindow::wxLayoutWindow(wxWindow *parent)
: wxScrolledWindow(parent, -1, wxDefaultPosition, wxDefaultSize,
@ -68,10 +60,12 @@ wxLayoutWindow::wxLayoutWindow(wxWindow *parent)
m_bitmap = new wxBitmap(4,4);
m_bitmapSize = wxPoint(4,4);
m_llist = new wxLayoutList();
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;
SetCursor(wxCURSOR_IBEAM);
SetDirty();
}
@ -95,9 +89,6 @@ wxLayoutWindow::MSWGetDlgCode()
void
wxLayoutWindow::OnMouse(int eventId, wxMouseEvent& event)
{
if(!m_doSendEvents) // nothing to do
return;
wxPaintDC dc( this );
PrepareDC( dc );
SetFocus();
@ -106,13 +97,20 @@ wxLayoutWindow::OnMouse(int eventId, wxMouseEvent& event)
findPos.x = dc.DeviceToLogicalX(event.GetX());
findPos.y = dc.DeviceToLogicalY(event.GetY());
findPos.x -= WXLO_XOFFSET;
findPos.y -= WXLO_YOFFSET;
if(findPos.x < 0) findPos.x = 0;
if(findPos.y < 0) findPos.y = 0;
#ifdef WXLAYOUT_DEBUG
wxLogDebug("wxLayoutWindow::OnMouse: (%d, %d) -> (%d, %d)",
event.GetX(), event.GetY(), findPos.x, findPos.y);
#endif
m_ClickPosition = findPos;
wxLayoutObject *obj = m_llist->FindObject(findPos);
wxPoint cursorPos;
wxLayoutObject *obj = m_llist->FindObjectScreen(dc, findPos, &cursorPos);
#ifdef WXLAYOUT_DEBUG
if(obj)
@ -121,7 +119,16 @@ wxLayoutWindow::OnMouse(int eventId, wxMouseEvent& event)
else
wxLogDebug("wxLayoutWindow::OnMouse: Found no object.");
#endif
// always move cursor to mouse click:
if(obj && eventId == WXLOWIN_MENU_LCLICK)
{
m_llist->MoveCursorTo(cursorPos);
DoPaint(false);
}
if(!m_doSendEvents) // nothing to do
return;
// only do the menu if activated, editable and not on a clickable object
if(eventId == WXLOWIN_MENU_RCLICK
&& IsEditable()
@ -176,6 +183,11 @@ wxLayoutWindow::OnChar(wxKeyEvent& event)
case 'k':
m_llist->DeleteToEndOfLine();
break;
#ifdef WXLAYOUT_DEBUG
case WXK_F1:
m_llist->SetFont(-1,-1,-1,-1,true); // underlined
break;
#endif
default:
;
}
@ -229,6 +241,8 @@ wxLayoutWindow::OnChar(wxKeyEvent& event)
if(m_llist->MoveCursorHorizontally(-1)) m_llist->Delete(1);
break;
case WXK_RETURN:
if(m_WrapMargin > 0)
m_llist->WrapLine(m_WrapMargin);
m_llist->LineBreak();
break;
default:
@ -238,8 +252,9 @@ wxLayoutWindow::OnChar(wxKeyEvent& event)
{
wxString tmp;
tmp += keyCode;
if(m_WrapMargin > 0 && isspace(keyCode))
m_llist->WrapLine(m_WrapMargin);
m_llist->Insert(tmp);
//// m_llist->WrapLine();
}
break;
}
@ -275,8 +290,11 @@ wxLayoutWindow::DoPaint(bool scrollToCursor)
// Maybe we need to change the scrollbar sizes or positions,
// so layout the list and check:
if(IsDirty() || scrollToCursor)
if(IsDirty())
m_llist->Layout(dc);
// this is needed even when only the cursor moved
m_llist->Layout(dc,y0+y1);
if(IsDirty())
ResizeScrollbars();
@ -315,8 +333,8 @@ wxLayoutWindow::DoPaint(bool scrollToCursor)
m_memDC->SetDeviceOrigin(0,0);
m_memDC->Clear();
// The +4 give the window a tiny border on the left and top, looks nice.
wxPoint offset(-x0+4,-y0+4);
// The offsets give the window a tiny border on the left and top, looks nice.
wxPoint offset(-x0+WXLO_XOFFSET,-y0+WXLO_YOFFSET);
m_llist->Draw(*m_memDC,offset);
if(IsEditable())
m_llist->DrawCursor(*m_memDC,m_HaveFocus,offset);
@ -409,6 +427,6 @@ wxLayoutWindow::OnSetFocus(wxFocusEvent &ev)
void
wxLayoutWindow::OnKillFocus(wxFocusEvent &ev)
{
m_HaveFocus = true;
m_HaveFocus = false;
DoPaint(); // to repaint the cursor
}

View File

@ -81,6 +81,11 @@ public:
void EnablePopup(bool enable = true) { m_DoPopupMenu = enable; }
/** Sets the wrap margin.
@param margin set this to 0 to disable it
*/
void SetWrapMargin(CoordType margin) { m_WrapMargin = margin; }
/** Redraws the window.
@param scrollToCursor if true, scroll the window so that the
cursor becomes visible
@ -154,6 +159,8 @@ private:
/// Can user edit the window?
bool m_Editable;
/// wrap margin
CoordType m_WrapMargin;
/// Is list dirty?
bool m_Dirty;
wxMemoryDC *m_memDC;