1///////////////////////////////////////////////////////////////////////////////
2// Name:        src/mac/popupwin.cpp
3// Purpose:     implements wxPopupWindow for wxMac
4// Author:      Stefan Csomor
5// Modified by:
6// Created:
7// RCS-ID:      $Id: popupwin.cpp 46459 2007-06-13 22:55:58Z SC $
8// Copyright:   (c) 2006 Stefan Csomor
9// License:     wxWindows licence
10///////////////////////////////////////////////////////////////////////////////
11
12// ============================================================================
13// declarations
14// ============================================================================
15
16// CAUTION : This is only experimental stuff right now
17
18// ----------------------------------------------------------------------------
19// headers
20// ----------------------------------------------------------------------------
21
22// For compilers that support precompilation, includes "wx.h".
23#include "wx/wxprec.h"
24
25#ifdef __BORLANDC__
26    #pragma hdrstop
27#endif
28
29#if wxUSE_POPUPWIN
30
31#ifndef WX_PRECOMP
32#endif //WX_PRECOMP
33
34#include "wx/popupwin.h"
35#include "wx/tooltip.h"
36
37#include "wx/mac/private.h"
38
39// ============================================================================
40// implementation
41// ============================================================================
42
43wxPopupWindow::~wxPopupWindow()
44{
45    if ( m_popupWindowRef )
46    {
47#if wxUSE_TOOLTIPS
48        wxToolTip::NotifyWindowDelete(m_popupWindowRef) ;
49#endif
50        wxPendingDelete.Append( new wxMacDeferredWindowDeleter( (WindowRef) m_popupWindowRef ) ) ;
51    }
52}
53
54bool wxPopupWindow::Create(wxWindow *parent, int flags)
55{
56    m_macIsUserPane = false ;
57
58    // popup windows are created hidden by default
59    Hide();
60
61    if ( ! wxPopupWindowBase::Create(parent) )
62        return false;
63
64    WindowClass wclass = kHelpWindowClass;
65    WindowAttributes attr = kWindowCompositingAttribute ;
66    WindowRef parentWindow =(WindowRef) parent->MacGetTopLevelWindowRef();
67
68    Rect bounds = { 0,0,0,0 };
69    OSStatus err = ::CreateNewWindow( wclass , attr , &bounds , (WindowRef*)&m_popupWindowRef ) ;
70    if ( err == noErr )
71    {
72//        SetWindowGroup( (WindowRef) m_popupWindowRef, GetWindowGroup(parentWindow));    //  Put them in the same group so that their window layers are consistent
73    }
74
75    m_peer = new wxMacControl(this , true /*isRootControl*/) ;
76
77    HIViewFindByID( HIViewGetRoot( (WindowRef) m_popupWindowRef ) , kHIViewWindowContentID ,
78        m_peer->GetControlRefAddr() ) ;
79    if ( !m_peer->Ok() )
80    {
81        // compatibility mode fallback
82        GetRootControl( (WindowRef) m_popupWindowRef , m_peer->GetControlRefAddr() ) ;
83        if ( !m_peer->Ok() )
84            CreateRootControl( (WindowRef) m_popupWindowRef , m_peer->GetControlRefAddr() ) ;
85    }
86
87    // the root control level handler
88    MacInstallEventHandler( (WXWidget) m_peer->GetControlRef() ) ;
89
90    // the frame window event handler
91    InstallStandardEventHandler( GetWindowEventTarget(MAC_WXHWND(m_popupWindowRef)) ) ;
92    // MacInstallTopLevelWindowEventHandler() ;
93
94    if ( parent )
95        parent->AddChild(this);
96
97    return true;
98}
99
100void wxPopupWindow::DoMoveWindow(int x, int y, int width, int height)
101{
102    Rect bounds = { y , x , y + height , x + width } ;
103    verify_noerr(SetWindowBounds( (WindowRef) m_popupWindowRef, kWindowStructureRgn , &bounds )) ;
104    wxWindowMac::MacSuperChangedPosition() ; // like this only children will be notified
105}
106
107void wxPopupWindow::DoGetPosition( int *x, int *y ) const
108{
109    Rect bounds ;
110
111    verify_noerr(GetWindowBounds((WindowRef) m_popupWindowRef, kWindowStructureRgn , &bounds )) ;
112
113    if (x)
114       *x = bounds.left ;
115    if (y)
116       *y = bounds.top ;
117}
118
119void wxPopupWindow::DoGetSize( int *width, int *height ) const
120{
121    Rect bounds ;
122
123    verify_noerr(GetWindowBounds((WindowRef) m_popupWindowRef, kWindowStructureRgn , &bounds )) ;
124
125    if (width)
126       *width = bounds.right - bounds.left ;
127    if (height)
128       *height = bounds.bottom - bounds.top ;
129}
130
131void wxPopupWindow::DoGetClientSize( int *width, int *height ) const
132{
133    Rect bounds ;
134
135    verify_noerr(GetWindowBounds((WindowRef) m_popupWindowRef, kWindowContentRgn , &bounds )) ;
136
137    if (width)
138       *width = bounds.right - bounds.left ;
139    if (height)
140       *height = bounds.bottom - bounds.top ;
141}
142
143bool wxPopupWindow::Show(bool show)
144{
145    if ( !wxWindowMac::Show(show) )
146        return false;
147
148    if (show)
149    {
150        ::ShowWindow( (WindowRef)m_popupWindowRef );
151        ::SelectWindow( (WindowRef)m_popupWindowRef ) ;
152
153        // because apps expect a size event to occur at this moment
154        wxSizeEvent event(GetSize() , m_windowId);
155        event.SetEventObject(this);
156        GetEventHandler()->ProcessEvent(event);
157    }
158    else
159    {
160        ::HideWindow( (WindowRef)m_popupWindowRef );
161    }
162    return true;
163}
164
165WXWindow wxPopupWindow::MacGetPopupWindowRef() const
166{
167    return m_popupWindowRef;
168}
169
170#endif // #if wxUSE_POPUPWIN
171