]> git.saurik.com Git - wxWidgets.git/commitdiff
Should work very well now.
authorKarsten Ballüder <ballueder@usa.net>
Sun, 14 Mar 1999 16:04:57 +0000 (16:04 +0000)
committerKarsten Ballüder <ballueder@usa.net>
Sun, 14 Mar 1999 16:04:57 +0000 (16:04 +0000)
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@1928 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

user/wxLayout/TODO
user/wxLayout/wxLayout.cpp
user/wxLayout/wxllist.cpp
user/wxLayout/wxllist.h
user/wxLayout/wxlwindow.cpp
user/wxLayout/wxlwindow.h

index cd9ff621ec5484289bfcaaa7d6233928ade9db4e..1bffa8dd999e4eb6def62e27893258ff796d74a0 100644 (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
 
index 880a1dd6903dc9ee2ef3cb6fdc257eba402b703e..441580e3a58f8d664ac98e7aeeeda041b72c915c 100644 (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());
index 2181189c6d7bdf5453c508062ffb41483da61596..246fbb98e19970a3cd6ba73c2247252831180e2f 100644 (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)
-   {
-      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);
 }
index 2ae0e081298fcc71a7b0182840551331a392d0fd..fab769d6f942538690610fae5f8d33d2e5fc0f6b 100644 (file)
 #   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);
 
    //@}
 
index 83cbefdc5cca204edb09e9e079f2cd542c877add..5fa7a63325c5fade7cbbe6ff947dad66a79de2f1 100644 (file)
 #   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
 }
index f6f7b6f03e1f5bef9c143db5a02bce53dd60f7e9..89d709a7286784b4fa0b6dc62476c9cfb8495158 100644 (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;