Extended am Sonntag #10
Der dynamische Notizblock
Ein Notizblock? Könnte man da nicht einfach ein Dokument-Item erstellen und fertig?
Könnte man.
Aber dann lernen wir ja gar nichts über dynamische Dokumente. Und Variablen. Und man braucht jedes Mal ein neues Item für eine simple Notiz. Und außerdem. Und überhaupt.
Import-Code
Bevor es losgeht findet ihr hier das fertige Item zum Schnell-Importieren:
Notizblock
!1Ev3YPTru4xgFvMMyjHTtqtCNbd4c1oIeV4F60PRqiDSzRxKi6hNyiwpl9POx1RAEX65SlcqGi21tYypIDxT7589D(5BbUjVp3Xe)3OMb3XIZmmTQBw30W61hCYh)yc3PgUdwxh6zyukSCwqKp9r)FJZA1JZoTlolLZoQhzqwNg6PDAZDoWWaxVp)ioJ1KotuyJGG(WNtBkf(3sRW6tpj0WanKWrIao7oVy3jXrJNG2Yl(Me9lzhjstH8bKnYhaIWBGHqOIaEbbGY2e0zrCN9wXFDdNKHVyF6fPQ)y4)srsAX0126JbTOH)j4xgArkyCOY9(rHPqyQce7mB(ShMn5H)9VMT7eAWoZwa4hOLwhwSqoZIwWAtaGzGSXObDtgf9PsyyTSy(ak1LpGszBJ2mXnHpT0XtGZXrYefPNnQMT)dziVJNcc)rHaMVUlkmFWoZsJNypr6DpeBFDMuI0FuTTZ)A)pbZVF4FOGtcYlV0SyqHN2Iqmo4eLkMUvCSzi6hvWNixn(IKW7BSWd9VIIDMySdXNivcu0X8HL1q5)QEmfP1iMDuZt4oVHZExlYcVd7jD6PmR7XC2hYGK0JXd42j7gGZo(mQD8YUyuzFS7SJjTPw4EeH3tBtVRowvD2o1Ov)fVXq)OizQyshWlaIreqeG50aTu0TQOtb1ivIU9x2)FEc8nRZwl6ImnO49Z3Ko97pcWkwMxPuViuKk8KIPqGY7QAZdNlLDhg(JZGcG9SZBBRPmol09trX3ET87dWZ)YxECOV(X3SewnDLn8SBYl6RwfRuN1QiBJ40Ev7KVHWUifKRPSR6dkPQtvrBrm)zRxuH81mPi82xu(sRxOV6zKiCA21F9FUbcjn95BCHw6lOrcigF7wv32Blfspz0wCbtvgFf1f1f0SENxe4WLoNX19KZxI1ahonBC(GtHeafhJb)rPj3subtc4jA2tzKU8HOcZLChu6O15QpiRGGG1LZ2)Z0GZWb0rk(MaAXHwTPBcxikBBJkYQ881Eylr8CT5PawfGkXS3ZqsBw3sHvuW6u84QAdfugQfBw5iQQAC5p0qfSqfvCY5o0ZlAOWzZZOjN1LGHQIY2(TNaeiu29NrN2ICQLrD0mTPn3TjvUFN7yrIVljk4AGH(lv2MDe9SPYPx2M8q6QkWTVQi8RP)s(uYOt8MaXdZcdKGHLNMMxGRibbw9haLclBq9HYislzjZTkyUgJvWC)ryjfKyBBAyuIX6WSM3AUPJERXWNQo(tRiwdgvrmINTQIurlDseg0CfbUjG86sUGD8vKt0rB0ld)U179Ynb92A9Woa0IdxyBC5dESlfCdx)AHcxvCLWBxEHGJXIgCT7hg7f6pIMuHMlwGp2f)(Mp(1Ek)yQJBedXkvuMjk((QyQQn)GT4oKSj4v58kUpcNfaPEcjbLQvO0DsN2J2PQGKXajChK8Y(JI9KyVWf4VVathSwyIS(UgM7AzLpWYWU2BSTOI(sRBwhl4TTEnIe8CQF0trBkRzfgp4cmk8Q9ELQo5zO9v81EQuOTK46pLpG0DrHis3DLU98bEdNMj)6FNOvGta)Syr69NIavsjiT4Fbk5)h
Was das Item können soll
Ich möchte einen handelsüblichen Notizblock modellieren, von dem man Zettel abreißen und einzeln beschreiben kann.
- Jeder Zettel soll zunächst eine Überschrift bekommen.
- Man kann danach beliebig viel Text hinzufügen, das muss nicht sofort passieren, d.h. man soll alte Notizen später ergänzen können.
- Man kann eine Notiz unterschreiben. Wenn man eine Notiz unterschrieben hat, soll es nicht mehr möglich sein, Text anzufügen.
Bei einem echten Notizzettel würde das natürlich trotzdem gehen, aber… ich will das so
Objektstruktur
Der Notizblock ist ein Item (wow, Sherlock…), der ein inneres Item enthält, das einen einzelnen Notizzettel modelliert. In diesem befindet sich ein Dokument, dass die eigentliche Notiz anzeigt. Wir haben es also mit einem Dokument in einem Item in einem Item zu tun.
Da ich mehrere Arbeitsabläufe pro Item und Dokument benötigen werde, überführe ich als erste Amtshandlung meine Objekte in den Expertenmodus.
Variablen
Der Notizblock an sich benötigt nur eine Objektvariable: Mit charges
speichere ich, wieviele (leere) Zettel der Block noch enthält.
Die einzelnen Zettel brauchen da etwas mehr Information. Beachte, dass die Objektvariablen der Notizzettel nichts mit der des Blocks zu tun haben. Auch wenn der Block zerstört wird, bleiben die abgelösten Zettel erhalten.
-
initialized
erhält den Werttrue
, sobald der Zettel zum ersten Mal benutzt wird. -
title
speichert den Titel bzw. das Thema der Notiz. -
content
enthält den eigentlichen Inhalt, der nach und nach eingegeben wird. -
controls
beinhaltet die Schaltflächen „Text hinzufügen“ und „Signieren“. Nachdem signiert wurde, wird diese Variable mit einem Text „unterschrieben von…“ überschrieben. -
signature
enthält die „Unterschrift“, sobald unterschrieben wurde. -
addedText
ist eine temporäre Variable, um Text zwischenzuspeichern, der hinzugefügt werden soll.
Das äußere Item: Notizblock
Der Notizblock ist ein benutzbares Item. Im Tooltip informiere ich den Spieler mit ${charges::100}
darüber, wieviele leere Zettel noch am Block heften. Die ::100
stellt dabei sicher, dass auch dann etwas angezeigt wird, wenn der Block noch nie benutzt wurde und somit die Variable charges
noch nicht existiert.
Benutzt man den Notizblock, wird onUse
ausgeführt. Achtung: Es gibt einen weiteren Arbeitsablauf mit selbem Namen im Notizzettel-Item.
- Initialisiere die Variable
charges
mit 100. Indem ich „Initialisieren“ statt „Wertzuweisung“ verwende, wird der Effekt nur bei der ersten Benutzung aktiv. Danach wird er ignoriert, da es die Variablecharges
schon gibt. - Verringere
charges
um 1, denn wir reißen gleich ein Blatt ab. - Spiele einen passenden Sound ab. Geschenkt.
- Füge das innere Item (Notizzettel) dem Spielerinventar hinzu.
- Bedingung: wenn
charges
Null erreicht: - Verbrauche (d.h. Zerstöre) den Notizblock.
Das Dokument
Der Inhalt des Dokuments, also des Objekts, das später meine Notiz auf den Bildschirm bringt, sieht… unspektakulär aus:
{h1:c}${title}{/h1}${content}
${controls}
In diesem Fall liegt die Würze in der Kürze.
${title}
wird durch den vom Spieler vergebenen Titel ersetzt, ${content}
entsprechend durch den Inhalt.
${controls}
beinhaltet die beiden Schaltflächen/Links, mit denen ich Text hinzufügen kann oder signieren.
Die drei Dokument-Arbeitsabläufe onAddTextClick
, onAddTextInput
und onSignClick
heben wir uns für später auf, denn zuerst kümmern wir uns um…
Das innere Item: Notizzettel
Wie der Notizblock ist dieses Item als benutzbar angelegt. Im Tooltip zeige ich mit ${title::<Kein Titel>}
den Titel an. Man muss also nicht jede Notiz „durchklicken“, um den Titel zu erfahren.
Außerdem fülle ich das Feld „Beschreibungstext“ mit ${signature::Ein einfacher Notizzettel}
aus. Das sorgt dafür, dass eine nicht unterzeichnete Notiz mit der Bemerkung „Ein einfacher Notizzettel“ versehen wird, ein unterschriebener hingegen mit der entsprechenden „Unterschrift“.
Der Notizzettel hat zwei Arbeitsabläufe: onUse
und initialize
. Wenn man einen Notizzettel benutzt (also rechtsklickt), …
- … wird das innere Dokument angezeigt, aber nur, wenn die Variable
initialized
auftrue
gesetzt ist. - … wird
initialize
aufgerufen, aber nur, wenn die Variableinitialized
nicht auftrue
gesetzt ist.
Anders ausgedrückt: onUse
bereitet den Notizzettel vor, falls das noch nicht geschehen ist, ansonsten zeigt es seinen Inhalt an.
initialize
kümmert sich darum, dass beim ersten Benutzen alle Variablen korrekt eingerichtet werden:
- Setze
initialized
auftrue
. - Lege die Variable
content
an. In der Datenbank sieht das Konstrukt etwas merkwürdig aus. Dort stehtcontent [=]
, aber es hat seine Richtigkeit. Der Inhalt soll anfangs leer sein. - Weise der Variable
controls
den Wert{h3:c}{link*onAddTextClick*Text hinzufügen} {link*onSignClick*Signieren}{/h3}
zu. Hier sind also die beiden Schaltflächen, die später im Dokument zu sehen sein werden. Sie stehen deshalb nicht direkt im Dokument, damit ich sie nach dem Signieren entfernen kann. - Eingabeaufforderung für die Variable
title
. Der Spieler soll hier einen Titel wählen. Sobald das geschehen ist, wirdonUse
aufgerufen.
Wer aufmerksam gelesen hat, wird feststellen, dass die beiden Arbeitsabläufe sich gegenseitig aufrufen. Das könnte sich zu einer gefährlichen Endlosschleife entwickeln. In diesem Fall ist das kein Problem, denn wir steuern die Aufrufe über die Variable initialized
. Indem wir sie im ersten Schritt auf true
setzen, stellen wir sicher, dass es kein ewiges hin und her geben kann.
Interaktionen im Dokument
Wie oben erwähnt, bleiben noch die drei Dokument-Arbeitsabläufe zu klären.
onAddTextClick
wird ausgelöst, sobald der Spieler auf die entsprechende Schaltfläche unten im Dokument klickt. Als einzigen Effekt enthält der Arbeitsablauf eine Eingabeaufforderung für die Variable addedText
.
Ist der Spieler fertig mit Schreiben, wird onAddTextInput
aufgerufen.
Hier wird im ersten Schritt die Variable content
modifiziert: ${content}{p} {/p}{p}${addedText}{/p}
. Der neue Wert besteht aus dem alten Wert (dafür sorgt der erste Teil ${content}
), sowie dem neuen Text ${addedText}
, der in einen Absatz eingebettet wird (dafür sorgen {p}
und {/p}
).
Dazwischen habe ich ein komisches Konstrukt {p} {/p}
reingemogelt. Dieses erzeugt eine Leerzeile. Das Leerzeichen in der Mitte ist ein geschütztes Leerzeichen, sonst funktioniert der Trick nicht.
Das geschützte Leerzeichen ist über die Tastenkombination ALT+255
erreichbar. Im Gegensatz zum normalen Leerzeichen wird es wie Text behandelt. Ohne dieses spezielle Zeichen würde Extended „denken“, dass mein Absatz leer ist, und ihn nicht anzeigen. Ich habe also einen nicht leeren Absatz und Extended spendiert mir den Zeilenumbruch, den ich haben möchte. Der Absatz an sich ist nicht zu sehen, weil… naja, weil er nur aus Leerzeichen besteht.
Im zweiten Schritt wird das Dokument erneut angezeigt. Bedenke, dass an dieser Stelle das Dokument bereits offen ist, aber indem ich es erneut öffne, wird auch der Inhalt mit dem neuen Wert von content
aktualisiert.
Der letzte Arbeitsablauf ist onSignClick
, der ausgelöst wird, wenn der Spieler seine Notiz unterzeichnen möchte.
Ähnlich wie bei onAddTextInput
werden hier Variablen neu gesetzt.
Zunächst bekommt controls
den neuen Wert {h3:c}unterzeichnet von ${trp:player:full}{/h3}
. Damit werden die beiden Schaltflächen durch einen Text ersetzt und sind nicht mehr anklickbar. ${trp:player:full}
ist ein Variablen-Tag, das den Spielernamen beinhaltet.
Danach wird das Dokument erneut angezeigt, damit die Änderungen sichtbar werden.
Im letzten Schritt wird die Variable signature
eingestellt. Dadurch ist dann bereits im Item-Tooltip ersichtlich, dass die Notiz fertiggestellt wurde, und nicht mehr veränderbar ist.
Viel Spaß beim Experimentieren und
bis zum nächsten Sonntag…