This is not necessary any longer after wxUSE_IOSTREAMH removal and it makes the sample code more clear.
		
			
				
	
	
		
			1071 lines
		
	
	
		
			30 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			1071 lines
		
	
	
		
			30 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| /////////////////////////////////////////////////////////////////////////////
 | |
| // Program:     wxWidgets Widgets Sample
 | |
| // Name:        textctrl.cpp
 | |
| // Purpose:     part of the widgets sample showing wxTextCtrl
 | |
| // Author:      Vadim Zeitlin
 | |
| // Created:     27.03.01
 | |
| // Copyright:   (c) 2001 Vadim Zeitlin
 | |
| // Licence:     wxWindows licence
 | |
| /////////////////////////////////////////////////////////////////////////////
 | |
| 
 | |
| // ============================================================================
 | |
| // declarations
 | |
| // ============================================================================
 | |
| 
 | |
| // ----------------------------------------------------------------------------
 | |
| // headers
 | |
| // ----------------------------------------------------------------------------
 | |
| 
 | |
| // for compilers that support precompilation, includes "wx/wx.h".
 | |
| #include "wx/wxprec.h"
 | |
| 
 | |
| #ifdef __BORLANDC__
 | |
|     #pragma hdrstop
 | |
| #endif
 | |
| 
 | |
| // for all others, include the necessary headers
 | |
| #ifndef WX_PRECOMP
 | |
|     #include "wx/log.h"
 | |
|     #include "wx/timer.h"
 | |
| 
 | |
|     #include "wx/bitmap.h"
 | |
|     #include "wx/button.h"
 | |
|     #include "wx/checkbox.h"
 | |
|     #include "wx/dcclient.h"
 | |
|     #include "wx/radiobox.h"
 | |
|     #include "wx/statbox.h"
 | |
|     #include "wx/stattext.h"
 | |
|     #include "wx/textctrl.h"
 | |
|     #include "wx/msgdlg.h"
 | |
| #endif
 | |
| 
 | |
| #include "wx/sizer.h"
 | |
| 
 | |
| #include "widgets.h"
 | |
| 
 | |
| #include "icons/text.xpm"
 | |
| 
 | |
| // ----------------------------------------------------------------------------
 | |
| // constants
 | |
| // ----------------------------------------------------------------------------
 | |
| 
 | |
| // control ids
 | |
| enum
 | |
| {
 | |
|     TextPage_Reset = wxID_HIGHEST,
 | |
| 
 | |
|     TextPage_Set,
 | |
|     TextPage_Add,
 | |
|     TextPage_Insert,
 | |
|     TextPage_Clear,
 | |
|     TextPage_Load,
 | |
| 
 | |
|     TextPage_StreamRedirector,
 | |
| 
 | |
|     TextPage_Password,
 | |
|     TextPage_NoVertScrollbar,
 | |
|     TextPage_WrapLines,
 | |
|     TextPage_Textctrl
 | |
| };
 | |
| 
 | |
| // textctrl line number radiobox values
 | |
| enum TextLines
 | |
| {
 | |
|     TextLines_Single,
 | |
|     TextLines_Multi,
 | |
|     TextLines_Max
 | |
| };
 | |
| 
 | |
| // wrap style radio box
 | |
| enum WrapStyle
 | |
| {
 | |
|     WrapStyle_None,
 | |
|     WrapStyle_Word,
 | |
|     WrapStyle_Char,
 | |
|     WrapStyle_Best,
 | |
|     WrapStyle_Max
 | |
| };
 | |
| 
 | |
| // Alignment style radio box
 | |
| enum AlignmentStyle
 | |
| {
 | |
|     Align_Left,
 | |
|     Align_Center,
 | |
|     Align_Right,
 | |
| };
 | |
| 
 | |
| #ifdef __WXMSW__
 | |
| 
 | |
| // textctrl kind values
 | |
| enum TextKind
 | |
| {
 | |
|     TextKind_Plain,
 | |
|     TextKind_Rich,
 | |
|     TextKind_Rich2,
 | |
|     TextKind_Max
 | |
| };
 | |
| 
 | |
| #endif // __WXMSW__
 | |
| 
 | |
| // default values for the controls
 | |
| static const struct ControlValues
 | |
| {
 | |
|     TextLines textLines;
 | |
| 
 | |
|     bool password;
 | |
|     bool readonly;
 | |
|     bool processEnter;
 | |
|     bool processTab;
 | |
|     bool filename;
 | |
|     bool noVertScrollbar;
 | |
| 
 | |
|     WrapStyle wrapStyle;
 | |
|     AlignmentStyle alignmentStyle;
 | |
| 
 | |
| #ifdef __WXMSW__
 | |
|     TextKind textKind;
 | |
| #endif // __WXMSW__
 | |
| } DEFAULTS =
 | |
| {
 | |
|     TextLines_Multi,    // multiline
 | |
|     false,              // not password
 | |
|     false,              // not readonly
 | |
|     true,               // do process enter
 | |
|     false,              // do not process Tab
 | |
|     false,              // not filename
 | |
|     false,              // don't hide vertical scrollbar
 | |
|     WrapStyle_Word,     // wrap on word boundaries
 | |
|     Align_Left,         // leading-alignment
 | |
| #ifdef __WXMSW__
 | |
|     TextKind_Plain      // plain EDIT control
 | |
| #endif // __WXMSW__
 | |
| };
 | |
| 
 | |
| // ----------------------------------------------------------------------------
 | |
| // TextWidgetsPage
 | |
| // ----------------------------------------------------------------------------
 | |
| 
 | |
| // Define a new frame type: this is going to be our main frame
 | |
| class TextWidgetsPage : public WidgetsPage
 | |
| {
 | |
| public:
 | |
|     // ctor(s) and dtor
 | |
|     TextWidgetsPage(WidgetsBookCtrl *book, wxImageList *imaglist);
 | |
| 
 | |
|     virtual wxWindow *GetWidget() const wxOVERRIDE { return m_text; }
 | |
|     virtual wxTextEntryBase *GetTextEntry() const wxOVERRIDE { return m_text; }
 | |
|     virtual void RecreateWidget() wxOVERRIDE { CreateText(); }
 | |
| 
 | |
|     // lazy creation of the content
 | |
|     virtual void CreateContent() wxOVERRIDE;
 | |
| 
 | |
| protected:
 | |
|     // create an info text contorl
 | |
|     wxTextCtrl *CreateInfoText();
 | |
| 
 | |
|     // create a horz sizer holding a static text and this text control
 | |
|     wxSizer *CreateTextWithLabelSizer(const wxString& label,
 | |
|                                       wxTextCtrl *text,
 | |
|                                       const wxString& label2 = wxEmptyString,
 | |
|                                       wxTextCtrl *text2 = NULL);
 | |
| 
 | |
|     // event handlers
 | |
|     void OnButtonReset(wxCommandEvent& event);
 | |
|     void OnButtonClearLog(wxCommandEvent& event);
 | |
| 
 | |
|     void OnButtonSet(wxCommandEvent& event);
 | |
|     void OnButtonAdd(wxCommandEvent& event);
 | |
|     void OnButtonInsert(wxCommandEvent& event);
 | |
|     void OnButtonClear(wxCommandEvent& event);
 | |
|     void OnButtonLoad(wxCommandEvent& event);
 | |
| 
 | |
|     void OnStreamRedirector(wxCommandEvent& event);
 | |
|     void OnButtonQuit(wxCommandEvent& event);
 | |
| 
 | |
|     void OnText(wxCommandEvent& event);
 | |
|     void OnTextEnter(wxCommandEvent& event);
 | |
|     void OnTextPasted(wxClipboardTextEvent& event);
 | |
| 
 | |
|     void OnCheckOrRadioBox(wxCommandEvent& event);
 | |
| 
 | |
|     void OnUpdateUIClearButton(wxUpdateUIEvent& event);
 | |
| 
 | |
|     void OnUpdateUIPasswordCheckbox(wxUpdateUIEvent& event);
 | |
|     void OnUpdateUINoVertScrollbarCheckbox(wxUpdateUIEvent& event);
 | |
|     void OnUpdateUIWrapLinesRadiobox(wxUpdateUIEvent& event);
 | |
| 
 | |
|     void OnUpdateUIResetButton(wxUpdateUIEvent& event);
 | |
| 
 | |
|     void OnIdle(wxIdleEvent& event);
 | |
| 
 | |
|     // reset the textctrl parameters
 | |
|     void Reset();
 | |
| 
 | |
|     // (re)create the textctrl
 | |
|     void CreateText();
 | |
| 
 | |
|     // is the control currently single line?
 | |
|     bool IsSingleLine() const
 | |
|     {
 | |
|         return m_radioTextLines->GetSelection() == TextLines_Single;
 | |
|     }
 | |
| 
 | |
|     // the controls
 | |
|     // ------------
 | |
| 
 | |
|     // the radiobox to choose between single and multi line
 | |
|     wxRadioBox *m_radioTextLines;
 | |
| 
 | |
|     // and another one to choose the wrapping style
 | |
|     wxRadioBox *m_radioWrap;
 | |
| 
 | |
|     // and yet another one to choose the alignment style
 | |
|     wxRadioBox *m_radioAlign;
 | |
| 
 | |
|     // the checkboxes controlling text ctrl styles
 | |
|     wxCheckBox *m_chkPassword,
 | |
|                *m_chkReadonly,
 | |
|                *m_chkProcessEnter,
 | |
|                *m_chkProcessTab,
 | |
|                *m_chkFilename,
 | |
|                *m_chkNoVertScrollbar;
 | |
| 
 | |
|     // under MSW we test rich edit controls as well here
 | |
| #ifdef __WXMSW__
 | |
|     wxRadioBox *m_radioKind;
 | |
| #endif // __WXMSW__
 | |
| 
 | |
|     // the textctrl itself and the sizer it is in
 | |
|     wxTextCtrl *m_text;
 | |
|     wxSizer *m_sizerText;
 | |
| 
 | |
|     // the information text zones
 | |
|     wxTextCtrl *m_textPosCur,
 | |
|                *m_textRowCur,
 | |
|                *m_textColCur,
 | |
|                *m_textPosLast,
 | |
|                *m_textLineLast,
 | |
|                *m_textSelFrom,
 | |
|                *m_textSelTo,
 | |
|                *m_textRange;
 | |
| 
 | |
|     // and the data to show in them
 | |
|     long m_posCur,
 | |
|          m_posLast,
 | |
|          m_selFrom,
 | |
|          m_selTo;
 | |
| 
 | |
|     wxString m_range10_20;
 | |
| 
 | |
| private:
 | |
|     // any class wishing to process wxWidgets events must use this macro
 | |
|     wxDECLARE_EVENT_TABLE();
 | |
|     DECLARE_WIDGETS_PAGE(TextWidgetsPage)
 | |
| };
 | |
| 
 | |
| // ----------------------------------------------------------------------------
 | |
| // WidgetsTextCtrl
 | |
| // ----------------------------------------------------------------------------
 | |
| 
 | |
| class WidgetsTextCtrl : public wxTextCtrl
 | |
| {
 | |
| public:
 | |
|     WidgetsTextCtrl(wxWindow *parent,
 | |
|                     wxWindowID id,
 | |
|                     const wxString& value,
 | |
|                     int flags)
 | |
|         : wxTextCtrl(parent, id, value, wxDefaultPosition, wxDefaultSize, flags)
 | |
|     {
 | |
|         Bind(wxEVT_LEFT_DOWN, &WidgetsTextCtrl::OnLeftClick, this);
 | |
|     }
 | |
| 
 | |
| private:
 | |
|     // Show the result of HitTest() at the mouse position if Alt is pressed.
 | |
|     void OnLeftClick(wxMouseEvent& event)
 | |
|     {
 | |
|         event.Skip();
 | |
|         if ( !event.AltDown() )
 | |
|             return;
 | |
| 
 | |
|         wxString where;
 | |
|         wxTextCoord x, y;
 | |
|         switch ( HitTest(event.GetPosition(), &x, &y) )
 | |
|         {
 | |
|             default:
 | |
|                 wxFAIL_MSG( "unexpected HitTest() result" );
 | |
|                 wxFALLTHROUGH;
 | |
| 
 | |
|             case wxTE_HT_UNKNOWN:
 | |
|                 x = y = -1;
 | |
|                 where = "nowhere near";
 | |
|                 break;
 | |
| 
 | |
|             case wxTE_HT_BEFORE:
 | |
|                 where = "before";
 | |
|                 break;
 | |
| 
 | |
|             case wxTE_HT_BELOW:
 | |
|                 where = "below";
 | |
|                 break;
 | |
| 
 | |
|             case wxTE_HT_BEYOND:
 | |
|                 where = "beyond";
 | |
|                 break;
 | |
| 
 | |
|             case wxTE_HT_ON_TEXT:
 | |
|                 where = "at";
 | |
|                 break;
 | |
|         }
 | |
| 
 | |
|         wxLogMessage("Mouse is %s (%ld, %ld)", where, x, y);
 | |
|     }
 | |
| };
 | |
| 
 | |
| // ----------------------------------------------------------------------------
 | |
| // event tables
 | |
| // ----------------------------------------------------------------------------
 | |
| 
 | |
| wxBEGIN_EVENT_TABLE(TextWidgetsPage, WidgetsPage)
 | |
|     EVT_IDLE(TextWidgetsPage::OnIdle)
 | |
| 
 | |
|     EVT_BUTTON(TextPage_Reset, TextWidgetsPage::OnButtonReset)
 | |
| 
 | |
|     EVT_BUTTON(TextPage_StreamRedirector, TextWidgetsPage::OnStreamRedirector)
 | |
| 
 | |
|     EVT_BUTTON(TextPage_Clear, TextWidgetsPage::OnButtonClear)
 | |
|     EVT_BUTTON(TextPage_Set, TextWidgetsPage::OnButtonSet)
 | |
|     EVT_BUTTON(TextPage_Add, TextWidgetsPage::OnButtonAdd)
 | |
|     EVT_BUTTON(TextPage_Insert, TextWidgetsPage::OnButtonInsert)
 | |
|     EVT_BUTTON(TextPage_Load, TextWidgetsPage::OnButtonLoad)
 | |
| 
 | |
|     EVT_UPDATE_UI(TextPage_Clear, TextWidgetsPage::OnUpdateUIClearButton)
 | |
| 
 | |
|     EVT_UPDATE_UI(TextPage_Password, TextWidgetsPage::OnUpdateUIPasswordCheckbox)
 | |
|     EVT_UPDATE_UI(TextPage_NoVertScrollbar, TextWidgetsPage::OnUpdateUINoVertScrollbarCheckbox)
 | |
|     EVT_UPDATE_UI(TextPage_WrapLines, TextWidgetsPage::OnUpdateUIWrapLinesRadiobox)
 | |
| 
 | |
|     EVT_UPDATE_UI(TextPage_Reset, TextWidgetsPage::OnUpdateUIResetButton)
 | |
| 
 | |
|     EVT_TEXT(TextPage_Textctrl, TextWidgetsPage::OnText)
 | |
|     EVT_TEXT_ENTER(TextPage_Textctrl, TextWidgetsPage::OnTextEnter)
 | |
|     EVT_TEXT_PASTE(TextPage_Textctrl, TextWidgetsPage::OnTextPasted)
 | |
| 
 | |
|     EVT_CHECKBOX(wxID_ANY, TextWidgetsPage::OnCheckOrRadioBox)
 | |
|     EVT_RADIOBOX(wxID_ANY, TextWidgetsPage::OnCheckOrRadioBox)
 | |
| wxEND_EVENT_TABLE()
 | |
| 
 | |
| // ============================================================================
 | |
| // implementation
 | |
| // ============================================================================
 | |
| 
 | |
| #if defined(__WXX11__)
 | |
|     #define FAMILY_CTRLS NATIVE_CTRLS
 | |
| #elif defined(__WXUNIVERSAL__)
 | |
|     #define FAMILY_CTRLS UNIVERSAL_CTRLS
 | |
| #else
 | |
|     #define FAMILY_CTRLS NATIVE_CTRLS
 | |
| #endif
 | |
| 
 | |
| IMPLEMENT_WIDGETS_PAGE(TextWidgetsPage, "Text",
 | |
|                        FAMILY_CTRLS | EDITABLE_CTRLS
 | |
|                        );
 | |
| 
 | |
| // ----------------------------------------------------------------------------
 | |
| // TextWidgetsPage creation
 | |
| // ----------------------------------------------------------------------------
 | |
| 
 | |
| TextWidgetsPage::TextWidgetsPage(WidgetsBookCtrl *book, wxImageList *imaglist)
 | |
|                : WidgetsPage(book, imaglist, text_xpm)
 | |
| {
 | |
|     // init everything
 | |
| #ifdef __WXMSW__
 | |
|     m_radioKind =
 | |
| #endif // __WXMSW__
 | |
|     m_radioWrap =
 | |
|     m_radioAlign =
 | |
|     m_radioTextLines = (wxRadioBox *)NULL;
 | |
| 
 | |
|     m_chkPassword =
 | |
|     m_chkReadonly =
 | |
|     m_chkProcessEnter =
 | |
|     m_chkProcessTab =
 | |
|     m_chkFilename =
 | |
|     m_chkNoVertScrollbar = (wxCheckBox *)NULL;
 | |
| 
 | |
|     m_text =
 | |
|     m_textPosCur =
 | |
|     m_textRowCur =
 | |
|     m_textColCur =
 | |
|     m_textPosLast =
 | |
|     m_textLineLast =
 | |
|     m_textSelFrom =
 | |
|     m_textSelTo =
 | |
|     m_textRange = (wxTextCtrl *)NULL;
 | |
| 
 | |
|     m_sizerText = (wxSizer *)NULL;
 | |
| 
 | |
|     m_posCur =
 | |
|     m_posLast =
 | |
|     m_selFrom =
 | |
|     m_selTo = -2; // not -1 which means "no selection"
 | |
| }
 | |
| 
 | |
| void TextWidgetsPage::CreateContent()
 | |
| {
 | |
|     // left pane
 | |
|     static const wxString modes[] =
 | |
|     {
 | |
|         "single line",
 | |
|         "multi line",
 | |
|     };
 | |
| 
 | |
|     wxStaticBox *box = new wxStaticBox(this, wxID_ANY, "&Set textctrl parameters");
 | |
|     m_radioTextLines = new wxRadioBox(this, wxID_ANY, "&Number of lines:",
 | |
|                                       wxDefaultPosition, wxDefaultSize,
 | |
|                                       WXSIZEOF(modes), modes,
 | |
|                                       1, wxRA_SPECIFY_COLS);
 | |
| 
 | |
|     wxSizer *sizerLeft = new wxStaticBoxSizer(box, wxVERTICAL);
 | |
| 
 | |
|     sizerLeft->Add(m_radioTextLines, 0, wxGROW | wxALL, 5);
 | |
|     sizerLeft->AddSpacer(5);
 | |
| 
 | |
|     m_chkPassword = CreateCheckBoxAndAddToSizer(
 | |
|                         sizerLeft, "&Password control", TextPage_Password
 | |
|                     );
 | |
|     m_chkReadonly = CreateCheckBoxAndAddToSizer(
 | |
|                         sizerLeft, "&Read-only mode"
 | |
|                     );
 | |
|     m_chkProcessEnter = CreateCheckBoxAndAddToSizer(
 | |
|                         sizerLeft, "Process &Enter"
 | |
|                     );
 | |
|     m_chkProcessTab = CreateCheckBoxAndAddToSizer(
 | |
|                         sizerLeft, "Process &Tab"
 | |
|                     );
 | |
|     m_chkFilename = CreateCheckBoxAndAddToSizer(
 | |
|                         sizerLeft, "&Filename control"
 | |
|                     );
 | |
|     m_chkNoVertScrollbar = CreateCheckBoxAndAddToSizer(
 | |
|                         sizerLeft, "No &vertical scrollbar",
 | |
|                         TextPage_NoVertScrollbar
 | |
|                     );
 | |
|     m_chkFilename->Disable(); // not implemented yet
 | |
|     sizerLeft->AddSpacer(5);
 | |
| 
 | |
|     static const wxString wrap[] =
 | |
|     {
 | |
|         "no wrap",
 | |
|         "word wrap",
 | |
|         "char wrap",
 | |
|         "best wrap",
 | |
|     };
 | |
| 
 | |
|     m_radioWrap = new wxRadioBox(this, TextPage_WrapLines, "&Wrap style:",
 | |
|                                  wxDefaultPosition, wxDefaultSize,
 | |
|                                  WXSIZEOF(wrap), wrap,
 | |
|                                  1, wxRA_SPECIFY_COLS);
 | |
|     sizerLeft->Add(m_radioWrap, 0, wxGROW | wxALL, 5);
 | |
| 
 | |
|     static const wxString halign[] =
 | |
|     {
 | |
|         "left",
 | |
|         "centre",
 | |
|         "right",
 | |
|     };
 | |
| 
 | |
|     m_radioAlign = new wxRadioBox(this, wxID_ANY, "&Text alignment",
 | |
|                                     wxDefaultPosition, wxDefaultSize,
 | |
|                                     WXSIZEOF(halign), halign, 1);
 | |
|     sizerLeft->Add(m_radioAlign, 0, wxGROW | wxALL, 5);
 | |
| 
 | |
| #ifdef __WXMSW__
 | |
|     static const wxString kinds[] =
 | |
|     {
 | |
|         "plain edit",
 | |
|         "rich edit",
 | |
|         "rich edit 2.0",
 | |
|     };
 | |
| 
 | |
|     m_radioKind = new wxRadioBox(this, wxID_ANY, "Control &kind",
 | |
|                                  wxDefaultPosition, wxDefaultSize,
 | |
|                                  WXSIZEOF(kinds), kinds,
 | |
|                                  1, wxRA_SPECIFY_COLS);
 | |
| 
 | |
|     sizerLeft->AddSpacer(5);
 | |
|     sizerLeft->Add(m_radioKind, 0, wxGROW | wxALL, 5);
 | |
| #endif // __WXMSW__
 | |
| 
 | |
|     wxButton *btn = new wxButton(this, TextPage_Reset, "&Reset");
 | |
|     sizerLeft->Add(2, 2, 0, wxGROW | wxALL, 1); // spacer
 | |
|     sizerLeft->Add(btn, 0, wxALIGN_CENTRE_HORIZONTAL | wxALL, 15);
 | |
| 
 | |
|     // middle pane
 | |
|     wxStaticBox *box2 = new wxStaticBox(this, wxID_ANY, "&Change contents:");
 | |
|     wxSizer *sizerMiddleUp = new wxStaticBoxSizer(box2, wxVERTICAL);
 | |
| 
 | |
|     btn = new wxButton(this, TextPage_Set, "&Set text value");
 | |
|     sizerMiddleUp->Add(btn, 0, wxALL | wxGROW, 1);
 | |
| 
 | |
|     btn = new wxButton(this, TextPage_Add, "&Append text");
 | |
|     sizerMiddleUp->Add(btn, 0, wxALL | wxGROW, 1);
 | |
| 
 | |
|     btn = new wxButton(this, TextPage_Insert, "&Insert text");
 | |
|     sizerMiddleUp->Add(btn, 0, wxALL | wxGROW, 1);
 | |
| 
 | |
|     btn = new wxButton(this, TextPage_Load, "&Load file");
 | |
|     sizerMiddleUp->Add(btn, 0, wxALL | wxGROW, 1);
 | |
| 
 | |
|     btn = new wxButton(this, TextPage_Clear, "&Clear");
 | |
|     sizerMiddleUp->Add(btn, 0, wxALL | wxGROW, 1);
 | |
| 
 | |
|     btn = new wxButton(this, TextPage_StreamRedirector, "St&ream redirection");
 | |
|     sizerMiddleUp->Add(btn, 0, wxALL | wxGROW, 1);
 | |
| 
 | |
|     wxStaticBox *box4 = new wxStaticBox(this, wxID_ANY, "&Info:");
 | |
|     wxSizer *sizerMiddleDown = new wxStaticBoxSizer(box4, wxVERTICAL);
 | |
| 
 | |
|     m_textPosCur = CreateInfoText();
 | |
|     m_textRowCur = CreateInfoText();
 | |
|     m_textColCur = CreateInfoText();
 | |
| 
 | |
|     wxSizer *sizerRow = new wxBoxSizer(wxHORIZONTAL);
 | |
|     sizerRow->Add(CreateTextWithLabelSizer
 | |
|                   (
 | |
|                     "Current pos:",
 | |
|                     m_textPosCur
 | |
|                   ),
 | |
|                   0, wxRIGHT, 5);
 | |
|     sizerRow->Add(CreateTextWithLabelSizer
 | |
|                   (
 | |
|                     "Col:",
 | |
|                     m_textColCur
 | |
|                   ),
 | |
|                   0, wxLEFT | wxRIGHT, 5);
 | |
|     sizerRow->Add(CreateTextWithLabelSizer
 | |
|                   (
 | |
|                     "Row:",
 | |
|                     m_textRowCur
 | |
|                   ),
 | |
|                   0, wxLEFT, 5);
 | |
|     sizerMiddleDown->Add(sizerRow, 0, wxALL, 5);
 | |
| 
 | |
|     m_textLineLast = CreateInfoText();
 | |
|     m_textPosLast = CreateInfoText();
 | |
|     sizerMiddleDown->Add
 | |
|                      (
 | |
|                         CreateTextWithLabelSizer
 | |
|                         (
 | |
|                           "Number of lines:",
 | |
|                           m_textLineLast,
 | |
|                           "Last position:",
 | |
|                           m_textPosLast
 | |
|                         ),
 | |
|                         0, wxALL, 5
 | |
|                      );
 | |
| 
 | |
|     m_textSelFrom = CreateInfoText();
 | |
|     m_textSelTo = CreateInfoText();
 | |
|     sizerMiddleDown->Add
 | |
|                      (
 | |
|                         CreateTextWithLabelSizer
 | |
|                         (
 | |
|                           "Selection: from",
 | |
|                           m_textSelFrom,
 | |
|                           "to",
 | |
|                           m_textSelTo
 | |
|                         ),
 | |
|                         0, wxALL, 5
 | |
|                      );
 | |
| 
 | |
|     m_textRange = new wxTextCtrl(this, wxID_ANY, wxEmptyString,
 | |
|                                  wxDefaultPosition, wxDefaultSize,
 | |
|                                  wxTE_READONLY);
 | |
|     sizerMiddleDown->Add
 | |
|                      (
 | |
|                         CreateTextWithLabelSizer
 | |
|                         (
 | |
|                           "Range 10..20:",
 | |
|                           m_textRange
 | |
|                         ),
 | |
|                         0, wxALL, 5
 | |
|                      );
 | |
| 
 | |
|     sizerMiddleDown->Add
 | |
|                      (
 | |
|                           new wxStaticText
 | |
|                           (
 | |
|                             this,
 | |
|                             wxID_ANY,
 | |
|                             "Alt-click in the text to see HitTest() result"
 | |
|                           ),
 | |
|                           wxSizerFlags().Border()
 | |
|                      );
 | |
| 
 | |
|     wxSizer *sizerMiddle = new wxBoxSizer(wxVERTICAL);
 | |
|     sizerMiddle->Add(sizerMiddleUp, 0, wxGROW);
 | |
|     sizerMiddle->Add(sizerMiddleDown, 1, wxGROW | wxTOP, 5);
 | |
| 
 | |
|     // right pane
 | |
|     wxStaticBox *box3 = new wxStaticBox(this, wxID_ANY, "&Text:");
 | |
|     m_sizerText = new wxStaticBoxSizer(box3, wxHORIZONTAL);
 | |
|     Reset();
 | |
|     CreateText();
 | |
|     m_sizerText->SetMinSize(150, 0);
 | |
| 
 | |
|     // the 3 panes panes compose the upper part of the window
 | |
|     wxSizer *sizerTop = new wxBoxSizer(wxHORIZONTAL);
 | |
|     sizerTop->Add(sizerLeft, 0, wxGROW | (wxALL & ~wxLEFT), 10);
 | |
|     sizerTop->Add(sizerMiddle, 0, wxGROW | wxALL, 10);
 | |
|     sizerTop->Add(m_sizerText, 1, wxGROW | (wxALL & ~wxRIGHT), 10);
 | |
| 
 | |
|     SetSizer(sizerTop);
 | |
| }
 | |
| 
 | |
| // ----------------------------------------------------------------------------
 | |
| // creation helpers
 | |
| // ----------------------------------------------------------------------------
 | |
| 
 | |
| wxTextCtrl *TextWidgetsPage::CreateInfoText()
 | |
| {
 | |
|     static int s_maxWidth = 0;
 | |
|     if ( !s_maxWidth )
 | |
|     {
 | |
|         // calc it once only
 | |
|         GetTextExtent("9999999", &s_maxWidth, NULL);
 | |
|     }
 | |
| 
 | |
|     wxTextCtrl *text = new wxTextCtrl(this, wxID_ANY, wxEmptyString,
 | |
|                                       wxDefaultPosition,
 | |
|                                       wxSize(s_maxWidth, wxDefaultCoord),
 | |
|                                       wxTE_READONLY);
 | |
|     return text;
 | |
| }
 | |
| 
 | |
| wxSizer *TextWidgetsPage::CreateTextWithLabelSizer(const wxString& label,
 | |
|                                                  wxTextCtrl *text,
 | |
|                                                  const wxString& label2,
 | |
|                                                  wxTextCtrl *text2)
 | |
| {
 | |
|     wxSizer *sizerRow = new wxBoxSizer(wxHORIZONTAL);
 | |
|     sizerRow->Add(new wxStaticText(this, wxID_ANY, label), 0,
 | |
|                   wxALIGN_CENTRE_VERTICAL | wxRIGHT, 5);
 | |
|     sizerRow->Add(text, 0, wxALIGN_CENTRE_VERTICAL);
 | |
|     if ( text2 )
 | |
|     {
 | |
|         sizerRow->Add(new wxStaticText(this, wxID_ANY, label2), 0,
 | |
|                       wxALIGN_CENTRE_VERTICAL | wxLEFT | wxRIGHT, 5);
 | |
|         sizerRow->Add(text2, 0, wxALIGN_CENTRE_VERTICAL);
 | |
|     }
 | |
| 
 | |
|     return sizerRow;
 | |
| }
 | |
| 
 | |
| // ----------------------------------------------------------------------------
 | |
| // operations
 | |
| // ----------------------------------------------------------------------------
 | |
| 
 | |
| void TextWidgetsPage::Reset()
 | |
| {
 | |
|     m_radioTextLines->SetSelection(DEFAULTS.textLines);
 | |
| 
 | |
|     m_chkPassword->SetValue(DEFAULTS.password);
 | |
|     m_chkReadonly->SetValue(DEFAULTS.readonly);
 | |
|     m_chkProcessEnter->SetValue(DEFAULTS.processEnter);
 | |
|     m_chkProcessTab->SetValue(DEFAULTS.processTab);
 | |
|     m_chkFilename->SetValue(DEFAULTS.filename);
 | |
|     m_chkNoVertScrollbar->SetValue(DEFAULTS.noVertScrollbar);
 | |
| 
 | |
|     m_radioWrap->SetSelection(DEFAULTS.wrapStyle);
 | |
|     m_radioAlign->SetSelection(DEFAULTS.alignmentStyle);
 | |
| 
 | |
| #ifdef __WXMSW__
 | |
|     m_radioKind->SetSelection(DEFAULTS.textKind);
 | |
| #endif // __WXMSW__
 | |
| }
 | |
| 
 | |
| void TextWidgetsPage::CreateText()
 | |
| {
 | |
|     int flags = GetAttrs().m_defaultFlags;
 | |
|     switch ( m_radioTextLines->GetSelection() )
 | |
|     {
 | |
|         default:
 | |
|             wxFAIL_MSG( "unexpected lines radio box selection" );
 | |
|             wxFALLTHROUGH;
 | |
| 
 | |
|         case TextLines_Single:
 | |
|             break;
 | |
| 
 | |
|         case TextLines_Multi:
 | |
|             flags |= wxTE_MULTILINE;
 | |
|             m_chkPassword->SetValue(false);
 | |
|             break;
 | |
|     }
 | |
| 
 | |
|     if ( m_chkPassword->GetValue() )
 | |
|         flags |= wxTE_PASSWORD;
 | |
|     if ( m_chkReadonly->GetValue() )
 | |
|         flags |= wxTE_READONLY;
 | |
|     if ( m_chkProcessEnter->GetValue() )
 | |
|         flags |= wxTE_PROCESS_ENTER;
 | |
|     if ( m_chkProcessTab->GetValue() )
 | |
|         flags |= wxTE_PROCESS_TAB;
 | |
|     if ( m_chkNoVertScrollbar->GetValue() )
 | |
|         flags |= wxTE_NO_VSCROLL;
 | |
| 
 | |
|     switch ( m_radioWrap->GetSelection() )
 | |
|     {
 | |
|         default:
 | |
|             wxFAIL_MSG( "unexpected wrap style radio box selection" );
 | |
|             wxFALLTHROUGH;
 | |
| 
 | |
|         case WrapStyle_None:
 | |
|             flags |= wxTE_DONTWRAP; // same as wxHSCROLL
 | |
|             break;
 | |
| 
 | |
|         case WrapStyle_Word:
 | |
|             flags |= wxTE_WORDWRAP;
 | |
|             break;
 | |
| 
 | |
|         case WrapStyle_Char:
 | |
|             flags |= wxTE_CHARWRAP;
 | |
|             break;
 | |
| 
 | |
|         case WrapStyle_Best:
 | |
|             // this is default but use symbolic file name for consistency
 | |
|             flags |= wxTE_BESTWRAP;
 | |
|             break;
 | |
|     }
 | |
| 
 | |
|     switch ( m_radioAlign->GetSelection() )
 | |
|     {
 | |
|         case Align_Left:
 | |
|             flags |= wxTE_LEFT;
 | |
|             break;
 | |
|         case Align_Center:
 | |
|             flags |= wxTE_CENTER;
 | |
|             break;
 | |
|         case Align_Right:
 | |
|             flags |= wxTE_RIGHT;
 | |
|             break;
 | |
|         default:
 | |
|             wxFAIL_MSG( "unexpected alignment style radio box selection" );
 | |
|     }
 | |
| 
 | |
| #ifdef __WXMSW__
 | |
|     switch ( m_radioKind->GetSelection() )
 | |
|     {
 | |
|         default:
 | |
|             wxFAIL_MSG( "unexpected kind radio box selection" );
 | |
|             wxFALLTHROUGH;
 | |
| 
 | |
|         case TextKind_Plain:
 | |
|             break;
 | |
| 
 | |
|         case TextKind_Rich:
 | |
|             flags |= wxTE_RICH;
 | |
|             break;
 | |
| 
 | |
|         case TextKind_Rich2:
 | |
|             flags |= wxTE_RICH2;
 | |
|             break;
 | |
|     }
 | |
| #endif // __WXMSW__
 | |
| 
 | |
|     wxString valueOld;
 | |
|     if ( m_text )
 | |
|     {
 | |
|         valueOld = m_text->GetValue();
 | |
| 
 | |
|         m_sizerText->Detach( m_text );
 | |
|         delete m_text;
 | |
|     }
 | |
|     else
 | |
|     {
 | |
|         valueOld = "Hello, Universe!";
 | |
|     }
 | |
| 
 | |
|     m_text = new WidgetsTextCtrl(this, TextPage_Textctrl, valueOld, flags);
 | |
| 
 | |
| #if 0
 | |
|     if ( m_chkFilename->GetValue() )
 | |
|         ;
 | |
| #endif // TODO
 | |
| 
 | |
|     // cast to int needed to silence gcc warning about different enums
 | |
|     m_sizerText->Add(m_text, 1, wxALL |
 | |
|                      (flags & wxTE_MULTILINE ? (int)wxGROW
 | |
|                                              : wxALIGN_TOP), 5);
 | |
|     m_sizerText->Layout();
 | |
| }
 | |
| 
 | |
| // ----------------------------------------------------------------------------
 | |
| // event handlers
 | |
| // ----------------------------------------------------------------------------
 | |
| 
 | |
| void TextWidgetsPage::OnIdle(wxIdleEvent& WXUNUSED(event))
 | |
| {
 | |
|     // update all info texts
 | |
| 
 | |
|     if ( m_textPosCur )
 | |
|     {
 | |
|         long posCur = m_text->GetInsertionPoint();
 | |
|         if ( posCur != m_posCur )
 | |
|         {
 | |
|             m_textPosCur->Clear();
 | |
|             m_textRowCur->Clear();
 | |
|             m_textColCur->Clear();
 | |
| 
 | |
|             long col, row;
 | |
|             m_text->PositionToXY(posCur, &col, &row);
 | |
| 
 | |
|             *m_textPosCur << posCur;
 | |
|             *m_textRowCur << row;
 | |
|             *m_textColCur << col;
 | |
| 
 | |
|             m_posCur = posCur;
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     if ( m_textPosLast )
 | |
|     {
 | |
|         long posLast = m_text->GetLastPosition();
 | |
|         if ( posLast != m_posLast )
 | |
|         {
 | |
|             m_textPosLast->Clear();
 | |
|             *m_textPosLast << posLast;
 | |
| 
 | |
|             m_posLast = posLast;
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     if ( m_textLineLast )
 | |
|     {
 | |
|         m_textLineLast->SetValue(
 | |
|                 wxString::Format("%d", m_text->GetNumberOfLines()) );
 | |
|     }
 | |
| 
 | |
|     if ( m_textSelFrom && m_textSelTo )
 | |
|     {
 | |
|         long selFrom, selTo;
 | |
|         m_text->GetSelection(&selFrom, &selTo);
 | |
|         if ( selFrom != m_selFrom )
 | |
|         {
 | |
|             m_textSelFrom->Clear();
 | |
|             *m_textSelFrom << selFrom;
 | |
| 
 | |
|             m_selFrom = selFrom;
 | |
|         }
 | |
| 
 | |
|         if ( selTo != m_selTo )
 | |
|         {
 | |
|             m_textSelTo->Clear();
 | |
|             *m_textSelTo << selTo;
 | |
| 
 | |
|             m_selTo = selTo;
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     if ( m_textRange )
 | |
|     {
 | |
|         wxString range = m_text->GetRange(10, 20);
 | |
|         if ( range != m_range10_20 )
 | |
|         {
 | |
|             m_range10_20 = range;
 | |
|             m_textRange->SetValue(range);
 | |
|         }
 | |
|     }
 | |
| }
 | |
| 
 | |
| void TextWidgetsPage::OnButtonReset(wxCommandEvent& WXUNUSED(event))
 | |
| {
 | |
|     Reset();
 | |
| 
 | |
|     CreateText();
 | |
| }
 | |
| 
 | |
| void TextWidgetsPage::OnButtonSet(wxCommandEvent& WXUNUSED(event))
 | |
| {
 | |
|     m_text->SetValue(m_text->GetWindowStyle() & wxTE_MULTILINE
 | |
|                         ? "Here,\nthere and\neverywhere"
 | |
|                         : "Yellow submarine");
 | |
| 
 | |
|     m_text->SetFocus();
 | |
| }
 | |
| 
 | |
| void TextWidgetsPage::OnButtonAdd(wxCommandEvent& WXUNUSED(event))
 | |
| {
 | |
|     if ( m_text->GetWindowStyle() & wxTE_MULTILINE )
 | |
|     {
 | |
|         m_text->AppendText("We all live in a\n");
 | |
|     }
 | |
| 
 | |
|     m_text->AppendText("Yellow submarine");
 | |
| }
 | |
| 
 | |
| void TextWidgetsPage::OnButtonInsert(wxCommandEvent& WXUNUSED(event))
 | |
| {
 | |
|     m_text->WriteText("Is there anybody going to listen to my story");
 | |
|     if ( m_text->GetWindowStyle() & wxTE_MULTILINE )
 | |
|     {
 | |
|         m_text->WriteText("\nall about the girl who came to stay");
 | |
|     }
 | |
| }
 | |
| 
 | |
| void TextWidgetsPage::OnButtonClear(wxCommandEvent& WXUNUSED(event))
 | |
| {
 | |
|     m_text->Clear();
 | |
|     m_text->SetFocus();
 | |
| }
 | |
| 
 | |
| void TextWidgetsPage::OnButtonLoad(wxCommandEvent& WXUNUSED(event))
 | |
| {
 | |
|     // search for the file in several dirs where it's likely to be
 | |
|     wxPathList pathlist;
 | |
|     pathlist.Add(".");
 | |
|     pathlist.Add("..");
 | |
|     pathlist.Add("../widgets");
 | |
|     pathlist.Add("../../../samples/widgets");
 | |
| 
 | |
|     wxString filename = pathlist.FindValidPath("textctrl.cpp");
 | |
|     if ( !filename )
 | |
|     {
 | |
|         wxLogError("File textctrl.cpp not found.");
 | |
|     }
 | |
|     else // load it
 | |
|     {
 | |
|         wxStopWatch sw;
 | |
|         if ( !m_text->LoadFile(filename) )
 | |
|         {
 | |
|             // this is not supposed to happen ...
 | |
|             wxLogError("Error loading file.");
 | |
|         }
 | |
|         else
 | |
|         {
 | |
|             long elapsed = sw.Time();
 | |
|             wxLogMessage("Loaded file '%s' in %lu.%us",
 | |
|                          filename, elapsed / 1000,
 | |
|                          (unsigned int) elapsed % 1000);
 | |
|         }
 | |
|     }
 | |
| }
 | |
| 
 | |
| void TextWidgetsPage::OnUpdateUIClearButton(wxUpdateUIEvent& event)
 | |
| {
 | |
|     event.Enable(!m_text->GetValue().empty());
 | |
| }
 | |
| 
 | |
| void TextWidgetsPage::OnUpdateUIWrapLinesRadiobox(wxUpdateUIEvent& event)
 | |
| {
 | |
|     event.Enable( !IsSingleLine() );
 | |
| }
 | |
| 
 | |
| void TextWidgetsPage::OnUpdateUIPasswordCheckbox(wxUpdateUIEvent& event)
 | |
| {
 | |
|     // can't put multiline control in password mode
 | |
|     event.Enable( IsSingleLine() );
 | |
| }
 | |
| 
 | |
| void TextWidgetsPage::OnUpdateUINoVertScrollbarCheckbox(wxUpdateUIEvent& event)
 | |
| {
 | |
|     // Vertical scrollbar creation can be blocked only in multiline control
 | |
|     event.Enable( !IsSingleLine());
 | |
| }
 | |
| 
 | |
| void TextWidgetsPage::OnUpdateUIResetButton(wxUpdateUIEvent& event)
 | |
| {
 | |
|     event.Enable( (m_radioTextLines->GetSelection() != DEFAULTS.textLines) ||
 | |
| #ifdef __WXMSW__
 | |
|                   (m_radioKind->GetSelection() != DEFAULTS.textKind) ||
 | |
| #endif // __WXMSW__
 | |
|                   (m_chkPassword->GetValue() != DEFAULTS.password) ||
 | |
|                   (m_chkReadonly->GetValue() != DEFAULTS.readonly) ||
 | |
|                   (m_chkProcessEnter->GetValue() != DEFAULTS.processEnter) ||
 | |
|                   (m_chkProcessTab->GetValue() != DEFAULTS.processTab) ||
 | |
|                   (m_chkFilename->GetValue() != DEFAULTS.filename) ||
 | |
|                   (m_chkNoVertScrollbar->GetValue() != DEFAULTS.noVertScrollbar) ||
 | |
|                   (m_radioWrap->GetSelection() != DEFAULTS.wrapStyle) );
 | |
| }
 | |
| 
 | |
| void TextWidgetsPage::OnText(wxCommandEvent& event)
 | |
| {
 | |
|     if ( !IsUsingLogWindow() )
 | |
|         return;
 | |
| 
 | |
|     // Replace middle of long text with ellipsis just to avoid filling up the
 | |
|     // log control with too much unnecessary stuff.
 | |
|     wxLogMessage("Text control value changed (now '%s')",
 | |
|                  wxControl::Ellipsize
 | |
|                  (
 | |
|                     event.GetString(),
 | |
|                     wxClientDC(this),
 | |
|                     wxELLIPSIZE_MIDDLE,
 | |
|                     GetTextExtent('W').x*100
 | |
|                  ));
 | |
| }
 | |
| 
 | |
| void TextWidgetsPage::OnTextEnter(wxCommandEvent& event)
 | |
| {
 | |
|     wxLogMessage("Text entered: '%s'", event.GetString());
 | |
|     event.Skip();
 | |
| }
 | |
| 
 | |
| void TextWidgetsPage::OnTextPasted(wxClipboardTextEvent& event)
 | |
| {
 | |
|     wxLogMessage("Text pasted from clipboard.");
 | |
|     event.Skip();
 | |
| }
 | |
| 
 | |
| void TextWidgetsPage::OnCheckOrRadioBox(wxCommandEvent& event)
 | |
| {
 | |
| #if defined(__WXMSW__) || defined(__WXGTK__) || defined(__WXOSX__)
 | |
|     // We should be able to change text alignment
 | |
|     // dynamically, without recreating the control.
 | |
|     if( event.GetEventObject() == m_radioAlign )
 | |
|     {
 | |
|         long flags = m_text->GetWindowStyle();
 | |
|         flags &= ~(wxTE_LEFT|wxTE_CENTER|wxTE_RIGHT);
 | |
| 
 | |
|         switch ( event.GetSelection() )
 | |
|         {
 | |
|             case Align_Left:
 | |
|                 flags |= wxTE_LEFT;
 | |
|                 break;
 | |
|             case Align_Center:
 | |
|                 flags |= wxTE_CENTER;
 | |
|                 break;
 | |
|             case Align_Right:
 | |
|                 flags |= wxTE_RIGHT;
 | |
|                 break;
 | |
|             default:
 | |
|                 wxFAIL_MSG( "unexpected alignment style radio box selection" );
 | |
|                 return;
 | |
|         }
 | |
| 
 | |
|         m_text->SetWindowStyle(flags);
 | |
|         m_text->Refresh();
 | |
| 
 | |
|         flags = m_text->GetWindowStyle();
 | |
|         wxLogMessage(wxString::Format("Text alignment: %s",
 | |
|                (flags & wxTE_RIGHT) ? "Right" :
 | |
|                (flags & wxTE_CENTER) ? "Center" : "Left"));
 | |
|     }
 | |
|     else
 | |
| #else
 | |
|     wxUnusedVar(event);
 | |
| #endif // WXMSW || WXGTK || WXOSX
 | |
|     {
 | |
|         CreateText();
 | |
|     }
 | |
| }
 | |
| 
 | |
| void TextWidgetsPage::OnStreamRedirector(wxCommandEvent& WXUNUSED(event))
 | |
| {
 | |
| #if wxHAS_TEXT_WINDOW_STREAM
 | |
|     wxStreamToTextRedirector redirect(m_text);
 | |
|     wxString str( "Outputed to cout, appears in wxTextCtrl!" );
 | |
|     wxSTD cout << str << wxSTD endl;
 | |
| #else
 | |
|     wxMessageBox("This wxWidgets build does not support wxStreamToTextRedirector");
 | |
| #endif
 | |
| }
 |