'=========================================================================== ' Subject: MOUSE ROUTINES W/DOUBLE CLICK Date: 09-03-96 (23:10) ' Author: Egbert Zijlema Code: PB ' Origin: zylema@bnc.nl Packet: MOUSE.ABC '=========================================================================== ' MOUS.BAS - mouse routines, new version with double click ' (revision of MOUSDEMO.BAS) ' Author : Egbert Zijlema (E.Zijlema@uni4nn.iaf.nl) ' (up)Date : September 3, 1996 ' Language : Power Basic 3.2 ' Copyright status: Public Domain ' Again? ' Yes, again a mouse routine from this author for a couple of reasons. ' A few minor bug fixes, to begin with. ' The most important reason for this revision, however, is a new ' key/mouse trap: ScrollMouse. It now contains 2 different mouse ' performances: the classical one to support pull down menus and ' another one to doubleclick an item. ' In this revision I left a lot of things out, just to keep it as ' simple as possible. For instance: the menu does not support ' highlighted characters and contains only 2 working options. ' Furthermore: I left the Power Basic mouse library out and replaced ' it by plain BASIC INTERRUPT calls; only their names are identical. ' Registered PB-users may re-replace them by the faster assembly ' code that came with version 3.2 (subdirectory EXAMPLE\MOUSUNIT.BAS). ' In that case: DO NOT FORGET to implement the mouseflag tests in those ' procedures. They are not in the original set. I suggested Dave Navarro ' already to include them, in one way or another, within the following ' PB-release. ' ScrollMouse - method 1: ' When clicking in the menu bar the selected menu pops down. The normal ' way here is to hold the left button until you confirm your selection by ' releasing it. ' ScrollMouse - method 2: ' After you've selected "Select files" in the File menu you can ' select 1 of the filenames by doubleclicking it. The doubleclick must ' be performed within half a second, otherwise the result will be ' zero, in order to wait for a following doubleclick. ' You can always escape by pressing the Esc-key or the right mouse button. DEFINT A - Z %NO = 0 : %YES = NOT %NO ' true or false %ALTF = 33 * 256 : %ALTX = 45 * 256 %HOME = 71 * 256 : %UP = 72 * 256 %DOWN = 80 * 256 : %ENDKEY = 79 * 256 %ENTER = 13 : %ESCAPE = 27 %MOUSEDRIVER = &H33 : %AX = 1 : %BX = 2 : %CX = 3 : %DX = 4 TYPE MOUSEFLAGS mseon AS INTEGER ' cursor on mouse AS INTEGER ' mouse is there menu AS BYTE ' matrix rowcounter END TYPE DIM mflg AS SHARED MOUSEFLAGS DIM MainScreen AS SHARED STRING ' original screen DIM FileName(1 : 60) AS SHARED STRING ' array of 60 elements DIM matrix(1 : 50, 1 : 80) AS SHARED INTEGER ' 2 * 25 rows - 80 cols ' NOTE: a text screen has 25 rows, indeed! ' BUT : the matrices of the menu(s) and the mainscreen ' overlap. Therefore we reserve 'rows' 26 through 50 ' for the menu, which is a much better way than ' swapping them after every menu/main screen switch. SUB MousInit temp = MsThere(buts) COLOR 15, 0 LOCATE 25, 2 IF temp THEN PRINT "Your mouse has ";LTRIM$(RTRIM$(STR$(buts))); " buttons"; mflg.mouse = %YES ELSE PRINT "Mouse driver not available"; END IF END SUB FUNCTION MsThere(buts AS INTEGER) AS INTEGER REG %AX, 0 CALL INTERRUPT %MOUSEDRIVER buts = REG(%BX) FUNCTION = REG(%AX) END FUNCTION SUB MsCursorOn IF mflg.mouse = 0 THEN EXIT SUB ' no mouse, so quit IF mflg.mseon = 0 THEN ' only when mouse is off REG %AX, 1 CALL INTERRUPT %MOUSEDRIVER mflg.mseon = %YES ' mouse cursor on END IF END SUB SUB MsCursorOff IF mflg.mouse = 0 THEN EXIT SUB IF mflg.mseon THEN REG %AX, 2 CALL INTERRUPT %MOUSEDRIVER mflg.mseon = 0 ' mouse cursor off END IF END SUB SUB MsLocate(BYVAL row AS INTEGER, BYVAL col AS INTEGER) IF mflg.mouse = 0 THEN EXIT SUB IF (pbvScrnMode = 7) OR (pbvScrnMode = 0) THEN row = (row - 1) * 8 col = (col - 1) * 8 END IF REG %AX, 4 REG %CX, col REG %DX, row CALL INTERRUPT %MOUSEDRIVER END SUB SUB MsStatus(buttons AS INTEGER, row AS INTEGER, col AS INTEGER) IF mflg.mouse = 0 THEN EXIT SUB REG %AX, 3 CALL INTERRUPT %MOUSEDRIVER buttons = REG(%BX) row = REG(%DX) col = REG(%CX) IF (pbvScrnMode = 7) OR (pbvScrnMode = 0) THEN row = (row \ 8) + 1 col = (col \ 8) + 1 END IF END SUB SUB MsSetWindow(BYVAL row AS INTEGER, BYVAL col AS INTEGER, _ BYVAL rows AS INTEGER, BYVAL cols AS INTEGER) IF mflg.mouse = 0 THEN EXIT SUB rows = row + rows - 1 ' adjust rows to real coordinates cols = col + cols - 1 ' adjust cols to real coordinates IF (pbvScrnMode = 7) OR (pbvScrnMode = 0) THEN row = row * 8 - 1 : rows = rows * 8 - 1 ' adjust for PB col = col * 8 - 1 : cols = cols * 8 - 1 ' adjust for PB END IF REG %AX, 7 REG %CX, col REG %DX, cols CALL INTERRUPT %MOUSEDRIVER REG %AX, 8 REG %CX, row REG %DX, rows CALL INTERRUPT %MOUSEDRIVER END SUB SUB box(row, col, rows, cols, fore, back) ' draw single rectangle toprow$ = CHR$(218) + STRING$(cols - 2, 196) + CHR$(191) ' ÚÄÄ¿ botrow$ = CHR$(192) + STRING$(cols - 2, 196) + CHR$(217) ' ÀÄÄÙ vert$ = CHR$(179) ' ³ COLOR fore, back LOCATE row, col: PRINT toprow$; FOR count = row + 1 TO row + rows - 2 LOCATE count, col PRINT vert$; SPACE$(cols - 2); vert$; NEXT LOCATE count, col: PRINT botrow$ END SUB SUB MenuMatrices ' reserve rows 3 throug 12 (28-37 in the matrix) for pop down menus ' this is enough if your menus contain no more than 10 options mflg.menu = 25 FOR row = 3 TO 12 FOR cell = 1 TO 80 matrix(row + mflg.menu, cell) = row - 2 + 256 ' no ascii! NEXT NEXT mflg.menu = 0 END SUB SUB DrawMenuBar mflg.menu = 25 COLOR 0, 7 LOCATE 1, 1 : PRINT SPACE$(80); LOCATE 1, 5 : PRINT "ile" COLOR 15, 7 LOCATE 1, 4 : PRINT "F" FOR cell = 4 TO 7 matrix(1, cell) = %ALTF matrix(1 + mflg.menu, cell) = %ALTF NEXT mflg.menu = 0 END SUB SUB FileMenu(choice) STATIC last REDIM MenuItem (1: 4) AS LOCAL STRING mflg.menu = 25 exclude = %ALTF options = 4 column = 3 MenuItem(1) = " Select files " MenuItem(2) = " Not supported " MenuItem(3) = " Bla bla " MenuItem(4) = " Exit " MsCursorOff box 2, column - 1, options + 2, LEN(MenuItem(1)) + 2, 15, 7 FOR row = 3 TO 6 LOCATE row, 3 : PRINT MenuItem(row - 2) NEXT ScrollMenu last, MenuItem(), column, options, exclude, result last = result SELECT CASE result CASE 1 mflg.menu = 0 SelectFiles CASE 4 : choice = %ALTX END SELECT END SUB FUNCTION ScrollMouse AS INTEGER MsStatus oldButn, oldRow, oldCol IF oldButn = 1 THEN ' test status to avoid ' repeat (causes flicker) oldKey = matrix(oldRow + mflg.menu, oldCol) END IF DO MsStatus buttons, row, col IF INSTAT THEN FUNCTION = CVI( INKEY$ + CHR$(0) ) EXIT FUNCTION ELSEIF buttons = 1 AND matrix(row + mflg.menu, col) <> oldKey THEN FUNCTION = matrix(row + mflg.menu, col) EXIT FUNCTION ELSEIF buttons = 2 THEN ' right button = escape ReleaseButtons FUNCTION = %ESCAPE EXIT FUNCTION END IF LOOP UNTIL (oldButn = 1) AND (buttons = 0) ' until release IF mflg.menu = 0 THEN ' perform doubleclick start# = TIMER DO MsStatus buttons, dummy, dummy now# = TIMER IF now# - start# > .5 THEN FUNCTION = 0 EXIT FUNCTION END IF LOOP UNTIL buttons = 1 ReleaseButtons END IF FUNCTION = %ENTER END FUNCTION SUB ReleaseButtons DO MsStatus buttons, dummy, dummy LOOP UNTIL buttons = 0 END SUB SUB ReadAndDisplayFiles temp$ = DIR$("\DOS\*.*") DO WHILE LEN(temp$) INCR count hwmany = count FileName(count) = LEFT$(temp$ + SPACE$(12), 12) IF count = UBOUND(FileName) THEN ' if there are more than 60 EXIT DO ELSE temp$ = DIR$ END IF LOOP ARRAY SORT FileName() COLOR 15, 0 FOR count = 1 TO 20 IF count > hwmany THEN EXIT SUB LOCATE count + 2, 2 : PRINT FileName(count); FOR cell = 2 TO 13 ' len(filename) = 12 matrix (count + 2, cell) = count + 256 ' no ascii NEXT NEXT END SUB SUB SelectFiles column = 2 options = 20 ScrollMenu 0, FileName(), column, options, %ALTF, result MsCursorOff IF result = 0 THEN EXIT SUB COLOR 7, 0 LOCATE 25, 1 PRINT "You selected: ";FileName(result); DO LOOP UNTIL LEN(INKEY$) RestoreMain END SUB SUB RestoreMain DEF SEG = &HB800 POKE$ 160, MainScreen DEF SEG END SUB SUB ScrollMenu(last, item$(), column, options, exclude, result) IF mflg.menu THEN result = last - 1 IF result <= 0 THEN result = 0 MsLocate 3, 5 ELSE MsLocate result + 2, 5 END IF MsRow = 1 : plus = 2 ELSE MsLocate 3, 5 MsRow = 3 : plus = 0 END IF DEF SEG = &HB800 ' assume color card MenuScreen$ = PEEK$(160, 3840) DEF SEG MsSetWindow MsRow, column - 1, options + plus, LEN(item$(1)) init = %YES DO MsCursorOn IF init AND mflg.menu THEN init = %NO KeyIn = %DOWN ELSE KeyIn = ScrollMouse END IF SELECT CASE KeyIn CASE %UP DECR result IF result < 1 THEN result = options CASE %DOWN INCR result IF result > options THEN result = 1 CASE %HOME result = 1 CASE %ENDKEY result = options CASE %ESCAPE result = 0 EXIT DO CASE exclude result = 0 CASE 257 TO 276 ' mouse only! result = KeyIn - 256 END SELECT IF result THEN MsCursorOff DEF SEG = &HB800 POKE$ 160, MenuScreen$ DEF SEG IF mflg.menu THEN COLOR 7,0 ELSE COLOR 0, 7 LOCATE result + 2, column PRINT item$(result) END IF LOOP UNTIL KeyIn = %ENTER AND result ' safety first MsCursorOff RestoreMain END SUB SUB MainMenu DO IF choice THEN KeyIn = choice choice = 0 ELSE KeyIn = ScrollMouse END IF ' modified = %NO SELECT CASE KeyIn CASE %ALTX MsCursorOff COLOR 7, 0 CLS SYSTEM CASE %ALTF FileMenu choice END SELECT MsCursorOn MsSetWindow 1, 1, 25, 80 LOOP END SUB CLS MenuMatrices DrawMenuBar ReadAndDisplayFiles DEF SEG = &HB800 MainScreen = PEEK$(160, 3840) DEF SEG MousInit MsLocate 1, 1 MsCursorOn MainMenu END