]> git.saurik.com Git - wxWidgets.git/commitdiff
fixes
authorKarsten Ballüder <ballueder@usa.net>
Fri, 30 Oct 1998 10:14:58 +0000 (10:14 +0000)
committerKarsten Ballüder <ballueder@usa.net>
Fri, 30 Oct 1998 10:14:58 +0000 (10:14 +0000)
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@938 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

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

index ae32c3be24d41016ddabe21f4ceb6ef64610c7a2..5539268bc7dac5936ee0489c21b5a84c9756f4ad 100644 (file)
@@ -3,7 +3,8 @@ README for wxLayout classes
 ---------------------------
 
 All the source in this directory is copyrighted under the
-LGPL (GNU LIBRARY PUBLIC LICENSE), by Karsten Ballueder <ballueder@usa.net>.
+GPL (GNU GENERAL PUBLIC LICENSE), version 2,
+by Karsten Ballueder <ballueder@usa.net>.
 
 
 This is still work in progress, so if you want to make any significant
index fea12a903268769c2aaeb473bfe748b33b866299..0ee29a39ac2a014fb22071a5da3f4f4da4c27aca 100644 (file)
@@ -161,7 +161,9 @@ public:
    void *pop_front(void);
 
    /** Insert an element into the list.
-       @param i an iterator pointing to the element, before which the new one should be inserted
+       @param i an iterator pointing to the element, before which the
+       new one should be inserted. After the insert operation i will
+       point to the newly inserted element.
        @param element the element data
    */
    void insert(iterator & i, void *element);
index abba142b089902db86f1591f8981510e73141b99..d44ee4bcbdae2d7aefb09724d6a508d72c6f8ddb 100644 (file)
   - the list is responsible for calculating positions
   - the draw coordinates for each object are the top left corner
   - coordinates only get calculated when things get redrawn
-  - during redraw each line gets iterated over twice, first just
-    calculating baselines and positions, second to actually draw it
-  - the cursor position is the position before an object, i.e. if the
+  - The cursor position is the position before an object, i.e. if the
     buffer starts with a text-object, cursor 0,0 is just before the
-    first character
+    first character. For all non-text objects, the cursor positions
+    are 0==before or 1==behind. So that all non-text objects count as
+    one cursor position.
+*/
+
+/*
+  TODO:
 
-  - the cursor position and size must be decided at layout/draw time
-    or the fonts will be wrong
+  - new cursor movement calculations
+    - moving lines and moving across linebreaks still broken 
+
+  - blinking cursor
+  - mouse click positions cursor
+  - selection (SetMark(), GetSelection())
+  - DND acceptance of text
+
+  - wxlwindow: formatting menu: problem with checked/unchecked consistency gtk bug?
 */
 
+#define   USE_NEW_CURSORCODE 1
+
 /*
   Known wxGTK bugs:
   - MaxX()/MaxY() don't get set
@@ -242,7 +255,7 @@ void
 wxLayoutList::LineBreak(void)
 {
    Insert(new wxLayoutObjectLineBreak);
-   m_CursorPosition.x = 0; m_CursorPosition.y++;
+   m_CursorPos.x = 0; m_CursorPos.y++;
 }
 
 void
@@ -391,10 +404,10 @@ wxLayoutList::Layout(wxDC &dc, wxLayoutMargins *margins)
          headOfLine++;
          position_HeadOfLine = position;
       }
-      if(cursorObject == NULL && cursorPos.y == m_CursorPosition.y) // look for cursor
+      if(cursorObject == NULL && cursorPos.y == m_CursorPos.y) // look for cursor
       {
-         if(cursorPos.x >= m_CursorPosition.x &&
-            m_CursorPosition.x-cursorPos.x+(**i).CountPositions()) // cursor is in current object
+         if(cursorPos.x >= m_CursorPos.x &&
+            m_CursorPos.x-cursorPos.x+(**i).CountPositions()) // cursor is in current object
          {
             cursorObject = *i;
             CalculateCursor(dc);
@@ -472,6 +485,14 @@ wxLayoutList::CalculateCursor(wxDC &dc)
    CoordType baseLineSkip = 20; //FIXME
 
    CoordType offset;
+   if( FindCurrentObject() == iterator(NULL))  // empty list
+   {
+      DrawCursor(dc,true); // erase it
+      m_CursorCoords = wxPoint(0,0);
+      m_CursorSize = wxPoint(2,baseLineSkip);
+      m_CursorMoved = false; // coords are valid
+      return;
+   }
    wxLayoutObjectBase &obj = **FindCurrentObject(&offset);
 
    WXL_VAR(offset);
@@ -511,6 +532,9 @@ wxLayoutList::CalculateCursor(wxDC &dc)
 void
 wxLayoutList::DrawCursor(wxDC &dc, bool erase)
 {
+   if(! m_Editable)
+      return;
+   
    if(erase)
    {
       //dc.SetBrush(*wxWHITE_BRUSH);
@@ -581,9 +605,6 @@ wxLayoutList::ShowCurrentObject()
    CoordType offs;
    wxLayoutObjectList::iterator i = FindCurrentObject(&offs);
 
-   wxLayoutDebug("Cursor is at (%d, %d)",
-                 m_CursorPosition.x, m_CursorPosition.y);
-
    i = FindCurrentObject(&offs);
    wxLogDebug(" Line length: %d", GetLineLength(i));
 
@@ -598,6 +619,10 @@ wxLayoutList::ShowCurrentObject()
                  ((wxLayoutObjectText *)(*i))->GetText().c_str(), offs);
    else
       wxLogDebug(" %s", TypeString((*i)->GetType()));
+   wxLayoutDebug("CursorPos (%d, %d)", (int) m_CursorPos.x, (int) m_CursorPos.y);
+   wxLayoutDebug("CursorOffset = %d", (int) m_CursorOffset);
+   wxLayoutDebug("CursorObject = %p", m_CursorObject);
+
 }
 
 #endif
@@ -703,9 +728,10 @@ wxLayoutList::FindObjectCursor(wxPoint *cpos, CoordType *offset)
 wxLayoutObjectList::iterator 
 wxLayoutList::FindCurrentObject(CoordType *offset)
 {
+#if ! defined( USE_NEW_CURSORCODE )
    wxLayoutObjectList::iterator obj = end();
 
-   obj = FindObjectCursor(&m_CursorPosition, offset);
+   obj = FindObjectCursor(&m_CursorPos, offset);
    if(obj == end())  // not ideal yet
    {
       obj = tail();
@@ -713,8 +739,15 @@ wxLayoutList::FindCurrentObject(CoordType *offset)
          *offset = (*obj)->CountPositions(); // at the end of it
    }
    return obj;
+#else
+   if(offset)
+      *offset = m_CursorOffset;
+   return m_CursorObject;
+#endif
 }
 
+#if ! defined( USE_NEW_CURSORCODE )
+
 bool
 wxLayoutList::MoveCursor(int dx, int dy)
 {
@@ -725,18 +758,19 @@ wxLayoutList::MoveCursor(int dx, int dy)
    
    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)
+   //FIXME calculate cursor object & offset for y movements
+   if(dy > 0 && m_CursorPos.y < m_MaxLine)
+      m_CursorPos.y += dy;
+   else if(dy < 0 && m_CursorPos.y > 0)
+      m_CursorPos.y += dy; // dy is negative
+   if(m_CursorPos.y < 0)
    {
-      m_CursorPosition.y = 0;
+      m_CursorPos.y = 0;
       rc = false;
    }
-   else if (m_CursorPosition.y > m_MaxLine)
+   else if (m_CursorPos.y > m_MaxLine)
    {
-      m_CursorPosition.y = m_MaxLine;
+      m_CursorPos.y = m_MaxLine;
       rc = false;
    }
    
@@ -744,18 +778,18 @@ wxLayoutList::MoveCursor(int dx, int dy)
    {
       i = FindCurrentObject(&offs);
       lineLength = GetLineLength(i,offs);
-      if(m_CursorPosition.x < lineLength)
+      if(m_CursorPos.x < lineLength)
       {
-         m_CursorPosition.x ++;
+         m_CursorPos.x ++;
          dx--;
          continue;
       }
       else
       {
-         if(m_CursorPosition.y < m_MaxLine)
+         if(m_CursorPos.y < m_MaxLine)
          {
-            m_CursorPosition.y++;
-            m_CursorPosition.x = 0;
+            m_CursorPos.y++;
+            m_CursorPos.x = 0;
             dx--;
          }
          else
@@ -767,20 +801,20 @@ wxLayoutList::MoveCursor(int dx, int dy)
    }
    while(dx < 0)
    {
-      if(m_CursorPosition.x > 0)
+      if(m_CursorPos.x > 0)
       {
-         m_CursorPosition.x --;
+         m_CursorPos.x --;
          dx++;
       }
       else
       {
-         if(m_CursorPosition.y > 0)
+         if(m_CursorPos.y > 0)
          {
-            m_CursorPosition.y --;
-            m_CursorPosition.x = 0;
+            m_CursorPos.y --;
+            m_CursorPos.x = 0;
             i = FindCurrentObject(&offs);
             lineLength = GetLineLength(i,offs);
-            m_CursorPosition.x = lineLength;
+            m_CursorPos.x = lineLength;
             dx++;
             continue;
          }
@@ -794,9 +828,9 @@ wxLayoutList::MoveCursor(int dx, int dy)
 // final adjustment:
    i = FindCurrentObject(&offs);
    lineLength = GetLineLength(i,offs);
-   if(m_CursorPosition.x > lineLength)
+   if(m_CursorPos.x > lineLength)
    {
-      m_CursorPosition.x = lineLength;
+      m_CursorPos.x = lineLength;
       rc = false;
    }
 #ifdef   WXLAYOUT_DEBUG
@@ -805,6 +839,115 @@ wxLayoutList::MoveCursor(int dx, int dy)
    return rc;
 }
 
+#else
+
+bool
+wxLayoutList::MoveCursor(int dx, int dy)
+{
+   CoordType diff;
+
+   m_CursorMoved = true;  
+   
+   enum { up, down} direction;
+
+   wxPoint newPos = wxPoint(m_CursorPos.x + dx,
+                            m_CursorPos.y + dy);
+
+   // check for bounds
+   if(newPos.x < 0) newPos.x = 0;
+   if(newPos.y < 0) newPos.y = 0;
+   else if(newPos.y > m_MaxLine) newPos.y = m_MaxLine;
+
+   if(newPos.y > m_CursorPos.y ||
+      newPos.y == m_CursorPos.y &&
+      newPos.x >= m_CursorPos.x)
+      direction = up;
+   else
+      direction = down;
+      
+   // now move cursor forwards until at the new position:
+
+   // first, go to the right line:
+   while(newPos.y != m_CursorPos.y)
+   {
+      if(direction == up)
+      {
+         m_CursorPos.x +=
+            (**m_CursorObject).CountPositions() - m_CursorOffset;
+         if(m_CursorObject == tail())
+            break;  // can't go any further
+         if((**m_CursorObject).GetType() == WXLO_TYPE_LINEBREAK
+            && m_CursorOffset == 1)
+         {
+            m_CursorPos.y++; m_CursorPos.x = 0;
+         }
+         m_CursorObject ++; m_CursorOffset = 0;
+      }
+      else // down
+      {
+         m_CursorPos.x -= m_CursorOffset;
+         if(m_CursorObject == begin())
+            break;  // can't go any further
+         if((**m_CursorObject).GetType() == WXLO_TYPE_LINEBREAK &&
+            m_CursorOffset == 0)
+         {
+            m_CursorPos.y--;
+            m_CursorPos.x = GetLineLength(m_CursorObject);
+         }
+         m_CursorObject --; m_CursorOffset = (**m_CursorObject).CountPositions();
+      }
+   }
+   if(newPos.y != m_CursorPos.y) // reached begin/end of list,
+      newPos.y = m_CursorPos.y;  // exited by break
+      
+   // now line is right, go to right column:
+   direction = newPos.x >= m_CursorPos.x ? up : down;
+   while(newPos.x != m_CursorPos.x)
+   {
+      if(direction == up)
+      {
+         diff = newPos.x - m_CursorPos.x;
+         if(diff >= (**m_CursorObject).CountPositions())
+         {
+            m_CursorPos.x += (**m_CursorObject).CountPositions();
+            if(m_CursorObject == tail())
+            {
+               m_CursorOffset = (**m_CursorObject).CountPositions();
+               break; // cannot go further
+            }
+            m_CursorObject++; m_CursorOffset = 0;
+         }
+         else
+         {
+            m_CursorPos.x += diff;
+            m_CursorOffset += diff;
+         }
+      }
+      else // down
+      {
+         diff = m_CursorPos.x - newPos.x;
+         if(diff >= m_CursorOffset)
+         {
+            if(m_CursorObject == begin())
+            {
+               m_CursorOffset = 0;
+               m_CursorPos.x = 0;
+               break; // cannot go further
+            }
+            m_CursorObject--;
+            m_CursorOffset = (**m_CursorObject).CountPositions();
+         }
+         else
+         {
+            m_CursorPos.x -= diff;
+            m_CursorOffset -= diff;
+         }
+      }
+   }
+   return true; // FIXME: when return what?
+}
+#endif
+
 void
 wxLayoutList::Delete(CoordType count)
 {
@@ -835,6 +978,8 @@ wxLayoutList::Delete(CoordType count)
          {
             m_MaxLine--;
             erase(i);
+            m_CursorObject = i; // new i!
+            m_CursorOffset = 0; // Pos unchanged
             count--;
             continue; // we're done
          }
@@ -861,12 +1006,15 @@ wxLayoutList::Delete(CoordType count)
          {
             count -= len;
             erase(i);
+            m_CursorObject = i;
+            m_CursorOffset = 0;
             continue; 
          }
          else
          {
             len = count;
             tobj->GetText().erase(offs,len);
+            // cursor unchanged
             return; // we are done
          }
       }
@@ -878,7 +1026,10 @@ wxLayoutList::Delete(CoordType count)
          if(offs == 0)
          {
             count = count > len ? count -= len : 0;
-            erase(i); // after this, i is the iterator for the following object
+            erase(i); // after this, i is the iterator for the
+                      // following object
+            m_CursorObject = i;
+            m_CursorOffset = 0;
             continue;
          }
          else // delete the following object
@@ -905,9 +1056,15 @@ wxLayoutList::Insert(wxLayoutObjectBase *obj)
 //   WXL_TRACE(Insert(obj));
 
    if(i == end())
+   {
       push_back(obj);
+      m_CursorObject = tail();
+   }
    else if(offs == 0)
+   {
       insert(i,obj);
+      m_CursorObject = i;
+   }
 // do we have to split a text object?
    else if((*i)->GetType() == WXLO_TYPE_TEXT && offs != (*i)->CountPositions())
    {
@@ -929,12 +1086,19 @@ wxLayoutList::Insert(wxLayoutObjectBase *obj)
       wxLayoutObjectList::iterator j = i; // we want to apend after this object
       j++;
       if(j != end())
+      {
          insert(j, obj);
+         m_CursorObject = j;
+      }
       else
+      {
          push_back(obj);
+         m_CursorObject = tail();
+      }
    }
+   m_CursorPos.x += obj->CountPositions();
+   m_CursorOffset = obj->CountPositions();
    
-   m_CursorPosition.x += obj->CountPositions();
    if(obj->GetType() == WXLO_TYPE_LINEBREAK)
       m_MaxLine++;
    m_CursorMoved = true;
@@ -970,6 +1134,9 @@ wxLayoutList::Insert(String const &text)
       tobj = (wxLayoutObjectText *)*i ;
       wxASSERT(tobj);
       tobj->GetText().insert(offs,text);
+      m_CursorObject = i;
+      m_CursorOffset = offs + text.length();
+      m_CursorPos.x += text.length();
       break;
    case WXLO_TYPE_LINEBREAK:
    default:
@@ -981,29 +1148,51 @@ wxLayoutList::Insert(String const &text)
          {
             tobj = (wxLayoutObjectText *)*j;
             tobj->GetText()+=text;
+            m_CursorObject = j;
+            m_CursorOffset = (**j).CountPositions();
+            m_CursorPos.x += text.length();
          }
          else
+         {
             insert(i,new wxLayoutObjectText(text));
+            m_CursorObject = i;
+            m_CursorOffset = (**i).CountPositions();
+            m_CursorPos.x += m_CursorOffset;
+         }
       }
-      else // cursor after linebreak
+      else // offset == 1 : cursor after linebreak
       {
          j++;
+         m_CursorPos.x ++;
+         m_CursorObject = j;
+         m_CursorOffset = 0;
          if(j != end() && (**j).GetType() == WXLO_TYPE_TEXT)
          {
             tobj = (wxLayoutObjectText *)*j;
             tobj->GetText()=text+tobj->GetText();
+            m_CursorOffset = text.length();
+            m_CursorPos.x += m_CursorOffset;
          }
          else
          {
             if(j == end())
+            {
                push_back(new wxLayoutObjectText(text));
+               m_CursorObject = tail();
+               m_CursorOffset = (**m_CursorObject).CountPositions();
+               m_CursorPos.x += text.length();
+            }
             else
+            {
                insert(j,new wxLayoutObjectText(text));
+               m_CursorObject = j;
+               m_CursorOffset = (**j).CountPositions();
+               m_CursorPos.x += text.length();
+            }
          }
       }
       break;
    }
-   m_CursorPosition.x += strlen(text.c_str());
    m_CursorMoved = true;
 }
 
@@ -1060,7 +1249,10 @@ wxLayoutList::Clear(int family, int size, int style, int weight,
    if(! m_ColourBG) m_ColourBG = wxWHITE;
    
    m_Position = wxPoint(0,0);
-   m_CursorPosition = wxPoint(0,0);
+   m_CursorPos = wxPoint(0,0);
+   m_CursorObject = iterator(NULL);
+   m_CursorOffset = 0;
+   
    m_MaxLine = 0;
    m_LineHeight = (BASELINESTRETCH*m_FontPtSize)/10;
    m_MaxX = 0; m_MaxY = 0;
@@ -1106,6 +1298,14 @@ wxLayoutList::Find(wxPoint coords) const
 
 /******************** printing stuff ********************/
 
+wxLayoutPrintout::wxLayoutPrintout(wxLayoutList &llist,
+                                   wxString const & title)
+:wxPrintout(title)
+{
+   m_llist = &llist;
+   m_title = title;
+}
+
 bool wxLayoutPrintout::OnPrintPage(int page)
 {
    wxDC *dc = GetDC();
index 6693df64f52d60c6f27d4511022205d0366ca90a..faa0fcfa15a8d5e68f95916b27a935253e58fba7 100644 (file)
@@ -280,6 +280,13 @@ public:
                 int weight=-1, int underline = -1,
                 char const *fg = NULL,
                 char const *bg = NULL);
+   /// changes to the next larger font size
+   inline void SetFontLarger(void)
+      { SetFont(-1,(12*m_FontPtSize)/10); }
+   /// changes to the next smaller font size
+   inline void SetFontSmaller(void)
+      { SetFont(-1,(10*m_FontPtSize)/12); }
+   
    /// set font family
    inline void SetFontFamily(int family) { SetFont(family); }
    /// set font size
@@ -345,11 +352,11 @@ public:
    bool IsEditable(void) const { return m_Editable; }
    /// 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; }
+   void SetCursor(wxPoint const &p) { m_CursorPos = p; }
    void DrawCursor(wxDC &dc, bool erase = false);
    
    /// Get current cursor position cursor coords
-   wxPoint GetCursor(void) const { return m_CursorPosition; }
+   wxPoint GetCursor(void) const { return m_CursorPos; }
    /// Gets graphical coordinates of cursor
    wxPoint GetCursorCoords(void) const { return m_CursorCoords; }
    
@@ -404,12 +411,16 @@ protected:
 
    //---- this is needed for editing:
    /// where is the text cursor (column,line):
-   wxPoint   m_CursorPosition;
+   wxPoint   m_CursorPos;
    /// where to draw the cursor
    wxPoint   m_CursorCoords;
    /// how large to draw it
    wxPoint   m_CursorSize;
-
+   /// object iterator for current cursor position:
+   iterator  m_CursorObject;
+   /// position of cursor within m_CursorObject:
+   int       m_CursorOffset;
+   
    /// to store content overwritten by cursor
    wxMemoryDC m_CursorMemDC;
 
@@ -435,9 +446,7 @@ class wxLayoutPrintout: public wxPrintout
 {
  public:
    wxLayoutPrintout(wxLayoutList &llist, wxString const & title =
-                    "wxLayout Printout")
-      :wxPrintout(title)
-      { m_llist = &llist; m_title = title;}
+                    "wxLayout Printout");
    bool OnPrintPage(int page);
    bool HasPage(int page);
    bool OnBeginDocument(int startPage, int endPage);
index 828ac67a71fc0d2f76c1e17c0db2b90ec93e210d..73a2d28e8f8894807d03fbec76d95e6f390be8cf 100644 (file)
@@ -39,6 +39,14 @@ BEGIN_EVENT_TABLE(wxLayoutWindow,wxScrolledWindow)
    EVT_LEFT_DOWN(wxLayoutWindow::OnLeftMouseClick)
    EVT_RIGHT_DOWN(wxLayoutWindow::OnRightMouseClick)
    EVT_LEFT_DCLICK(wxLayoutWindow::OnMouseDblClick)
+   EVT_MENU(WXLOWIN_MENU_LARGER, wxLayoutWindow::OnMenu)
+   EVT_MENU(WXLOWIN_MENU_SMALLER, wxLayoutWindow::OnMenu)
+   EVT_MENU(WXLOWIN_MENU_UNDERLINE, wxLayoutWindow::OnMenu)
+   EVT_MENU(WXLOWIN_MENU_BOLD, wxLayoutWindow::OnMenu)
+   EVT_MENU(WXLOWIN_MENU_ITALICS, wxLayoutWindow::OnMenu)
+   EVT_MENU(WXLOWIN_MENU_ROMAN, wxLayoutWindow::OnMenu)
+   EVT_MENU(WXLOWIN_MENU_TYPEWRITER, wxLayoutWindow::OnMenu)
+   EVT_MENU(WXLOWIN_MENU_SANSSERIF, wxLayoutWindow::OnMenu)
 END_EVENT_TABLE()
 
 wxLayoutWindow::wxLayoutWindow(wxWindow *parent)
@@ -49,8 +57,9 @@ wxLayoutWindow::wxLayoutWindow(wxWindow *parent)
    m_ScrollbarsSet = false;
    m_doSendEvents = false;
    m_ViewStartX = 0; m_ViewStartY = 0;
-
-
+   m_DoPopupMenu = true;
+   m_PopupMenu = NULL;
+   
    CoordType
       max_x, max_y, lineHeight;
    m_llist.GetSize(&max_x, &max_y, &lineHeight);
@@ -90,7 +99,7 @@ wxLayoutWindow::OnMouse(int eventId, wxMouseEvent& event)
    wxPaintDC dc( this );
    PrepareDC( dc );     
    SetFocus();
-
+   
    wxPoint findPos;
    findPos.x = dc.DeviceToLogicalX(event.GetX());
    findPos.y = dc.DeviceToLogicalY(event.GetY());
@@ -98,6 +107,13 @@ wxLayoutWindow::OnMouse(int eventId, wxMouseEvent& event)
    TRACEMESSAGE(("wxLayoutWindow::OnMouse: (%d, %d) -> (%d, %d)",
                  event.GetX(), event.GetY(), findPos.x, findPos.y));
 
+   if(eventId == WXLOWIN_MENU_RCLICK && m_DoPopupMenu && m_llist.IsEditable())
+   {
+      // when does this menu get freed?
+      // how do we handle toggling? FIXME
+      PopupMenu(MakeFormatMenu(), event.GetX(), event.GetY());
+      return;
+   }
    // find the object at this position
    wxLayoutObjectBase *obj = m_llist.Find(findPos);
    if(obj)
@@ -290,3 +306,61 @@ wxLayoutWindow::Print(void)
       dc.EndDoc();
    }
 }
+
+wxMenu *
+wxLayoutWindow::MakeFormatMenu()
+{
+   if(m_PopupMenu)
+      return m_PopupMenu;
+   
+   wxMenu *m = new wxMenu();
+
+   m->Append(WXLOWIN_MENU_LARGER   ,_("&Larger"),_("Switch to larger font."), false);
+   m->Append(WXLOWIN_MENU_SMALLER  ,_("&Smaller"),_("Switch to smaller font."), false);
+   m->AppendSeparator();
+   m->Append(WXLOWIN_MENU_UNDERLINE,_("&Underline"),_("Toggle underline mode."), true);
+   m->Append(WXLOWIN_MENU_BOLD     ,_("&Bold"),_("Toggle bold mode."), true);
+   m->Append(WXLOWIN_MENU_ITALICS  ,_("&Italics"),_("Toggle italics mode."), true);
+   m->AppendSeparator();
+   m->Append(WXLOWIN_MENU_ROMAN     ,_("&Roman"),_("Toggle underline mode."), false);
+   m->Append(WXLOWIN_MENU_TYPEWRITER,_("&Typewriter"),_("Toggle bold mode."), false);
+   m->Append(WXLOWIN_MENU_SANSSERIF ,_("&Sans Serif"),_("Toggle italics mode."), false);
+
+   return m_PopupMenu = m;
+}
+
+void wxLayoutWindow::OnMenu(wxCommandEvent& event)
+{
+   if(! m_llist.IsEditable())
+      return;
+   
+   switch (event.GetId())
+   {
+   case WXLOWIN_MENU_LARGER:
+      m_llist.SetFontLarger();
+      break;
+   case WXLOWIN_MENU_SMALLER:
+      m_llist.SetFontSmaller();
+      break;
+   case WXLOWIN_MENU_UNDERLINE:
+      m_llist.SetFontUnderline(
+         m_PopupMenu->IsChecked(WXLOWIN_MENU_UNDERLINE) ? false : true
+            );
+         break;
+   case WXLOWIN_MENU_BOLD:
+      m_llist.SetFontWeight(
+         m_PopupMenu->IsChecked(WXLOWIN_MENU_BOLD) ? wxNORMAL : wxBOLD
+            );
+   case WXLOWIN_MENU_ITALICS:
+      m_llist.SetFontStyle(
+         m_PopupMenu->IsChecked(WXLOWIN_MENU_ITALICS) ? wxNORMAL : wxITALIC
+            );
+      break;
+   case WXLOWIN_MENU_ROMAN:
+      m_llist.SetFontFamily(wxROMAN); break;
+   case WXLOWIN_MENU_TYPEWRITER:
+      m_llist.SetFontFamily(wxFIXED); break;
+   case WXLOWIN_MENU_SANSSERIF:
+      m_llist.SetFontFamily(wxSWISS); break;
+   }
+}