Popup-Menüs mit Spalten (GFA)

Dieses Programm macht es möglich, bei Einbindung der drei Prozeduren ein Popup-Menü auf den Bildschirm zu zeichnen und es gleich, ohne weitere Arbeit, auswerten (bewachen) zu lassen, wobei die Nummer des ausgewählten Menüpunktes zurückgegeben wird. Die Texte, die in den einzelnen Zellen stehen sollen, werden in einem String durch einen Vertikalstrich (/) getrennt übergeben.

Wie beim Popup-Programm in der ST 6/88 wird, wenn am Anfang eines Zellen-Textes ein "-" steht, der Eintrag hell geschrieben und ist nicht anwählbar. Auch leere Zellen sind nicht anwählbar! Sie können jedoch nach Prozeduraufruf aus dem Feld Eintraege$() gelesen werden. Wobei Eintraege$(0) gleich dem Titel des Menüs ist.

Die Feldnummern stimmen mit dem Rückgabewert überein, so daß es möglich ist, die Beschriftung der gewählten Zelle aus Eintraege$(re%) auszulesen, wobei re% der Rückgabe wert (Nummer der gewählten Zelle) ist. Die Spalten werden vertikal beschriftet! Das heißt, daß die Zellen wie folgt angeordnet sind:

Zelle 1 | Zelle 4 | Zelle 7 
Zelle 2 | Zelle 5 | Zelle 8 
Zelle 3 | Zelle 6 | Zelle 9

Übergeben werden:

X-Position der Menübox 
Y-Position der Menübox

Bei beiden Positionen wird abgefragt, ob die Box aus dem Bildschirm ragt. Wenn ja, werden die Positionen entsprechend korrigiert!

Spaltenanzahl

Anzahl der Spalten, die das Menü haben soll! Bei Null wird die Prozedur nicht ausgeführi. weil sonst Fehler auftreten und eine Menübox mit null Spalten nicht gezeichnet werden kann!

Menü-String

Ist oben schon besprochen!

Wahlbalkenmodus

Modus des Wahlbalkcns:

1 = Schwarz/REPLACE 
2 = Hell/OR 
3 = Schwarz/XOR

(ausprobieren!)

Rückgabewert

Der Rückgabewert wird in die entsprechende Variable geschrieben (Pointer). Die Variable muß am Anfang ein haben! Die Wahl kann dann aus dieser Variablen abgefragt werden (kann Integer% sein!).

Zum Programm

Das Hauptprogramm (Do-Loop-Schleife) soll als Demonstration dienen. W ird die rechte Maustaste gedrückt, erscheint das Menü an der Mausposition. Wird im Menü Quit angewählt, wird das Programm beendet. Die Prozedur Popup ist die Hauptprozedur. Sie springt zur Prozedur Drawpop, die das Menü zeichnet und die Zellentexte aus dem Übergabestring holt und die Variablen Maxlenght, Eintraege und das Feld Eintraege$() benennt. Technisches steht im Programm in Form von Remarks! Die Prozedur Rahmen schaltet den Rahmen bei Pbox, Pcircle und Pellipse aus bzw. ein!

' **************************************************************************** '
' **                           POPUP mit Spalten !                          ** '
' **                      Programm 1988 Patrick Hoffmann                    ** '
' **            Erste Version 1.6.1988  Letzte Version: 4.6.1988            ** '
' **      Drei Proceduren die ein Popupmenü mit beliebig vielen Spalten     ** '
' **     auf den Bildschirm zeichnen und es bis zum Ergebnis überwachen!    ** '
' **                Geschrieben für die Zeitschrift ST-Computer             ** '
' **                                                                        ** '
' **                       (c) MAXON Computer GmbH 1988                     ** '
' **************************************************************************** '
@rahmen(1)              ! siehe Procedure
DEFFILL 1,2,4
PBOX -1,18,640,400      ! Hintergrund
DO
  IF MOUSEK=2           ! Rechte Maustaste?
    '
    ' Popupmenü-Parameter:
    '  X-Position
    '  Y-Position
    '  Spaltenanzahl (bei Null wird die Procedure beendet)
    '  MENÜ-String (Menüpunkte werden durch ein "|" getrennt,
    '    wobei der erste der Titel des Menüs ist !
    '  Wahlbalken-Modus: 1=Vollschwarz ; 2=Hell/OR ; 3=Schwarz/XOR
    '  Pointer für die Rückgabe der Nummer des Ausgewählten Punktes
    '    ( Mu₧ am Anfang ein '*' haben !!! )
    '
    @popup(MOUSEX,MOUSEY,3,"HAUPTMENÜ|Dieses|Popupmenü|macht|es|wirklich|möglich|ein|Popupmenü|
    mit|beliebig|vielen|Spalten|zu|Zeichen|und|zu|überwachen|-----------||QUIT!",3,*re%)
  ENDIF
  EXIT IF re%=20
LOOP
'
PROCEDURE popup(x,y,columns,pop$,mode,re)
  LOCAL menu,b,h,hidepoint$
  IF columns>0
    @drawpop(x,y,columns,pop$)           ! siehe Procedure
    b1=maxlenght*8+16                    ! Zellenbreite
    h1=INT(eintraege/columns+0.9999)     ! (Anzahl Zellen vertikal)
    b=(maxlenght*8+16)*columns           ! Boxbreite
    h=h1*16+48                           ! Boxhöhe
    x=MAX(MIN(639-b,x),0)                ! Achtung falls Box au₧er Screen kommt!
    y=MAX(MIN(399-h,y),0)                !  "   "    "    "    "      "     "
    IF mode=2                            ! Wahlbalken-Modus
      DEFFILL 1,2,2
    ELSE
      DEFFILL 1,1
    ENDIF
    GRAPHMODE mode                       !   "          "
    @rahmen(0)
    menu=-100                            ! Keine Zelle angewählt
    REPEAT
      MOUSE mx,my,mk                     ! Mausdaten
      IF mx>x AND mx<x+b AND my>y+43 AND my<y+h-4    ! In Popup-Box?
        nn=INT((my-y+36)/16)-4                       ! Zeile
        nmenu=nn+(INT((mx-x)/(b/columns))*h1)        ! Zellennummer
        IF LEFT$(eintraege$(nmenu))<>"-" AND eintraege$(nmenu)<>"" ! Zelle anwählbar?
          IF menu<>nmenu                             ! Neue Zelle angewählt?
            PUT x+2+n2*(b/columns),y+43+(n1-1)*16,hidepoint$   ! Old
          ENDIF
          n1=INT((my-y+36)/16)-4                     ! Zeile
          n2=INT((mx-x)/(b/columns))                 ! Spalte
          IF menu<>nmenu
            menu=nmenu                               ! Zelle registriert
            ' Hintergrund retten und Zelle Kennzeichnen
            GET x+2+n2*(b/columns),y+43+(n1-1)*16,x+b1-2+n2*(b/columns),y+59+(n1-1)*16,hidepoint$
            PBOX x+2+n2*(b/columns),y+43+(n1-1)*16,x+b1-2+n2*(b/columns),y+59+(n1-1)*16
          ENDIF
        ENDIF
      ELSE                ! Maus au₧erhalb Popupbox ?
        IF menu<>-100
          PUT x+2+n2*(b/columns),y+43+(n1-1)*16,hidepoint$   ! Demarkieren
          menu=-100                                          ! Deregistrieren
        ENDIF
      ENDIF
    UNTIL mk=1                           ! Ausgewählt?
    @rahmen(1)
    GRAPHMODE 1
    PUT x,y,hide$                   ! Box schlie₧en/Hintergrund zurücklegen
    *re=menu                             ! Rückgabe
    CLR eintraege,maxlenght              ! Benutzte Variablen löschen
  ENDIF
RETURN
'
PROCEDURE drawpop(x,y,columns,pop$)      ! Zeichnet Poupmenü
  LOCAL p,b,h,titel$
  IF DIM?(eintraege$())<>0               ! Schon Dimensioniert?
    ERASE eintraege$()                   ! Ja -> DIM löschen
  ENDIF
  DIM eintraege$(500)           ! Neu DIM ! (Schnelles Stringarrayfill mit "")
  FOR i=1 TO 500
    DO
      INC p
      EXIT IF MID$(pop$,p,1)="|" OR p>LEN(pop$)       ! Neue Zelle?
      eintraege$(eintraege)=eintraege$(eintraege)+MID$(pop$,p,1) !Zelle in Feld
    LOOP
    IF eintraege>0
      IF LEFT$(eintraege$(eintraege))="-"                      ! links "-" ?
        maxlenght=MAX(LEN(eintraege$(eintraege))-1,maxlenght)  ! Zellenbreite
      ELSE
        maxlenght=MAX(LEN(eintraege$(eintraege)),maxlenght)    ! Zellenbreite
      ENDIF
    ENDIF
    EXIT IF p>LEN(pop$)      ! Fertig?
    INC eintraege            ! Anzahl Zellen
  NEXT i
  titel$=LEFT$(pop$,INSTR(pop$,"|")-1)            ! Titel
  maxlenght=MAX(INT(LEN(titel$)/columns)-columns+2,maxlenght)
  b=(maxlenght*8+16)*columns                       ! Boxbreite
  h=INT(eintraege/columns+0.9999)*16+48            ! Boxhöhe
  x=MAX(MIN(639-b,x),0)                            ! siehe Procedure Popup
  y=MAX(MIN(399-h,y),0)                            !  " "   "     "   " "
  GET x,y,MIN(639,x+b),MIN(399,y+h),hide$          ! Boxhintergrund retten
  DEFFILL 1,0
  PBOX x,y,x+b,y+h                                 ! Box zeichen
  BOX x+1,y+1,x+b-1,y+h-1                          !  "      "
  LINE x,y+32,x+b,y+32                             !  "      "
  IF columns>1
    FOR i=1 TO columns-1                              ! Trennlinien...
      LINE x+(b/columns)*i,y+32,x+(b/columns)*i,y+h   ! zwischen den...
    NEXT i                                            ! ...Spalten
  ENDIF
  TEXT x+8,y+24,titel$            ! Titel
  k=0
  FOR j=1 TO columns
    FOR i=1 TO INT(eintraege/columns+0.99999)         ! Zellen beschriften
      INC k
      IF LEFT$(eintraege$(k))="-"                      ! links "-" ?
        DEFTEXT 1,2
        TEXT x+8+(b/columns)*(j-1),y+(i*16)+40,RIGHT$(eintraege$(k),LEN(eintraege$(k))-1)
        DEFTEXT 1,0
      ELSE
        TEXT x+8+(b/columns)*(j-1),y+(i*16)+40,eintraege$(k)
      ENDIF
    NEXT i
  NEXT j
RETURN
'
PROCEDURE rahmen(flag)            ! Schaltet Rahmen bei...
  DPOKE INTIN,flag                ! ...PBOX,PCIRCLE,PELLIPSE...
  VDISYS 104                      ! aus (0) bzw. ein (1)!
RETURN

Patrick Hoffmann
Aus: ST-Computer 05 / 1989, Seite 80

Links

Copyright-Bestimmungen: siehe Über diese Seite