Registriert: Di Okt 03, 2006 14:07 Beiträge: 1277 Wohnort: Wien
Mit Read-Only Memos hätte ich kein Problem. Leider hab ich einen Charakterfehler: ich hätte die ganze Zeit ein dummes Gefühl im Magen, wenn ich nur ein Read-Only Memo schreibe. Das wäre ja so, als ob man jemandem einen saftigen Braten unter die Nase hält, aber essen darf er nur den Kümmel obendrauf.
Registriert: Do Dez 05, 2002 10:35 Beiträge: 4234 Wohnort: Dortmund
GUI: Sieht ja alles schon recht vielversprechend aus.
Memo vs TextSuite: Natürlich habe ich nichts dagegen, wenn man die TextSuite verwendet. Dafür habe ich sie ja gemacht. Allerdings zum aktuellen Zeitpunkt kann ich nicht dazu raten mit der TextSuite ein schreibares Memo erstellen zu wollen. Der Grund dafür ist recht einfach. Die TextSuite kann aktuell überwiegend "nur" Text darstellen. Aber für ein Memo (oder Editoren jeglicher Art) ist noch viel mehr von Nöten. Zum Beispiel. Navigation mit Cursotasten, Klicken mit der Maus, etc etc. Dort benötigt man umfangreiche Methoden zum Erfragen wo sich genau welches Wort/Buchstabe befindet etc. Diese Informationen gibt es zwar schon so halb. Aber nur intern und nur sehr sehr flüchtig. Das einfach so rauszureichen geht nicht da bedarf es schon einer etwas komplexeren Lösung aber dazu habe ich schon ein paar anfängliche Ideen.
FreeType2 wird in der ersten stabilen Version aber noch nicht enthalten sein. Eigentlich hängt alles (seit unzähligen Monaten) nur noch an der Doku, die Nerven kostet. Aber das ist ein anderes Thema und gehört eigentlich nicht hier her.
PS: Textprogrammierung. Weiß gar nicht was ihr alle habt. Da finde ich Vektorrechnung etc. viel schlimmer.
Registriert: Di Okt 03, 2006 14:07 Beiträge: 1277 Wohnort: Wien
Ich habe in Deinem Link geschmökert.
Zitat:
The existing parser is an fundamental part of the base renderer but it must be an seperate class.
Seh ich auch so.
Ein funktionierender einzeiliger Texteditor ist in der glPasGUI als SEPARATE KLASSE drin: In "GUIDescendants.pas" gibts eine Klasse "TGUILineEditor", der kapselt folgendes Verhalten: Scrolling/Selektieren/Einfügen/Löschen/Copy&Paste, sowohl für einzelne Zeichen als auch für Substrings. Er braucht nur eine Font, die einen String darstellen kann und ihm ein ein paar Daten gibt (nur das Übliche: Breite/Höhe des Strings - so was hast Du bestimmt eingebaut), alles weitere macht er selber. Er wirkt etwas erdig, weil er keine Optimierungen drin hat, aber er ist stabil. Ich habe mir aber noch keine Gedanken darüber gemacht, ob man diese Klasse auf einen mehrzeiligen Editor erweitern kann.
@Vektorrechnung: Öhm, sagte nicht irgend so ein griechischer Knabe mal: gebt mir einen Vektor und ich hebe die Welt aus den Angeln?
Registriert: Do Sep 25, 2003 15:56 Beiträge: 7810 Wohnort: Sachsen - ERZ / C
Programmiersprache: Java (, Pascal)
Gut das Markieren, Ersetzen, Ergänzen, Löschen von Text ist das eine. Dann wäre da noch das korrekte Umbrechen von Text. Zumindest das war aber glaub ich schon bei Lossy enthalten, oder?
_________________ Blog: kevin-fleischer.de und fbaingermany.com
Registriert: Do Dez 05, 2002 10:35 Beiträge: 4234 Wohnort: Dortmund
Ja Klar. Die Abfrage der Höhe/Breite existiert. Nur damit die Positionen zu erfragen an welche man aktuell editiert finde ich persönlich nicht optimal. Denn um solch eine Position zu finden müsste man Zeichen für Zeichen den Text länger werden lassen und die Länge erfragen. Aktuell würde es auch reichen die Längen einzelner Zeichen zu erfragen und zu addieren. Spätestens mit Kerning wird das aber nicht mehr funktionieren, da sich einige Zeichenkombinationen unterschneiden können. Und bei der Abfrage einer Höhe/Breite muss der Text intern jedes Mal in WideString konvertiert und geparst werden. Wenn man lange Texte hat, dann könnte das schon etwas zähflüssig werden. Aber da denke ich auch nur bei wirklich langen Texten wird man das merken. Da wird vermutlich das was sonst noch gerendert wird eher ins Gewicht fallen.
Bei einem Editor für mehrzeilige Texte kann man vermutlich genau so vor gehen. Wobei man da Wortumbrechungen berücksichtigen muss. Also die Länge der Worte berechen und schauen welche passen noch in die Zeile. Ansonsten wird eine neue Zeile gemacht. Nur da dürfte das Problem eher sein, dass mehrzeilige Texte eben auch reichlich größer sind. Und dann muss man in irgendeiner Form die Texte cachen. Denn beim Schreiben ist eigentlich nur das aktuelle Wort von interesse. Bzw beim Einfügen eben der markierte Bereich. Alles Andere verändert sich nicht und muss höchsten neu ausgerichtet werden. Aber in sich bleibt es gleich. Was den Berechnungsaufwand beträchtlich verringern sollte.
PS: Mit Klasse in dem Bugtrackereintrag meine aber auch nicht nur eine seperate Klasse sondern ein Objekt welches von Außen gesteuert werden kann.
PPS: Flash ja das Umbrechen von Text ist drin. Man beachte aber, dass ich das Wort "korrekt" bewusst ausgelassen habe. Aber von etwaigen Umbrechungen wärend des Zeichnens merkt der Entwickler nichts und kann auch nicht feststellen wo und wieso. Was bei normaler Ausgabe auch egal ist. Und zum Markieren etc. muss auch die Position jedes einzelnen Buchstabens genau bekannt sein. Bzw es muss möglich sein diese zu erfragen. Denn man braucht immer einen Cursor der die aktuelle Stelle markiert.
Registriert: Di Okt 03, 2006 14:07 Beiträge: 1277 Wohnort: Wien
Zitat:
Nur damit die Positionen zu erfragen an welche man aktuell editiert finde ich persönlich nicht optimal.
Das würde ich auch nicht optimal finden. Aber so mach ich es ja auch nicht. Die aktuelle Position im Text schreibt er immer mit, der LineEditor kriegt ja vom Editierfeld (NOTA BENE: das sind nicht nur zwei verschiedenen Klassen sondern auch zwei verschiedene Objekte: die Instanz von TGUIEdit=Editierfeld enthält eine Instanz von TGUILineEditor=Editor ) die Information, was der User grade macht. Also kann er die Position einfach updaten und muss nichts berechnen.
Zitat:
Mit Klasse in dem Bugtrackereintrag meine aber auch nicht nur eine seperate Klasse sondern ein Objekt welches von Außen gesteuert werden kann.
Ja, so meinte ich das auch. Jedes TGUIEdit hat seine eigene Instanz von TGUILineEditor. Der LineEditor ist kein Singleton.
Zitat:
Denn man braucht immer einen Cursor der die aktuelle Stelle markiert.
Genau. Jede Instanz von TLineEditor hat seine eigenen Informationen betreffend den Text, der sich in dem jeweiligen individuellen Editierfeld befindet. Ander gehts gar nicht. Ich kann ja zwanzig Editierfelder auf dem Formular haben. Die Infos müssen alle separat gespeichert werden.
Du musst bedenken, dass ich mehr Infos vom Benutzer hab als Du. Ich kriege alle Tastenschläge und Mausklicks mit. Dafür habe ich im Gegenzug keine Detailinfos aus der Schrift, so wie Du. Also arbeitet mein Editor wahrscheinlich ein wenig anders als Deiner. Und zugegeben, Kerning habe ich nicht einbezogen.
Aber eigentlich red ich mich um Kopf und Kragen. Mir wäre ohnehin lieber, wenn ich das nicht machen muss.
Traude
Registriert: Do Dez 05, 2002 10:35 Beiträge: 4234 Wohnort: Dortmund
Zitat:
Du musst bedenken, dass ich mehr Infos vom Benutzer hab als Du. Ich kriege alle Tastenschläge und Mausklicks mit. Dafür habe ich im Gegenzug keine Detailinfos aus der Schrift, so wie Du. Also arbeitet mein Editor wahrscheinlich ein wenig anders als Deiner. Und zugegeben, Kerning habe ich nicht einbezogen.
Isch habe gar kein Auto ähh Editor. Also meiner Meinung nach kann man die beiden Sachen auch nicht direkt vergleichen. Alleine schon dadurch, dass die TextSuite lediglich dazu dient möglichst einfach Text auszugeben. Und Textberechnungen finden aktuell nur intern statt und ohne, dass dem Entwickler diese Informationen detailiert zur Verfügung stehen. Das von mir war nur Laut gedacht wie man es lösen könnte bzw. auch welche Probleme auftreten würden, wenn man so etwas mit der TextSuite machen wollte. Wie Flash es angedeutet hatte. Also rein von meinem Standpunkt aus gesehen.
Registriert: Di Okt 03, 2006 14:07 Beiträge: 1277 Wohnort: Wien
Wie schade, ich hatte schon gehofft, ich könnte etwas auf Dich abschieben.
Nein aber im Ernst: Durch eine Anpassung an die VCL wird eine Schnittstelle zur TextSuite möglich. So ist es geplant und ich denke, das sollte so bleiben.
Registriert: Do Sep 02, 2004 19:42 Beiträge: 4158
Programmiersprache: FreePascal, C++
Ich habe heute im Verlauf des etwas langweiligen Parkplatzdienstes nochmal über die sache mit In-Wörter-Aufteilen nachgedacht.
Nehmen wir mal an, wir haben einen Text, der auch schon schön in Wörter aufgesplittet ist. Von diesen Wörtern kennen wir schon die Längen in Pixel und haben sie schon ausgerichtet auf dem Bildschirm. Um jetzt herauszufinden, wo ein Benutzer gerade hingeklickt hat, müssten wir doch erstmal nur unsere Wörterliste durchgehen. Das sollte viel schneller sein, als immer neu die Stringlänge zu berechnen. Dann kann man innerhalb der Wörter noch Detailberechnungen anstellen, welcher Buchstabe genau getroffen ist. Das erspart das ganze auf der kompletten Textgröße.
Wenn jetzt der Benutzer anfängt zu tippen, müssen wir eigentlich nur an der entsprechenden Stelle im Wortobjekt was einfügen. Und wenn es ein Trennzeichen ist (z.B. Leerzeichen oder Bindestrich), dann wird das Wort an der Stelle aufgeteilt und das Trennzeichen eventuell (wenns kein Leerzeichen ist) an eines der beiden Wörter angehangen, je nach Zeichen.
Was haltet ihr davon?
Gruß Lord Horazont
_________________ If you find any deadlinks, please send me a notification – Wenn du tote Links findest, sende mir eine Benachrichtigung. current projects: ManiacLab; aioxmpp zombofant network • my photostream „Writing code is like writing poetry“ - source unknown
„Give a man a fish, and you feed him for a day. Teach a man to fish and you feed him for a lifetime. “ ~ A Chinese Proverb
Registriert: Di Okt 03, 2006 14:07 Beiträge: 1277 Wohnort: Wien
Ich versuche mal, das Problem ganz konsequent zu durchdenken. Ich fange damit an, um den ganzen verfügbaren Text eine gedankliche Bounding Box zu ziehen. Die Einheiten sind Pixel. Dann haben wir eine verläßliche virtuelle Fläche, die unseren ganzen Text umfasst. Das oberste linke Pixel hat die Koordinaten 0/0.
Wir nehmen jetzt an, dass unsere Schrift eine Truetype-Schrift ist (die Buchstaben haben verschiedenen Breite) und wir könnten auch mehrere Schriften haben, die verschiedene Größe haben können. Wir können also nicht davon ausgehen, dass unsere Zeilen gleich hoch sind. Ich lasse das Kerning mal weg, denn da kenn ich mich nicht aus und kann daher die Konsequenzen, die sich daraus ergeben, nicht wirklich abschätzen.
Wenn wir Deinen Ansatz mit den Wörtern nehmen, dann können wir damit Folgendes machen: Für jedes Wort wird noch die Bounding Box gespeichert.
Jetzt habe ich gleich mein erstes Problem: ganz offensichtlich ist diese virtuelle Textfläche von der Breite des Fensters oder der eingestellten Seitenbreite abhängig. Sollte sich das Fenster oder die Seitenbreite ändern, ändern sich auch die ganzen Koordinaten der Wort-Datenbank. Nehmen wir das mal in Kauf.
Wenn wir jetzt wissen wollen, was der Benutzer angeklickt hat, brauchen wir noch die Info, welches die erste angezeigte Zeile ist, man kann auch die erste angezeigte Pixelreihe nehmen, Pixeln sind wahrscheinlich besser. Zu dem Wert, den der Mausklick liefert, muss man noch den Index der ersten angezeigten PixelZeile dazuzählen, damit müßte man eigentlich schnell zumindest feststellen können, in welcher Bounding-Wort-Box man gelandet ist. Ich hab jetzt stillschweigend angenommen, dass die erste angezeigte Pixelspalte links die Indexnummer Null hat. Aber was man mit Y macht kann man natürlich auch mit X machen. Das Clipping läßt grüßen. (Wenn Pluto hier mitliest: dieses Zeug sollte ihm eigentlich bekannt vorkommen).
Um die Bounding Box des Wortes schnell zu finden, müsstest Du sie in einer geeigneten Reihenfolge gespeichert haben. Für diesen Ansatz wäre es auch gut, wenn das ganze Textfeld mit Bounding Boxen bedeckt wäre, sonst hätten wir ein Problem, wenn der Benutzer in einen Wortzwischenraum klickt.
Die Wortboxen könnte man beispielsweise mit dem linken oberen Punkt speichern, zuerst nach Y und innerhalb dessen nach X geordnet (es gibt im allgemeinen mehr Zeilen als Spalten, anders ausgedrückt: die virtuelle Fläche tendiert dazu, mehr hoch als breit zu sein)
Eine Alternative wäre, das ganze nach Zeilen zu speichern. Auch nach Absätzen wären denkbar.
Na gut, und jetzt fügt unser Benutzer in das Wort einen Substring ein. Diese Änderung hat nicht nur Auswirkungen auf unser aktuelles Wort, sondern auch auf alle nachfolgenden Wörter dieses Absatzes, denn ihre Bounding Boxen werden verschoben. Und das müsste doch eigentlich gleich passieren, denn wenn Du schreibst, verschieben sich die Wörter nach hinten, brechen sich automatisch um usw. Das ist während des Editierens zu sehen. Also bei jeder Änderung muss der ganze Absatz geändert werden. Wenn der Absatz um eine Zeile vergrößert wird, muss der ganze nachfolgende Text verändert werden. Nicht die Strings natürlich, aber zumindest der oberste linke Punkt jeder Wortbox.
An diesem Punkt würde ich vorschlagen, einen guten Kompromiss zwischen den kleineren Verwaltungseinheiten (und unserem Fall die Wortboxen) und den großen Verwaltungseinheiten (Absätze?) zu finden, damit die Rechenzeit für das Verschieben optimiert wird. Die kleineren Verwaltungseinheiten könnten sich auf die größeren beziehen, nicht auf den ganzen Text, da muss man weniger reorganisieren.
Scheint von der Rechentechnik her ein durchaus gangbarer Weg zu sein. Ginge aber auch mit Zeilen. Mit Zeilen würde sich der Verwaltungsaufwand reduzieren: man kann sie einfach in einer Liste speichern.
Ich vermute, dass MS Word nach Absätzen organisiert ist. Zumindest kann man für jeden Absatz bestimmte Daten speichern.
Registriert: Do Sep 02, 2004 19:42 Beiträge: 4158
Programmiersprache: FreePascal, C++
Ja, an so einen Ansatz hatte ich gedacht.
Nach Zeilen organisieren halte ich deswegen für problematisch, weil sich die Zeilen mit jeder Änderung selbst verändern können. Bei Absätzen passiert dies nur, wenn man einen neuen Erstellt. Bei Zeilen reicht es, die Größe der Box zu verändern.
Auf die Idee, den Wörtern auch noch einen Absatz zuzuordnen bin ich bisher nicht gekommen, das halte ich für einen guten Einfall. Damit sind wir hier bei Octree-Ähnlichen Verfahren für Memos. Mit einer solchen Implementation sollte man auf eine passable geschwindigkeit und einen relativ geringen Aufwand in der Verwaltung kommen.
Gruß Lord Horazont
_________________ If you find any deadlinks, please send me a notification – Wenn du tote Links findest, sende mir eine Benachrichtigung. current projects: ManiacLab; aioxmpp zombofant network • my photostream „Writing code is like writing poetry“ - source unknown
„Give a man a fish, and you feed him for a day. Teach a man to fish and you feed him for a lifetime. “ ~ A Chinese Proverb
Registriert: Di Okt 03, 2006 14:07 Beiträge: 1277 Wohnort: Wien
In Wirklichkeit handelt es sich um eine Datenbankorganisation. So etwas braucht man überall, auch bei Grafikprogrammierung. Besonders in der Grafikprogrammierung, hier muss es besonders schnell gehen.
Das mit den Zeilen: ich weiß nicht so recht. Wenn man nur eine Zeilenorganisation hat, bricht die Performance bei langen Texten bestimmt ein. Aber wenn man wieder die Abstufung Absätze => Zeilen einführt, könnte es gehen. Absätze sind im allgemeinen nicht so lang. Zusätzlich tritt das Problem nur dann auf, wenn in einen Absatz etwas eingefügt wird. Wenn ein neuer Absatz geschrieben wird, ist der aktuelleCursor immer am Ende des Absatzes.
Registriert: Do Dez 05, 2002 10:35 Beiträge: 4234 Wohnort: Dortmund
Ich glaube es würde auch schon genügen, wenn man den Text in Worte zerlegt und bei Veränderungen dann nur die Positionen der Worte neu berechnet. So wirklich kompliziert müsste das meiner Meinung nach gar nicht sein. Denn all diese Aktionen basieren auf Benutzeraktionen und damit wäre es für den Benutzer nicht mehr sichtbar ob die 1 Millisekunde länger dauern oder nicht. Im Endeffekt müsste ja nur eine Liste durchgegangen werden.
Boundingboxen würde ich persönlich für nicht so gut empfinden. Denn falls man tatsächlich unterschiedliche Größen haben will und eine große Schrift und eine Kleine zusammentreffen. Dann sollte der Benutzer trotzdem Text markieren können, wenn er am oberen Ende der Zeile klickt. Also wären die Boxen eigentlich immer vom Oberen der Zeile bis zum unteren. Egal wie groß die Zeichen tatsächlich sind. Das ist besser bedienbar und spart abfragen, da man nur ein mal pro Zeile testen müsste ob man in der richtigen Zeile ist. Ansonsten müsste man nur noch testen welches Wort man hat und dann welcher Buchstabe. Ich denke das ist vom Aufwand her sehr überschaubar.
Zitat:
Wie schade, ich hatte schon gehofft, ich könnte etwas auf Dich abschieben.
Normal würde ich da ja ja zu sagen aber aktuell habe ich ein paar Baustellen. Allerdings bei einigen ist zu mindest ein baldiges Ende in sicht.
Registriert: Do Sep 25, 2003 15:56 Beiträge: 7810 Wohnort: Sachsen - ERZ / C
Programmiersprache: Java (, Pascal)
Also ich finde die Diskussion auf alle Fälle schon mal sehr spannend.
Mal eine kurze Zusammenfassung was ich glaube gelesen zu haben:
Ich denke eine hierrarchische Aufteilung ist tatsächlich das sinnvollste. Also Text -> Absatz -> Zeichengruppe -> Zeichen.
Dann sollten die "Gruppen Bounding Volumes (BV)" sich nicht auf die Zeichen(gruppen)höhe beschränken, sondern sollten so hoch sein, wie die Zeile ist.
Hinter Zeilenumbrüchen sollte ein leeres BV eingesetzt werden. Ein Leerzeichen ist ein eigenes BV. Stehen mehrere Leerzeichen-BVs zusammen, werden sie vereint. (Spart Platz in der Verwaltungsliste.) Das passiert auch, wenn zwei Wort-BVs direkt nebeneinander liegen.
Die Höhe einer Zeile ist abhängig vom höchsten Zeichen einer Gruppe in der Zeile, oder einem festeingestellten Wert.
_________________ Blog: kevin-fleischer.de und fbaingermany.com
Registriert: Di Okt 03, 2006 14:07 Beiträge: 1277 Wohnort: Wien
Naja, so in etwa. Ich bin sicher, dass man während der Implementierung noch ein wenig umdisponieren muss. Manche Dinge werden einem erst bewusst, wenn man dann wirklich vor dem konkreten Problem steht. Die eigentliche Botschaft ist, dass man die Daten strukturieren muss.
Aber ich selber möchte im Augenblick kein Memo implementieren. Ich hab das Ende jener Dinge jetzt vor Augen, die ich mir vorgenommen habe. Die OpenGL GUI war für mich irgendwie eine Art "Pflicht". Ihr wisst, dass ich ganz andere Interessen habe als 2D (!) zu programmieren. Ich finde, es ist die Zeit gekommen, mich mal ins Vergnügen zu stürzen.
Mitglieder in diesem Forum: 0 Mitglieder und 3 Gäste
Du darfst keine neuen Themen in diesem Forum erstellen. Du darfst keine Antworten zu Themen in diesem Forum erstellen. Du darfst deine Beiträge in diesem Forum nicht ändern. Du darfst deine Beiträge in diesem Forum nicht löschen. Du darfst keine Dateianhänge in diesem Forum erstellen.