1 /////////////////////////////////////////////////////////////////////////////
3 // Purpose: wxControl class
8 // Copyright: (c) AUTHOR
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
13 #pragma implementation "control.h"
16 #include "wx/control.h"
20 #include "wx/notebook.h"
21 #include "wx/tabctrl.h"
22 #include "wx/radiobox.h"
23 #include "wx/spinbutt.h"
24 #include "wx/scrolbar.h"
25 #include "wx/button.h"
26 #include "wx/dialog.h"
27 #include "wx/statbox.h"
29 #include "wx/stattext.h"
31 #if !USE_SHARED_LIBRARY
32 IMPLEMENT_ABSTRACT_CLASS(wxControl
, wxWindow
)
34 BEGIN_EVENT_TABLE(wxControl
, wxWindow
)
35 EVT_MOUSE_EVENTS( wxControl::OnMouseEvent
)
36 EVT_CHAR( wxControl::OnKeyDown
)
37 EVT_PAINT( wxControl::OnPaint
)
41 #include <wx/mac/uma.h>
45 ControlActionUPP wxMacLiveScrollbarActionUPP
= NULL
;
47 pascal void wxMacLiveScrollbarActionProc( ControlHandle control
, ControlPartCode partCode
) ;
48 pascal void wxMacLiveScrollbarActionProc( ControlHandle control
, ControlPartCode partCode
)
52 wxControl
* wx
= (wxControl
*) GetControlReference( control
) ;
55 wx
->MacHandleControlClick( control
, partCode
) ;
60 wxControl::wxControl()
63 m_macHorizontalBorder
= 0 ; // additional pixels around the real control
64 m_macVerticalBorder
= 0 ;
65 m_backgroundColour
= *wxWHITE
;
66 m_foregroundColour
= *wxBLACK
;
67 #if WXWIN_COMPATIBILITY
69 #endif // WXWIN_COMPATIBILITY
71 if ( wxMacLiveScrollbarActionUPP
== NULL
)
74 wxMacLiveScrollbarActionUPP
= NewControlActionUPP( wxMacLiveScrollbarActionProc
);
76 wxMacLiveScrollbarActionUPP
= NewControlActionProc( wxMacLiveScrollbarActionProc
) ;
81 bool wxControl::Create(wxWindow
*parent
, wxWindowID id
,
83 const wxSize
& size
, long style
,
84 const wxValidator
& validator
,
88 m_macHorizontalBorder
= 0 ; // additional pixels around the real control
89 m_macVerticalBorder
= 0 ;
90 bool rval
= wxWindow::Create(parent
, id
, pos
, size
, style
, name
);
93 SetValidator(validator
);
99 wxControl::~wxControl()
101 m_isBeingDeleted
= TRUE
;
102 // If we delete an item, we should initialize the parent panel,
103 // because it could now be invalid.
104 wxPanel
*panel
= wxDynamicCast(GetParent(), wxPanel
);
107 if (panel
->GetDefaultItem() == (wxButton
*) this)
108 panel
->SetDefaultItem(NULL
);
112 UMADisposeControl( m_macControl
) ;
113 m_macControl
= NULL
;
117 void wxControl::SetLabel(const wxString
& title
)
126 if( wxApp::s_macDefaultEncodingIsPC
)
127 label
= wxMacMakeMacStringFromPC( title
) ;
132 c2pstrcpy( (StringPtr
) maclabel
, label
) ;
134 strcpy( (char *) maclabel
, label
) ;
135 c2pstr( (char *) maclabel
) ;
137 ::SetControlTitle( m_macControl
, maclabel
) ;
141 wxSize
wxControl::DoGetBestSize() const
143 return wxSize(20, 20);
146 bool wxControl::ProcessCommand (wxCommandEvent
& event
)
149 // 1) A callback function (to become obsolete)
150 // 2) OnCommand, starting at this window and working up parent hierarchy
151 // 3) OnCommand then calls ProcessEvent to search the event tables.
152 #if WXWIN_COMPATIBILITY
155 (void)(*m_callback
)(this, event
);
160 #endif // WXWIN_COMPATIBILITY
162 return GetEventHandler()->ProcessEvent(event
);
166 // ------------------------
167 wxList
*wxWinMacControlList
= NULL
;
168 wxControl
*wxFindControlFromMacControl(ControlHandle inControl
)
170 wxNode
*node
= wxWinMacControlList
->Find((long)inControl
);
173 return (wxControl
*)node
->Data();
176 void wxAssociateControlWithMacControl(ControlHandle inControl
, wxControl
*control
)
178 // adding NULL WindowRef is (first) surely a result of an error and
179 // (secondly) breaks menu command processing
180 wxCHECK_RET( inControl
!= (ControlHandle
) NULL
, "attempt to add a NULL WindowRef to window list" );
182 if ( !wxWinMacControlList
->Find((long)inControl
) )
183 wxWinMacControlList
->Append((long)inControl
, control
);
186 void wxRemoveMacControlAssociation(wxControl
*control
)
188 wxWinMacControlList
->DeleteObject(control
);
191 void wxControl::MacPreControlCreate( wxWindow
*parent
, wxWindowID id
, wxString label
,
193 const wxSize
& size
, long style
,
194 const wxValidator
& validator
,
195 const wxString
& name
, Rect
*outBounds
, StringPtr maclabel
)
200 SetValidator(validator
);
202 m_windowStyle
= style
;
203 parent
->AddChild((wxButton
*)this);
205 m_backgroundColour
= parent
->GetBackgroundColour() ;
206 m_foregroundColour
= parent
->GetForegroundColour() ;
209 m_windowId
= NewControlId();
217 AdjustForParentClientOrigin(x
, y
, wxSIZE_USE_EXISTING
);
222 parent
->MacClientToRootWindow( &x
, &y
) ;
223 outBounds
->top
= y
+ m_macVerticalBorder
;
224 outBounds
->left
= x
+ m_macHorizontalBorder
;
225 outBounds
->bottom
= outBounds
->top
+ m_height
- 2 * m_macVerticalBorder
;
226 outBounds
->right
= outBounds
->left
+ m_width
- 2 * m_macHorizontalBorder
;
229 strcpy( c_text
, label
) ;
230 if( wxApp::s_macDefaultEncodingIsPC
)
232 wxMacConvertFromPCForControls( c_text
) ;
236 c2pstrcpy( (StringPtr
) maclabel
, c_text
) ;
238 strcpy( (char *) maclabel
, c_text
) ;
239 c2pstr( (char *) maclabel
) ;
243 void wxControl::MacPostControlCreate()
245 wxASSERT_MSG( m_macControl
!= NULL
, "No valid mac control" ) ;
247 if ( IsKindOf( CLASSINFO( wxScrollBar
) ) )
251 else if ( IsKindOf( CLASSINFO( wxStaticBox
) ) || IsKindOf( CLASSINFO( wxRadioBox
) ) || IsKindOf( CLASSINFO( wxButton
) ) )
253 ControlFontStyleRec controlstyle
;
254 controlstyle
.flags
= kControlUseFontMask
;
255 controlstyle
.font
= kControlFontSmallBoldSystemFont
;
257 ::UMASetControlFontStyle( m_macControl
, &controlstyle
) ;
261 ControlFontStyleRec controlstyle
;
262 controlstyle
.flags
= kControlUseFontMask
;
263 controlstyle
.font
= kControlFontSmallSystemFont
;
265 ::UMASetControlFontStyle( m_macControl
, &controlstyle
) ;
267 ControlHandle container
= GetParent()->MacGetContainerForEmbedding() ;
268 wxASSERT_MSG( container
!= NULL
, "No valid mac container control" ) ;
269 ::UMAEmbedControl( m_macControl
, container
) ;
270 m_macControlIsShown
= true ;
271 MacAdjustControlRect() ;
272 wxAssociateControlWithMacControl( m_macControl
, this ) ;
275 void wxControl::MacAdjustControlRect()
277 wxASSERT_MSG( m_macControl
!= NULL
, "No valid mac control" ) ;
278 if ( m_width
== -1 || m_height
== -1 )
280 Rect bestsize
= { 0 , 0 , 0 , 0 } ;
281 short baselineoffset
;
283 UMAGetBestControlRect( m_macControl
, &bestsize
, &baselineoffset
) ;
285 if ( EmptyRect( &bestsize
) )
288 bestsize
.left
= bestsize
.top
= 0 ;
289 bestsize
.right
= 16 ;
290 bestsize
.bottom
= 16 ;
291 if ( IsKindOf( CLASSINFO( wxScrollBar
) ) )
293 bestsize
.bottom
= 16 ;
295 else if ( IsKindOf( CLASSINFO( wxSpinButton
) ) )
297 bestsize
.bottom
= 24 ;
303 if ( IsKindOf( CLASSINFO( wxButton
) ) )
305 m_width
= m_label
.Length() * 8 + 12 ;
307 else if ( IsKindOf( CLASSINFO( wxStaticText
) ) )
309 m_width
= m_label
.Length() * 8 ;
312 m_width
= bestsize
.right
- bestsize
.left
;
314 m_width
+= 2 * m_macHorizontalBorder
;
316 if ( m_height
== -1 )
318 m_height
= bestsize
.bottom
- bestsize
.top
;
322 m_height
+= 2 * m_macVerticalBorder
;
325 wxMacDrawingHelper
helper ( wxFindWinFromMacWindow( GetMacRootWindow() ) ) ;
328 UMASizeControl( m_macControl
, m_width
- 2 * m_macHorizontalBorder
, m_height
- 2 * m_macVerticalBorder
) ;
332 ControlHandle
wxControl::MacGetContainerForEmbedding()
335 return m_macControl
;
337 return wxWindow::MacGetContainerForEmbedding() ;
340 void wxControl::MacSuperChangedPosition()
345 GetControlBounds( m_macControl
, &contrlRect
) ;
346 int former_mac_x
= contrlRect
.left
;
347 int former_mac_y
= contrlRect
.top
;
350 GetParent()->MacClientToRootWindow( & mac_x
, & mac_y
) ;
352 WindowRef rootwindow
= GetMacRootWindow() ;
353 wxWindow
* wxrootwindow
= wxFindWinFromMacWindow( rootwindow
) ;
354 UMASetThemeWindowBackground( rootwindow
, kThemeBrushDialogBackgroundActive
, false ) ;
355 wxMacDrawingHelper
focus( wxrootwindow
) ;
357 if ( mac_x
!= former_mac_x
|| mac_y
!= former_mac_y
)
360 Rect inval
= { former_mac_y
, former_mac_x
, former_mac_y
+ m_height
, former_mac_x
+ m_width
} ;
361 InvalWindowRect( rootwindow
, &inval
) ;
363 UMAMoveControl( m_macControl
, mac_x
+ m_macHorizontalBorder
, mac_y
+ m_macVerticalBorder
) ;
365 Rect inval
= { mac_y
, mac_x
, mac_y
+ m_height
, mac_x
+ m_width
} ;
366 InvalWindowRect( rootwindow
, &inval
) ;
369 if ( wxrootwindow
->IsKindOf( CLASSINFO( wxDialog
) ) )
374 UMASetThemeWindowBackground( rootwindow
, kThemeBrushDocumentWindowBackground
, false ) ;
378 wxWindow::MacSuperChangedPosition() ;
381 void wxControl::MacSuperEnabled( bool enabled
)
386 if ( UMAHasAppearance() )
390 ::DeactivateControl( m_macControl ) ;
395 ::ActivateControl( m_macControl ) ;
402 ::HiliteControl( m_macControl , 255 ) ;
407 ::HiliteControl( m_macControl , 0 ) ;
411 wxWindow::MacSuperEnabled( enabled ) ;
415 void wxControl::MacSuperShown( bool show
)
421 if ( m_macControlIsShown
)
423 ::UMAHideControl( m_macControl
) ;
424 m_macControlIsShown
= false ;
429 if ( MacIsReallyShown() && !m_macControlIsShown
)
431 ::UMAShowControl( m_macControl
) ;
432 m_macControlIsShown
= true ;
437 wxWindow::MacSuperShown( show
) ;
440 void wxControl::DoSetSize(int x
, int y
,
441 int width
, int height
,
444 if ( m_macControl
== NULL
)
446 wxWindow::DoSetSize( x
, y
,width
, height
,sizeFlags
) ;
450 WindowRef rootwindow
= GetMacRootWindow() ;
451 wxWindow
* wxrootwindow
= wxFindWinFromMacWindow( rootwindow
) ;
452 UMASetThemeWindowBackground( rootwindow
, kThemeBrushDialogBackgroundActive
, false ) ;
456 int former_w
= m_width
;
457 int former_h
= m_height
;
460 GetControlBounds( m_macControl
, &contrlRect
) ;
461 int former_mac_x
= contrlRect
.left
;
462 int former_mac_y
= contrlRect
.top
;
464 int currentX
, currentY
;
465 GetPosition(¤tX
, ¤tY
);
466 int currentW
,currentH
;
467 GetSize(¤tW
, ¤tH
);
469 int actualWidth
= width
;
470 int actualHeight
= height
;
473 if (x
== -1 && !(sizeFlags
& wxSIZE_ALLOW_MINUS_ONE
))
475 if (y
== -1 && !(sizeFlags
& wxSIZE_ALLOW_MINUS_ONE
))
478 actualWidth
= currentW
;
480 actualHeight
= currentH
;
482 if ( actualX
== currentX
&& actualY
== currentY
&& actualWidth
== currentW
&& actualHeight
== currentH
)
485 AdjustForParentClientOrigin(actualX
, actualY
, sizeFlags
);
486 WindowRef macrootwindow
= GetMacRootWindow() ;
487 wxMacDrawingHelper
focus( wxFindWinFromMacWindow( macrootwindow
) ) ;
489 int mac_x
= actualX
;
490 int mac_y
= actualY
;
491 GetParent()->MacClientToRootWindow( & mac_x
, & mac_y
) ;
493 if ( mac_x
!= former_mac_x
|| mac_y
!= former_mac_y
)
496 Rect inval
= { former_mac_y
, former_mac_x
, former_mac_y
+ m_height
, former_mac_x
+ m_width
} ;
497 InvalWindowRect( macrootwindow
, &inval
) ;
499 UMAMoveControl( m_macControl
, mac_x
+ m_macHorizontalBorder
, mac_y
+ m_macVerticalBorder
) ;
501 Rect inval
= { mac_y
, mac_x
, mac_y
+ m_height
, mac_x
+ m_width
} ;
502 InvalWindowRect(macrootwindow
, &inval
) ;
506 if ( actualX
!= former_x
|| actualY
!= former_y
)
511 MacRepositionScrollBars() ;
512 // To consider -> should the parameters be the effective or the virtual coordinates (AdjustForParent..)
513 wxMoveEvent
event(wxPoint(m_x
, m_y
), m_windowId
);
514 event
.SetEventObject(this);
515 GetEventHandler()->ProcessEvent(event
);
517 if ( actualWidth
!= former_w
|| actualHeight
!= former_h
)
520 Rect inval
= { mac_y
, mac_x
, mac_y
+ former_h
, mac_x
+ former_w
} ;
521 InvalWindowRect( macrootwindow
, &inval
) ;
523 m_width
= actualWidth
;
524 m_height
= actualHeight
;
526 UMASizeControl( m_macControl
, m_width
- 2 * m_macHorizontalBorder
, m_height
- 2 * m_macVerticalBorder
) ;
528 Rect inval
= { mac_y
, mac_x
, mac_y
+ m_height
, mac_x
+ m_width
} ;
529 InvalWindowRect( macrootwindow
, &inval
) ;
532 MacRepositionScrollBars() ;
533 wxSizeEvent
event(wxSize(m_width
, m_height
), m_windowId
);
534 event
.SetEventObject(this);
535 GetEventHandler()->ProcessEvent(event
);
537 if ( wxrootwindow
->IsKindOf( CLASSINFO( wxDialog
) ) )
542 UMASetThemeWindowBackground( rootwindow
, kThemeBrushDocumentWindowBackground
, false ) ;
546 bool wxControl::Show(bool show
)
548 if ( !wxWindow::Show( show
) )
555 if ( m_macControlIsShown
)
557 ::UMAHideControl( m_macControl
) ;
558 m_macControlIsShown
= false ;
563 if ( MacIsReallyShown() && !m_macControlIsShown
)
565 ::UMAShowControl( m_macControl
) ;
566 m_macControlIsShown
= true ;
573 bool wxControl::Enable(bool enable
)
575 if ( !wxWindow::Enable(enable
) )
581 if ( UMAHasAppearance() )
584 ::ActivateControl( m_macControl
) ;
586 ::DeactivateControl( m_macControl
) ;
591 ::HiliteControl( m_macControl
, 0 ) ;
593 ::HiliteControl( m_macControl
, 255 ) ;
599 void wxControl::Refresh(bool eraseBack
, const wxRect
*rect
)
603 wxWindow::Refresh( eraseBack
, rect
) ;
607 wxWindow::Refresh( eraseBack
, rect
) ;
611 void wxControl::MacRedrawControl()
615 WindowRef window
= GetMacRootWindow() ;
618 wxWindow
* win
= wxFindWinFromMacWindow( window
) ;
621 wxMacDrawingHelper
help( win
) ;
622 // the mac control manager always assumes to have the origin at 0,0
625 bool hasTabBehind
= false ;
626 wxWindow
* parent
= GetParent() ;
629 if( parent
->MacGetWindowData() )
631 UMASetThemeWindowBackground( win
->MacGetWindowData()->m_macWindow
, kThemeBrushDialogBackgroundActive
, false ) ;
635 if( parent
->IsKindOf( CLASSINFO( wxNotebook
) ) || parent
->IsKindOf( CLASSINFO( wxTabCtrl
) ))
637 if ( ((wxControl
*)parent
)->m_macControl
)
638 SetUpControlBackground( ((wxControl
*)parent
)->m_macControl
, -1 , true ) ;
642 parent
= parent
->GetParent() ;
645 UMADrawControl( m_macControl
) ;
646 UMASetThemeWindowBackground( win
->MacGetWindowData()->m_macWindow
, win
->MacGetWindowData()->m_macWindowBackgroundTheme
, false ) ;
647 wxDC::MacInvalidateSetup() ;
653 void wxControl::OnPaint(wxPaintEvent
& event
)
657 WindowRef window
= GetMacRootWindow() ;
660 wxWindow
* win
= wxFindWinFromMacWindow( window
) ;
663 wxMacDrawingHelper
help( win
) ;
664 // the mac control manager always assumes to have the origin at 0,0
667 bool hasTabBehind
= false ;
668 wxWindow
* parent
= GetParent() ;
671 if( parent
->MacGetWindowData() )
673 UMASetThemeWindowBackground( win
->MacGetWindowData()->m_macWindow
, kThemeBrushDialogBackgroundActive
, false ) ;
677 if( parent
->IsKindOf( CLASSINFO( wxNotebook
) ) || parent
->IsKindOf( CLASSINFO( wxTabCtrl
) ))
679 if ( ((wxControl
*)parent
)->m_macControl
)
680 SetUpControlBackground( ((wxControl
*)parent
)->m_macControl
, -1 , true ) ;
684 parent
= parent
->GetParent() ;
687 UMADrawControl( m_macControl
) ;
688 UMASetThemeWindowBackground( win
->MacGetWindowData()->m_macWindow
, win
->MacGetWindowData()->m_macWindowBackgroundTheme
, false ) ;
689 wxDC::MacInvalidateSetup() ;
695 // wxWindow::OnPaint( event ) ;
698 void wxControl::OnEraseBackground(wxEraseEvent
& event
)
700 // In general, you don't want to erase the background of a control,
701 // or you'll get a flicker.
702 // TODO: move this 'null' function into each control that
707 void wxControl::OnKeyDown( wxKeyEvent
&event
)
709 if ( m_macControl
== NULL
)
712 EventRecord
*ev
= wxTheApp
->MacGetCurrentEvent() ;
715 keychar
= short(ev
->message
& charCodeMask
);
716 keycode
= short(ev
->message
& keyCodeMask
) >> 8 ;
718 UMAHandleControlKey( m_macControl
, keycode
, keychar
, ev
->modifiers
) ;
721 void wxControl::OnMouseEvent( wxMouseEvent
&event
)
723 if ( m_macControl
== NULL
)
729 if (event
.GetEventType() == wxEVT_LEFT_DOWN
|| event
.GetEventType() == wxEVT_LEFT_DCLICK
)
735 MacClientToRootWindow( &x
, &y
) ;
737 ControlHandle control
;
741 WindowRef window
= GetMacRootWindow() ;
748 if ( !event
.m_leftDown
&& !event
.m_rightDown
)
749 modifiers
|= btnState
;
751 if ( event
.m_shiftDown
)
752 modifiers
|= shiftKey
;
754 if ( event
.m_controlDown
)
755 modifiers
|= controlKey
;
757 if ( event
.m_altDown
)
758 modifiers
|= optionKey
;
760 if ( event
.m_metaDown
)
761 modifiers
|= cmdKey
;
763 controlpart
= FindControl( localwhere
, window
, &control
) ;
766 if ( AcceptsFocus() && FindFocus() != this )
771 if ( control
&& UMAIsControlActive( control
) )
774 if ( controlpart
== kControlIndicatorPart
&& !UMAHasAppearance() )
775 controlpart
= UMAHandleControlClick( control
, localwhere
, modifiers
, (ControlActionUPP
) NULL
) ;
777 controlpart
= UMAHandleControlClick( control
, localwhere
, modifiers
, (ControlActionUPP
) -1 ) ;
778 wxTheApp
->s_lastMouseDown
= 0 ;
779 if ( controlpart
&& ! ( ( UMAHasAppearance() || (controlpart
!= kControlIndicatorPart
) )
780 && (IsKindOf( CLASSINFO( wxScrollBar
) ) ) ) ) // otherwise we will get the event twice
782 MacHandleControlClick( control
, controlpart
) ;
790 bool wxControl::MacCanFocus() const
792 { if ( m_macControl
== NULL
)
799 void wxControl::MacHandleControlClick( ControlHandle control
, SInt16 controlpart
)
801 wxASSERT_MSG( m_macControl
!= NULL
, "No valid mac control" ) ;