1 /////////////////////////////////////////////////////////////////////////////
2 // Program: wxWindows Widgets Sample
4 // Purpose: part of the widgets sample showing wxTextCtrl
5 // Author: Vadim Zeitlin
8 // Copyright: (c) 2001 Vadim Zeitlin
9 // License: wxWindows license
10 /////////////////////////////////////////////////////////////////////////////
12 // ============================================================================
14 // ============================================================================
16 // ----------------------------------------------------------------------------
18 // ----------------------------------------------------------------------------
20 // for compilers that support precompilation, includes "wx/wx.h".
21 #include "wx/wxprec.h"
27 // for all others, include the necessary headers
32 #include "wx/button.h"
33 #include "wx/checkbox.h"
34 #include "wx/radiobox.h"
35 #include "wx/statbox.h"
36 #include "wx/stattext.h"
37 #include "wx/textctrl.h"
44 #include "icons/text.xpm"
46 // ----------------------------------------------------------------------------
48 // ----------------------------------------------------------------------------
66 // textctrl line number radiobox values
75 // textctrl kind values
85 // default values for the controls
86 static const struct ControlValues
97 TextLines_Multi
, // multiline
98 FALSE
, // not password
99 TRUE
, // do wrap lines
100 FALSE
, // not readonly
102 TextKind_Plain
// plain EDIT control
106 // ----------------------------------------------------------------------------
108 // ----------------------------------------------------------------------------
110 // Define a new frame type: this is going to be our main frame
111 class TextWidgetsPage
: public WidgetsPage
115 TextWidgetsPage(wxNotebook
*notebook
, wxImageList
*imaglist
);
116 virtual ~TextWidgetsPage();
119 // create an info text contorl
120 wxTextCtrl
*CreateInfoText();
122 // create a horz sizer holding a static text and this text control
123 wxSizer
*CreateTextWithLabelSizer(const wxString
& label
,
125 const wxString
& label2
= wxEmptyString
,
126 wxTextCtrl
*text2
= NULL
);
129 void OnButtonReset(wxCommandEvent
& event
);
130 void OnButtonClearLog(wxCommandEvent
& event
);
132 void OnButtonSet(wxCommandEvent
& event
);
133 void OnButtonAdd(wxCommandEvent
& event
);
134 void OnButtonInsert(wxCommandEvent
& event
);
135 void OnButtonClear(wxCommandEvent
& event
);
136 void OnButtonLoad(wxCommandEvent
& event
);
138 void OnButtonQuit(wxCommandEvent
& event
);
140 void OnText(wxCommandEvent
& event
);
141 void OnTextEnter(wxCommandEvent
& event
);
143 void OnCheckOrRadioBox(wxCommandEvent
& event
);
145 void OnUpdateUIClearButton(wxUpdateUIEvent
& event
);
147 void OnUpdateUIPasswordCheckbox(wxUpdateUIEvent
& event
);
148 void OnUpdateUIWrapLinesCheckbox(wxUpdateUIEvent
& event
);
150 void OnUpdateUIResetButton(wxUpdateUIEvent
& event
);
152 void OnIdle(wxIdleEvent
& event
);
154 // reset the textctrl parameters
157 // (re)create the textctrl
160 // is the control currently single line?
161 bool IsSingleLine() const
163 return m_radioTextLines
->GetSelection() == TextLines_Single
;
169 // the radiobox to choose between single and multi line
170 wxRadioBox
*m_radioTextLines
;
172 // the checkboxes controlling text ctrl styles
173 wxCheckBox
*m_chkPassword
,
177 // under MSW we test rich edit controls as well here
179 wxRadioBox
*m_radioKind
;
182 // the textctrl itself and the sizer it is in
184 wxSizer
*m_sizerText
;
186 // the information text zones
187 wxTextCtrl
*m_textPosCur
,
196 // and the data to show in them
203 // any class wishing to process wxWindows events must use this macro
204 DECLARE_EVENT_TABLE()
205 DECLARE_WIDGETS_PAGE(TextWidgetsPage
)
208 // ----------------------------------------------------------------------------
210 // ----------------------------------------------------------------------------
212 BEGIN_EVENT_TABLE(TextWidgetsPage
, WidgetsPage
)
213 EVT_IDLE(TextWidgetsPage::OnIdle
)
215 EVT_BUTTON(TextPage_Reset
, TextWidgetsPage::OnButtonReset
)
217 EVT_BUTTON(TextPage_Clear
, TextWidgetsPage::OnButtonClear
)
218 EVT_BUTTON(TextPage_Set
, TextWidgetsPage::OnButtonSet
)
219 EVT_BUTTON(TextPage_Add
, TextWidgetsPage::OnButtonAdd
)
220 EVT_BUTTON(TextPage_Insert
, TextWidgetsPage::OnButtonInsert
)
221 EVT_BUTTON(TextPage_Load
, TextWidgetsPage::OnButtonLoad
)
223 EVT_UPDATE_UI(TextPage_Clear
, TextWidgetsPage::OnUpdateUIClearButton
)
225 EVT_UPDATE_UI(TextPage_Password
, TextWidgetsPage::OnUpdateUIPasswordCheckbox
)
226 EVT_UPDATE_UI(TextPage_WrapLines
, TextWidgetsPage::OnUpdateUIWrapLinesCheckbox
)
228 EVT_UPDATE_UI(TextPage_Reset
, TextWidgetsPage::OnUpdateUIResetButton
)
230 EVT_TEXT(TextPage_Textctrl
, TextWidgetsPage::OnText
)
231 EVT_TEXT_ENTER(TextPage_Textctrl
, TextWidgetsPage::OnTextEnter
)
233 EVT_CHECKBOX(-1, TextWidgetsPage::OnCheckOrRadioBox
)
234 EVT_RADIOBOX(-1, TextWidgetsPage::OnCheckOrRadioBox
)
237 // ============================================================================
239 // ============================================================================
241 IMPLEMENT_WIDGETS_PAGE(TextWidgetsPage
, _T("Text"));
243 // ----------------------------------------------------------------------------
244 // TextWidgetsPage creation
245 // ----------------------------------------------------------------------------
247 TextWidgetsPage::TextWidgetsPage(wxNotebook
*notebook
, wxImageList
*imaglist
)
248 : WidgetsPage(notebook
)
250 imaglist
->Add(wxBitmap(text_xpm
));
256 m_radioTextLines
= (wxRadioBox
*)NULL
;
260 m_chkReadonly
= (wxCheckBox
*)NULL
;
270 m_textRange
= (wxTextCtrl
*)NULL
;
272 m_sizerText
= (wxSizer
*)NULL
;
277 m_selTo
= -2; // not -1 which means "no selection"
280 static const wxString modes
[] =
286 wxStaticBox
*box
= new wxStaticBox(this, -1, _T("&Set textctrl parameters"));
287 m_radioTextLines
= new wxRadioBox(this, -1, _T("&Number of lines:"),
288 wxDefaultPosition
, wxDefaultSize
,
289 WXSIZEOF(modes
), modes
,
290 1, wxRA_SPECIFY_COLS
);
292 wxSizer
*sizerLeft
= new wxStaticBoxSizer(box
, wxVERTICAL
);
294 sizerLeft
->Add(m_radioTextLines
, 0, wxGROW
| wxALL
, 5);
295 sizerLeft
->Add(5, 5, 0, wxGROW
| wxALL
, 5); // spacer
297 m_chkPassword
= CreateCheckBoxAndAddToSizer(
298 sizerLeft
, _T("&Password control"), TextPage_Password
300 m_chkWrapLines
= CreateCheckBoxAndAddToSizer(
301 sizerLeft
, _T("Line &wrap"), TextPage_WrapLines
303 m_chkReadonly
= CreateCheckBoxAndAddToSizer(
304 sizerLeft
, _T("&Read-only mode")
308 static const wxString kinds
[] =
315 m_radioKind
= new wxRadioBox(this, -1, _T("Control &kind"),
316 wxDefaultPosition
, wxDefaultSize
,
317 WXSIZEOF(kinds
), kinds
,
318 1, wxRA_SPECIFY_COLS
);
320 sizerLeft
->Add(5, 5, 0, wxGROW
| wxALL
, 5); // spacer
321 sizerLeft
->Add(m_radioKind
, 0, wxGROW
| wxALL
, 5);
324 wxButton
*btn
= new wxButton(this, TextPage_Reset
, _T("&Reset"));
325 sizerLeft
->Add(2, 2, 0, wxGROW
| wxALL
, 1); // spacer
326 sizerLeft
->Add(btn
, 0, wxALIGN_CENTRE_HORIZONTAL
| wxALL
, 15);
329 wxStaticBox
*box2
= new wxStaticBox(this, -1, _T("&Change contents:"));
330 wxSizer
*sizerMiddleUp
= new wxStaticBoxSizer(box2
, wxVERTICAL
);
332 btn
= new wxButton(this, TextPage_Set
, _T("&Set text value"));
333 sizerMiddleUp
->Add(btn
, 0, wxALL
| wxGROW
, 1);
335 btn
= new wxButton(this, TextPage_Add
, _T("&Append text"));
336 sizerMiddleUp
->Add(btn
, 0, wxALL
| wxGROW
, 1);
338 btn
= new wxButton(this, TextPage_Insert
, _T("&Insert text"));
339 sizerMiddleUp
->Add(btn
, 0, wxALL
| wxGROW
, 1);
341 btn
= new wxButton(this, TextPage_Load
, _T("&Load file"));
342 sizerMiddleUp
->Add(btn
, 0, wxALL
| wxGROW
, 1);
344 btn
= new wxButton(this, TextPage_Clear
, _T("&Clear"));
345 sizerMiddleUp
->Add(btn
, 0, wxALL
| wxGROW
, 1);
347 wxStaticBox
*box4
= new wxStaticBox(this, -1, _T("&Info:"));
348 wxSizer
*sizerMiddleDown
= new wxStaticBoxSizer(box4
, wxVERTICAL
);
350 m_textPosCur
= CreateInfoText();
351 m_textRowCur
= CreateInfoText();
352 m_textColCur
= CreateInfoText();
354 wxSizer
*sizerRow
= new wxBoxSizer(wxHORIZONTAL
);
355 sizerRow
->Add(CreateTextWithLabelSizer
361 sizerRow
->Add(CreateTextWithLabelSizer
366 0, wxLEFT
| wxRIGHT
, 5);
367 sizerRow
->Add(CreateTextWithLabelSizer
373 sizerMiddleDown
->Add(sizerRow
, 0, wxALL
, 5);
375 m_textLineLast
= CreateInfoText();
376 m_textPosLast
= CreateInfoText();
379 CreateTextWithLabelSizer
381 _T("Number of lines:"),
383 _T("Last position:"),
389 m_textSelFrom
= CreateInfoText();
390 m_textSelTo
= CreateInfoText();
393 CreateTextWithLabelSizer
395 _T("Selection: from"),
403 m_textRange
= new wxTextCtrl(this, -1, _T(""),
404 wxDefaultPosition
, wxDefaultSize
,
408 CreateTextWithLabelSizer
416 wxSizer
*sizerMiddle
= new wxBoxSizer(wxVERTICAL
);
417 sizerMiddle
->Add(sizerMiddleUp
, 0, wxGROW
);
418 sizerMiddle
->Add(sizerMiddleDown
, 1, wxGROW
| wxTOP
, 5);
421 wxStaticBox
*box3
= new wxStaticBox(this, -1, _T("&Text:"));
422 m_sizerText
= new wxStaticBoxSizer(box3
, wxHORIZONTAL
);
425 m_sizerText
->SetMinSize(150, 0);
427 // the 3 panes panes compose the upper part of the window
428 wxSizer
*sizerTop
= new wxBoxSizer(wxHORIZONTAL
);
429 sizerTop
->Add(sizerLeft
, 0, wxGROW
| (wxALL
& ~wxLEFT
), 10);
430 sizerTop
->Add(sizerMiddle
, 0, wxGROW
| wxALL
, 10);
431 sizerTop
->Add(m_sizerText
, 1, wxGROW
| (wxALL
& ~wxRIGHT
), 10);
439 TextWidgetsPage::~TextWidgetsPage()
443 // ----------------------------------------------------------------------------
445 // ----------------------------------------------------------------------------
447 wxTextCtrl
*TextWidgetsPage::CreateInfoText()
449 static int s_maxWidth
= 0;
453 GetTextExtent(_T("9999999"), &s_maxWidth
, NULL
);
456 wxTextCtrl
*text
= new wxTextCtrl(this, -1, _T(""),
458 wxSize(s_maxWidth
, -1),
463 wxSizer
*TextWidgetsPage::CreateTextWithLabelSizer(const wxString
& label
,
465 const wxString
& label2
,
468 wxSizer
*sizerRow
= new wxBoxSizer(wxHORIZONTAL
);
469 sizerRow
->Add(new wxStaticText(this, -1, label
), 0,
470 wxALIGN_CENTRE_VERTICAL
| wxRIGHT
, 5);
471 sizerRow
->Add(text
, 0, wxALIGN_CENTRE_VERTICAL
);
474 sizerRow
->Add(new wxStaticText(this, -1, label2
), 0,
475 wxALIGN_CENTRE_VERTICAL
| wxLEFT
| wxRIGHT
, 5);
476 sizerRow
->Add(text2
, 0, wxALIGN_CENTRE_VERTICAL
);
482 // ----------------------------------------------------------------------------
484 // ----------------------------------------------------------------------------
486 void TextWidgetsPage::Reset()
488 m_radioTextLines
->SetSelection(DEFAULTS
.textLines
);
489 m_chkPassword
->SetValue(DEFAULTS
.password
);
490 m_chkWrapLines
->SetValue(DEFAULTS
.wraplines
);
491 m_chkReadonly
->SetValue(DEFAULTS
.readonly
);
493 m_radioKind
->SetSelection(DEFAULTS
.textKind
);
497 void TextWidgetsPage::CreateText()
500 switch ( m_radioTextLines
->GetSelection() )
503 wxFAIL_MSG( _T("unexpected lines radio box selection") );
505 case TextLines_Single
:
508 case TextLines_Multi
:
509 flags
|= wxTE_MULTILINE
;
510 m_chkPassword
->SetValue(FALSE
);
514 if ( m_chkPassword
->GetValue() )
515 flags
|= wxTE_PASSWORD
;
516 if ( m_chkReadonly
->GetValue() )
517 flags
|= wxTE_READONLY
;
518 if ( !m_chkWrapLines
->GetValue() )
522 switch ( m_radioKind
->GetSelection() )
525 wxFAIL_MSG( _T("unexpected kind radio box selection") );
543 valueOld
= m_text
->GetValue();
545 m_sizerText
->Detach( m_text
);
550 valueOld
= _T("Hello, Universe!");
553 m_text
= new wxTextCtrl(this, TextPage_Textctrl
,
555 wxDefaultPosition
, wxDefaultSize
,
558 // cast to int needed to silence gcc warning about different enums
559 m_sizerText
->Add(m_text
, 1, wxALL
|
560 (flags
& wxTE_MULTILINE
? (int)wxGROW
562 m_sizerText
->Layout();
565 // ----------------------------------------------------------------------------
567 // ----------------------------------------------------------------------------
569 void TextWidgetsPage::OnIdle(wxIdleEvent
& WXUNUSED(event
))
571 // update all info texts
575 long posCur
= m_text
->GetInsertionPoint();
576 if ( posCur
!= m_posCur
)
578 m_textPosCur
->Clear();
579 m_textRowCur
->Clear();
580 m_textColCur
->Clear();
583 m_text
->PositionToXY(posCur
, &col
, &row
);
585 *m_textPosCur
<< posCur
;
586 *m_textRowCur
<< row
;
587 *m_textColCur
<< col
;
595 long posLast
= m_text
->GetLastPosition();
596 if ( posLast
!= m_posLast
)
598 m_textPosLast
->Clear();
599 *m_textPosLast
<< posLast
;
605 if ( m_textLineLast
)
607 m_textLineLast
->SetValue(
608 wxString::Format(_T("%d"), m_text
->GetNumberOfLines()) );
611 if ( m_textSelFrom
&& m_textSelTo
)
614 m_text
->GetSelection(&selFrom
, &selTo
);
615 if ( selFrom
!= m_selFrom
)
617 m_textSelFrom
->Clear();
618 *m_textSelFrom
<< selFrom
;
623 if ( selTo
!= m_selTo
)
625 m_textSelTo
->Clear();
626 *m_textSelTo
<< selTo
;
634 m_textRange
->SetValue(m_text
->GetRange(10, 20));
638 void TextWidgetsPage::OnButtonReset(wxCommandEvent
& WXUNUSED(event
))
645 void TextWidgetsPage::OnButtonSet(wxCommandEvent
& WXUNUSED(event
))
647 m_text
->SetValue(m_text
->GetWindowStyle() & wxTE_MULTILINE
648 ? _T("Here,\nthere and\neverywhere")
649 : _T("Yellow submarine"));
654 void TextWidgetsPage::OnButtonAdd(wxCommandEvent
& WXUNUSED(event
))
656 if ( m_text
->GetWindowStyle() & wxTE_MULTILINE
)
658 m_text
->AppendText(_T("We all live in a\n"));
661 m_text
->AppendText(_T("Yellow submarine"));
664 void TextWidgetsPage::OnButtonInsert(wxCommandEvent
& WXUNUSED(event
))
666 m_text
->WriteText(_T("Is there anybody going to listen to my story"));
667 if ( m_text
->GetWindowStyle() & wxTE_MULTILINE
)
669 m_text
->WriteText(_T("\nall about the girl who came to stay"));
673 void TextWidgetsPage::OnButtonClear(wxCommandEvent
& WXUNUSED(event
))
679 void TextWidgetsPage::OnButtonLoad(wxCommandEvent
& WXUNUSED(event
))
681 // search for the file in several dirs where it's likely to be
683 pathlist
.Add(_T("."));
684 pathlist
.Add(_T(".."));
685 pathlist
.Add(_T("../../../samples/widgets"));
687 wxString filename
= pathlist
.FindValidPath(_T("textctrl.cpp"));
690 wxLogError(_T("File textctrl.cpp not found."));
695 if ( !m_text
->LoadFile(filename
) )
697 // this is not supposed to happen ...
698 wxLogError(_T("Error loading file."));
702 long elapsed
= sw
.Time();
703 wxLogMessage(_T("Loaded file '%s' in %lu.%us"),
704 filename
.c_str(), elapsed
/ 1000,
705 (unsigned int) elapsed
% 1000);
710 void TextWidgetsPage::OnUpdateUIClearButton(wxUpdateUIEvent
& event
)
712 event
.Enable(!m_text
->GetValue().empty());
715 void TextWidgetsPage::OnUpdateUIWrapLinesCheckbox(wxUpdateUIEvent
& event
)
717 event
.Enable( !IsSingleLine() );
720 void TextWidgetsPage::OnUpdateUIPasswordCheckbox(wxUpdateUIEvent
& event
)
722 // can't put multiline control in password mode
723 event
.Enable( IsSingleLine() );
726 void TextWidgetsPage::OnUpdateUIResetButton(wxUpdateUIEvent
& event
)
728 event
.Enable( (m_radioTextLines
->GetSelection() != DEFAULTS
.textLines
) ||
730 (m_radioKind
->GetSelection() != DEFAULTS
.textKind
) ||
732 (m_chkReadonly
->GetValue() != DEFAULTS
.readonly
) ||
733 (m_chkPassword
->GetValue() != DEFAULTS
.password
) ||
734 (m_chkWrapLines
->GetValue() != DEFAULTS
.wraplines
) );
737 void TextWidgetsPage::OnText(wxCommandEvent
& event
)
739 // small hack to suppress the very first message: by then the logging is
740 // not yet redirected and so initial setting of the text value results in
741 // an annoying message box
742 static bool s_firstTime
= TRUE
;
749 wxLogMessage(_T("Text ctrl value changed"));
752 void TextWidgetsPage::OnTextEnter(wxCommandEvent
& event
)
754 wxLogMessage(_T("Text entered: '%s'"), event
.GetString().c_str());
757 void TextWidgetsPage::OnCheckOrRadioBox(wxCommandEvent
& event
)