| Index | Manual | Download | Source | Macros | Embedded word Case ins.
Sitemap | Links | Forum | Tests | Projects

# dirsling.htm
Data
Data
Procedures
AddUnderscores
DirWindowPaint
EditField
MainGui
MainWindowPaint
OneLine2Dir

This is a GUI module of EuroTool program EuroDirs for Linux.

         EUROASM CPU=X64,Unicode=No,DumpWidth=36
    dirsling PROGRAM Format=COFF,Width=64
         %DROPMACRO *
         INCLUDEHEAD1 argument.htm, dirslinc.htm
         INCLUDE1 linabi.htm, cpuext64.htm, cpuext.htm, linsfile.htm, lins.htm, \
                  string64.htm, memory64.htm, time.htm, status32.htm

↑ Data

    EDIT              STRUC    ; A structure for passing parameters for the procedure EditField.
    .Address           D QWORD ; Address of the field in memory. The field is in UTF-8, NUL-terminated.
    .MaxSize           D WORD  ; Maximal possible size of the field in memory (bytes).
    .ScreenSize        D WORD  ; Size of the visible field on the screen.
    .ScreenRow         D WORD  ; Row of the edit field in the terminal window (1, 2, 3,,).
    .ScreenCol         D WORD  ; Left column of the edit field in the terminal window (1, 2, 3,,).
                      ENDSTRUC EDIT
    MinWidth          EQU 150  ; Minimal number of columns of the window.
    MinHeight         EQU  20  ; Minimal number of rows of the main window.
    [.rodata]         ; Constants.
    BoxV              DB BYTE '│',0          ; BOX DRAWINGS LIGHT VERTICAL       2502
    BoxDR             DB BYTE '┌',0          ; BOX DRAWINGS LIGHT DOWN AND RIGHT 250C
    BoxDL             DB BYTE '┐',0          ; BOX DRAWINGS LIGHT DOWN AND LEFT  2510
    BoxUR             DB BYTE '└',0          ; BOX DRAWINGS LIGHT UP AND RIGHT   2514
    BoxUL             DB BYTE '┘',0          ; BOX DRAWINGS LIGHT UP AND LEFT    2518
    Box2V             DB BYTE '║',0          ; BOX DRAWINGS DOUBLE VERTICAL      2551
    Box2DR            DB BYTE '╔',0          ; BOX DRAWINGS DOUBLE DOWN AND LEFT 2554
    Box2DL            DB BYTE '╗',0          ; BOX DRAWINGS LIGHT DOWN AND LEFT  2557
    Box2UR            DB BYTE '╚',0          ; BOX DRAWINGS DOUBLE UP AND RIGHT  255A
    Box2UL            DB BYTE '╝',0          ; BOX DRAWINGS DOUBLE UP AND LEFT   2518
    Boxes             DB NAME_MAX*2*BYTE '─' ; BOX DRAWINGS LIGHT HORIZONTAL     2500
    Boxes2            DB NAME_MAX * BYTE '═' ; BOX DRAWINGS DOUBLE HORIZONTAL    2550
    Space5            DB 5 * BYTE ' ',0
    Spaces            DB NAME_MAX * 2 * BYTE ' '
    BtnHead1          DB "Inserted ",0
    BtnHead2          DB "Increased ",0
    BtnHead3          DB "Unchanged ",0
    BtnHead4          DB "Decreased ",0
    BtnHead5          DB "Deleted ",0
    BtnTail1          DB " new directories",0
    BtnTail3          DB " directories",0
    BtnTail5          DB " old directories",0
    ; Not zero-terminated sequences for detection of keyboard.
    EscUp             DB 27,'[A'
    EscDown           DB 27,'[B'
    EscRight          DB 27,'[C'
    EscLeft           DB 27,'[D'
    EscHome           DB 27,'[H'
    EscEnd            DB 27,'[F'
    EscShiftTab       DB 27,'[Z'
    EscPgUp           DB 27,'[5~'
    EscPgDn           DB 27,'[6~'
    EscDelete         DB 27,'[3~'
    EscCtrlHome       DB 27,'[1;5H'
    EscCtrlEnd        DB 27,'[1;5F'
    ; Zero-terminated sequences for writing to terminal.
    EscDirsColor::    DB 27,'[30;47m',0
    EscDefColor::     DB 27,'[39;49m',0
    EscEnhColor::     DB 27,'[38;5;160m',0
    EscDimColor       DB 27,'[38;5;243m',0
    EscFileColor      DB 27,'[48;5;195m',0
    EscFindColor      DB 27,'[30;103m',0
    EscEditColor      DB 27,'[30;107m',0
    EscErase::        DB 27,'[2J',0
    EscEscape         DB 27,0
    EscEnableMouse    DB 27,'[?1000;1006;1015h',0
    EscDisableMouse:: DB 27,'[?1000;1006;1015l',0
    EscHideCursor     DB 27,'[?25l',0
    EscShowCursor::   DB 27,'[?25h',0
    EscTab            DB 9
    [.data]           ; Variable data.
    EscResize         DB 27,'[8;'
    ValResize         DB 'xxxxxxxxx'  ; Replaced by '24;150t',0
    EscRightDiv2      DB 27,'['
    ValRightDiv2      DB 'xxxxx'      ; Replaced by '123C',0
    EscRightEdge      DB 27,'['
    ValRightEdge      DB 'xxxxx'      ; Replaced by '123C',0
    EscDivN           DB 27,'['
    ValDivN           DB 'xxxxx'      ; Replaced by '123C',0
    EscLineXX         DB 27,'['
    ValLineXX         DB 'XXH',0
    EscGoto           DB 27,'['
    EscGotoRowColH    DB 'row;colH',0
      line %FOR 1..14 ; Define EscLine1, EscLine2 etc.
    EscLine%line      DB 27,'[%line{}H',0
           %ENDFOR line
    [.bss]            ; Working data.
    Edit              DS EDIT
    TtySize           DS TTYSIZE
    TermIO::          DS TERMIO
    MainWidth         DD DWORD
    MainHeight        DD DWORD ; Number of rows in the main window (20..99).
    DirHeight         DD DWORD ; Number of rows in the directory window, without borders (5..84).
    MainWidthDiv2     DD DWORD
    MainWidthDiv5     DD DWORD
    Remainder2        DD DWORD
    Remainder5        DD DWORD
    LineNr            DD DWORD ; Ordinal number of row in DirWindow (0,1,2,...)
    LineCnt           DD DWORD ; Row counter in DirWindow (DirHeight, DirHeight-1,,,0).
    FindTextSize      DD DWORD
    TabSelected       DD DWORD ; 0,5,10,15,20,25,30,35,40 selects editable field or button from TabSelTable with Tab od Shift-Tab.
    SelectedLineNr    DD DWORD ; Ordinal number of the row which is in the topmost row of DirWindow.
    KeyBuffer         DB 32 * BYTE
    PreviousScanDir   DB 264 * BYTE
    FindText          DB NAME_MAX * BYTE
    [.text]

MainGui
  This is the graphic entry procedure which calls MainWindowPaint to paint the window and then it reads mouse and keyboard from the terminal.
Called by
  MainCon.
Calls
  MainWindowPaint.

    MainGui:: PROC
        CALL MainWindowPaint
        CALL DirWindowPaint
        LEA RBX,[TermIO]
        LinABI ioctl,0,TCGETS,RBX          ; Load current local terminal status.
        RstSt [RBX+TERMIO.c_lflag],ICANON+ECHO
        LinABI ioctl,0,TCSETS,RBX          ; Disable terminal echo.
        StdOutput EscEnableMouse
    .10:XOR EDI,EDI                        ; Read the keyboard in the main window.
        LEA RSI,[KeyBuffer]
        MOV R8,RSI
        MOV [RSI],RDI
        MOV EDX,SIZE# KeyBuffer
        LinABI read,RDI,RSI,RDX
        TEST EAX
        JNA .10:
        XOR ECX,ECX
        MOV EBX,[SelectedLineNr::]
    key %FOR EscUp,EscDown,EscCtrlHome,EscCtrlEnd,EscHome,EscEnd,EscPgUp,EscPgDn,EscShiftTab,EscTab,EscEscape
           LEA RDI,[%key]        ; Check if a cursor key was read and dispatch it to .%key.
           MOV CL,SIZE# %key
           MOV RSI,R8
           REPE CMPSB
           JE .%key:
        %ENDFOR key
        MOV RSI,R8               ; Read the mouse. Expected 1B 5B 3C 3b 3B 3r 3r 3B 3c 3c 4D 00
        LODSW                    ;                                 Esc [ lt btn ;   col  ;   row  M
        CMP AX,0x5B1B            ; Esc [
        JNE .10:
        LODSB
        CMP AL,0x3C              ; Less-than?
        JNE .10:
        LodD RSI                 ; Mouse button left=0 right=2 wheelUp=64 wheelDown=65
        JC  .10:
        SUB EBX,3                ; SelectedLineNr for the case wheelUp.
        CMP AL,64                ; Scroll wheel up?
        JE .50:
        ADD EBX,3+3              ; SelectedLineNr for the case wheelDown.
        CMP AL,65                ; Scroll wheel down?
        JE .70:
        XOR EBX,EBX              ; Not scrolled.
        CMP AL,0                 ; Left button?
        JNE .10:
        LODSB                    ; Read the column where it was clicked.
        CMP AL,';'
        JNE .10:
        LodD                     ; Column.
        JC .10:
        MOV EBX,EAX              ; X-coordinate of mouse cursor.
        SHL EBX,16
        LODSB                    ; Read the row where it was clicked.
        CMP AL,';'
        JNE .10:
        LodD                     ; Row.
        JC .10:
        MOV BX,AX                ; Y-coordinate of mouse cursor.
        LODSB
        OR AL,'M'^'m'
        CMP AL,'m'
        JNE .10:
        ; Mouse cursor coordinates at left button click are in EBX. Row number is in BX.
        CMP BX,8
        JB .40:
        CMP BX,10
        JA  .40:
        MOV EAX,1                ; At line 8..10 - one of the five buttons clicked.
        SHR EBX,16               ; Get X-coordinate to EBX.
    .20:SUB EBX,[MainWidthDiv5]
        JB .30:
        INC EAX
        JMP .20:
    Row9Btn1:MOV AL,1
        JMP .30:
    Row9Btn2:MOV AL,2
        JMP .30:
    Row9Btn3:MOV AL,3
        JMP .30:
    Row9Btn4:MOV AL,4
        JMP .30:
    Row9Btn5:MOV AL,5
    .30:CMP EAX,5
        JA .10:
        MOVB [ArgViewDirs::],AL  ; Change the view.
        CALL MainWindowPaint
        JMP .10:
    .40:CMP BX,11
        JB .42:
        CMP BX,13
        JA .42:
    Row12:
        LEA RSI,[Edit]           ; At Row 11..13 - "FindText" clicked.
        LEA RAX,[FindText]
        MOV ECX,SIZE# FindText
        MOV [RSI+EDIT.Address],RAX
        MOV [RSI+EDIT.MaxSize],CX
        MOV [RSI+EDIT.ScreenRow],12
        MOV [RSI+EDIT.ScreenCol],18
        MOV EAX,[MainWidth]
        SUB EAX,18
        MOV [RSI+EDIT.ScreenSize],AX
        Clear KeyBuffer
        CALL EditField
        CALL MainWindowPaint
        CALL DirWindowPaint
        JMP .10:
    .42:CMP BX,1
        JB .44:
        CMP BX,3
        JA .44:
        SHR EBX,16               ; At Row 1..3 - ScanDir selection. Get X-coordinate to BX.
        CMP BX,55
        JB .44:                  ; If outside the field.
    Row2:
        LEA RSI,[Edit]
        LEA RAX,[ArgScanDir::]
        MOV ECX,NAME_MAX
        MOV [RSI+EDIT.Address],RAX
        MOV [RSI+EDIT.MaxSize],CX
        MOV [RSI+EDIT.ScreenRow],2
        MOV [RSI+EDIT.ScreenCol],56
        MOV ECX,[MainWidth]
        SUB ECX,56
        MOV [RSI+EDIT.ScreenSize],CX
        MOV RSI,RAX              ; ArgScanDir::.
        GetLength$ RAX
        LEA RDI,[PreviousScanDir]
        REP MOVSB                ; Store the last scan directory name.
        CALL EditField
        LEA RSI,[PreviousScanDir]
        GetLength$ RSI
        LEA RDI,[ArgScanDir::]
        REPE CMPSB
        JE .43:
        XOR EAX,EAX              ; ArgScanDir has been changed, invalidate I/O files.
        MOV [ArgInputFile::],EAX
        MOV [ArgOutputFile::],EAX
    .43:CALL LoadAndCompareScans::
        CALL MainWindowPaint
        CALL DirWindowPaint
        JMP .10:
    Row6ColL:
        MOV EAX,[MainWidth]      ; At Row 6 - selection of scan files.
        SHR EAX,1
        STC
        JMP .45:
    Row6ColR:
        MOV EAX,[MainWidth]      ; At Row 6 - selection of scan files.
        SHR EAX,1
        XOR EBX,EBX
        JMP .45:
    .44:CMP BX,5
        JB .49:
        CMP BX,7
        JA .49:
        MOV EAX,[MainWidth]      ; At Row 5..7 - selection of scan files.
        SHR EAX,1
        SHR EBX,16               ; Column to EBX.
        CMP EBX,EAX              ; Differenciate (to flags) between older and newer scan.
    .45:LEA RBX,[Edit]
        MOV [RBX+EDIT.ScreenRow],6
        MOV [RBX+EDIT.ScreenSize],AX
        MOV [RBX+EDIT.MaxSize],NAME_MAX
        LEA RDX,[ArgInputFile::]
        MOV ECX,2
        JB .47:
        LEA RDX,[ArgOutputFile::]
        LEA ECX,[EAX+2]
    .47:MOV [RBX+EDIT.Address],RDX
        MOV [RBX+EDIT.ScreenCol],CX
        SUB EAX,2
        MOV [RBX+EDIT.ScreenSize],AX
        CALL EditField
        CALL LoadAndCompareScans::
    .49:CALL MainWindowPaint
        CALL DirWindowPaint
        JMP .10:
    .EscUp:
        DEC EBX
    .50:TEST EBX
        JNS .60:
        SUB EBX,EBX
    .60:MOV [SelectedLineNr::],EBX
        CALL DirWindowPaint
        JMP .10:
    .EscDown:
        INC EBX
    .70:MOV EAX,[MaxLineNr::]
        CMP EBX,EAX
        JB .60:
        MOV EBX,EAX
        JMP .60:
    .EscPgUp:
        SUB EBX,[DirHeight]
        INC EBX
        JMP .50:
    .EscPgDn:
        ADD EBX,[DirHeight]
        DEC EBX
        JMP .70:
    .EscCtrlHome:
    .EscHome:
        MOV EBX,0
        JMP .60:
    .EscCtrlEnd:
    .EscEnd:
        MOV EBX,[MaxLineNr::]
      ;  SUB EBX,[DirHeight]
      ;  INC EBX,EBX
        JMP .60:
    TabSelTable:       ; Each jump is encoded to 5 bytes long instruction.
      JMP Row2
      JMP Row6ColL
      JMP Row6ColR
      JMP Row9Btn1
      JMP Row9Btn2
      JMP Row9Btn3
      JMP Row9Btn4
      JMP Row9Btn5
      JMP Row12
    .EscShiftTab:
        MOV EAX,[TabSelected]
        SUB EAX,5
        JNB .80:
        MOV EAX,8*5
        JMP .80:
    .EscTab: ; Tab pressed.
        MOV EAX,[TabSelected]
        ADD EAX,5
        CMP AL,8*5
        JNA .80:
        SUB EAX,EAX
    .80:MOV [TabSelected],EAX              ; RAX=0,5,10,15,20,25,30,35,40.
        LEA RCX,[TabSelTable+RAX]
        JMP RCX
    .EscEscape:
        StdOutput EscDisableMouse,EscErase
        LEA RBX,[TermIO]
        LinABI ioctl,0,TCGETS,RBX          ; Get current terminal echo.
        SetSt [RBX+TERMIO.c_lflag],ICANON+ECHO
        LinABI ioctl,0,TCSETS,RBX          ; Restore terminal echo.
        TerminateProgram 0
       ENDP MainGui

MainWindowPaint
  Procedure MainWindowPaint paints the main window.
  It is invoked when the folder with scan files or the date od scan file changes, when a button for ViewDirs is clicked, and when the terminal is resized.
  MainWindowPaint uses pseudographic frames for painting. The low part (directory window) is cleared with spaces. DirWindowPaint should be called to paint the lower part.
Called by
  MainGui.

    MainWindowPaint PROC
        LinABI ioctl,0,TIOCGWINSZ,TtySize ; Check if the terminal is big enough.
        MOVZXW EDX,[TtySize.ts_lines]
        MOVZXW ECX,[TtySize.ts_cols]
        MOV EAX,MinHeight        ; Minimal acceptable rows (20..99).
        CMP EDX,EAX
        JB .10:
        MOV EAX,EDX
    .10:LEA RDI,[ValResize]
        StoD RDI
        MOV AL,';'
        STOSB
        MOV EAX,MinWidth         ; Minimal acceptable columns.
        CMP ECX,EAX
        JB .13:
        MOV EAX,ECX
    .13:StoD RDI
        MOV AX,'t'
        STOSW
        StdOutput EscResize
        LinABI ioctl,0,TIOCGWINSZ,TtySize
        MOVZXW EDX,[TtySize.ts_lines]
        DEC EDX                  ; Reserve one low row for status.
        MOV [MainHeight],EDX
        SUB EDX,15
        MOV [DirHeight],EDX
        MOVZXW ECX,[TtySize.ts_cols]
        MOV [MainWidth],ECX
        MOV EAX,ECX
        XOR EDX,EDX
        SHR ECX,1
        ADC EDX,EDX
        MOV [Remainder2],EDX
        MOV [MainWidthDiv2],ECX
        MOV ECX,5
        XOR EDX,EDX
        DIV RCX
        MOV [MainWidthDiv5],EAX
        MOV [Remainder5],EDX
        MOV EAX,[MainWidthDiv2]
        DEC EAX
        StoD ValRightDiv2        ; Prepare EscRightDiv2
        MOV AX,'C'
        STOSW
        MOV EAX,[MainWidth]
        DEC EAX
        StoD ValRightEdge        ; Prepare EscRightEdge
        MOV AX,'C'
        STOSW
        MOV EAX,[ArgViewDirs::]  ; 1..5.
        LEA RCX,[8*RAX-8+Buffers::]
        MOV [BufferSelected::],RCX
        BufferRetrieve RCX       ; Returns array of SCAN_INDEXes.
        SHR ECX,4                ; Each is 8 bytes long.
        MOV [MaxLineNr::],ECX
        INC ECX
        SUB ECX,[DirHeight]
        JA  .16:
        XOR ECX,ECX
    .16:INC ECX
        MOV [SelectedLineNr],ECX
        ; Start painting.
        StdOutput EscLine1,EscDirsColor    ; Row 1
        StdOutput Spaces,Size=54
        CMPD [MainWidth],28
        JNA .Row2:
        StdOutput EscDimColor,BoxDR
        MOV ECX,[MainWidth]
        SUB ECX,56
        LEA EAX,[2*ECX+ECX]
        StdOutput Boxes,Size=RAX
        StdOutput BoxDL,Space5
    .Row2: StdOutput EscLine2,=B' ',EscEnhColor,EuroDirs::,EscDimColor,Version::, \
             =B".  A folder with scan files:",BoxV,EscFileColor,ArgScanDir::,EscDirsColor
        CMPD [MainWidth],28                ; Row 2
        JB .22:
        GetLengthUTF8 ArgScanDir::
        MOV EAX,[MainWidth]
        SUB EAX,ECX
        SUB EAX,56
        JB .22:
        StdOutput Spaces,Size=RAX
        JMP .25:
    .22:StdOutput EscLine2,EscRightEdge
        JMP .Row3:
    .25:StdOutput EscDimColor,BoxV,Space5
    .Row3:
        StdOutput EscLine3                 ; Row 3
        StdOutput Spaces,Size=54
        CMPD [MainWidth],28
        JNA .Row4:
        StdOutput BoxUR
        MOV ECX,[MainWidth]
        SUB ECX,56
        LEA EAX,[2*ECX+ECX]
        StdOutput Boxes,Size=RAX
        StdOutput BoxUL,Space5
    .Row4:StdOutput EscLine4, =B" Select an older scan file"
        MOV EAX,[MainWidthDiv2]            ; Row 4
        SUB EAX,23
        StdOutput Spaces,Size=RAX
        StdOutput =B"and compare it with a newer scan file"
        StdOutput Spaces,Size=RAX
        StdOutput EscLine5, BoxDR          ; Row 5
        MOV ECX,[MainWidthDiv2]
        SUB ECX,2
        LEA EAX,[2*ECX+ECX]
        StdOutput Boxes,Size=RAX
        StdOutput BoxDL,BoxDR
        ADD ECX,[Remainder2]
        LEA EAX,[2*ECX+ECX]
        StdOutput Boxes,Size=RAX
        StdOutput BoxDL,Space5
        LEA RSI,[ArgInputFile::]
        StdOutput EscLine6, BoxV, EscFileColor, RSI, EscDirsColor
        GetLengthUTF8 RSI                  ; Row 6
        MOV EAX,[MainWidthDiv2]
        SUB EAX,2
        SUB EAX,ECX
        JA .27:
        StdOutput EscLine6,EscRightDiv2
        JMP .30:
    .27:StdOutput Spaces,Size=RAX
    .30:LEA RSI,[ArgOutputFile::]
        StdOutput EscDimColor,BoxV,BoxV,EscFileColor, RSI,EscDirsColor
        GetLengthUTF8 RSI
        MOV EAX,[MainWidthDiv2]
        ADD EAX,[Remainder2]
        SUB EAX,2
        SUB EAX,ECX
        JA .35:
        StdOutput EscLine6,EscRightEdge
        JMP .41:
    .35:StdOutput Spaces,Size=RAX
    .41:StdOutput EscDimColor,BoxV,Space5
        StdOutput EscLine7, BoxUR          ; Row 7
        MOV ECX,[MainWidthDiv2]
        SUB ECX,2
        LEA EAX,[2*ECX+ECX]
        StdOutput Boxes,Size=RAX
        StdOutput BoxUL,BoxUR
        ADD ECX,[Remainder2]
        LEA EAX,[2*ECX+ECX]
        StdOutput Boxes,Size=RAX
        StdOutput BoxUL,Space5
        StdOutput EscLine8,EscDirsColor,Box2DR
        MOV ECX,[MainWidthDiv5]            ; Row 8
        SUB ECX,2
        LEA EAX,[2*RCX+RCX]
        StdOutput Boxes2,Size=RAX
        StdOutput Box2DL,Box2DR
        StdOutput Boxes2,Size=RAX
        StdOutput Box2DL,Box2DR
        StdOutput Boxes2,Size=RAX
        StdOutput Box2DL,Box2DR
        StdOutput Boxes2,Size=RAX
        StdOutput Box2DL,Box2DR
        ADD ECX,[Remainder5]
        LEA EAX,[2*RCX+RCX]
        StdOutput Boxes2,Size=RAX
        StdOutput Box2DL,Space5
        StdOutput EscLine9,Box2V           ; Row 9 Button 1 title
        LEA RSI,[Numbers::+00]
        GetLength$ RSI
        ADD ECX,SIZE#BtnHead1 + SIZE#BtnTail1  ; Size of the button title.
        MOV EDX,[MainWidthDiv5]            ; Space inside the button rectangle.

        CMPB [ArgViewDirs::],1
        JNE .44:
        StdOutput EscEditColor
    .44:StdOutput BtnHead1,RSI,BtnTail1
        SUB EDX,ECX
        JB  .47:
        StdOutput Spaces,Size=RDX
        JMP .50:
    .47:MOV EAX,[MainWidthDiv5]
        DEC EAX
        StoD ValDivN
        MOV AX,'C'
        STOSW
        StdOutput EscLine9,EscDivN
    .50:StdOutput EscDirsColor,Box2V,Box2V
        LEA RSI,[Numbers::+20]             ; Row 9  Button 2
        GetLength$ RSI
        CMPB [ArgViewDirs::],2
        JNE .52:
        StdOutput EscEditColor
    .52:ADD ECX,SIZE#BtnHead2 + SIZE#BtnTail3  ; Size of the button title.
        MOV EDX,[MainWidthDiv5]
        StdOutput BtnHead2,RSI,BtnTail3
        SUB EDX,ECX
        JB  .55:
        StdOutput Spaces,Size=RDX
        JMP .58:
    .55:MOV EAX,[MainWidthDiv5]
        ADD EAX,EAX
        DEC EAX
        StoD ValDivN
        MOV AX,'C'
        STOSW
        StdOutput EscLine9,EscDivN
    .58:StdOutput EscDirsColor,Box2V,Box2V
        LEA RSI,[Numbers::+40]             ; Row 9  Button 3
        GetLength$ RSI
        ADD ECX,SIZE#BtnHead3 + SIZE#BtnTail3  ; Size of the button title.
        MOV EDX,[MainWidthDiv5]
        CMPB [ArgViewDirs::],3
        JNE .61:
        StdOutput EscEditColor
    .61:StdOutput BtnHead3,RSI,BtnTail3
        SUB EDX,ECX
        JB  .64:
        StdOutput Spaces,Size=RDX
        JMP .67:
    .64:MOV EAX,[MainWidthDiv5]
        LEA EAX,[2*EAX+EAX]
        DEC EAX
        StoD ValDivN
        MOV AX,'C'
        STOSW
        StdOutput EscLine9,EscDivN
    .67:StdOutput EscDirsColor,Box2V,Box2V
        LEA RSI,[Numbers::+60]             ; Row 9  Button 4
        GetLength$ RSI
        ADD ECX,SIZE#BtnHead4 + SIZE#BtnTail3  ; Size of the button title.
        MOV EDX,[MainWidthDiv5]
        CMPB [ArgViewDirs::],4
        JNE .70:
        StdOutput EscEditColor
    .70:StdOutput BtnHead4,RSI,BtnTail3
        SUB EDX,ECX
        JB  .72:
        StdOutput Spaces,Size=RDX
        JMP .75:
    .72:MOV EAX,[MainWidthDiv5]
        LEA EAX,[4*EAX]
        DEC EAX
        StoD ValDivN
        MOV AX,'C'
        STOSW
        StdOutput EscLine9,EscDivN
    .75:StdOutput EscDirsColor,Box2V,Box2V
        LEA RSI,[Numbers::+80]             ; Row 9 Button 5
        GetLength$ RSI
        ADD ECX,SIZE#BtnHead5 + SIZE#BtnTail5  ; Size of the button title.
        MOV EDX,[MainWidthDiv5]
        ADD EDX,[Remainder5]
        CMPB [ArgViewDirs::],5
        JNE .78:
        StdOutput EscEditColor
    .78:StdOutput BtnHead5,RSI,BtnTail5
        SUB EDX,ECX
        JB  .81:
        StdOutput Spaces,Size=RDX
        JMP .84:
    .81:MOV EAX,[MainWidthDiv5]
        LEA EAX,[4*EAX+EAX]
        DEC EAX
        StoD ValDivN
        MOV AX,'C'
        STOSW
        StdOutput EscLine9,EscDivN
    .84:StdOutput EscDirsColor,Box2V,Space5
        StdOutput EscLine10,Box2UR         ; Row 10
        MOV ECX,[MainWidthDiv5]
        SUB ECX,2
        LEA EAX,[2*RCX+RCX]
        StdOutput Boxes2,Size=RAX
        StdOutput Box2UL,Box2UR
        StdOutput Boxes2,Size=RAX
        StdOutput Box2UL,Box2UR
        StdOutput Boxes2,Size=RAX
        StdOutput Box2UL,Box2UR
        StdOutput Boxes2,Size=RAX
        StdOutput Box2UL,Box2UR
        ADD ECX,[Remainder5]
        LEA EAX,[2*RCX+RCX]
        StdOutput Boxes2,Size=RAX
        StdOutput Box2UL,Space5
        StdOutput EscLine11,EscDimColor    ; Row 11
        StdOutput Spaces,Size=16
        StdOutput BoxDR
        MOV ECX,[MainWidth]
        LEA ECX,[2*RCX+RCX-18*3]
        StdOutput Boxes,Size=RCX
        StdOutput BoxDL,Space5
        StdOutput EscLine12,=B" Find this text:",BoxV,EscFindColor,FindText,EscDirsColor
        GetLengthUTF8 FindText             ; Row 12
        NEG ECX
        ADD ECX,[MainWidth]
        SUB ECX,18
        JB .87:
        StdOutput Spaces,Size=RCX
        JMP .90:
    .87:StdOutput EscLine12,EscRightEdge
    .90:StdOutput BoxV,Space5
    ; Row 13
        StdOutput EscLine13
        StdOutput Spaces,Size=16
        StdOutput EscDimColor,BoxUR
        MOV ECX,[MainWidth]
        LEA ECX,[2*RCX+RCX-18*3]
        StdOutput Boxes,Size=RCX
        StdOutput BoxUL,Space5
        StdOutput EscLine14,BoxDR          ; Row 14
        MOV ECX,[MainWidth]
        LEA ECX,[2*RCX+RCX-2*3]
        StdOutput Boxes,Size=RCX
        StdOutput BoxDL,Space5
        GetLength$ FindText                ; Rows 15...
        MOV [FindTextSize],ECX
        CALL DirWindowPaint
        MOV EAX,[MainHeight]               ; The last line (20..99).
        StoD ValLineXX,Size=2
        StdOutput EscDimColor,EscLineXX,BoxUR
        MOV ECX,[MainWidth]
        LEA ECX,[2*RCX+RCX-2*3]
        StdOutput Boxes,Size=RCX
        StdOutput BoxUL,Space5,EscDirsColor
        ; MainWindow is painted; DirWindow is erased to blank.
        RET
     ENDP MainWindowPaint

DirWindowPaint
  Procedure DirWindowPaint paints the lower part of the MainWindow which contains volume and directory name, sorted by volume.
  Contents of the selected index buffer will be in memory [IndexInMemory::]..[IndexEndInMemory::], number of indexes in [IndexNumber::]. SCAN_INDEX.Ptr refers to [NamesInMemory].
  DirWindowPaint begins to paint at row 15 of the main window with index whose ordinal number (0..IndexNumber] has been put to [SelectedLineNr].
  [SelectedLineNr] is manipulated with kursor keys. Number of printed rows is max. [DirHeight].
Input
  ArgViewDir is ordinal 1..5 of the buffer with SCAN_INDEXes.
  SelectedLineNr is ordinal number of the index displayed in the top of DirWindow.
Called by
  MainGui, MainWindowPaint.

    DirWindowPaint  PROC
        MOV EAX,[ArgViewDirs::]  ; 1..5.
        LEA RBX,[8*EAX-8+Buffers::]
        BufferRetrieve RBX
        ADD RCX,RSI
        MOV EAX,ECX
        SHR EAX,4
        MOV [IndexInMemory::],RSI
        MOV [IndexEndInMemory::],RCX
        MOV [IndexNumber::],RAX
        MOV EAX,[DirHeight]      ; Number of lines in DirWindow.
        MOV [LineCnt],EAX        ; Counter of written lines in DirWindow (0..DirHeight).
        MOV [LineNr],15          ; Ordinal number of row in MainWindowPaint (15..15+DirHeight).
        MOV EBX,[SelectedLineNr] ; Ordinal number of row in the topmost position of DirWindow (0..MaxLineNr::).
    .10:MOV EAX,[LineNr]
        StoD ValLineXX,Size=2
        StdOutput EscLineXX,EscDimColor,BoxV,EscDirsColor
        CALL OneLine2Dir::       ; RBX is line number (0,1,2,,). Returns Dir=RSI,RCX with the line.
        TEST RCX
        JZ .70:
        MOV EDX,ECX
        MOV RDI,RSI
        MOV R8,RDI
        LEA RSI,[FindText]
        CMPD [FindTextSize],0
        JZ  .60:
        LODSB
    .20:REPNE SCASB
        JNE .60:
        PUSH RCX,RSI,RDI
          MOV ECX,[FindTextSize]
          DEC ECX
          REPE CMPSB
        POP RDI,RSI,RCX
        JNE .20:
        PUSH RDX,RDI
         LEA RCX,[RDI-1]
         SUB RCX,R8
         SUB RDX,RCX
         StdOutput R8,Size=RCX
         StdOutput EscFindColor
         ADD R8,RCX
         MOV ECX,[FindTextSize]
         StdOutput R8,Size=RCX
         StdOutput EscDirsColor
         ADD R8,RCX
         SUB RDX,RCX
         StdOutput R8,Size=RDX
        POP RDI,RDX
        JMP .65:
    .60:MOV RDI,R8
        StdOutput RDI,Size=RDX
    .65:GetLengthUTF8 RDI,Size=RDX
        MOV EAX,[MainWidth]
        DEC EAX
        SUB EAX,ECX
        JB .70:
        StdOutput Spaces,Size=RAX
        JMP .80:
    .70:MOV EAX,[MainWidth]
        SUB EAX,2
        StdOutput Spaces,Size=RAX
    .80:StdOutput EscDimColor,BoxV,Space5
        INC EBX
        INC [LineNr]
        DEC [LineCnt]
        JA  .10:
        RET
       ENDP DirWindowPaint

EditField
  Procedure EditField is called when the user selects or clicks on the editable window.
  It allows to change the field contents. Input parameters are supplied by the structured variable EDIT.

    EditField PROC
         LEA RBX,[Edit]
         MOV RSI,[RBX+EDIT.Address]
         GetLengthUTF8 RSI
         MOV R11,RCX
    .10: ; R11 is cursor position withing the visible field in characters (0,1,2,,).
         PUSH R11
          XOR R11,R11
          CALL .CursorAtR11:
          MOV RSI,[RBX+EDIT.Address]
          MOV R9,RSI             ; R9 points at the beginning of the edit field in memory.
          MOVZX EAX,[RBX+EDIT.ScreenSize]
          GetLengthUTF8 RSI      ; Length goes to RCX.
          SUB EAX,ECX
          ADD R11,RCX
          StdOutput EscShowCursor,EscEditColor,RSI
          StdOutput Spaces,Size=RAX
         POP R11
    .20: CALL .CursorAtR11:     ; Display (perhaps new) cursor position.
    .40: XOR EDI,EDI            ; Read the keyboard.
         LEA RSI,[KeyBuffer]
         MOV [RSI],RDI          ; Clear the key buffer.
         MOV R8,RSI             ; R8 points at the beginning of the keyboard buffer.
         MOV EDX,SIZE# KeyBuffer
         LinABI read,RDI,RSI,RDX
         TEST EAX
         JNA .40:
         XOR ECX,ECX
         MOV RDX,RAX             ; Number of read bytes.
         MOV EAX,[RSI]
         AND EAX,0x00FFFFFF
         CMP EAX,0x3C5B1B        ; Mouse ANSI sequence Esc [ lt
         JE .40:
         Dispatch AL,0x7F,0x09,0x08,0x0A,0x0D ; First try the control characters BS, TAB, NL.
    key  %FOR EscDelete,EscLeft,EscRight,EscHome,EscEnd,EscShiftTab,EscEscape ; Then try kursor keys.
           LEA RDI,[%key]
           MOV CL,SIZE# %key
           MOV RSI,R8
           REPE CMPSB
           JE .%key:
         %ENDFOR key
         CMP AL,27               ; Other special key in ANSI sequence?
         JE .40:                 ; Ignore other ANSI sequences.
         ; Ordinary key was pressed, perhaps multibyte (UTF-8). Its size is in RDX (1..4).
         CALL .Cursor2Physical
         ; Insert RDX bytes at R8 to the current physical position represented by R12.
         GetLength$ R9
         LEA RSI,[R9+RCX-1]
         LEA RDI,[RSI+RDX]
         SUB RCX,R12
         STD
          REP MOVSB
         CLD
         LEA RDI,[R9+R12]
         MOV RSI,R8
         MOV ECX,EDX
         REP MOVSB
         INC R11                 ; Finally, increment cursor position.
         JMP .10:
    .Cursor2Physical PROC        ; Convert the cursor position R11 (0,1,2,,GetLengthUTF8)
         XOR R12,R12             ;  to physical position R12 (0,1,2,,GetLength$). Clobbers RAX,RCX.
         XOR ECX,ECX             ; Cursor position.
    .50: CMP RCX,R11
         JAE .60:
         MOVZXB EAX,[R9+R12]
         INC RCX
         INC R12
         CMP AL,0x80
         JB .50:
         NEG AL                  ; Scan bits 7..0 of the inverted first byte.
         BSR EAX,EAX             ; Returns  EAX= 5, 4, 3 for 2, 3, 4 bytes long UTF-8 character.
         NEG RAX                 ;          RAX=-5,-4,-3 for 2, 3, 4 bytes long UTF-8 character.
         LEA R12,[R12+RAX+6]
         JMP .50:
    .60: ; R12 is physical offset (0,1,2,,GetLength$) corresponding with cursor offset in R11.
         RET
        ENDP .Cursor2Physical
    .CursorAtR11 PROC ; Place the cursor in the edit field at column R11 (0,1,2..GetLengthUTF8).
                      ; R11 represents the visible position, not the position in strings bytes. It clobbers RAX,RDI.
         LEA RDI,[EscGotoRowColH]
         MOVZX EAX,[RBX+EDIT.ScreenRow]
         StoD RDI
         MOV AL,';'
         STOSB
         MOVZX EAX,[RBX+EDIT.ScreenCol]
         ADD RAX,R11
         StoD RDI
         MOV AX,'H'
         STOSW
         StdOutput EscGoto
         RET
        ENDP .CursorAtR11
    .EscHome:
         XOR R11,R11
         JMP .20:
    .EscEnd:
         GetLengthUTF8 R9
         MOV R11,RCX
         JMP .20:
    .EscLeft:
         TEST R11
         JZ .20:
         DEC R11
         JMP .20:
    .EscRight:
         GetLengthUTF8 R9
         CMP R11,RCX
         JAE .20:
         INC R11
         JMP .20:
    .0x08:
    .0x7F:                       ; Move the cursor left and then perform .EscDelete.
         TEST R11
         JZ .20:
         DEC R11
    .EscDelete:                  ; Erase the character at cursor position R11. Move chars on the left by one position.
         CALL .Cursor2Physical
         MOV EDX,1               ; Size of the erased character.
         MOVZXB EAX,[R9+R12]
         CMP AL,0x80
         JB .D2:
         NEG AL                  ; Scan bits 7..0 of the inverted first byte.
         BSR EAX,EAX             ; Returns  EAX= 5, 4, 3 for 2, 3, 4 bytes long UTF-8 character.
         NEG RAX                 ;          RAX=-5,-4,-3 for 2, 3, 4 bytes long UTF-8 character.
         LEA RDX,[RDX+RAX+6]
    .D2: LEA RDI,[R9+R12]
         LEA RSI,[RDI+RDX]
         GetLength$ R9
         INC ECX
         SUB RCX,R12
         REP MOVSB
         JMP .10:
    .0x0D:
    .0x0A:
    .0x09:
    .EscShiftTab:
    .EscEscape:
         XOR R11,R11
         CALL .CursorAtR11:
         MOV RSI,[RBX+EDIT.Address]
         GetLengthUTF8 RSI
         MOV EDX,[MainWidth]
         SUB EDX,18
         SUB EDX,ECX
         StdOutput EscFindColor,RSI, EscDirsColor
         StdOutput Spaces,Size=RDX
         StdOutput EscHideCursor
         RET
       ENDP EditField

OneLine2Dir

  Construct a line from the [BufferSelected] into Dir. The line looks like `dir_size directory\name\in\UTF8`, it is encoded in UTF-8 and zero terminated.
  When the input line number RBX is 0, an empty line is returned (CF=1. RCX=0).
  When the input line number RBX is 1, first line is returned (CF=0. RCX>0).
  When the input line number RBX is 2, sedond line is returned etc.
  When the input line number RBX is bigger than the [MaxLineNr], an empty line is returned (CF=1, RCX=0).

Input
  RBX= line number (0,1,2,,,).
  [ArgViewDirs::]= selected view (1..5 alias ArgViewDirsIns..ArgViewDirsDel).
Output
  RSI=Dir is filled with the line containing the differential size and name in WIDE encoding.
  RCX= is size of the output line in bytes.
Calls
  AddUnderscores
Clobbers
  RAX,RDX

    OneLine2Dir:: PROC
       PUSH RBX,RDI
        MOV EAX,[ArgViewDirs::]
        MOV RDX,[Buffers+8*RAX-8]
        BufferRetrieve RDX    ; Load the buffer contents to RSI,RCX.
        ADD RCX,RSI           ; The end of buffer contents.
        SAL EBX,4             ; Each SCAN_INDEX in the buffer contents has size=16.
        JZ .10:
        LEA RBX,[RBX+RSI-SIZE# SCAN_INDEX] ; Let RBX point at the selected SCAN_INDEX.
        CMP RBX,RCX           ; Is it out of contents?
        JB .20:
    .10:XOR ECX,ECX
        LEA RSI,[Dir::]
        STC
        JMP .90:              ; Abort when the requested line number exceeded the buffer and return CF=1 and empty line.
    .20:MOV RDX,[NewerInMemory::]
        CMP AL,ArgViewDirsDel
        JNE .30:
        MOV RDX,[OlderInMemory::] ; Select the mapping of File_scanOlder or File_scanNewer.
    .30:MOV RAX,[RBX+SCAN_INDEX.Volume]
        LEA RSI,[NumberA::]
        StoD RSI,Size=20      ; Store the directory volume as a decimal ANSI
        CALL AddUnderscores   ;  and complete it with separators.
        LEA RSI,[Number_A::]
        CMPB [ArgViewDirs::],ArgViewDirsDel
        JNE .50:
        CMPB [RSI],'0'
        JE .50:
        INC RSI               ; Skip the minus sign when viewing deleted direcotires.
    .50:LEA RDI,[Dir::]
        CMPB [ArgViewDirs::],ArgViewDirsInc
        JNE .60:
        MOV AL,'+'            ; Add a plus sign when viewing incremented directories.
        JMP .70:
    .60:LODSB
        CMP AL,0
        JE .80:
    .70:STOSB
        JMP .60:
    .80:MOV ECX,[RBX+SCAN_INDEX.Size]
        MOV EAX,[RBX+SCAN_INDEX.Ptr]
        ADD RDX,RAX           ; Let RDX point to the directory name.
        MOV RSI,RDX
        REP MOVSB
        MOV RCX,RDI           ; At the end of directory name.
        MOVB [RDI],0          ; Zero terminate.
        LEA RSI,[Dir]
        SUB RCX,RSI           ; CF=0, RSI,RCX is the target line.
    .90:POP RDI,RBX
        RET
      ENDP OneLine2Dir

AddUnderscores

  Complete an ASCII decadic number with underscores `_` each three digits.

Input
  RSI= is pointer to the beginning of the number.
  RDI= is pointer at the end of the number.
Output
  Number_A is filled with the number and separators, space and zero terminated.
Called by
  OneLine2Dir
Clobbers
  RAX,RCX,RDI

    AddUnderscores PROC
       PUSH RDX
        SUB RDI,RSI
        MOV ECX,3
        MOV EAX,EDI
        XOR EDX,EDX
        LEA RDI,[Number_A::]
        DIV RCX
        CMP EDX,0
        JNE .20:
        REP MOVSB
        DEC EAX
        JMP .40:
    .20:CMP EDX,1
        JNE .30:
        MOVSB
        CMPB [RSI-1],'-'
        JNE .40:
        XCHG EAX,EDX
        DEC EDX
        JS .80:
        JMP .60:
    .30:MOVSW
    .40:XCHG EAX,EDX
    .50:DEC RDX
        JS .80:
        MOV AL,'_'
        STOSB
    .60:MOV CL,3
        REP MOVSB
        JMP .50:
    .80:MOV AX,' '
        STOSW
       POP RDX
       RET
     ENDP AddUnderscores

      ENDPROGRAM dirsling

▲Back to the top▲