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
;
58 if ( wxMacLiveScrollbarActionUPP
== NULL
)
60 wxMacLiveScrollbarActionUPP
= NewControlActionProc( wxMacLiveScrollbarActionProc
) ;
64 wxControl::~wxControl()
66 // If we delete an item, we should initialize the parent panel,
67 // because it could now be invalid.
68 wxWindow
*parent
= (wxWindow
*)GetParent();
71 if (parent
->GetDefaultItem() == (wxButton
*) this)
72 parent
->SetDefaultItem(NULL
);
76 UMADisposeControl( m_macControl
) ;
81 void wxControl::SetLabel(const wxString
& label
)
89 strcpy( (char*) maclabel
, label
) ;
90 c2pstr( (char*) maclabel
) ;
92 ::SetControlTitle( m_macControl
, maclabel
) ;
96 wxString
wxControl::GetLabel() const
101 void wxControl::ProcessCommand (wxCommandEvent
& event
)
104 // 1) A callback function (to become obsolete)
105 // 2) OnCommand, starting at this window and working up parent hierarchy
106 // 3) OnCommand then calls ProcessEvent to search the event tables.
109 (void) (*(m_callback
)) (*this, event
);
113 GetEventHandler()->OnCommand(*this, event
);
117 void wxControl::Centre (int direction
)
119 int x
, y
, width
, height
, panel_width
, panel_height
, new_x
, new_y
;
121 wxWindow
*parent
= (wxWindow
*) GetParent ();
125 parent
->GetClientSize (&panel_width
, &panel_height
);
126 GetSize (&width
, &height
);
127 GetPosition (&x
, &y
);
132 if (direction
& wxHORIZONTAL
)
133 new_x
= (int) ((panel_width
- width
) / 2);
135 if (direction
& wxVERTICAL
)
136 new_y
= (int) ((panel_height
- height
) / 2);
138 SetSize (new_x
, new_y
, width
, height
);
141 void wxControl::SetClientSize (int width
, int height
)
143 SetSize (-1, -1, width
, height
);
146 // ------------------------
147 wxList
*wxWinMacControlList
= NULL
;
148 wxControl
*wxFindControlFromMacControl(ControlHandle inControl
)
150 wxNode
*node
= wxWinMacControlList
->Find((long)inControl
);
153 return (wxControl
*)node
->Data();
156 void wxAssociateControlWithMacControl(ControlHandle inControl
, wxControl
*control
)
158 // adding NULL WindowRef is (first) surely a result of an error and
159 // (secondly) breaks menu command processing
160 wxCHECK_RET( inControl
!= (ControlHandle
) NULL
, "attempt to add a NULL WindowRef to window list" );
162 if ( !wxWinMacControlList
->Find((long)inControl
) )
163 wxWinMacControlList
->Append((long)inControl
, control
);
166 void wxRemoveMacControlAssociation(wxControl
*control
)
168 wxWinMacControlList
->DeleteObject(control
);
171 void wxControl::MacPreControlCreate( wxWindow
*parent
, wxWindowID id
, wxString label
,
173 const wxSize
& size
, long style
,
174 const wxValidator
& validator
,
175 const wxString
& name
, Rect
*outBounds
, StringPtr maclabel
)
180 SetValidator(validator
);
182 m_windowStyle
= style
;
183 parent
->AddChild((wxButton
*)this);
185 m_backgroundColour
= parent
->GetBackgroundColour() ;
186 m_foregroundColour
= parent
->GetForegroundColour() ;
189 m_windowId
= NewControlId();
197 AdjustForParentClientOrigin(x
, y
, wxSIZE_USE_EXISTING
);
205 parent
->MacClientToRootWindow( &x
, &y
) ;
206 outBounds
->top
= y
+ m_macVerticalBorder
;
207 outBounds
->left
= x
+ m_macHorizontalBorder
;
208 outBounds
->bottom
= outBounds
->top
+ m_height
- 2 * m_macVerticalBorder
;
209 outBounds
->right
= outBounds
->left
+ m_width
- 2 * m_macHorizontalBorder
;
211 strcpy( (char*) maclabel
, label
) ;
212 if( wxApp::s_macDefaultEncodingIsPC
)
214 wxMacConvertFromPCForControls( (char*) maclabel
) ;
217 c2pstr( (char*) maclabel
) ;
220 void wxControl::MacPostControlCreate()
222 wxASSERT_MSG( m_macControl
!= NULL
, "No valid mac control" ) ;
224 if ( IsKindOf( CLASSINFO( wxScrollBar
) ) )
228 else if ( IsKindOf( CLASSINFO( wxStaticBox
) ) )
230 ControlFontStyleRec controlstyle
;
231 controlstyle
.flags
= kControlUseFontMask
;
232 controlstyle
.font
= kControlFontSmallBoldSystemFont
;
234 ::UMASetControlFontStyle( m_macControl
, &controlstyle
) ;
238 ControlFontStyleRec controlstyle
;
239 controlstyle
.flags
= kControlUseFontMask
;
240 controlstyle
.font
= kControlFontSmallSystemFont
;
242 ::UMASetControlFontStyle( m_macControl
, &controlstyle
) ;
244 ControlHandle container
= GetParent()->MacGetContainerForEmbedding() ;
245 wxASSERT_MSG( container
!= NULL
, "No valid mac container control" ) ;
246 ::UMAEmbedControl( m_macControl
, container
) ;
247 MacAdjustControlRect() ;
248 wxAssociateControlWithMacControl( m_macControl
, this ) ;
251 void wxControl::MacAdjustControlRect()
253 wxASSERT_MSG( m_macControl
!= NULL
, "No valid mac control" ) ;
254 if ( m_width
== -1 || m_height
== -1 )
256 Rect bestsize
= { 0 , 0 , 0 , 0 } ;
257 short baselineoffset
;
259 UMAGetBestControlRect( m_macControl
, &bestsize
, &baselineoffset
) ;
261 if ( EmptyRect( &bestsize
) )
264 bestsize
.left
= bestsize
.top
= 0 ;
265 bestsize
.right
= 16 ;
266 bestsize
.bottom
= 16 ;
267 if ( IsKindOf( CLASSINFO( wxScrollBar
) ) )
269 bestsize
.bottom
= 16 ;
271 else if ( IsKindOf( CLASSINFO( wxSpinButton
) ) )
273 bestsize
.bottom
= 24 ;
279 if ( IsKindOf( CLASSINFO( wxButton
) ) )
281 m_width
= m_label
.Length() * 8 + 12 + 2 * m_macHorizontalBorder
;
283 else if ( IsKindOf( CLASSINFO( wxStaticText
) ) )
285 m_width
= m_label
.Length() * 8 ;
288 m_width
= bestsize
.right
- bestsize
.left
+ 2 * m_macHorizontalBorder
;
290 if ( m_height
== -1 )
292 m_height
= bestsize
.bottom
- bestsize
.top
;
296 m_height
+= 2 * m_macVerticalBorder
;
299 wxMacDrawingHelper
helper ( wxFindWinFromMacWindow( GetMacRootWindow() ) ) ;
302 UMASizeControl( m_macControl
, m_width
- 2 * m_macHorizontalBorder
, m_height
- 2 * m_macVerticalBorder
) ;
306 ControlHandle
wxControl::MacGetContainerForEmbedding()
309 return m_macControl
;
311 return wxWindow::MacGetContainerForEmbedding() ;
314 void wxControl::MacSuperChangedPosition()
318 int former_mac_x
= (**m_macControl
).contrlRect
.left
;
319 int former_mac_y
= (**m_macControl
).contrlRect
.top
;
322 GetParent()->MacClientToRootWindow( & mac_x
, & mac_y
) ;
324 WindowRef rootwindow
= GetMacRootWindow() ;
325 wxWindow
* wxrootwindow
= wxFindWinFromMacWindow( rootwindow
) ;
326 UMASetThemeWindowBackground( rootwindow
, kThemeBrushDialogBackgroundActive
, false ) ;
327 wxMacDrawingHelper
focus( wxrootwindow
) ;
329 if ( mac_x
!= former_mac_x
|| mac_y
!= former_mac_y
)
332 Rect inval
= { former_mac_y
, former_mac_x
, former_mac_y
+ m_height
, former_mac_x
+ m_width
} ;
333 InvalRect( &inval
) ;
335 UMAMoveControl( m_macControl
, mac_x
+ m_macHorizontalBorder
, mac_y
+ m_macVerticalBorder
) ;
337 Rect inval
= { mac_y
, mac_x
, mac_y
+ m_height
, mac_x
+ m_width
} ;
338 InvalRect( &inval
) ;
341 if ( wxrootwindow
->IsKindOf( CLASSINFO( wxDialog
) ) )
346 UMASetThemeWindowBackground( rootwindow
, kThemeBrushDocumentWindowBackground
, false ) ;
350 wxWindow::MacSuperChangedPosition() ;
353 void wxControl::MacSuperEnabled( bool enabled
)
357 if ( UMAHasAppearance() )
361 ::DeactivateControl( m_macControl
) ;
366 ::ActivateControl( m_macControl
) ;
373 ::HiliteControl( m_macControl
, 255 ) ;
378 ::HiliteControl( m_macControl
, 0 ) ;
382 wxWindow::MacSuperEnabled( enabled
) ;
385 void wxControl::MacSuperShown( bool show
)
391 ::UMAHideControl( m_macControl
) ;
396 ::UMAShowControl( m_macControl
) ;
400 wxWindow::MacSuperShown( show
) ;
403 void wxControl::DoSetSize(int x
, int y
,
404 int width
, int height
,
407 if ( m_macControl
== NULL
)
409 wxWindow::DoSetSize( x
, y
,width
, height
,sizeFlags
) ;
413 WindowRef rootwindow
= GetMacRootWindow() ;
414 wxWindow
* wxrootwindow
= wxFindWinFromMacWindow( rootwindow
) ;
415 UMASetThemeWindowBackground( rootwindow
, kThemeBrushDialogBackgroundActive
, false ) ;
419 int former_w
= m_width
;
420 int former_h
= m_height
;
422 int former_mac_x
= (**m_macControl
).contrlRect
.left
;
423 int former_mac_y
= (**m_macControl
).contrlRect
.top
;
425 int currentX
, currentY
;
426 GetPosition(¤tX
, ¤tY
);
427 int currentW
,currentH
;
428 GetSize(¤tW
, ¤tH
);
430 int actualWidth
= width
;
431 int actualHeight
= height
;
434 if (x
== -1 || (sizeFlags
& wxSIZE_ALLOW_MINUS_ONE
))
436 if (y
== -1 || (sizeFlags
& wxSIZE_ALLOW_MINUS_ONE
))
439 actualWidth
= currentW
;
441 actualHeight
= currentH
;
443 if ( actualX
== currentX
&& actualY
== currentY
&& actualWidth
== currentW
&& actualHeight
== currentH
)
446 AdjustForParentClientOrigin(actualX
, actualY
, sizeFlags
);
447 wxMacDrawingHelper
focus( wxFindWinFromMacWindow( GetMacRootWindow() ) ) ;
449 int mac_x
= actualX
;
450 int mac_y
= actualY
;
451 GetParent()->MacClientToRootWindow( & mac_x
, & mac_y
) ;
453 if ( mac_x
!= former_mac_x
|| mac_y
!= former_mac_y
)
456 Rect inval
= { former_mac_y
, former_mac_x
, former_mac_y
+ m_height
, former_mac_x
+ m_width
} ;
457 InvalRect( &inval
) ;
459 UMAMoveControl( m_macControl
, mac_x
+ m_macHorizontalBorder
, mac_y
+ m_macVerticalBorder
) ;
461 Rect inval
= { mac_y
, mac_x
, mac_y
+ m_height
, mac_x
+ m_width
} ;
462 InvalRect( &inval
) ;
466 if ( actualX
!= former_x
|| actualY
!= former_y
)
471 MacRepositionScrollBars() ;
472 // To consider -> should the parameters be the effective or the virtual coordinates (AdjustForParent..)
473 wxMoveEvent
event(wxPoint(m_x
, m_y
), m_windowId
);
474 event
.SetEventObject(this);
475 GetEventHandler()->ProcessEvent(event
);
477 if ( actualWidth
!= former_w
|| actualHeight
!= former_h
)
480 Rect inval
= { mac_y
, mac_x
, mac_y
+ former_h
, mac_x
+ former_w
} ;
481 InvalRect( &inval
) ;
483 m_width
= actualWidth
;
484 m_height
= actualHeight
;
486 UMASizeControl( m_macControl
, m_width
- 2 * m_macHorizontalBorder
, m_height
- 2 * m_macVerticalBorder
) ;
488 Rect inval
= { mac_y
, mac_x
, mac_y
+ m_height
, mac_x
+ m_width
} ;
489 InvalRect( &inval
) ;
492 MacRepositionScrollBars() ;
493 wxSizeEvent
event(wxSize(m_width
, m_height
), m_windowId
);
494 event
.SetEventObject(this);
495 GetEventHandler()->ProcessEvent(event
);
497 if ( wxrootwindow
->IsKindOf( CLASSINFO( wxDialog
) ) )
502 UMASetThemeWindowBackground( rootwindow
, kThemeBrushDocumentWindowBackground
, false ) ;
506 void wxControl::DoSetClientSize(int width
, int height
)
508 DoSetSize( -1 , -1 , width
, height
) ;
511 bool wxControl::Show(bool show
)
513 if ( m_macControl
== NULL
)
514 return wxWindow::Show( show
) ;
516 if ( m_macShown
== show
)
520 ::UMAShowControl( m_macControl
) ;
522 ::UMAHideControl( m_macControl
) ;
524 return wxWindow::Show( show
) ;
527 void wxControl::Enable(bool enable
)
529 if ( m_macControl
== NULL
)
530 return wxWindow::Enable( enable
) ;
532 if ( m_macEnabled
== enable
)
535 if ( UMAHasAppearance() )
538 ::ActivateControl( m_macControl
) ;
540 ::DeactivateControl( m_macControl
) ;
545 ::HiliteControl( m_macControl
, 0 ) ;
547 ::HiliteControl( m_macControl
, 255 ) ;
550 return wxWindow::Enable( enable
) ;
553 void wxControl::Refresh(bool eraseBack
, const wxRect
*rect
)
557 wxWindow::Refresh( eraseBack
, rect
) ;
561 wxWindow::Refresh( eraseBack
, rect
) ;
565 void wxControl::OnPaint(wxPaintEvent
& event
)
569 WindowRef window
= GetMacRootWindow() ;
572 wxWindow
* win
= wxFindWinFromMacWindow( window
) ;
575 wxMacDrawingHelper
help( win
) ;
578 bool hasTabBehind
= false ;
579 wxWindow
* parent
= GetParent() ;
582 if( parent
->m_macWindowData
)
584 UMASetThemeWindowBackground( win
->m_macWindowData
->m_macWindow
, kThemeBrushDialogBackgroundActive
, false ) ;
588 if( parent
->IsKindOf( CLASSINFO( wxNotebook
) ) || parent
->IsKindOf( CLASSINFO( wxTabCtrl
) ))
590 if ( ((wxControl
*)parent
)->m_macControl
)
591 SetUpControlBackground( ((wxControl
*)parent
)->m_macControl
, -1 , true ) ;
595 parent
= parent
->GetParent() ;
598 UMADrawControl( m_macControl
) ;
599 UMASetThemeWindowBackground( win
->m_macWindowData
->m_macWindow
, win
->m_macWindowData
->m_macWindowBackgroundTheme
, false ) ;
605 wxWindow::OnPaint( event
) ;
609 void wxControl::OnKeyDown( wxKeyEvent
&event
)
611 if ( m_macControl
== NULL
)
614 EventRecord
*ev
= wxTheApp
->MacGetCurrentEvent() ;
617 keychar
= short(ev
->message
& charCodeMask
);
618 keycode
= short(ev
->message
& keyCodeMask
) >> 8 ;
620 UMAHandleControlKey( m_macControl
, keycode
, keychar
, ev
->modifiers
) ;
623 void wxControl::OnMouseEvent( wxMouseEvent
&event
)
625 if ( m_macControl
== NULL
)
631 if (event
.GetEventType() == wxEVT_LEFT_DOWN
)
637 MacClientToRootWindow( &x
, &y
) ;
639 ControlHandle control
;
643 WindowRef window
= GetMacRootWindow() ;
650 if ( !event
.m_leftDown
&& !event
.m_rightDown
)
651 modifiers
|= btnState
;
653 if ( event
.m_shiftDown
)
654 modifiers
|= shiftKey
;
656 if ( event
.m_controlDown
)
657 modifiers
|= controlKey
;
659 if ( event
.m_altDown
)
660 modifiers
|= optionKey
;
662 if ( event
.m_metaDown
)
663 modifiers
|= cmdKey
;
665 controlpart
= FindControl( localwhere
, window
, &control
) ;
667 if ( AcceptsFocus() && FindFocus() != this )
671 if ( control
&& UMAIsControlActive( control
) )
674 if ( controlpart
== kControlIndicatorPart
&& !UMAHasAppearance() )
675 controlpart
= UMAHandleControlClick( control
, localwhere
, modifiers
, (ControlActionUPP
) NULL
) ;
677 controlpart
= UMAHandleControlClick( control
, localwhere
, modifiers
, (ControlActionUPP
) -1 ) ;
678 wxTheApp
->s_lastMouseDown
= 0 ;
679 if ( controlpart
&& ! ( ( UMAHasAppearance() || (controlpart
!= kControlIndicatorPart
) )
680 && (IsKindOf( CLASSINFO( wxScrollBar
) ) ) ) ) // otherwise we will get the event twice
682 MacHandleControlClick( control
, controlpart
) ;
690 bool wxControl::MacCanFocus() const
692 { if ( m_macControl
== NULL
)
699 void wxControl::MacHandleControlClick( ControlHandle control
, SInt16 controlpart
)
701 wxASSERT_MSG( m_macControl
!= NULL
, "No valid mac control" ) ;