VirtualBox

Changeset 35865 in vbox


Ignore:
Timestamp:
Feb 7, 2011 11:44:20 AM (14 years ago)
Author:
vboxsync
Message:

FE/Qt4-OSX: Add resizing by keeping the current aspect ration in scale mode.

Location:
trunk/src/VBox/Frontends/VirtualBox/src
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Frontends/VirtualBox/src/platform/darwin/VBoxUtils-darwin-cocoa.mm

    r35750 r35865  
    2929#import <AppKit/NSColor.h>
    3030#import <AppKit/NSFont.h>
     31
     32#import <objc/objc-class.h>
    3133
    3234/* For the keyboard stuff */
     
    470472}
    471473
     474/* Make an empty interface declaration of QCocoaWindowDelegate to shut up the
     475   compiler. */
     476@interface QCocoaWindowDelegate: NSObject {}
     477@end
     478
     479/* Our resize proxy singleton. This class has two major tasks. First it is used
     480   to proxy the windowWillResize selector of the Qt delegate. As this is class
     481   global and therewith done for all Qt window instances, we have to track the
     482   windows we are interested in. This is the second task. */
     483@interface UIResizeProxy: NSObject
     484{
     485    NSMutableArray *m_pArray;
     486}
     487+(UIResizeProxy*)sharedResizeProxy;
     488-(void)addWindow:(NSWindow*)pWindow;
     489-(void)removeWindow:(NSWindow*)pWindow;
     490-(BOOL)containsWindow:(NSWindow*)pWindow;
     491@end
     492
     493static UIResizeProxy *gSharedResizeProxy = nil;
     494
     495@implementation UIResizeProxy
     496+(UIResizeProxy*)sharedResizeProxy
     497{
     498    if (gSharedResizeProxy == nil)
     499        gSharedResizeProxy = [[super allocWithZone:NULL] init];
     500    return gSharedResizeProxy;
     501}
     502-(id)init
     503{
     504    if ((self = [super init]))
     505    {
     506        /* Create an array which contains the registered windows. */
     507        m_pArray = [[NSMutableArray alloc] init];
     508        /* Swizzle the windowWillResize method. This means replacing the
     509           original method with our own one and reroute the original one to
     510           another name. */
     511        Class oriClass = [QCocoaWindowDelegate class];
     512        Class myClass = [UIResizeProxy class];
     513        SEL oriSel = @selector(windowWillResize:toSize:);
     514        SEL qtSel  = @selector(qtWindowWillResize:toSize:);
     515        Method m1 = class_getInstanceMethod(oriClass, oriSel);
     516        Method m2 = class_getInstanceMethod(myClass, oriSel);
     517        Method m3 = class_getInstanceMethod(myClass, qtSel);
     518        /* Overwrite the original implementation with our own one. old contains
     519           the old implementation. */
     520        IMP old = method_setImplementation(m1, method_getImplementation(m2));
     521        /* Add a new method to our class with the old implementation. */
     522        class_addMethod(oriClass, qtSel, old, method_getTypeEncoding(m3));
     523    }
     524    return self;
     525}
     526- (void)addWindow:(NSWindow*)pWindow
     527{
     528    [m_pArray addObject:pWindow];
     529}
     530- (void)removeWindow:(NSWindow*)pWindow
     531{
     532    [m_pArray removeObject:pWindow];
     533}
     534- (BOOL)containsWindow:(NSWindow*)pWindow
     535{
     536    return [m_pArray containsObject:pWindow];
     537}
     538- (NSSize)qtWindowWillResize:(NSWindow *)pWindow toSize:(NSSize)newFrameSize
     539{
     540    /* This is a fake implementation. It will be replaced by the original Qt
     541       method. */
     542    return newFrameSize;
     543}
     544- (NSSize)windowWillResize:(NSWindow *)pWindow toSize:(NSSize)newFrameSize
     545{
     546    /* Call the original implementation for newFrameSize. */
     547    NSSize qtSize = [self qtWindowWillResize:pWindow toSize:newFrameSize];
     548    /* Check if we are responsible for this window. */
     549    if (![[UIResizeProxy sharedResizeProxy] containsWindow:pWindow])
     550        return qtSize;
     551    /* The static modifier method in NSEvent is >= 10.6. It allows us to check
     552       the shift modifier state during the resize. If it is not available the
     553       user have to press shift before he start to resize. */
     554    if ([NSEvent respondsToSelector:@selector(modifierFlags)])
     555        if (((int)(intptr_t)[NSEvent performSelector:@selector(modifierFlags)] & NSShiftKeyMask) == NSShiftKeyMask)
     556            return qtSize;
     557    else
     558        /* Shift key pressed when this resize event was initiated? */
     559        if (([pWindow resizeFlags] & NSShiftKeyMask) == NSShiftKeyMask)
     560            return qtSize;
     561    /* The default case is to calculate the aspect radio of the old size and
     562       used it for the new size. */
     563    NSSize s = [pWindow frame].size;
     564    double a = (double)s.width / s.height;
     565    NSSize newSize = NSMakeSize(newFrameSize.width, newFrameSize.width / a);
     566    /* We have to make sure the new rectangle meets the minimum requirements. */
     567    NSSize testSize = [self qtWindowWillResize:pWindow toSize:newSize];
     568    if (   testSize.width > newSize.width
     569        || testSize.height > newSize.height)
     570    {
     571        double w1 = testSize.width / newSize.width;
     572        double h1 = testSize.height / newSize.height;
     573        if (   w1 > 1
     574            && w1 > h1)
     575        {
     576            newSize.width = testSize.width;
     577            newSize.height = testSize.width * a;
     578        }else if (h1 > 1)
     579        {
     580            newSize.width = testSize.height * a;
     581            newSize.height = testSize.height;
     582        }
     583    }
     584    return newSize;
     585}
     586@end
     587
     588void darwinInstallResizeDelegate(NativeNSWindowRef pWindow)
     589{
     590    [[UIResizeProxy sharedResizeProxy] addWindow:pWindow];
     591}
     592
     593void darwinUninstallResizeDelegate(NativeNSWindowRef pWindow)
     594{
     595    [[UIResizeProxy sharedResizeProxy] removeWindow:pWindow];
     596}
     597
  • trunk/src/VBox/Frontends/VirtualBox/src/platform/darwin/VBoxUtils-darwin.cpp

    r35750 r35865  
    140140{
    141141    return ::darwinMinaturizeWindow(::darwinToNativeWindow(pWidget));
     142}
     143
     144void darwinInstallResizeDelegate(QWidget *pWidget)
     145{
     146    ::darwinInstallResizeDelegate(::darwinToNativeWindow(pWidget));
     147}
     148
     149void darwinUninstallResizeDelegate(QWidget *pWidget)
     150{
     151    ::darwinUninstallResizeDelegate(::darwinToNativeWindow(pWidget));
    142152}
    143153
  • trunk/src/VBox/Frontends/VirtualBox/src/platform/darwin/VBoxUtils-darwin.h

    r35750 r35865  
    8484bool darwinSetFrontMostProcess();
    8585uint64_t darwinGetCurrentProcessId();
     86
     87void darwinInstallResizeDelegate(NativeNSWindowRef pWindow);
     88void darwinUninstallResizeDelegate(NativeNSWindowRef pWindow);
    8689
    8790bool darwinUnifiedToolbarEvents(const void *pvCocoaEvent, const void *pvCarbonEvent, void *pvUser);
     
    236239bool darwinIsWindowMaximized(QWidget *pWidget);
    237240void darwinMinaturizeWindow(QWidget *pWidget);
    238 
    239241bool darwinOpenFile(const QString &strFile);
    240242
    241243QString darwinSystemLanguage(void);
    242244QPixmap darwinCreateDragPixmap(const QPixmap& aPixmap, const QString &aText);
     245
     246void darwinInstallResizeDelegate(QWidget *pWidget);
     247void darwinUninstallResizeDelegate(QWidget *pWidget);
    243248
    244249void darwinRegisterForUnifiedToolbarContextMenuEvents(QMainWindow *pWindow);
  • trunk/src/VBox/Frontends/VirtualBox/src/runtime/scale/UIMachineWindowScale.cpp

    r35424 r35865  
    7878
    7979#ifdef Q_WS_MAC
     80    /* Install the resize delegate for keeping the aspect ratio. */
     81    ::darwinInstallResizeDelegate(this);
    8082    /* Beta label? */
    8183    if (vboxGlobal().isBeta())
     
    8688#endif /* Q_WS_MAC */
    8789
    88 
    8990    /* Show window: */
    9091    showSimple();
     
    9394UIMachineWindowScale::~UIMachineWindowScale()
    9495{
     96#ifdef Q_WS_MAC
     97    /* Uninstall the resize delegate for keeping the aspect ratio. */
     98    ::darwinUninstallResizeDelegate(this);
     99#endif /* Q_WS_MAC */
     100
    95101    /* Save normal window settings: */
    96102    saveWindowSettings();
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette