X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/cf76eeeca070a1cfeb3d686d2053e138aad74266..e7300ec6d9ebbd1cfa2fcf12c0ce6e5aee85a152:/src/x11/textctrl.cpp?ds=sidebyside diff --git a/src/x11/textctrl.cpp b/src/x11/textctrl.cpp index 9a0718f33c..d7ee081007 100644 --- a/src/x11/textctrl.cpp +++ b/src/x11/textctrl.cpp @@ -135,6 +135,8 @@ BEGIN_EVENT_TABLE(wxTextCtrl, wxControl) EVT_CHAR(wxTextCtrl::OnChar) EVT_MOUSE_EVENTS(wxTextCtrl::OnMouse) EVT_IDLE(wxTextCtrl::OnIdle) + EVT_KILL_FOCUS(wxTextCtrl::OnKillFocus) + EVT_SET_FOCUS(wxTextCtrl::OnSetFocus) EVT_MENU(wxID_CUT, wxTextCtrl::OnCut) EVT_MENU(wxID_COPY, wxTextCtrl::OnCopy) @@ -214,13 +216,15 @@ bool wxTextCtrl::Create( wxWindow *parent, if ((style & wxTE_MULTILINE) != 0) style |= wxALWAYS_SHOW_SB; - wxTextCtrlBase::Create( parent, id, wxDefaultPosition, size, + wxTextCtrlBase::Create( parent, id, pos /* wxDefaultPosition */, size, style|wxVSCROLL|wxHSCROLL|wxNO_FULL_REPAINT_ON_RESIZE ); SetBackgroundColour( *wxWHITE ); SetCursor( wxCursor( wxCURSOR_IBEAM ) ); + m_editable = ((m_windowStyle & wxTE_READONLY) == 0); + if (HasFlag(wxTE_PASSWORD)) m_sourceFont = wxFont( 12, wxMODERN, wxNORMAL, wxNORMAL ); else @@ -245,6 +249,8 @@ bool wxTextCtrl::Create( wxWindow *parent, // We create an input handler since it might be useful CreateInputHandler(wxINP_HANDLER_TEXTCTRL); + MyAdjustScrollbars(); + return TRUE; } @@ -267,7 +273,10 @@ wxString wxTextCtrl::GetValue() const void wxTextCtrl::SetValue(const wxString& value) { - m_modified = TRUE; + m_modified = FALSE; + + wxString oldValue = GetValue(); + m_cursorX = 0; m_cursorY = 0; ClearSelection(); @@ -317,6 +326,13 @@ void wxTextCtrl::SetValue(const wxString& value) } } } + + // Don't need to refresh if the value hasn't changed + if ((GetWindowStyle() & wxTE_MULTILINE) == 0) + { + if (value == oldValue) + return; + } MyAdjustScrollbars(); @@ -356,6 +372,17 @@ bool wxTextCtrl::IsEditable() const void wxTextCtrl::GetSelection(long* from, long* to) const { + if (m_selStartX == -1 || m_selStartY == -1 || + m_selEndX == -1 || m_selEndY == -1) + { + *from = GetInsertionPoint(); + *to = GetInsertionPoint(); + } + else + { + *from = XYToPosition(m_selStartX, m_selStartY); + *to = XYToPosition(m_selEndX, m_selEndY); + } } void wxTextCtrl::Clear() @@ -736,14 +763,15 @@ long wxTextCtrl::XYToPosition(long x, long y) const { if (i < (size_t)y) { - ret += m_lines[i].m_text.Len(); + // Add one for the end-of-line character + ret += m_lines[i].m_text.Len() + 1; continue; } - if ((size_t)x < m_lines[i].m_text.Len()) + if ((size_t)x < (m_lines[i].m_text.Len()+1)) return (ret + x); else - return (ret + m_lines[i].m_text.Len()); + return (ret + m_lines[i].m_text.Len() + 1); } return ret; @@ -764,19 +792,25 @@ bool wxTextCtrl::PositionToXY(long pos, long *x, long *y) const for (size_t i = 0; i < m_lines.GetCount(); i++) { - pos -= m_lines[i].m_text.Len(); - if (pos <= 0) + //pos -= m_lines[i].m_text.Len(); + //if (pos <= 0) + + // Add one for the end-of-line character. (In Windows, + // there are _two_ positions for each end of line.) + if (pos <= ((int)m_lines[i].m_text.Len())) { - xx = -pos; + xx = pos; if (x) *x = xx; if (y) *y = yy; return TRUE; } + pos -= (m_lines[i].m_text.Len() + 1); yy++; } // Last pos - xx = m_lines[ m_lines.GetCount()-1 ].m_text.Len(); + //xx = m_lines[ m_lines.GetCount()-1 ].m_text.Len(); + xx = pos; if (x) *x = xx; if (y) *y = yy; @@ -950,10 +984,18 @@ void wxTextCtrl::Undo() void wxTextCtrl::SetInsertionPoint(long pos) { + ClearSelection(); + long x, y; + PositionToXY(pos, & x, & y); + m_cursorX = x; + m_cursorY = y; + // TODO: scroll to this position if necessary + Refresh(); } void wxTextCtrl::SetInsertionPointEnd() { + SetInsertionPoint(GetLastPosition()); } long wxTextCtrl::GetInsertionPoint() const @@ -964,7 +1006,9 @@ long wxTextCtrl::GetInsertionPoint() const long wxTextCtrl::GetLastPosition() const { size_t lineCount = m_lines.GetCount() - 1; - return XYToPosition( m_lines[lineCount].m_text.Len()-1, lineCount ); + // It's the length of the line, not the length - 1, + // because there's a position after the last character. + return XYToPosition( m_lines[lineCount].m_text.Len(), lineCount ); } void wxTextCtrl::SetSelection(long from, long to) @@ -983,7 +1027,20 @@ bool wxTextCtrl::Enable( bool enable ) bool wxTextCtrl::SetFont(const wxFont& font) { - return FALSE; + wxTextCtrlBase::SetFont( font ); + + m_sourceFont = font; + + wxClientDC dc(this); + dc.SetFont( m_sourceFont ); + m_lineHeight = dc.GetCharHeight(); + m_charWidth = dc.GetCharWidth(); + + // TODO: recalc longest lines + + MyAdjustScrollbars(); + + return TRUE; } bool wxTextCtrl::SetForegroundColour(const wxColour& colour) @@ -1816,13 +1873,18 @@ void wxTextCtrl::OnPaint( wxPaintEvent &event ) int scroll_y = 0; GetViewStart( NULL, &scroll_y ); + // We have a inner border of two pixels + // around the text, so scroll units do + // not correspond to lines. + if (scroll_y > 0) scroll_y--; + int size_x = 0; int size_y = 0; GetClientSize( &size_x, &size_y ); dc.SetPen( *wxTRANSPARENT_PEN ); dc.SetBrush( wxBrush( wxTHEME_COLOUR(HIGHLIGHT), wxSOLID ) ); - int upper = wxMin( (int)m_lines.GetCount(), scroll_y+(size_y/m_lineHeight)+1 ); + int upper = wxMin( (int)m_lines.GetCount(), scroll_y+(size_y/m_lineHeight)+2 ); for (int i = scroll_y; i < upper; i++) { int x = 0+2; @@ -1834,10 +1896,14 @@ void wxTextCtrl::OnPaint( wxPaintEvent &event ) DrawLine( dc, 0+2, i*m_lineHeight+2, m_lines[i].m_text, i ); } - dc.SetBrush( *wxRED_BRUSH ); - // int xx = m_cursorX*m_charWidth; - int xx = PosToPixel( m_cursorY, m_cursorX ); - dc.DrawRectangle( xx+2, m_cursorY*m_lineHeight+2, 2, m_lineHeight ); + if (m_editable && (FindFocus() == this)) + { + ///dc.SetBrush( *wxRED_BRUSH ); + dc.SetBrush( *wxBLACK_BRUSH ); + // int xx = m_cursorX*m_charWidth; + int xx = PosToPixel( m_cursorY, m_cursorX ); + dc.DrawRectangle( xx+2, m_cursorY*m_lineHeight+2, 2, m_lineHeight ); + } } void wxTextCtrl::OnMouse( wxMouseEvent &event ) @@ -1891,6 +1957,8 @@ void wxTextCtrl::OnChar( wxKeyEvent &event ) { if (m_lines.GetCount() == 0) return; + if (!m_editable) return; + int size_x = 0; int size_y = 0; GetClientSize( &size_x, &size_y ); @@ -2183,9 +2251,11 @@ void wxTextCtrl::RefreshDown( int n ) void wxTextCtrl::MoveCursor( int new_x, int new_y, bool shift, bool centre ) { - // if (IsSingleLine()) + if (!m_editable) return; + + // if (IsSingleLine() || (m_lang == wxSOURCE_LANG_NONE)) { - if (new_x > m_lines[new_y].m_text.Len()) + if (new_x > (int) (m_lines[new_y].m_text.Len())) new_x = m_lines[new_y].m_text.Len(); } @@ -2197,6 +2267,7 @@ void wxTextCtrl::MoveCursor( int new_x, int new_y, bool shift, bool centre ) if (shift) { int x,y,w,h; + bool erase_background = TRUE; if (!has_selection) { @@ -2261,11 +2332,17 @@ void wxTextCtrl::MoveCursor( int new_x, int new_y, bool shift, bool centre ) { y = m_selEndY*m_lineHeight; h = (new_y-m_selEndY+1) * m_lineHeight; + + erase_background = ((m_selEndY < m_selStartY) || + ((m_selEndY == m_selStartY) && (m_selEndX < m_selStartX))); } else { y = new_y*m_lineHeight; h = (-new_y+m_selEndY+1) * m_lineHeight; + + erase_background = ((m_selEndY > m_selStartY) || + ((m_selEndY == m_selStartY) && (m_selEndX > m_selStartX))); } no_cursor_refresh = TRUE; m_cursorX = new_x; @@ -2278,7 +2355,7 @@ void wxTextCtrl::MoveCursor( int new_x, int new_y, bool shift, bool centre ) CalcScrolledPosition( x, y, &x, &y ); wxRect rect( x+2, y+2, w, h ); - Refresh( TRUE, &rect ); + Refresh( erase_background, &rect ); } else { @@ -2326,14 +2403,18 @@ void wxTextCtrl::MoveCursor( int new_x, int new_y, bool shift, bool centre ) m_cursorY = new_y; Refresh( TRUE, &rect ); - - wxClientDC dc(this); - PrepareDC( dc ); - dc.SetPen( *wxTRANSPARENT_PEN ); - dc.SetBrush( *wxRED_BRUSH ); - // int xx = m_cursorX*m_charWidth; - int xx = PosToPixel( m_cursorY, m_cursorX ); - dc.DrawRectangle( xx+2, m_cursorY*m_lineHeight+2, 2, m_lineHeight ); + + if (FindFocus() == this) + { + wxClientDC dc(this); + PrepareDC( dc ); + dc.SetPen( *wxTRANSPARENT_PEN ); + //dc.SetBrush( *wxRED_BRUSH ); + dc.SetBrush( *wxBLACK_BRUSH ); + // int xx = m_cursorX*m_charWidth; + int xx = PosToPixel( m_cursorY, m_cursorX ); + dc.DrawRectangle( xx+2, m_cursorY*m_lineHeight+2, 2, m_lineHeight ); + } } int size_x = 0; @@ -2379,7 +2460,7 @@ void wxTextCtrl::MyAdjustScrollbars() int height = 0; GetClientSize( NULL, &height ); height -= 4; - if (height >= m_lines.GetCount() *m_lineHeight) + if (height >= (int)m_lines.GetCount() *m_lineHeight) y_range = 0; int view_x = 0; @@ -2475,6 +2556,18 @@ void wxTextCtrl::Thaw() { } +void wxTextCtrl::OnSetFocus( wxFocusEvent& event ) +{ + // To hide or show caret, as appropriate + Refresh(); +} + +void wxTextCtrl::OnKillFocus( wxFocusEvent& event ) +{ + // To hide or show caret, as appropriate + Refresh(); +} + // ---------------------------------------------------------------------------- // text control scrolling // ----------------------------------------------------------------------------