]> git.saurik.com Git - wxWidgets.git/blobdiff - user/wxLayout/wxlwindow.cpp
wxlayout bug
[wxWidgets.git] / user / wxLayout / wxlwindow.cpp
index a0b37cb1c4afc1efd0eb6b8e673a8ebfae2eff59..a64e4286ae5f0841bbcbf4b4b4cdf9793aa8039b 100644 (file)
@@ -121,7 +121,6 @@ wxLayoutWindow::OnMouse(int eventId, wxMouseEvent& event)
    PrepareDC( dc );     
    SetFocus();
 
-   
    wxPoint findPos;
    findPos.x = dc.DeviceToLogicalX(event.GetX());
    findPos.y = dc.DeviceToLogicalY(event.GetY());
@@ -163,8 +162,8 @@ wxLayoutWindow::OnMouse(int eventId, wxMouseEvent& event)
    if(obj && eventId == WXLOWIN_MENU_LCLICK)
    {
       m_llist->MoveCursorTo(cursorPos);
-      m_ScrollToCursor = true;
-      Refresh();
+      ScrollToCursor();
+      Refresh(FALSE); // DoPaint suppresses flicker under GTK
    }
    if(!m_doSendEvents) // nothing to do
       return;
@@ -228,139 +227,130 @@ wxLayoutWindow::OnChar(wxKeyEvent& event)
             ;
          }
       }
-   
-   if(!IsEditable()) // do nothing
-   {
-      switch(keyCode)
-      {
-      case WXK_UP:
-         m_llist->MoveCursorVertically(-1);
-         break;
-      case WXK_DOWN:
-         m_llist->MoveCursorVertically(1);
-         break;
-      case WXK_PRIOR:
-         m_llist->MoveCursorVertically(-20);
-         break;
-      case WXK_NEXT:
-         m_llist->MoveCursorVertically(20);
-         break;
-      default:
-         ;
-      }
-      return;
-   }
-   
-   /* First, handle control keys */
-   if(event.ControlDown() && ! event.AltDown())
+
+   /* These two nested switches work like this:
+      The first one processes all non-editing keycodes, to move the
+      cursor, etc. It's default will process all keycodes causing
+      modifications to the buffer, but only if editing is allowed.
+   */
+   switch(keyCode)
    {
-      switch(keyCode)
+   case WXK_RIGHT:
+      m_llist->MoveCursorHorizontally(1);
+      break;
+   case WXK_LEFT:
+      m_llist->MoveCursorHorizontally(-1);
+      break;
+   case WXK_UP:
+      m_llist->MoveCursorVertically(-1);
+      break;
+   case WXK_DOWN:
+      m_llist->MoveCursorVertically(1);
+      break;
+   case WXK_PRIOR:
+      m_llist->MoveCursorVertically(-20);
+      break;
+   case WXK_NEXT:
+      m_llist->MoveCursorVertically(20);
+      break;
+   case WXK_HOME:
+      m_llist->MoveCursorToBeginOfLine();
+      break;
+   case WXK_END:
+      m_llist->MoveCursorToEndOfLine();
+      break;
+   default:
+      if(keyCode == 'c' && event.ControlDown())
+         Copy();
+      if( IsEditable() )
       {
-      case WXK_DELETE :
-      case 'd':
-         m_llist->Delete(1);
-         break;
-      case 'y':
-         m_llist->DeleteLines(1);
-         break;
-      case 'h': // like backspace
-         if(m_llist->MoveCursorHorizontally(-1)) m_llist->Delete(1);
-         break;
-      case 'u':
-         m_llist->DeleteToBeginOfLine();
-         break;
-      case 'k':
-         m_llist->DeleteToEndOfLine();
-         break;
-      case 'v':
-         Paste();
-         break;
+         /* First, handle control keys */
+         if(event.ControlDown() && ! event.AltDown())
+         {
+            switch(keyCode)
+            {
+            case WXK_DELETE :
+            case 'd':
+               m_llist->Delete(1);
+               break;
+            case 'y':
+               m_llist->DeleteLines(1);
+               break;
+            case 'h': // like backspace
+               if(m_llist->MoveCursorHorizontally(-1)) m_llist->Delete(1);
+               break;
+            case 'u':
+               m_llist->DeleteToBeginOfLine();
+               break;
+            case 'k':
+               m_llist->DeleteToEndOfLine();
+               break;
+            case 'v':
+               Paste();
+               break;
 #ifdef WXLAYOUT_DEBUG
-      case WXK_F1:
-         m_llist->SetFont(-1,-1,-1,-1,true);  // underlined
-         break;
+            case WXK_F1:
+               m_llist->SetFont(-1,-1,-1,-1,true);  // underlined
+               break;
 #endif
-      default:
-         ;
-      }
-   }
-   // ALT only:
-   else if( event.AltDown() && ! event.ControlDown() )
-   {
-      switch(keyCode)
-      {
-      case WXK_DELETE:
-      case 'd':
-         m_llist->DeleteWord();
-         break;
-      default:
-         ;
-      }
-   }
-   // no control keys:
-   else if ( ! event.AltDown() && ! event.ControlDown())
-   {
-      switch(keyCode)
-      {
-      case WXK_RIGHT:
-         m_llist->MoveCursorHorizontally(1);
-         break;
-      case WXK_LEFT:
-         m_llist->MoveCursorHorizontally(-1);
-         break;
-      case WXK_UP:
-         m_llist->MoveCursorVertically(-1);
-         break;
-      case WXK_DOWN:
-         m_llist->MoveCursorVertically(1);
-         break;
-      case WXK_PRIOR:
-         m_llist->MoveCursorVertically(-20);
-         break;
-      case WXK_NEXT:
-         m_llist->MoveCursorVertically(20);
-         break;
-      case WXK_HOME:
-         m_llist->MoveCursorToBeginOfLine();
-         break;
-      case WXK_END:
-         m_llist->MoveCursorToEndOfLine();
-         break;
-      case WXK_INSERT:
-         if(event.ShiftDown())
-            Paste();
-         break;
-      case WXK_DELETE :
-         m_llist->Delete(1);
-         break;
-      case WXK_BACK: // backspace
-         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:
-         if((!(event.ControlDown() || event.AltDown() || event.MetaDown()))
-            && (keyCode < 256 && keyCode >= 32)
-            )
+            default:
+               ;
+            }
+         }
+         // ALT only:
+         else if( event.AltDown() && ! event.ControlDown() )
          {
-            wxString tmp;
-            tmp += keyCode;
-            if(m_WrapMargin > 0 && isspace(keyCode))
-                m_llist->WrapLine(m_WrapMargin);
-            m_llist->Insert(tmp);
+            switch(keyCode)
+            {
+            case WXK_DELETE:
+            case 'd':
+               m_llist->DeleteWord();
+               break;
+            default:
+               ;
+            }
          }
-         break;
-      }
-   }
-   SetDirty();
-   SetModified();
-   m_ScrollToCursor = true;
-   //DoPaint(true); // paint and scroll to cursor
+         // no control keys:
+         else if ( ! event.AltDown() && ! event.ControlDown())
+         {
+            switch(keyCode)
+            {
+            case WXK_INSERT:
+               if(event.ShiftDown())
+                  Paste();
+               break;
+            case WXK_DELETE :
+               m_llist->Delete(1);
+               break;
+            case WXK_BACK: // backspace
+               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:
+               if((!(event.ControlDown() || event.AltDown() || event.MetaDown()))
+                  && (keyCode < 256 && keyCode >= 32)
+                  )
+               {
+                  wxString tmp;
+                  tmp += keyCode;
+                  if(m_WrapMargin > 0 && isspace(keyCode))
+                     m_llist->WrapLine(m_WrapMargin);
+                  m_llist->Insert(tmp);
+               }
+               break;
+            }
+         }
+         SetDirty();
+         SetModified();
+      }// if(IsEditable()) 
+   }// first switch()
+   ScrollToCursor();
    wxRect r = *m_llist->GetUpdateRect();
-   Refresh( FALSE, &r);
+   DoPaint(&r);
 }
 
 void
@@ -397,20 +387,16 @@ wxLayoutWindow::ScrollToCursor(void)
       cursor is visible if we are editing. */
       /** Scroll so that cursor is visible! */
    WXLO_DEBUG(("m_ScrollToCursor = %d", (int) m_ScrollToCursor));
-   if(IsEditable() && m_ScrollToCursor)
+   wxPoint cc = m_llist->GetCursorScreenPos(*m_memDC);
+   if(cc.x < x0 || cc.y < y0
+      || cc.x >= x0+(9*x1)/10 || cc.y >= y0+(9*y1/10))  // (9*x)/10 ==  90%
    {
-      wxPoint cc = m_llist->GetCursorScreenPos(*m_memDC);
-      if(cc.x < x0 || cc.y < y0
-         || cc.x >= x0+(9*x1)/10 || cc.y >= y0+(9*y1/10))  // (9*x)/10 ==  90%
-      {
-         int nx, ny;
-         nx = cc.x - x1/2; if(nx < 0) nx = 0;
-         ny = cc.y - y1/2; if(ny < 0) ny = 0;
-         Scroll(nx/dx,ny/dy); // new view start
-         x0 = nx; y0 = ny;
-         m_ScrollToCursor = false; // avoid recursion
-         Refresh(FALSE);  /// Re-entering this function!
-      }
+      int nx, ny;
+      nx = cc.x - x1/2; if(nx < 0) nx = 0;
+      ny = cc.y - y1/2; if(ny < 0) ny = 0;
+      Scroll(nx/dx,ny/dy); // new view start
+      x0 = nx; y0 = ny;
+      m_ScrollToCursor = false; // avoid recursion
    }
 }
 
@@ -453,33 +439,14 @@ wxLayoutWindow::InternalPaint(const wxRect *updateRect)
    if(x1 > m_maxx) m_maxx = x1;  
    if(y1 > m_maxy) m_maxy = y1;
 
-
-   //m_llist->InvalidateUpdateRect();
-   //const wxRect *r = m_llist->GetUpdateRect();
    WXLO_DEBUG(("Update rect: %ld,%ld / %ld,%ld",
                updateRect->x, updateRect->y,
                updateRect->x+updateRect->width,
                updateRect->y+updateRect->height));
 
-#if 0
-   //FIXME: we should never need to call Layout at all because the
-   //       list does it automatically.
-// Maybe we need to change the scrollbar sizes or positions,
-   // so layout the list and check:
-   if(IsDirty())
-      m_llist->Layout(dc);
-   wxLogDebug("Update rect after calling Layout: %ld,%ld / %ld,%ld",
-              r->x, r->y, r->x+r->width, r->y+r->height);
-   // this is needed even when only the cursor moved
-   m_llist->Layout(dc,y0+y1);
-   wxLogDebug("Update rect after calling Layout again: %ld,%ld / %ld,%ld",
-              r->x, r->y, r->x+r->width, r->y+r->height);
-#endif
-   
    if(IsDirty())
       ResizeScrollbars();
    
-   
    /* Check whether the window has grown, if so, we need to reallocate 
       the bitmap to be larger. */
    if(x1 > m_bitmapSize.x || y1 > m_bitmapSize.y)
@@ -494,8 +461,6 @@ wxLayoutWindow::InternalPaint(const wxRect *updateRect)
       m_memDC->SelectObject(*m_bitmap);
    }
 
-   // Device origins on the memDC are suspect, we translate manually
-   // with the translate parameter of Draw().
    m_memDC->SetDeviceOrigin(0,0);
    m_memDC->SetBrush(wxBrush(m_llist->GetDefaults()->GetBGColour(),wxSOLID));
    m_memDC->SetPen(wxPen(m_llist->GetDefaults()->GetBGColour(),
@@ -529,14 +494,20 @@ wxLayoutWindow::InternalPaint(const wxRect *updateRect)
                updateRect->x+updateRect->width,
                updateRect->y+updateRect->height)); 
    
+   // Device origins on the memDC are suspect, we translate manually
+   // with the translate parameter of Draw().
    wxPoint offset(-x0+WXLO_XOFFSET,-y0+WXLO_YOFFSET);
    m_llist->Draw(*m_memDC,offset, y0, y0+y1);
+
    // We start calculating a new update rect before drawing the
    // cursor, so that the cursor coordinates get included in the next
-   // update rectangle:
+   // update rectangle (although they are drawn on the memDC, this is
+   // needed to erase it):
    m_llist->InvalidateUpdateRect(); 
-   if(IsEditable()) //we draw the cursor
-      m_llist->DrawCursor(*m_memDC,m_HaveFocus,offset);
+   m_llist->DrawCursor(*m_memDC,
+                       m_HaveFocus && IsEditable(), // draw a thick
+                       // cursor for editable windows with focus
+                       offset);
 
 // Now copy everything to the screen:
 #if 0
@@ -701,12 +672,12 @@ void
 wxLayoutWindow::OnSetFocus(wxFocusEvent &ev)
 {
    m_HaveFocus = true;
-//FIXME   DoPaint(); // to repaint the cursor
+//FIXME: need argument   DoPaint(); // to repaint the cursor
 }
 
 void
 wxLayoutWindow::OnKillFocus(wxFocusEvent &ev)
 {
    m_HaveFocus = false;
-//FIXME   DoPaint(); // to repaint the cursor
+//FIXME: need argument   DoPaint(); // to repaint the cursor
 }