more work on wxTextCtrl: mostly works but very slow
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/branches/wxUNIVERSAL@8841 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
5
TODO
5
TODO
@@ -14,13 +14,14 @@ samples:
|
|||||||
|
|
||||||
wxTextCtrl
|
wxTextCtrl
|
||||||
|
|
||||||
*! call to RefreshLineRange() from Replace() is broken
|
*!! display corrupted when typing text in quickly (even single line)
|
||||||
*! display corrupted when typing text in quickly (caret problem?)
|
|
||||||
* caret leaves traces under wxGTK
|
* caret leaves traces under wxGTK
|
||||||
? text ctrl display pb when text is truncated
|
? text ctrl display pb when text is truncated
|
||||||
* remember selection when losing/gaining activation
|
* remember selection when losing/gaining activation
|
||||||
* too much is refreshed when double clicking (word select)
|
* too much is refreshed when double clicking (word select)
|
||||||
|
|
||||||
|
* scrolling by dragging mouse outside the window
|
||||||
|
|
||||||
All
|
All
|
||||||
|
|
||||||
! wxThemeSettings
|
! wxThemeSettings
|
||||||
|
@@ -115,6 +115,8 @@
|
|||||||
# endif
|
# endif
|
||||||
#endif /* wxUSE_RADIOBTN */
|
#endif /* wxUSE_RADIOBTN */
|
||||||
|
|
||||||
|
/* I wonder if we shouldn't just remove all occurrences of
|
||||||
|
wxUSE_DYNAMIC_CLASSES from the sources? */
|
||||||
#if !defined(wxUSE_DYNAMIC_CLASSES) || !wxUSE_DYNAMIC_CLASSES
|
#if !defined(wxUSE_DYNAMIC_CLASSES) || !wxUSE_DYNAMIC_CLASSES
|
||||||
# if wxABORT_ON_CONFIG_ERROR
|
# if wxABORT_ON_CONFIG_ERROR
|
||||||
# error "wxUSE_DYNAMIC_CLASSES must be defined as 1"
|
# error "wxUSE_DYNAMIC_CLASSES must be defined as 1"
|
||||||
|
@@ -16,7 +16,7 @@
|
|||||||
#pragma interface "ffile.h"
|
#pragma interface "ffile.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if wxUSE_FILE
|
#if wxUSE_FFILE
|
||||||
|
|
||||||
#ifndef WX_PRECOMP
|
#ifndef WX_PRECOMP
|
||||||
#include "wx/string.h"
|
#include "wx/string.h"
|
||||||
@@ -109,7 +109,7 @@ private:
|
|||||||
wxString m_name; // the name of the file (for diagnostic messages)
|
wxString m_name; // the name of the file (for diagnostic messages)
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // wxUSE_FILE
|
#endif // wxUSE_FFILE
|
||||||
|
|
||||||
#endif // _WX_FFILE_H_
|
#endif // _WX_FFILE_H_
|
||||||
|
|
||||||
|
@@ -20,11 +20,6 @@
|
|||||||
|
|
||||||
#include "wx/defs.h"
|
#include "wx/defs.h"
|
||||||
|
|
||||||
#if !wxUSE_FILE
|
|
||||||
#undef wxUSE_TEXTFILE
|
|
||||||
#define wxUSE_TEXTFILE 0
|
|
||||||
#endif // wxUSE_FILE
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// constants
|
// constants
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
@@ -55,6 +55,7 @@
|
|||||||
#define wxUSE_ZLIB 0
|
#define wxUSE_ZLIB 0
|
||||||
#define wxUSE_APPLE_IEEE 0
|
#define wxUSE_APPLE_IEEE 0
|
||||||
#define wxUSE_FILE 0
|
#define wxUSE_FILE 0
|
||||||
|
#define wxUSE_FFILE 1
|
||||||
#define wxUSE_TEXTFILE 0
|
#define wxUSE_TEXTFILE 0
|
||||||
#define wxUSE_INTL 0
|
#define wxUSE_INTL 0
|
||||||
#define wxUSE_MENUS 0
|
#define wxUSE_MENUS 0
|
||||||
|
@@ -67,6 +67,7 @@ enum
|
|||||||
TextTest_Add,
|
TextTest_Add,
|
||||||
TextTest_Insert,
|
TextTest_Insert,
|
||||||
TextTest_Clear,
|
TextTest_Clear,
|
||||||
|
TextTest_Load,
|
||||||
|
|
||||||
TextTest_Password,
|
TextTest_Password,
|
||||||
TextTest_WrapLines,
|
TextTest_WrapLines,
|
||||||
@@ -133,6 +134,7 @@ protected:
|
|||||||
void OnButtonInsert(wxCommandEvent& event);
|
void OnButtonInsert(wxCommandEvent& event);
|
||||||
void OnButtonAdd(wxCommandEvent& event);
|
void OnButtonAdd(wxCommandEvent& event);
|
||||||
void OnButtonClear(wxCommandEvent& event);
|
void OnButtonClear(wxCommandEvent& event);
|
||||||
|
void OnButtonLoad(wxCommandEvent& event);
|
||||||
|
|
||||||
void OnButtonQuit(wxCommandEvent& event);
|
void OnButtonQuit(wxCommandEvent& event);
|
||||||
|
|
||||||
@@ -231,6 +233,7 @@ BEGIN_EVENT_TABLE(TextTestFrame, wxFrame)
|
|||||||
EVT_BUTTON(TextTest_Clear, TextTestFrame::OnButtonClear)
|
EVT_BUTTON(TextTest_Clear, TextTestFrame::OnButtonClear)
|
||||||
EVT_BUTTON(TextTest_Add, TextTestFrame::OnButtonAdd)
|
EVT_BUTTON(TextTest_Add, TextTestFrame::OnButtonAdd)
|
||||||
EVT_BUTTON(TextTest_Insert, TextTestFrame::OnButtonInsert)
|
EVT_BUTTON(TextTest_Insert, TextTestFrame::OnButtonInsert)
|
||||||
|
EVT_BUTTON(TextTest_Load, TextTestFrame::OnButtonLoad)
|
||||||
|
|
||||||
EVT_UPDATE_UI(TextTest_Clear, TextTestFrame::OnUpdateUIClearButton)
|
EVT_UPDATE_UI(TextTest_Clear, TextTestFrame::OnUpdateUIClearButton)
|
||||||
|
|
||||||
@@ -305,9 +308,6 @@ TextTestFrame::TextTestFrame(const wxString& title)
|
|||||||
the pane containing the textctrl itself and the lower pane containing
|
the pane containing the textctrl itself and the lower pane containing
|
||||||
the buttons which allow to add/change/delete strings to/from it.
|
the buttons which allow to add/change/delete strings to/from it.
|
||||||
*/
|
*/
|
||||||
wxSizer *sizerTop = new wxBoxSizer(wxVERTICAL),
|
|
||||||
*sizerUp = new wxBoxSizer(wxHORIZONTAL),
|
|
||||||
*sizerLeft;
|
|
||||||
|
|
||||||
// upper left pane
|
// upper left pane
|
||||||
static const wxString modes[] =
|
static const wxString modes[] =
|
||||||
@@ -326,7 +326,7 @@ TextTestFrame::TextTestFrame(const wxString& title)
|
|||||||
m_chkWrapLines = new wxCheckBox(m_panel, TextTest_WrapLines, _T("Line &wrap"));
|
m_chkWrapLines = new wxCheckBox(m_panel, TextTest_WrapLines, _T("Line &wrap"));
|
||||||
m_chkReadonly = new wxCheckBox(m_panel, -1, _T("&Read-only mode"));
|
m_chkReadonly = new wxCheckBox(m_panel, -1, _T("&Read-only mode"));
|
||||||
|
|
||||||
sizerLeft = new wxStaticBoxSizer(box, wxVERTICAL);
|
wxSizer *sizerLeft = new wxStaticBoxSizer(box, wxVERTICAL);
|
||||||
|
|
||||||
sizerLeft->Add(m_radioTextLines, 0, wxGROW | wxALL, 5);
|
sizerLeft->Add(m_radioTextLines, 0, wxGROW | wxALL, 5);
|
||||||
sizerLeft->Add(5, 5, 0, wxGROW | wxALL, 5); // spacer
|
sizerLeft->Add(5, 5, 0, wxGROW | wxALL, 5); // spacer
|
||||||
@@ -347,6 +347,9 @@ TextTestFrame::TextTestFrame(const wxString& title)
|
|||||||
btn = new wxButton(m_panel, TextTest_Insert, _T("&Insert text"));
|
btn = new wxButton(m_panel, TextTest_Insert, _T("&Insert text"));
|
||||||
sizerMiddleUp->Add(btn, 0, wxALL | wxGROW, 5);
|
sizerMiddleUp->Add(btn, 0, wxALL | wxGROW, 5);
|
||||||
|
|
||||||
|
btn = new wxButton(m_panel, TextTest_Load, _T("&Load file"));
|
||||||
|
sizerMiddleUp->Add(btn, 0, wxALL | wxGROW, 5);
|
||||||
|
|
||||||
btn = new wxButton(m_panel, TextTest_Clear, _T("&Clear"));
|
btn = new wxButton(m_panel, TextTest_Clear, _T("&Clear"));
|
||||||
sizerMiddleUp->Add(btn, 0, wxALL | wxGROW, 5);
|
sizerMiddleUp->Add(btn, 0, wxALL | wxGROW, 5);
|
||||||
|
|
||||||
@@ -363,20 +366,20 @@ TextTestFrame::TextTestFrame(const wxString& title)
|
|||||||
_T("Current pos:"),
|
_T("Current pos:"),
|
||||||
m_textPosCur
|
m_textPosCur
|
||||||
),
|
),
|
||||||
0, wxGROW | wxRIGHT, 5);
|
0, wxRIGHT, 5);
|
||||||
sizerRow->Add(CreateTextWithLabelSizer
|
sizerRow->Add(CreateTextWithLabelSizer
|
||||||
(
|
(
|
||||||
_T("Col:"),
|
_T("Col:"),
|
||||||
m_textColCur
|
m_textColCur
|
||||||
),
|
),
|
||||||
0, wxGROW | wxLEFT | wxRIGHT, 5);
|
0, wxLEFT | wxRIGHT, 5);
|
||||||
sizerRow->Add(CreateTextWithLabelSizer
|
sizerRow->Add(CreateTextWithLabelSizer
|
||||||
(
|
(
|
||||||
_T("Row:"),
|
_T("Row:"),
|
||||||
m_textRowCur
|
m_textRowCur
|
||||||
),
|
),
|
||||||
0, wxGROW | wxLEFT, 5);
|
0, wxLEFT, 5);
|
||||||
sizerMiddleDown->Add(sizerRow, 0, wxALL | wxGROW, 5);
|
sizerMiddleDown->Add(sizerRow, 0, wxALL, 5);
|
||||||
|
|
||||||
m_textLineLast = CreateInfoText();
|
m_textLineLast = CreateInfoText();
|
||||||
m_textPosLast = CreateInfoText();
|
m_textPosLast = CreateInfoText();
|
||||||
@@ -389,7 +392,7 @@ TextTestFrame::TextTestFrame(const wxString& title)
|
|||||||
_T("Last position:"),
|
_T("Last position:"),
|
||||||
m_textPosLast
|
m_textPosLast
|
||||||
),
|
),
|
||||||
0, wxALL | wxGROW, 5
|
0, wxALL, 5
|
||||||
);
|
);
|
||||||
|
|
||||||
m_textSelFrom = CreateInfoText();
|
m_textSelFrom = CreateInfoText();
|
||||||
@@ -403,11 +406,11 @@ TextTestFrame::TextTestFrame(const wxString& title)
|
|||||||
_T("to"),
|
_T("to"),
|
||||||
m_textSelTo
|
m_textSelTo
|
||||||
),
|
),
|
||||||
0, wxALL | wxGROW, 5
|
0, wxALL, 5
|
||||||
);
|
);
|
||||||
wxSizer *sizerMiddle = new wxBoxSizer(wxVERTICAL);
|
wxSizer *sizerMiddle = new wxBoxSizer(wxVERTICAL);
|
||||||
sizerMiddle->Add(sizerMiddleUp, 1, wxGROW, 5);
|
sizerMiddle->Add(sizerMiddleUp, 0, wxGROW);
|
||||||
sizerMiddle->Add(sizerMiddleDown, 1, wxGROW | wxTOP, 5);
|
sizerMiddle->Add(sizerMiddleDown, 0, wxGROW | wxTOP, 5);
|
||||||
|
|
||||||
// I don't understand what's going on :-(
|
// I don't understand what's going on :-(
|
||||||
#ifdef __WXGTK__
|
#ifdef __WXGTK__
|
||||||
@@ -428,8 +431,9 @@ TextTestFrame::TextTestFrame(const wxString& title)
|
|||||||
);
|
);
|
||||||
|
|
||||||
// the 3 panes panes compose the upper part of the window
|
// the 3 panes panes compose the upper part of the window
|
||||||
|
wxSizer *sizerUp = new wxBoxSizer(wxHORIZONTAL);
|
||||||
sizerUp->Add(sizerLeft, 0, wxGROW | (wxALL & ~wxLEFT), 10);
|
sizerUp->Add(sizerLeft, 0, wxGROW | (wxALL & ~wxLEFT), 10);
|
||||||
sizerUp->Add(sizerMiddle, 1, wxGROW | wxALL, 10);
|
sizerUp->Add(sizerMiddle, 0, wxGROW | wxALL, 10);
|
||||||
sizerUp->Add(m_sizerText, 1, wxGROW | (wxALL & ~wxRIGHT), 10);
|
sizerUp->Add(m_sizerText, 1, wxGROW | (wxALL & ~wxRIGHT), 10);
|
||||||
|
|
||||||
// the lower one only has the log textctrl and a button to clear it
|
// the lower one only has the log textctrl and a button to clear it
|
||||||
@@ -457,7 +461,8 @@ TextTestFrame::TextTestFrame(const wxString& title)
|
|||||||
sizerDown->Add(sizerBtns, 0, wxALL | wxALIGN_RIGHT, 5);
|
sizerDown->Add(sizerBtns, 0, wxALL | wxALIGN_RIGHT, 5);
|
||||||
|
|
||||||
// put everything together
|
// put everything together
|
||||||
sizerTop->Add(sizerUp, 1, wxGROW | (wxALL & ~(wxTOP | wxBOTTOM)), 10);
|
wxSizer *sizerTop = new wxBoxSizer(wxVERTICAL);
|
||||||
|
sizerTop->Add(sizerUp, 1, wxGROW | wxRIGHT | wxLEFT, 10);
|
||||||
sizerTop->Add(0, 5, 0, wxGROW); // spacer in between
|
sizerTop->Add(0, 5, 0, wxGROW); // spacer in between
|
||||||
sizerTop->Add(sizerDown, 0, wxGROW | (wxALL & ~wxTOP), 10);
|
sizerTop->Add(sizerDown, 0, wxGROW | (wxALL & ~wxTOP), 10);
|
||||||
|
|
||||||
@@ -487,7 +492,7 @@ wxTextCtrl *TextTestFrame::CreateInfoText()
|
|||||||
if ( !s_maxWidth )
|
if ( !s_maxWidth )
|
||||||
{
|
{
|
||||||
// calc it once only
|
// calc it once only
|
||||||
GetTextExtent(_T("99999"), &s_maxWidth, NULL);
|
GetTextExtent(_T("9999999"), &s_maxWidth, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
wxTextCtrl *text = new wxTextCtrl(m_panel, -1, _T(""),
|
wxTextCtrl *text = new wxTextCtrl(m_panel, -1, _T(""),
|
||||||
@@ -678,6 +683,21 @@ void TextTestFrame::OnButtonClear(wxCommandEvent& WXUNUSED(event))
|
|||||||
m_text->SetFocus();
|
m_text->SetFocus();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TextTestFrame::OnButtonLoad(wxCommandEvent& WXUNUSED(event))
|
||||||
|
{
|
||||||
|
// search for the file in several dirs where it's likely to be
|
||||||
|
wxPathList pathlist;
|
||||||
|
pathlist.Add(_T("."));
|
||||||
|
pathlist.Add(_T(".."));
|
||||||
|
pathlist.Add(_T("../../../samples/texttest"));
|
||||||
|
|
||||||
|
wxString filename = pathlist.FindValidPath(_T("texttest.cpp"));
|
||||||
|
if ( !filename )
|
||||||
|
wxLogError(_T("File texttest.cpp not found."));
|
||||||
|
else if ( !m_text->LoadFile(filename) )
|
||||||
|
wxLogError(_T("Error loading file."));
|
||||||
|
}
|
||||||
|
|
||||||
void TextTestFrame::OnUpdateUIClearButton(wxUpdateUIEvent& event)
|
void TextTestFrame::OnUpdateUIClearButton(wxUpdateUIEvent& event)
|
||||||
{
|
{
|
||||||
event.Enable(!m_text->GetValue().empty());
|
event.Enable(!m_text->GetValue().empty());
|
||||||
|
@@ -386,12 +386,9 @@ MyUnivFrame::MyUnivFrame(const wxString& title)
|
|||||||
new wxTextCtrl(this, -1, _T("Hello, Universe!"),
|
new wxTextCtrl(this, -1, _T("Hello, Universe!"),
|
||||||
wxPoint(550, 150), wxDefaultSize);
|
wxPoint(550, 150), wxDefaultSize);
|
||||||
#else // TEST_TEXT_ONLY
|
#else // TEST_TEXT_ONLY
|
||||||
#if 0
|
#if 1
|
||||||
wxTextCtrl *text = new wxTextCtrl(this, -1, _T("Hello, Universe!"),
|
wxTextCtrl *text = new wxTextCtrl(this, -1, _T("Hello, Universe!"),
|
||||||
wxPoint(10, 40));
|
wxPoint(10, 40));
|
||||||
wxSize sizeText = text->GetBestSize();
|
|
||||||
sizeText.x = 200;
|
|
||||||
text->SetSize(sizeText);
|
|
||||||
#else
|
#else
|
||||||
wxTextCtrl *text = new wxTextCtrl(this, -1, _T("Hello,\nMultiverse!"),
|
wxTextCtrl *text = new wxTextCtrl(this, -1, _T("Hello,\nMultiverse!"),
|
||||||
wxPoint(10, 30),
|
wxPoint(10, 30),
|
||||||
@@ -410,6 +407,9 @@ MyUnivFrame::MyUnivFrame(const wxString& title)
|
|||||||
wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL));
|
wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL));
|
||||||
text->SetFocus();
|
text->SetFocus();
|
||||||
//text->SetEditable(FALSE);
|
//text->SetEditable(FALSE);
|
||||||
|
wxSize sizeText = text->GetBestSize();
|
||||||
|
sizeText.x = 200;
|
||||||
|
text->SetSize(sizeText);
|
||||||
#endif // !TEST_TEXT_ONLY/TEST_TEXT_ONLY
|
#endif // !TEST_TEXT_ONLY/TEST_TEXT_ONLY
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -28,7 +28,7 @@
|
|||||||
#pragma hdrstop
|
#pragma hdrstop
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if wxUSE_FILE
|
#if wxUSE_FFILE
|
||||||
|
|
||||||
#ifndef WX_PRECOMP
|
#ifndef WX_PRECOMP
|
||||||
#include "wx/intl.h"
|
#include "wx/intl.h"
|
||||||
@@ -258,4 +258,4 @@ size_t wxFFile::Length() const
|
|||||||
return (size_t)-1;
|
return (size_t)-1;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // wxUSE_FILE
|
#endif // wxUSE_FFILE
|
||||||
|
@@ -23,6 +23,18 @@
|
|||||||
with lots of text
|
with lots of text
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
Optimisation hints from PureQuantify:
|
||||||
|
|
||||||
|
1. wxStringTokenize is the slowest part of Replace
|
||||||
|
2. GetDC/ReleaseDC are very slow, avoid calling them several times
|
||||||
|
3. GetCharHeight() should be cached too
|
||||||
|
4. wxClientDC construction/destruction in HitTestLine is horribly expensive
|
||||||
|
|
||||||
|
For line wrapping controls HitTest2 takes 50% of program time. The results
|
||||||
|
of GetRowsPerLine and GetPartOfWrappedLine *MUST* be cached.
|
||||||
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Some terminology:
|
Some terminology:
|
||||||
|
|
||||||
@@ -1828,32 +1840,59 @@ void wxTextCtrl::UpdateLastVisible()
|
|||||||
if ( !IsSingleLine() )
|
if ( !IsSingleLine() )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// OPT: estimate the correct value first, just adjust it later
|
// use (efficient) HitTestLine to find the last visible character
|
||||||
|
wxString text = m_value.Mid((size_t)m_colStart /* to the end */);
|
||||||
wxString text;
|
wxTextCoord col;
|
||||||
wxCoord w, wOld;
|
switch ( HitTestLine(text, m_rectText.width, &col) )
|
||||||
|
|
||||||
w =
|
|
||||||
wOld = 0;
|
|
||||||
|
|
||||||
m_colLastVisible = m_colStart;
|
|
||||||
|
|
||||||
const wxChar *pc = m_value.c_str() + (size_t)m_colStart;
|
|
||||||
for ( ; *pc; pc++ )
|
|
||||||
{
|
{
|
||||||
text += *pc;
|
case wxTE_HT_BEYOND:
|
||||||
wOld = w;
|
// everything is visible
|
||||||
w = GetTextWidth(text);
|
m_colLastVisible = text.length();
|
||||||
if ( w > m_rectText.width )
|
|
||||||
{
|
|
||||||
// this char is too much
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_colLastVisible++;
|
// calc it below
|
||||||
|
m_posLastVisible = -1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
/*
|
||||||
|
case wxTE_HT_BEFORE:
|
||||||
|
case wxTE_HT_BELOW:
|
||||||
|
*/
|
||||||
|
default:
|
||||||
|
wxFAIL_MSG(_T("unexpected HitTestLine() return value"));
|
||||||
|
// fall through
|
||||||
|
|
||||||
|
case wxTE_HT_ON_TEXT:
|
||||||
|
if ( col > 0 )
|
||||||
|
{
|
||||||
|
// the last entirely seen character is the previous one because
|
||||||
|
// this one is only partly visible - unless the width of the
|
||||||
|
// string is exactly the max width
|
||||||
|
m_posLastVisible = GetTextWidth(text.Truncate(col + 1));
|
||||||
|
if ( m_posLastVisible > m_rectText.width )
|
||||||
|
{
|
||||||
|
// this character is not entirely visible, take the
|
||||||
|
// previous one
|
||||||
|
col--;
|
||||||
|
|
||||||
|
// recalc it
|
||||||
|
m_posLastVisible = -1;
|
||||||
|
}
|
||||||
|
//else: we can just see it
|
||||||
|
|
||||||
|
m_colLastVisible = col;
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_posLastVisible = wOld;
|
// calculate the width of the text really shown
|
||||||
|
if ( m_posLastVisible == -1 )
|
||||||
|
{
|
||||||
|
m_posLastVisible = GetTextWidth(text.Truncate(m_colLastVisible + 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
// current value is relative the start of the string text which starts at
|
||||||
|
// m_colStart, we need an absolute offset into string
|
||||||
|
m_colLastVisible += m_colStart;
|
||||||
|
|
||||||
wxLogTrace(_T("text"), _T("Last visible column/position is %d/%ld"),
|
wxLogTrace(_T("text"), _T("Last visible column/position is %d/%ld"),
|
||||||
m_colLastVisible, m_posLastVisible);
|
m_colLastVisible, m_posLastVisible);
|
||||||
@@ -1918,12 +1957,15 @@ size_t wxTextCtrl::GetPartOfWrappedLine(const wxChar* text,
|
|||||||
// the last entirely seen character is the previous one because
|
// the last entirely seen character is the previous one because
|
||||||
// this one is only partly visible - unless the width of the
|
// this one is only partly visible - unless the width of the
|
||||||
// string is exactly the max width
|
// string is exactly the max width
|
||||||
wReal = GetTextWidth(s.Truncate(col));
|
wReal = GetTextWidth(s.Truncate(col + 1));
|
||||||
if ( wReal > m_rectText.width )
|
if ( wReal > m_rectText.width )
|
||||||
{
|
{
|
||||||
// this character is not entirely visible, take the
|
// this character is not entirely visible, take the
|
||||||
// previous one
|
// previous one
|
||||||
col--;
|
col--;
|
||||||
|
|
||||||
|
// recalc the width
|
||||||
|
wReal = -1;
|
||||||
}
|
}
|
||||||
//else: we can just see it
|
//else: we can just see it
|
||||||
|
|
||||||
@@ -2639,7 +2681,7 @@ void wxTextCtrl::UpdateScrollbars()
|
|||||||
// is our height enough to show all items?
|
// is our height enough to show all items?
|
||||||
wxTextCoord nRows = GetNumberOfRowsBefore(GetNumberOfLines());
|
wxTextCoord nRows = GetNumberOfRowsBefore(GetNumberOfLines());
|
||||||
wxCoord lineHeight = GetCharHeight();
|
wxCoord lineHeight = GetCharHeight();
|
||||||
bool showScrollbarY = nRows*lineHeight > size.y;
|
bool showScrollbarY = !IsSingleLine() && nRows*lineHeight > size.y;
|
||||||
|
|
||||||
// is our width enough to show the longest line?
|
// is our width enough to show the longest line?
|
||||||
wxCoord charWidth, maxWidth;
|
wxCoord charWidth, maxWidth;
|
||||||
@@ -3072,12 +3114,6 @@ void wxTextCtrl::DoDrawTextInRect(wxDC& dc, const wxRect& rectUpdate)
|
|||||||
if ( colEnd > m_colLastVisible )
|
if ( colEnd > m_colLastVisible )
|
||||||
{
|
{
|
||||||
colEnd = m_colLastVisible;
|
colEnd = m_colLastVisible;
|
||||||
|
|
||||||
// we don't draw the last character because it may be shown
|
|
||||||
// only partially in single line mode (in multi line we can't
|
|
||||||
// avoid showing parts of characters anyhow)
|
|
||||||
if ( colEnd > colStart )
|
|
||||||
colEnd--;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -349,6 +349,17 @@ public:
|
|||||||
bool pressed);
|
bool pressed);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class wxWin32TextCtrlInputHandler : public wxStdTextCtrlInputHandler
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
wxWin32TextCtrlInputHandler(wxInputHandler *handler)
|
||||||
|
: wxStdTextCtrlInputHandler(handler) { }
|
||||||
|
|
||||||
|
virtual bool HandleKey(wxControl *control,
|
||||||
|
const wxKeyEvent& event,
|
||||||
|
bool pressed);
|
||||||
|
};
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// wxWin32ColourScheme: uses (default) Win32 colours
|
// wxWin32ColourScheme: uses (default) Win32 colours
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
@@ -770,7 +781,7 @@ wxInputHandler *wxWin32Theme::GetInputHandler(const wxString& control)
|
|||||||
else if ( control == wxINP_HANDLER_CHECKLISTBOX )
|
else if ( control == wxINP_HANDLER_CHECKLISTBOX )
|
||||||
handler = new wxStdCheckListboxInputHandler(GetDefaultInputHandler());
|
handler = new wxStdCheckListboxInputHandler(GetDefaultInputHandler());
|
||||||
else if ( control == wxINP_HANDLER_TEXTCTRL )
|
else if ( control == wxINP_HANDLER_TEXTCTRL )
|
||||||
handler = new wxStdTextCtrlInputHandler(GetDefaultInputHandler());
|
handler = new wxWin32TextCtrlInputHandler(GetDefaultInputHandler());
|
||||||
else
|
else
|
||||||
handler = GetDefaultInputHandler();
|
handler = GetDefaultInputHandler();
|
||||||
|
|
||||||
@@ -2121,3 +2132,42 @@ bool wxWin32CheckboxInputHandler::HandleKey(wxControl *control,
|
|||||||
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// wxWin32TextCtrlInputHandler
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
bool wxWin32TextCtrlInputHandler::HandleKey(wxControl *control,
|
||||||
|
const wxKeyEvent& event,
|
||||||
|
bool pressed)
|
||||||
|
{
|
||||||
|
// handle only MSW-specific text bindings here, the others are handled in
|
||||||
|
// the base class
|
||||||
|
if ( pressed )
|
||||||
|
{
|
||||||
|
int keycode = event.GetKeyCode();
|
||||||
|
|
||||||
|
wxControlAction action;
|
||||||
|
if ( keycode == WXK_DELETE && event.ShiftDown() )
|
||||||
|
{
|
||||||
|
action = wxACTION_TEXT_CUT;
|
||||||
|
}
|
||||||
|
else if ( keycode == WXK_INSERT )
|
||||||
|
{
|
||||||
|
if ( event.ControlDown() )
|
||||||
|
action = wxACTION_TEXT_COPY;
|
||||||
|
else if ( event.ShiftDown() )
|
||||||
|
action = wxACTION_TEXT_PASTE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( action != wxACTION_NONE )
|
||||||
|
{
|
||||||
|
control->PerformAction(action);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return wxStdTextCtrlInputHandler::HandleKey(control, event, pressed);
|
||||||
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user