set m_isBeingDeleted to true (only) in SendDestroyEvent(); call it as early as possib...
[wxWidgets.git] / src / palmos / control.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/palmos/control.cpp
3 // Purpose: wxControl class
4 // Author: William Osborne - minimal working wxPalmOS port
5 // Modified by: Wlodzimierz ABX Skiba - native implementation
6 // Created: 10/13/04
7 // RCS-ID: $Id$
8 // Copyright: (c) William Osborne, Wlodzimierz Skiba
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
11
12 // ============================================================================
13 // declarations
14 // ============================================================================
15
16 // ----------------------------------------------------------------------------
17 // headers
18 // ----------------------------------------------------------------------------
19
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 #if wxUSE_CONTROLS
28
29 #include "wx/control.h"
30
31 #ifndef WX_PRECOMP
32 #include "wx/event.h"
33 #include "wx/app.h"
34 #include "wx/dcclient.h"
35 #include "wx/log.h"
36 #include "wx/settings.h"
37 #include "wx/button.h"
38 #include "wx/checkbox.h"
39 #include "wx/radiobut.h"
40 #include "wx/slider.h"
41 #include "wx/toplevel.h"
42 #endif
43
44 #include "wx/tglbtn.h"
45
46 #include <Control.h>
47 #include <Form.h>
48 #ifdef __WXPALMOS6__
49 #include <StatusBar.h>
50 #else
51 #include <PenInputMgr.h>
52 #endif // __WXPALMOS6__
53
54 // ----------------------------------------------------------------------------
55 // wxWin macros
56 // ----------------------------------------------------------------------------
57
58 IMPLEMENT_ABSTRACT_CLASS(wxControl, wxWindow)
59
60 BEGIN_EVENT_TABLE(wxControl, wxWindow)
61 EVT_ERASE_BACKGROUND(wxControl::OnEraseBackground)
62 END_EVENT_TABLE()
63
64 // ============================================================================
65 // wxControl implementation
66 // ============================================================================
67
68 // ----------------------------------------------------------------------------
69 // wxControl ctor/dtor
70 // ----------------------------------------------------------------------------
71
72 void wxControl::Init()
73 {
74 m_palmControl = false;
75 m_palmField = false;
76 }
77
78 wxControl::~wxControl()
79 {
80 SendDestroyEvent();
81
82 SetLabel(wxEmptyString);
83
84 DestroyChildren();
85
86 uint16_t index;
87 FormType* form = (FormType*)GetObjectFormIndex(index);
88 if(form!=NULL && index!=frmInvalidObjectId)
89 {
90 FrmRemoveObject((FormType **)&form,index);
91 }
92 }
93
94 // ----------------------------------------------------------------------------
95 // control window creation
96 // ----------------------------------------------------------------------------
97
98 bool wxControl::Create(wxWindow *parent,
99 wxWindowID id,
100 const wxPoint& pos,
101 const wxSize& size,
102 long style,
103 const wxValidator& wxVALIDATOR_PARAM(validator),
104 const wxString& name)
105 {
106 if ( !wxWindow::Create(parent, id, pos, size, style, name) )
107 return false;
108
109 #if wxUSE_VALIDATORS
110 SetValidator(validator);
111 #endif
112
113 return true;
114 }
115
116 bool wxControl::PalmCreateControl(int style,
117 const wxString& label,
118 const wxPoint& pos,
119 const wxSize& size,
120 uint8_t groupID)
121 {
122 FormType* form = (FormType*)GetParentForm();
123 if(form==NULL)
124 return false;
125
126
127 wxCoord x = pos.x == wxDefaultCoord ? 0 : pos.x,
128 y = pos.y == wxDefaultCoord ? 0 : pos.y,
129 w = size.x == wxDefaultCoord ? 1 : size.x,
130 h = size.y == wxDefaultCoord ? 1 : size.y;
131
132 wxWindow *win = this;
133 while(win->GetParent())
134 {
135 win = win->GetParent();
136 wxPoint pt(win->GetClientAreaOrigin());
137 x += pt.x;
138 y += pt.y;
139 }
140
141 ControlType *control = CtlNewControl(
142 (void **)&form,
143 GetId(),
144 (ControlStyleType)style,
145 NULL,
146 x,
147 y,
148 w,
149 h,
150 stdFont,
151 groupID,
152 true
153 );
154
155 if(control==NULL)
156 return false;
157
158 m_palmControl = true;
159
160 SetInitialSize(size);
161 SetLabel(label);
162 Show();
163 return true;
164 }
165
166 bool wxControl::PalmCreateField(const wxString& label,
167 const wxPoint& pos,
168 const wxSize& size,
169 bool editable,
170 bool underlined,
171 int justification)
172 {
173 FormType* form = (FormType*)GetParentForm();
174 if(form==NULL)
175 return false;
176
177 m_label = label;
178
179 wxCoord x = pos.x == wxDefaultCoord ? 0 : pos.x,
180 y = pos.y == wxDefaultCoord ? 0 : pos.y,
181 w = size.x == wxDefaultCoord ? 1 : size.x,
182 h = size.y == wxDefaultCoord ? 1 : size.y;
183
184 AdjustForParentClientOrigin(x, y);
185
186 FieldType *field = FldNewField(
187 (void **)&form,
188 GetId(),
189 x,
190 y,
191 w,
192 h,
193 stdFont,
194 10,
195 editable,
196 underlined,
197 false,
198 false,
199 (JustificationType)justification,
200 false,
201 false,
202 false
203 );
204
205 if(field==NULL)
206 return false;
207
208 m_palmField = true;
209
210 SetInitialSize(size);
211 SetLabel(label);
212 Show();
213 return true;
214 }
215
216 // ----------------------------------------------------------------------------
217 // various accessors
218 // ----------------------------------------------------------------------------
219
220 WXFORMPTR wxControl::GetParentForm() const
221 {
222 wxWindow* parentTLW = GetParent();
223 while ( parentTLW && !parentTLW->IsTopLevel() )
224 {
225 parentTLW = parentTLW->GetParent();
226 }
227 wxTopLevelWindowPalm* tlw = wxDynamicCast(parentTLW, wxTopLevelWindowPalm);
228 if(!tlw)
229 return NULL;
230 return tlw->GetForm();
231 }
232
233 WXFORMPTR wxControl::GetObjectFormIndex(uint16_t& index) const
234 {
235 FormType* form = (FormType* )GetParentForm();
236 if(form!=NULL)
237 index = FrmGetObjectIndex(form, GetId());
238 else
239 index = frmInvalidObjectId;
240 return form;
241 }
242
243 void* wxControl::GetObjectPtr() const
244 {
245 uint16_t index;
246 FormType* form = (FormType*)GetObjectFormIndex(index);
247 if(form==NULL || index==frmInvalidObjectId)return NULL;
248 return FrmGetObjectPtr(form,index);
249 }
250
251 wxBorder wxControl::GetDefaultBorder() const
252 {
253 // we want to automatically give controls a sunken style (confusingly,
254 // it may not really mean sunken at all as we map it to WS_EX_CLIENTEDGE
255 // which is not sunken at all under Windows XP -- rather, just the default)
256 return wxBORDER_SUNKEN;
257 }
258
259 void wxControl::SetIntValue(int val)
260 {
261 FormType* form = (FormType*)GetParentForm();
262 if(form==NULL)
263 return;
264 uint16_t index = FrmGetObjectIndex(form, GetId());
265 if(index==frmInvalidObjectId)
266 return;
267 FrmSetControlValue(form, index, val);
268 }
269
270 void wxControl::SetBoolValue(bool val)
271 {
272 SetIntValue(val?1:0);
273 }
274
275 bool wxControl::GetBoolValue() const
276 {
277 FormType* form = (FormType*)GetParentForm();
278 if(form==NULL)
279 return false;
280 uint16_t index = FrmGetObjectIndex(form, GetId());
281 if(index==frmInvalidObjectId)
282 return false;
283 return ( FrmGetControlValue(form, index) == 1 );
284 }
285
286 wxSize wxControl::DoGetBestSize() const
287 {
288 return wxSize(16, 16);
289 }
290
291 void wxControl::DoGetBounds( WXRECTANGLEPTR rect ) const
292 {
293 if(rect==NULL)
294 return;
295 FormType* form = (FormType*)GetParentForm();
296 if(form==NULL)
297 return;
298 uint16_t index = FrmGetObjectIndex(form,GetId());
299 if(index==frmInvalidObjectId)
300 return;
301 FrmGetObjectBounds(form,index,(RectangleType*)rect);
302 }
303
304 void wxControl::DoSetBounds( WXRECTANGLEPTR rect )
305 {
306 if(rect==NULL)
307 return;
308 FormType* form = (FormType*)GetParentForm();
309 if(form==NULL)
310 return;
311 uint16_t index = FrmGetObjectIndex(form,GetId());
312 if(index==frmInvalidObjectId)
313 return;
314 FrmSetObjectBounds(form,index,(RectangleType*)rect);
315 }
316
317 void wxControl::DoGetPosition( int *x, int *y ) const
318 {
319 int ox = 0, oy = 0;
320 AdjustForParentClientOrigin(ox, oy);
321
322 RectangleType rect;
323 DoGetBounds(&rect);
324
325 if(x)
326 *x = rect.topLeft.x - ox;
327 if(y)
328 *y = rect.topLeft.y - oy;
329 }
330
331 void wxControl::DoGetSize( int *width, int *height ) const
332 {
333 RectangleType rect;
334 DoGetBounds(&rect);
335
336 if(width)
337 *width = rect.extent.x;
338 if(height)
339 *height = rect.extent.y;
340 }
341
342 void wxControl::DoMoveWindow(int x, int y, int width, int height)
343 {
344 wxRect area = GetRect();
345 RectangleType rect;
346 rect.topLeft.x = x;
347 rect.topLeft.y = y;
348 rect.extent.x = width;
349 rect.extent.y = height;
350 DoSetBounds(&rect);
351 GetParent()->Refresh(true, &area);
352 }
353
354 bool wxControl::Enable(bool enable)
355 {
356 ControlType *control = (ControlType *)GetObjectPtr();
357 if( !IsPalmControl() || (control == NULL))
358 return false;
359 if( CtlEnabled(control) == enable)
360 return false;
361 CtlSetEnabled( control, enable);
362 return true;
363 }
364
365 bool wxControl::IsEnabled() const
366 {
367 ControlType *control = (ControlType *)GetObjectPtr();
368 if( !IsPalmControl() || (control == NULL))
369 return false;
370 return CtlEnabled(control);
371 }
372
373 bool wxControl::IsShown() const
374 {
375 return StatGetAttribute ( statAttrBarVisible , NULL );
376 }
377
378 bool wxControl::Show( bool show )
379 {
380 FormType* form = (FormType*)GetParentForm();
381 if(form==NULL)
382 return false;
383 uint16_t index = FrmGetObjectIndex(form,GetId());
384 if(index==frmInvalidObjectId)
385 return false;
386 if(show)
387 FrmShowObject(form,index);
388 else
389 FrmHideObject(form,index);
390 return true;
391 }
392
393 void wxControl::SetFieldLabel(const wxString& label)
394 {
395 FieldType* field = (FieldType*)GetObjectPtr();
396 if(field==NULL)
397 return;
398
399 uint16_t newSize = label.length() + 1;
400 MemHandle strHandle = FldGetTextHandle(field);
401 FldSetTextHandle(field, NULL );
402 if (strHandle)
403 {
404 if(MemHandleResize(strHandle, newSize)!=errNone)
405 strHandle = 0;
406 }
407 else
408 {
409 strHandle = MemHandleNew( newSize );
410 }
411 if(!strHandle)
412 return;
413
414 char* str = (char*) MemHandleLock( strHandle );
415 if(str==NULL)
416 return;
417
418 strcpy(str, label.c_str());
419 MemHandleUnlock(strHandle);
420 FldSetTextHandle(field, strHandle);
421 FldRecalculateField(field, true);
422 }
423
424 void wxControl::SetControlLabel(const wxString& label)
425 {
426 ControlType* control = (ControlType*)GetObjectPtr();
427 if(control==NULL)
428 return;
429 CtlSetLabel(control, "");
430 m_label = label;
431 if(!m_label.empty())
432 CtlSetLabel(control,m_label.c_str());
433 }
434
435 void wxControl::SetLabel(const wxString& label)
436 {
437 if(IsPalmField())
438 SetFieldLabel(label);
439
440 // unlike other native controls, slider has no label
441 if(IsPalmControl() && !wxDynamicCast(this,wxSlider))
442 SetControlLabel(label);
443 }
444
445 wxString wxControl::GetFieldLabel()
446 {
447 FieldType* field = (FieldType*)GetObjectPtr();
448 if(field==NULL)
449 return wxEmptyString;
450 return FldGetTextPtr(field);
451 }
452
453 wxString wxControl::GetControlLabel()
454 {
455 ControlType* control = (ControlType*)GetObjectPtr();
456 if(control==NULL)
457 return wxEmptyString;
458 return CtlGetLabel(control);
459 }
460 #if 0
461 wxString wxControl::GetLabel()
462 {
463 if(IsPalmField())
464 return GetFieldLabel();
465
466 // unlike other native controls, slider has no label
467 if(IsPalmControl() && !wxDynamicCast(this,wxSlider))
468 return GetControlLabel();
469
470 return wxEmptyString;
471 }
472 #endif
473 /* static */ wxVisualAttributes
474 wxControl::GetClassDefaultAttributes(wxWindowVariant WXUNUSED(variant))
475 {
476 wxVisualAttributes attrs;
477
478 // old school (i.e. not "common") controls use the standard dialog font
479 // by default
480 attrs.font = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT);
481
482 // most, or at least many, of the controls use the same colours as the
483 // buttons -- others will have to override this (and possibly simply call
484 // GetCompositeControlsDefaultAttributes() from their versions)
485 attrs.colFg = wxSystemSettings::GetColour(wxSYS_COLOUR_BTNTEXT);
486 attrs.colBg = wxSystemSettings::GetColour(wxSYS_COLOUR_BTNFACE);
487
488 return attrs;
489 }
490
491 // another version for the "composite", i.e. non simple controls
492 /* static */ wxVisualAttributes
493 wxControl::GetCompositeControlsDefaultAttributes(wxWindowVariant WXUNUSED(variant))
494 {
495 wxVisualAttributes attrs;
496 attrs.font = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT);
497 attrs.colFg = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT);
498 attrs.colBg = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW);
499
500 return attrs;
501 }
502
503 // ----------------------------------------------------------------------------
504 // message handling
505 // ----------------------------------------------------------------------------
506
507 bool wxControl::ProcessCommand(wxCommandEvent& event)
508 {
509 return HandleWindowEvent(event);
510 }
511
512 void wxControl::OnEraseBackground(wxEraseEvent& event)
513 {
514 }
515
516 #endif // wxUSE_CONTROLS