**************************************************************************
; HNDLMENU-Modul
; 21.01.1993 by Jan Kriesten
**************************************************************************

		.INCLUDE "OFFSET.SH"
		
*** Globale Variablen:

		;*** Arbeitsbereich des Desktops:
		.IMPORT desk

		;*** MyDial-Variablen:
		.IMPORT my_mousnumber, my_mousform, mygl_wbox, mygl_hbox

*** Globale Funktionen:

		;*** Routinen zur Listbox-Behandlung:
		.EXPORT listbox, HndlDial, dial_do, obj2item

		;*** Scrollroutine (aus MISC.S):
		.IMPORT scroll_area
		
		;*** MyDial-Routinen:
		.IMPORT open_dial, dial_draw, dial_move, close_dial
		.IMPORT obj_edit, form_Keybd, mybeep, objc_rect
		.IMPORT get_idx, get_obspec, do_state, undo_state

		;*** Bibliotheksfunktionen:
		.IMPORT form_button, graf_mouse, graf_slidebox, strncpy
		.IMPORT EvntMulti, objc_find, objc_change, objc_draw, wind_update

**************************************************************************
; Routinen zur Listbox-Behandlung
**************************************************************************

		.TEXT
		
;-------------------------------------------------------------------------------
; Funktionsname:	HndlDial
; 		->	a0:	Zeiger auf Objektbaum
;			a1:	Zeiger auf RECT fr die Ausgangsposition von Grow-/Shrinkbox
;			d0:	TRUE: Grow-/Shrinkboxen zeichnen, sonst FALSE
;			d1:	Default-Editfeld
;		<-	d0: Exit-Button, mit dem Dialog verlassen wurde (Bit 15 ist bei
;				Doppelklick gesetzt!)
;
; Die Funktion handelt eine Dialogbox unter Verwendung der Funktionen hndl_list
; open_dial, dial_draw, dial_do und dial_close vollst„ndig ab. Sie ist eine
; an meine eigene dial_do-Routine angepažte Version der Namensgleichen MyDial-
; Routine.
;
HndlDial:
		movem.l		d3/d4/a3/a4, -(sp)	; Register retten
		
		movea.l		a0, a3				; Tree sichern
		movea.l		a1, a4				; Rect-Adresse sichern
		move.w		d0, d3				; Grow/Shrink? sichern
		move.w		d1, d4				; Default-Edit-Objekt sichern
		
		link		a2, #-32			; Lokale Variable anlegen
			DIALINF		.EQU	-32		; Offset der Variable

		;*** Dialogbox ”ffnen:
		pea			DIALINF(a2)			; Adresse der DialInfo-Struktur auf den Stack
		jsr			open_dial			; MYDIAL: ”ffne Dialog
		addq.l		#4, sp				; Stack restaurieren

		;*** Dialogbox zeichnen:
		lea			DIALINF(a2), a0		; Adresse der DialInfo-Struktur nach a0
		jsr			dial_draw			; MYDIAL: Dialog zeichnen

		;*** Dialog abarbeiten:
		lea			DIALINF(a2), a0		; Adresse der DialInfo-Struktur nach a0
		clr.l		a1					; keine Listbox
		move.w		d4, d0				; Default Edit-Objekt
		jsr			dial_do
		move.w		d0, d4				; Rckgabe sichern
		
		;*** SELECTED-Status beim Exit-Objekt l”schen:
		ext.l		d0					; suchen der Anfangsadresse des Objekts
		move.l		d0, d1				; d0 ist nur Hilfsvariable
		add.l		d1, d1				;\
		add.l		d0, d1				; >	d1 * 24 [ (d0 + d0 + d0) * 8 ]
		lsl.l		#3, d1				;/
		andi.w		#$FFFE, 10(a0, d1.l); SELECTED l”schen

		;*** Dialogbox schliežen:
		movea.l		a4, a0				; Bildschirmmitte fr Grow-/Shrinkbox zeichnen
		lea			DIALINF(a2), a1		; Adresse der Dialinfo-Struktur
		move.w		d3, d0				; keine Grow-/Shrinkbox zeichnen
		jsr			close_dial			; MYDIAL: Dialog schliežen

		;*** Ende der Funktion:
		move.w		d4, d0				; Rckgabewert wieder setzen
		unlk		a2					; Lokale Variablen entfernen
		movem.l		(sp)+, d3/d4/a3/a4	; Register restaurieren
		rts								; und zurck

;-------------------------------------------------------------------------------
; Funktionsname:	dial_do
; 		->	a0:	Zeiger auf Dialinfo-Struktur
;			a1:	Zeiger auf Listbox-Struktur
;			d0: Start-Editfeld
;		<-	d0: Exit-Button, mit dem Dialog verlassen wurde (Bit 15 ist bei
;				Doppelklick gesetzt!)
;
; Die Funktion handelt eine Dialogbox unter Verwendung der Funktionen hndl_list
; und dial_move vollst„ndig ab. Sie ist eine erweiterung der MyDial-Funktion 
; dial_do.
;
dial_do:
		move.l		a2, -(sp)			; Register retten
		move.l		a3, -(sp)			; "
		
		movea.l		a0, a3				; Pointer auf DIALINFO sichern
		movea.l		a1, a2				; Pointer auf LISTBOX  sichern

		cmp.w		#-1, d7				; war d7 -1?
		bne			.loop				; wenn nicht, dann ist die Parameter-
										; bergabe in Ordnung!
		clr.l		a2					; sonst kein Pointer auf Listbox!
		
.loop:
*** Abhandlung des Dialoges mit editieren, shortcuts und listen durch hndl_list:
		movea.l		(a3), a0			; Pointer auf Objektbaum bergeben
		movea.l		a2, a1				; Pointer auf LISTBOX bergeben
		bsr			hndl_list			; Dialog mit Listbox abarbeiten
		move.w		d0, d2				; Retten des Return-Buttons

;*** suchen der Anfangsadresse des Exit-Objekts
		movea.l		(a3), a0			; Adresse des Dialogbaums holen
		andi.l		#$00007fff, d0		; Bit 15 (Doppelklick) l”schen
		move.l		d0, d1				; d0 ist nur Hilfsvariable
		add.l		d1, d1				;\
		add.l		d0, d1				; >	d1 * 24 [ (d0 + d0 + d0) * 8 ]
		lsl.l		#3, d1				;/
		move.w		6(a0, d1.l), d0		; ob_type des Buttons 
		
		lsr			#8, d0				; extended objecttype holen
		cmpi.w		#17, d0				; Dialmover?
		bne			.ld_ende			; wenn nicht, dann zurck

		;*** Mauszeiger in Hand verwandeln:
		clr.l		a0					; keine eigene Mausform
		moveq.l		#4, d0				; FLATHAND darstellen
		jsr			graf_mouse			; AES-Funktion ausfhren
		
;*** Dialogbox verschieben:
		lea			desk, a0			; Adresse des Desk-Arbeitsbereiches holen
		move.w		6(a0), -(sp)		; desk.h auf den Stack
		move.w		4(a0), d2			; desk.w nach d2
		move.w		2(a0), d1			; desk.y nach d1
		move.w		(a0), d0			; desk.x nach d0
		movea.l		a3, a0				; DIALINFO-Adresse nach a0
		jsr			dial_move			; MYDIAL: Dialog verschieben
		addq.l		#2, sp				; Stack aufr„umen

		;*** Mauszeiger in letzte Mausform zurck:
		movea.l		my_mousform, a0		; letzte Mausform
		movea.l		(a0), a0			; "
		movea.l		my_mousnumber, a1	; Nummer der letzten Mausform
		move.w		(a1), d0			; "
		jsr			graf_mouse			; AES-Funktion ausfhren

		clr.w		d0					; 0 Start-Editobjekt		
		bra			.loop				; weiter

*** Ende von dial_do:

.ld_ende:
		move.w		d2, d0				; Exit-Button zurckgeben
		
		movea.l		(sp)+, a3			; Register restaurieren
		movea.l		(sp)+, a2			; "
		
		rts

;-------------------------------------------------------------------------------
; Funktionsname:	hndl_list
; 		->	a0:	Zeiger auf Objekt-Baum
;		->	a1: Zeiger auf Listbox-Struktur
;		->	d0:	Start-Editobjekt
;		<-	d0: Exit-Button, mit dem Dialog verlassen wurde (Bit 15 ist bei
;				Doppelklick gesetzt!)
;
; Eine Dialogbox wird soweit abgearbeit, daž Eintr„ge in Editfelder vorgenommen,
; Shortcuts und Buttons behandelt und Clicks in Listboxen abgearbeitet
; werden.
;
hndl_list:
		movem.l		d3-d7/a3-a5, -(sp)	; Register retten

;*** Variablen initialisieren:		
		movea.l		a0, a3				; Zeiger auf Objektbaum retten
		movea.l		a1, a4				; Zeiger auf Listbox-Struktur retten
		move.w		d0, d4				; Start-Editfeld retten
		
		;*** Bildschirmaktionen anderer Programme sperren:
		moveq.l		#1, d0				; BEG_UPDATE
		jsr			wind_update			; AES-Funktion ausfhren
		
		;*** Mauskontrolle bernehmen:
		moveq.l		#3, d0				; BEG_MCTRL
		jsr			wind_update			; AES-Funktion ausfhren

		tst.w		d4					; war ein Editfeld ausgew„hlt?
		bne			.no_search			; wenn ja, dann brauchen wir nicht suchen

		moveq.l		#-2, d1				; Vorw„rts suchen
		movea.l		a3, a0				; Zeiger auf Dialogbaum nach a0
		bsr			find_obj			; Start-Editfeld suchen

.no_search:
		move.w		d0, d4				; Start-Editfeld in next_obj

		clr.l		d3					; aktuelles edit_obj initialisieren
		moveq.l		#1, d7				; cont auf TRUE setzen

		;*** EvntStruct initialisieren:
		lea			evnt_strct, a0		; Adresse des evnt_strct-Feldes laden
		move.l		#$00030002, (a0)	; flags: MU_KEYBD|MU_BUTTON, maximal gez„hlte Tastendrcke: 2
		move.l		#$00010001, 4(a0)	; Maske: linke Maustaste, State: muž gedrckt sein
		clr.l		8(a0)				; keine Rechtecke und Flags fr Maus		
		clr.l		12(a0)
		clr.l		16(a0)
		clr.l		20(a0)
		clr.l		24(a0)
		clr.l		28(a0)				; kein Timer
		
;               *+++++*+++++* Schleife abarbeiten *+++++*+++++*

while:
		tst.w		d7					; cont noch ungleich 0?
		beq			.hl_ende			; wenn nein, dann ende der Funktion
		
		tst.w		d4					; ist next_obj gleich Null?
		beq			.l1					; wenn ja, dann kein Editfeld initialisieren
		
		cmp.w		d3, d4				; und ist edit_obj != next_obj?
		beq			.l1					; wenn ja, ebenfalls nix Editfeld initialisieren
		
;*** Editfeld initialisieren:
		move.w		d4, d3				; edit_obj = next_obj setzen
		clr.w		d4					; und next_obj auf 0 setzen

		move.w		d3, edit_obj		; nur zum šbergeben der Adresse
		move.w		d5, idx				; "
		
		move.w		#-1, -(sp)			; kein Window-Handle
		pea			edit_obj			; hier neues edit_obj eintragen
		clr.w		-(sp)				; Bildschirmausgaben sind erlaubt
		move.w		#1, -(sp)			; obj_edit initialiseren, Cursor einschalten
		lea			idx, a1				; Adresse des Indexes
		clr.w		d2					; kein kreturn
		clr.w		d1					; kein kstate
		move.w		d3, d0				; Objektnummer des aktuellen Edit-Objekts
		movea.l		a3, a0				; Zeiger auf Dialogbaum
		jsr			obj_edit			; MYDIAL: neue objc_edit-Routine
		lea			10(sp), sp			; Stack aufr„umen

		move.w		edit_obj, d3		; aktuelles Edit-Objekt zurckschreiben
		move.w		idx, d5				; aktuellen idx zurckschreiben

.l1:
*** Event-Multi aufrufen:
		;*** jetzt kommt ein Event-Multi!
		lea			evnt_strct, a0		; Adresse des evnt_strct-Feldes laden
		jsr			EvntMulti			; AES-Funktion ausfhren

		;*** Rckgabe sichern:
		move.w		d0, d6				; Return-Wert von evnt_multi
		lea			ev_mox, a0			; Adresse des intout-Feldes laden
		move.l		(a0), mox			; mox, moy sichern
		move.l		4(a0), mobutton		; mobutton, kstate sichern
		move.l		8(a0), kreturn		; kreturn, breturn sichern

*** šberprfen, ob ein Tastaturereignis aufgetreten ist:
		btst.b		#0, d6				; Bit 0 gesetzt (Tastaturereignis)?
		beq			.mous_ev			; wenn Zero-Flag, dann auf mbutton testen

*** Tastaturereignis abarbeiten:
		move.w		d4, next_obj		; nur zum šbergeben der Adresse

		;*** form_Keybd aufrufen:
		pea			kreturn				; Adresse von kreturn auf den Stack
		lea			next_obj, a1		; Adresse von next_obj nach a1
		move.w		kstate, -(sp)		; Status der Sondertasten auf den Stack
		move.w		kreturn, d2			; Inhalt von kreturn nach d2
		move.w		d4, d1				; next_obj nach d1
		move.w		d3, d0				; edit_obj nach d0
		movea.l		a3, a0				; Zeiger auf Dialogbaum
		jsr			form_Keybd			; MYDIAL: neue form_keybd-Routine
		addq.l		#6, sp				; Stack aufr„umen
		
		move.w		next_obj, d4		; aktuelles next_obj zurckschreiben
		move.w		d0, d7				; Return-Wert ist cont
		
		;*** Ist Eingabe in ein Editobjekt n”tig?
		tst.w		kreturn				; ist kreturn 0?
		beq			.no_editinput		; wenn ja, dann keine Eingabe

		;*** Eingabe in Edit-Objekt vornehmen:		
		move.w		d3, edit_obj		; nur zum šbergeben der Adresse
		move.w		d5, idx				; "
		
		move.w		#-1, -(sp)			; kein Window-Handle
		pea			edit_obj			; hier neues edit_obj eintragen
		clr.w		-(sp)				; Bildschirmausgaben sind erlaubt
		move.w		#2, -(sp)			; Zeichen verarbeiten (ED_CHAR)
		lea			idx, a1				; Adresse des Indexes
		move.w		kreturn, d2			; kreturn
		move.w		kstate, d1			; kstate
		move.w		d3, d0				; Objektnummer des aktuellen Edit-Objekts
		movea.l		a3, a0				; Zeiger auf Dialogbaum
		jsr			obj_edit			; MYDIAL: neue objc_edit-Routine
		lea			10(sp), sp			; Stack aufr„umen

		move.w		edit_obj, d3		; aktuelles Edit-Objekt zurckschreiben
		move.w		idx, d5				; aktuellen idx zurckschreiben

		move.w		d3, d4				; next_obj = edit_obj setzen

		bra			.mous_ev			; weiter bei .mous_ev

.no_editinput:

		;*** war die Eingabe vielleicht ein Shortcut fr ein Exit-Objekt?
		andi.l		#$0000FFFF, d3		; d3 erweiteren
		move.l		d3, d0				; d0 ist nur Hilfsvariable
		add.l		d0, d0				;\
		add.l		d3, d0				; >	d0 * 24 [ (d3 + d3 + d3) * 8 ]
		lsl.l		#3, d0				;/
		move.w		8(a3, d0.l), d0		; ob_flags des Objekts

		btst.b		#2, d0				; Bit 2 (EXIT) in ob_flags gesetzt?
		beq			.mous_ev			; wenn nicht, dann weiter bei .mous_ev

		cmp.w		d3, d4				; und edit_obj != next_obj?
		beq			.mous_ev			; wenn nicht, dann weiter bei .mous_ev

		move.w		d3, d4				; next_obj = edit_obj setzen
		clr.w		d3					; edit_obj = FALSE setzen
		clr.w		d7					; cont = FALSE setzen

.mous_ev:

*** Mausereignis abarbeiten:

		btst.l		#1, d6				; war ein Mausereignis aufgetreten?
		beq			.no_event			; wenn nicht, dann weiter bei .no_event

		;*** Suchen, auf welches Objekt ein Click ausgefhrt wurde:
		move.w		moy, -(sp)			; y-Koordinate des Mausclicks
		move.w		mox, d2				; x-Koordinate des Mausclicks
		moveq.l		#8, d1				; Suchtiefe: MAX_DEPTH
		clr.w		d0					; Startobjekt: 0
		movea.l		a3, a0				; Tree-Adresse
		jsr			objc_find			; AES-Funktion ausfhren
		addq.l		#2, sp				; Stack restaurieren

		;*** Rckgabe sichern:
		move.w		d0, d4				; Rckgabe ist neues next_obj
		
		;*** Ist berhaupt eins gefunden worden?
		bpl			.found				; wenn ja, dann weiter bei .found

		;*** kein Objekt gefunden:
		jsr			mybeep				; Piepser ausfhren
		clr.w		d4					; und next_obj auf 0 setzen
		bra			.no_event			; dann weiter mit .no_event
		
.found:
		*** ist in eine Listbox geclickt worden?
		cmpa.l		#0, a4				; ist berhaupt eine Listbox vorhanden?
		beq			.no_list			; wenn nicht, dann weiter mit .no_list

		cmp.w		ROOT(a4), d4		; gefundenes Objekt >= ROOT-Objekt der Listbox?
		bmi			.no_list			; wenn nicht, dann weiter mit .no_list
		
		cmp.w		DOWN(a4), d4		; gefundenes Objekt <= DOWN-Arrow der Listbox?
		bhi			.no_list			; wenn nicht, dann weiter mit .no_list

*** Listbox bearbeiten:
		lea			mk, a1				; Adresse der mk-info-Struktur
		movea.l		a4, a0				; Listbox-Adresse nach a0
		moveq.l		#4, d0				; LIST_CLICK
		bsr			listbox				; Unterroutine zur List-Behandlung

		cmpi.l		#0, FUNC(a4)		; ist eine Funktion vorhanden?
		beq			.no_lfunc			; wenn nicht, dann weiter bei .no_lfunc
		
		cmpi.w		#2, breturn			; breturn == 2?
		bne			.no_lfunc			; wenn nicht, dann weiter bei .no_lfunc

		move.w		d4, d0				; Angeclicktes Objekt		
		movea.l		a4, a0				; Listbox-Adresse nach a0
		movea.l		FUNC(a4), a1		; Funktionsadresse holen
		jsr			(a1)				; Funktion aufrufen

.no_lfunc:
		clr.w		d7
		bra			.no_event			; weiter bei .no_event

.no_list:
		;*** Keine Listbox, dann form_button ausfhren
		lea			next_obj, a1		; Adresse von next_obj
		move.w		breturn, d1			; clicks
		move.w		d4, d0				; next_obj
		movea.l		a3, a0				; Tree-Adresse
		jsr			form_button			; AES-Funktion ausfhren
		
		move.w		d0, d7				; return-Wert: 0 = EXIT Objekt;

		;*** Bedingung fr Ende des Dialoges erfllt?
		;+++	cont = 0?
		beq			.no_event			; Edit-Cursor ausschalten und Schluž

		;+++	next_obj EDITABLE?
		move.w		next_obj, d4		; neues next_obj
		beq			.no_event			; wenn nicht editable, dann .no_event

		;+++	Auf Editobjekt geclickt
		;		_und_ erweiterter Typ 25
		;		_und_ breturn == 2?

		andi.l		#$0000FFFF, d4		; d4 erweiteren
		move.l		d4, d0				; d0 ist nur Hilfsvariable
		add.l		d0, d0				;\
		add.l		d3, d0				; >	d0 * 24 [ (d3 + d3 + d3) * 8 ]
		lsl.l		#3, d0				;/
		move.w		8(a3, d0.l), d1		; ob_flags des Objekts
		move.w		6(a3, d0.l), d0		; ob_type des Objekts

		btst.l		#3, d1				; Bit 3 (EDITABLE) in ob_flags gesetzt?
		beq			.no_event			; wenn nicht, dann gleich dort weiter

		lsr.w		#8, d0
		cmpi.w		#25, d0
		bne			.bear_edit			; wenn nicht, dann weiter bei .bear_edit

		cmpi.w		#2, breturn			; breturn == 2?
		bne			.bear_edit			; wenn nicht, dann weiter bei .bear_edit
		
		clr.w		d7					; cont auf 0 setzen
		
		bra			.no_event			; Edit-Cursor ausschalten und Schluž

*** Bearbeiten eines Editfeldes:		
.bear_edit:
		; muž am Cursor etwas ge„ndert werden?
		cmp.w		d3, d4				; ist next_obj != edit_obj?
		beq			.m2					; wenn nicht, dann weiter bei .m2

		;*** Cursor im derzeitigen Editobjekt l”schen:
		move.w		d3, edit_obj		; nur zum šbergeben der Adresse
		move.w		d5, idx				; "
		
		move.w		#-1, -(sp)			; kein Window-Handle
		pea			edit_obj			; hier neues edit_obj eintragen
		clr.w		-(sp)				; Bildschirmausgaben sind erlaubt
		move.w		#3, -(sp)			; Cursor abschalten (ED_END)
		lea			idx, a1				; Adresse des Indexes
		clr.w		d2					; keine Eingabe
		move.w		kstate, d1			; kstate
		move.w		d3, d0				; Objektnummer des aktuellen Edit-Objekts
		movea.l		a3, a0				; Zeiger auf Dialogbaum
		jsr			obj_edit			; MYDIAL: neue objc_edit-Routine
		lea			10(sp), sp			; Stack aufr„umen

		move.w		idx, d5				; aktuellen idx zurckschreiben

		move.w		d4, d3				; edit_obj = next_obj
		clr.w		d4					; und next_obj = 0 setzen

.m2:
		;*** Ausdehnung des Edit-Objekts berechnen:
		clr.w		d1					; ??
		lea			work, a1			; RECT des Objekts
		move.w		d3, d0				; das aktuelle Editobjekt
		movea.l		a3, a0				; Tree-Adresse
		jsr			objc_rect			; MYDIAL: Ausdehnung berechnen

		;*** Adresse des ob_spec des Edit-Objekts:
		movea.l		a3, a0				; Tree-Adresse
		move.w		d3, d0				; das aktuelle Editobjekt
		jsr			get_obspec			; MYDIAL: Zeiger auf ob_spec holen
		movea.l		d0, a0

		;*** Zeichensatzgr”že Korrekt setzen:
		cmpi.w		#5, 12(a0)			; Fontgr”že SMALL?
		bne			.normal				; wenn nicht, dann weiter bei .normal
		
		moveq.l		#6, d2				; wbox setzen
		bra			.switch				; und weiter bei .switch

.normal:
		move.w		mygl_wbox, d2		; sonst normale Punktgr”že

		;*** Textausrichtung beachten:
.switch:
		move.w		work, d1			; work.x nach d1

		cmpi.w		#1, 16(a0)			; TE_RIGHT?
		bne			.s1					; wenn nicht, dann weiter bei .s1

		moveq.l		#-1, d0				; -1 wegen Stringende
		add.w		26(a0), d0			; + ob_spec->te_tmplen
		mulu.w		d2, d0				; das ganze mal wbox
		add.w		work+4, d1			; work.w dazuaddieren
		sub.w		d0, d1				; und das in d0 davon abziehen

		bra			.s2					; weiter bei .s2

.s1:
		cmpi.w		#2, 16(a0)			; TE_CNTR?
		bne			.s2					; wenn nicht, dann weiter bei .s2

		moveq.l		#-1, d0				; -1 wegen Stringende
		add.w		26(a0), d0			; + ob_spec->te_tmplen
		mulu.w		d2, d0				; das ganze mal wbox
		move.w		work+4, d6			; work.w nach d6
		sub.w		d0, d6				; und das in d0 davon abziehen
		lsr.w		#1, d6				; insgesamt noch durch 2 teilen
		add.w		d6, d1				; und zu d1 hinzuaddieren

.s2:
		;*** neuen idx berechnen:
		ext.l		d5
		move.w		d2, d0				; wbox
		lsr.w		#1, d0				; wbox/2
		move.w		mox, d5				; ( x-Position des Mausclicks
		sub.w		d1, d5				; minus work.x
		add.w		d0, d5				; plus wbox/2 )
		divu.w		d2, d5				; durch wbox


		;*** neuer idx zu grož?
		moveq.l		#-1, d0				; -1 wegen Stringende
		add.w		26(a0), d0			; ob_spec->te_tmplen nach d0
		cmp.w		d5, d0				; idx gr”žer als te_tmplen?
		bpl			.not_greater		; wenn nicht, dann weiter bei .not_greater

		move.w		d0, d5				; idx = te_tmplen-1 setzen

.not_greater:

		;*** absolute Cursorposition berechnen:
		move.w		d5, d1				; aktueller index
		move.w		d3, d0				; aktuelles Editobjekt
		movea.l		a3, a0				; Tree-Adresse
		jsr			get_idx				; MYDIAL: absolute Cursorposition berechnen
		move.w		d0, d5				; absoluten neuen idx sichern

		;*** und noch Cursor an neuer Position zeichnen:
		move.w		d3, edit_obj		; nur zum šbergeben der Adresse
		move.w		d5, idx				; "
		
		move.w		#-1, -(sp)			; kein Window-Handle
		pea			edit_obj			; hier neues edit_obj eintragen
		clr.w		-(sp)				; Bildschirmausgaben sind erlaubt
		move.w		#2, -(sp)			; Zeichen verarbeiten (ED_CHAR)
		lea			idx, a1				; Adresse des Indexes
		clr.w		d2					; kein Zeichen verarbeiten
		move.w		kstate, d1			; kstate
		move.w		d3, d0				; Objektnummer des aktuellen Edit-Objekts
		movea.l		a3, a0				; Zeiger auf Dialogbaum
		jsr			obj_edit			; MYDIAL: neue objc_edit-Routine
		lea			10(sp), sp			; Stack aufr„umen

		move.w		edit_obj, d3		; aktuelles Edit-Objekt zurckschreiben
		move.w		idx, d5				; aktuellen idx zurckschreiben

.no_event:

*** šberprfen, ob im aktuelles Editobjekt der Cursor ausgeschaltet werden muž:
		tst.w		d7					; Dialogende?
		beq			.end_obedit			; wenn ja, dann Cursor abschalten
		
		tst.w		d4					; oder next_obj != 0
		beq			while				; wenn nein, dann weiter bei while

		cmp.w		d3, d4				; ist next_obj != edit_obj?
		beq			while				; wenn nicht, dann weiter bei while

.end_obedit:

*** Cursor im aktuellen Editobjekt abschalten:
		move.w		d3, edit_obj		; nur zum šbergeben der Adresse
		move.w		d5, idx				; "
		
		move.w		#-1, -(sp)			; kein Window-Handle
		pea			edit_obj			; hier neues edit_obj eintragen
		clr.w		-(sp)				; Bildschirmausgaben sind erlaubt
		move.w		#3, -(sp)			; Cursor abschalten (ED_END)
		lea			idx, a1				; Adresse des Indexes
		clr.w		d2					; keine Eingabe
		move.w		kstate, d1			; kstate
		move.w		d3, d0				; Objektnummer des aktuellen Edit-Objekts
		movea.l		a3, a0				; Zeiger auf Dialogbaum
		jsr			obj_edit			; MYDIAL: neue objc_edit-Routine
		lea			10(sp), sp			; Stack aufr„umen

		move.w		edit_obj, d3		; aktuelles Edit-Objekt zurckschreiben
		move.w		idx, d5				; aktuellen idx zurckschreiben

		bra			while				; und wieder zu while verzweigen		

*** Ende der Funktion:

.hl_ende:
		;*** Mauskontrolle freigeben:
		moveq.l		#2, d0				; END_MCTRL
		jsr			wind_update			; AES-Funktion ausfhren
		
		;*** Bildschirmaktionen wieder erlauben:
		clr.w		d0					; END_UPDATE
		jsr			wind_update			; AES-Funktion ausfhren
		
		move.w		d4, d0				; next_obj ist Exit-Objekt

		movem.l		(sp)+, a3-a5/d3-d7	; Register restaurieren
		rts								; und zurck


;-------------------------------------------------------------------------------
*** Suchen eines Editobjekts:
find_obj:
		movem		d3-d6, -(sp) 		 ; Register retten
		
		moveq.l		#3, d4				; flag fr EDITABLE (Bit 3: 8)
		move.w		#1, d5				; Inkrement mit 1 vorbesetzen
		moveq.l		#5, d6				; flag fr LASTOB (Bit 5: 32)

		;*** Was ist zu tun?
		addq.w		#1, d1				; Rckw„rts suchen?
		beq			.case_1				; ja, dann weiter bei .case_1
		addq.w		#1, d1				; Vorw„rts suchen?
		beq			.case_2				; ja, dann weiter bei .case_2
		addq.w		#1, d1				; DEFAULT-Objekt suchen?
		bne			.while				; nein, dann eben doch Vorw„rts suchen

		;*** DEFAULT-Objekt suchen:
		moveq.l		#2, d4				; flag auf DEFAULT setzen
		bra			.while				; und suchen ...
		
		;*** case FMD_BACKWARD:
.case_1:
		moveq.l		#-1, d5				; dann um 1 dekrementieren

		;*** case FMD_FORWARD:
.case_2:
		move.w		d0, d3				; start der Suche ist Start-Objekt
		add.w		d5, d3				; + Inkrement
		
		;*** jetzt kommt eine while-Schleife:
.loop:
		move.w		d3, d1
		ext			d1
		move.l		d1, d2
		add.l		d2, d2
		add.l		d1, d2
		lsl.l		#3, d2
		move.w		8(a0, d2), d1
		
		;*** ob_flags & flag?
		btst.b		d4, d1				; ist BIT 'd4' in d1 gesetzt?
		beq			.l1					; nein, dann weiter bei .l1
	
		move.w		d3, d0				; aktuelles Objekt ist Rckgabewert
		bra			fo_ende				; und schluss ...

.l1:
		;*** ob_flags & LASTOBJ?
		btst		d6, d1				; ist Bit 'd6' in d1 gesetzt?
		bne			fo_ende				; ja, also letztes Objekt => ende

		add.w		d5, d3				; counter erh”hen/erniedrigen
		
.while:
		tst.w		d3
		bpl.b		.loop				; positiv oder null: => .loop

fo_ende:

		movem		(sp)+, d3-d6 		; Register restaurieren
		rts		

;-------------------------------------------------------------------------------
; Funktionsname:	listbox
; 		->	a0:	Zeiger auf Listbox-Struktur
;			a1: Zeiger auf mk-info-Struktur
;			d0:	flags (LIST_CLICK, LIST_INIT, LIST_DRAW)
;		<-	nichts.
;
; Eine Listbox wird abgearbeitet (Init, Draw und Click).
;
listbox:
		movem.l		d3-d7/a3-a5, -(sp)	; Register retten
		movea.l		a0, a3				; Listbox-Adresse retten
		movea.l		a1, a5				; MKINFO-Adresse retten
		move.w		d0, d7				; Flags retten
		
		movea.l		TREE(a3), a4		; Tree-Adresse sichern

VERKETTET		.EQU	2

;           ############### flags & LIST_INIT ###############

		btst.l		#0, d7				; LIST_INIT?
		beq			.list_click			; sonst .list_click abarbeiten
		
		move.w		ITEMS(a3), d0		; Berechnen des Offsets des
		ext.l		d0					; Item-Objekts
		move.l		d0, d2				; Offset in d2 berechnen
		add.l		d2, d2				; \
		add.l		d0, d2				;  > d2 * 24 
		lsl.l		#3, d2				; /
		
		;*** Berechnen der sichtbaren Eintr„ge:
		move.w		OB_TAIL(a4, d2.l), d1	; ob_tail von Item-Objekt
		sub.w		OB_HEAD(a4, d2.l), d1	; - ob_head
		addq.l		#1, d1					; plus 1
		move.w		d1, VIS_ITEMS(a3)		; Anzahl der sichtbaren Eintr„ge
		
		;*** Maximale Position berechnen (in d6):
		move.w		NUM_ITEMS(a3), d6		; Anzahl der Elemente
		sub.w		d1, d6					; minus Anzahl der sichtbaren Eintr„ge
		
		;*** Breite der Liste bestimmen:
		move.w		OB_WIDTH(a4, d2.l), d0	; ob_width nach d0
		ext.l		d0						; auf Long erweitern
		move.l		d0, d1					; und zus„tzlich in d1 sichern
		addq.l		#1, d0					; ein Pixel wird unten abgezogen
		divu.w		mygl_wbox, d0			; durch Zeichenbreite teilen
		move.w		d0, WIDTH(a3)			; in Listbox sichern
		
		;*** Objekt-Breite notfalls korrigieren:
		divu.w		mygl_wbox, d1			; ob_width durch Zeichenbreite teilen
		swap		d1						; Rest betrachten
		tst.w		d1
		bne			.n1						; wenn nicht 0, dann weiter bei .n1
		
		sub.w		#1, OB_WIDTH(a4, d2.l)	; ob_width korrigieren

.n1:
		;*** ist list->first_item > max_pos?
		cmp.w		FIRST_ITEM(a3), d6		; Vergleich mit max_pos
		bpl			.n2						; nicht gr”žer, dann weiter bei .n2
		
		move.w		d6, FIRST_ITEM(a3)		; sonst auf max_pos setzen
		
.n2:
		;*** ist list->first_item < 0?
		tst.w		FIRST_ITEM(a3)			; Vergleich auf 0
		bpl			.n3						; wenn >= 0, dann weiter bei .n3
	
		clr.w		FIRST_ITEM(a3)			; sonst auf 0 setzen
			
.n3:

		;*** Adresse der Itemlist in Register schieben:
		movea.l		ITEMLIST(a3), a5		; Adresse nach a5

;			######+++++###### Schleife ######++++++######
		clr.w		d4						; Schleifenz„hler initialisieren
		
.loop1:
		;*** aktuelle Objektnummer berechnen:
		moveq.l		#1, d5
		add.w		d4, d5
		add.w		ITEMS(a3), d5
		ext.l		d5
		
		;*** Status des Objektes ist nicht selektiert:
		move.w		SEL_STATE(a3), d1		; Art der Selektion nach d1
		move.w		d5, d0					; Nummer des Objekts
		movea.l		a4, a0					; Tree-Adresse nach a0
		jsr			undo_state				; MYDIAL: Status setzen

		;*** Offset des aktuellen Objekts berechnen:
		move.l		d5, d2
		add.l		d2, d2
		add.l		d5, d2
		lsl.l		#3, d2
		
		;*** ob_width des Objekts notfalls korrigieren:
		move.w		OB_WIDTH(a4, d2.l), d0	; ob_width nach d0
		ext.l		d0						; auf Long erweitern
		divu.w		mygl_wbox, d0			; dividieren ...
		swap		d0						; Rest betrachten
		tst.w		d0
		bne			.n4						; wenn nicht 0, dann weiter bei .n4
		
		sub.w		#1, OB_WIDTH(a4, d2.l)	; ob_width korrigieren
.n4:
		move.w		OB_TYPE(a4, d2.l), d0	; ob_type nach d0

		;*** Adresse des Zielstrings holen:
		
		;###### switch:
		cmpi.w		#28, d0					; ist ob_type == G_STRING
		beq			.sw1
		
		cmpi.w		#26, d0					; ist ob_type == G_BUTTON
		beq			.sw1
		
		bra			.sw2					; sonst ist ob_type G_TEXT,
											; G_BOXTEXT, G_FTEXT oder G_FBOXTEXT
.sw1:
		movea.l		OB_SPEC(a4, d2.l), a0	; Adresse des Textes
		bra			.n5						; weiter bei .n5

.sw2:
		movea.l		OB_SPEC(a4, d2.l), a0	; Zeiger auf eine Tedinfo-Struktur
		movea.l		(a0), a0				; Adresse des Textes
		
.n5:
		;*** sichtbare Eintr„ge in die Listbox kopieren:
		move.w		d4, d0					; aktuelle Nummer
		add.w		FIRST_ITEM(a3), d0		; + erster sichtbarer Eintrag
		cmp.w		NUM_ITEMS(a3), d0		; gengend Eintr„ge vorhanden?
		bpl			.n6						; wenn nicht, dann mit '0' fllen

*** Fallunterscheidung:
***	1. Verkettete Liste der Daten
*** 2. Direkter Zeiger
*** 3. Indirekter Zeiger

		;*** Auf Verkettete Liste Testen:
		cmpi.w		#VERKETTET, INDIRECT(a3); Verkettete Liste?
		bne			.nicht_verkettetx		; wenn nicht, dann dort weiter

		;*** Adresse des Struktur holen:
		movea.l		a5, a1					; Adresse der Itemlist nach a1
		move.w		ITEMSIZE(a3), d0		; Gr”že der Liststruktur
		sub.w		#4, d0					; -4, da steht der Zeiger auf's n„chste Element
		move.w		d4, d1					; counter
		
.roundx:
		sub.w		#1, d0					; counter um 1 erniedrigen
		bmi			.copy1					; wenn kleiner Null, dann Schluž
		movea.l		(a1, d1.w), a1			; sonst n„chstes Element holen
		bra			.roundx					; und weiter

.nicht_verkettetx:		
		;*** Addresse des Items holen:
		move.w		FIRST_ITEM(a3), d1		; Offset berechnen
		add.w		d4, d1					;
		mulu.w		ITEMSIZE(a3), d1		;
		
		movea.l		a5, a1					; Adresse nach a1
		adda.l		d1, a1					; + Offset

		;*** list->indirect testen:
		tst.w		INDIRECT(a3)			; Test
		beq			.copy1					; wenn 0, dann nicht indirekt!

		movea.l		(a1), a1				; Zeiger auf Zeiger! ;-)
		
.copy1:
		;*** kopieren:
		move.w		WIDTH(a3), d0			; Breite der Box
		ext.l		d0
		jsr			strncpy					; String kopieren
		
		bra			.for1					; weiter mit .for
		
.n6:
		clr.b		(a0)					; mit '0' fllen
		
.for1:
		addq.l		#1, d4
		cmp.w		VIS_ITEMS(a3), d4		; Schleife oft genug durchlaufen?
		bmi			.loop1					; wenn nicht, dann nochmal
;		-------------------- Schleifenende --------------------

		;*** aktives Objekt sichtbar?
		movea.l		a3, a0					; Listbox-Adresse nach a0
		bsr			in_listbox				; testen, ob sichtbar
		
		tst.w		d0						; sichtbar?
		beq			.not_vis				; wenn nicht, dann weiter bei .not_vis

		;*** Status setzen:
		move.w		ACTIVE(a3), d0			; Element-Nummer
		movea.l		a3, a0					; Listbox-Adresse nach a0
		bsr			item2obj				; Element-Nr. in Objekt-Nr. umwandeln
		movea.l		a4, a0					; Tree-Adresse nach a0
		move.w		SEL_STATE(a3), d1		; Art der Selektion
		jsr			do_state				; MYDIAL: Selektieren
		
.not_vis:
		;*** Offset des Sliders berechnen:
		move.w		SLIDER(a3), d0
		ext.l		d0
		move.l		d0, d3
		add.l		d3, d3
		add.l		d0, d3
		lsl.l		#3, d3
		
		;*** Slidergr”že setzen:
		movea.l		a3, a0					
		bsr			calc_size				; Gr”že berechnen
		
		move.w		d0, OB_HEIGHT(a4, d3.l)	; Gr”že setzen
		
		;*** Sliderposition setzen:
		movea.l		a3, a0
		bsr			calc_pos				; Position berechnen
		
		move.w		d0, OB_Y(a4, d3.l)		; Position setzen

		;*** falls flags & LIST_DRAW, dann zeichnen:
		btst.l		#1, d7					; LIST_DRAW gesetzt?
		beq			.list_click				; wenn nicht, dann weiter bei .list_click
		
		clr.w		d1						; FALSE
		move.w		ROOT(a3), d0			; Root zeichnen
		movea.l		a3, a0					; Listbox-Adresse nach a0
		bsr			draw_listobj			; Listbox zeichnen		

;           ############### flags & LIST_CLICK ###############
.list_click:

		btst.l		#2, d7					; LIST_CLICK?
		beq			lb_ende					; sonst Ende der Funktion

		;*** Objekt suchen, auf das geclickt wurde:
		move.w		MOY(a5), -(sp)			; Maus-Y auf den Stack
		move.w		MOX(a5), d2				; Maus-X nach d2
		moveq.l		#8, d1					; Maximale Suchtiefe
		move.w		ROOT(a3), d0			; ab dem Root-Objekt suchen
		movea.l		a4, a0					; Dialog-Baum bergeben
		jsr			objc_find				; AES-Funktion ausfhren
		addq.l		#2, sp					; Stack restaurieren
		
		ext.l		d0
		move.l		d0, d3					; Objekt-Nummer nach d3

		;*** Test, ob ein List-Eintrag neu gezeichnet werden muž:
		tst.w		SEL_STATE(a3)			; ist die Art der Selektion != NORMAL
		beq			.tst_parent				; wenn gleich Null, dann weiter bei .tst_parent

		cmp.w		ITEMS(a3), d3			; ist ITEMS < obj
		ble			.tst_parent				; wenn nicht, dann weiter bei .tst_parent
		
		add.l		d0, d0					; Offset von obj im Baum berechnen
		add.l		d3, d0					;
		lsl.l		#3, d0					;
		
		move.w		OB_STATE(a4, d0.l), d0	; ob_state des Objekts nach d0
		andi.w		#8, d0					; DISABLED-Status testen
		bne			.tst_parent				; wenn != 0, dann weiter bei .tst_parent
		
		move.w		VIS_ITEMS(a3), d0		; vis_items nach d0
		cmp.w		NUM_ITEMS(a3), d0		; vis_items < num_items?
		bmi			.n7						; wenn ja, dann weiter bei .n7
		
		move.w		NUM_ITEMS(a3), d0		; sonst num_items nach d0
.n7:
		add.w		ITEMS(a3), d0			; + ITEMS
		cmp.w		d0, d3					; obj <= d0?
		bgt			.tst_parent				; wenn nicht, dann weiter bei .tst_parent

*######* Eintrag in der Listbox selektiert:		
		move.w		d3, d0					; obj nach d0
		movea.l		a3, a0					; Adresse der Listbox nach a0
		bsr			obj2item				; Objekt-Nr. in Eintrag-Nr. umwandeln

		move.w		ACTIVE(a3), d4			; aktiver Eintrag nach d4
		cmp.w		d4, d0					; ist aktiver Eintrag != dem gew„hlten Eintrag?
		beq			.tst_parent				; wenn nicht, dann weiter bei .tst_parent
		
		cmp.w		#-1, d4					; ist schon einmal selektiert worden?
		beq			.n8						; wenn nicht, dann weiter bei .n8

		movea.l		a3, a0					; Adresse der Listbox nach a0
		bsr			in_listbox				; aktiver Eintrag sichtbar?
		tst.w		d0						; sichtbar?
		beq			.n8						; wenn nicht, dann weiter bei .n8

		;*** Aktiven Eintrag deselektieren:
		move.w		d4, d0					; aktiver Eintrag nach d0
		movea.l		a3, a0					; Adresse der Listbox nach a0
		bsr			item2obj				; Eintrag-Nr. in Objekt-Nr. umwandeln
		movea.l		a3, a0					; Adresse der Listbox nach a0
		moveq.l		#1, d1					; TRUE
		bsr			draw_listobj			; List-Objekt neu zeichnen
		
.n8:
		;*** Neues Objekt als aktiven Eintrag selektieren:
		movea.l		a3, a0					; Adresse der Listbox nach a0
		move.l		d3, d0					; Objekt-Nr. nach d0
		bsr			obj2item				; Objekt-Nr. in Eintrag-Nr. umwandeln
		move.w		d0, ACTIVE(a3)			; Aktiven Eintrag sichern
		
		movea.l		a3, a0					; Adresse der Listbox nach a0
		moveq.l		#1, d1					; TRUE
		move.w		d3, d0					; obj zeichnen
		bsr			draw_listobj			; List-Objekt neu zeichnen

		;*** Test, ob Slider oder Pfeil der Listbox angeclickt wurde:
.tst_parent:
		cmp.w		PARENT(a3), d3			; PARENT-Objekt <= obj?
		bmi			lb_ende					; wenn nicht, dann Ende
		
		cmp.w		DOWN(a3), d3 			; obj <= DOWN-Objekt?
		bhi			lb_ende					; wenn nicht, dann Ende
		
*######* Slider bzw. Pfeil der Listbox wurde angeclickt:

		move.w		FIRST_ITEM(a3), d4		; new_pos = first_item setzen
		move.w		d4, d5					; old_pos ebenfallst
		move.w		NUM_ITEMS(a3), d6		; unteres WORD: max_pos
		sub.w		VIS_ITEMS(a3), d6		; max_pos = num_items - vis_items
		
		bpl			.n9						; ist max_pos >= 0
		
		clr.w		d6						; wenn nicht, dann Null setzen
.n9:
		;*** Objekt suchen:
		cmp.w		UP(a3), d3				; obj = UP-Pfeil?
		bne			.n10					; wenn nicht, dann .n10
		
		subq.l		#1, d4					; --new_pos
		bra			.calc_delta				; weiter bei .calc_delta
		
.n10:
		cmp.w		DOWN(a3), d3			; obj = DOWN-Pfeil?
		bne			.n11					; wenn nicht, dann .n11
		
		addq.l		#1, d4					; ++new_pos
		bra			.calc_delta				; weiter bei .calc_delta
		
.n11:
		cmp.w		PARENT(a3), d3			; obj = PARENT-Objekt?
		bne			.n12
		
		;*** Seite hoch oder runter?
		clr.w		d1						; FALSE
		lea			work, a1				; hier soll das RECT hin
		move.w		SLIDER(a3), d0			; Objektnummer des Sliders
		movea.l		a4, a0					; Dialogbaum
		jsr			objc_rect				; MYDIAL: RECT des Objekts holen

		move.w		MOY(a5), d0		
		cmp.w		work+2, d0				; oberhalb des Sliders geclickt?
		bpl			.unterhalb				; wenn nicht, dann .unterhalb
		
		sub.w		VIS_ITEMS(a3), d4		; new_pos -= vis_items (Seite hoch)
		bra			.calc_delta				; weiter bei .calc_delta

.unterhalb:
		add.w		VIS_ITEMS(a3), d4		; new_pos += vis_items (Seite runter)
		bra			.calc_delta				; weiter bei .calc_delta

.n12:
		cmp.w		SLIDER(a3), d3			; obj = SLIDER-Objekt?
		bne			.calc_delta				; weiter bei .calc_delta

		;*** Slider verschieben und neue Position berechnen:
		moveq.l		#1, d2					; Vertikal verschieben
		move.w		d3, d1					; Objektnummer des Sliders
		move.w		PARENT(a3), d0			; Slidebox
		movea.l		a4, a0					; Tree-Adresse
		jsr			graf_slidebox			; AES-Funktion ausfhren
		
		ext.l		d0						; d0 auf Long erweitern
		mulu.w		d6, d0					; mit max_pos multiplizieren
		
		divu.w		#1000, d0				; neue Position berechnen
		move.w		d0, d4					; und in new_pos sichern
		
		swap		d0						; Rest betrachten
		cmpi.w		#500, d0				; Rest > 500?
		bmi			.calc_delta				; wenn nicht, dann weiter bei .calc_delta
		
		addq.l		#1, d4					; sonst noch 1 zu new_pos addieren
		
.calc_delta:
		;*** erstmal neue Position betrachten:
		cmp.w		d4, d6					; new_pos > max_pos?
		bpl			.n13					; wenn nicht, dann weiter bei .n13
		
		move.w		d6, d4					; sonst new_pos = max_pos setzen
		bra			.n14					; weiter bei .n14
		
.n13:
		tst.w		d4						; new_pos < 0?
		bpl			.n14					; wenn nicht, dann weiter bei .n14

		clr.w		d4						; sonst new_pos = 0 setzen
				
.n14:
		;*** delta berechnen:
		move.w		d4, d7					; new_pos nach d7 kopieren
		sub.w		d5, d7					; delta = new_pos - old_pos
		
		;*** muž was verschoben werden?
		tst.w		d7						; delta != 0?
		beq			lb_ende					; wenn nicht, dann Ende

*######* Scrollen!

		move.w		ACTIVE(a3), d5			; aktiven Eintrag in d5 sichern
		
		;*** erstmal aktiven Eintrag deselektieren:
		tst.w		d5						; ist aktiver Eintrag != -1?
		bmi			.no_active1				; wenn nicht, dann weiter bei .no_active1

		movea.l		a3, a0					; Listbox-Adresse nach a0
		bsr			in_listbox				; aktiver Eintrag sichtbar?
		tst.w		d0						; sichtbar?
		beq			.no_active1				; wenn nicht, dann .no_active1
		
		move.w		d5, d0					; aktiver Eintrag nach d0
		movea.l		a3, a0					; Listbox-Adresse nach a0
		bsr			item2obj				; Eintrag-Nr. in Objekt-Nr. wandeln
		movea.l		a4, a0					; Tree-Adresse nach a0
		move.w		SEL_STATE(a3), d1		; Selektions-Art nach d1
		jsr			undo_state				; MYDIAL: Status zurcksetzen		

.no_active1:
		move.w		d4, FIRST_ITEM(a3)		; neues first_item ist new_pos

		;*** aktiven Eintrag selektieren:
		tst.w		d5						; ist aktiver Eintrag != -1?
		bmi			.no_active2				; wenn nicht, dann weiter bei .no_active2

		movea.l		a3, a0					; Listbox-Adresse nach a0
		bsr			in_listbox				; aktiver Eintrag sichtbar?
		tst.w		d0						; sichtbar?
		beq			.no_active2				; wenn nicht, dann .no_active2
		
		move.w		d5, d0					; aktiver Eintrag nach d0
		movea.l		a3, a0					; Listbox-Adresse nach a0
		bsr			item2obj				; Eintrag-Nr. in Objekt-Nr. wandeln
		movea.l		a4, a0					; Tree-Adresse nach a0
		move.w		SEL_STATE(a3), d1		; Selektions-Art nach d1
		jsr			do_state				; MYDIAL: Status setzen

.no_active2:

		;*** Adresse der Itemlist in Register schieben:
		movea.l		ITEMLIST(a3), a5		; Adresse nach a5

;			######+++++###### Schleife ######++++++######
		clr.w		d4						; Schleifenz„hler initialisieren
		
.loop2:
		;*** aktuelle Objektnummer berechnen:
		moveq.l		#1, d5
		add.w		d4, d5
		add.w		ITEMS(a3), d5
		ext.l		d5
		
		;*** Offset des aktuellen Objekts berechnen:
		move.l		d5, d2
		add.l		d2, d2
		add.l		d5, d2
		lsl.l		#3, d2
		
		move.w		OB_TYPE(a4, d2.l), d0	; ob_type nach d0

		;*** Adresse des Zielstrings holen:
		
		;###### switch:
		cmpi.w		#28, d0					; ist ob_type == G_STRING
		beq			.sw3
		
		cmpi.w		#26, d0					; ist ob_type == G_BUTTON
		beq			.sw3
		
		bra			.sw4					; sonst ist ob_type G_TEXT,
											; G_BOXTEXT, G_FTEXT oder G_FBOXTEXT
.sw3:
		movea.l		OB_SPEC(a4, d2.l), a0	; Adresse des Textes
		bra			.n15					; weiter bei .n15

.sw4:
		movea.l		OB_SPEC(a4, d2.l), a0	; Zeiger auf eine Tedinfo-Struktur
		movea.l		(a0), a0				; Adresse des Textes
		
.n15:
		;*** sichtbare Eintr„ge in die Listbox kopieren:
		move.w		d4, d0					; aktuelle Nummer
		add.w		FIRST_ITEM(a3), d0		; + erster sichtbarer Eintrag
		cmp.w		NUM_ITEMS(a3), d0		; gengend Eintr„ge vorhanden?
		bpl			.n16					; wenn nicht, dann mit '0' fllen

*** Fallunterscheidung:
***	1. Verkettete Liste der Daten
*** 2. Direkter Zeiger
*** 3. Indirekter Zeiger

		;*** Auf Verkettete Liste Testen:
		cmpi.w		#VERKETTET, INDIRECT(a3); Verkettete Liste?
		bne			.nicht_verkettety		; wenn nicht, dann dort weiter

		;*** Adresse des Struktur holen:
		movea.l		a5, a1					; Adresse der Itemlist nach a1
		move.w		ITEMSIZE(a3), d0		; Gr”že der Liststruktur
		sub.w		#4, d0					; -4, da steht der Zeiger auf's n„chste Element
		move.w		d4, d1					; counter
		
.roundy:
		sub.w		#1, d0					; counter um 1 erniedrigen
		bmi			.copy2					; wenn kleiner Null, dann Schluž
		movea.l		(a1, d1.w), a1			; sonst n„chstes Element holen
		bra			.roundy					; und weiter

.nicht_verkettety:
		
		;*** Addresse des Items holen:
		move.w		FIRST_ITEM(a3), d1		; Offset berechnen
		add.w		d4, d1					;
		mulu.w		ITEMSIZE(a3), d1		;
		
		movea.l		a5, a1					; Adresse nach a1
		adda.l		d1, a1					; + Offset

		;*** list->indirect testen:
		tst.w		INDIRECT(a3)			; Test
		beq			.copy2					; wenn 0, dann nicht indirekt!

		movea.l		(a1), a1				; Zeiger auf Zeiger! ;-)
		
.copy2:
		;*** kopieren:
		move.w		WIDTH(a3), d0			; Breite der Box
		ext.l		d0
		jsr			strncpy					; String kopieren
		
		bra			.for2					; weiter mit .for2
		
.n16:
		clr.b		(a0)					; mit '0' fllen
		
.for2:
		addq.l		#1, d4
		cmp.w		VIS_ITEMS(a3), d4		; Schleife oft genug durchlaufen?
		bmi			.loop2					; wenn nicht, dann nochmal
;		-------------------- Schleifenende --------------------

		;*** Sliderposition neu berechnen:
		move.w		SLIDER(a3), d5			; Objektnummer des Sliders holen
		ext.l		d5
		move.l		d5, d2					; Offset im Baum berechnen
		add.l		d5, d5					; \
		add.l		d2, d5					;  > Objektnummer * 24
		lsl.l		#3, d5					; /

		move.w		OB_Y(a4, d5.l), d4		; altes ob_y sichern
		
		movea.l		a3, a0					; Listbox-Adresse nach a0
		bsr			calc_pos				; Neue Sliderposition berechnen

		move.w		d0, OB_Y(a4, d5.l)		; neues ob_y sichern
		
		;*** wenn alte Position != neue Position, dann neu zeichnen:
		cmp.w		d4, d0					; Vergleich alt <=> neu
		beq			.n17					; wenn gleich, dann weiter bei .n17
		
		clr.w		d1						; FALSE
		move.w		PARENT(a3), d0			; ab Parent-Objekt neuzeichnen
		movea.l		a3, a0					; Listbox-Adresse nach a0
		bsr			draw_listobj			; neuzeichnen ...
		
.n17:
		;*** testen, ob sich Scrollen lohnt (delta = -1 bzw. delta = 1):
		cmpi.w		#1, d7					; delta = 1?
		beq			.do_scroll				; dann scrollen
		
		cmpi.w		#-1, d7					; oder delta = -1
		beq			.do_scroll				; dann auch scrollen

		;*** nur neuzeichnen:
		clr.w		d1						; FALSE
		move.w		ITEMS(a3), d0			; Items zeichnen
		movea.l		a3, a0					; Listbox-Adresse nach a0
		bsr			draw_listobj			; neuzeichnen ...
		
		bra			lb_ende					; und fertig ...
		
.do_scroll:
		;###### Scrollen:
		
		moveq.l		#1, d0					; H”he berechnen
		add.w		ITEMS(a3), d0			; 1 + Objektnummer items
		move.l		d0, d1					; Offset berechnen
		add.l		d0, d0					; \
		add.l		d1, d0					;  > * 24
		lsl.l		#3, d0					; /
		move.w		OB_HEIGHT(a4, d0.l), d3 ; ob_height in d3 sichern
		
		;*** RECT der ITEM-Box holen:
		clr.w		d1						; FALSE
		lea			work, a1				; hier soll das RECT hin
		move.w		ITEMS(a3), d0			; Objektnummer der ITEM-Box
		movea.l		a4, a0					; Tree-Adresse
		jsr			objc_rect				; MYDIAL: RECT einess Objekts holen
		
		;*** hoch- oder runterscrollen bercksichtigen:
		tst.w		d7						; delta betrachten
		bmi			.runter_scrollen		; spricht fr sich ...
		
		add.w		d3, work+2				; work.y + height
		sub.w		d3, work+6				; work.h - height
		
		move.w		ITEMS(a3), d4			; 
		add.w		VIS_ITEMS(a3), d4		;
		
		bra			.scroll_and_draw		; weiter bei .scroll_and_draw
		
.runter_scrollen:
		sub.w		d3, work+6				; work.h - height
		
		move.w		ITEMS(a3), d4			;
		addq.l		#1, d4					;
		
.scroll_and_draw:
		move.w		d7, d0					; delta nach d0
		muls.w		d3, d0					; delta * height
		lea			work, a0				; RECT-Adresse nach a0
		bsr			scroll_area				; und scrollen
		
		clr.w		d1						; FALSE
		move.w		d4, d0					; Objektnummer
		movea.l		a3, a0					; Listbox-Adresse nach a0
		bsr			draw_listobj			; und zeichnen
		
lb_ende:
		movem.l		(sp)+, d3-d7/a3-a5		; Register restaurieren
		rts

;-------------------------------------------------------------------------------
; Funktionsname:	draw_listobj
; 		->	a0:	Zeiger auf Listbox-Struktur
;			d0:	Nummer des Objekts
;			d1:	invertieren des Status, TRUE oder FALSE
;		<-	nichts
;
; Die Funktion zeichnet ein Element der Listbox neu.
;
draw_listobj:
		movem.l		d3-d5/a3-a4, -(sp)		; Register retten

		movea.l		a0, a3					; Parameter verteilen
		move.w		d0, d3					; "
		ext.l		d3
		move.w		d1, d4					; "

		movea.l		TREE(a3), a4			; Tree-Adresse nach a4

		;*** RECT des zu zeichnenden Objekts holen:
		moveq.l		#1, d1					; d1 mit TRUE fr Slider vorbesetzen
		cmp.w		SLIDER(a3), d3			; ist Objekt der Slider?
		beq			.is_slider				; wenn ja, dann weiter bei .is_slider
		clr.w		d1						; sonst d1 = FALSE
.is_slider:
		lea			work, a1				; Adresse fr RECT des Objekts
		move.w		d3, d0					; Objekt-Nummer
		movea.l		a4, a0					; Objekt-Baum
		jsr			objc_rect				; MYDIAL: Rect des Objekts holen

		tst.w		d4						; Status invertieren gesetzt?
		beq			.no_invert				; wenn nicht, dann weiter bei .no_invert

		;*** Objekt invertieren:
		movea.l		a4, a0					; Adresse des Objektbaums holen
		move.l		d3, d0					; Objekt-Nr. nach d0
		add.l		d0, d0					; Offset berechnen
		add.l		d3, d0					;
		lsl.l		#3, d0					;
		move.w		10(a0, d0.l), d0		; ob_state des Objekts
		eori.w		#1, d0					; Bit 0 setzen oder l”schen

		move.w		#1, -(sp)				; Objekt neu zeichnen
		move.w		d0, -(sp)				; neuer Status
		move.l		work+4, -(sp)			; wc, hc
		move.w		work+2, -(sp)			; yc
		move.w		work, d2				; xc
		clr.w		d1						; Reserviert, muž 0 sein
		move.w		d3, d0					; Objekt-Nr.
		jsr			objc_change				; AES-Funktion ausfhren
		lea			10(sp), sp				; Stack restaurieren
		
		bra			dlo_ende				; und schluž!
		

.no_invert:
		;*** erstmal den Offset des Objekts berechnen:
		move.l		d3, d5					; Objektnummer nach d5
		add.l		d5, d5					; \
		add.l		d3, d5					;  > * 24
		lsl.l		#3, d5					; /

		move.w		OB_TYPE(a4, d5.l), d0	; ob_type nach d0
		cmpi.w		#28, d0					; ob_type = G_STRING?
		beq			.draw1					; dann .draw1
	
		cmp.w		ITEMS(a3), d3			; oder obj = items?
		beq			.draw1					; dann auch draw1
		
		lea			desk, a0				; Adresse von desk holen
		move.l		4(a0), -(sp)			; work.h und work.w auf den Stack
		move.w		2(a0), -(sp)			; work.y auf den Stack
		move.w		(a0), d2				; work.x nach d2
		moveq.l		#8, d1					; maximale Tiefe
		move.w		d3, d0					; obj
		movea.l		a4, a0					; Tree-Adresse
		jsr			objc_draw				; AES-Funktion ausfhren
		addq.l		#6, sp					; Stack aufr„umen
				
		bra			dlo_ende				; Ende 
		
.draw1:
		lea			work, a0				; Adresse von work holen
		move.l		4(a0), -(sp)			; work.h und work.w auf den Stack
		move.w		2(a0), -(sp)			; work.y auf den Stack
		move.w		(a0), d2				; work.x nach d2
		moveq.l		#8, d1					; maximale Tiefe
		move.w		ITEMS(a3), d0			; item-Box zeichnen
		movea.l		a4, a0					; Tree-Adresse
		jsr			objc_draw				; AES-Funktion ausfhren
		addq.l		#6, sp					; Stack aufr„umen
				
dlo_ende:
		movem.l		(sp)+, d3-d5/a3-a4		; Register restaurieren
		rts		

;-------------------------------------------------------------------------------
; Funktionsname:	calc_pos
; 		->	a0:	Zeiger auf Listbox-Struktur
;		<-	d0: aktuelle Position des Listbox-Sliders
;
; Die Funktion berechnet die aktuelle Position des Sliders einer Listbox.
;
calc_pos:
		move.l		d3, -(sp)				; Register retten
		
		move.w		NUM_ITEMS(a0), d3		; num_items
		sub.w		VIS_ITEMS(a0), d3		; - vis_items
		
		bgt			.else					; Differenz > 0? --> .else
		
		clr.w		d0						; sonst aktuelle Position 0 setzen
		bra			cp_ende					; und Ende ...
		
.else:
		movea.l		TREE(a0), a1			; Adresse des Dialogbaums nach a1
		move.w		PARENT(a0), d1			; Nummer des parent-Objekts
		ext.l		d1						; Offset im Baum berechnen
		move.l		d1, d2					; "
		add.l		d2, d2					; "
		add.l		d1, d2					; "
		lsl.l		#3, d2					; "
		move.w		OB_HEIGHT(a1, d2.l), d0	; ob_height holen
		
		move.w		SLIDER(a0), d1			; Nummer des slider-Objekts
		ext.l		d1						; Offset im Baum berechnen
		move.l		d1, d2					; "
		add.l		d2, d2					; "
		add.l		d1, d2					; "
		lsl.l		#3, d2					; "
		sub.w		OB_HEIGHT(a1, d2.l), d0	; ob_height des Sliders von ob_height
											; des parent-Objekts abziehen
		
		mulu.w		FIRST_ITEM(a0), d0		; multiplizieren mit Nummer des 
											; ersten sichtbaren Objekts
		divu.w		d3, d0					; und das ganze durch die 
											; maximalen Positionen teilen

cp_ende:
		move.l		(sp)+, d3
		rts


;-------------------------------------------------------------------------------
; Funktionsname:	calc_size
; 		->	a0:	Zeiger auf Listbox-Struktur
;		<-	d0: Gr”že des Listbox-Sliders
;
; Die Funktion berechnet die aktuelle Gr”že des Sliders einer Listbox.
;
calc_size:
		movea.l		TREE(a0), a1			; Adresse des Dialogbaums nach a1
		move.w		PARENT(a0), d1			; Nummer des parent-Objekts
		ext.l		d1						; Offset im Baum berechnen
		move.l		d1, d2					; "
		add.l		d2, d2					; "
		add.l		d1, d2					; "
		lsl.l		#3, d2					; "
		move.w		22(a1, d2.l), d0		; ob_height nach d0

		move.w		NUM_ITEMS(a0), d1		; num_items > 0?
		beq			.no_item				; wenn nicht, dann weiter bei .no_item
		
		cmp.w		VIS_ITEMS(a0), d1		; vis_items <= num_items?
		bmi			.no_item				; wenn nicht, dann weiter bei .no_item

		mulu.w		VIS_ITEMS(a0), d0		; size * vis_items
		divu.w		d1, d0					; / num_items
		
.no_item:

		cmp.w		mygl_hbox, d0			; size kleiner als box fr ein Zeichen?
		bpl			cs_ende					; wenn nicht, dann Ende

		move.w		mygl_hbox, d0			; size = gl_hbox setzen

cs_ende:
		rts


;-------------------------------------------------------------------------------
; Funktionsname:	in_listbox
; 		->	a0:	Zeiger auf Listbox-Struktur
;		<-	d0: TRUE, wenn aktuelles Objekt in der Listbox zu sehen ist,
;				sonst FALSE
;
; Die Funktion gibt zurck, ob das aktive Objekt in der Listbox zu sehen ist.
;
in_listbox:
		clr.w		d0						; Rckgabe auf FALSE setzen

		;*** Aktiver Eintrag in Listbox?
		move.w		ACTIVE(a0), d1			; aktives Objekt der Listbox
		sub.w		FIRST_ITEM(a0), d1		; - Nummer der ersten sichtbaren
		
		bmi			in_lb_ende				; wenn kleiner Null dann nicht sichtbar
		
		;*** min zwischen vis_items und num_items bestimmen:
		move.w		VIS_ITEMS(a0), d2		; vis_items nach d2
		cmp.w		NUM_ITEMS(a0), d2		; vergleichen mit num_items
		
		bmi			.n1						; wenn vis_items < num_items, weiter bei .n1

		move.w		NUM_ITEMS(a0), d2		; sonst num_items nach d2
.n1:
		cmp.w		d1, d2					; sichtbar?
		blt			in_lb_ende				; wenn nicht, dann Ende
				
		moveq.l		#1, d0					; sonst TRUE.
		
in_lb_ende:
		rts

;-------------------------------------------------------------------------------
; Funktionsname:	item2obj
; 		->	a0:	Zeiger auf Listbox-Struktur
;			d0: Nummer des Eintrags
;		<-	d0: Objektnummer
;
; Wandelt eine Eintragnummer in eine Objektnummer um.
;
item2obj:
											; Nummer des Eintrags
		sub.w		FIRST_ITEM(a0), d0		; - Nummer des ersten sichtbaren
		add.w		ITEMS(a0), d0			; + Objektnummer der Box mit den Eintr„gen
		addq.w		#1, d0					; + 1
		
		rts

;-------------------------------------------------------------------------------
; Funktionsname:	obj2item
; 		->	a0:	Zeiger auf Listbox-Struktur
;			d0: Nummer des Objekts
;		<-	d0: Nummer des Eintrages
;
; Wandelt eine Objektnummer in eine Eintragnummer um.
;
obj2item:
											; Nummer des Objekts
		add.w		FIRST_ITEM(a0), d0		; + Nummer des ersten sichtbaren Eintrags
		sub.w		ITEMS(a0), d0			; - Objektnummer der Box mit den Eintr„gen
		subq.l		#1, d0					; - 1

		rts

*****************************************************************************

		.DATA
		.EVEN
		

*****************************************************************************

		.BSS
		.EVEN

*** šbergabeparameter fr obj_edit:
edit_obj:		ds.w	1
next_obj:		ds.w	1
idx:			ds.w	1

*** RECT eines Objekts:
work:			ds.w	4

*** Variablen fr das Event-Handling:
evnt_strct:		ds.w	16
ev_rc:			ds.w	1
ev_mox:			ds.w	1
ev_moy:			ds.w	1
ev_mbutton:		ds.w	1
ev_kstate:		ds.w	1
ev_kreturn:		ds.w	1
ev_breturn:		ds.w	1
evnt_buff:		ds.w	8

*** MKINFO-Struktur:
mk:
mox:		ds.w	1
moy:		ds.w	1
momask:		ds.w	1
mobutton:	ds.w	1
kstate:		ds.w	1
kreturn:	ds.w	1
breturn:	ds.w	1
ascii_code:	ds.w	1
scan_code:	ds.w	1
shift:		ds.w	1
contrl:		ds.w	1
alt:		ds.w	1

		.END

