]> git.saurik.com Git - wxWidgets.git/commitdiff
Looks like I've fixed the editing
authorKarsten Ballüder <ballueder@usa.net>
Wed, 12 Aug 1998 16:14:15 +0000 (16:14 +0000)
committerKarsten Ballüder <ballueder@usa.net>
Wed, 12 Aug 1998 16:14:15 +0000 (16:14 +0000)
bugs. Delete/Insert/Home/End/Ctrl-Delete all work as expected.
Cursor gets redrawn properly.
Scroll-to-cursor still missing.

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@511 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

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

index bedb164c7130a2dedd7dd3ca07031e3a45fb81f0..ae32c3be24d41016ddabe21f4ceb6ef64610c7a2 100644 (file)
@@ -9,7 +9,7 @@ LGPL (GNU LIBRARY PUBLIC LICENSE), by Karsten Ballueder <ballueder@usa.net>.
 This is still work in progress, so if you want to make any significant
 changes, please get in touch with me before.
 
 This is still work in progress, so if you want to make any significant
 changes, please get in touch with me before.
 
-There are three building blocks for richt text editing:
+There are three building blocks for rich text editing:
 
 wxllist :
 
 
 wxllist :
 
@@ -40,7 +40,6 @@ linebreaks) and export of objects, text or html.
 Planned for the future is an html parser for importing html.
 
 
 Planned for the future is an html parser for importing html.
 
 
-
 wxLayout.cpp is a simple test program. It will export Text and HTML to
 stdout and demonstrate some of the features and bugs of wxLayoutList.
 
 wxLayout.cpp is a simple test program. It will export Text and HTML to
 stdout and demonstrate some of the features and bugs of wxLayoutList.
 
index 529807c1c201274a319d683c17687d060c8077f2..938d91670d1dff79b2b171c7da8b9f365c4f6183 100644 (file)
@@ -50,9 +50,9 @@ wxLayoutObjectBase::Debug(void)
         << GetSize(&bl).y << " bl=" << bl; 
 }
 
         << GetSize(&bl).y << " bl=" << bl; 
 }
 
-#  define   WXL_VAR(x)   cerr << #x"=" << x << endl;
+#  define   WXL_VAR(x)   cerr << #x"=" << x << endl
 #  define   WXL_DBG_POINT(p)   cerr << #p << ": " << p.x << ',' << p.y << endl
 #  define   WXL_DBG_POINT(p)   cerr << #p << ": " << p.x << ',' << p.y << endl
-#  define   WXL_TRACE(f)   cerr << #f":" << endl;
+#  define   WXL_TRACE(f)   cerr << #f":" << endl
 #else 
 #  define   WXL_VAR(x)   
 #  define   WXL_DBG_POINT(p)   
 #else 
 #  define   WXL_VAR(x)   
 #  define   WXL_DBG_POINT(p)   
@@ -273,10 +273,10 @@ wxLayoutList::Draw(wxDC &dc, bool findObject, wxPoint const &findCoords)
    CoordType baseLineSkip = (BASELINESTRETCH * baseLine)/10;
 
    // where to draw the cursor
    CoordType baseLineSkip = (BASELINESTRETCH * baseLine)/10;
 
    // where to draw the cursor
-   wxPoint cursorPosition, cursorSize;
+   wxPoint
+      cursorPosition = wxPoint(0,0),
+      cursorSize = wxPoint(1,baseLineSkip);
    
    
-   // we trace the objects' cursor positions so we can draw the cursor
-   wxPoint cursor = wxPoint(0,0);
    // the cursor position inside the object
    CoordType cursorOffset = 0;
    // object under cursor
    // the cursor position inside the object
    CoordType cursorOffset = 0;
    // object under cursor
@@ -305,8 +305,6 @@ wxLayoutList::Draw(wxDC &dc, bool findObject, wxPoint const &findCoords)
 #endif
       dc.IsKindOf(CLASSINFO(wxPostScriptDC)))
    {
 #endif
       dc.IsKindOf(CLASSINFO(wxPostScriptDC)))
    {
-      WXL_VAR(wxThePrintSetupData);
-      
       dc.GetSize(&pageWidth, &pageHeight);
       dc.StartDoc(_("Printing..."));
       dc.StartPage();
       dc.GetSize(&pageWidth, &pageHeight);
       dc.StartDoc(_("Printing..."));
       dc.StartPage();
@@ -324,7 +322,6 @@ wxLayoutList::Draw(wxDC &dc, bool findObject, wxPoint const &findCoords)
    position.y = margins.right;
    position.x = margins.left;
    
    position.y = margins.right;
    position.x = margins.left;
    
-   WXL_VAR(findObject); WXL_VAR(findCoords.x); WXL_VAR(findCoords.y);
    // if the cursorobject is a cmd, we need to find the first
    // printable object:
    while(cursorObject != end()
    // if the cursorobject is a cmd, we need to find the first
    // printable object:
    while(cursorObject != end()
@@ -375,38 +372,34 @@ wxLayoutList::Draw(wxDC &dc, bool findObject, wxPoint const &findCoords)
       // draw the cursor
       if(m_Editable && draw && i == cursorObject)
       {
       // draw the cursor
       if(m_Editable && draw && i == cursorObject)
       {
+         WXL_VAR((**cursorObject).GetType());
+         WXL_VAR(m_CursorPosition.x); WXL_VAR(m_CursorPosition.y);
          if(type == WXLO_TYPE_TEXT) // special treatment
          {
             long descent = 0l; long width, height;
             tobj = (wxLayoutObjectText *)*i;
             String  str = tobj->GetText();
          if(type == WXLO_TYPE_TEXT) // special treatment
          {
             long descent = 0l; long width, height;
             tobj = (wxLayoutObjectText *)*i;
             String  str = tobj->GetText();
-            WXL_VAR(m_CursorPosition.x); WXL_VAR(cursor.x);
+            WXL_VAR(m_CursorPosition.x);
             str = str.substr(0, cursorOffset);
             str = str.substr(0, cursorOffset);
-            WXL_VAR(str);
             dc.GetTextExtent(Str(str), &width,&height, &descent);
             dc.GetTextExtent(Str(str), &width,&height, &descent);
-            WXL_VAR(height);
-            WXL_VAR(width);
-            WXL_VAR(descent);
             cursorPosition = wxPoint(position.x+width,
             cursorPosition = wxPoint(position.x+width,
-                                      position.y+(baseLineSkip-height));
+                                     position.y+(baseLineSkip-height));
             cursorSize = wxPoint(1, height);
             cursorSize = wxPoint(1, height);
-            //dc.DrawLine(position.x+width,
-            //            position.y+(baseLineSkip-height),
-            //            position.x+width, position.y+baseLineSkip);
          }
          }
-         else
+         else if(type == WXLO_TYPE_LINEBREAK)
          {
          {
-            if(type == WXLO_TYPE_LINEBREAK)
-               //dc.DrawLine(0, position.y+baseLineSkip, 0,               position.y+2*baseLineSkip);
-            {
-               cursorPosition = wxPoint(0, position.y);
-               cursorSize = wxPoint(1,baseLineSkip);
-            }
+            WXL_VAR(cursorOffset);
+            if(cursorOffset)
+               cursorPosition = wxPoint(0, position.y+baseLineSkip);
             else
             else
-            {
-               cursorPosition = wxPoint(position.x, position.y);
-               cursorSize = wxPoint(size.x > 0 ? size.x : 1,size.y > 0 ? size.y : baseLineSkip);
-            }
+               cursorPosition = wxPoint(0, position.y);
+            cursorSize = wxPoint(1,baseLineSkip);
+               
+         }
+         else
+         {
+            cursorPosition = wxPoint(position.x, position.y);
+            cursorSize = wxPoint(size.x > 0 ? size.x : 1,size.y > 0 ? size.y : baseLineSkip);
          }
       }
 
          }
       }
 
@@ -505,7 +498,7 @@ wxLayoutList::Debug(void)
         << m_CursorPosition.y;
    
    i = FindCurrentObject(&offs);
         << m_CursorPosition.y;
    
    i = FindCurrentObject(&offs);
-   cerr << " line length: " << GetLineLength(i) << "  ";
+   cerr << " line length: " << GetLineLength(i,offs) << "  ";
    if(i == end())
    {
       cerr << "<<no object found>>" << endl;
    if(i == end())
    {
       cerr << "<<no object found>>" << endl;
@@ -559,10 +552,10 @@ wxLayoutList::FindObjectCursor(wxPoint *cpos, CoordType *offset)
          {
             if(cpos->x == object.x)
             {
          {
             if(cpos->x == object.x)
             {
-               *offset = 0;
+               if(offset) *offset = 0;
                return i;
             }
                return i;
             }
-            *offset=1;
+            if(offset) *offset=1;
             cpos->x = object.x;
             return i;
          }
             cpos->x = object.x;
             return i;
          }
@@ -594,7 +587,7 @@ wxLayoutList::FindObjectCursor(wxPoint *cpos, CoordType *offset)
    if((**i).GetType()==WXLO_TYPE_LINEBREAK)
    {
       if(offset)
    if((**i).GetType()==WXLO_TYPE_LINEBREAK)
    {
       if(offset)
-         *offset = (cpos->x > object.x) ? 1 : 0;
+         *offset = 1;
       return i;
    }
    cpos->x = object.x; // would be the coordinate of next object
       return i;
    }
    cpos->x = object.x; // would be the coordinate of next object
@@ -619,26 +612,33 @@ wxLayoutList::FindCurrentObject(CoordType *offset)
    return obj;
 }
 
    return obj;
 }
 
-void
+bool
 wxLayoutList::MoveCursor(int dx, int dy)
 {
    CoordType offs, lineLength;
    wxLayoutObjectList::iterator i;
 
 wxLayoutList::MoveCursor(int dx, int dy)
 {
    CoordType offs, lineLength;
    wxLayoutObjectList::iterator i;
 
+   bool rc = true; // have we moved?
 
    if(dy > 0 && m_CursorPosition.y < m_MaxLine)
       m_CursorPosition.y += dy;
    else if(dy < 0 && m_CursorPosition.y > 0)
       m_CursorPosition.y += dy; // dy is negative
    if(m_CursorPosition.y < 0)
 
    if(dy > 0 && m_CursorPosition.y < m_MaxLine)
       m_CursorPosition.y += dy;
    else if(dy < 0 && m_CursorPosition.y > 0)
       m_CursorPosition.y += dy; // dy is negative
    if(m_CursorPosition.y < 0)
+   {
       m_CursorPosition.y = 0;
       m_CursorPosition.y = 0;
+      rc = false;
+   }
    else if (m_CursorPosition.y > m_MaxLine)
    else if (m_CursorPosition.y > m_MaxLine)
+   {
       m_CursorPosition.y = m_MaxLine;
       m_CursorPosition.y = m_MaxLine;
+      rc = false;
+   }
    
    while(dx > 0)
    {
       i = FindCurrentObject(&offs);
    
    while(dx > 0)
    {
       i = FindCurrentObject(&offs);
-      lineLength = GetLineLength(i);
+      lineLength = GetLineLength(i,offs);
       if(m_CursorPosition.x < lineLength)
       {
          m_CursorPosition.x ++;
       if(m_CursorPosition.x < lineLength)
       {
          m_CursorPosition.x ++;
@@ -654,7 +654,10 @@ wxLayoutList::MoveCursor(int dx, int dy)
             dx--;
          }
          else
             dx--;
          }
          else
+         {
+            rc = false;
             break; // cannot move there
             break; // cannot move there
+         }
       }
    }
    while(dx < 0)
       }
    }
    while(dx < 0)
@@ -671,21 +674,26 @@ wxLayoutList::MoveCursor(int dx, int dy)
             m_CursorPosition.y --;
             m_CursorPosition.x = 0;
             i = FindCurrentObject(&offs);
             m_CursorPosition.y --;
             m_CursorPosition.x = 0;
             i = FindCurrentObject(&offs);
-            lineLength = GetLineLength(i);
+            lineLength = GetLineLength(i,offs);
             m_CursorPosition.x = lineLength;
             dx++;
             continue;
          }
          else
             m_CursorPosition.x = lineLength;
             dx++;
             continue;
          }
          else
+         {
+            rc = false;
             break; // cannot move left any more
             break; // cannot move left any more
+         }
       }
    }
    // final adjustment:
    i = FindCurrentObject(&offs);
       }
    }
    // final adjustment:
    i = FindCurrentObject(&offs);
-   lineLength = GetLineLength(i);
+   lineLength = GetLineLength(i,offs);
    if(m_CursorPosition.x > lineLength)
    if(m_CursorPosition.x > lineLength)
+   {
       m_CursorPosition.x = lineLength;
       m_CursorPosition.x = lineLength;
-      
+      rc = false;
+   }
 #ifdef   WXLAYOUT_DEBUG
    i = FindCurrentObject(&offs);
    cerr << "Cursor: "
 #ifdef   WXLAYOUT_DEBUG
    i = FindCurrentObject(&offs);
    cerr << "Cursor: "
@@ -695,7 +703,7 @@ wxLayoutList::MoveCursor(int dx, int dy)
    if(i == end())
    {
       cerr << "<<no object found>>" << endl;
    if(i == end())
    {
       cerr << "<<no object found>>" << endl;
-      return;  // FIXME we should set cursor position to maximum allowed
+      return rc;  // FIXME we should set cursor position to maximum allowed
       // value then
    }
    if((*i)->GetType() == WXLO_TYPE_TEXT)
       // value then
    }
    if((*i)->GetType() == WXLO_TYPE_TEXT)
@@ -706,6 +714,7 @@ wxLayoutList::MoveCursor(int dx, int dy)
    else
       cerr << ' ' << _t[(*i)->GetType()] << endl;
 #endif
    else
       cerr << ' ' << _t[(*i)->GetType()] << endl;
 #endif
+   return rc;
 }
 
 void
 }
 
 void
@@ -829,6 +838,8 @@ void
 wxLayoutList::Insert(String const &text)
 {
    wxLayoutObjectText *tobj = NULL;
 wxLayoutList::Insert(String const &text)
 {
    wxLayoutObjectText *tobj = NULL;
+   wxLayoutObjectList::iterator j;
+
    WXL_TRACE(Insert(text));
 
    if(! m_Editable)
    WXL_TRACE(Insert(text));
 
    if(! m_Editable)
@@ -837,22 +848,57 @@ wxLayoutList::Insert(String const &text)
    CoordType offs;
    wxLayoutObjectList::iterator i = FindCurrentObject(&offs);
 
    CoordType offs;
    wxLayoutObjectList::iterator i = FindCurrentObject(&offs);
 
-   if(i != end() && (*i)->GetType() == WXLO_TYPE_TEXT)
-   {  // insert into an existing text object:
+   if(i == end())
+   {
+      Insert(new wxLayoutObjectText(text));
+      return;
+   }
+
+   switch((**i).GetType())
+   {
+   case WXLO_TYPE_TEXT:
+      // insert into an existing text object:
       WXL_TRACE(inserting into existing object);
       tobj = (wxLayoutObjectText *)*i ;
       wxASSERT(tobj);
       tobj->GetText().insert(offs,text);
       WXL_TRACE(inserting into existing object);
       tobj = (wxLayoutObjectText *)*i ;
       wxASSERT(tobj);
       tobj->GetText().insert(offs,text);
-   }
-   else      // check whether the previous object is text:
-   {
-      wxLayoutObjectList::iterator j = i;
-      j--;
+      break;
+   case WXLO_TYPE_LINEBREAK:
+      j = i;
+      if(offs == 0) // try to append to previous object
+      {
+         j--;
+         if(j != end() && (**j).GetType() == WXLO_TYPE_TEXT)
+         {
+            tobj = (wxLayoutObjectText *)*j;
+            tobj->GetText()+=text;
+         }
+         else
+            insert(i,new wxLayoutObjectText(text));
+      }
+      else // cursor after linebreak
+      {
+         j++;
+         if(j != end() && (**j).GetType() == WXLO_TYPE_TEXT)
+         {
+            tobj = (wxLayoutObjectText *)*j;
+            tobj->GetText()=text+tobj->GetText();
+         }
+         else
+         {
+            if(j == end())
+               push_back(new wxLayoutObjectText(text));
+            else
+               insert(j,new wxLayoutObjectText(text));
+         }
+      }
+      break;
+   default:
+      j = i; j--;
       WXL_TRACE(checking previous object);
       WXL_TRACE(checking previous object);
-      if(0 && j != end() && (*j)->GetType() == WXLO_TYPE_TEXT)
+      if(j != end() && (**j).GetType() == WXLO_TYPE_TEXT)
       {
       {
-         tobj = (wxLayoutObjectText *)*i;
-         wxASSERT(tobj);
+         tobj = (wxLayoutObjectText *)*j;
          tobj->GetText()+=text;
       }
       else  // insert a new text object
          tobj->GetText()+=text;
       }
       else  // insert a new text object
@@ -866,13 +912,16 @@ wxLayoutList::Insert(String const &text)
 }
 
 CoordType
 }
 
 CoordType
-wxLayoutList::GetLineLength(wxLayoutObjectList::iterator i)
+wxLayoutList::GetLineLength(wxLayoutObjectList::iterator i, CoordType offs)
 {
    if(i == end())
       return 0;
 
    CoordType len = 0;
 
 {
    if(i == end())
       return 0;
 
    CoordType len = 0;
 
+   if(offs == 0 && (**i).GetType() == WXLO_TYPE_LINEBREAK)
+      // we are before a linebrak
+      return 0;
    // search backwards for beginning of line:
    while(i != begin() && (*i)->GetType() != WXLO_TYPE_LINEBREAK)
       i--;
    // search backwards for beginning of line:
    while(i != begin() && (*i)->GetType() != WXLO_TYPE_LINEBREAK)
       i--;
index 8959a80e104cb8f459473d1267e249e07ca8f48c..c892b8a318c2a27c05b733b8d4de40a599cf6b99 100644 (file)
@@ -39,7 +39,7 @@
 
 /// Types of currently supported layout objects.
 enum wxLayoutObjectType
 
 /// Types of currently supported layout objects.
 enum wxLayoutObjectType
-{ WXLO_TYPE_INVALID, WXLO_TYPE_TEXT, WXLO_TYPE_CMD, WXLO_TYPE_ICON, WXLO_TYPE_LINEBREAK };
+{ WXLO_TYPE_INVALID = 0, WXLO_TYPE_TEXT, WXLO_TYPE_CMD, WXLO_TYPE_ICON, WXLO_TYPE_LINEBREAK };
 
 /// Type used for coordinates in drawing.
 typedef long CoordType;
 
 /// Type used for coordinates in drawing.
 typedef long CoordType;
@@ -249,8 +249,8 @@ public:
    void SetEditable(bool editable = true) { m_Editable = editable; }
    /// return true if list is editable
    bool IsEditable(void) const { return m_Editable; }
    void SetEditable(bool editable = true) { m_Editable = editable; }
    /// return true if list is editable
    bool IsEditable(void) const { return m_Editable; }
-   /// move cursor
-   void MoveCursor(int dx = 0, int dy = 0);
+   /// move cursor, returns true if it could move to the desired position
+   bool MoveCursor(int dx = 0, int dy = 0);
    void SetCursor(wxPoint const &p) { m_CursorPosition = p; }
    wxPoint GetCursor(void) const { return m_CursorPosition; }
    /// delete one or more cursor positions
    void SetCursor(wxPoint const &p) { m_CursorPosition = p; }
    wxPoint GetCursor(void) const { return m_CursorPosition; }
    /// delete one or more cursor positions
@@ -264,8 +264,10 @@ public:
    wxLayoutObjectCmd const *GetDefaults(void) const { return m_DefaultSetting ; }
 
    wxLayoutObjectList::iterator FindCurrentObject(CoordType *offset = NULL);
    wxLayoutObjectCmd const *GetDefaults(void) const { return m_DefaultSetting ; }
 
    wxLayoutObjectList::iterator FindCurrentObject(CoordType *offset = NULL);
-   // get the length of the line with the object pointed to by i
-   CoordType GetLineLength(wxLayoutObjectList::iterator i);
+   // get the length of the line with the object pointed to by i, offs 
+   // only used to decide whether we are before or after linebreak
+   CoordType GetLineLength(wxLayoutObjectList::iterator i,
+                           CoordType offs = 0);
 //@}
 protected:
    /// font parameters:
 //@}
 protected:
    /// font parameters:
index 8d5b14e234e668d9571a4f28b8c5b3c72573b761..6e880288a5d18cb63f1e42c1ef47d574cb8aa351 100644 (file)
@@ -68,6 +68,7 @@ wxLayoutWindow::OnChar(wxKeyEvent& event)
    
    long keyCode = event.KeyCode();
    wxPoint p;
    
    long keyCode = event.KeyCode();
    wxPoint p;
+   CoordType help;
    
    switch(event.KeyCode())
    {
    
    switch(event.KeyCode())
    {
@@ -100,11 +101,19 @@ wxLayoutWindow::OnChar(wxKeyEvent& event)
       m_llist.SetCursor(p);
       break;
    case WXK_DELETE :
       m_llist.SetCursor(p);
       break;
    case WXK_DELETE :
-      m_llist.Delete(1);
+      if(event.ControlDown()) // delete to end of line
+      {
+         help = m_llist.GetLineLength(
+            m_llist.FindCurrentObject(NULL))
+            - m_llist.GetCursor().x;
+         m_llist.Delete(help ? help : 1);
+      }
+      else
+         m_llist.Delete(1);
       break;
    case WXK_BACK: // backspace
       break;
    case WXK_BACK: // backspace
-      m_llist.MoveCursor(-1);
-      m_llist.Delete(1);
+      if(m_llist.MoveCursor(-1))
+         m_llist.Delete(1);
       break;
    case WXK_RETURN:
       m_llist.LineBreak();
       break;
    case WXK_RETURN:
       m_llist.LineBreak();