Frage

Der iTunes Mini-Player (nur ein Beispiel geben) unterstützt Click-through in denen die Anwendung nicht nach vorne gebracht wird, wenn die Wiedergabe / Pause und Lautstärkeregler verwendet werden.

Wie wird das gemacht?

Ich habe mich über Apples Dokumentation und ein wenig weiter zu gehen, in Cocoa Event-Handling Guide, Event Dispatch heißt es:

  

Einige Ereignisse, von denen viele durch die Application Kit definiert sind (Typ NSAppKitDefined), haben mit Aktionen, die von einem Fenster oder dem Anwendungsobjekt selbst gesteuert zu tun. Beispiele für diese Ereignisse sind diejenigen im Zusammenhang mit Aktivieren, Deaktivieren, versteckt, und die Anwendung zeigt. NSApp filtert diese Ereignisse früh in seiner Dispatch-Routine aus und behandelt sie selbst.

Also, aus meinem begrenzten Verständnis ( Wie ein Ereignis Trägt eine Cocoa, Anwendung ) Subklassen NSApplication und überwiegende - (void)sendEvent:(NSEvent *)theEvent sollte jede Maus und Tastatur Ereignisfalle, aber immer noch wird das Fenster auf Klick angehoben. Also entweder das Fenster angehoben wird, bevor das Ereignis von NSApplication zu sehen ist oder fehlt mir etwas anderes.

Ich habe Demystifying NSApplication bei Matt Gallagher sah es durch neu zu erstellen leider Matt hat die Ereigniswarteschlange nicht decken, so anders als das, ich bin ratlos.

Jede Hilfe würde geschätzt, danke.

Edited hinzufügen: Gefunden einen Beitrag an Lloyd Lounge , in dem er spricht über das gleiche Problem und Links zu einem Beitrag unter CocoaBuilder, capture erste rechte Maus nach unten . Ich bin zur Zeit den Code dort geliefert auszuprobieren, nachdem um einige Hantieren und die NSLog reaktivieren für [theEvent type], die linke Maustaste Aktivität gefangen wird.

Nun, nach links auf das Fenster klicken sie vorzuverlegen eine Folge von Ereignistypen produziert, 13, 1, 13, sind diese NSAppKitDefined, NSLeftMouseDown und NSAppKitDefined wieder. Kann ich diese herauszufiltern oder finden, wohin sie gehen?

War es hilfreich?

Lösung 2

Das ist nicht ganz die Antwort, die ich suchte, aber jetzt ausreichend gut es funktioniert. Durch Subklassen NSView und Umsetzung der folgenden Methoden können diese Ansicht dann als Schaltfläche dienen.

- (void)mouseDown:(NSEvent *)theEvent {
    [NSApp preventWindowOrdering];
//  [self setNeedsDisplay:YES];
}

- (BOOL)acceptsFirstMouse:(NSEvent *)theEvent {
    return YES;
}

- (BOOL)shouldDelayWindowOrderingForEvent:(NSEvent *)theEvent {
    return YES;
}

Nichts anderes erforderlich ist, das ist es. Natürlich umgeht dies die alle NSButton Güte, dass ich halten wollte, muss ich entwerfen und dann die Tastenzustände des Zeichnens und Aktualisierung kümmern, aber ich bin nur froh, eine Antwort zu haben.

Andere Tipps

Dies kann mit einem NSPanel erreicht werden, die nicht auf deaktivieren versteckt worden ist gesetzt und Schlüssel werden nur nach Bedarf. Dies setzt auch voraus, dass die Kontrollen Sie Rückkehr YES verwenden -acceptsFirstMouse:; NSButtons tut dies standardmäßig aktiviert.

Sie können die Haut auf deactivate Flagge durch IB für das Panel ausschalten, aber Sie werden die -setBecomesKeyOnlyIfNeeded:YES Nachricht an der Platte ausgeben müssen, um es zu halten und die App nach vorne kommen auf die Schaltfläche klickt.

Es ist möglich, eine NSButton reagiert auf Click-through-Ereignisse zu machen, ohne sein Verhalten zu ändern, wenn die App aktiv ist:

Interface (ClickThroughButton.h):

#import <AppKit/AppKit.h>

@interface ClickThroughButton : NSButton

@end

Implementation (ClickThroughButton.m):

#import "ClickThroughButton.h"

@implementation ClickThroughButton

- (BOOL)shouldDelayWindowOrderingForEvent:(NSEvent *)theEvent {
    return ![NSApp isActive];    
}

- (void)mouseDown:(NSEvent *)theEvent {    
    if (![NSApp isActive]) {
        [NSApp preventWindowOrdering];        

        [self highlight:YES];

        NSEvent *mouseUpEvent = [[self window] nextEventMatchingMask:NSLeftMouseUpMask
                                                  untilDate:[NSDate distantFuture]
                                                     inMode:NSEventTrackingRunLoopMode
                                                    dequeue:YES];
        NSPoint mouseLocation = [self convertPoint:[mouseUpEvent locationInWindow] fromView:nil];
        BOOL mouseUpInside = [self mouse:mouseLocation inRect:[self bounds]];

        if (mouseUpInside) {
            if ([self target])
                [[self target] performSelector:[self action] withObject:self]; 
        }

        [self highlight:NO];            

    } else {
        [super mouseDown:theEvent];        
    }
}

@end

Haben Sie acceptsFirstMouse: ausgecheckt? Jeder NSView kann YES zu diesem Ereignisse zurückkehren zu sagen, dass die Ansicht, die das Ereignis behandeln soll, anstatt das Fenster in den Vordergrund zu bringen. Vermutlich durch das Ereignis abfängt, wird es nicht verwendet werden, um das Fenster in den Vordergrund zu bringen, aber ich kann nicht dafür verbürgen.

Sie werden offensichtlich brauchen keine Kontrolle Sie dieses Verhalten haben wollen, Unterklasse acceptsFirstMouse: außer Kraft zu setzen.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top