]> 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.
 
-There are three building blocks for richt text editing:
+There are three building blocks for rich text editing:
 
 wxllist :
 
@@ -40,7 +40,6 @@ linebreaks) and export of objects, text or 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.
 
index 529807c1c201274a319d683c17687d060c8077f2..938d91670d1dff79b2b171c7da8b9f365c4f6183 100644 (file)
@@ -50,9 +50,9 @@ wxLayoutObjectBase::Debug(void)
         << 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_TRACE(f)   cerr << #f":" << endl;
+#  define   WXL_TRACE(f)   cerr << #f":" << endl
 #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
-   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
@@ -305,8 +305,6 @@ wxLayoutList::Draw(wxDC &dc, bool findObject, wxPoint const &findCoords)
 #endif
       dc.IsKindOf(CLASSINFO(wxPostScriptDC)))
    {
-      WXL_VAR(wxThePrintSetupData);
-      
       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;
    
-   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()
@@ -375,38 +372,34 @@ wxLayoutList::Draw(wxDC &dc, bool findObject, wxPoint const &findCoords)
       // 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();
-            WXL_VAR(m_CursorPosition.x); WXL_VAR(cursor.x);
+            WXL_VAR(m_CursorPosition.x);
             str = str.substr(0, cursorOffset);
-            WXL_VAR(str);
             dc.GetTextExtent(Str(str), &width,&height, &descent);
-            WXL_VAR(height);
-            WXL_VAR(width);
-            WXL_VAR(descent);
             cursorPosition = wxPoint(position.x+width,
-                                      position.y+(baseLineSkip-height));
+                                     position.y+(baseLineSkip-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
-            {
-               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);
-   cerr << " line length: " << GetLineLength(i) << "  ";
+   cerr << " line length: " << GetLineLength(i,offs) << "  ";
    if(i == end())
    {
       cerr << "<<no object found>>" << endl;
@@ -559,10 +552,10 @@ wxLayoutList::FindObjectCursor(wxPoint *cpos, CoordType *offset)
          {
             if(cpos->x == object.x)
             {
-               *offset = 0;
+               if(offset) *offset = 0;
                return i;
             }
-            *offset=1;
+            if(offset) *offset=1;
             cpos->x = object.x;
             return i;
          }
@@ -594,7 +587,7 @@ wxLayoutList::FindObjectCursor(wxPoint *cpos, CoordType *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
@@ -619,26 +612,33 @@ wxLayoutList::FindCurrentObject(CoordType *offset)
    return obj;
 }
 
-void
+bool
 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)
+   {
       m_CursorPosition.y = 0;
+      rc = false;
+   }
    else if (m_CursorPosition.y > m_MaxLine)
+   {
       m_CursorPosition.y = m_MaxLine;
+      rc = false;
+   }
    
    while(dx > 0)
    {
       i = FindCurrentObject(&offs);
-      lineLength = GetLineLength(i);
+      lineLength = GetLineLength(i,offs);
       if(m_CursorPosition.x < lineLength)
       {
          m_CursorPosition.x ++;
@@ -654,7 +654,10 @@ wxLayoutList::MoveCursor(int dx, int dy)
             dx--;
          }
          else
+         {
+            rc = false;
             break; // cannot move there
+         }
       }
    }
    while(dx < 0)
@@ -671,21 +674,26 @@ wxLayoutList::MoveCursor(int dx, int dy)
             m_CursorPosition.y --;
             m_CursorPosition.x = 0;
             i = FindCurrentObject(&offs);
-            lineLength = GetLineLength(i);
+            lineLength = GetLineLength(i,offs);
             m_CursorPosition.x = lineLength;
             dx++;
             continue;
          }
          else
+         {
+            rc = false;
             break; // cannot move left any more
+         }
       }
    }
    // final adjustment:
    i = FindCurrentObject(&offs);
-   lineLength = GetLineLength(i);
+   lineLength = GetLineLength(i,offs);
    if(m_CursorPosition.x > lineLength)
+   {
       m_CursorPosition.x = lineLength;
-      
+      rc = false;
+   }
 #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;
-      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)
@@ -706,6 +714,7 @@ wxLayoutList::MoveCursor(int dx, int dy)
    else
       cerr << ' ' << _t[(*i)->GetType()] << endl;
 #endif
+   return rc;
 }
 
 void
@@ -829,6 +838,8 @@ void
 wxLayoutList::Insert(String const &text)
 {
    wxLayoutObjectText *tobj = NULL;
+   wxLayoutObjectList::iterator j;
+
    WXL_TRACE(Insert(text));
 
    if(! m_Editable)
@@ -837,22 +848,57 @@ wxLayoutList::Insert(String const &text)
    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);
-   }
-   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);
-      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
@@ -866,13 +912,16 @@ wxLayoutList::Insert(String const &text)
 }
 
 CoordType
-wxLayoutList::GetLineLength(wxLayoutObjectList::iterator i)
+wxLayoutList::GetLineLength(wxLayoutObjectList::iterator i, CoordType offs)
 {
    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--;
index 8959a80e104cb8f459473d1267e249e07ca8f48c..c892b8a318c2a27c05b733b8d4de40a599cf6b99 100644 (file)
@@ -39,7 +39,7 @@
 
 /// 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;
@@ -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; }
-   /// 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
@@ -264,8 +264,10 @@ public:
    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:
index 8d5b14e234e668d9571a4f28b8c5b3c72573b761..6e880288a5d18cb63f1e42c1ef47d574cb8aa351 100644 (file)
@@ -68,6 +68,7 @@ wxLayoutWindow::OnChar(wxKeyEvent& event)
    
    long keyCode = event.KeyCode();
    wxPoint p;
+   CoordType help;
    
    switch(event.KeyCode())
    {
@@ -100,11 +101,19 @@ wxLayoutWindow::OnChar(wxKeyEvent& event)
       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
-      m_llist.MoveCursor(-1);
-      m_llist.Delete(1);
+      if(m_llist.MoveCursor(-1))
+         m_llist.Delete(1);
       break;
    case WXK_RETURN:
       m_llist.LineBreak();