amiga-news ENGLISH VERSION
.
Links| Forum| Kommentare| News melden
.
Chat| Umfragen| Newsticker| Archiv
.

amiga-news.de Forum > Programmierung > Listview ändern [ - Suche - Neue Beiträge - Registrieren - Login - ]

-1- [ - Beitrag schreiben - ]

23.01.2007, 23:47 Uhr

MaikG
Posts: 5172
Nutzer
Wenn ich ein Listview aufgebaut habe, wie ändere ich es dann?
Ich weiss wie man was hinzufügt aber was ist wenn Zeile 10 zu Zeile 3
werden soll? Muss ich die Liste dann neu aufbauen und das Gadget
refreshen oder geht das einfacher?

[ - Antworten - Zitieren - Direktlink - ]

24.01.2007, 10:37 Uhr

thomas
Posts: 7718
Nutzer

ReAction oder GadTools ?

Generell setzt man die Liste auf -1, dann kann man damit machen, was man will und dann setzt man die Liste wieder auf den Listenpointer.

Was meinst du mit einfacher ? Was ist einfacher als Remove() und Insert() ?

Hier ist ein komplettes ListBrowser-Beispiel für ReAction: http://thomas-rapp.homepage.t-online.de/examples/lb.c

Bei GadTools läuft es genauso, nur daß man statt Get/SetGadgetAttrs eben GT_Get/SetGadgetAttrs benutzen muß und daß das Attribut nicht LISTBROWSER_Labels sondern GTLV_Labels heißt. Statt LISTBROWSER_SelectedNode mußt du dir die Nummer der Node heraussuchen und GTLV_Selected setzen.

Gruß Thomas

--
Email: thomas-rapp@web.de
Home: thomas-rapp.homepage.t-online.de/

[ - Antworten - Zitieren - Direktlink - ]

24.01.2007, 17:30 Uhr

MaikG
Posts: 5172
Nutzer
>ReAction oder GadTools ?

GadTools

>Generell setzt man die Liste auf -1, dann kann man damit machen,
>was man will und dann setzt man die Liste wieder auf den
>Listenpointer.

Bei GadTools?

>Was meinst du mit einfacher ? Was ist einfacher als Remove() und
>Insert() ?

Gibs ja bei GadTools vermutlich nicht.
Ich mein sowas wie:

swap Line10 Line3


>Bei GadTools läuft es genauso, nur daß man statt Get/SetGadgetAttrs
>eben GT_Get/SetGadgetAttrs benutzen muß und daß das Attribut nicht
>LISTBROWSER_Labels sondern GTLV_Labels heißt. Statt
>LISTBROWSER_SelectedNode mußt du dir die Nummer der Node
>heraussuchen und GTLV_Selected setzen.

Muss ich mir mal runterladen.

[ - Antworten - Zitieren - Direktlink - ]

24.01.2007, 17:38 Uhr

thomas
Posts: 7718
Nutzer
@MaikG:

Zitat:
Bei GadTools?

Ja.


Zitat:
Gibs ja bei GadTools vermutlich nicht.

Das sind Funktionen der exec.library, die gibt's überall.


Zitat:
swap Line10 Line3

GT_SetGadgetAttrs (listbrowser,window,requester,GTLV_Labels,-1,TAG_END);
node9 = node10->ln_Pred;
node2 = node3->ln_Pred;
Remove (node10);
Remove (node3);
Insert (list,node10,node2);
Insert (list,node3,node9);
GT_SetGadgetAttrs (listbrowser,window,requester,GTLV_Labels,list,TAG_END);

Gruß Thomas

--
Email: thomas-rapp@web.de
Home: thomas-rapp.homepage.t-online.de/

[ - Antworten - Zitieren - Direktlink - ]

24.01.2007, 19:31 Uhr

MaikG
Posts: 5172
Nutzer
>Das sind Funktionen der exec.library, die gibt's überall.

Ach stimmt ja.


>GT_SetGadgetAttrs (listbrowser,window,requester,GTLV_Labels,-1,TAG_END);
>node9 = node10->ln_Pred;
>node2 = node3->ln_Pred;
>Remove (node10);
>Remove (node3);
>Insert (list,node10,node2);
>Insert (list,node3,node9);
>GT_SetGadgetAttrs (listbrowser,window,requester,GTLV_Labels,list,TAG_END);

Und nodeXX sind Pointer zu den einzelnen Node's?
Ist das jetzt 10 mit 2 vertauschen und 3 mit 9?

Bei dem Beispiel was ich habe wird z.B. das entfehrnen
der nodes z.B. so gemacht, der eine scheint auf dem nächsten
zu verweisen, extra Pointer sind da nicht:

code:
worknode&=PEEKL(ListHead&+lh_head)
DO
	nextnode&=PEEKL(worknode&+ln_Succ)
	IF nextnode&=0 THEN EXIT LOOP
	FreeMem worknode&,node_sizeof
	worknode&=nextnode&
LOOP



[ - Antworten - Zitieren - Direktlink - ]

25.01.2007, 09:09 Uhr

thomas
Posts: 7718
Nutzer
@MaikG:
Zitat:
Ist das jetzt 10 mit 2 vertauschen und 3 mit 9?

Nein, es macht genau das, was da steht: es entfernt node3 und node10 und fügt dann node3 hinter node9 ein und node10 hinter node2.

Du hattest also vorher 1 2 3 4 5 6 7 8 9 10, dann 1 2 4 5 6 7 8 9 und zuletzt 1 2 10 4 5 6 7 8 9 3.

Zitat:
Bei dem Beispiel was ich habe wird z.B. das entfehrnen
der nodes z.B. so gemacht, der eine scheint auf dem nächsten
zu verweisen, extra Pointer sind da nicht:


Ich weiß nicht genau, was du damit meinst. Das Beispiel entfernt überhaupt nichts. Es gibt nur den Speicher aller Nodes nacheinander frei, ohne die Verpointerung entsprechend anzupassen. D.h. bereits nach dem Freigeben der ersten Node ist die Liste ungültig, die Pointer der Liste und der nächsten Node zeigen ins Leere. Das funktioniert nur, weil du die Liste anschließend nicht mehr benutzt.

Bevor du irgendwelche Annahmen machst ("scheint auf den nächsten zu verweisen", welch ein Horror) solltest du dich vielleicht ein wenig mit verketteten Listen beschäftigen, vielleicht ein Buch über Algorithmen und Datenstrukturen lesen. Speziell mit doppelt verketteten Listen und ganz speziell damit, wie sie in der exec.library implementiert sind.

Gruß Thomas

--
Email: thomas-rapp@web.de
Home: thomas-rapp.homepage.t-online.de/

[ - Antworten - Zitieren - Direktlink - ]

25.01.2007, 10:12 Uhr

MaikG
Posts: 5172
Nutzer
>Du hattest also vorher 1 2 3 4 5 6 7 8 9 10, dann 1 2 4 5 6 7 8 9 und zuletzt 1 2 10 4 5 6 7 8 9 3.

Aha, okay.




>Ich weiß nicht genau, was du damit meinst. Das Beispiel entfernt
>überhaupt nichts. Es gibt nur den Speicher aller Nodes nacheinander
>frei, ohne die Verpointerung entsprechend anzupassen.

Ja, ist nur zum freigeben des Listviews beim Beenden.
Ich wollte damit nur sagen das in diesem beispiel nicht jeder
node eine eigene Variable hat. Und fragen obe nodeXX nun Pointer
auf die Einzelnen Einträge sind und ich dafür dann entsprechende
Variablen(Array) anlegen muss.


>Bevor du irgendwelche Annahmen machst ("scheint auf den nächsten zu
<>verweisen", welch ein Horror) solltest du dich vielleicht ein
>wenig mit verketteten Listen beschäftigen,

Muss ich mal suchen


> vielleicht ein Buch über Algorithmen und Datenstrukturen lesen.

Wozu brauche ich hier Algorithmen? Ein Buch ist wohl übertrieben
für so ein kleines Listview, in der Zeit könnte ich dann ja glatt
mein eigenes Listviewgadget Programmieren.

[ - Antworten - Zitieren - Direktlink - ]

25.01.2007, 10:51 Uhr

thomas
Posts: 7718
Nutzer
Zitat:
Und fragen obe nodeXX nun Pointer
auf die Einzelnen Einträge sind und ich dafür dann entsprechende
Variablen(Array) anlegen muss.


Du brauchst vier Variablen:

Zum einen hast du die beiden Nodes, die du vertauschen möchstest, nennen wir sie tauschnode1 und tauschnode2. Und dann mußt du dir die Position merken, an der die Nodes nachher eingefügt werden sollen. Bei Insert mußt du die Node angeben, hinter der die neue Node eingefügt wird. Also brauchst du die Node vor tauschnode1 (nennen wir sie vor_node1) und die Node vor tauschnode2 (vor_node2).

Dann kommt folgende Routine heraus:

code:
void swap_listbrowser_nodes (struct Gadget *lb,struct Window *win,struct Node *tauschnode1,struct Node *tauschnode2)

{
struct Node *vor_node1;
struct Node *vor_node2;
struct List *labels;

GT_GetGadgetAttrs (lb,win,NULL,GTLV_Labels,&labels,TAG_END);
GT_SetGadgetAttrs (lb,win,NULL,GTLV_Labels,-1,TAG_END);
vor_node1 = tauschnode1->ln_Pred;
vor_node2 = tauschnode2->ln_Pred;
Remove (tauschnode1);
Remove (tauschnode2);
Insert (list,tauschnode2,vor_node1);
Insert (list,tauschnode1,vor_node2);
GT_SetGadgetAttrs (lb,win,NULL,GTLV_Labels,labels,TAG_END);
}


Gruß Thomas

--
Email: thomas-rapp@web.de
Home: thomas-rapp.homepage.t-online.de/

[ - Antworten - Zitieren - Direktlink - ]

25.01.2007, 12:49 Uhr

Mad_Dog
Posts: 1944
Nutzer
Zitat:
Original von MaikG:

>Bevor du irgendwelche Annahmen machst ("scheint auf den nächsten zu
<>verweisen", welch ein Horror) solltest du dich vielleicht ein
>wenig mit verketteten Listen beschäftigen,

Muss ich mal suchen


Guckst Du hier:

http://w3.norman-interactive.com/C-Kurs_9_1.html

Das ist nur eine ganz kurze, allgemeine Einführung in (einfach-)verkettete Listen.

Zitat:
> vielleicht ein Buch über Algorithmen und Datenstrukturen lesen.

Wozu brauche ich hier Algorithmen?


Na Du willst doch Elemente vertauschen, einfügen und löschen, oder?

Tipp: Geh mal in die Bücherei und besorg Dir folgendes Buch:

Algorithmen in C
von Robert Sedgewick
ISBN 3-8273-7182-1

Da drin sind die wichtigsten Grundlagen zu Datenstrukturen und Algorithmen beschrieben.

Wenn Du das Prinzip nicht verstanden hast, nach dem die Datenstrukturen im AmigaOS aufgebaut sind, kannst Du auch nichts damit anfangen - Du pfuschst dann nur daran rum - und das willst Du doch nicht, oder?

Nachtrag:

Auf Wikipedia gibt's auch einen einführenden Artikel zum Thema:

http://de.wikipedia.org/wiki/Liste_(Datenstruktur)

Hoffe, das hilft Dir weiter.

--
http://www.norman-interactive.com

[ Dieser Beitrag wurde von Mad_Dog am 25.01.2007 um 13:02 Uhr geändert. ]

[ - Antworten - Zitieren - Direktlink - ]

25.01.2007, 18:11 Uhr

MaikG
Posts: 5172
Nutzer
>Zum einen hast du die beiden Nodes, die du vertauschen möchstest,
>nennen wir sie tauschnode1 und tauschnode2. Und dann mußt du dir
>die Position merken, an der die Nodes nachher eingefügt werden
>sollen. Bei Insert mußt du die Node angeben, hinter der die neue
>Node eingefügt wird. Also brauchst du die Node vor tauschnode1
>(nennen wir sie vor_node1) und die Node vor tauschnode2 (vor_node2).

Verstehe, aber wenn ich beliebige unbekannte einträge bearbeiten
will brauche ich zeiger auf jeden einzelnen Eintrag.
Weil, wie ich jetzt gelesen habe zeigt ein node immer auf
das nächste, man könnte zwar nachträglich von node1 zu
node245 gehen um den Zeiger zu node 246 zu bekommen. Aber
es ist doch einfacher bei der Node erzeugung gleich die Adresse
in ein Array abzulegen.


>Na Du willst doch Elemente vertauschen, einfügen und löschen, oder?

Ja, nur vertauschen eigentlich, aber das ist ja nur eine Standart
liste.


>Wenn Du das Prinzip nicht verstanden hast, nach dem die
>Datenstrukturen im AmigaOS aufgebaut sind, kannst Du auch nichts
>damit anfangen - Du pfuschst dann nur daran rum - und das willst
>Du doch nicht, oder?

Habs verstanden, ein Node enthält einen Wert und einen Zeiger
auf den nächsten node. Das ist damit man Speicher sparrt, den ggf. aber
fragmentiert.

[ - Antworten - Zitieren - Direktlink - ]

25.01.2007, 22:35 Uhr

MaikG
Posts: 5172
Nutzer
Also der Source übersetzt in Basic löscht nur 2 Einträge, fügt diese
aber nicht woanders wieder ein, hab das jetzt so:


code:
TAGLIST VARPTR(temptag&(0)), GTLV_Labels& ,-1&,TAG_END&
 GT_SetGadgetAttrsA my_gads&(MYGAD_LISTVIEW%), win&, 0,VARPTR(temptag&(0))

 Remove nodes&(10)
 Insert listviewlist&, nodes&(10),nodes&(9)

 SWAP nodes&(9), nodes&(10) REM Pointer 9 und 10 vertauschen.

 TAGLIST VARPTR(temptag&(0)),GTLV_Labels& ,listviewlist&,TAG_END&
 GT_SetGadgetAttrsA my_gads&(MYGAD_LISTVIEW%), win&, 0,VARPTR(temptag&(0))


Funktionieren tut es, ist es so korrekt gemacht?

[ Dieser Beitrag wurde von MaikG am 25.01.2007 um 22:35 Uhr geändert. ]

[ - Antworten - Zitieren - Direktlink - ]

25.01.2007, 22:44 Uhr

Holger
Posts: 8116
Nutzer
Zitat:
Original von MaikG:
Habs verstanden, ein Node enthält einen Wert und einen Zeiger
auf den nächsten node. Das ist damit man Speicher sparrt, den ggf. aber
fragmentiert.

Nein, man spart überhaupt keinen Speicher. Im Gegenteil, im Vergleich zu bestimmten anderen Datenstrukturen, benötigt das mehr Speicher. Der Vorteil liegt darin, dass Operationen wie "Reihenfolge ändern", "Einfügen" und "Entfernen" sehr schnell durchgeführt werden, unabhängig von der Größe der List-Nodes. Auf die Fragmentierung hat das gar keinen Einfluss, weil diese von der Strategie abhängen, mit der man den Speicher für die Nodes belegt. Ein wesentlicher Nachteil dieser Datenstruktur ist, dass die Objekte immer nur in einer einzigen Liste enthalten sein können.

Du solltest Dich wirklich mit dem Thema „Algorithmen und Datenstrukturen“ befassen.

mfg
--
Good coders do not comment. What was hard to write should be hard to read too.

[ - Antworten - Zitieren - Direktlink - ]

26.01.2007, 12:35 Uhr

Mad_Dog
Posts: 1944
Nutzer
Zitat:
Original von MaikG:

Aber es ist doch einfacher bei der Node erzeugung gleich die Adresse
in ein Array abzulegen.


Wozu das denn? Du merkst Dir nur den Zeiger auf den ersten Node - diese Variable wird auch Anker genannt. Die Zeiger der auf die anderen Nodes sind ja jeweils im vorherigen Node abgelegt (Tail).

Der Vorteil einer solchen Datenstruktur ist, daß sie dynamisch ist, d.h. Du kannst sie zur Laufzeit größer oder kleiner machen, aufspalten, umordnen usw. - und zwar ohne daß Du dabei jedesmal den gesamten Inhalt umkopieren musst. Du kopierst nur die Zeiger um, nicht aber die Daten.



--
http://www.norman-interactive.com

[ - Antworten - Zitieren - Direktlink - ]

26.01.2007, 18:24 Uhr

MaikG
Posts: 5172
Nutzer
>Nein, man spart überhaupt keinen Speicher.

Doch wenn ich DIM Entry$(4000) mache und z.B. nur 10 Einträge
hineingelegt werden braucht das mehr speicher.
Bei 4000 dann natürlich nicht mehr.


>Wozu das denn? Du merkst Dir nur den Zeiger auf den ersten Node
>- diese Variable wird auch Anker genannt.

Ja, muss man ja.

>Die Zeiger der auf die anderen Nodes sind ja jeweils im vorherigen
>Node abgelegt (Tail).

Ja schon, aber ich müsste dann ja jedesmal so tun

Node1 - nächsten Zeiger auslesen
zu Node 2
Node2 - nächsten Zeiger auslesen
usw.
Die Zeiger bekomme ich doch beim anlegen der einträge, warum
also Resourcen verschwenden?


>Du kopierst nur die Zeiger um, nicht aber die Daten.

mach ich doch, der swap befehl tauscht nur die Zeiger um.

[ - Antworten - Zitieren - Direktlink - ]

26.01.2007, 19:40 Uhr

thomas
Posts: 7718
Nutzer
@MaikG:
Zitat:
Doch wenn ich DIM Entry$(4000) mache und z.B. nur 10 Einträge
hineingelegt werden braucht das mehr speicher.
Bei 4000 dann natürlich nicht mehr.


:-)

Darum geht es ja bei der verketteten Liste. Bei einem Array mußt du vorher eine Annahme machen, wieviele Elemente du brauchst. Bei einer verketteten Liste kannst du vollkommen dynamisch Elemente hinzufügen und entfernen.

Der Vergleich des Speicherverbrauchs wird aber immer bei gleicher Anzahl Elemente gemacht und da ist die Liste aufgrund der benötigten Pointer klar schlechter.

Das gleiche gilt beim Zugriff, das hast du auch schon erkannt. Beim Array kann man direkt auf ein bestimmtes Element zugreifen, während man sich bei der Liste von Pointer zu Pointer hangeln muß.

Allerdings gibt es Situationen, in denen der Nachteil "ich brauche eine Obergrenze" so stark wiegt, daß man auf die Vorteile Direktzugriff und Speicherersparnis verzichtet.

Dein "Array aus Pointern" ist da so ein Zwischending. Du versuchst, die Vorteile des Array wieder hineinzubringen, ohne die Liste zu verlieren. Das funktioniert aber nicht:

Zitat:
mach ich doch, der swap befehl tauscht nur die Zeiger um.

Damit vertauscht du aber nur *deine* beiden Pointer. Nicht die Pointer, die die Liste bilden. Die Liste ist nach wie vor intakt und hat die gleiche Reihenfolge woe vorher.

Zitat:
Node1 - nächsten Zeiger auslesen
zu Node 2
Node2 - nächsten Zeiger auslesen
usw.
Die Zeiger bekomme ich doch beim anlegen der einträge, warum
also Resourcen verschwenden?


Speicher ist auch eine Resource. Und dein DIM xy(4000) verschwendet sehr viel mehr Speicher als die Routine, die die Liste durchgeht.

Außerdem hast du doch irgendwie herausbekommen, daß du die Einträge 3 und 10 vertauschen möchtest. Dafür hast du doch vermutlich die Liste ohnehin schon untersuchen müssen und kannst dir die Pointer von der Untersuchung merken.

Gruß Thomas

--
Email: thomas-rapp@web.de
Home: thomas-rapp.homepage.t-online.de/

[ - Antworten - Zitieren - Direktlink - ]

26.01.2007, 23:24 Uhr

MaikG
Posts: 5172
Nutzer
>Dein "Array aus Pointern" ist da so ein Zwischending. Du versuchst,
>die Vorteile des Array wieder hineinzubringen, ohne die Liste zu
>verlieren. Das funktioniert aber nicht:
>Damit vertauscht du aber nur *deine* beiden Pointer. Nicht die
>Pointer, die die Liste bilden. Die Liste ist nach wie vor intakt
>und hat die gleiche Reihenfolge woe vorher.

Ja, irgendwie funktioniert da irgendetwas nicht richtig.
Ich hab es zwar so hinbekommen das es geht, aber ruft
man die Funktion das erste mal auf gehts nicht, beim 2.mal ja.
Lastline% ist der selektierte Eintrag.

code:
REM down
    TAGLIST VARPTR(temptag&(0)), GTLV_Labels& ,-1&,TAG_END&
    GT_SetGadgetAttrsA my_gads&(MYGAD_LISTVIEW%), win&, 0&,VARPTR(temptag&(0))

    Remove nodes&(Lastline%)
    Insert listviewlist&, nodes&(Lastline%),nodes&(Lastline%+1) REM 10 9
    SWAP nodes&(Lastline%+1), nodes&(Lastline%)
    INCR Lastline%

    TAGLIST VARPTR(temptag&(0)),GTLV_Labels& ,listviewlist&,TAG_END&
    GT_SetGadgetAttrsA my_gads&(MYGAD_LISTVIEW%), win&, 0&,VARPTR(temptag&(0))


REM up
    TAGLIST VARPTR(temptag&(0)), GTLV_Labels& ,-1&,TAG_END&
    GT_SetGadgetAttrsA my_gads&(MYGAD_LISTVIEW%), win&, 0&,VARPTR(temptag&(0))

    Remove nodes&(Lastline%)
    Insert listviewlist&, nodes&(Lastline%),nodes&(Lastline%-1) REM 10 9
    SWAP nodes&(Lastline%-1), nodes&(Lastline%)
    DECR Lastline%

    TAGLIST VARPTR(temptag&(0)),GTLV_Labels& ,listviewlist&,TAG_END&
    GT_SetGadgetAttrsA my_gads&(MYGAD_LISTVIEW%), win&, 0&,VARPTR(temptag&(0))



>Speicher ist auch eine Resource. Und dein DIM xy(4000) verschwendet
>sehr viel mehr Speicher als die Routine, die die Liste durchgeht.

Bei 4000 Einträgen dauerts aber lange bis ich den 3999 Eintrag rausgesucht
habe.

>Außerdem hast du doch irgendwie herausbekommen, daß du die Einträge
>3 und 10 vertauschen möchtest. Dafür hast du doch vermutlich die
>Liste ohnehin schon untersuchen müssen und kannst dir die Pointer
>von der Untersuchung merken.

Also eigentlich ist es eine Liste(oder soll es werden) mit Einträgen
die vom User beliebig mit UP/Down sortiert werden kann

Gibts kein Listview das ein Array aktzeptiert?


[ Dieser Beitrag wurde von MaikG am 26.01.2007 um 23:25 Uhr geändert. ]

[ - Antworten - Zitieren - Direktlink - ]

27.01.2007, 00:24 Uhr

thomas
Posts: 7718
Nutzer
@MaikG:

Das Down müßte funktionieren. Aber bei dem Up hast du dich verrechnet.

Zitat:
Insert listviewlist&, nodes&(Lastline%),nodes&(Lastline%-1)

Du fügst die Node, die du verschieben möchtest, hinter der ein, die davor liegt. Das ist der gleiche Platz wie vorher. Du mußt sie hinter Lastline-2 einfügen.

Außerdem berücksichtigst du nicht den Fall, wenn du oben ankommst. Was machst du, wenn Lastline 2 ist ? Dann ist Lastline-2 = 0 und das ist kein Array-Element.

Das gleiche gilt für Down, wenn Lastline die vorletzte Zeile ist und der User auf Down klickt.

Das Konstrukt, das ich oben benutzt habe, funktioniert mit Exec-Listen deshalb ohne Fallunterscheidung, weil Exec-Listen etwas trickreich aufgebaut sind, besonders der List-Header. Dort wurden mit drei Pointern zwei Pseudo-Nodes versteckt. Dadurch wird bei Insert(...,...,firstnode->ln_Pred) bzw. Insert(...,...,lastnode) automatisch der Header angepaßt und man muß nicht unterscheiden, ob man am Anfang, am Ende oder in der Mitte einfügt. Das ist auch der Grund, warum bei Remove nur die Node und nicht auch die List angegeben werden muß.

Gruß Thomas

--
Email: thomas-rapp@web.de
Home: thomas-rapp.homepage.t-online.de/

[ - Antworten - Zitieren - Direktlink - ]

27.01.2007, 15:10 Uhr

MaikG
Posts: 5172
Nutzer
>Du fügst die Node, die du verschieben möchtest, hinter der ein,
>die davor liegt. Das ist der gleiche Platz wie vorher. Du mußt sie
>hinter Lastline-2 einfügen.

Ah, cool jetzt gehts.

>Außerdem berücksichtigst du nicht den Fall, wenn du oben ankommst.
>Was machst du, wenn Lastline 2 ist ? Dann ist Lastline-2 = 0 und
>das ist kein Array-Element.

Also ich habs oben und unten begrenzt, also was in der obersten
Zeile ist kann nicht weiter nach oben verschoben werden.
Das Array beginnt in Basic bei 0 (wenn nicht anders angegeben),
also sinds genau genommen 4001.


Hab noch eine Frage, kann man das Gadtools-Listview dazu
bringen den gewählten eintrag mit blau hinterlegt zu lassen,
auch wenn die Maustaste losgelassen wurde?

[ - Antworten - Zitieren - Direktlink - ]

27.01.2007, 15:17 Uhr

Holger
Posts: 8116
Nutzer
Zitat:
Original von MaikG:
>Nein, man spart überhaupt keinen Speicher.

Doch wenn ich DIM Entry$(4000) mache und z.B. nur 10 Einträge
hineingelegt werden braucht das mehr speicher.
Bei 4000 dann natürlich nicht mehr.

Du hast ja nicht gesagt, womit Du vergleichst. Wenn ich DIM Entry$(10) mache, und genau 10 Einträge brauche, verbraucht das weniger Speicher als 10 Objekte, die jeweils zwei Pointer auf Vorgänger und Nachfolger mitschleppen. Und Basic zeichnet sich ja gerade dadurch aus, dass das dynamischen Vergrößern eines DIM-Arrays, zumindest bei einigen Dialekten problemlos möglich ist.

Der Nachteil ist natürlich, das beim Array-Resize die Daten kopiert werden müssen, was Zeit kostet. Genau das ist die Motivation für den Einsatz von verketteten Listen, höhere Performance bei Insert und Remove, dafür der Kompromiss der geringeren Performance bei einem direkten Zugriff auf ein Element aus der Mitte.

Zitat:
Original von thomas:
Darum geht es ja bei der verketteten Liste. Bei einem Array mußt du vorher eine Annahme machen, wieviele Elemente du brauchst.

Oder Performance-Einbußen in Kauf nehmen, wenn die Annahme zu klein war, bzw. Speicherverschwendung, wenn sie zu groß war.
Zitat:
Dein "Array aus Pointern" ist da so ein Zwischending. Du versuchst, die Vorteile des Array wieder hineinzubringen, ohne die Liste zu verlieren. Das funktioniert aber nicht:
Es funktioniert, wenn man halt das Anpassen der Listen-Verkettung auch durchführt, was aber kein Nachteil der Datenstruktur "Array von Pointern" ist, sondern daher rührt, dass eben AmigaOS nur doppelt-verkettete Listen als Input akzeptiert.

Trotzdem kann das als temporärer Speicher durchaus sinnvoll sein, wenn man z.B. eine komplette Sortierung einer sehr großen Liste vornimmt und erst danach wieder die Verkettungs-Pointer anpasst, was eine O(n) Operation ist.
Zitat:
Original von MaikG:
Bei 4000 Einträgen dauerts aber lange bis ich den 3999 Eintrag rausgesucht habe.

Da gibt's einen einfachen Trick: merke Dir die Anzahl der Einträge. Wenn Du ein Element e[x>(Anzahl/2)] suchst, fange von hinten an. Schon hast Du die maximale Such-Zeit halbiert. Übrigens ist 4000 noch keine so beeindruckende Zahl...

Ähnliche Feinheiten gibt es auch bei anderen Operationen, je nach dem, was man machen will. Da kann man sich schon mal einen Pointer auf eine Node merken, wenn man weiß, dass man sich demnächst relativ zu dieser in der Liste bewegen will.
Zitat:
Gibts kein Listview das ein Array aktzeptiert?

Nicht auf dem Amiga. Da sind doppelt-verkettete Listen das erste Mittel der Wahl. Du weißt doch: wenn man als einziges Werkzeug den Hammer kennt, sieht für einen jedes Problem wie ein Nagel aus...

mfg
--
Good coders do not comment. What was hard to write should be hard to read too.

[ - Antworten - Zitieren - Direktlink - ]

27.01.2007, 15:30 Uhr

Holger
Posts: 8116
Nutzer
Zitat:
Original von MaikG:
Hab noch eine Frage, kann man das Gadtools-Listview dazu
bringen den gewählten eintrag mit blau hinterlegt zu lassen,
auch wenn die Maustaste losgelassen wurde?


Meines Wissens nur über einen eigenen Rendering-Hook, das dürfte in Basic deutlich schwerer zu machen sein.

mfg
--
Good coders do not comment. What was hard to write should be hard to read too.

[ - Antworten - Zitieren - Direktlink - ]

27.01.2007, 16:04 Uhr

thomas
Posts: 7718
Nutzer
Zitat:
Hab noch eine Frage, kann man das Gadtools-Listview dazu
bringen den gewählten eintrag mit blau hinterlegt zu lassen,
auch wenn die Maustaste losgelassen wurde?


GTLV_ShowSelected,NULL

Wenn die ausgewählte Zeile automatisch in einem String-Gadget erscheinen soll, gibst du statt NULL einfach den Zeiger auf das String-Gadget an.

Gruß Thomas

--
Email: thomas-rapp@web.de
Home: thomas-rapp.homepage.t-online.de/

[ - Antworten - Zitieren - Direktlink - ]

27.01.2007, 16:06 Uhr

thomas
Posts: 7718
Nutzer
Zitat:
Also ich habs oben und unten begrenzt, also was in der obersten
Zeile ist kann nicht weiter nach oben verschoben werden.


Das habe ich mir schon gedacht. Aber wenn du die zweite Zeile nach ganz oben schieben möchtest, funktioniert dein Programm nicht.

Gruß Thomas

--
Email: thomas-rapp@web.de
Home: thomas-rapp.homepage.t-online.de/

[ - Antworten - Zitieren - Direktlink - ]

27.01.2007, 18:02 Uhr

MaikG
Posts: 5172
Nutzer
>Da gibt's einen einfachen Trick: merke Dir die Anzahl der Einträge.
>Wenn Du ein Element e[x>(Anzahl/2)] suchst, fange von hinten an.

Ja, aber ein Array ist mir lieber...


>GTLV_ShowSelected,NULL
>Wenn die ausgewählte Zeile automatisch in einem String-Gadget
>erscheinen soll, gibst du statt NULL einfach den Zeiger auf das
>String-Gadget an.


Funktioniert, aber beim verschieben geht der Balken nicht mit.


>Das habe ich mir schon gedacht. Aber wenn du die zweite Zeile nach
>ganz oben schieben möchtest, funktioniert dein Programm nicht.

Nein, das geht schon. Lastline ist der Code der vom Listview
kommt +1. Also Ursprung 1.

[ - Antworten - Zitieren - Direktlink - ]

27.01.2007, 22:48 Uhr

MaikG
Posts: 5172
Nutzer
So Balken geht jetzt auch mit und es wird auch Automatisch
gescrollt.


Danke @all

[ - Antworten - Zitieren - Direktlink - ]


-1- [ - Beitrag schreiben - ]


amiga-news.de Forum > Programmierung > Listview ändern [ - Suche - Neue Beiträge - Registrieren - Login - ]


.
Impressum | Datenschutzerklärung | Netiquette | Werbung | Kontakt
Copyright © 1998-2024 by amiga-news.de - alle Rechte vorbehalten.
.