]> git.saurik.com Git - wxWidgets.git/blob - src/generic/extdlgg.cpp
1. more wxMotif fixes
[wxWidgets.git] / src / generic / extdlgg.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: extdlgg.cpp
3 // Purpose: extended generic dialog
4 // Author: Robert Roebling
5 // Modified by:
6 // Created: 04/01/98
7 // RCS-ID: $Id$
8 // Copyright: (c) Robert Roebling
9 // Licence: wxWindows license
10 /////////////////////////////////////////////////////////////////////////////
11
12 #ifdef __GNUG__
13 #pragma implementation "extdlgg.h"
14 #endif
15
16 // For compilers that support precompilation, includes "wx.h".
17 #include "wx/wxprec.h"
18
19 #ifdef __BORLANDC__
20 #pragma hdrstop
21 #endif
22
23 #ifndef WX_PRECOMP
24 #include <stdio.h>
25 #include "wx/intl.h"
26 #include "wx/dialog.h"
27 #include "wx/button.h"
28 #endif
29
30 #if wxUSE_STATLINE
31 #include "wx/statline.h"
32 #endif
33
34 #include "wx/generic/extdlgg.h"
35
36 //-----------------------------------------------------------------------------
37 // wxExtDialog
38 //-----------------------------------------------------------------------------
39
40 #define BUTTON_AREA_MARGIN 10
41
42 #if !USE_SHARED_LIBRARY
43 IMPLEMENT_DYNAMIC_CLASS(wxExtDialog, wxDialog)
44
45 BEGIN_EVENT_TABLE(wxExtDialog, wxDialog)
46 EVT_SIZE(wxExtDialog::OnSize)
47 EVT_BUTTON(wxID_YES, wxExtDialog::OnYes)
48 EVT_BUTTON(wxID_NO, wxExtDialog::OnNo)
49 EVT_BUTTON(wxID_CANCEL, wxExtDialog::OnCancel)
50 END_EVENT_TABLE()
51 #endif
52
53 wxExtDialog::wxExtDialog( wxWindow *parent, wxWindowID id,
54 const wxString& title, long extraStyle,
55 const wxPoint& pos, const wxSize& size,
56 long style, const wxString &name )
57 {
58 Create( parent, id, title, extraStyle, pos, size, style, name );
59 }
60
61 bool wxExtDialog::Create( wxWindow *parent, wxWindowID id,
62 const wxString& title, long extraStyle,
63 const wxPoint& pos, const wxSize& size,
64 long style, const wxString &name )
65 {
66 if (!wxDialog::Create( parent, id, title, pos, size, style, name ))
67 return FALSE;
68
69 m_extraStyle = extraStyle;
70
71 m_clientWindowMargin = 10;
72
73 if (m_windowStyle & wxED_BUTTONS_RIGHT)
74 {
75 m_spacePerButton.x = wxButton::GetDefaultSize().x + 18;
76 m_spacePerButton.y = wxButton::GetDefaultSize().y + 8;
77 }
78 else
79 {
80 m_spacePerButton.x = wxButton::GetDefaultSize().x + 8;
81 m_spacePerButton.y = wxButton::GetDefaultSize().y + 18;
82 }
83
84 #if defined(__WXGTK__) || defined(__WXMOTIF__)
85 // Under Motif and GTK, the default button has a big frame around
86 // it and to avoid overlapping buttons we make the margin bigger.
87 // We could give other platforms a bigger margin as well, but this
88 // wouldn't be standard L&F.
89 m_spacePerButton.x += 10;
90 m_spacePerButton.y += 10;
91 #endif
92
93 wxButton *ok = (wxButton *) NULL;
94 wxButton *cancel = (wxButton *) NULL;
95 wxButton *yes = (wxButton *) NULL;
96 wxButton *no = (wxButton *) NULL;
97
98
99 if (m_extraStyle & wxYES_NO)
100 {
101 yes = new wxButton( this, wxID_YES, _("Yes") );
102 m_buttons.Append( yes );
103 no = new wxButton( this, wxID_NO, _("No") );
104 m_buttons.Append( no );
105 }
106
107 if (m_extraStyle & wxYES)
108 {
109 yes = new wxButton( this, wxID_YES, _("Yes") );
110 m_buttons.Append( yes );
111 }
112
113 if (m_extraStyle & wxNO)
114 {
115 no = new wxButton( this, wxID_NO, _("No") );
116 m_buttons.Append( no );
117 }
118
119 if (m_extraStyle & wxOK)
120 {
121 ok = new wxButton( this, wxID_OK, _("OK") );
122 m_buttons.Append( ok );
123 }
124
125 if (m_extraStyle & wxFORWARD)
126 AddButton( new wxButton( this, wxID_FORWARD, _("Forward") ) );
127
128 if (m_extraStyle & wxBACKWARD)
129 AddButton( new wxButton( this, wxID_BACKWARD, _("Backward") ) );
130
131 if (m_extraStyle & wxSETUP)
132 AddButton( new wxButton( this, wxID_SETUP, _("Setup") ) );
133
134 if (m_extraStyle & wxMORE)
135 AddButton( new wxButton( this, wxID_MORE, _("More...") ) );
136
137 if (m_extraStyle & wxHELP)
138 AddButton( new wxButton( this, wxID_HELP, _("Help") ) );
139
140 if (m_extraStyle & wxCANCEL)
141 {
142 cancel = new wxButton( this, wxID_CANCEL, _("Cancel") );
143 m_buttons.Append( cancel );
144 }
145
146 if ((m_extraStyle & wxNO_DEFAULT) == 0)
147 {
148 if (ok)
149 {
150 ok->SetDefault();
151 ok->SetFocus();
152 }
153 else if (yes)
154 {
155 yes->SetDefault();
156 yes->SetFocus();
157 }
158 }
159
160 #if wxUSE_STATLINE
161 if (style & wxED_STATIC_LINE)
162 {
163 int line_style = wxLI_HORIZONTAL;
164 if (style & wxED_BUTTONS_RIGHT) line_style = wxLI_VERTICAL;
165
166 m_statLine = new wxStaticLine( this, -1, wxDefaultPosition, wxDefaultSize, line_style );
167 }
168 else
169 m_statLine = (wxStaticLine*) NULL;
170 #endif
171
172 if (m_extraStyle & wxCENTRE)
173 Centre( wxBOTH );
174
175 return TRUE;
176 }
177
178 void wxExtDialog::AddButton( wxButton *button )
179 {
180 m_buttons.Append( button );
181 }
182
183 void wxExtDialog::SetDefaultButton( wxWindowID button )
184 {
185 wxNode *node = m_buttons.First();
186 while (node)
187 {
188 wxButton *but = (wxButton*) node->Data();
189 if (but->GetId() == button)
190 {
191 but->SetDefault();
192 but->SetFocus();
193 return;
194 }
195 }
196 }
197
198 void wxExtDialog::EnableButton( wxWindowID button, bool enable )
199 {
200 wxNode *node = m_buttons.First();
201 while (node)
202 {
203 wxButton *but = (wxButton*) node->Data();
204 if (but->GetId() == button)
205 {
206 but->Enable(enable);
207 return;
208 }
209 }
210 }
211
212 bool wxExtDialog::ButtonIsEnabled( wxWindowID button )
213 {
214 wxNode *node = m_buttons.First();
215 while (node)
216 {
217 wxButton *but = (wxButton*) node->Data();
218 if (but->GetId() == button)
219 return but->IsEnabled();
220 }
221 return FALSE;
222 }
223
224 void wxExtDialog::OnSize( wxSizeEvent &WXUNUSED(event) )
225 {
226 wxSize client_size( GetClientSize() );
227 wxSize button_area( LayoutButtons() );
228
229 if (HasFlag(wxED_BUTTONS_RIGHT))
230 client_size.x -= button_area.x;
231 else
232 client_size.y -= button_area.y;
233
234 if (m_clientWindow)
235 {
236 if (m_windowStyle & wxED_CLIENT_MARGIN)
237 m_clientWindow->SetSize( m_clientWindowMargin,
238 m_clientWindowMargin,
239 client_size.x - 2*m_clientWindowMargin,
240 client_size.y - 2*m_clientWindowMargin );
241 else
242 m_clientWindow->SetSize( 0, 0, client_size.x, client_size.y );
243
244 if (m_clientWindow->GetAutoLayout())
245 m_clientWindow->Layout();
246 }
247 }
248
249 void wxExtDialog::OnYes(wxCommandEvent& event)
250 {
251 EndModal( wxID_YES );
252 }
253
254 void wxExtDialog::OnNo(wxCommandEvent& event)
255 {
256 EndModal( wxID_NO );
257 }
258
259 void wxExtDialog::OnCancel(wxCommandEvent& event)
260 {
261 /* allow cancellation via ESC/Close button except if
262 only YES and NO are specified. */
263 if ((m_extraStyle & wxYES_NO) != wxYES_NO || (m_extraStyle & wxCANCEL))
264 {
265 EndModal( wxID_CANCEL );
266 }
267 }
268
269 wxSize wxExtDialog::GetButtonAreaSize()
270 {
271 if (m_buttons.GetCount() == 0) return wxSize(0,0);
272
273 wxSize ret(0,0);
274
275 if (m_windowStyle & wxED_BUTTONS_RIGHT)
276 {
277 ret.x = m_spacePerButton.x;
278 ret.y = m_buttons.GetCount()*m_spacePerButton.y + 2*BUTTON_AREA_MARGIN;
279 #if wxUSE_STATLINE
280 if (m_statLine)
281 ret.x += wxStaticLine::GetDefaultSize();
282 #endif
283 }
284 else
285 {
286 ret.x = m_buttons.GetCount()*m_spacePerButton.x + 2*BUTTON_AREA_MARGIN;
287 ret.y = m_spacePerButton.y;
288 #if wxUSE_STATLINE
289 if (m_statLine)
290 ret.y += wxStaticLine::GetDefaultSize();
291 #endif
292 }
293
294 return ret;
295 }
296
297 wxSize wxExtDialog::LayoutButtons()
298 {
299 if (m_buttons.GetCount() == 0) return wxSize(0,0);
300
301 wxSize area_used( GetButtonAreaSize() );
302 wxSize client_area( GetClientSize() );
303
304 if (m_windowStyle & wxED_BUTTONS_RIGHT)
305 {
306 area_used.y = client_area.y;
307 wxSize area_used_by_buttons( area_used );
308 #if wxUSE_STATLINE
309 if (m_statLine)
310 area_used_by_buttons.x -= wxStaticLine::GetDefaultSize();
311 #endif
312
313 int space_for_each_button = (client_area.y-2*BUTTON_AREA_MARGIN) / m_buttons.GetCount();
314 int n = 0;
315 wxNode *node = m_buttons.First();
316 while (node)
317 {
318 wxButton *button = (wxButton*)node->Data();
319
320 wxSize button_size( button->GetSize() );
321 if (button_size.x < wxButton::GetDefaultSize().x) button_size.x = wxButton::GetDefaultSize().x;
322
323 int center_of_button_y = n*space_for_each_button + space_for_each_button/2;
324 int button_y = BUTTON_AREA_MARGIN + center_of_button_y - button_size.y/2;
325
326 int center_of_button_x = client_area.x - area_used_by_buttons.x/2;
327 int button_x = center_of_button_x - button_size.x/2;
328
329 button->SetSize( button_x, button_y, button_size.x, button_size.y );
330
331 node = node->Next();
332 n++;
333 }
334
335 #if wxUSE_STATLINE
336 if (m_statLine)
337 m_statLine->SetSize( client_area.x - area_used_by_buttons.x - wxStaticLine::GetDefaultSize(),
338 0,
339 wxStaticLine::GetDefaultSize(),
340 client_area.y );
341 #endif
342 }
343 else
344 {
345 area_used.x = client_area.x;
346 wxSize area_used_by_buttons( area_used );
347 #if wxUSE_STATLINE
348 if (m_statLine)
349 area_used_by_buttons.y -= wxStaticLine::GetDefaultSize();
350 #endif
351
352 int space_for_each_button = (client_area.x-2*BUTTON_AREA_MARGIN) / m_buttons.GetCount();
353 int n = 0;
354 wxNode *node = m_buttons.First();
355 while (node)
356 {
357 wxButton *button = (wxButton*)node->Data();
358
359 wxSize button_size( button->GetSize() );
360 if (button_size.x < wxButton::GetDefaultSize().x) button_size.x = wxButton::GetDefaultSize().x;
361
362 int center_of_button_x = n*space_for_each_button + space_for_each_button/2;
363 int button_x = BUTTON_AREA_MARGIN + center_of_button_x - button_size.x/2;
364
365 int center_of_button_y = client_area.y - area_used_by_buttons.y/2;
366 int button_y = center_of_button_y - button_size.y/2;
367
368 button->SetSize( button_x, button_y, button_size.x, button_size.y );
369
370 node = node->Next();
371 n++;
372 }
373
374 #if wxUSE_STATLINE
375 if (m_statLine)
376 m_statLine->SetSize( 0,
377 client_area.y - area_used_by_buttons.y - wxStaticLine::GetDefaultSize(),
378 client_area.x,
379 wxStaticLine::GetDefaultSize() );
380 #endif
381 }
382
383 return area_used;
384 }
385
386