cancelTracking funktioniert nicht wie erwartet

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

  • cancelTracking funktioniert nicht wie erwartet

    Ich versuche ein eigenes Menü (in einem NSStatusItem) zu bauen, dessen Einträge ähnlich wie die des Standardmenüs aussehen. Dafür habe ich die Klassen MenuItem von NSMenuItem und MenuItemView von NSView abgeleitet. Jeder Menüeintrag hat jeweils einen MenuItemView als Outlet view gesetzt. Die Anzeige funktioniert bereits ganz gut, aber die Verarbeitung der Mausklicks noch nicht. Das ist der Code des Views:

    C-Quellcode

    1. @implementation MenuItemView
    2. - (BOOL)acceptsFirstResponder {
    3. return YES;
    4. }
    5. - (void)drawRect:(NSRect)inDirtyRect {
    6. MenuItem *theMenuItem = (MenuItem *)self.menuItem;
    7. if(self.menuItem.isHighlighted) {
    8. [theMenuItem.highlightColor setFill];
    9. theMenuItem.textColor = [NSColor selectedMenuItemTextColor];
    10. }
    11. else {
    12. [[NSColor clearColor] setFill];
    13. theMenuItem.textColor = [NSColor labelColor];
    14. }
    15. NSRectFill(inDirtyRect);
    16. }
    17. - (void)mouseUp:(NSEvent *)inEvent {
    18. MenuItem *theMenuItem = (MenuItem *)self.menuItem;
    19. [NSApp sendAction:theMenuItem.action to:theMenuItem.target from:theMenuItem];
    20. [theMenuItem.menu cancelTracking];
    21. }
    22. @end
    Alles anzeigen

    Wenn ich den Menüeitrag anklicke, wird mouseUp: zwar ausgeführt, cancelTracking führt aber nicht dazu, das Menü zu schließen. Ich habe mir schon mehrere Apple-Beispiele angesehen und nach dem Problem im Internet gesucht. Bisher erfolglos.

    Wie kann ich ein Menü schließen?
    „Meine Komplikation hatte eine Komplikation.“
  • Guten Morgen,

    ich kann Dir nicht konkret helfen, aber seit 10.10 haben sie ja NSSatusItem neu gemacht.
    Da gibt es viele Sachen, die nicht mehr funktionieren.

    Hast Du Dein Menü einfach mal in ein normales Fenster/PopUpButton gehängt?

    Als unschöne Notlösung könntest Du eine Nachricht senden, die beim Controller vom StatusItem das Menü nil setzt und dann wieder richtig setzt.
    Damit wäre es dann auch zu.

    Bei Deinem -mouseUp: müsstest Du vermutlich noch testen, ob das auch im View ist.
    Sonst würde es auch ungewollt feuern.

    Viele Grüße
  • little_pixel schrieb:

    Da gibt es viele Sachen, die nicht mehr funktionieren.
    Ja, das betrifft aber hauptsächlich die Darstellung. Im Wesentlichen hat der Statusitem einem Button, der die ganzen Einzelteile jetzt enthält.

    little_pixel schrieb:

    Hast Du Dein Menü einfach mal in ein normales Fenster/PopUpButton gehängt?
    Ich habe es mal in einem normalen Menü ausprobiert. Da funktioniert es.

    little_pixel schrieb:

    Als unschöne Notlösung könntest Du eine Nachricht senden, die beim Controller vom StatusItem das Menü nil setzt und dann wieder richtig setzt.
    Damit wäre es dann auch zu.
    Ich probiere das mal. Hört sich aber schlimm an. ;)

    little_pixel schrieb:

    Klicke nach dem Programmstart mal auf eine andere Anwendung und dann Dein StatusItem.
    Somit hat Deine Anwendung keinen Fokus.
    Da habe ich keine Veränderung.
    „Meine Komplikation hatte eine Komplikation.“
  • Eigentlich brauche ich die Views nur, um die Position der Menüeinträge auf dem Bildschirm zu ermitteln. Ein alternativer Ansatz, bei dem ich die Applikationsfenster nach der Mausposition durchsuche, funktioniert nur, wenn es Menüeinträge mit Views gibt. Ansonsten hat das Menü anscheinend kein Fenster, was in der App sichtbar ist.

    Quellcode

    1. NSPoint thePoint = [NSEvent mouseLocation];
    2. for(NSWindow *theWindow in [NSApp windows]) {
    3. NSRect theFrame = theWindow.frame;
    4. if(NSPointInRect(thePoint, theFrame)) {
    5. NSView *theView = theWindow.contentView;
    6. thePoint = [theView convertPoint:[theWindow mouseLocationOutsideOfEventStream] fromView:nil];
    7. theView = [theView hitTest:thePoint];
    8. NSLog(@"view: %@", theView);
    9. }
    10. }
    „Meine Komplikation hatte eine Komplikation.“
  • little_pixel schrieb:

    Du kannst den Knopf im StatusItem mit -window abfragen.
    Damit wüsstest Du den ersten Punkt auf dem Bildschirm.
    Dein Menü kannst Du dann auf Grund der Zeilenhöhe etc. berechnen.

    Viele Grüße
    Daran hatte ich auch schon gedacht. Das Menü verrät ja komischerweise sogar, wie groß es ist. Allerdings ist die horizontale Position des Menüs unklar. Die Menüeinträge sind zudem in einem Submenü, was die ganze Sache noch mal verschärft.

    Ich verstehe die Philosophie des Menü-APIs auch nicht ganz. Einerseits erlaubt Apple eigene Views, andererseits fehlen aber auch viele sinnvolle Funktionen, die mühselig nachgefrickelt werden müssen.
    „Meine Komplikation hatte eine Komplikation.“
  • little_pixel schrieb:

    Und vielleicht noch ein anderer Ansatz, wenn Dir das zusagt:

    Ich habe bei meiner letzten Anwendung kein Menü mehr verwendet, sondern das Menü als Popup mit Tabelle dargestellt.
    Das ist voll hipp… :D

    Das würde Dein Problem vermutlich auch schon lösen.

    Viele Grüße
    Hmm, das wäre auch eine interessante Möglichkeit. Dabei könnte ich auch ein paar andere Restriktionen des Menüs über Bord werfen.
    „Meine Komplikation hatte eine Komplikation.“
  • So, ich habe mal was für Dich nachgeschaut…

    Ich habe ja auch so eine StatusItem-Dingens-App, bei der ich die Menüs komplett mit Views selbst gebaut habe.

    Bei mir steht Folgendes:

    C-Quellcode

    1. -(void)mouseUp:(NSEvent *)theEvent
    2. {
    3. [menu cancelTrackingWithoutAnimation];

    Die Anwendung funktioniert immer noch einwandfrei, obwohl sie mittlerweile sieben Jahre als ist.

    Viele Grüße