]> git.saurik.com Git - wxWidgets.git/blame - src/common/dlgcmn.cpp
Improved size handling.
[wxWidgets.git] / src / common / dlgcmn.cpp
CommitLineData
e37feda2
VZ
1/////////////////////////////////////////////////////////////////////////////
2// Name: common/dlgcmn.cpp
3// Purpose: common (to all ports) wxDialog functions
4// Author: Vadim Zeitlin
5// Modified by:
6// Created: 28.06.99
7// RCS-ID: $Id$
8// Copyright: (c) Vadim Zeitlin
65571936 9// Licence: wxWindows licence
e37feda2
VZ
10/////////////////////////////////////////////////////////////////////////////
11
12// ============================================================================
13// declarations
14// ============================================================================
15
16// ----------------------------------------------------------------------------
17// headers
18// ----------------------------------------------------------------------------
19
e37feda2
VZ
20// For compilers that support precompilation, includes "wx.h".
21#include "wx/wxprec.h"
22
23#ifdef __BORLANDC__
24 #pragma hdrstop
25#endif
26
27#ifndef WX_PRECOMP
f6bcfd97 28 #include "wx/button.h"
e37feda2
VZ
29 #include "wx/dialog.h"
30 #include "wx/dcclient.h"
9f3a38fc 31 #include "wx/intl.h"
e37feda2 32 #include "wx/settings.h"
9f3a38fc 33 #include "wx/stattext.h"
92afa2b1 34 #include "wx/sizer.h"
f6bcfd97 35 #include "wx/button.h"
7d9f12f3 36 #include "wx/containr.h"
e37feda2
VZ
37#endif
38
5d1b4919
VZ
39#if wxUSE_STATTEXT
40
41// ----------------------------------------------------------------------------
42// wxTextWrapper
43// ----------------------------------------------------------------------------
44
45// this class is used to wrap the text on word boundary: wrapping is done by
46// calling OnStartLine() and OnOutputLine() functions
47class wxTextWrapper
48{
49public:
50 wxTextWrapper() { m_eol = false; }
51
52 // win is used for getting the font, text is the text to wrap, width is the
53 // max line width or -1 to disable wrapping
54 void Wrap(wxWindow *win, const wxString& text, int widthMax);
55
0db7dfb0
VZ
56 // we don't need it, but just to avoid compiler warnings
57 virtual ~wxTextWrapper() { }
58
5d1b4919
VZ
59protected:
60 // line may be empty
61 virtual void OnOutputLine(const wxString& line) = 0;
62
63 // called at the start of every new line (except the very first one)
64 virtual void OnNewLine() { }
65
66private:
67 // call OnOutputLine() and set m_eol to true
68 void DoOutputLine(const wxString& line)
69 {
70 OnOutputLine(line);
71
72 m_eol = true;
73 }
74
75 // this function is a destructive inspector: when it returns true it also
76 // resets the flag to false so calling it again woulnd't return true any
77 // more
78 bool IsStartOfNewLine()
79 {
80 if ( !m_eol )
81 return false;
82
83 m_eol = false;
84
85 return true;
86 }
87
88
89 bool m_eol;
90};
91
92#endif // wxUSE_STATTEXT
93
94// ----------------------------------------------------------------------------
92afa2b1 95// wxDialogBase
5d1b4919 96// ----------------------------------------------------------------------------
e37feda2 97
5d1b4919 98// FIXME - temporary hack in absence of wxTopLevelWindow, should be always used
7d9f12f3
VS
99#ifdef wxTopLevelWindowNative
100BEGIN_EVENT_TABLE(wxDialogBase, wxTopLevelWindow)
101 WX_EVENT_TABLE_CONTROL_CONTAINER(wxDialogBase)
102END_EVENT_TABLE()
103
104WX_DELEGATE_TO_CONTROL_CONTAINER(wxDialogBase)
105#endif
106
107void wxDialogBase::Init()
108{
109 m_returnCode = 0;
9ceeecb9 110 m_affirmativeId = wxID_OK;
c6ece595
VZ
111 m_escapeId = wxID_ANY;
112
e4b713a2
VZ
113 // the dialogs have this flag on by default to prevent the events from the
114 // dialog controls from reaching the parent frame which is usually
115 // undesirable and can lead to unexpected and hard to find bugs
116 SetExtraStyle(GetExtraStyle() | wxWS_EX_BLOCK_EVENTS);
117
7d9f12f3
VS
118#ifdef wxTopLevelWindowNative // FIXME - temporary hack, should be always used!
119 m_container.SetContainerWindow(this);
120#endif
121}
122
5d1b4919 123#if wxUSE_STATTEXT
1e6feb95 124
5d1b4919 125void wxTextWrapper::Wrap(wxWindow *win, const wxString& text, int widthMax)
e37feda2 126{
5d1b4919
VZ
127 const wxChar *lastSpace = NULL;
128 wxString line;
129
130 const wxChar *lineStart = text.c_str();
131 for ( const wxChar *p = lineStart; ; p++ )
132 {
133 if ( IsStartOfNewLine() )
134 {
135 OnNewLine();
136
137 lastSpace = NULL;
138 line.clear();
139 lineStart = p;
140 }
141
142 if ( *p == _T('\n') || *p == _T('\0') )
143 {
144 DoOutputLine(line);
145
146 if ( *p == _T('\0') )
147 break;
148 }
149 else // not EOL
150 {
151 if ( *p == _T(' ') )
152 lastSpace = p;
153
154 line += *p;
68379eaf 155
5d1b4919
VZ
156 if ( widthMax >= 0 && lastSpace )
157 {
158 int width;
159 win->GetTextExtent(line, &width, NULL);
68379eaf 160
5d1b4919
VZ
161 if ( width > widthMax )
162 {
163 // remove the last word from this line
164 line.erase(lastSpace - lineStart, p + 1 - lineStart);
165 DoOutputLine(line);
166
167 // go back to the last word of this line which we didn't
168 // output yet
169 p = lastSpace;
170 }
171 }
172 //else: no wrapping at all or impossible to wrap
173 }
174 }
175}
176
cfd1ac21
MW
177class wxTextSizerWrapper : public wxTextWrapper
178{
179public:
180 wxTextSizerWrapper(wxWindow *win)
181 {
182 m_win = win;
183 m_hLine = 0;
184 }
185
186 wxSizer *CreateSizer(const wxString& text, int widthMax)
187 {
188 m_sizer = new wxBoxSizer(wxVERTICAL);
189 Wrap(m_win, text, widthMax);
190 return m_sizer;
191 }
192
193protected:
194 virtual void OnOutputLine(const wxString& line)
195 {
196 if ( !line.empty() )
197 {
198 m_sizer->Add(new wxStaticText(m_win, wxID_ANY, line));
199 }
200 else // empty line, no need to create a control for it
201 {
202 if ( !m_hLine )
203 m_hLine = m_win->GetCharHeight();
204
205 m_sizer->Add(5, m_hLine);
206 }
207 }
208
209private:
210 wxWindow *m_win;
211 wxSizer *m_sizer;
212 int m_hLine;
213};
214
5d1b4919
VZ
215wxSizer *wxDialogBase::CreateTextSizer(const wxString& message)
216{
2b5f62a0
VZ
217 // I admit that this is complete bogus, but it makes
218 // message boxes work for pda screens temporarily..
5d1b4919
VZ
219 int widthMax = -1;
220 const bool is_pda = wxSystemSettings::GetScreenType() <= wxSYS_SCREEN_PDA;
2b5f62a0
VZ
221 if (is_pda)
222 {
5d1b4919 223 widthMax = wxSystemSettings::GetMetric( wxSYS_SCREEN_X ) - 25;
2b5f62a0 224 }
68379eaf 225
5d1b4919
VZ
226 // '&' is used as accel mnemonic prefix in the wxWidgets controls but in
227 // the static messages created by CreateTextSizer() (used by wxMessageBox,
228 // for example), we don't want this special meaning, so we need to quote it
229 wxString text(message);
230 text.Replace(_T("&"), _T("&&"));
68379eaf 231
cfd1ac21 232 wxTextSizerWrapper wrapper(this);
b730516c 233
cfd1ac21
MW
234 return wrapper.CreateSizer(text, widthMax);
235}
5d1b4919 236
cfd1ac21
MW
237class wxLabelWrapper : public wxTextWrapper
238{
239public:
240 void WrapLabel(wxWindow *text, int widthMax)
241 {
242 m_text.clear();
243 Wrap(text, text->GetLabel(), widthMax);
244 text->SetLabel(m_text);
245 }
a350a488 246
cfd1ac21
MW
247protected:
248 virtual void OnOutputLine(const wxString& line)
249 {
250 m_text += line;
251 }
a350a488 252
cfd1ac21
MW
253 virtual void OnNewLine()
254 {
255 m_text += _T('\n');
256 }
68379eaf 257
cfd1ac21
MW
258private:
259 wxString m_text;
260};
68379eaf 261
dec48aa5 262void
a351409e 263#if defined(__WXGTK__) && !defined(__WXUNIVERSAL__)
dec48aa5
VZ
264wxStaticText
265#else
266wxStaticTextBase
267#endif
268::Wrap(int width)
5d1b4919 269{
cfd1ac21 270 wxLabelWrapper wrapper;
5d1b4919 271 wrapper.WrapLabel(this, width);
e37feda2 272}
b730516c 273
5d1b4919 274#endif // wxUSE_STATTEXT
1e6feb95
VZ
275
276#if wxUSE_BUTTON
277
92afa2b1 278wxSizer *wxDialogBase::CreateButtonSizer( long flags )
e37feda2 279{
102c0454
JS
280#ifdef __SMARTPHONE__
281 wxDialog* dialog = (wxDialog*) this;
282 if (flags & wxOK){
283 dialog->SetLeftMenu(wxID_OK);
284 }
285
286 if (flags & wxCANCEL){
287 dialog->SetRightMenu(wxID_CANCEL);
288 }
289
290 if (flags & wxYES){
291 dialog->SetLeftMenu(wxID_YES);
292 }
293
294 if (flags & wxNO){
295 dialog->SetLeftMenu(wxID_NO);
296 }
297 wxBoxSizer* sizer = new wxBoxSizer(wxHORIZONTAL);
298 return sizer;
299#else
acf2ac37 300 return CreateStdDialogButtonSizer( flags );
102c0454 301#endif
acf2ac37 302}
68379eaf 303
acf2ac37
RR
304wxStdDialogButtonSizer *wxDialogBase::CreateStdDialogButtonSizer( long flags )
305{
306 wxStdDialogButtonSizer *sizer = new wxStdDialogButtonSizer();
307 wxButton *ok = NULL;
acf2ac37
RR
308 wxButton *yes = NULL;
309 wxButton *no = NULL;
52069700 310
acf2ac37 311 if (flags & wxOK){
331c1816 312 ok = new wxButton(this, wxID_OK);
52069700 313 sizer->AddButton(ok);
2b5f62a0 314 }
52069700 315
acf2ac37 316 if (flags & wxCANCEL){
331c1816 317 wxButton *cancel = new wxButton(this, wxID_CANCEL);
52069700 318 sizer->AddButton(cancel);
b5b49e42 319 }
52069700 320
acf2ac37 321 if (flags & wxYES){
331c1816 322 yes = new wxButton(this, wxID_YES);
52069700 323 sizer->AddButton(yes);
e37feda2 324 }
52069700 325
acf2ac37 326 if (flags & wxNO){
331c1816 327 no = new wxButton(this, wxID_NO);
52069700 328 sizer->AddButton(no);
e37feda2 329 }
52069700 330
acf2ac37 331 if (flags & wxHELP){
331c1816 332 wxButton *help = new wxButton(this, wxID_HELP);
52069700 333 sizer->AddButton(help);
e37feda2 334 }
52069700 335
b730516c
RD
336 if (flags & wxNO_DEFAULT)
337 {
338 if (no)
339 {
340 no->SetDefault();
341 no->SetFocus();
342 }
343 }
344 else
92afa2b1
RR
345 {
346 if (ok)
347 {
348 ok->SetDefault();
349 ok->SetFocus();
350 }
351 else if (yes)
352 {
353 yes->SetDefault();
354 yes->SetFocus();
355 }
356 }
d30814cd 357
9ceeecb9
JS
358 if (flags & wxOK)
359 SetAffirmativeId(wxID_OK);
360 else if (flags & wxYES)
361 SetAffirmativeId(wxID_YES);
b730516c 362
d30814cd
MB
363 sizer->Realize();
364
acf2ac37 365 return sizer;
e37feda2
VZ
366}
367
acf2ac37 368
1e6feb95 369#endif // wxUSE_BUTTON