1 /////////////////////////////////////////////////////////////////////////////
3 // Purpose: wxControl class
8 // Copyright: (c) AUTHOR
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
13 #pragma implementation "control.h"
16 #include "wx/control.h"
17 #include "wx/notebook.h"
18 #include "wx/tabctrl.h"
19 #include "wx/radiobox.h"
20 #include "wx/spinbutt.h"
22 #if !USE_SHARED_LIBRARY
23 IMPLEMENT_ABSTRACT_CLASS(wxControl
, wxWindow
)
25 BEGIN_EVENT_TABLE(wxControl
, wxWindow
)
26 EVT_MOUSE_EVENTS( wxControl::OnMouseEvent
)
27 EVT_CHAR( wxControl::OnKeyDown
)
28 EVT_PAINT( wxControl::OnPaint
)
32 #include <wx/mac/uma.h>
36 ControlActionUPP wxMacLiveScrollbarActionUPP
= NULL
;
38 pascal void wxMacLiveScrollbarActionProc( ControlHandle control
, ControlPartCode partCode
) ;
39 pascal void wxMacLiveScrollbarActionProc( ControlHandle control
, ControlPartCode partCode
)
43 wxControl
* wx
= (wxControl
*) GetControlReference( control
) ;
46 wx
->MacHandleControlClick( control
, partCode
) ;
51 wxControl::wxControl()
54 m_macHorizontalBorder
= 0 ; // additional pixels around the real control
55 m_macVerticalBorder
= 0 ;
56 m_backgroundColour
= *wxWHITE
;
57 m_foregroundColour
= *wxBLACK
;
58 #if WXWIN_COMPATIBILITY
60 #endif // WXWIN_COMPATIBILITY
62 if ( wxMacLiveScrollbarActionUPP
== NULL
)
64 wxMacLiveScrollbarActionUPP
= NewControlActionProc( wxMacLiveScrollbarActionProc
) ;
68 bool wxControl::Create(wxWindow
*parent
, wxWindowID id
,
70 const wxSize
& size
, long style
,
71 const wxValidator
& validator
,
75 m_macHorizontalBorder
= 0 ; // additional pixels around the real control
76 m_macVerticalBorder
= 0 ;
77 bool rval
= wxWindow::Create(parent
, id
, pos
, size
, style
, name
);
80 SetValidator(validator
);
86 wxControl::~wxControl()
88 m_isBeingDeleted
= TRUE
;
89 // If we delete an item, we should initialize the parent panel,
90 // because it could now be invalid.
91 wxPanel
*panel
= wxDynamicCast(GetParent(), wxPanel
);
94 if (panel
->GetDefaultItem() == (wxButton
*) this)
95 panel
->SetDefaultItem(NULL
);
99 UMADisposeControl( m_macControl
) ;
100 m_macControl
= NULL
;
104 void wxControl::SetLabel(const wxString
& title
)
113 if( wxApp::s_macDefaultEncodingIsPC
)
114 label
= wxMacMakeMacStringFromPC( title
) ;
118 strcpy( (char*) maclabel
, label
) ;
119 c2pstr( (char*) maclabel
) ;
121 ::SetControlTitle( m_macControl
, maclabel
) ;
125 wxSize
wxControl::DoGetBestSize() const
127 return wxSize(20, 20);
130 bool wxControl::ProcessCommand (wxCommandEvent
& event
)
133 // 1) A callback function (to become obsolete)
134 // 2) OnCommand, starting at this window and working up parent hierarchy
135 // 3) OnCommand then calls ProcessEvent to search the event tables.
136 #if WXWIN_COMPATIBILITY
139 (void)(*m_callback
)(this, event
);
144 #endif // WXWIN_COMPATIBILITY
146 return GetEventHandler()->ProcessEvent(event
);
150 // ------------------------
151 wxList
*wxWinMacControlList
= NULL
;
152 wxControl
*wxFindControlFromMacControl(ControlHandle inControl
)
154 wxNode
*node
= wxWinMacControlList
->Find((long)inControl
);
157 return (wxControl
*)node
->Data();
160 void wxAssociateControlWithMacControl(ControlHandle inControl
, wxControl
*control
)
162 // adding NULL WindowRef is (first) surely a result of an error and
163 // (secondly) breaks menu command processing
164 wxCHECK_RET( inControl
!= (ControlHandle
) NULL
, "attempt to add a NULL WindowRef to window list" );
166 if ( !wxWinMacControlList
->Find((long)inControl
) )
167 wxWinMacControlList
->Append((long)inControl
, control
);
170 void wxRemoveMacControlAssociation(wxControl
*control
)
172 wxWinMacControlList
->DeleteObject(control
);
175 void wxControl::MacPreControlCreate( wxWindow
*parent
, wxWindowID id
, wxString label
,
177 const wxSize
& size
, long style
,
178 const wxValidator
& validator
,
179 const wxString
& name
, Rect
*outBounds
, StringPtr maclabel
)
184 SetValidator(validator
);
186 m_windowStyle
= style
;
187 parent
->AddChild((wxButton
*)this);
189 m_backgroundColour
= parent
->GetBackgroundColour() ;
190 m_foregroundColour
= parent
->GetForegroundColour() ;
193 m_windowId
= NewControlId();
201 AdjustForParentClientOrigin(x
, y
, wxSIZE_USE_EXISTING
);
209 parent
->MacClientToRootWindow( &x
, &y
) ;
210 outBounds
->top
= y
+ m_macVerticalBorder
;
211 outBounds
->left
= x
+ m_macHorizontalBorder
;
212 outBounds
->bottom
= outBounds
->top
+ m_height
- 2 * m_macVerticalBorder
;
213 outBounds
->right
= outBounds
->left
+ m_width
- 2 * m_macHorizontalBorder
;
215 strcpy( (char*) maclabel
, label
) ;
216 if( wxApp::s_macDefaultEncodingIsPC
)
218 wxMacConvertFromPCForControls( (char*) maclabel
) ;
221 c2pstr( (char*) maclabel
) ;
224 void wxControl::MacPostControlCreate()
226 wxASSERT_MSG( m_macControl
!= NULL
, "No valid mac control" ) ;
228 if ( IsKindOf( CLASSINFO( wxScrollBar
) ) )
232 else if ( IsKindOf( CLASSINFO( wxStaticBox
) ) || IsKindOf( CLASSINFO( wxRadioBox
) ) || IsKindOf( CLASSINFO( wxButton
) ) )
234 ControlFontStyleRec controlstyle
;
235 controlstyle
.flags
= kControlUseFontMask
;
236 controlstyle
.font
= kControlFontSmallBoldSystemFont
;
238 ::UMASetControlFontStyle( m_macControl
, &controlstyle
) ;
242 ControlFontStyleRec controlstyle
;
243 controlstyle
.flags
= kControlUseFontMask
;
244 controlstyle
.font
= kControlFontSmallSystemFont
;
246 ::UMASetControlFontStyle( m_macControl
, &controlstyle
) ;
248 ControlHandle container
= GetParent()->MacGetContainerForEmbedding() ;
249 wxASSERT_MSG( container
!= NULL
, "No valid mac container control" ) ;
250 ::UMAEmbedControl( m_macControl
, container
) ;
251 MacAdjustControlRect() ;
252 wxAssociateControlWithMacControl( m_macControl
, this ) ;
255 void wxControl::MacAdjustControlRect()
257 wxASSERT_MSG( m_macControl
!= NULL
, "No valid mac control" ) ;
258 if ( m_width
== -1 || m_height
== -1 )
260 Rect bestsize
= { 0 , 0 , 0 , 0 } ;
261 short baselineoffset
;
263 UMAGetBestControlRect( m_macControl
, &bestsize
, &baselineoffset
) ;
265 if ( EmptyRect( &bestsize
) )
268 bestsize
.left
= bestsize
.top
= 0 ;
269 bestsize
.right
= 16 ;
270 bestsize
.bottom
= 16 ;
271 if ( IsKindOf( CLASSINFO( wxScrollBar
) ) )
273 bestsize
.bottom
= 16 ;
275 else if ( IsKindOf( CLASSINFO( wxSpinButton
) ) )
277 bestsize
.bottom
= 24 ;
283 if ( IsKindOf( CLASSINFO( wxButton
) ) )
285 m_width
= m_label
.Length() * 8 + 12 ;
287 else if ( IsKindOf( CLASSINFO( wxStaticText
) ) )
289 m_width
= m_label
.Length() * 8 ;
292 m_width
= bestsize
.right
- bestsize
.left
;
294 m_width
+= 2 * m_macHorizontalBorder
;
296 if ( m_height
== -1 )
298 m_height
= bestsize
.bottom
- bestsize
.top
;
302 m_height
+= 2 * m_macVerticalBorder
;
305 wxMacDrawingHelper
helper ( wxFindWinFromMacWindow( GetMacRootWindow() ) ) ;
308 UMASizeControl( m_macControl
, m_width
- 2 * m_macHorizontalBorder
, m_height
- 2 * m_macVerticalBorder
) ;
312 ControlHandle
wxControl::MacGetContainerForEmbedding()
315 return m_macControl
;
317 return wxWindow::MacGetContainerForEmbedding() ;
320 void wxControl::MacSuperChangedPosition()
325 GetControlBounds( m_macControl
, &contrlRect
) ;
326 int former_mac_x
= contrlRect
.left
;
327 int former_mac_y
= contrlRect
.top
;
330 GetParent()->MacClientToRootWindow( & mac_x
, & mac_y
) ;
332 WindowRef rootwindow
= GetMacRootWindow() ;
333 wxWindow
* wxrootwindow
= wxFindWinFromMacWindow( rootwindow
) ;
334 UMASetThemeWindowBackground( rootwindow
, kThemeBrushDialogBackgroundActive
, false ) ;
335 wxMacDrawingHelper
focus( wxrootwindow
) ;
337 if ( mac_x
!= former_mac_x
|| mac_y
!= former_mac_y
)
340 Rect inval
= { former_mac_y
, former_mac_x
, former_mac_y
+ m_height
, former_mac_x
+ m_width
} ;
341 InvalWindowRect( rootwindow
, &inval
) ;
343 UMAMoveControl( m_macControl
, mac_x
+ m_macHorizontalBorder
, mac_y
+ m_macVerticalBorder
) ;
345 Rect inval
= { mac_y
, mac_x
, mac_y
+ m_height
, mac_x
+ m_width
} ;
346 InvalWindowRect( rootwindow
, &inval
) ;
349 if ( wxrootwindow
->IsKindOf( CLASSINFO( wxDialog
) ) )
354 UMASetThemeWindowBackground( rootwindow
, kThemeBrushDocumentWindowBackground
, false ) ;
358 wxWindow::MacSuperChangedPosition() ;
361 void wxControl::MacSuperEnabled( bool enabled
)
366 if ( UMAHasAppearance() )
370 ::DeactivateControl( m_macControl ) ;
375 ::ActivateControl( m_macControl ) ;
382 ::HiliteControl( m_macControl , 255 ) ;
387 ::HiliteControl( m_macControl , 0 ) ;
391 wxWindow::MacSuperEnabled( enabled ) ;
395 void wxControl::MacSuperShown( bool show
)
401 ::UMAHideControl( m_macControl
) ;
406 ::UMAShowControl( m_macControl
) ;
410 wxWindow::MacSuperShown( show
) ;
413 void wxControl::DoSetSize(int x
, int y
,
414 int width
, int height
,
417 if ( m_macControl
== NULL
)
419 wxWindow::DoSetSize( x
, y
,width
, height
,sizeFlags
) ;
423 WindowRef rootwindow
= GetMacRootWindow() ;
424 wxWindow
* wxrootwindow
= wxFindWinFromMacWindow( rootwindow
) ;
425 UMASetThemeWindowBackground( rootwindow
, kThemeBrushDialogBackgroundActive
, false ) ;
429 int former_w
= m_width
;
430 int former_h
= m_height
;
433 GetControlBounds( m_macControl
, &contrlRect
) ;
434 int former_mac_x
= contrlRect
.left
;
435 int former_mac_y
= contrlRect
.top
;
437 int currentX
, currentY
;
438 GetPosition(¤tX
, ¤tY
);
439 int currentW
,currentH
;
440 GetSize(¤tW
, ¤tH
);
442 int actualWidth
= width
;
443 int actualHeight
= height
;
446 if (x
== -1 && !(sizeFlags
& wxSIZE_ALLOW_MINUS_ONE
))
448 if (y
== -1 && !(sizeFlags
& wxSIZE_ALLOW_MINUS_ONE
))
451 actualWidth
= currentW
;
453 actualHeight
= currentH
;
455 if ( actualX
== currentX
&& actualY
== currentY
&& actualWidth
== currentW
&& actualHeight
== currentH
)
458 AdjustForParentClientOrigin(actualX
, actualY
, sizeFlags
);
459 WindowRef macrootwindow
= GetMacRootWindow() ;
460 wxMacDrawingHelper
focus( wxFindWinFromMacWindow( macrootwindow
) ) ;
462 int mac_x
= actualX
;
463 int mac_y
= actualY
;
464 GetParent()->MacClientToRootWindow( & mac_x
, & mac_y
) ;
466 if ( mac_x
!= former_mac_x
|| mac_y
!= former_mac_y
)
469 Rect inval
= { former_mac_y
, former_mac_x
, former_mac_y
+ m_height
, former_mac_x
+ m_width
} ;
470 InvalWindowRect( macrootwindow
, &inval
) ;
472 UMAMoveControl( m_macControl
, mac_x
+ m_macHorizontalBorder
, mac_y
+ m_macVerticalBorder
) ;
474 Rect inval
= { mac_y
, mac_x
, mac_y
+ m_height
, mac_x
+ m_width
} ;
475 InvalWindowRect(macrootwindow
, &inval
) ;
479 if ( actualX
!= former_x
|| actualY
!= former_y
)
484 MacRepositionScrollBars() ;
485 // To consider -> should the parameters be the effective or the virtual coordinates (AdjustForParent..)
486 wxMoveEvent
event(wxPoint(m_x
, m_y
), m_windowId
);
487 event
.SetEventObject(this);
488 GetEventHandler()->ProcessEvent(event
);
490 if ( actualWidth
!= former_w
|| actualHeight
!= former_h
)
493 Rect inval
= { mac_y
, mac_x
, mac_y
+ former_h
, mac_x
+ former_w
} ;
494 InvalWindowRect( macrootwindow
, &inval
) ;
496 m_width
= actualWidth
;
497 m_height
= actualHeight
;
499 UMASizeControl( m_macControl
, m_width
- 2 * m_macHorizontalBorder
, m_height
- 2 * m_macVerticalBorder
) ;
501 Rect inval
= { mac_y
, mac_x
, mac_y
+ m_height
, mac_x
+ m_width
} ;
502 InvalWindowRect( macrootwindow
, &inval
) ;
505 MacRepositionScrollBars() ;
506 wxSizeEvent
event(wxSize(m_width
, m_height
), m_windowId
);
507 event
.SetEventObject(this);
508 GetEventHandler()->ProcessEvent(event
);
510 if ( wxrootwindow
->IsKindOf( CLASSINFO( wxDialog
) ) )
515 UMASetThemeWindowBackground( rootwindow
, kThemeBrushDocumentWindowBackground
, false ) ;
519 bool wxControl::Show(bool show
)
521 if ( !wxWindow::Show( show
) )
527 ::UMAShowControl( m_macControl
) ;
529 ::UMAHideControl( m_macControl
) ;
534 bool wxControl::Enable(bool enable
)
536 if ( !wxWindow::Enable(enable
) )
542 if ( UMAHasAppearance() )
545 ::ActivateControl( m_macControl
) ;
547 ::DeactivateControl( m_macControl
) ;
552 ::HiliteControl( m_macControl
, 0 ) ;
554 ::HiliteControl( m_macControl
, 255 ) ;
560 void wxControl::Refresh(bool eraseBack
, const wxRect
*rect
)
564 wxWindow::Refresh( eraseBack
, rect
) ;
568 wxWindow::Refresh( eraseBack
, rect
) ;
572 void wxControl::MacRedrawControl()
576 WindowRef window
= GetMacRootWindow() ;
579 wxWindow
* win
= wxFindWinFromMacWindow( window
) ;
582 wxMacDrawingHelper
help( win
) ;
583 // the mac control manager always assumes to have the origin at 0,0
586 bool hasTabBehind
= false ;
587 wxWindow
* parent
= GetParent() ;
590 if( parent
->MacGetWindowData() )
592 UMASetThemeWindowBackground( win
->MacGetWindowData()->m_macWindow
, kThemeBrushDialogBackgroundActive
, false ) ;
596 if( parent
->IsKindOf( CLASSINFO( wxNotebook
) ) || parent
->IsKindOf( CLASSINFO( wxTabCtrl
) ))
598 if ( ((wxControl
*)parent
)->m_macControl
)
599 SetUpControlBackground( ((wxControl
*)parent
)->m_macControl
, -1 , true ) ;
603 parent
= parent
->GetParent() ;
606 UMADrawControl( m_macControl
) ;
607 UMASetThemeWindowBackground( win
->MacGetWindowData()->m_macWindow
, win
->MacGetWindowData()->m_macWindowBackgroundTheme
, false ) ;
613 void wxControl::OnPaint(wxPaintEvent
& event
)
617 WindowRef window
= GetMacRootWindow() ;
620 wxWindow
* win
= wxFindWinFromMacWindow( window
) ;
623 wxMacDrawingHelper
help( win
) ;
624 // the mac control manager always assumes to have the origin at 0,0
627 bool hasTabBehind
= false ;
628 wxWindow
* parent
= GetParent() ;
631 if( parent
->MacGetWindowData() )
633 UMASetThemeWindowBackground( win
->MacGetWindowData()->m_macWindow
, kThemeBrushDialogBackgroundActive
, false ) ;
637 if( parent
->IsKindOf( CLASSINFO( wxNotebook
) ) || parent
->IsKindOf( CLASSINFO( wxTabCtrl
) ))
639 if ( ((wxControl
*)parent
)->m_macControl
)
640 SetUpControlBackground( ((wxControl
*)parent
)->m_macControl
, -1 , true ) ;
644 parent
= parent
->GetParent() ;
647 UMADrawControl( m_macControl
) ;
648 UMASetThemeWindowBackground( win
->MacGetWindowData()->m_macWindow
, win
->MacGetWindowData()->m_macWindowBackgroundTheme
, false ) ;
654 // wxWindow::OnPaint( event ) ;
657 void wxControl::OnEraseBackground(wxEraseEvent
& event
)
659 // In general, you don't want to erase the background of a control,
660 // or you'll get a flicker.
661 // TODO: move this 'null' function into each control that
666 void wxControl::OnKeyDown( wxKeyEvent
&event
)
668 if ( m_macControl
== NULL
)
671 EventRecord
*ev
= wxTheApp
->MacGetCurrentEvent() ;
674 keychar
= short(ev
->message
& charCodeMask
);
675 keycode
= short(ev
->message
& keyCodeMask
) >> 8 ;
677 UMAHandleControlKey( m_macControl
, keycode
, keychar
, ev
->modifiers
) ;
680 void wxControl::OnMouseEvent( wxMouseEvent
&event
)
682 if ( m_macControl
== NULL
)
688 if (event
.GetEventType() == wxEVT_LEFT_DOWN
|| event
.GetEventType() == wxEVT_LEFT_DCLICK
)
694 MacClientToRootWindow( &x
, &y
) ;
696 ControlHandle control
;
700 WindowRef window
= GetMacRootWindow() ;
707 if ( !event
.m_leftDown
&& !event
.m_rightDown
)
708 modifiers
|= btnState
;
710 if ( event
.m_shiftDown
)
711 modifiers
|= shiftKey
;
713 if ( event
.m_controlDown
)
714 modifiers
|= controlKey
;
716 if ( event
.m_altDown
)
717 modifiers
|= optionKey
;
719 if ( event
.m_metaDown
)
720 modifiers
|= cmdKey
;
722 controlpart
= FindControl( localwhere
, window
, &control
) ;
724 if ( AcceptsFocus() && FindFocus() != this )
728 if ( control
&& UMAIsControlActive( control
) )
731 if ( controlpart
== kControlIndicatorPart
&& !UMAHasAppearance() )
732 controlpart
= UMAHandleControlClick( control
, localwhere
, modifiers
, (ControlActionUPP
) NULL
) ;
734 controlpart
= UMAHandleControlClick( control
, localwhere
, modifiers
, (ControlActionUPP
) -1 ) ;
735 wxTheApp
->s_lastMouseDown
= 0 ;
736 if ( controlpart
&& ! ( ( UMAHasAppearance() || (controlpart
!= kControlIndicatorPart
) )
737 && (IsKindOf( CLASSINFO( wxScrollBar
) ) ) ) ) // otherwise we will get the event twice
739 MacHandleControlClick( control
, controlpart
) ;
747 bool wxControl::MacCanFocus() const
749 { if ( m_macControl
== NULL
)
756 void wxControl::MacHandleControlClick( ControlHandle control
, SInt16 controlpart
)
758 wxASSERT_MSG( m_macControl
!= NULL
, "No valid mac control" ) ;