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