📄 taskbar.cpp
字号:
// NB: Here we have to perform a deep copy of the menu,
// copying each and every menu item from menu to m_pMenu.
// Other implementations use wxWindow::PopupMenu here,
// which idle execution until the user selects something,
// but since the Mac handles this internally, we can't -
// and have no way at all to idle it while the dock menu
// is being shown before menu goes out of scope (it may
// not be on the heap, and may expire right after this function
// is done - we need it to last until the carbon event is triggered -
// that's when the user right clicks).
//
// Also, since there is no equal (assignment) operator
// on either wxMenu or wxMenuItem, we have to do all the
// dirty work ourselves.
// perform a deep copy of the menu
wxMenuItemList& theList = menu->GetMenuItems();
wxMenuItemList::compatibility_iterator theNode = theList.GetFirst();
// create the main menu
wxMenu *m_pMenu = new wxMenu(menu->GetTitle());
while (theNode != NULL)
{
wxMenuItem* theItem = theNode->GetData();
m_pMenu->Append(
new wxMenuItem(
m_pMenu, // parent menu
theItem->GetId(), // id
theItem->GetText(), // text label
theItem->GetHelp(), // status bar help string
theItem->GetKind(), // menu flags - checkable, separator, etc.
wxDeepCopyMenu(theItem->GetSubMenu()) )); // submenu
theNode = theNode->GetNext();
}
return m_pMenu;
}
//-----------------------------------------------------------------------------
// wxDockTaskBarIcon ctor
//
// Initializes the dock implementation of wxTaskBarIcon.
//
// Here we create some Mac-specific event handlers and UPPs.
//-----------------------------------------------------------------------------
wxDockTaskBarIcon::wxDockTaskBarIcon(wxTaskBarIcon* parent)
: wxTaskBarIconImpl(parent),
m_eventHandlerRef(NULL), m_pMenu(NULL),
m_theLastMenu(GetApplicationDockTileMenu()), m_iconAdded(false)
{
// register the events that will return the dock menu
EventTypeSpec tbEventList[] =
{
{ kEventClassCommand, kEventProcessCommand },
{ kEventClassApplication, kEventAppGetDockTileMenu }
};
m_eventupp = NewEventHandlerUPP(wxDockEventHandler);
wxASSERT(m_eventupp != NULL);
OSStatus err = InstallApplicationEventHandler(
m_eventupp,
GetEventTypeCount(tbEventList), tbEventList,
this, &m_eventHandlerRef);
verify_noerr( err );
}
//-----------------------------------------------------------------------------
// wxDockTaskBarIcon Destructor
//
// Cleans up mac events and restores the old icon to the dock
//-----------------------------------------------------------------------------
wxDockTaskBarIcon::~wxDockTaskBarIcon()
{
// clean up event handler and event UPP
RemoveEventHandler(m_eventHandlerRef);
DisposeEventHandlerUPP(m_eventupp);
// restore old icon and menu to the dock
RemoveIcon();
}
//-----------------------------------------------------------------------------
// wxDockTaskBarIcon::DoCreatePopupMenu
//
// Helper function that handles a request from the dock event handler
// to get the menu for the dock
//-----------------------------------------------------------------------------
wxMenu * wxDockTaskBarIcon::DoCreatePopupMenu()
{
// get the menu from the parent
wxMenu* theNewMenu = CreatePopupMenu();
if (theNewMenu)
{
if (m_pMenu)
delete m_pMenu;
m_pMenu = theNewMenu;
m_pMenu->SetInvokingWindow(m_menuEventWindow);
}
// the return here can be one of three things
// (in order of priority):
// 1) User passed a menu from CreatePopupMenu override
// 2) menu sent to and copied from PopupMenu
// 3) If neither (1) or (2), then NULL
//
return m_pMenu;
}
//-----------------------------------------------------------------------------
// wxDockTaskBarIcon::IsIconInstalled
//
// Returns whether or not the dock is not using the default image
//-----------------------------------------------------------------------------
bool wxDockTaskBarIcon::IsIconInstalled() const
{
return m_iconAdded;
}
//-----------------------------------------------------------------------------
// wxDockTaskBarIcon::SetIcon
//
// Sets the icon for the dock CGImage functions and SetApplicationDockTileImage
//-----------------------------------------------------------------------------
bool wxDockTaskBarIcon::SetIcon(const wxIcon& icon, const wxString& tooltip)
{
// convert the wxIcon into a wxBitmap so we can perform some
// wxBitmap operations with it
wxBitmap bmp( icon );
wxASSERT( bmp.Ok() );
// get the CGImageRef for the wxBitmap:
// OSX builds only, but then the dock only exists in OSX
CGImageRef pImage = (CGImageRef) bmp.CGImageCreate();
wxASSERT( pImage != NULL );
// actually set the dock image
OSStatus err = SetApplicationDockTileImage( pImage );
verify_noerr( err );
// free the CGImage, now that it's referenced by the dock
if (pImage != NULL)
CGImageRelease( pImage );
bool success = (err == noErr);
m_iconAdded = success;
return success;
}
//-----------------------------------------------------------------------------
// wxDockTaskBarIcon::RemoveIcon
//
// Restores the old image for the dock via RestoreApplicationDockTileImage
//-----------------------------------------------------------------------------
bool wxDockTaskBarIcon::RemoveIcon()
{
if (m_pMenu)
{
delete m_pMenu;
m_pMenu = NULL;
}
// restore old icon to the dock
OSStatus err = RestoreApplicationDockTileImage();
verify_noerr( err );
// restore the old menu to the dock
SetApplicationDockTileMenu( m_theLastMenu );
bool success = (err == noErr);
m_iconAdded = !success;
return success;
}
//-----------------------------------------------------------------------------
// wxDockTaskBarIcon::PopupMenu
//
// 2.4 and wxPython method that "pops of the menu in the taskbar".
//
// In reality because of the way the dock menu works in carbon
// we just save the menu, and if the user didn't override CreatePopupMenu
// return the menu passed here, thus sort of getting the same effect.
//-----------------------------------------------------------------------------
bool wxDockTaskBarIcon::PopupMenu(wxMenu *menu)
{
wxASSERT(menu != NULL);
if (m_pMenu)
delete m_pMenu;
// start copy of menu
m_pMenu = wxDeepCopyMenu(menu);
// finish up
m_pMenu->SetInvokingWindow(m_menuEventWindow);
return true;
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//
// wxTaskBarIcon
//
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
IMPLEMENT_DYNAMIC_CLASS(wxTaskBarIcon, wxEvtHandler)
//-----------------------------------------------------------------------------
// wxTaskBarIcon Constructor
//
// Creates the backend
//
// Note that we only support DOCK currently as others require cocoa and
// also some require hacks and other such things. (MenuExtras are
// actually seperate programs that also require a special undocumented id
// hack and other such fun stuff).
//-----------------------------------------------------------------------------
wxTaskBarIcon::wxTaskBarIcon(wxTaskBarIconType nType)
{
wxASSERT_MSG(
nType == DOCK,
wxT("Only the DOCK implementation of wxTaskBarIcon on Mac-Carbon is currently supported!") );
m_impl = new wxDockTaskBarIcon(this);
}
//-----------------------------------------------------------------------------
// wxTaskBarIcon Destructor
//
// Destroys the backend
//-----------------------------------------------------------------------------
wxTaskBarIcon::~wxTaskBarIcon()
{
delete m_impl;
}
//-----------------------------------------------------------------------------
// wxTaskBarIcon::SetIcon
// wxTaskBarIcon::RemoveIcon
// wxTaskBarIcon::PopupMenu
//
// Just calls the backend version of the said function.
//-----------------------------------------------------------------------------
bool wxTaskBarIcon::IsIconInstalled() const
{ return m_impl->IsIconInstalled(); }
bool wxTaskBarIcon::SetIcon(const wxIcon& icon, const wxString& tooltip)
{ return m_impl->SetIcon(icon, tooltip); }
bool wxTaskBarIcon::RemoveIcon()
{ return m_impl->RemoveIcon(); }
bool wxTaskBarIcon::PopupMenu(wxMenu *menu)
{ return m_impl->PopupMenu(menu); }
#endif // wxHAS_TASK_BAR_ICON
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -