NSTableView: mouseDown und Dragging

Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

  • NSTableView: mouseDown und Dragging

    Hi!

    Ich kämpfe gerade mit einer eigenen NSTableView-Klasse: Bei Klicken auf eine Zeile soll eine bestimmte Methode ausgeführt werden, auch wenn die Zeile schon selektiert war. Da die Delegate-Methoden nur auf geänderte Selektionen reagieren, habe ich "mouseDown" überschrieben. So weit, so gut.

    Heute habe ich nun Dragging zum Umsortieren von Zeilen implementiert und es kollidiert mit dem obigen Verfahren: Die Aktion wird (natürlich) auch zu Beginn des Drags ausgeführt, was ich nicht möchte.

    "mouseUp" kann ich nicht nutzen, da das Dragging dieses Event scheinbar schluckt, zumindest wird diese Methode nicht mehr angesprungen, wenn ich in "mouseDown" auch die Methode der Super-Klasse aufrufe. Mache ich das nicht, funktioniert das Dragging nicht. Die Methoden / Notifications bzgl. Selection funktionieren wie gesagt nicht bei Anklicken einer bereits ausgewählten Zeile.

    Mir gehen langsam die Ideen aus... Ich bin kurz davor, morgen (heute komme ich nicht mehr dazu) mit diversen Zustands-Variablen herum zu doktern, aber irgendwie ist das alles Pfusch.

    Any ideas?

    Mattes
    Diese Seite bleibt aus technischen Gründen unbedruckt.
  • Du könntest Dir in mouseDown den nächsten Event holen, bei MouseUp startest Du Deine Aktion und bei MouseDragged rufst Du die super Methode auf.

    Quellcode

    1. // wait for next event
    2. theEvent = [[controlView window] nextEventMatchingMask:(NSLeftMouseDraggedMask | NSLeftMouseUpMask)];
    Xcode 4 sucks – „,Multiple exclamation marks‘, he went on, shaking his head, are a sure sign of a diseased mind.‘“ (Terry Pratchett 1992: Eric)

    "Wir ordnen und befehlen hiermit allen Ernstes, dass die Advocati wollene schwarze Mäntel, welche bis unter das Knie gehen, unserer Verordnung gemäß zu tragen haben, damit man die Spitzbuben schon von weitem erkennt." (Friedrich Wilhelm I., Soldatenkönig)
  • Hi Mika,

    Danke für Deine Antwort, ich fürchte nur, sie nicht richtig verstanden zu haben:

    Wenn ich in "mouseDown" nicht die super-Methode aufrufe (oder mit einem anderen Event), funktioniert das Dragging nicht mehr. Rufe ich die super-Methode auf, kommt kein "mouseUp" mehr an, so dass ich dort meine Aktion nicht starten kann.

    Ich habe das Gefühl, den Wald vor lauter Bäumen nicht zu sehen. Es wäre toll, wenn noch jemand einen Tipp hat, ich komme allerdings erst morgen Abend zum Weiterforschen...

    Mattes
    Diese Seite bleibt aus technischen Gründen unbedruckt.
  • Wenn ich in "mouseDown" nicht die super-Methode aufrufe (oder mit einem anderen Event), funktioniert das Dragging nicht mehr. Rufe ich die super-Methode auf, kommt kein "mouseUp" mehr an, so dass ich dort meine Aktion nicht starten kann.​


    Deshalb solltest Du mit -nextEventMatchingMask: auf den nächsten Event warten und dann entscheiden …
    Xcode 4 sucks – „,Multiple exclamation marks‘, he went on, shaking his head, are a sure sign of a diseased mind.‘“ (Terry Pratchett 1992: Eric)

    "Wir ordnen und befehlen hiermit allen Ernstes, dass die Advocati wollene schwarze Mäntel, welche bis unter das Knie gehen, unserer Verordnung gemäß zu tragen haben, damit man die Spitzbuben schon von weitem erkennt." (Friedrich Wilhelm I., Soldatenkönig)
  • Meinst Du aus Sicht der GUI? Da habe ich schon daran gedacht, z. B. ein Icon in die Tabellenzeile aufzunehmen, das dann als Button fungiert. Ist aber Plan B, ich würde lieber beim aktuellen, den Benutzern bekannten Layout bleiben.

    Wenn Du intern meinst: ich würde gerne eine andere Methode nutzen, weiß aber nicht, welche: Die o. g. Delegate-Methoden reagieren leider nicht auf Klick einer bereits ausgewählten Zeile.

    Ciao, Mattes
    Diese Seite bleibt aus technischen Gründen unbedruckt.
  • Ich meinte ersteres.

    Wenn der User die Software so schon kennt und du das draggen jetzt zusätzlich einbauen möchtest, dann wäre es auch möglich für das Draggen einen extra Button zu machen der das Draggen aktiviert und das klick solange deaktiviert (Also quasi ein Editmodus wie bei iOS) oder sogar noch einfacher ein extra Fenster mit einer kleinen Table wo er nur tauschen kann.

    Gruß

    Claus
    2 Stunden Try & Error erspart 10 Minuten Handbuchlesen.

    Pre-Kaffee-Posts sind mit Vorsicht zu geniessen :)
  • Wenn mouseUp nicht nach dem Dragging kommt, muss ja irgend ein anderes Event signalisieren, dass das Dragging vorbei ist.

    Wobei, Du möchtest das Event ja nur auslösen, wenn kein Dragging vollzogen wird/wurde/werden soll.
    Wie mika schon schrieb solltest Du also das Folgeevent abwarten. Was kommt direkt nach dem MouseDown, wenn Du in die Zelle klickst?
    Alternativ: was kommt direkt nach dem MouseDown, wenn Du mit dem Dragging loslegst?

    An Hand dieser Information kannst Du dann ja entscheiden:
    Event != Dragging-Event: Aktion durchführen
    (Mich hat die fehlende Info bezüglich Geklicke ohne Selektionsänderung auch schon genervt.)
    «Applejack» "Don't you use your fancy mathematics to muddle the issue!"

    Iä-86! Iä-64! Awavauatsh fthagn!

    kmr schrieb:

    Ach, Du bist auch so ein leichtgläubiger Zeitgenosse, der alles glaubt, was irgendwelche Typen vor sich hin brabbeln. :-P
  • Michael schrieb:

    Zitat von MyMattes: „Any ideas?“
    Hast du schon versucht, in <b>mouseDown:</b> deine Methode mit <b>performSelector:withObject:afterDelay:</b> aufzurufen?

    Auch eine gute Möglichkeit. Und wenn das Dragging einsetzt, wirfst Du diesen Aufruf einfach wieder weg:
    [NSObject cancelPreviousPerformRequestsWithTarget:selector:object:]
    «Applejack» "Don't you use your fancy mathematics to muddle the issue!"

    Iä-86! Iä-64! Awavauatsh fthagn!

    kmr schrieb:

    Ach, Du bist auch so ein leichtgläubiger Zeitgenosse, der alles glaubt, was irgendwelche Typen vor sich hin brabbeln. :-P
  • Hallo Jungs,

    Danke an alle für Eure Tipps. Schon der erste von Mika war optimal, ich war gestern nur zu verpeilt, ihn zu verstehen...

    mika schrieb:

    Du könntest Dir in mouseDown den nächsten Event holen, bei MouseUp startest Du Deine Aktion und bei MouseDragged rufst Du die super Methode auf.


    Genau so mache ich es nun. Es gibt nur die "mouseDown:"-Methode und die sieht prinzipiell so aus:

    Quellcode

    1. - (void)mouseDown:(NSEvent *)event
    2. {
    3. NSEvent *nextEvent = [[self window] nextEventMatchingMask: NSLeftMouseUpMask | NSLeftMouseDraggedMask];
    4. switch (nextEvent.type)
    5. {
    6. case NSLeftMouseDragged:
    7. {
    8. // Mouse is dragged: pass event to super class to handle row reordering
    9. [super mouseDown:event];
    10. break;
    11. }
    12. case NSLeftMouseUp:
    13. {
    14. // Mouse button was released without movement: Single click
    15. NSPoint mouseUpPosition = [self convertPoint:[nextEvent locationInWindow] fromView:nil];
    16. NSInteger row = [self rowAtPoint:mouseUpPosition];
    17. // Deal with click on row...
    18. break;
    19. }
    20. default:
    21. break;
    22. }
    23. }
    Alles anzeigen


    Funktioniert 1a und nach meinem Empfinden sogar "echter" als meine ursprüngliche Lösung: Ich hatte ein NSColorPanel bei "mouseDown:" aufgerufen, aber eigentlich erwartet man (ich?) eine solche Reaktion auf einen Mausklick erst beim "mouseUp:".

    Nochmals Danke, Mattes
    Diese Seite bleibt aus technischen Gründen unbedruckt.

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von MyMattes ()