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/spinbutt.h"
21 #if !USE_SHARED_LIBRARY
22 IMPLEMENT_ABSTRACT_CLASS(wxControl
, wxWindow
)
24 BEGIN_EVENT_TABLE(wxControl
, wxWindow
)
25 EVT_MOUSE_EVENTS( wxControl::OnMouseEvent
)
26 EVT_CHAR( wxControl::OnKeyDown
)
27 EVT_PAINT( wxControl::OnPaint
)
31 #include <wx/mac/uma.h>
35 ControlActionUPP wxMacLiveScrollbarActionUPP
= NULL
;
37 pascal void wxMacLiveScrollbarActionProc( ControlHandle control
, ControlPartCode partCode
)
41 wxControl
* wx
= (wxControl
*) GetControlReference( control
) ;
44 wx
->MacHandleControlClick( control
, partCode
) ;
49 wxControl::wxControl()
52 m_macHorizontalBorder
= 0 ; // additional pixels around the real control
53 m_macVerticalBorder
= 0 ;
54 m_backgroundColour
= *wxWHITE
;
55 m_foregroundColour
= *wxBLACK
;
56 #if WXWIN_COMPATIBILITY
58 #endif // WXWIN_COMPATIBILITY
60 if ( wxMacLiveScrollbarActionUPP
== NULL
)
62 wxMacLiveScrollbarActionUPP
= NewControlActionProc( wxMacLiveScrollbarActionProc
) ;
66 wxControl::~wxControl()
68 m_isBeingDeleted
= TRUE
;
69 // If we delete an item, we should initialize the parent panel,
70 // because it could now be invalid.
71 wxPanel
*panel
= wxDynamicCast(GetParent(), wxPanel
);
74 if (panel
->GetDefaultItem() == (wxButton
*) this)
75 panel
->SetDefaultItem(NULL
);
79 UMADisposeControl( m_macControl
) ;
84 void wxControl::SetLabel(const wxString
& title
)
93 if( wxApp::s_macDefaultEncodingIsPC
)
94 label
= wxMacMakeMacStringFromPC( title
) ;
98 strcpy( (char*) maclabel
, label
) ;
99 c2pstr( (char*) maclabel
) ;
101 ::SetControlTitle( m_macControl
, maclabel
) ;
105 wxSize
wxControl::DoGetBestSize()
107 return wxSize(20, 20);
110 bool wxControl::ProcessCommand (wxCommandEvent
& event
)
113 // 1) A callback function (to become obsolete)
114 // 2) OnCommand, starting at this window and working up parent hierarchy
115 // 3) OnCommand then calls ProcessEvent to search the event tables.
116 #if WXWIN_COMPATIBILITY
119 (void)(*m_callback
)(this, event
);
124 #endif // WXWIN_COMPATIBILITY
126 return GetEventHandler()->ProcessEvent(event
);
130 // ------------------------
131 wxList
*wxWinMacControlList
= NULL
;
132 wxControl
*wxFindControlFromMacControl(ControlHandle inControl
)
134 wxNode
*node
= wxWinMacControlList
->Find((long)inControl
);
137 return (wxControl
*)node
->Data();
140 void wxAssociateControlWithMacControl(ControlHandle inControl
, wxControl
*control
)
142 // adding NULL WindowRef is (first) surely a result of an error and
143 // (secondly) breaks menu command processing
144 wxCHECK_RET( inControl
!= (ControlHandle
) NULL
, "attempt to add a NULL WindowRef to window list" );
146 if ( !wxWinMacControlList
->Find((long)inControl
) )
147 wxWinMacControlList
->Append((long)inControl
, control
);
150 void wxRemoveMacControlAssociation(wxControl
*control
)
152 wxWinMacControlList
->DeleteObject(control
);
155 void wxControl::MacPreControlCreate( wxWindow
*parent
, wxWindowID id
, wxString label
,
157 const wxSize
& size
, long style
,
158 const wxValidator
& validator
,
159 const wxString
& name
, Rect
*outBounds
, StringPtr maclabel
)
164 SetValidator(validator
);
166 m_windowStyle
= style
;
167 parent
->AddChild((wxButton
*)this);
169 m_backgroundColour
= parent
->GetBackgroundColour() ;
170 m_foregroundColour
= parent
->GetForegroundColour() ;
173 m_windowId
= NewControlId();
181 AdjustForParentClientOrigin(x
, y
, wxSIZE_USE_EXISTING
);
189 parent
->MacClientToRootWindow( &x
, &y
) ;
190 outBounds
->top
= y
+ m_macVerticalBorder
;
191 outBounds
->left
= x
+ m_macHorizontalBorder
;
192 outBounds
->bottom
= outBounds
->top
+ m_height
- 2 * m_macVerticalBorder
;
193 outBounds
->right
= outBounds
->left
+ m_width
- 2 * m_macHorizontalBorder
;
195 strcpy( (char*) maclabel
, label
) ;
196 if( wxApp::s_macDefaultEncodingIsPC
)
198 wxMacConvertFromPCForControls( (char*) maclabel
) ;
201 c2pstr( (char*) maclabel
) ;
204 void wxControl::MacPostControlCreate()
206 wxASSERT_MSG( m_macControl
!= NULL
, "No valid mac control" ) ;
208 if ( IsKindOf( CLASSINFO( wxScrollBar
) ) )
212 else if ( IsKindOf( CLASSINFO( wxStaticBox
) ) )
214 ControlFontStyleRec controlstyle
;
215 controlstyle
.flags
= kControlUseFontMask
;
216 controlstyle
.font
= kControlFontSmallBoldSystemFont
;
218 ::UMASetControlFontStyle( m_macControl
, &controlstyle
) ;
222 ControlFontStyleRec controlstyle
;
223 controlstyle
.flags
= kControlUseFontMask
;
224 controlstyle
.font
= kControlFontSmallSystemFont
;
226 ::UMASetControlFontStyle( m_macControl
, &controlstyle
) ;
228 ControlHandle container
= GetParent()->MacGetContainerForEmbedding() ;
229 wxASSERT_MSG( container
!= NULL
, "No valid mac container control" ) ;
230 ::UMAEmbedControl( m_macControl
, container
) ;
231 MacAdjustControlRect() ;
232 wxAssociateControlWithMacControl( m_macControl
, this ) ;
235 void wxControl::MacAdjustControlRect()
237 wxASSERT_MSG( m_macControl
!= NULL
, "No valid mac control" ) ;
238 if ( m_width
== -1 || m_height
== -1 )
240 Rect bestsize
= { 0 , 0 , 0 , 0 } ;
241 short baselineoffset
;
243 UMAGetBestControlRect( m_macControl
, &bestsize
, &baselineoffset
) ;
245 if ( EmptyRect( &bestsize
) )
248 bestsize
.left
= bestsize
.top
= 0 ;
249 bestsize
.right
= 16 ;
250 bestsize
.bottom
= 16 ;
251 if ( IsKindOf( CLASSINFO( wxScrollBar
) ) )
253 bestsize
.bottom
= 16 ;
255 else if ( IsKindOf( CLASSINFO( wxSpinButton
) ) )
257 bestsize
.bottom
= 24 ;
263 if ( IsKindOf( CLASSINFO( wxButton
) ) )
265 m_width
= m_label
.Length() * 8 + 12 + 2 * m_macHorizontalBorder
;
267 else if ( IsKindOf( CLASSINFO( wxStaticText
) ) )
269 m_width
= m_label
.Length() * 8 ;
272 m_width
= bestsize
.right
- bestsize
.left
+ 2 * m_macHorizontalBorder
;
274 if ( m_height
== -1 )
276 m_height
= bestsize
.bottom
- bestsize
.top
;
280 m_height
+= 2 * m_macVerticalBorder
;
283 wxMacDrawingHelper
helper ( wxFindWinFromMacWindow( GetMacRootWindow() ) ) ;
286 UMASizeControl( m_macControl
, m_width
- 2 * m_macHorizontalBorder
, m_height
- 2 * m_macVerticalBorder
) ;
290 ControlHandle
wxControl::MacGetContainerForEmbedding()
293 return m_macControl
;
295 return wxWindow::MacGetContainerForEmbedding() ;
298 void wxControl::MacSuperChangedPosition()
302 int former_mac_x
= (**m_macControl
).contrlRect
.left
;
303 int former_mac_y
= (**m_macControl
).contrlRect
.top
;
306 GetParent()->MacClientToRootWindow( & mac_x
, & mac_y
) ;
308 WindowRef rootwindow
= GetMacRootWindow() ;
309 wxWindow
* wxrootwindow
= wxFindWinFromMacWindow( rootwindow
) ;
310 UMASetThemeWindowBackground( rootwindow
, kThemeBrushDialogBackgroundActive
, false ) ;
311 wxMacDrawingHelper
focus( wxrootwindow
) ;
313 if ( mac_x
!= former_mac_x
|| mac_y
!= former_mac_y
)
316 Rect inval
= { former_mac_y
, former_mac_x
, former_mac_y
+ m_height
, former_mac_x
+ m_width
} ;
317 InvalRect( &inval
) ;
319 UMAMoveControl( m_macControl
, mac_x
+ m_macHorizontalBorder
, mac_y
+ m_macVerticalBorder
) ;
321 Rect inval
= { mac_y
, mac_x
, mac_y
+ m_height
, mac_x
+ m_width
} ;
322 InvalRect( &inval
) ;
325 if ( wxrootwindow
->IsKindOf( CLASSINFO( wxDialog
) ) )
330 UMASetThemeWindowBackground( rootwindow
, kThemeBrushDocumentWindowBackground
, false ) ;
334 wxWindow::MacSuperChangedPosition() ;
337 void wxControl::MacSuperEnabled( bool enabled
)
342 if ( UMAHasAppearance() )
346 ::DeactivateControl( m_macControl ) ;
351 ::ActivateControl( m_macControl ) ;
358 ::HiliteControl( m_macControl , 255 ) ;
363 ::HiliteControl( m_macControl , 0 ) ;
367 wxWindow::MacSuperEnabled( enabled ) ;
371 void wxControl::MacSuperShown( bool show
)
378 ::UMAHideControl( m_macControl ) ;
383 ::UMAShowControl( m_macControl ) ;
387 wxWindow::MacSuperShown( show ) ;
391 void wxControl::DoSetSize(int x
, int y
,
392 int width
, int height
,
395 if ( m_macControl
== NULL
)
397 wxWindow::DoSetSize( x
, y
,width
, height
,sizeFlags
) ;
401 WindowRef rootwindow
= GetMacRootWindow() ;
402 wxWindow
* wxrootwindow
= wxFindWinFromMacWindow( rootwindow
) ;
403 UMASetThemeWindowBackground( rootwindow
, kThemeBrushDialogBackgroundActive
, false ) ;
407 int former_w
= m_width
;
408 int former_h
= m_height
;
410 int former_mac_x
= (**m_macControl
).contrlRect
.left
;
411 int former_mac_y
= (**m_macControl
).contrlRect
.top
;
413 int currentX
, currentY
;
414 GetPosition(¤tX
, ¤tY
);
415 int currentW
,currentH
;
416 GetSize(¤tW
, ¤tH
);
418 int actualWidth
= width
;
419 int actualHeight
= height
;
422 if (x
== -1 || (sizeFlags
& wxSIZE_ALLOW_MINUS_ONE
))
424 if (y
== -1 || (sizeFlags
& wxSIZE_ALLOW_MINUS_ONE
))
427 actualWidth
= currentW
;
429 actualHeight
= currentH
;
431 if ( actualX
== currentX
&& actualY
== currentY
&& actualWidth
== currentW
&& actualHeight
== currentH
)
434 AdjustForParentClientOrigin(actualX
, actualY
, sizeFlags
);
435 wxMacDrawingHelper
focus( wxFindWinFromMacWindow( GetMacRootWindow() ) ) ;
437 int mac_x
= actualX
;
438 int mac_y
= actualY
;
439 GetParent()->MacClientToRootWindow( & mac_x
, & mac_y
) ;
441 if ( mac_x
!= former_mac_x
|| mac_y
!= former_mac_y
)
444 Rect inval
= { former_mac_y
, former_mac_x
, former_mac_y
+ m_height
, former_mac_x
+ m_width
} ;
445 InvalRect( &inval
) ;
447 UMAMoveControl( m_macControl
, mac_x
+ m_macHorizontalBorder
, mac_y
+ m_macVerticalBorder
) ;
449 Rect inval
= { mac_y
, mac_x
, mac_y
+ m_height
, mac_x
+ m_width
} ;
450 InvalRect( &inval
) ;
454 if ( actualX
!= former_x
|| actualY
!= former_y
)
459 MacRepositionScrollBars() ;
460 // To consider -> should the parameters be the effective or the virtual coordinates (AdjustForParent..)
461 wxMoveEvent
event(wxPoint(m_x
, m_y
), m_windowId
);
462 event
.SetEventObject(this);
463 GetEventHandler()->ProcessEvent(event
);
465 if ( actualWidth
!= former_w
|| actualHeight
!= former_h
)
468 Rect inval
= { mac_y
, mac_x
, mac_y
+ former_h
, mac_x
+ former_w
} ;
469 InvalRect( &inval
) ;
471 m_width
= actualWidth
;
472 m_height
= actualHeight
;
474 UMASizeControl( m_macControl
, m_width
- 2 * m_macHorizontalBorder
, m_height
- 2 * m_macVerticalBorder
) ;
476 Rect inval
= { mac_y
, mac_x
, mac_y
+ m_height
, mac_x
+ m_width
} ;
477 InvalRect( &inval
) ;
480 MacRepositionScrollBars() ;
481 wxSizeEvent
event(wxSize(m_width
, m_height
), m_windowId
);
482 event
.SetEventObject(this);
483 GetEventHandler()->ProcessEvent(event
);
485 if ( wxrootwindow
->IsKindOf( CLASSINFO( wxDialog
) ) )
490 UMASetThemeWindowBackground( rootwindow
, kThemeBrushDocumentWindowBackground
, false ) ;
494 bool wxControl::Show(bool show
)
496 if ( !wxWindow::Show( show
) )
502 ::UMAShowControl( m_macControl
) ;
504 ::UMAHideControl( m_macControl
) ;
509 bool wxControl::Enable(bool enable
)
511 if ( !wxWindow::Enable(enable
) )
517 if ( UMAHasAppearance() )
520 ::ActivateControl( m_macControl
) ;
522 ::DeactivateControl( m_macControl
) ;
527 ::HiliteControl( m_macControl
, 0 ) ;
529 ::HiliteControl( m_macControl
, 255 ) ;
535 void wxControl::Refresh(bool eraseBack
, const wxRect
*rect
)
539 wxWindow::Refresh( eraseBack
, rect
) ;
543 wxWindow::Refresh( eraseBack
, rect
) ;
547 void wxControl::OnPaint(wxPaintEvent
& event
)
551 WindowRef window
= GetMacRootWindow() ;
554 wxWindow
* win
= wxFindWinFromMacWindow( window
) ;
557 wxMacDrawingHelper
help( win
) ;
560 bool hasTabBehind
= false ;
561 wxWindow
* parent
= GetParent() ;
564 if( parent
->MacGetWindowData() )
566 UMASetThemeWindowBackground( win
->MacGetWindowData()->m_macWindow
, kThemeBrushDialogBackgroundActive
, false ) ;
570 if( parent
->IsKindOf( CLASSINFO( wxNotebook
) ) || parent
->IsKindOf( CLASSINFO( wxTabCtrl
) ))
572 if ( ((wxControl
*)parent
)->m_macControl
)
573 SetUpControlBackground( ((wxControl
*)parent
)->m_macControl
, -1 , true ) ;
577 parent
= parent
->GetParent() ;
580 UMADrawControl( m_macControl
) ;
581 UMASetThemeWindowBackground( win
->MacGetWindowData()->m_macWindow
, win
->MacGetWindowData()->m_macWindowBackgroundTheme
, false ) ;
587 // wxWindow::OnPaint( event ) ;
590 void wxControl::OnEraseBackground(wxEraseEvent
& event
)
592 // In general, you don't want to erase the background of a control,
593 // or you'll get a flicker.
594 // TODO: move this 'null' function into each control that
599 void wxControl::OnKeyDown( wxKeyEvent
&event
)
601 if ( m_macControl
== NULL
)
604 EventRecord
*ev
= wxTheApp
->MacGetCurrentEvent() ;
607 keychar
= short(ev
->message
& charCodeMask
);
608 keycode
= short(ev
->message
& keyCodeMask
) >> 8 ;
610 UMAHandleControlKey( m_macControl
, keycode
, keychar
, ev
->modifiers
) ;
613 void wxControl::OnMouseEvent( wxMouseEvent
&event
)
615 if ( m_macControl
== NULL
)
621 if (event
.GetEventType() == wxEVT_LEFT_DOWN
)
627 MacClientToRootWindow( &x
, &y
) ;
629 ControlHandle control
;
633 WindowRef window
= GetMacRootWindow() ;
640 if ( !event
.m_leftDown
&& !event
.m_rightDown
)
641 modifiers
|= btnState
;
643 if ( event
.m_shiftDown
)
644 modifiers
|= shiftKey
;
646 if ( event
.m_controlDown
)
647 modifiers
|= controlKey
;
649 if ( event
.m_altDown
)
650 modifiers
|= optionKey
;
652 if ( event
.m_metaDown
)
653 modifiers
|= cmdKey
;
655 controlpart
= FindControl( localwhere
, window
, &control
) ;
657 if ( AcceptsFocus() && FindFocus() != this )
661 if ( control
&& UMAIsControlActive( control
) )
664 if ( controlpart
== kControlIndicatorPart
&& !UMAHasAppearance() )
665 controlpart
= UMAHandleControlClick( control
, localwhere
, modifiers
, (ControlActionUPP
) NULL
) ;
667 controlpart
= UMAHandleControlClick( control
, localwhere
, modifiers
, (ControlActionUPP
) -1 ) ;
668 wxTheApp
->s_lastMouseDown
= 0 ;
669 if ( controlpart
&& ! ( ( UMAHasAppearance() || (controlpart
!= kControlIndicatorPart
) )
670 && (IsKindOf( CLASSINFO( wxScrollBar
) ) ) ) ) // otherwise we will get the event twice
672 MacHandleControlClick( control
, controlpart
) ;
680 bool wxControl::MacCanFocus() const
682 { if ( m_macControl
== NULL
)
689 void wxControl::MacHandleControlClick( ControlHandle control
, SInt16 controlpart
)
691 wxASSERT_MSG( m_macControl
!= NULL
, "No valid mac control" ) ;