Bezierkurven und class

Moin, RagTime-Liste!

Meine Begeisterung für RagTime 6.5 kennt keine Grenzen. Denn RagTime läßt sich am Mac mittels AppleScript sehr schön automatisieren. Mein Ziel ist das Drucken von Scherenschnitten (Kunstwerke aus schwarzem Papier mit Schere geschnitten) und auch die Konstruktion von Werkstattzeichnungen. Meine »Zeichenmaschine« spezialisiert sich auf Bezierkurven, denn mit dieser Objektart lassen sich alle anderen Objektformen darstellen. Die Bezierkurve kennt die Klasse pCIC, die anzeigt, ob die Umlinie geschlossen ist oder nicht. Mit set «class pClC» of selection to true kann ein AppleScript eine ausgewählte Bezierkurve schließen, mit … to false wieder öffnen. 

Und nun meine Frage:
Kennt jemand zufällig die class, mit der ein ausgewähltes Bezierkurvenobjekt in den Bearbeitungsmodus umgeschaltet wird? 

Der Skripteditor nimmt nur auf: set «class » of selection to true/ … to false. Dabei wird der Name der class verschluckt. Deshalb stockt an dieser Stelle das Skript, wenn es die Zeile ausführen soll.

Noch eine kleine Leckerei:
Meine Bezierkurven lassen sich per Klick von RagTime aus in Safari (browser) im SVG-Format darstellen. Dank an Thomas Kaegi für seine Dienstleistung VSuchlauf.

Norbert Lindenthal

Re: Bezierkurven und class

#10159 On 13 Mai, 2011 12:20 Jürgen Schell said,

Hallo Norbert,

die einfachste Methode ist: Einfach einen der Punkte auswählen.

Beispiel für den Fall, dass ein Bézier-Kurvenobjekt ausgewählt ist:

tell application "RagTime 6.5"
	tell window 1
		set x to selection
	end tell
	select Bezier point 1 of x
end tell

Das bringt die Kurve in den Edit-Modus.

In Foren verdirbt es mir manchmal stark die Laune, wenn jemand auf eine Frage sinngemäß antwortet: "Weshalb willst Du das eigentlich? Will doch was anderes." Nach einer Antwort ist mir die Rückfrage hoffentlich dennoch erlaubt: Da das Script die Point List unabhängig vom Bearbeiten-Modus setzen kann, hab ich den Zweck nicht ganz verstanden.

Jürgen

www.j-schell.de

Re: Bezierkurven und class

#10161 On 13 Mai, 2011 15:02 Thomas Kaegi said,

Hallo Jürgen

In deinem Script ist vorausgesetzt, dass das Bézier-Kurvenobjekt ausgewählt ist. Norbert versucht aber ganze Abläufe zu automatisieren. Deshalb ist wohl die vollständige Auswahl eher zielführend, z.B.:

select Bezier point 1 of Bezier curve 1 of page 1 of layout "Layout 1" of document 1

Natürlich ist dabei das Wesentliche deinem Vorschlag entnommen. Mit diesem Script-Code wird das betreffende Bézier-Objekt in den Bearbeitungsmodus versetzt.

Gruss, Thomas

Re: Bezierkurven und class

#10162 On 14 Mai, 2011 13:09 Jürgen Schell said,

Hallo Thomas,

…Norbert versucht aber ganze Abläufe zu automatisieren…

Deshalb meine Rückfrage: Wenn man nicht interaktiv mit der Maus arbeitet (und dafür den Kurvenbearbeiten-Modus ausgelöst haben will), fällt mir keine Anwendung ein: Die Punkte einer Bézierkurve können vom Script immer direkt bearbeitet werden, egal, ob die Kurve ausgewählt ist und / oder sich im Bearbeiten-Modus befindet. Man kann die Punktliste auslesen, dann Änderungen hinein rechnen und anschließend die Punktliste wieder setzen.

Hier ein einfaches Beispiel für so eine Bearbeitung:

tell application "RagTime 6.5"
	set x to a reference to (Bezier curve 1 of page 1 of layout "Layout 1" of document 1)
	set pl to point list of x
	repeat with C in pl
		set item 1 of C to (item 1 of C) * 1.5
	end repeat
	set point list of x to pl
end tell

Das Script multipliziert für jeden Kurven- und Kontrollpunkt die X-Koordinate mit 1,5 und setzt dann die Punktliste. (Wirkung ist: Jeder Punkt wird um diesen Faktor vom linken Blattrand weiter entfernt.) Ist ein sehr simples Beispiel, zeigt aber gut, wie man so eine Bearbeitung macht, und dass der Kurvenbearbeiten-Modus bei so einer Automatisierung egal ist.

Jürgen

www.j-schell.de

Re: Bezierkurven und class

#10163 On 15 Mai, 2011 10:42 werkwelt said,

Moin, Jürgen und Thomas,

Eure Ideen helfen weiter.

Meine Frage kam auf, weil offensichtlich eine Skripteditoraufnahme (Mitschreiben durch den Skripteditor beim Bedienen meiner Bezierkurve) nicht ausführbar wird, weil die class leer bleibt. (Sobald RagTime 6.6 ausgearbeitet wird, könnte hier nachgebessert werden.)

Meine »Zeichenmaschine« arbeitet gegenläufig, mal ändert man mit der Maus die graphische Bezierkurve, mal ändert man entsprechende numerische Werte. Beim Löschen von Bezierstützpunkten (Markieren mit der Maus, Löschen mit der Taste »rückwärts löschen«) wird die Bezierkurve verlassen und das Objekt verliert den Bearbeitungsmodus. Ich bin allerdings noch am Lernen und Üben und merke gerade, daß die Bezierkurvenbearbeitungswerkzeuge mit Kürzeln belegt werden können. Löscht man mit dem Minuszeichenwerkzeug, bleibt die Bezierkurve im Bearbeitenmodus. Das Umschalten über Kürzel ist sehr komfortabel.

Für meine Zeichenmaschine lote ich aus, wo in RagTime die Grenzen liegen, um eine Bedienoberfläche gestalten zu können.
Beispielsweise würde ich gerne nach dem Umschalten eines Knopfes als Einblendmenü einen Skript anstoßen können (ohne anschließend noch einen weiteren Knopf betätigen zu müssen).
Oder ich würde gerne die Palette mit den Kurvenbearbeitungswerkzeugen in der Nähe meiner Bezierkurven auftauchen lassen. :-)

RagTime, FileTime, FileMaker, AppleScript und Spell Catcher X geben Flügel (und eine »Zeichenmaschine«).

Mit freundlichen Grüßen,
Norbert Lindenthal

Re: Bezierkurven und class

#10167 On 16 Mai, 2011 16:57 Thomas Kaegi said,

Hallo Norbert

Beispielsweise würde ich gerne nach dem Umschalten eines Knopfes als Einblendmenü einen Skript anstoßen können (ohne anschließend noch einen weiteren Knopf betätigen zu müssen).

Das geht meines Erachtens nicht. Mit der MetaFormel-Funktion "RechneText" lassen sich zwar Formeln zusammenstellen. Aber da ein AppleScript kein Rechenblattbefehl sein kann, kann das Script nicht aus einer Formel aufgerufen werden, sondern eben nur mit einem Knopf.

Was ich mir vorstellen kann, aber das müsste einer der AppleScript-Päpste bestätigen: Vielleicht ist es möglich, im Hintergrund ständig ein Script laufen zu lassen, welches die Änderung des Einblendmenüs feststellt und nur bei Änderung des Knopfwertes den Rest des Scripts ausführt oder ein anderes anstösst.

Gruss, Thomas

Re: Bezierkurven und class

#10170 On 17 Mai, 2011 23:39 djschulz said,

Kleine Anregung für dieses Problem.

In RagTime ein neues Layout mit einem Rechenblatt und einem Knopf erstellen.
Knopf als Einblendmenü definieren und den Namen als Ergebnis zurückliefern lassen. Ich habe dem Knopf hier zwei Einträge gegeben, "Zelle füllen" und "Zellinhalt löschen".

Dann Folgendes Skript im Skripteditor als "Programm" mit der Option "Nicht Automatisch beenden" abspeichern.


on idle
try
tell application "RagTime 6"
tell document 1
if value of button "Knopf 1" = "Zelle füllen" then
set value of cell "A1" of table "Rechenblatt 1" to "Hallo"
else
set value of cell "A1" of table "Rechenblatt 1" to ""
end if
end tell
end tell
end try
return 1
end idle

Die Zahl hinter dem return gibt an, nach wieviel Sekunden der idle-Handler erneut aufgerufen wird, Läßt man den Wert weg wird standardmäßig nur alle 30 Sekunden nachgeschaut, was hier wohl zu wenig ist. Kleinere Zeitmaße als eine Sekunde sind nicht möglich, zumindest nicht ohne Fremderweiterung.

Dann das Programm starten und in RagTime einfach mal das Einblendmenü bedienen. Je nachdem welchen Wert man im Einblendmenüp auswählt wird die Zelle A1 gelöscht oder mit "Hallo" gefüllt.

Alternativ kann man das Skript auch noch in den Hintergrund schicken, so das es im Finder nicht sichtbar ist. Steht auf Seite 670 in meinem Buch "AppleScript - Der automatische Mac".

Und natürlich kann man das idle-Programm auch aus RagTime heraus starten, zum Beispiel so:

set scriptName to "idle.app"
--Pfad zum Skript "scriptName" zusammenbauen wenn es z.B. in /Library/Scripts/ liegt:
set thePath to (POSIX path of (path to library folder from local domain as text)) & "Scripts/" & scriptName & "/Contents/MacOS/applet"
-- idle-Programm über die Shell starten und stdout und stderr in dev/null umleiten damit das Terminal nicht aufgeht:
set x to do shell script (quoted form of thePath) & "> /dev/null 2> /dev/null &"

Gruß und viel Spaß beim Basteln
Detlef

Re: Bezierkurven und class

#10171 On 18 Mai, 2011 14:04 Thomas Kaegi said,

Hallo Norbert

Das Script von Detlef (danke!) kannst du einfach um das Script herumbauen, das du gerne mit jeder Änderung der Wahl mit dem Einblendmenü auslösen möchtest. Ich habe das mal versucht und erfolgreich getestet. Detlefs Script habe ich abgeändert. In Zelle A1 des Rechenblattes ist der beim letzten Durchlauf des Scripts festgestellte Wert (egal ob Titel oder Index) des Einblendmenü-Knopfes gesichert. Wurde die Wahl mit dem Einblendmenü verändert, dann wird der zuerst der neue Wert des Knopfes in A1 gesichert und dann die eigentliche Aufgabe, die nach Änderung der Knopfwahl ausgeführt werden soll, erledigt.

Damit diese "eigentliche Aufgabe" nicht gleich nach Öffnen des RagTime-Dokumentes und Start des Scripts bereits ausgeführt wird, habe ich im Script noch die Zeilen eingefügt, mit denen der Wert des Knopfes in Zelle A1 übertragen wird, sofern die Zelle vorher leer ist (Bedingung ist natürlich, dass das RagTime-Dokument so gesichert ist).

Als "eigentliche Aufgabe" habe ich hier als Test nur das Initialisieren und Inkrementieren des Wertes in Zelle A2 definiert. Da musst du natürlich das Script für die von dir definierte Aufgabe einsetzen. Und natürlich kann in diesem Scriptteil auch eine differenzierter Ablauf in Abhängigkeit vom Wert des Knopfes programmiert werden.


on idle
try
-- Aufpassen: in der folgenden Zeile richtige RagTime-Version angeben!
tell application "RagTime 6.5"
tell document 1
-- beim Start des Scripts den Wert des Knopfes zuerst sichern
if cell "A1" of table "Rechenblatt 1" is empty then
set value of cell "A1" of table "Rechenblatt 1" to value of button "Knopf 1"
end if
-- hat der Wert des Einblendmenüs "Knopf 1" geändert?
if value of button "Knopf 1" is not equal to value of cell "A1" of table "Rechenblatt 1" then
-- Ja: neuen Wert des Knopfes für nächsten Vergleich sichern
set value of cell "A1" of table "Rechenblatt 1" to value of button "Knopf 1"
-- und eigentliche Aufgabe lösen
if cell "A2" of table "Rechenblatt 1" is empty then
set value of cell "A2" of table "Rechenblatt 1" to 1
else
set value of cell "A2" of table "Rechenblatt 1" to (value of cell "A2" of table "Rechenblatt 1") + 1
end if
-- Ende der eigentlichen Aufgabe
end if
end tell
end tell
end try
return 1
end idle

Den zweiten Teil der Anregung von Detlef habe ich nicht getestet. Ich habe einfach nach dem Öffnen des RagTime-Dokumentes das Script gestartet.

Gruss, Thomas