Browse Source

Added some new methods to SystemTrayIconComponent for highlighting and message bubbles.

tags/2021-05-28
jules 12 years ago
parent
commit
09d20dcae8
7 changed files with 146 additions and 47 deletions
  1. +1
    -1
      modules/juce_audio_plugin_client/RTAS/juce_RTAS_MacUtilities.mm
  2. +26
    -27
      modules/juce_gui_basics/native/juce_mac_NSViewComponentPeer.mm
  3. +1
    -1
      modules/juce_gui_basics/native/juce_mac_Windowing.mm
  4. +17
    -3
      modules/juce_gui_extra/misc/juce_SystemTrayIconComponent.h
  5. +23
    -4
      modules/juce_gui_extra/native/juce_linux_SystemTrayIcon.cpp
  6. +40
    -5
      modules/juce_gui_extra/native/juce_mac_SystemTrayIcon.cpp
  7. +38
    -6
      modules/juce_gui_extra/native/juce_win32_SystemTrayIcon.cpp

+ 1
- 1
modules/juce_audio_plugin_client/RTAS/juce_RTAS_MacUtilities.mm View File

@@ -69,7 +69,7 @@ void* attachSubWindow (void* hostWindowRef, Component* comp)
f.size.height = comp->getHeight();
[content setFrame: f];
const int mainScreenHeight = [[[NSScreen screens] objectAtIndex: 0] frame].size.height;
const int mainScreenHeight = getMainScreenHeight();
#if WINDOWPOSITION_BODGE
{


+ 26
- 27
modules/juce_gui_basics/native/juce_mac_NSViewComponentPeer.mm View File

@@ -41,6 +41,23 @@ extern CheckEventBlockedByModalComps isEventBlockedByModalComps;
namespace juce {
#endif
//==============================================================================
static CGFloat getMainScreenHeight() noexcept
{
return [[[NSScreen screens] objectAtIndex: 0] frame].size.height;
}
static void flipScreenRect (NSRect& r) noexcept
{
r.origin.y = getMainScreenHeight() - (r.origin.y + r.size.height);
}
static NSRect flippedScreenRect (NSRect r) noexcept
{
flipScreenRect (r);
return r;
}
//==============================================================================
class NSViewComponentPeer : public ComponentPeer
{
@@ -107,7 +124,7 @@ public:
{
r.origin.x = (CGFloat) component.getX();
r.origin.y = (CGFloat) component.getY();
r.origin.y = [[[NSScreen screens] objectAtIndex: 0] frame].size.height - (r.origin.y + r.size.height);
flipScreenRect (r);
window = [createWindowInstance() initWithContentRect: r
styleMask: getNSWindowStyleMask (windowStyleFlags)
@@ -241,9 +258,7 @@ public:
}
else
{
r.origin.y = [[[NSScreen screens] objectAtIndex: 0] frame].size.height - (r.origin.y + r.size.height);
[window setFrame: [window frameRectForContentRect: r]
[window setFrame: [window frameRectForContentRect: flippedScreenRect (r)]
display: true];
}
}
@@ -263,7 +278,7 @@ public:
r.origin = [viewWindow convertBaseToScreen: r.origin];
#endif
r.origin.y = [[[NSScreen screens] objectAtIndex: 0] frame].size.height - r.origin.y - r.size.height;
flipScreenRect (r);
}
else
{
@@ -875,13 +890,9 @@ public:
#endif
)
{
NSRect current = [window frame];
current.origin.y = [[[NSScreen screens] objectAtIndex: 0] frame].size.height - current.origin.y - current.size.height;
Rectangle<int> pos (convertToRectInt (flippedScreenRect (r)));
Rectangle<int> original (convertToRectInt (flippedScreenRect ([window frame])));
r.origin.y = [[[NSScreen screens] objectAtIndex: 0] frame].size.height - r.origin.y - r.size.height;
Rectangle<int> pos (convertToRectInt (r));
Rectangle<int> original (convertToRectInt (current));
const Rectangle<int> screenBounds (Desktop::getInstance().getDisplays().getTotalBounds (true));
#if defined (MAC_OS_X_VERSION_10_6) && MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_6
@@ -898,15 +909,12 @@ public:
{
constrainer->checkBounds (pos, original, screenBounds,
pos.getY() != original.getY() && pos.getBottom() == original.getBottom(),
pos.getX() != original.getX() && pos.getRight() == original.getRight(),
pos.getX() != original.getX() && pos.getRight() == original.getRight(),
pos.getY() == original.getY() && pos.getBottom() != original.getBottom(),
pos.getX() == original.getX() && pos.getRight() != original.getRight());
pos.getX() == original.getX() && pos.getRight() != original.getRight());
}
r.origin.x = pos.getX();
r.origin.y = [[[NSScreen screens] objectAtIndex: 0] frame].size.height - r.size.height - pos.getY();
r.size.width = pos.getWidth();
r.size.height = pos.getHeight();
r = flippedScreenRect (makeNSRect (pos));
}
return r;
@@ -1578,17 +1586,8 @@ private:
static NSRect firstRectForCharacterRange (id self, SEL, NSRange)
{
if (NSViewComponentPeer* const owner = getOwner (self))
{
if (Component* const comp = dynamic_cast <Component*> (owner->findCurrentTextInputTarget()))
{
const Rectangle<int> bounds (comp->getScreenBounds());
return NSMakeRect (bounds.getX(),
[[[NSScreen screens] objectAtIndex: 0] frame].size.height - bounds.getY(),
bounds.getWidth(),
bounds.getHeight());
}
}
return flippedScreenRect (makeNSRect (comp->getScreenBounds()));
return NSZeroRect;
}


+ 1
- 1
modules/juce_gui_basics/native/juce_mac_Windowing.mm View File

@@ -214,7 +214,7 @@ Point<int> MouseInputSource::getCurrentRawMousePosition()
JUCE_AUTORELEASEPOOL
{
const NSPoint p ([NSEvent mouseLocation]);
return Point<int> (roundToInt (p.x), roundToInt ([[[NSScreen screens] objectAtIndex: 0] frame].size.height - p.y));
return Point<int> (roundToInt (p.x), roundToInt (getMainScreenHeight() - p.y));
}
}


+ 17
- 3
modules/juce_gui_extra/misc/juce_SystemTrayIconComponent.h View File

@@ -55,13 +55,27 @@ public:
~SystemTrayIconComponent();
//==============================================================================
/** Changes the image shown in the taskbar.
*/
/** Changes the image shown in the taskbar. */
void setIconImage (const Image& newImage);
/** Changes the tooltip that Windows shows above the icon. */
/** Changes the icon's tooltip (if the current OS supports this). */
void setIconTooltip (const String& tooltip);
/** Highlights the icon (if the current OS supports this). */
void setHighlighted (bool);
/** Shows a floating text bubble pointing to the icon (if the current OS supports this). */
void showInfoBubble (const String& title, const String& content);
/** Hides the icon's floating text bubble (if the current OS supports this). */
void hideInfoBubble();
/** Returns the raw handle to whatever kind of internal OS structure is
involved in showing this icon.
@see ComponentPeer::getNativeHandle()
*/
void* getNativeHandle() const;
#if JUCE_LINUX
/** @internal */
void paint (Graphics&) override;


+ 23
- 4
modules/juce_gui_extra/native/juce_linux_SystemTrayIcon.cpp View File

@@ -28,8 +28,7 @@ extern Display* display;
class SystemTrayIconComponent::Pimpl
{
public:
Pimpl (const Image& image_, Window windowH)
: image (image_)
Pimpl (const Image& im, Window windowH) : image (im)
{
ScopedXLock xlock;
@@ -117,7 +116,27 @@ void SystemTrayIconComponent::paint (Graphics& g)
RectanglePlacement::xLeft | RectanglePlacement::yTop | RectanglePlacement::onlyReduceInSize, false);
}
void SystemTrayIconComponent::setIconTooltip (const String& /* tooltip */)
void SystemTrayIconComponent::setIconTooltip (const String& /*tooltip*/)
{
// xxx not yet implemented!
// xxx Not implemented!
}
void SystemTrayIconComponent::setHighlighted (bool)
{
// xxx Not implemented!
}
void SystemTrayIconComponent::showInfoBubble (const String& /*title*/, const String& /*content*/)
{
// xxx Not implemented!
}
void SystemTrayIconComponent::hideInfoBubble()
{
// xxx Not implemented!
}
void* SystemTrayIconComponent::getNativeHandle() const
{
return getWindowHandle();
}

+ 40
- 5
modules/juce_gui_extra/native/juce_mac_SystemTrayIcon.cpp View File

@@ -44,6 +44,11 @@ public:
statusItem = [[[NSStatusBar systemStatusBar] statusItemWithLength: NSSquareStatusItemLength] retain];
[statusItem setView: view];
[[NSNotificationCenter defaultCenter] addObserver: view
selector: @selector (frameChanged:)
name: NSWindowDidMoveNotification
object: nil];
}
~Pimpl()
@@ -88,10 +93,6 @@ public:
if (([e modifierFlags] & NSCommandKeyMask) != 0)
eventMods = eventMods.withFlags (ModifierKeys::commandModifier);
NSRect r = [[e window] frame];
r.origin.y = [[[NSScreen screens] objectAtIndex: 0] frame].size.height - r.origin.y - r.size.height;
owner.setBounds (convertToRectInt (r));
const Time now (Time::getCurrentTime());
MouseInputSource mouseSource = Desktop::getInstance().getMainMouseSource();
@@ -117,9 +118,10 @@ public:
}
}
private:
SystemTrayIconComponent& owner;
NSStatusItem* statusItem;
private:
NSImage* statusIcon;
NSControl* view;
bool isHighlighted;
@@ -139,6 +141,7 @@ private:
addMethod (@selector (mouseDown:), handleEventDown, "v@:@");
addMethod (@selector (rightMouseDown:), handleEventDown, "v@:@");
addMethod (@selector (drawRect:), drawRect, "v@:@");
addMethod (@selector (frameChanged:), frameChanged, "v@:@");
registerClass();
}
@@ -178,6 +181,17 @@ private:
fraction: 1.0f];
}
}
static void frameChanged (id self, SEL, NSNotification*)
{
if (Pimpl* const owner = getOwner (self))
{
NSRect r = [[[owner->statusItem view] window] frame];
NSRect sr = [[[NSScreen screens] objectAtIndex: 0] frame];
r.origin.y = sr.size.height - r.origin.y - r.size.height;
owner->owner.setBounds (convertToRectInt (r));
}
}
};
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Pimpl)
@@ -204,3 +218,24 @@ void SystemTrayIconComponent::setIconTooltip (const String&)
{
// xxx not yet implemented!
}
void SystemTrayIconComponent::setHighlighted (bool highlight)
{
if (pimpl != nullptr)
pimpl->setHighlighted (highlight);
}
void SystemTrayIconComponent::showInfoBubble (const String& /*title*/, const String& /*content*/)
{
// xxx Not implemented!
}
void SystemTrayIconComponent::hideInfoBubble()
{
// xxx Not implemented!
}
void* SystemTrayIconComponent::getNativeHandle() const
{
return pimpl != nullptr ? pimpl->statusItem : nullptr;
}

+ 38
- 6
modules/juce_gui_extra/native/juce_win32_SystemTrayIcon.cpp View File

@@ -48,7 +48,7 @@ public:
iconData.uCallbackMessage = WM_TRAYNOTIFY;
iconData.hIcon = hicon;
Shell_NotifyIcon (NIM_ADD, &iconData);
notify (NIM_ADD);
// In order to receive the "TaskbarCreated" message, we need to request that it's not filtered out.
// (Need to load dynamically, as ChangeWindowMessageFilter is only available in Vista and later)
@@ -64,7 +64,7 @@ public:
SetWindowLongPtr (iconData.hWnd, GWLP_WNDPROC, (LONG_PTR) originalWndProc);
iconData.uFlags = 0;
Shell_NotifyIcon (NIM_DELETE, &iconData);
notify (NIM_DELETE);
DestroyIcon (iconData.hIcon);
}
@@ -74,7 +74,7 @@ public:
iconData.hIcon = hicon;
iconData.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP;
Shell_NotifyIcon (NIM_MODIFY, &iconData);
notify (NIM_MODIFY);
DestroyIcon (oldIcon);
}
@@ -83,7 +83,7 @@ public:
{
iconData.uFlags = NIF_TIP;
toolTip.copyToUTF16 (iconData.szTip, sizeof (iconData.szTip) - 1);
Shell_NotifyIcon (NIM_MODIFY, &iconData);
notify (NIM_MODIFY);
}
void handleTaskBarEvent (const LPARAM lParam)
@@ -162,19 +162,30 @@ public:
else if (message == taskbarCreatedMessage)
{
iconData.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP;
Shell_NotifyIcon (NIM_ADD, &iconData);
notify (NIM_ADD);
}
return CallWindowProc (originalWndProc, hwnd, message, wParam, lParam);
}
private:
void showBubble (const String& title, const String& content)
{
iconData.uFlags = 0x10 /*NIF_INFO*/;
title.copyToUTF16 (iconData.szInfoTitle, sizeof (iconData.szInfoTitle) - 1);
content.copyToUTF16 (iconData.szInfo, sizeof (iconData.szInfo) - 1);
notify (NIM_MODIFY);
}
SystemTrayIconComponent& owner;
NOTIFYICONDATA iconData;
private:
WNDPROC originalWndProc;
const DWORD taskbarCreatedMessage;
enum { WM_TRAYNOTIFY = WM_USER + 100 };
void notify (DWORD message) noexcept { Shell_NotifyIcon (message, &iconData); }
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Pimpl)
};
@@ -201,3 +212,24 @@ void SystemTrayIconComponent::setIconTooltip (const String& tooltip)
if (pimpl != nullptr)
pimpl->setToolTip (tooltip);
}
void SystemTrayIconComponent::setHighlighted (bool)
{
// N/A on Windows.
}
void SystemTrayIconComponent::showInfoBubble (const String& title, const String& content)
{
if (pimpl != nullptr)
pimpl->showBubble (title, content);
}
void SystemTrayIconComponent::hideInfoBubble()
{
showInfoBubble (String::empty, String::empty);
}
void* SystemTrayIconComponent::getNativeHandle() const
{
return pimpl != nullptr ? &(pimpl->iconData) : nullptr;
}

Loading…
Cancel
Save