Jedes anspruchsvolle Mal- und Grafikprogramm verfügt über eine Funktion, die es gestattet. Bildausschnitte von beliebiger Größe auf dem Bildschirm zu verschieben bzw. zu kopieren. Hierbei besteht der Unterschied zwischen „Verschieben“ und „Kopieren“ darin, daß bei der Funktion „Verschieben“ der Ausschnitt im wahrsten Sinne aus dem Bild „herausgeschnitten“ wird. Bei der Funktion „Kopieren“ verbleibt der Originalausschnitt im Bild, die Kopie des Ausschnitts läßt sich an anderer Stelle beliebig positionieren.
Das Verschieben von grafischen Einheiten stellt den wesentlichen Bestandteil des sogenannten Layouts etwa einer Druckvorlage dar. Die in diesem Artikel gezeigten Routinen lassen Schere und Klebstoff - Hauptwerkzeuge beim Layout - endgültig überflüssig werden: Alle grafischen Einheiten, seien es Texte, Bilder oder auch Notensysteme, können mit der Maus auf dem Bildschirm druckfertig arrangiert werden.
Der zu verschiebende Bildausschnitt wird mit dem „Gummifaden“ eingerahmt. Dieser eingerahmte Bildschirmbereich wird in geeigneter Weise zwischengespeichert - gepuffert - und kann dann an beliebiger Stelle mit der Maus wieder auf dem Bildschirm plaziert werden. Bei der Funktion „Verschieben“ wird der Bereich unter dem Rahmen gelöscht.
Die Realisierung dieses an sich einfachen Prinzips findet sich in der Procedure Verschieben(Copy%). Betrachten wir das Listing:
Die Do-Loop-Hauptschleife ist nur notwendig, falls nach dem Aufruf der Prozedur die Möglichkeit bestehen soll, mehrere Verschiebungen unmittelbar nacheinander vornehmen zu können.
Die erste While-Wend-Schleife wird bis zum Mausklick mit der linken Taste durchlaufen. Dabei ist die Menüüberwachung eingeschaltet. Erfolgt nun ein Mausklick, wird mit MOUSE xl%, yl%,k% die augenblickliche Bildschirmposition der Maus festgehalten und der Variablen xl% bzw. yl% übergeben.
Die Werte der Koordinaten xl% und yl% bleiben in der nun folgenden Rahmenschleife konstant, da hier mit MOUSE xr%,yr%,k% eine eigene Mausstatusauswertung erfolgt. Der Grund für diese zweifache Statusermittlung liegt in dem Prinzip, nach dem der “Gummifaden” auf dem Bildschirm erzeugt wird: Für das Zeichnen des Rahmens mit dem BOX-Befehl werden vier Koordinaten benötigt, zwei für die linke obere Ecke (xl%,yl%) und zwei für die rechte untere Ecke (xr%,yr%). Da die Größe des Rahmens mit der Maus eingestellt wird und diese nur zwei Koordinaten liefert, müssen die Werte der linken, oberen Koordinaten konstant bleiben, wahrend die Werte der Koordinaten der rechten, unteren
Ecke analog zur Mausbewegung verändert werden können. Zur Realisierung des “Gummifadens' benötigt man demnach prinzipiell zwei Schleifen mit zwei unabhängigen Statusermittlungen.
Nach einer Bewegung der Maus muß vor dem Zeichnen des neuen Rahmens der alte Rahmen gelöscht werden, da andernfalls nach mehreren Mausbewegungen nur noch ein schwarz ausgefülltes Rechteck auf dem Bildschirm verbleiben würde. Das Löschen das alten Rahmens geschieht mit dem zweiten BOX-Befehl innerhalb der Rahmenschleife. Die beiden gleichartigen BOX-Befehle sind durch eine Repeat-Until-Schleife voneinander getrennt. Diese Schleife wird nach einer Mausbewegung verlassen, und das zweite BOX xl%,yl%,xr%,yr% überschreibt (im Graphmode 3) den alten Rahmen.
Die Rahmenschleife wird verlassen, sobald die linke Maustaste losgelassen wurde. Der eingerahmte Bereich wird jetzt mit GET xl%,yl%,xr%,yr%,Snp$ gepuffert. Findet die Verschiebung/Kopie in einem GEM-Fenster statt, muß zur y-Koordinate der Wert 38 hinzuaddiert werden. Der Grund hierfür: Die Grafikbefehle in GEM-Fenstern haben einen anderen Bezugspunkt als die Rasterbefehle GET und PUT, die immer vom Punkt (0,0) ausgehen.
Soll der Ausschnitt verschoben, aber dabei nicht kopiert werden, überdeckt ein Rechteck von der Größe des Ausschnitts den eingerahmten Bereich mit PBOX xl%,yl%,xr%,yr% bei Deffill 0. Die Füllmusterfarbe wird danach sicherheitshalber mit Deffill 1 wieder auf "Objektfarbe” festgelegt. Die Entscheidung, ob der Ausschnitt verschoben oder kopiert wird, übergibt man schon beim Aufruf der Prozedur mit dem Wert der Variablen Copy%. Nach dem Verlassen der Rahmenschleife würde sich ohne weitere Maßnahmen der Mauscursor an der rechten unteren Ecke des Rahmens befinden. Damit in der folgenden Verschiebeschleife der Mauscursor sofort wieder an der linken oberen Ecke des Ausschnitts erscheint, wird mit DPOKE 9952,xl%+1 bzw. DPOKE 9954,yl%+38 der Cursor dorthin zurückgesetzt. Eine beliebige Mausposition kann also bestimmt werden, indem einfach die entsprechenden Werte plus GEM-Offset an diese Adressen ge” de poked” werden.
In der Verschiebeschleife wird nach erneuter Statusermittlung zunächst der Originalhintergrund mit SGET Bild$ gepuffert. Nun zeigt PUT x%,y%+38,Snp$,7 den Ausschnitt, was allerdings erst ab dem zweiten Schleifendurchlauf, d.h. nach der ersten Verschiebung, deutlich wird: Nach einer Mausbewegung wird die While-Wend-Warteschleife verlassen und mit SPUTBild> der Ausschnitt an seiner alten Position überdeckt. Die Verschiebeschleife wird erneut durchlaufen, und jetzt zeigt der PUT-Befehl den Ausschnitt an seiner neuen Position.
Erfolgt nun ein abschließender Mausklick, wird die Verschiebeschleife verlassen, und der Ausschnitt befindet sich an seiner endgültigen Position.
Die Möglichkeit zum Verschieben des Ausschnitts resultiert demnach aus dem Zusammenwirken der Befehle SPUT für den Hintergrund und PUT für den Ausschnitt. Die Tatsache, daß der Ausschnitt nach einer Mausbewegung an seiner alten Position mit SPUT überdeckt wird, ist übrigens die Ursache für ein leichtes Flackern des Ausschnitts während des Verschiebens. Die Warteschleife sorgt dafür, daß bei unbewegter Maus kein solches Flackern entsteht. Für den jeweiligen PUT-Modus stehen prinzipiell die Werte 0 bis 15 zur Verfügung, wobei die wichtigsten die Modi 3 (Graphmode 1), 6 (Graphmode 3), 7 (Graphmode 2) und 4 (Graphmode 4) sind.
Die beschriebene Prozedur kann in jedes Grafikprogramm integriert werden. In dieser Demoversion werden mit der Procedure Flaechen bzw. Procedure Text einfache grafische Einheiten zum Ausprobieren der Verschiebe- bzw. Kopierfunktion erzeugt.
' (c) MAXON Computer GmbH 1988
'
DIM m$(22) !Menü erstellen
RESTORE mmenue
FOR z%=0 TO 21
READ m$(z%)
NEXT z%
mmenue:
DATA DESK , Info ,--------------------
DATA 1,2,3,4,5,6,""
DATA GRAFIK , Flächen , Text ,---------------, Quit,""
DATA LAYOUT , Verschieben , Kopieren ,---------------,"","",""
MENU m$()
FULLW 1 !GEM-Fenster öffnen
'
GOSUB menu
PROCEDURE menu
DEFMOUSE 0
DO ! Auf Ereignis
ON MENU ! warten
REPEAT ! und wenn
UNTIL MOUSEK=0 ! Maustaste losgelassen
ON MENU GOSUB auswahl ! verzweigen
LOOP
RETURN
'
PROCEDURE auswahl !Auswahl treffen
IF MENU(0)=1
MENU OFF
GOSUB copyright
ENDIF
IF MENU(0)=11
MENU OFF
GOSUB flaechen
ENDIF
IF MENU(0)=12
MENU OFF
GOSUB text
ENDIF
IF MENU(0)=14
MENU OFF
END
ENDIF
IF MENU(0)=17
MENU OFF
GOSUB verschieben(0)
ENDIF
IF MENU(0)=18
MENU OFF
GOSUB verschieben(1)
ENDIF
RETURN
'
'
PROCEDURE verschieben(copy%)
DEFMOUSE 5 ! Fadenkreuz
DO ! Hauptschleife
WHILE MOUSEK=0
ON MENU
WEND
ON MENU
MOUSE xl%,yl%,k% ! Mauskoordinaten links-oben
GRAPHMODE 3
DEFLINE 2,1,,
'
' ***** Rahmen zeichnen *****
'
WHILE MOUSEK=1
MOUSE xr%,yr%,k% ! Mauskoordinaten rechts-unten
BOX xl%,yl%,xr%,yr% ! Verschiebe-Bild umrahmen
REPEAT
UNTIL MOUSEK=0 OR MOUSEX<>xr% OR MOUSEY<>yr% ! Wenn Maus bewegt
BOX xl%,yl%,xr%,yr% ! alten Rahmen loeschen
WEND
DEFLINE 1,1,,
GET xl%,yl%+38,xr%,yr%+38,snp$ ! Ausschnitt puffern
IF NOT copy%=1 ! Nicht kopieren?
DEFFILL 0 !
GRAPHMODE 1 !
PBOX xl%,yl%,xr%,yr% !dann Original überdecken
DEFFILL 1
ENDIF
DPOKE 9952,xl%+1 ! Mauscursor nach links-oben
DPOKE 9954,yl%+38! zurücksetzen
'
' ***** Verschieben/Kopieren *****
'
WHILE MOUSEK=0
ON MENU
MOUSE x%,y%,k%
SGET bild$ ! Hintergrund puffern
PUT x%,y%+38,snp$,7 ! Ausschnitt zeigen
WHILE MOUSEX=x% AND MOUSEY=y% AND MOUSEK=0 ! Auf Mausbewegung warten
ON MENU
WEND
SPUT bild$ !Hintergrund über Ausschnitt legen
WEND
PUT x%,y%+38,snp$,7
WHILE MOUSEK=1 !Warten bis Taste losgelassen
WEND
LOOP
DEFTEXT ,0,,13
RETURN
'
PROCEDURE flaechen
GRAPHMODE 1
FOR z%=1 TO 3 STEP 2
DEFFILL ,2,RANDOM(24)
PBOX 50*z%,50*z%,100*z%,100*z%
NEXT z%
DEFFILL 1
GOSUB menu
RETURN
'
PROCEDURE text
GRAPHMODE 2
FOR z%=60 TO 300 STEP 80
TEXT 340,z%," Verschieben oder kopieren "
NEXT z%
GOSUB menu
RETURN
'
'
PROCEDURE copyright
CLS
BOX 120,70,530,270
DEFTEXT ,,,13
TEXT 150,130,"Verschieben und Kopieren von Bildausschnitten"
DEFTEXT ,,,13
TEXT 260,170,"in GfA-Basic"
DEFTEXT ,,,6
TEXT 230,210,"MAXON Computer 1988"
DEFTEXT ,,,13
PAUSE 100
CLS
GOSUB menu
RETURN