home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Crawly Crypt Collection 1
/
crawlyvol1.bin
/
bbs
/
jet_conf
/
listbox.s
< prev
next >
Wrap
Text File
|
1993-04-12
|
52KB
|
1,629 lines
**************************************************************************
; 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 für 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 ; Rückgabe 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 für 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 ; Rückgabewert wieder setzen
unlk a2 ; Lokale Variablen entfernen
movem.l (sp)+, d3/d4/a3/a4 ; Register restaurieren
rts ; und zurück
;-------------------------------------------------------------------------------
; 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 zurück
;*** Mauszeiger in Hand verwandeln:
clr.l a0 ; keine eigene Mausform
moveq.l #4, d0 ; FLATHAND darstellen
jsr graf_mouse ; AES-Funktion ausführen
;*** 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 zurück:
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 ausführen
clr.w d0 ; 0 Start-Editobjekt
bra .loop ; weiter
*** Ende von dial_do:
.ld_ende:
move.w d2, d0 ; Exit-Button zurückgeben
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 ausführen
;*** Mauskontrolle übernehmen:
moveq.l #3, d0 ; BEG_MCTRL
jsr wind_update ; AES-Funktion ausführen
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 Tastendrücke: 2
move.l #$00010001, 4(a0) ; Maske: linke Maustaste, State: muß gedrückt sein
clr.l 8(a0) ; keine Rechtecke und Flags für 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 zurückschreiben
move.w idx, d5 ; aktuellen idx zurückschreiben
.l1:
*** Event-Multi aufrufen:
;*** jetzt kommt ein Event-Multi!
lea evnt_strct, a0 ; Adresse des evnt_strct-Feldes laden
jsr EvntMulti ; AES-Funktion ausführen
;*** Rückgabe 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
*** Überprüfen, 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 zurückschreiben
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 zurückschreiben
move.w idx, d5 ; aktuellen idx zurückschreiben
move.w d3, d4 ; next_obj = edit_obj setzen
bra .mous_ev ; weiter bei .mous_ev
.no_editinput:
;*** war die Eingabe vielleicht ein Shortcut für 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 ausgeführt 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 ausführen
addq.l #2, sp ; Stack restaurieren
;*** Rückgabe sichern:
move.w d0, d4 ; Rückgabe ist neues next_obj
;*** Ist überhaupt eins gefunden worden?
bpl .found ; wenn ja, dann weiter bei .found
;*** kein Objekt gefunden:
jsr mybeep ; Piepser ausführen
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 ausführen
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 ausführen
move.w d0, d7 ; return-Wert: 0 = EXIT Objekt;
;*** Bedingung für Ende des Dialoges erfüllt?
;+++ 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 zurückschreiben
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 zurückschreiben
move.w idx, d5 ; aktuellen idx zurückschreiben
.no_event:
*** Überprüfen, 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 zurückschreiben
move.w idx, d5 ; aktuellen idx zurückschreiben
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 ausführen
;*** Bildschirmaktionen wieder erlauben:
clr.w d0 ; END_UPDATE
jsr wind_update ; AES-Funktion ausführen
move.w d4, d0 ; next_obj ist Exit-Objekt
movem.l (sp)+, a3-a5/d3-d7 ; Register restaurieren
rts ; und zurück
;-------------------------------------------------------------------------------
*** Suchen eines Editobjekts:
find_obj:
movem d3-d6, -(sp) ; Register retten
moveq.l #3, d4 ; flag für EDITABLE (Bit 3: 8)
move.w #1, d5 ; Inkrement mit 1 vorbesetzen
moveq.l #5, d6 ; flag für LASTOB (Bit 5: 32)
;*** Was ist zu tun?
addq.w #1, d1 ; Rückwä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 Rückgabewert
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 ; genügend Einträge vorhanden?
bpl .n6 ; wenn nicht, dann mit '0' füllen
*** 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' füllen
.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 ausführen
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 ausführen
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 zurücksetzen
.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 ; genügend Einträge vorhanden?
bpl .n16 ; wenn nicht, dann mit '0' füllen
*** 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' füllen
.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 berücksichtigen:
tst.w d7 ; delta betrachten
bmi .runter_scrollen ; spricht für 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 für 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 für 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 ausführen
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 ausführen
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 ausführen
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 für 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 zurück, ob das aktive Objekt in der Listbox zu sehen ist.
;
in_listbox:
clr.w d0 ; Rückgabe 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 für obj_edit:
edit_obj: ds.w 1
next_obj: ds.w 1
idx: ds.w 1
*** RECT eines Objekts:
work: ds.w 4
*** Variablen für 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