Frage zur Hauptmenü-Gestaltung mit OutlineView

  • Frage zur Hauptmenü-Gestaltung mit OutlineView

    Hallo!

    bevor ich mich wieder wochenlang plage...:

    Ich baue ein hierarchisches Hautmenü, ähnlich dem in iTunes, das variabel befüllt werden soll. Teile des Menüs kommen fix vom Programm, anderes wird vom Benutzer hinzugefügt. Es soll also zur Laufzeit "dynamisch" sein. Das Menü enthält Menütexte und dazu passende Icons.

    Ist folgende Umsetzung schlau? (hab' ja kürzlich ein gutes Buch gelesen...):
    Ich verwende eine Subclass von NSOutlineView und packe mit NSAttributedStrings die Inhalte (Icon und Text) rein. In der Subclass implementiere ich die Mausevents.
    Wovon ich keine Idee habe:
    Wie stelle ich fest, auf welches Item des Menüs der Benutzer geklickt hat, wo es doch dynamisch ist? Irgendwo müße ich eine Art Referenz hinterlegen. Nur wo?

    No.
  • RE: Frage zur Hauptmenü-Gestaltung mit OutlineView

    jedes MenuItem kann ein tag und ein representedObject haben. Damit solltest du eigentlich alle nötigen infos übermitteln können. Das Menü solltest du auf Anfrage dynamisch erzeugen. Das geht mit diesen Delegate-Funktionen von NSMenu:

    Quellcode

    1. @interface NSObject(NSMenuDelegate)
    2. - (void)menuNeedsUpdate:(NSMenu*)menu;
    3. - (int)numberOfItemsInMenu:(NSMenu*)menu;
    4. - (BOOL)menu:(NSMenu*)menu updateItem:(NSMenuItem*)item atIndex:(int)index shouldCancel:(BOOL)shouldCancel;
    5. // implement either the first one or the next two to populate the menu
    6. - (BOOL)menuHasKeyEquivalent:(NSMenu*)menu forEvent:(NSEvent*)event target:(id*)target action:(SEL*)action;
    7. // bypasses populating the menu for checking for key equivalents. set target and action on return
    8. @end


    HTH
    Max
  • RE: Frage zur Hauptmenü-Gestaltung mit OutlineView

    Ja, ja, über Outline-Views hätte ich nohc was schreiben sollen. Aber das Problem ist da ja eigentlich nicht speziell.

    Also, langer Rede kurzer Sinn:
    Es gibt mehrere Möglichkeiten, das zu implementieren. Die Ableitungsidee ist eine. Allerdings würde ich eher zur Ableitung des Controllers tendieren. Aber ist Ableitung notwendig? Mir würde etwas anderes vorschweben:

    Du baust dir einen MyOutlineViewHelper. Diesen lässt du das Array observieren. Wie man eine Observierung anmeldet und behandelt, wird ja beschrieben. Jetzt machst du etwas Trickreiches: Bei jeder Änderung des beobachteten Arrays erzeugst du dir eine Kopie und fügst deine Objekte hinzu. Der Controller oder das TableView hängen dann an diesem Array, nicht mehr am Original.

    Das sollten dann allerdings nicht Strings sein, sondern wiederum Entitäten, am besten eine gefakte Klasse oder einfach ein Dictionary, welches die im Outline-View gebundenen Attribute kennt. Du kannst bei dem Outline-View ja abfragen, welche Bindungen er hat. Diese fakst du ins Dictionary.

    Aber viel einfacher:
    Wieso erzeugst du nicht einfach bei der Installation/dem Programmstart die entsprechenden Einträge? Du gibst den Einträgen einfach eine Eigenschaft -buildIn, mit der du Löschungen und Veränderungen steuerst.
    Es hat noch nie etwas gefunzt. To tear down the Wall would be a Werror!
    25.06.2016: [Swift] gehört zu meinen *Favorite Tags* auf SO. In welcher Bedeutung von "favorite"?
  • Hier ist mal mein bisheriger Ansatz. Lange noch nicht fertig und ne fortgeschrittenere Version entwickelt sich gerade in nem Projekt weiter.

    Der Teufel steckt im Detail.

    Das Ganze wird bestückt wie ein Menue. Du musst aber bedenken, daß sich nicht alle Menupunkte gleich verhalten. Manche kann man umbenennen, manche nicht, Manche sind löschbar oder nicht, verschiebar, sortierbar usw. Es gibt auch drei versiedene Menubereiche z.B. Papierkorb unten, oder Kategorien in der Mitte, hier können Subkategoien rein.

    Durch überschreiben von BrowserMenuItem kann ich die Verschiedensten Datenquellen darstellen, ein Menupunkt listet z.B. CoreData ein Anderer ein Unetrverzeichnis des Filesystems.

    Aber immer noch viel zu tun....
    Seminare, Artikel, Code. ObjectiveCeeds - alles für die Apfelzucht.
  • Danke für die zahlreichen Antworten.
    Ich werde mir dieses WE mal alle Lösungsansätze ansehen.

    Das mir dem Observieren gefällt mir gut. Ein Objekt hält die fixen Menüpunkte, ein anderes die variablen. Vielleicht brauche ich sogar noch ein drittes, weil die Menüdarstellung auch von eingegebenen Daten abhängt.
    Sobald sich an den dreien was ändert, wird das Array, das die Menüinhalte hält (also Inhalte der obigen Drei enthält), angepaßt. Das Array mit den Menüinhalten ist an den OutlineView gebunden.

    Ich wollte aber noch auf etwas anderes hinaus. Wenn ich MausEvents abfangen muß (anklicken, drag&drop,...) muß ich das doch in einer Subclass vom OutlineView machen, der auch die Custom Class des Views ist. Oder?

    LG
    No.
  • Ich schreibe gerade dazu ei Tutorial. Mal schauen, was dabei herumkommt. Du kannst ja auf die Seite schauen.

    Wieso in Gottes Namen willst du an die Maus-Routinen? Aber das würde so richtig sein.
    Es hat noch nie etwas gefunzt. To tear down the Wall would be a Werror!
    25.06.2016: [Swift] gehört zu meinen *Favorite Tags* auf SO. In welcher Bedeutung von "favorite"?
  • Irgendwie muß ich doch feststellen, ob der Benutzer einen Menüpunkt im OutlineView anklickt oder dragged.
    *grübel*
    Oder geht's mit einem Controller, wie bei einem Button? Ein Button führt zur Action, wenn man ihn anklickt, ein OutlineView nicht (?).

    Ach, ich muß noch viel lernen...

    No.
  • Na, wenn du mit Bindings arbeitest, ist dir das in der Regel egal. Die holen dann halt für den entsprechenden Eintrag gleich die Daten.

    Wenn das Ganze mehr Operationen symbolisiert, dann musst du das. Da gibt es aber auch Tricks, insbesondere über die Selektion. Warte mal ab. :)

    BTW: Ich mache das jetzt seit 5(?) Jahren nd muss noch viel lernen.
    Es hat noch nie etwas gefunzt. To tear down the Wall would be a Werror!
    25.06.2016: [Swift] gehört zu meinen *Favorite Tags* auf SO. In welcher Bedeutung von "favorite"?
  • Ich ändere es gerade ein wenig. Anstelle verschiedener "Lösungen" wird es ein Weg. Das ist einfach so richtig von der Bezeichnung.

    Also am WE werde ihc es vllt und hoffentlich fertig bekommen. Aber du kannst ganz allgemein schon Anregungen finden.
    Es hat noch nie etwas gefunzt. To tear down the Wall would be a Werror!
    25.06.2016: [Swift] gehört zu meinen *Favorite Tags* auf SO. In welcher Bedeutung von "favorite"?
  • Ich werd' noch irre mit dem TreeController... Hilfeee!
    Ich habe:

    Klasse SHMainMenuItem (einzelne Zeilen im OutlineView), die enthält:
    String *menuItemText, NSMutableArray *menuItemListe

    Klasse SHMainMenu (baut das Hauptmenü zusammen), die enthält:
    NSMutableArray *hauptMenu, IBOutlet id derHMController (ein Outlet zum HauptMenuTreeController)
    hier erstelle ich ein Menüitem:
    SHMainMenuItem *_neuesMenue = [[SHMainMenuItem alloc]init];

    Der HauptMenuTreeController ist im IB sauber an den OutletView gebunden. Die add:-Action über einen extra zum Testen angelegten Button funktioniert.

    Nur: ich seh' nix von meinem in SHMainMenu erstelltem Hauptmenü im OutlineView. Ich hab's schon mit vielem probert: "Controller Content" im IB, ... nix geht.
    Das einzige, was funktioniert, ist, wenn ich den Controller Content auf content array -> Bind to: SHMainMenu -> Model key path: hauptMenu setze. Das geht aber nur mit einer Ebene.

    Habt Ihr einen Tip für mich?

    Ich habe das ganze schon testweise mit einem ArrayController und TableView ohne Probleme hinbekommen (Controller Content->Content Array im IB), nur bei der Kombination TreeController und OutlineView klappt's nicht.

    Ah ja: kurz gesagt, ich will eine <vorgefertigte> Hierarchie mit einem TreeController in einem OutlineView darstellen.

    No.
  • Ich bin mir nicht mehr sicher, dass wir vom Gleichen sprechen. Vielleicht solltest du mal einen Screen-Shot posten.

    Ansonsten: den Child-Keypath hast du ordentlich gesetzt? Vllt lädst du mal das Projekt hoch.
    Es hat noch nie etwas gefunzt. To tear down the Wall would be a Werror!
    25.06.2016: [Swift] gehört zu meinen *Favorite Tags* auf SO. In welcher Bedeutung von "favorite"?
  • Guten Morgen! =)

    Ich war/bin gerade am Herumprobieren und werd' heute (abend) noch eine Idee ausprobieren (Controller Content -> Content Array im IB mit der Klasse, die die Daten des OutlineView hält. Bei "this class is not key value coding-compliant for the key children." bin ich schon. Die KVC Acessoren muß ich noch in die Klasse einbauen).

    Wenn's nach wie vor hakt lade ich es gerne hoch. Danke für das Angebot.

    Gestern war ich fast soweit, das ganze mit einer klassichen Datasource zu bauen, wäre nicht plötzlich heute geworden.

    No.
  • Sodala,
    ich komme nicht weiter.

    Zwei Überlegungen:

    1. ich muß
    -(void)insertObject:(id)object atArrangedObjectIndexPath:(NSIndexPath *)indexPath;
    benutzen, damit der TreeController nicht ein leeres Objekt anhängt, sondern das (id)object, das ich mit übergebe. Allerdings steige ich bei NSIndexPath schon wieder aus. indexPath=0 oder 1 funktioniert nicht.

    2. ich habe ein Problem mit dem Timing. Meine Vermutung:
    Die Instanz des TreeControllers liegt im NIB. Die Instanz "läuft längst" und kriegt von meinem Objektbaum, den ich "anderswo" zusammenbaue nichts (mehr) mit. Ich muß zuerst meinen Objektbaum bauen und DANACH mit
    bind:toObject:withKeyPath:options:
    den TreeController an mein Bäumchen hängen.

    Bin ich mit wenigstens einer meiner Überlegungen auf dem richtigen Dampfer?

    No.
  • Ich kann das jetzt leider hier nicht wirklich nachvollziehen. Wie baust du denn den Path? Außredem solltest du wenigstens mal ein paar Screenshots posten. Ich weiß nicht mehr ganz, worauf du hinaus willst.

    2. Nein, das sollte gleichgültig sein. Dazu ist KVO ja gerade da. Wie baust du denn den Objektbaum zusammen?
    Es hat noch nie etwas gefunzt. To tear down the Wall would be a Werror!
    25.06.2016: [Swift] gehört zu meinen *Favorite Tags* auf SO. In welcher Bedeutung von "favorite"?