Frage

Ich habe eine NSButton -Unterklasse, die ich mit den rechten Maustastklicks arbeiten möchte. Nur überladen -rightMouseDown: Wird es nicht reduzieren, da ich das gleiche Verhalten wie bei normalen Klicks möchte (z. B. die Schaltfläche wird nach unten gedrückt, kann der Benutzer abbrechen, indem die Taste verlässt, die Aktion wird gesendet, wenn die Maus freigegeben wird usw.).

Was ich bisher versucht habe, ist Überladen -rightMouse{Down,Up,Dragged}, Ändern der Ereignisse, um die Schaltflächenklicks der linken Maus anzuzeigen und sie dann an zu senden -mouse{Down,Up,Dragged}. Nun wäre dies eindeutig ein Hack, und da sich Mac OS X nicht alles mochte. Ich kann auf die Schaltfläche klicken, aber beim Verlassen bleibt die Schaltfläche eingedrückt.

Ich könnte das Verhalten selbst nachahmen, was nicht zu kompliziert sein sollte. Ich weiß jedoch nicht, wie der Knopf eingeschoben wird.


Bevor Sie sagen "Nicht! Es ist ein unkonventionelles Mac OS X -Verhalten und sollte vermieden werden": Ich habe darüber nachgedacht und ein Rechtsklick könnte den Workflow erheblich verbessern. Grundsätzlich radelt der Knopf durch 4 Zustände, und ich möchte mit der Rechtsprechung klicken, um ihn umgekehrt zu machen. Es ist kein wesentliches Merkmal, aber es wäre schön. Wenn Sie immer noch Lust haben, "Nicht!" Zu sagen, lassen Sie mich Ihre Gedanken wissen. Ich schätze es!

Vielen Dank!

Bearbeiten: Dies war mein Versuch, das Ereignis zu ändern (Sie können den Typ nicht ändern, also habe ich eine neue gemacht und alle Informationen über das Kopieren. Ich habe es versuchen, wie du es tust):

// I've contracted all three for brevity
- (void)rightMouse{Down,Up,Dragging}:(NSEvent *)theEvent {
    NSEvent *event = [NSEvent mouseEventWithType:NSLeftMouse{Down,Up,Dragging} location:[theEvent locationInWindow] modifierFlags:[theEvent modifierFlags] timestamp:[theEvent timestamp] windowNumber:[theEvent windowNumber] context:[theEvent context] eventNumber:[theEvent eventNumber] clickCount:[theEvent clickCount] pressure:[theEvent pressure]];
    [self mouse{Down,Up,Dragging}:event]; 
}

Update: Das habe ich bemerkt -mouseUp: Wurde nie nach NSButton geschickt, und wenn ich es in ein NSControl geändert habe, war es das. Ich konnte nicht herausfinden, warum dies war, bis Francis McGrew darauf hinwies, dass es seine eigene Event -Handling -Schleife enthält. Nun, dies machte auch Sinn, warum ich das umlegen konnte -rightMouseDown:, aber der Knopf würde nicht zur Veröffentlichung steigen. Dies liegt daran, dass ich selbst neue Ereignisse abholte, die ich nicht von rechts nach links Maustastereignissen abfangen und konvertieren konnte.

War es hilfreich?

Lösung

NSButton tritt in eine Mausverfolgungsschleife ein. Um dies zu ändern, müssen Sie NSButton unterklassen und Ihre eigene benutzerdefinierte Tracking -Schleife erstellen. Probieren Sie diesen Code aus:

- (void) rightMouseDown:(NSEvent *)theEvent 
{
    NSEvent *newEvent = theEvent;
    BOOL mouseInBounds = NO;

    while (YES) 
        {
            mouseInBounds = NSPointInRect([newEvent locationInWindow], [self convertRect:[self frame] fromView:nil]);
            [self highlight:mouseInBounds];

            newEvent = [[self window] nextEventMatchingMask:NSRightMouseDraggedMask | NSRightMouseUpMask];

            if (NSRightMouseUp == [newEvent type])
            {
                break;
            }
        }
    if (mouseInBounds) [self performClick:nil];
}

So mache ich es; Hoffentlich funktioniert es für Sie.

Andere Tipps

Ich habe eine linke Mausklick-and-Hold in eine gefälschte rechte Maus auf eine Pfadsteuerung verwandelt. Ich bin mir nicht sicher, ob dies alle Ihre Probleme lösen wird, aber ich fand, dass der Schlüsselunterschied bei meinem Timestempel darin bestand, den Zeitstempel zu ändern:

NSEvent *event = [NSEvent mouseEventWithType:NSLeftMouseDown 
                                    location:[theEvent locationInWindow] 
                               modifierFlags:[theEvent modifierFlags] 
                                   timestamp:CFAbsoluteGetTimeCurrent()
                                windowNumber:[theEvent windowNumber] 
                                     context:[theEvent context]
 // I was surprised to find eventNumber didn't seem to need to be faked 
                                 eventNumber:[theEvent eventNumber]   
                                  clickCount:[theEvent clickCount] 
                                    pressure:[theEvent pressure]];

Die andere Sache ist, dass abhängig von Ihrem Knopftyp der es ist state Möglicherweise ist der Wert, der es erscheinen lässt oder nicht.

Update: Ich denke, ich habe herausgefunden, warum rightMouseUp: wird nie angerufen. Per the -[NSControl mouseDown:] Dokument mouseDown Ereignis, und es nicht Pause Tracking bis es wird mouseUp. Während es verfolgt, kann es nichts anderes tun. Ich habe zum Beispiel am Ende eines Brauchs versucht mouseDown::

[self performSelector:@selector(mouseUp:) withObject:myFakeMouseUpEvent afterDelay:1.0];

Aber dies wird bis zu einem Normalwert verschoben mouseUp: wird auf andere Weise ausgelöst. Wenn Sie also auf die rechte Maustaste geklickt haben, können Sie (mit der Maus) eine nicht senden leftMouseUp, somit verfolgt die Schaltfläche immer noch und akzeptiert eine nicht rightMouseUp Veranstaltung. Ich weiß immer noch nicht, was die Lösung ist, aber ich dachte, das wären nützliche Informationen.

Nicht viel zu den Antworten oben zu erweitern, aber für diejenigen, die in Swift arbeiten, haben Sie möglicherweise Probleme Dass der Compiler akzeptiert, sodass Sie einige Zeit sparen können. Gibt es einen ordentlichen Weg? Dies gilt in Ihrer Unterklasse -

var rightAction: Selector = nil 
  // add a new property, by analogy with action property

override func rightMouseDown(var theEvent: NSEvent!) {
  var newEvent: NSEvent!

  let maskUp = NSEventMask.RightMouseUpMask.rawValue
  let maskDragged = NSEventMask.RightMouseDraggedMask.rawValue
  let mask = Int( maskUp | maskDragged ) // cast from UInt

  do {
    newEvent = window!.nextEventMatchingMask(mask)
  }
  while newEvent.type == .RightMouseDragged

Meine Schleife ist zu einem Do ... während, wie es immer mindestens einmal ausführen muss, und ich habe nie gern geschrieben while true, und ich muss nichts mit den Ziehenereignissen tun.

Ich hatte endlose Probleme, aussagekräftige Ergebnisse von Convertrect () zu erzielen, vielleicht weil meine Kontrollen in eine Tabellenansicht eingebettet waren. Vielen Dank an Gustav Larsson oben für mein Ende für den letzten Teil -

let whereUp = newEvent.locationInWindow
let p = convertPoint(whereUp, fromView: nil)
let mouseInBounds = NSMouseInRect(p, bounds, flipped) // bounds, not frame
if mouseInBounds {
  sendAction(rightAction, to: target)
  // assuming rightAction and target have been allocated
  }
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top