]> git.saurik.com Git - wxWidgets.git/blob - src/mac/carbon/taskbar.cpp
cleanup image after application
[wxWidgets.git] / src / mac / carbon / taskbar.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: taskbar.cpp
3 // Purpose: wxTaskBarIcon OSX Implementation
4 // Author: Ryan Norton
5 // Modified by:
6 // Created: 09/25/2004
7 // RCS-ID: $Id$
8 // Copyright: (c) 2004 Ryan Norton
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
11
12 #include "wx/wxprec.h"
13
14 #include "wx/defs.h"
15
16 #ifdef wxHAS_TASK_BAR_ICON
17
18 #include "wx/mac/private.h"
19
20 #include "wx/taskbar.h"
21 #include "wx/menu.h"
22 #include "wx/icon.h"
23
24 #if 0
25
26 #include "wx/frame.h"
27 #include "wx/dialog.h"
28
29 #endif
30
31 IMPLEMENT_DYNAMIC_CLASS(wxTaskBarIcon, wxEvtHandler)
32
33 pascal OSStatus wxDockEventHandler( EventHandlerCallRef inHandlerCallRef,
34 EventRef inEvent, void* pData)
35 {
36 wxTaskBarIcon*& pTB = (wxTaskBarIcon*&) pData;
37
38 const UInt32 eventClass = GetEventClass(inEvent);
39 const UInt32 eventKind = GetEventKind(inEvent);
40
41 if (eventClass == kEventClassCommand && eventKind == kEventCommandProcess)
42 {
43 MenuRef hMenu = MAC_WXHMENU(pTB->GetCurrentMenu()->GetHMenu());
44 OSStatus result = eventNotHandledErr ;
45
46 HICommand command ;
47 OSErr err;
48
49 err = GetEventParameter(inEvent, kEventParamDirectObject, typeHICommand,
50 NULL, sizeof(HICommand), NULL, &command);
51 wxASSERT(err == noErr);
52
53 MenuItemIndex menuItemIndex;
54 err = GetIndMenuItemWithCommandID(hMenu, command.commandID, 1, NULL, &menuItemIndex);
55 wxASSERT(err == noErr);
56
57
58 MenuCommand id = command.commandID ;
59 wxMenuItem* item = NULL;
60 // for items we don't really control
61 if ( id == kHICommandPreferences )
62 {
63 id = wxApp::s_macPreferencesMenuItemId ;
64
65 wxMenuBar* mbar = wxMenuBar::MacGetInstalledMenuBar() ;
66 if ( mbar )
67 {
68 wxMenu* menu = NULL ;
69 item = mbar->FindItem( id , &menu ) ;
70 }
71 }
72 else if (id != 0)
73 GetMenuItemRefCon( hMenu , menuItemIndex , (UInt32*) &item ) ;
74
75 if ( item )
76 {
77 if (item->IsCheckable())
78 {
79 item->Check( !item->IsChecked() ) ;
80 }
81
82 item->GetMenu()->SendEvent( id , item->IsCheckable() ? item->IsChecked() : -1 ) ;
83 result = noErr ;
84 }
85 return result ;
86 }
87
88 wxASSERT(eventClass == kEventClassApplication && eventKind == kEventAppGetDockTileMenu);
89
90 //set the internal event
91 pTB->SetInternalEvent(inEvent);
92
93 //process the right click event
94 wxTaskBarIconEvent evt(wxEVT_TASKBAR_RIGHT_UP,NULL);
95 pTB->ProcessEvent(evt);
96
97 //set the internal event
98 pTB->SetInternalEvent(NULL);
99
100 return noErr;
101 }
102
103 DEFINE_ONE_SHOT_HANDLER_GETTER( wxDockEventHandler );
104
105 wxTaskBarIcon::wxTaskBarIcon(const wxTaskBarIconType& nType)
106 : m_nType(nType), m_pEvent(NULL), m_pMenu(NULL), m_iconAdded(false)
107 {
108 //Register the events that will return the dock menu
109 EventTypeSpec tbEventList[] = { { kEventClassCommand, kEventProcessCommand },
110 { kEventClassApplication, kEventAppGetDockTileMenu } };
111
112 OSStatus err = InstallApplicationEventHandler(
113 GetwxDockEventHandlerUPP(),
114 GetEventTypeCount(tbEventList), tbEventList,
115 this, NULL);
116
117 wxASSERT(err == noErr);
118 }
119 wxTaskBarIcon::~wxTaskBarIcon()
120 {
121 //TODO:uninstall event handler
122 }
123
124 void wxTaskBarIcon::SetInternalEvent(void* pEvent)
125 {
126 m_pEvent = pEvent;
127 }
128
129 wxMenu* wxTaskBarIcon::GetCurrentMenu()
130 {
131 return m_pMenu;
132 }
133
134 // Operations:
135 bool wxTaskBarIcon::SetIcon(const wxIcon& icon, const wxString& tooltip)
136 {
137 #if 0
138 wxASSERT(wxTheApp);
139 wxWindow* pTopWindow = wxTheApp->GetTopWindow();
140
141 wxASSERT(pTopWindow);
142
143 if(pTopWindow->IsKindOf(CLASSINFO(wxDialog)))
144 ((wxDialog*)pTopWindow)->SetIcon(icon);
145 else
146 {
147 wxASSERT(pTopWindow->IsKindOf(CLASSINFO(wxFrame)));
148 ((wxFrame*)pTopWindow)->SetIcon(icon);
149 }
150
151 return true;
152 #else
153 //TODO: Educated guess
154
155 CGImageRef pImage;
156 //create the icon from the bitmap and mask bitmap contained within
157 OSStatus err = CreateCGImageFromPixMaps(
158 GetGWorldPixMap(MAC_WXHBITMAP(icon.GetHBITMAP())),
159 GetGWorldPixMap(MAC_WXHBITMAP(icon.GetMask()->GetMaskBitmap())),
160 &pImage
161 );
162
163 wxASSERT(err == 0);
164
165 err = SetApplicationDockTileImage(pImage);
166
167 wxASSERT(err == 0);
168
169 if (pImage != NULL)
170 CGImageRelease(pImage);
171
172 m_iconAdded = true;
173 return true;
174 #endif
175 }
176
177 bool wxTaskBarIcon::RemoveIcon()
178 {
179 //TODO: Not tested
180 OSStatus err = RestoreApplicationDockTileImage();
181 wxASSERT(err == 0);
182 m_iconAdded = false;
183
184 return true;
185 }
186
187 bool wxTaskBarIcon::PopupMenu(wxMenu *menu)
188 {
189 wxASSERT(m_pEvent != NULL);
190
191 if (m_pMenu)
192 delete m_pMenu;
193
194 m_pMenu = menu;
195 menu->SetEventHandler(this);
196
197 //note to self - a MenuRef IS A MenuHandle
198 MenuRef hMenu = MAC_WXHMENU(menu->GetHMenu());
199
200 //When we call SetEventParameter it will decrement
201 //the reference count of the menu - we need to make
202 //sure it stays around in the wxMenu class here
203 RetainMenu(hMenu);
204
205 //set the actual dock menu
206 OSStatus err = SetEventParameter((EventRef) m_pEvent, kEventParamMenuRef,
207 typeMenuRef, sizeof(MenuRef),
208 &hMenu);
209 wxASSERT(err == 0);
210
211 return true;
212 }
213
214 #endif //wxHAS_TASK_BAR_ICON