From 77c630ca853a557a42408d6ca2ee2ff658ff4708 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Karsten=20Ball=C3=BCder?= Date: Sun, 14 Mar 1999 16:04:57 +0000 Subject: [PATCH] Should work very well now. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@1928 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- user/wxLayout/TODO | 12 -- user/wxLayout/wxLayout.cpp | 7 +- user/wxLayout/wxllist.cpp | 217 ++++++++++++++++++++++++++++-------- user/wxLayout/wxllist.h | 72 +++++++++++- user/wxLayout/wxlwindow.cpp | 66 +++++++---- user/wxLayout/wxlwindow.h | 7 ++ 6 files changed, 288 insertions(+), 93 deletions(-) diff --git a/user/wxLayout/TODO b/user/wxLayout/TODO index cd9ff621ec..1bffa8dd99 100644 --- a/user/wxLayout/TODO +++ b/user/wxLayout/TODO @@ -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 diff --git a/user/wxLayout/wxLayout.cpp b/user/wxLayout/wxLayout.cpp index 880a1dd690..441580e3a5 100644 --- a/user/wxLayout/wxLayout.cpp +++ b/user/wxLayout/wxLayout.cpp @@ -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()); diff --git a/user/wxLayout/wxllist.cpp b/user/wxLayout/wxllist.cpp index 2181189c6d..246fbb98e1 100644 --- a/user/wxLayout/wxllist.cpp +++ b/user/wxLayout/wxllist.cpp @@ -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) - { - m_Position = pos; - if(m_Next) m_Next->RecalculatePositions(--recurse); - } - else + wxASSERT(recurse >= 0); + wxPoint pos = m_Position; + CoordType height = m_Height; + +// WXLO_TRACE("RecalculatePositions()"); + RecalculatePosition(); + if(m_Next) { - m_Position = pos; - if(recurse && 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(); } - } 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); } diff --git a/user/wxLayout/wxllist.h b/user/wxLayout/wxllist.h index 2ae0e08129..fab769d6f9 100644 --- a/user/wxLayout/wxllist.h +++ b/user/wxLayout/wxllist.h @@ -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); //@} diff --git a/user/wxLayout/wxlwindow.cpp b/user/wxLayout/wxlwindow.cpp index 83cbefdc5c..5fa7a63325 100644 --- a/user/wxLayout/wxlwindow.cpp +++ b/user/wxLayout/wxlwindow.cpp @@ -29,6 +29,12 @@ # include "wxlwindow.h" #endif +#include + + +#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 } diff --git a/user/wxLayout/wxlwindow.h b/user/wxLayout/wxlwindow.h index f6f7b6f03e..89d709a728 100644 --- a/user/wxLayout/wxlwindow.h +++ b/user/wxLayout/wxlwindow.h @@ -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; -- 2.45.2