]>
Commit | Line | Data |
---|---|---|
607667fd RN |
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 | ||
976f9240 RN |
24 | // |
25 | //TODO: Implement Apple Software Guidelines - show the top window it it's not shown, | |
26 | //and force it to be unminimized - and all unminimized windows should be brought to | |
27 | //the front | |
cc3388ae | 28 | // |
976f9240 | 29 | //TODO: |
607667fd RN |
30 | IMPLEMENT_DYNAMIC_CLASS(wxTaskBarIcon, wxEvtHandler) |
31 | ||
32 | pascal OSStatus wxDockEventHandler( EventHandlerCallRef inHandlerCallRef, | |
33 | EventRef inEvent, void* pData) | |
34 | { | |
35 | wxTaskBarIcon*& pTB = (wxTaskBarIcon*&) pData; | |
36 | ||
37 | const UInt32 eventClass = GetEventClass(inEvent); | |
38 | const UInt32 eventKind = GetEventKind(inEvent); | |
39 | ||
40 | if (eventClass == kEventClassCommand && eventKind == kEventCommandProcess) | |
41 | { | |
976f9240 RN |
42 | //TODO: |
43 | //TODO: This is a complete copy of | |
44 | //static pascal OSStatus wxMacAppCommandEventHandler( EventHandlerCallRef handler , EventRef event , void *data ) | |
45 | //FIND A WAY TO EXTERN THIS AND USE THAT HERE INSTEAD!! | |
46 | //TODO: | |
607667fd RN |
47 | MenuRef hMenu = MAC_WXHMENU(pTB->GetCurrentMenu()->GetHMenu()); |
48 | OSStatus result = eventNotHandledErr ; | |
49 | ||
50 | HICommand command ; | |
51 | OSErr err; | |
52 | ||
53 | err = GetEventParameter(inEvent, kEventParamDirectObject, typeHICommand, | |
54 | NULL, sizeof(HICommand), NULL, &command); | |
55 | wxASSERT(err == noErr); | |
56 | ||
57 | MenuItemIndex menuItemIndex; | |
58 | err = GetIndMenuItemWithCommandID(hMenu, command.commandID, 1, NULL, &menuItemIndex); | |
59 | wxASSERT(err == noErr); | |
60 | ||
61 | ||
62 | MenuCommand id = command.commandID ; | |
63 | wxMenuItem* item = NULL; | |
64 | // for items we don't really control | |
65 | if ( id == kHICommandPreferences ) | |
66 | { | |
67 | id = wxApp::s_macPreferencesMenuItemId ; | |
68 | ||
69 | wxMenuBar* mbar = wxMenuBar::MacGetInstalledMenuBar() ; | |
70 | if ( mbar ) | |
71 | { | |
72 | wxMenu* menu = NULL ; | |
73 | item = mbar->FindItem( id , &menu ) ; | |
74 | } | |
75 | } | |
76 | else if (id != 0) | |
77 | GetMenuItemRefCon( hMenu , menuItemIndex , (UInt32*) &item ) ; | |
78 | ||
79 | if ( item ) | |
80 | { | |
81 | if (item->IsCheckable()) | |
82 | { | |
83 | item->Check( !item->IsChecked() ) ; | |
84 | } | |
85 | ||
86 | item->GetMenu()->SendEvent( id , item->IsCheckable() ? item->IsChecked() : -1 ) ; | |
87 | result = noErr ; | |
88 | } | |
89 | return result ; | |
90 | } | |
91 | ||
92 | wxASSERT(eventClass == kEventClassApplication && eventKind == kEventAppGetDockTileMenu); | |
a45beea1 | 93 | |
607667fd RN |
94 | //process the right click event |
95 | wxTaskBarIconEvent evt(wxEVT_TASKBAR_RIGHT_UP,NULL); | |
96 | pTB->ProcessEvent(evt); | |
97 | ||
a45beea1 RN |
98 | //create popup menu |
99 | wxMenu* menu = pTB->DoCreatePopupMenu(); | |
100 | ||
101 | OSStatus err = noErr; | |
102 | ||
103 | if(menu) | |
104 | { | |
105 | //note to self - a MenuRef IS A MenuHandle | |
106 | MenuRef hMenu = MAC_WXHMENU(menu->GetHMenu()); | |
107 | ||
108 | //When we call SetEventParameter it will decrement | |
109 | //the reference count of the menu - we need to make | |
110 | //sure it stays around in the wxMenu class here | |
111 | RetainMenu(hMenu); | |
607667fd | 112 | |
a45beea1 RN |
113 | //set the actual dock menu |
114 | err = SetEventParameter((EventRef) inEvent, kEventParamMenuRef, | |
115 | typeMenuRef, sizeof(MenuRef), | |
116 | &hMenu); | |
117 | wxASSERT(err == 0); | |
118 | } | |
119 | ||
120 | return err; | |
607667fd RN |
121 | } |
122 | ||
123 | DEFINE_ONE_SHOT_HANDLER_GETTER( wxDockEventHandler ); | |
124 | ||
125 | wxTaskBarIcon::wxTaskBarIcon(const wxTaskBarIconType& nType) | |
a45beea1 | 126 | : m_nType(nType), m_pEventHandlerRef(NULL), m_pMenu(NULL), m_iconAdded(false) |
607667fd RN |
127 | { |
128 | //Register the events that will return the dock menu | |
129 | EventTypeSpec tbEventList[] = { { kEventClassCommand, kEventProcessCommand }, | |
130 | { kEventClassApplication, kEventAppGetDockTileMenu } }; | |
131 | ||
cc3388ae RN |
132 | #ifdef __WXDEBUG__ |
133 | OSStatus err = | |
134 | #endif | |
135 | InstallApplicationEventHandler( | |
607667fd RN |
136 | GetwxDockEventHandlerUPP(), |
137 | GetEventTypeCount(tbEventList), tbEventList, | |
cc3388ae | 138 | this, (&(EventHandlerRef&)m_pEventHandlerRef)); |
607667fd RN |
139 | |
140 | wxASSERT(err == noErr); | |
141 | } | |
cc3388ae | 142 | |
607667fd RN |
143 | wxTaskBarIcon::~wxTaskBarIcon() |
144 | { | |
cc3388ae | 145 | RemoveEventHandler((EventHandlerRef&)m_pEventHandlerRef); |
607667fd RN |
146 | } |
147 | ||
a45beea1 | 148 | wxMenu* wxTaskBarIcon::GetCurrentMenu() |
607667fd | 149 | { |
a45beea1 | 150 | return m_pMenu; |
607667fd RN |
151 | } |
152 | ||
a45beea1 | 153 | wxMenu* wxTaskBarIcon::DoCreatePopupMenu() |
607667fd | 154 | { |
a45beea1 RN |
155 | if (m_pMenu) |
156 | delete m_pMenu; | |
157 | ||
158 | m_pMenu = CreatePopupMenu(); | |
159 | ||
160 | if (m_pMenu) | |
161 | m_pMenu->SetEventHandler(this); | |
162 | ||
607667fd RN |
163 | return m_pMenu; |
164 | } | |
165 | ||
166 | // Operations: | |
167 | bool wxTaskBarIcon::SetIcon(const wxIcon& icon, const wxString& tooltip) | |
168 | { | |
976f9240 | 169 | //TODO: (IT WORKS!) Make work without mask - mayby by using a wxDC? |
607667fd | 170 | |
cc3388ae RN |
171 | wxASSERT(icon.GetMask() != NULL); |
172 | ||
607667fd RN |
173 | CGImageRef pImage; |
174 | //create the icon from the bitmap and mask bitmap contained within | |
175 | OSStatus err = CreateCGImageFromPixMaps( | |
176 | GetGWorldPixMap(MAC_WXHBITMAP(icon.GetHBITMAP())), | |
177 | GetGWorldPixMap(MAC_WXHBITMAP(icon.GetMask()->GetMaskBitmap())), | |
178 | &pImage | |
179 | ); | |
180 | ||
181 | wxASSERT(err == 0); | |
182 | ||
183 | err = SetApplicationDockTileImage(pImage); | |
184 | ||
185 | wxASSERT(err == 0); | |
739e35e4 RN |
186 | |
187 | if (pImage != NULL) | |
188 | CGImageRelease(pImage); | |
607667fd | 189 | |
976f9240 | 190 | return m_iconAdded = err == noErr; |
607667fd RN |
191 | } |
192 | ||
193 | bool wxTaskBarIcon::RemoveIcon() | |
194 | { | |
607667fd RN |
195 | OSStatus err = RestoreApplicationDockTileImage(); |
196 | wxASSERT(err == 0); | |
197 | ||
976f9240 | 198 | return !(m_iconAdded = !(err == noErr)); |
607667fd RN |
199 | } |
200 | ||
201 | bool wxTaskBarIcon::PopupMenu(wxMenu *menu) | |
202 | { | |
607667fd RN |
203 | if (m_pMenu) |
204 | delete m_pMenu; | |
a45beea1 | 205 | |
607667fd | 206 | m_pMenu = menu; |
a45beea1 RN |
207 | |
208 | wxASSERT(menu); | |
209 | m_pMenu->SetEventHandler(this); | |
210 | ||
211 | return SetApplicationDockTileMenu(MAC_WXHMENU(menu->GetHMenu())); | |
607667fd RN |
212 | } |
213 | ||
f2641bc2 | 214 | #endif //wxHAS_TASK_BAR_ICON |