Results 1 to 8 of 8

Thread: Undo / Redo

  1. #1

    Undo / Redo

    Ik heb al gezocht hier op het forum, en zie vanallerlei dingen over undo/redo maar kan er weinig mee. Links die niet werken, en eerlijk gezegd wordt ik er een beetje moedeloos van. Kan me geen beeld maken waar te beginnen, daarom vraag ik om de hulp van de mensen hier..

    Ik heb een programma voor aanpassen van een playlist. Die laadt ik in een eigen component, omdat ik zo makkelijker mee kan werken:
    Click image for larger version. 

Name:	H.fw.jpg 
Views:	107 
Size:	10.3 KB 
ID:	7621

    Ik heb dus groepen die in een objectlist staan, en in elke groep de kanalen die onder die groep vallen.
    - elke groep heeft een lijst met kanalen, en een titel (groepnaam)
    - elk kanaal heeft meerdere string properties (naam, logo, id, url)

    Op zich dus simpele data, maar hoe ik hier undo/redo in kan maken? Iemand een voorbeeld of een startpunt? Ik kom er niet aan uit hoe ik het moet aanpakken. is het best om een redo/undo in de component class te maken? waar ik bijhoud welke acties uitgevoerd zijn?

  2. #2
    Een ouwetje, maar had je deze thread gevonden? Die heeft weinig linkjes en diverse ideeën voor de implementatie.
    1+1=b

  3. #3
    Dankje Goleztrol, maar kom er niet aan uit. Ik dacht zelf om het zo te doen:

    Objectlist waarin ik de TIPTVGroup opsla, dit tot max 10x, en bij elke undo kan ik de versie terugplaatsen die in de objectlist staat. Zo kan ik ook een redo doen waarbij ik ipv naar beneden terug naar boven ga.. Of is dat een hele "vuile" manier? / te veel resources voor iets simpels?
    Last edited by Reidinga; 21-Aug-17 at 18:44.

  4. #4
    Tja, dat hangt er een beetje van af. Een kanaal heeft meerdere stringproperties, zoals een naam, logo, id, url.... zeg dat dat 10 properies zijn * (ruim gerekend) gemiddeld 500 tekens per stuk * 2 bytes per teken = 10KB per 'versie' van een kanaal. Dan kan je dus met 1MB geheugen een undo-lijst van 100 wijzigingen bijhouden. Met ca 2GB geheugen beschikbaar voor je programma kan je dus al een aardiger poosje knutselen voordat je in de problemen raakt.

    Je kan het ook doen zoals Marcel in die andere thread voorstelde:

    Je begint met het uitgangspunt zoals je dat geladen hebt van schijf (of een 'leeg' object als je net bent begonnen), en in je todo-lijst sla je alleen de commando's op om tot de volgende versie te komen. Daarvoor is het dan wel handig als je programma ook al die commando's gebruikt om het object te bewerken, zodat je zeker weet dat de eerste keer en de volgende keer hetzelfde werken.

    Dus bijvoorbeeld bij het starten van je commando:
    - Commando: New playlist, wordt automatisch uitgevoerd.
    Je klikt op Nieuw Kanaal. Je krijgt een schermpje om waarden in te vullen, en dat resulteert in:
    - Commando: Append Channel:name=Mijn eerste kanaal;logo=<geserialiseerd plaatje;url=example.com

    Je klikt op Nieuw Kanaal. Je krijgt een schermpje om waarden in te vullen, en dat resulteert in:
    - Commando: Append Channel:name=Mijn tweede kanaal;logo=<geserialiseerd plaatje;url=gewoontest.arg

    Je klikt op Nieuw nummer. Je krijgt een schermpje om waarden in te vullen, en dat resulteert in:
    - Commando: Append song:title=Bugje komt zo;artist=Holboercadero

    Als je nu 'undo' kiest, dan kan je twee dingen doen:
    - Het laatste commando ongedaan maken. Snelst, maar lastiger te maken. Een append ongedaan maken is redelijk simpel, omdat je dan alleen het toegevoegde ding moet verwijderen, maar bij bewerkingen of verplaatsingen binnen de lijst is het lastiger te implementeren (je moet goed de vorige waarden bewaren), en daarmee ook foutgevoeliger.
    - Beginnen bij het begin en alle commando's afspelen, behalve de laatste. Dat is wat Marcel voorstelde. Als je undo-lijst heel lang wordt dan zou je daar een vertraging in kunnen merken, maar dan moet het wel een lange lijst zijn (of inefficient gebouwd zijn ).

    Leesvoer:
    Command pattern op Wikipedia
    Voorbeeld in Delphi
    Filmpje met uitleg door Nick Hodges
    1+1=b

  5. #5
    Dankjewel Goleztrol, dat is duidelijk.
    Ik had zelf ook zoiets als idee.. namelijk, een aparte classe met objectlist welke objecten houd die undo/redo gegevens vasthouden. Dus bij elke uitgevoerde actie komt er een object met de actie gegevens bij - move/delete/add en bijhorende gegevens. Zo kan je dus ook redo doen tot je aan max van de lijst zit.

    Dat filmpje is wel heer interessant, dat zeker maar ik ben absoluut niet bekend met interfaces etc.. Dus dat is nog even boven mijn pet, om hoe ik zo'n systeem kan gaan bouwen. Zeker omdat ik dan dus mijn complete classen zal moeten "ombouwen" denk ik

    [Edit:]
    Ik heb in mijn component een event handler gemaakt die afgaat bij elke wijziging die gedaan word, dus move/add/rename etc. zowel bij kanalen als bij de groepen zelf. Door deze event handler kan ik mijn acties/knoppen enabled/disabled zetten. Zo ook de redo/undo. Ik heb nu dus een functie canundo en fuctie canredo gemaakt, die lezen de interne lijst uit met handelingen en kijkt of er een undo of redo mogelijk is. Beetje zoals hetgeen jij bedoelde denk ik maar zonder de interfaces. Dan kan ik met de procedure undo of redo de actie ongedaan maken en herhalen. Tevens sla ik in het object wat de undo/redo gegevens heeft ook een string property die ik kan weergeven in de caption van de undo/redo zodat het leest als "Ongedaan maken - Groep verwijderen", of "Ongedaan maken - Kanaal aanpassen"

    Ik houd nu geen objectlist bij maar een array, een array voor undo en voor redo een aparte. Zo kan ik het aantal undo's beperken evenals de redo's. Tevens kan ik zo als de gebruiker een nieuwe actie uitvoert de herhalingen (redo) weghalen uit de redo lijst. Anders word de undo een zooitje en gaat hij alles door elkaar doen.

    Ik wil wel overstappen naar de interfaces, maar moet ik even eerst eens meer over nazoeken om te zien of ik er kom.
    Last edited by Reidinga; 22-Aug-17 at 16:27.

  6. #6
    Update:

    Dank aan Goleztrol voor de links en uitleg, en voor eerdere posts. Ik heb dus een array gemaakt waar ik de acties in opsla, en dit werkt uitstekend.. ik kan kanalen verwijderen en ongedaan maken, toevoegen en ongedaan maken, wijzigen etc. Nu nog paar aanpassingen zodat ik ook de groepen kan ongedaan maken (gehele groep opslaan). Zo vaak gebeurd het niet dat er groepen verwijderd worden, maar soms kan dit per ongeluk voorkomen, maar staan gemiddeld een 40/50 groepen in. Dus al zou ik alles willen verwijderen en ongedaan maken, dan nog kom ik niet boven de 10mb aan info.. Dus denk dat dit voorlopig volstaat allen dank!

  7. #7
    Silly member NGLN's Avatar
    Join Date
    Aug 2004
    Location
    Werkendam
    Posts
    5,133
    [Veel te laat]
    Zie ook: Undo in listview (ook oud).
    Last edited by NGLN; 28-Aug-17 at 16:08.
    (Sender as TNLDUser).Signature := 'Groeten van Albert';

  8. #8
    Dankjewel, heb inderdaad zon zelfde oplossing gebruikt. Alleen heb ik 2 zulke lijsten, een voor undo en een voor redo.

    Screenshotje van het programma:
    Click image for larger version. 

Name:	Screentje.jpg 
Views:	117 
Size:	98.9 KB 
ID:	7625
    Last edited by Reidinga; 30-Aug-17 at 20:39.

Thread Information

Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •