VirtualBox

source: vbox/trunk/src/VBox/Frontends/VirtualBox/src/platform/darwin/UICocoaDockIconPreview.mm

Last change on this file was 98421, checked in by vboxsync, 17 months ago

Merging r155511 from gui4 branch: FE/Qt: Runtime UI: Pass uimachine instead of uisession to dock icon preview object.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 9.2 KB
RevLine 
[24377]1/* $Id: UICocoaDockIconPreview.mm 98421 2023-02-02 09:21:40Z vboxsync $ */
[17340]2/** @file
[52727]3 * VBox Qt GUI - Cocoa helper for the dock icon preview.
[17340]4 */
5
6/*
[98103]7 * Copyright (C) 2009-2023 Oracle and/or its affiliates.
[17340]8 *
[96407]9 * This file is part of VirtualBox base platform packages, as
10 * available from https://www.virtualbox.org.
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation, in version 3 of the
15 * License.
16 *
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, see <https://www.gnu.org/licenses>.
24 *
25 * SPDX-License-Identifier: GPL-3.0-only
[17340]26 */
27
[24377]28/* VBox includes */
[27215]29#include "UICocoaDockIconPreview.h"
[24377]30#include "VBoxCocoaHelper.h"
[17340]31
[24377]32/* System includes */
33#import <Cocoa/Cocoa.h>
[17340]34
[27215]35@interface UIDockTileMonitor: NSView
[24377]36{
[27215]37 UICocoaDockIconPreviewPrivate *p;
[17340]38
[24377]39 NSImageView *mScreenContent;
40 NSImageView *mMonitorGlossy;
41}
[27215]42- (id)initWithFrame:(NSRect)frame parent:(UICocoaDockIconPreviewPrivate*)parent;
[24377]43- (NSImageView*)screenContent;
44- (void)resize:(NSSize)size;
45@end
[17340]46
[27215]47@interface UIDockTileOverlay: NSView
[17340]48{
[27215]49 UICocoaDockIconPreviewPrivate *p;
[24377]50}
[27215]51- (id)initWithFrame:(NSRect)frame parent:(UICocoaDockIconPreviewPrivate*)parent;
[24377]52@end
[17340]53
[27215]54@interface UIDockTile: NSView
[24377]55{
[27215]56 UICocoaDockIconPreviewPrivate *p;
[17340]57
[27215]58 UIDockTileMonitor *mMonitor;
[28342]59 NSImageView *mAppIcon;
[24377]60
[27215]61 UIDockTileOverlay *mOverlay;
[17340]62}
[27215]63- (id)initWithParent:(UICocoaDockIconPreviewPrivate*)parent;
[28279]64- (void)destroy;
[28342]65- (NSView*)screenContentWithParentView:(NSView*)parentView;
[24377]66- (void)cleanup;
67- (void)restoreAppIcon;
68- (void)updateAppIcon;
69- (void)restoreMonitor;
70- (void)updateMonitorWithImage:(CGImageRef)image;
71- (void)resizeMonitor:(NSSize)size;
72@end
[17340]73
[29200]74/*
[24377]75 * Helper class which allow us to access all members/methods of AbstractDockIconPreviewHelper
76 * from any Cocoa class.
77 */
[27215]78class UICocoaDockIconPreviewPrivate: public UIAbstractDockIconPreviewHelper
[17340]79{
[24377]80public:
[98421]81 inline UICocoaDockIconPreviewPrivate(UIMachine *pMachine, const QPixmap& overlayImage)
82 : UIAbstractDockIconPreviewHelper(pMachine, overlayImage)
[24377]83 {
[27215]84 mUIDockTile = [[UIDockTile alloc] initWithParent:this];
[24377]85 }
[17340]86
[27215]87 inline ~UICocoaDockIconPreviewPrivate()
[17340]88 {
[28279]89
90 [mUIDockTile destroy];
[27215]91 [mUIDockTile release];
[17340]92 }
[29200]93
[27215]94 UIDockTile *mUIDockTile;
[24377]95};
[17340]96
[29200]97/*
98 * Cocoa wrapper for the abstract dock icon preview class
[24377]99 */
[98421]100UICocoaDockIconPreview::UICocoaDockIconPreview(UIMachine *pMachine, const QPixmap& overlayImage)
101 : UIAbstractDockIconPreview(pMachine, overlayImage)
[24377]102{
103 CocoaAutoreleasePool pool;
104
[98421]105 d = new UICocoaDockIconPreviewPrivate(pMachine, overlayImage);
[17340]106}
107
[27215]108UICocoaDockIconPreview::~UICocoaDockIconPreview()
[17340]109{
[24377]110 CocoaAutoreleasePool pool;
[17340]111
[24377]112 delete d;
113}
[17340]114
[27215]115void UICocoaDockIconPreview::updateDockOverlay()
[24377]116{
117 CocoaAutoreleasePool pool;
[17340]118
[27215]119 [d->mUIDockTile updateAppIcon];
[17340]120}
121
[27215]122void UICocoaDockIconPreview::updateDockPreview(CGImageRef VMImage)
[17340]123{
[24377]124 CocoaAutoreleasePool pool;
[17340]125
[27215]126 [d->mUIDockTile updateMonitorWithImage:VMImage];
[24377]127}
[17340]128
[27215]129void UICocoaDockIconPreview::updateDockPreview(UIFrameBuffer *pFrameBuffer)
[24377]130{
131 CocoaAutoreleasePool pool;
[17340]132
[27215]133 UIAbstractDockIconPreview::updateDockPreview(pFrameBuffer);
[17340]134}
135
[27215]136void UICocoaDockIconPreview::setOriginalSize(int width, int height)
[17340]137{
[24377]138 CocoaAutoreleasePool pool;
[17340]139
[27215]140 [d->mUIDockTile resizeMonitor:NSMakeSize(width, height)];
[24377]141}
142
[29200]143/*
[24377]144 * Class for arranging/updating the layers for the glossy monitor preview.
145 */
[61244]146@implementation UIDockTileMonitor
[27215]147- (id)initWithFrame:(NSRect)frame parent:(UICocoaDockIconPreviewPrivate*)parent
[24377]148{
149 self = [super initWithFrame:frame];
150
151 if (self != nil)
[17340]152 {
[24377]153 p = parent;
154 /* The screen content view */
[27215]155 mScreenContent = [[NSImageView alloc] initWithFrame:NSRectFromCGRect(p->flipRect(p->m_updateRect))];
[24377]156// [mScreenContent setImageAlignment: NSImageAlignCenter];
[85329]157 [mScreenContent setImageAlignment: NSImageAlignTopLeft];
[85330]158 [mScreenContent setImageScaling: NSImageScaleAxesIndependently];
[24377]159 [self addSubview: mScreenContent];
160 /* The state view */
[27215]161 mMonitorGlossy = [[NSImageView alloc] initWithFrame:NSRectFromCGRect(p->flipRect(p->m_monitorRect))];
[30151]162 [mMonitorGlossy setImage: ::darwinToNSImageRef(p->m_dockMonitorGlossy)];
[24377]163 [self addSubview: mMonitorGlossy];
[17340]164 }
[24377]165
166 return self;
[17340]167}
168
[61244]169- (void)drawRect:(NSRect)aRect
[17340]170{
[30151]171 NSImage *dockMonitor = ::darwinToNSImageRef(p->m_dockMonitor);
[85335]172#if MAC_OS_X_VERSION_MIN_REQUIRED >= 101200
[85331]173 [dockMonitor drawInRect:NSRectFromCGRect(p->flipRect(p->m_monitorRect)) fromRect:aRect operation:NSCompositingOperationSourceOver fraction:1.0];
174#else
[27215]175 [dockMonitor drawInRect:NSRectFromCGRect(p->flipRect(p->m_monitorRect)) fromRect:aRect operation:NSCompositeSourceOver fraction:1.0];
[85331]176#endif
[24377]177 [dockMonitor release];
178}
[17340]179
[24377]180- (NSImageView*)screenContent
181{
182 return mScreenContent;
183}
[17340]184
[61244]185- (void)resize:(NSSize)size
[24377]186{
187 /* Calculate the new size based on the aspect ratio of the original screen
188 size */
189 float w, h;
190 if (size.width > size.height)
191 {
[27215]192 w = p->m_updateRect.size.width;
193 h = ((float)size.height / size.width * p->m_updateRect.size.height);
[24377]194 }
195 else
196 {
[27215]197 w = ((float)size.width / size.height * p->m_updateRect.size.width);
198 h = p->m_updateRect.size.height;
[24377]199 }
[27215]200 CGRect r = (p->flipRect (p->centerRectTo (CGRectMake (0, 0, (int)w, (int)h), p->m_updateRect)));
[24377]201 r.origin.x = (int)r.origin.x;
202 r.origin.y = (int)r.origin.y;
203 r.size.width = (int)r.size.width;
204 r.size.height = (int)r.size.height;
205// printf("gui %f %f %f %f\n", r.origin.x, r.origin.y, r.size.width, r.size.height);
206 /* Center within the update rect */
207 [mScreenContent setFrame:NSRectFromCGRect (r)];
[17340]208}
[24377]209@end
[17340]210
[29200]211/*
[24377]212 * Simple implementation for the overlay of the OS & the state icon. Is used both
213 * in the application icon & preview mode.
214 */
[27215]215@implementation UIDockTileOverlay
216- (id)initWithFrame:(NSRect)frame parent:(UICocoaDockIconPreviewPrivate*)parent
[24377]217{
218 self = [super initWithFrame:frame];
219
220 if (self != nil)
221 p = parent;
222
223 return self;
224}
225
[61244]226- (void)drawRect:(NSRect)aRect
[24377]227{
[63492]228 RT_NOREF(aRect);
[24377]229 NSGraphicsContext *nsContext = [NSGraphicsContext currentContext];
230 CGContextRef pCGContext = (CGContextRef)[nsContext graphicsPort];
231 p->drawOverlayIcons (pCGContext);
232}
233@end
234
[29200]235/*
[24377]236 * VirtualBox Dock Tile implementation. Manage the switching between the icon
237 * and preview mode & forwards all update request to the appropriate methods.
238 */
[27215]239@implementation UIDockTile
240- (id)initWithParent:(UICocoaDockIconPreviewPrivate*)parent
[24377]241{
242 self = [super init];
243
244 if (self != nil)
245 {
246 p = parent;
247 /* Add self as the content view of the dock tile */
248 NSDockTile *dock = [[NSApplication sharedApplication] dockTile];
249 [dock setContentView: self];
250 /* App icon is default */
251 [self restoreAppIcon];
252 /* The overlay */
[27215]253 mOverlay = [[UIDockTileOverlay alloc] initWithFrame:NSRectFromCGRect(p->flipRect (p->m_dockIconRect)) parent:p];
[24377]254 [self addSubview: mOverlay];
255 }
256
257 return self;
258}
259
[28279]260- (void)destroy
261{
262 /* Remove all content from the application dock tile. */
263 [mOverlay removeFromSuperview];
264 [mOverlay release];
265 mOverlay = nil;
266 NSDockTile *dock = [[NSApplication sharedApplication] dockTile];
267 [dock setContentView: nil];
268 /* Cleanup all other resources */
269 [self cleanup];
270}
271
[28342]272- (NSView*)screenContentWithParentView:(NSView*)parentView
[24377]273{
[28342]274 if (mMonitor != nil)
275 {
276 void *pId = p->currentPreviewWindowId();
277 if (parentView == pId)
278 return [mMonitor screenContent];
279 }
280 return nil;
[24377]281}
282
283- (void)cleanup
284{
285 if (mAppIcon != nil)
286 {
287 [mAppIcon removeFromSuperview];
288 [mAppIcon release];
289 mAppIcon = nil;
290 }
291 if (mMonitor != nil)
292 {
293 [mMonitor removeFromSuperview];
294 [mMonitor release];
295 mMonitor = nil;
296 }
297}
298
299- (void)restoreAppIcon
300{
301 if (mAppIcon == nil)
302 {
303 [self cleanup];
[27215]304 mAppIcon = [[NSImageView alloc] initWithFrame:NSRectFromCGRect (p->flipRect (p->m_dockIconRect))];
[24377]305 [mAppIcon setImage: [NSImage imageNamed:@"NSApplicationIcon"]];
306 [self addSubview: mAppIcon positioned:NSWindowBelow relativeTo:mOverlay];
307 }
308}
309
310- (void)updateAppIcon
311{
312 [self restoreAppIcon];
313 [[[NSApplication sharedApplication] dockTile] display];
314}
315
316- (void)restoreMonitor
317{
318 if (mMonitor == nil)
319 {
320 p->initPreviewImages();
321 [self cleanup];
[27215]322 mMonitor = [[UIDockTileMonitor alloc] initWithFrame:NSRectFromCGRect (p->flipRect (p->m_dockIconRect)) parent:p];
[24377]323 [self addSubview: mMonitor positioned:NSWindowBelow relativeTo:mOverlay];
324 }
325}
326
327- (void)updateMonitorWithImage:(CGImageRef)image
328{
329 [self restoreMonitor];
[30151]330 NSImage *nsimage = ::darwinToNSImageRef(image);
[24377]331 [[mMonitor screenContent] setImage: nsimage];
332 [nsimage release];
333 [[[NSApplication sharedApplication] dockTile] display];
334}
335
[61244]336- (void)resizeMonitor:(NSSize)size
[24377]337{
[28540]338 [self restoreMonitor];
[24377]339 [mMonitor resize:size];
340}
341@end
342
Note: See TracBrowser for help on using the repository browser.

© 2023 Oracle
ContactPrivacy policyTerms of Use