VirtualBox

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

Last change on this file was 98421, checked in by vboxsync, 16 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
Line 
1/* $Id: UICocoaDockIconPreview.mm 98421 2023-02-02 09:21:40Z vboxsync $ */
2/** @file
3 * VBox Qt GUI - Cocoa helper for the dock icon preview.
4 */
5
6/*
7 * Copyright (C) 2009-2023 Oracle and/or its affiliates.
8 *
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
26 */
27
28/* VBox includes */
29#include "UICocoaDockIconPreview.h"
30#include "VBoxCocoaHelper.h"
31
32/* System includes */
33#import <Cocoa/Cocoa.h>
34
35@interface UIDockTileMonitor: NSView
36{
37 UICocoaDockIconPreviewPrivate *p;
38
39 NSImageView *mScreenContent;
40 NSImageView *mMonitorGlossy;
41}
42- (id)initWithFrame:(NSRect)frame parent:(UICocoaDockIconPreviewPrivate*)parent;
43- (NSImageView*)screenContent;
44- (void)resize:(NSSize)size;
45@end
46
47@interface UIDockTileOverlay: NSView
48{
49 UICocoaDockIconPreviewPrivate *p;
50}
51- (id)initWithFrame:(NSRect)frame parent:(UICocoaDockIconPreviewPrivate*)parent;
52@end
53
54@interface UIDockTile: NSView
55{
56 UICocoaDockIconPreviewPrivate *p;
57
58 UIDockTileMonitor *mMonitor;
59 NSImageView *mAppIcon;
60
61 UIDockTileOverlay *mOverlay;
62}
63- (id)initWithParent:(UICocoaDockIconPreviewPrivate*)parent;
64- (void)destroy;
65- (NSView*)screenContentWithParentView:(NSView*)parentView;
66- (void)cleanup;
67- (void)restoreAppIcon;
68- (void)updateAppIcon;
69- (void)restoreMonitor;
70- (void)updateMonitorWithImage:(CGImageRef)image;
71- (void)resizeMonitor:(NSSize)size;
72@end
73
74/*
75 * Helper class which allow us to access all members/methods of AbstractDockIconPreviewHelper
76 * from any Cocoa class.
77 */
78class UICocoaDockIconPreviewPrivate: public UIAbstractDockIconPreviewHelper
79{
80public:
81 inline UICocoaDockIconPreviewPrivate(UIMachine *pMachine, const QPixmap& overlayImage)
82 : UIAbstractDockIconPreviewHelper(pMachine, overlayImage)
83 {
84 mUIDockTile = [[UIDockTile alloc] initWithParent:this];
85 }
86
87 inline ~UICocoaDockIconPreviewPrivate()
88 {
89
90 [mUIDockTile destroy];
91 [mUIDockTile release];
92 }
93
94 UIDockTile *mUIDockTile;
95};
96
97/*
98 * Cocoa wrapper for the abstract dock icon preview class
99 */
100UICocoaDockIconPreview::UICocoaDockIconPreview(UIMachine *pMachine, const QPixmap& overlayImage)
101 : UIAbstractDockIconPreview(pMachine, overlayImage)
102{
103 CocoaAutoreleasePool pool;
104
105 d = new UICocoaDockIconPreviewPrivate(pMachine, overlayImage);
106}
107
108UICocoaDockIconPreview::~UICocoaDockIconPreview()
109{
110 CocoaAutoreleasePool pool;
111
112 delete d;
113}
114
115void UICocoaDockIconPreview::updateDockOverlay()
116{
117 CocoaAutoreleasePool pool;
118
119 [d->mUIDockTile updateAppIcon];
120}
121
122void UICocoaDockIconPreview::updateDockPreview(CGImageRef VMImage)
123{
124 CocoaAutoreleasePool pool;
125
126 [d->mUIDockTile updateMonitorWithImage:VMImage];
127}
128
129void UICocoaDockIconPreview::updateDockPreview(UIFrameBuffer *pFrameBuffer)
130{
131 CocoaAutoreleasePool pool;
132
133 UIAbstractDockIconPreview::updateDockPreview(pFrameBuffer);
134}
135
136void UICocoaDockIconPreview::setOriginalSize(int width, int height)
137{
138 CocoaAutoreleasePool pool;
139
140 [d->mUIDockTile resizeMonitor:NSMakeSize(width, height)];
141}
142
143/*
144 * Class for arranging/updating the layers for the glossy monitor preview.
145 */
146@implementation UIDockTileMonitor
147- (id)initWithFrame:(NSRect)frame parent:(UICocoaDockIconPreviewPrivate*)parent
148{
149 self = [super initWithFrame:frame];
150
151 if (self != nil)
152 {
153 p = parent;
154 /* The screen content view */
155 mScreenContent = [[NSImageView alloc] initWithFrame:NSRectFromCGRect(p->flipRect(p->m_updateRect))];
156// [mScreenContent setImageAlignment: NSImageAlignCenter];
157 [mScreenContent setImageAlignment: NSImageAlignTopLeft];
158 [mScreenContent setImageScaling: NSImageScaleAxesIndependently];
159 [self addSubview: mScreenContent];
160 /* The state view */
161 mMonitorGlossy = [[NSImageView alloc] initWithFrame:NSRectFromCGRect(p->flipRect(p->m_monitorRect))];
162 [mMonitorGlossy setImage: ::darwinToNSImageRef(p->m_dockMonitorGlossy)];
163 [self addSubview: mMonitorGlossy];
164 }
165
166 return self;
167}
168
169- (void)drawRect:(NSRect)aRect
170{
171 NSImage *dockMonitor = ::darwinToNSImageRef(p->m_dockMonitor);
172#if MAC_OS_X_VERSION_MIN_REQUIRED >= 101200
173 [dockMonitor drawInRect:NSRectFromCGRect(p->flipRect(p->m_monitorRect)) fromRect:aRect operation:NSCompositingOperationSourceOver fraction:1.0];
174#else
175 [dockMonitor drawInRect:NSRectFromCGRect(p->flipRect(p->m_monitorRect)) fromRect:aRect operation:NSCompositeSourceOver fraction:1.0];
176#endif
177 [dockMonitor release];
178}
179
180- (NSImageView*)screenContent
181{
182 return mScreenContent;
183}
184
185- (void)resize:(NSSize)size
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 {
192 w = p->m_updateRect.size.width;
193 h = ((float)size.height / size.width * p->m_updateRect.size.height);
194 }
195 else
196 {
197 w = ((float)size.width / size.height * p->m_updateRect.size.width);
198 h = p->m_updateRect.size.height;
199 }
200 CGRect r = (p->flipRect (p->centerRectTo (CGRectMake (0, 0, (int)w, (int)h), p->m_updateRect)));
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)];
208}
209@end
210
211/*
212 * Simple implementation for the overlay of the OS & the state icon. Is used both
213 * in the application icon & preview mode.
214 */
215@implementation UIDockTileOverlay
216- (id)initWithFrame:(NSRect)frame parent:(UICocoaDockIconPreviewPrivate*)parent
217{
218 self = [super initWithFrame:frame];
219
220 if (self != nil)
221 p = parent;
222
223 return self;
224}
225
226- (void)drawRect:(NSRect)aRect
227{
228 RT_NOREF(aRect);
229 NSGraphicsContext *nsContext = [NSGraphicsContext currentContext];
230 CGContextRef pCGContext = (CGContextRef)[nsContext graphicsPort];
231 p->drawOverlayIcons (pCGContext);
232}
233@end
234
235/*
236 * VirtualBox Dock Tile implementation. Manage the switching between the icon
237 * and preview mode & forwards all update request to the appropriate methods.
238 */
239@implementation UIDockTile
240- (id)initWithParent:(UICocoaDockIconPreviewPrivate*)parent
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 */
253 mOverlay = [[UIDockTileOverlay alloc] initWithFrame:NSRectFromCGRect(p->flipRect (p->m_dockIconRect)) parent:p];
254 [self addSubview: mOverlay];
255 }
256
257 return self;
258}
259
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
272- (NSView*)screenContentWithParentView:(NSView*)parentView
273{
274 if (mMonitor != nil)
275 {
276 void *pId = p->currentPreviewWindowId();
277 if (parentView == pId)
278 return [mMonitor screenContent];
279 }
280 return nil;
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];
304 mAppIcon = [[NSImageView alloc] initWithFrame:NSRectFromCGRect (p->flipRect (p->m_dockIconRect))];
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];
322 mMonitor = [[UIDockTileMonitor alloc] initWithFrame:NSRectFromCGRect (p->flipRect (p->m_dockIconRect)) parent:p];
323 [self addSubview: mMonitor positioned:NSWindowBelow relativeTo:mOverlay];
324 }
325}
326
327- (void)updateMonitorWithImage:(CGImageRef)image
328{
329 [self restoreMonitor];
330 NSImage *nsimage = ::darwinToNSImageRef(image);
331 [[mMonitor screenContent] setImage: nsimage];
332 [nsimage release];
333 [[[NSApplication sharedApplication] dockTile] display];
334}
335
336- (void)resizeMonitor:(NSSize)size
337{
338 [self restoreMonitor];
339 [mMonitor resize:size];
340}
341@end
342
Note: See TracBrowser for help on using the repository browser.

© 2023 Oracle
ContactPrivacy policyTerms of Use