Eigene Komponente und Repaint

Rund um die LCL und andere Komponenten
Mathias
Beiträge: 6194
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Eigene Komponente und Repaint

Beitrag von Mathias »

...weitere Vorteile von Properties: Wenn man später merkt, daß der Bezeichner doch eher nur gelesen werden werden darf,

Das habe ich auch schon gebraucht, wen etwas ReadOnly sein soll.
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Mathias
Beiträge: 6194
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Eigene Komponente und Repaint

Beitrag von Mathias »

Jetzt kommt das nächste Problem. Und zwar will ich den Text Scrollen.
Dafür sind mir 2 Ideen gekommen.

1. Variante:
Ich nehme eine Horizontalen und ein Vertikallen - TScrollBar.

2. Variante
Ich nehme eine TScrollBox, aber da wird der Effekt kommen, das das Panel immer grösser wird, je länger der Text.
Und daher denke ich fällt dies weg.

Was bei beiden Varianten noch ein Problem ist.
Der Vertikale ist einfach, Items.Count * Zeichenhöhe und man hat die Anzahl Pixel für das Panl.Hight. oder beim TScrollBar.max.
Bei der Horizontalen wird es schon rechenintensiver. Ich muss alle Text-Zeilen durchlaufen und mit Canvas.TextWidth, die längste Zeile ermitteln.
Dabei nehme ich an, wen der Text sehr lange wird kommt das Ganze ins stotter.

Was ich bei beiden Varianten machen kann um CPU-Zeit zu sparen, ich kann ermitteln welche Zeilen sichtbar sind und nur diese mit Canvas.TextOut ausgeben.

Wie macht dies TMemo, damit können auch sehr lange Texte verarbeitet werden.
Oder soll ich beim Record TColorString noch eine dritte Variable mit der Textlänge hinzufügen ?

Wer hat eine gute Idee, was am besten ist ? :wink:
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Michl
Beiträge: 2505
Registriert: Di 19. Jun 2012, 12:54

Re: Eigene Komponente und Repaint

Beitrag von Michl »

Mathias hat geschrieben:Wer hat eine gute Idee, was am besten ist ? :wink:

1. Möglichkeit: Packe eine Scrollbar neben das Panel. Das Panel bleibt unberührt in seiner Form. Scrolle nur das Offset deiner Liste und zeige die x Einträge an.
2. Möglichkeit: Nimm eine fertige Komponente (z.B. das VirtualStringTree ist sehr schnell und gut verbiegbar).

Code: Alles auswählen

type
  TLiveSelection = (lsMoney, lsChilds, lsTime);
  TLive = Array[0..1] of TLiveSelection; 

Mathias
Beiträge: 6194
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Eigene Komponente und Repaint

Beitrag von Mathias »

1. Möglichkeit: Packe eine Scrollbar neben das Panel. Das Panel bleibt unberührt in seiner Form. Scrolle nur das Offset deiner Liste und zeige die x Einträge an.

Ich denke, dies ist besser als ein riessen Panel in einer Scrollbox.
Aber wie mache ich dies am besten für die Horizontale ?
Gibt es einen Weg, ohne das ich bei jedem Paint, im meiner Liste alle Einträge mit Canvas.TextWidth durchsuchen muss ?
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

wp_xyz
Beiträge: 4889
Registriert: Fr 8. Apr 2011, 09:01

Re: Eigene Komponente und Repaint

Beitrag von wp_xyz »

Führe ein Variable TopLine ein. Die Ausgabe beginnt erst bei diesem ZeilenIndex und endet, wenn die Zahl der sichtbaren Zeilen überschritten wird. Das heißt, du musst dir während Paint die vertikale Pixelposition merken und mit der Ausgabe enden, wenn der untere Rand des sichtbaren Bereichs unterschritten wird. Oder du berechnest dir aus der Memo-Höhe und der Zeilenhöhe die Zahl der sichtbarn Zeilen. TopLine kannst du auch mit der Position eines vertikalen Scrollbars synchronisieren. ScrollBar.Max ist die Anzahl der Zeilen (evtl reduziert um die Zahl der sichtbaren Zeilen, so dass die letzte Zeilen unten im Memo erscheint, nicht oben - oder so ähnlich).

Beim Einlesen der ColorStringListe ins Memo würde ich alle Zeilen durchlaufen und für den Canvas des Memo und den entsprechenden Font die längste Zeile ermitteln, das bestimmt das Max des horizontalen Scrollbalkens. Die Ausgabe jeder Zeile beginnt nicht bei x=0 sondern wird mit einem negativen x-Offset versehen, so dass die Zeile links vom sichtbaren Bereich beginnt. Der Betrag des x-Offset entspricht der Position des horizontaln Scrollbalkens (evtl. wieder um die Pixelbreite des Memos korrigieren - das weiß ich jetzt nicht genau).

Mathias
Beiträge: 6194
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Eigene Komponente und Repaint

Beitrag von Mathias »

Mit der Vertikalen, sieht es momentan gar nicht so schlecht aus, ausser das noch etwas mit der Formal nicht stimmt, und in der falschen Methode wird es auch noch sein.
Aber dies were ich schon noch hin kriegen.

Beim Einlesen der ColorStringListe ins Memo würde ich alle Zeilen durchlaufen und für den Canvas des Memo und den entsprechenden Font die längste Zeile ermitteln,

An das habe ich auch schon gedacht, nur wen ich aber genau diese Zeile lösche, dann stimmt die Länge nicht mehr. Eigentlich wäre dies nur ein Schönheitsfehler.

Wegen der Horizontalen, habe ich gerade festgestellt, das die Lazarus-IDE dies sehr einfach gemacht hat. Dort ist einfach eine lange ScrollBar über mehrere Seiten.
Aber die TMemo, die nimmt es da einiges genauer.

Führe ein Variable TopLine ein. Die Ausgabe beginnt erst bei diesem ZeilenIndex und endet, wenn die Zahl der sichtbaren Zeilen überschritten wird. Das heißt, du musst dir während Paint die vertikale Pixelposition merken und mit der Ausgabe enden, wenn der untere Rand des sichtbaren Bereichs unterschritten wird.

Das wird einer der nächsten Schritte sein.
Dateianhänge
TList_ColorString.zip
(126.98 KiB) 36-mal heruntergeladen
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

wp_xyz
Beiträge: 4889
Registriert: Fr 8. Apr 2011, 09:01

Re: Eigene Komponente und Repaint

Beitrag von wp_xyz »

Mathias hat geschrieben:
Beim Einlesen der ColorStringListe ins Memo würde ich alle Zeilen durchlaufen und für den Canvas des Memo und den entsprechenden Font die längste Zeile ermitteln,

An das habe ich auch schon gedacht, nur wen ich aber genau diese Zeile lösche, dann stimmt die Länge nicht mehr.

Genaugenommen, gehört das in die OnChange-Ereignisbehandlung: Bei jeder Änderung an der Liste muss wieder die Liste durchlaufen und die längste Zeile bestimmt werden. Oder du protokollierst den Index der längsten Zeile und führst diese Neuberechnung nur dann aus, wenn die Änderung die längste Zeile betrifft, und auch nur dann, wenn diese kürzer wird. Evtl. muss dann die Definition des OnChange-Ereignisses geändert werden, damit das Memo mitkriegt, welche Zeile geändert wurde.

Mathias
Beiträge: 6194
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Eigene Komponente und Repaint

Beitrag von Mathias »

Da ich meine Komponente gedacht ist, um eine Logfiles-Ausgabe zu machen, habe ich habe ich es natürlich einfach, mit der längsten Zeile, da man im in einem Logfiles keine Zeilen löscht.

Oder du protokollierst den Index der längsten Zeile und führst diese Neuberechnung nur dann aus, wenn die Änderung die längste Zeile betrifft, und auch nur dann, wenn diese kürzer wird

Kommt da nicht eine Sanduhr, wen man eine sehr grosses Text-Datei hat ?
Oder würde man so was in ein OnIdle Ereigniss bauen ?

Wie ist dies bei TMemo gelöst ?

Im Anhang habe ich die Vertikale schon recht gut hin gekriegt. Oder hättet ihr das anders gelöst ?
Was noch fehlt ist das Maus-Rad.
Dateianhänge
TList_ColorString.zip
(126.99 KiB) 33-mal heruntergeladen
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

wp_xyz
Beiträge: 4889
Registriert: Fr 8. Apr 2011, 09:01

Re: Eigene Komponente und Repaint

Beitrag von wp_xyz »

Mathias hat geschrieben:Im Anhang habe ich die Vertikale schon recht gut hin gekriegt. Oder hättet ihr das anders gelöst ?

Ja. In deiner Paint-Methode gibst du ALLE Strings aus, wobei bei einer großen Datei die meisten nicht sichtbar sind. Das dauert. Lasse die i-Schleife nur zwischen der ersten und letzten sichtbaren Zeile laufen.

Mathias
Beiträge: 6194
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Eigene Komponente und Repaint

Beitrag von Mathias »

wp_xyz hat geschrieben:
Mathias hat geschrieben:Im Anhang habe ich die Vertikale schon recht gut hin gekriegt. Oder hättet ihr das anders gelöst ?

Ja. In deiner Paint-Methode gibst du ALLE Strings aus, wobei bei einer großen Datei die meisten nicht sichtbar sind. Das dauert. Lasse die i-Schleife nur zwischen der ersten und letzten sichtbaren Zeile laufen.

Dies wollte ich eigentlich auch machen, aber dies ist mir untergegangen. :oops:
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Antworten