Zeichnungen und Seiten sind aus drawing objects aufgebaut. Sie umfassen gezeichnete Objekte wie Rechtecke und Kurven sowie grafische Texte.
Die Objekte werden über ihren Index oder - sofern sie haben - über ihren Namen angesprochen. Der Name kann vom Anwender über die Palette Objektkoordinaten vergeben werden, oder das Script legt sie mit einem Namen an.
Der Index zählt in der Zeichnung von vorn nach hinten: Das am weitesten vorn liegende Zeichnungsobjekt hat den Index 1, das nächste 2 usw.
drawing objects haben für die Varianten Unterklassen:
rectangle -- Rechteck
graphic line -- Linie
graphic text -- Graphischer Text
arc -- Bogen
oval
sector
polygon
Bezier curve
multigon -- Vieleck
Wird das Objekt über die Unterklasse angesprochen, kann der Index niedriger sein. polygon 1 kann drawing object 5 sein. Es ist das am weitesten vorn liegende Polygon.
tell application "RagTime 6.5"
     tell document 1
          delete rectangle 1 of page 1 of layout 1
     end tell
end tell
löscht das am weitesten vorn liegende Rechteck der Seite 1 von Layout 1, selbst, wenn davor noch ein Oval liegt. “delete drawing object 1� dagegen löscht das am weitesten vorn liegende Objekt, gleich, ob ein Rechteck, ein grafischer Text etc. (Um das am weitesten hinten liegende Objekt zu löschen, benutzen Sie den Index -1: delete rectangle -1 of page 1 of layout 1
Erzeugt werden Zeichnungsobjekte mit make. Dabei muss die hinten/vorn-Position mit z.B. “at end� oder “at beginning� angegeben werden.
tell application "RagTime 6.5"
     tell document 1
          make new rectangle at beginning of page 1 of layout 1
     end tell
end tell
legt ein Rechteck auf Seite 1 des Layouts 1 an, das VOR allen anderen Objekten liegt. Soll es hinten liegen, benutzt man “at end�.
Wie bei Seiten kann auch “at before� und “at after� benutzt werden:
tell application "RagTime 6.5"
     tell page 1 of layout 1 of document 1
          make new rectangle at after drawing object 1 with data {100, 100, 200, 300}
     end tell
end tell
erzeugt ein Rechteck in der zweiten Ebene von vorn und legt die Position auf der Seite gemessen in Punkt fest.
Zuerst wird mitten auf einer Seite ein Kreis gezeichnet und mit »Zeichnung – Objektart – Bézier-Kurve« umgewandelt. Dann werden die Punkte mit dem Testscript abgefragt. In meinem Fall ist das Ergebnis die Liste
{{158.7401, 409.6062}, {158.7401, 336.809}, {217.7539, 277.7952}, {290.5511, 277.7952}, {363.3483, 277.7952}, {422.3621, 336.809}, {422.3621, 409.6062}, {422.3621, 482.4034}, {363.3483, 541.4172}, {290.5511, 541.4172}, {217.7539, 541.4172}, {158.7401, 482.4034}, {158.7401, 409.6062}}
RagTime legt die Punkte bei dem Kreis beginnend bei 9 Uhr im Uhrzeigersinn an. Hervorgehoben hab ich die Punkte 3 bis 5. Sie werden etwas umgestaltet für die Tropfenform.
Folgendes Script wird nun für die Zeichnung benutzt:
set punkteListe to {{158.7401, 409.6062}, {158.7401, 336.809}, {217.7539 + 50, 277.7952}, {290.5511, 277.7952 - 150}, {363.3483 - 50, 277.7952}, {422.3621, 336.809}, {422.3621, 409.6062}, {422.3621, 482.4034}, {363.3483, 541.4172}, {290.5511, 541.4172}, {217.7539, 541.4172}, {158.7401, 482.4034}, {158.7401, 409.6062}}
tell application "RagTime 6.5"
     set neuesDokument to (make new document with properties {component types:drawing} at end)
     tell drawing 1 of neuesDokument
          set dasPolygon to (make new Bezier curve at beginning with data punkteListe with properties {color:{red:10, green:60, blue:60}})
         Â
     end tell
end tell
Hervorgehoben sind wieder die Punkte mit den Änderungen. Das Resultat ist ein garantiert symmetrischer Tropfen.
Gruppen von Zeichnungsobjekten sind in RagTime ein weiteres Objekt der Seite / der Zeichnung. Um Objekte zu gruppieren legt man das neue Gruppenobjekt an und übergibt die Bestandteile als Daten:
tell application "RagTime 6.5"
     tell page 1 of layout 1 of document 1
          make new drawing group at end with data {rectangle 1, rectangle 2, rectangle 3}
     end tell
end tell
Der Code legt auf der Seite eine neue Gruppe an und die ersten drei Rechtecke sind die gruppierten Objekte.
Für die Umkehrung gibt es ein eigenes Verb:
tell application "RagTime 6.5"
     tell page 1 of layout 1 of document 1
          ungroup drawing group 1
     end tell
end tell
Alle Koordinatenangaben sind in Punkt (1/72 Zoll) gemessen von der oberen linken Ecke. Vertikale Koordinaten werden nach unten größer, horizontale nach rechts.
Beim Anlegen eines Rechtecks ist es naheliegend, die Koordinaten gleich als dessen Daten zu übergeben:
tell application "RagTime 6.5"
     tell layout 1 of document 1
          make new rectangle at beginning of page 1 with data {100, 100, 300, 200}
     end tell
end tell
Die Reihenfolge der Koordinaten ist: {X links, Y oben, X rechts, Y unten}
Bei den Koordinaten ist im AppleScript-Verzeichnis der Unterschied zwischen definition rect und bounds wichtig (sowie auf den ersten Blick vielleicht etwas unklar):
In RagTime können Zeichnungsobjekte transformiert werden: gedreht, skaliert, geschert.
Das definition rect gibt die Koordinaten an, die vor dieser Transformation galten. (Wenn Sie in der Palette Objektkoordinaten auf “Standard� klicken, bekommt das Objekt wieder die Grenzen des definition rect.) bounds hingegen gibt die Koordinaten an, mit denen das transformierte Objekt auf der Seite / der Zeichnung sichtbar ist. (Dies entspricht im User Interface von RagTime in der Palette "Objektkoordinaten" der Teilung in die Koordinaten, die oben in der Gruppe unter "Name" stehen, und die Koordinaten, die in der nächsten Gruppe für die Ränder stehen. Drehen Sie in RagTime ein Rechteck auf z.B. 45°, um den Unterschied zu sehen.)
Analog: left und left position. die zweite Form gibt den Wert des transformierten Objekts.
Beispiel (die Antworten von RagTime sind mit “-->� eingetragen. Sie wurden aus dem AppleEvent Log des Script Editors kopiert.):
tell application "RagTime 6.5"
     tell page 1 of layout 1 of document 1
          make new rectangle at beginning with data {200, 250, 300, 400}
               tell rectangle 1
               set vertical scaling factor to 2.5
               set horizontal scaling factor to 2.5
               get definition rect
               --> {200.0, 250.0, 300.0, 400.0}
               get bounds
               --> {125.0, 137.5, 375.0, 512.5}
               get left
               --> 200.0
               get left position
               --> 125.0
          end tell
     end tell
end tell
Die Koordinaten von bounds umfassen einen größeren Bereich und left position liegt weiter links, weil die Skalierung von 250% berücksichtigt wird.
Polygone und Bézierkurven werden in RagTime als Listen von Punkten angelegt. Jeder Punkt ist dabei wieder eine Liste. Beispiel:
-- Script 1
set punkteListe to {{50, 50}, {100, 200}, {150, 50}, {50, 50}}
tell application "RagTime 6.5"
     set neuesDokument to (make new document with properties {component types:drawing} at end)
     tell drawing 1 of neuesDokument
          make new polygon at beginning with data punkteListe with properties {color:{red:10, green:60, blue:60}}
     end tell
end tell
Das Script legt ein neues Dokument – bestehend aus einer Zeichnung – an und zeichnet ein Dreieck. Die Liste {{50, 50}, {100, 200}, {150, 50}, {50, 50}} ist die Liste der Eckpunkte des Polygons. Jeder Punkt ist wieder eine Liste von zwei Koordinaten, X und Y. Y wird dabei von oben nach unten gemessen. Die Maßeineit sind Punkt (also 1/72 Zoll). Wie bei der Eigenschaft definition rect handelt es sich um die Koordinaten ohne irgendwelche Transformationen wie Drehung. Dies wird Deutlich im folgenden Script:
-- Script 2
set punkteListe to {{50, 50}, {100, 200}, {150, 50}, {50, 50}}
tell application "RagTime 6.5"
     set neuesDokument to (make new document with properties {component types:drawing} at end)
     tell drawing 1 of neuesDokument
          set dasPolygon to (make new polygon at beginning with data {{0, 0}, {1, 1}} with properties {color:{red:10, green:60, blue:60}})
          set rotation of dasPolygon to 0.25
          change point list of dasPolygon to punkteListe
     end tell
end tell
Hier wird zunächst ein Polygon mit nur zwei Punkten angelegt und anschließend rotiert. Dann wird die Punktliste auf denselben Wert gesetzt, wie im Script 1. Das Resultat ist ein Dreieck, dessen Spitze nach links zeigt: Die Dreihung wird weiterhin auf die Koordinaten angewandt.
Sehen wir uns eine Bézierkurve an. Zuerst wird von Hand eine in RagTime gezeichnet, wie abgebildet. Während sie ausgewält ist, wird die Punktliste mit einem Script abgefragt:
tell application "RagTime 6.5"
     try
          get point list of selection of window 1
     end try
end tell
(In der Praxis ist dieses simple Testscript sehr hilfreich. In vielen Fällen ist es am einfachsten, zunächst eine ungefähre Kurve von Hand anzulegen und deren Werte abzufragen, um die Größenordnung der realistischen Werte zu bekommen.)
Das Script liefert in meinem Fall folgende Liste als Resultat:
{{34.7244, 141.0236}, {64.4882, 87.1653}, {138.8976, 95.6693}, {182.1259, 136.063}, {225.3543, 176.4566}, {287.7165, 177.1653}, {318.1889, 155.1968}}
Das sind sieben Koordinatenpaare für Punkte. Sehen wir uns die Kurve noch einmal mit ausgewählten Punkten an (Abbildung unten):
Es gibt drei Punkte auf der Kurve und vier Endpunkte von den »Anfassern«. Jede Bézierkurve in RagTime (und in anderen Programmen) ist zusammengesetzt aus einer Reihe von Segmenten, die je von vier Punkten definiert sind. Der letzte Punkt eines Segments ist immer der erste des folgenden. So eine Bézierkurve als ganzes ist also immer durch Anzahl_Segmente * 3 + 1 Punkte definiert.
Alle Transformationen in RagTime wirken auf das Zeichnungsobjekt einschließlich seiner Linienstärken und ggf. auch auf die Darstellung seines Inhalts. Schreibt man in einem gespiegelten Rahmen, erscheint auch der Text spiegelverkehrt. Ebenso erscheint Text in einem gescherten Rahmen selbst geschert.
Skalieren eines Objekts:
tell application "RagTime 6.5"
     tell page 1 of layout 1 of document 1
          set Rechteck to (make new rectangle at beginning with data {200, 250, 300, 400})
          set vertical scaling of Rechteck to 3
          set horizontal scaling of Rechteck to 3
     end tell
end tell
Vertikale und horizontale Skalierung werden einzeln gesetzt. Die Zahl ist einfach der Faktor der Skalierung. Ein Skalierungsfaktor -1 spiegelt das Objekt.
Rotieren eines Objekts:
tell application "RagTime 6.5"
     tell page 1 of layout 1 of document 1
          set Rechteck to (make new rectangle at beginning with data {200, 250, 300, 400})
          set rotation of Rechteck to 45 / 360
     end tell
end tell
Das Script legt ein Rechteck an und dreht es um 45° im Uhrzeigersinn. Beachten Sie den Ausdruck »45 / 360«. RagTime behandelt 1 als vollständige 360°-Drehung. 0.5 dreht also um 180°, 0.25 um 90° usw.
Scheren eines Objekts
tell application "RagTime 6.5"
     tell page 1 of layout 1 of document 1
          set X to 15 / 360
          set Rechteck to (make new rectangle at beginning with data {200, 250, 300, 400})
          set horizontal skewing of Rechteck to X
     end tell
end tell
Das Script legt ein Rechteck an und schert es um 15°. Die maximale Scherung, die RagTime akzeptiert ist ± 63,4° (± 0,1762). Wieder sind 360° auf 1 normiert, deshalb der Ausdruck »15 / 360«.
Lassen Sie sich nicht davon verwirren, dass nach den Setzen einer Transformation die anschließende Abfrage bisweilen etwas anderes liefert. Die Transformation eines Objekts ist letztlich eine 2*2 Matrix. Und mehrere Einzeloperationen führen zur selben Matrix. Wenn RagTime dann wieder rückwärts rechnet, können die Einzeltransformationen anders aussehen:
tell application "RagTime 6.5"
     tell page 1 of layout 1 of document 1
          set X to 30 / 360
          set Rechteck to (make new rectangle at beginning with data {200, 250, 300, 400})
          set vertical skewing of Rechteck to X
         Â
          vertical skewing of Rechteck
          --> 0.0
          horizontal skewing of Rechteck
          --> 0.0833
          vertical scaling of Rechteck
          --> 0.866
          horizontal scaling of Rechteck
          --> 1.1547
          rotation of Rechteck
          --> 0.0833
          transformation matrix of Rechteck
          --> {1.0, 0.5773, 0.0, 1.0}
     end tell
end tell
Das Rechteck wird ursprünglich um 30° vertikal geschert. Fragt man anschließend die Eigenschaften ab, ist die vertikale Skalierung zu 0 geworden, alle anderen Eigenschaften sind allerdings anders. Die Kombination von Scherung, Skalierung und Drehung, die das Script zurück meldet, ist tatsächlich äquivalent zu einer 30° vertikalen Scherung. Die Matrix wird im Script im letzten Schritt abgefragt. Sollen mehrere Objekte mit gleichen Transformationen erzeugt werden, ist es oft am einfachsten, ein Objekt mit den vertrauten Techniken (drehen, skalieren) anzulegen, dann dessen Matrix abzufragen und anschließend die weiteren Objekte mit dieser Matrix zu erzeugen.
Sollen Objekte gleich mit einer Transformation erzeugt werden (schneller, weniger Bildschirm-Updates), sieht die Syntax wie folgt aus:
tell application "RagTime 6.5"
     tell page 1 of layout 1 of document 1
          set X to {1.0, 0.5773, 0.0, 1.0}
          set Rechteck to (make new rectangle at beginning with data {200, 250, 300, 400} with properties {transformation matrix:X})
     end tell
end tell
Meistens sollen Rechtecke und andere Zeichnungsobjekte auf einer Seite RagTime-Komponenten enthalten: Texte, Bilder, Rechenblätter etc. Hier ein paar Strategien:
tell application "RagTime 6.5"
     tell page 1 of layout 1 of document 1
          make new rectangle at beginning with data {200, 250, 300, 400} ¬
               with properties {contents type:table}
     end tell
end tell
ist die kürzeste Form, ein Rechteck mit einem Rechenblatt anzulegen. (Nebenbei: Die property-Liste kann auch noch Eigenschaften wie Linienformat, Farbe etc. für das Rechteck enthalten.)
Nachteilig bei dem Verfahren ist, dass man keine Referenz auf das erzeugte Rechenblatt bekommt. Die braucht man aber evtl. später im Code. Alternative:
tell application "RagTime 6.5"
     tell document 1
          set neueTabelle to (make new table at end)
          tell page 1 of layout 1
               make new rectangle at beginning with data {200, 250, 300, 400}
               set contents of rectangle 1 to neueTabelle
          end tell
     end tell
end tell
“neueTabelle� enthält jetzt die Referenz auf das Rechenblatt, das in dem Rechteck angelegt wurde, z.B.
--> table "Rechenblatt 1" of document id 1