Author Topic: Simple File Selection box for graphical modes (Now works in Linux too)  (Read 4440 times)

0 Members and 1 Guest are viewing this topic.

Offline Dav

  • Forum Resident
  • Posts: 792
    • View Profile
This is an update to a simple file section box FUNCTION I made a while back.  The old one wouldn't work in Linux at all - this one does.  Not trying to replace the great direntry.h method, but just throwing in a single FUNCTION alternative easy to stick in a program.   Tested this in Windows and Linux Mint (new fan) and it seems to work correctly and the same in both (can't test it in Mac).

(Special thanks to the Linux guys in this thread).

- Dav

EDIT: 11/23/2021 - Fixed file list bug under Linux to show all files when *.* used.
Code: QB64: [Select]
  1. '==============
  2. 'FILESELECT.BAS  v1.1
  3. '==============
  4. 'Simple file selector box for graphical screen modes.
  5. 'Coded by Dav, NOV/2021 (with the kind help of the QB64.org forum gurus!)
  6.  
  7. '* NOW WORKS UNDER LINUX!
  8.  
  9. 'Navigate through directories and select a file.
  10. 'Use ARROWS, PAGE Up/Down, HOME, END to scroll list.
  11. 'Press ENTER to select highlighted file or enter highlighted dir.
  12. 'ESC will cancel and close box
  13.  
  14. 'things to do: auto center box on screen, and ditch x/y input?
  15. '              ...will need to adjust box size based on file/dir chr length
  16. '              Add user defined colors instead...?
  17.  
  18.  
  19. SCREEN _NEWIMAGE(700, 500, 32)
  20.  
  21. '=== draw a background
  22. CLS , _RGB(32, 32, 32)
  23. FOR x = 1 TO _WIDTH STEP 3
  24.     FOR y = 1 TO _HEIGHT STEP 3
  25.         PSET (x, y), _RGB(RND * 255, RND * 255, RND * 255)
  26.     NEXT
  27.  
  28. '=== Ask user to select a file
  29. a$ = FileSelect$(5, 15, 20, 55, "*.*")
  30.  
  31. IF a$ <> "" THEN
  32.     PRINT "You selected: "; a$
  33.  
  34.  
  35.  
  36. FUNCTION FileSelect$ (y, x, y2, x2, Filespec$)
  37.  
  38.     '=== save original place of cursor
  39.     origy = CSRLIN
  40.     origx = POS(1)
  41.  
  42.     '=== save colors
  43.     fg& = _DEFAULTCOLOR
  44.     bg& = _BACKGROUNDCOLOR
  45.  
  46.     '=== Save whole screen
  47.     DIM scr1 AS _MEM, scr2 AS _MEM
  48.     scr1 = _MEMIMAGE(0): scr2 = _MEMNEW(scr1.SIZE)
  49.     _MEMCOPY scr1, scr1.OFFSET, scr1.SIZE TO scr2, scr2.OFFSET
  50.  
  51.     '=== Generate a unique temp filename to use based on date + timer
  52.     tmp$ = "_qb64_" + DATE$ + "_" + LTRIM$(STR$(INT(TIMER))) + ".tmp"
  53.     IF INSTR(_OS$, "LINUX") THEN tmp$ = "/tmp/" + tmp$
  54.  
  55.     loadagain:
  56.  
  57.     top = 0
  58.     selection = 0
  59.  
  60.     '=== list directories
  61.     IF INSTR(_OS$, "LINUX") THEN
  62.         SHELL _HIDE "find . -maxdepth 1 -type d > " + tmp$
  63.     ELSE
  64.         SHELL _HIDE "dir /b /A:D > " + tmp$
  65.     END IF
  66.  
  67.     '=== make room for names
  68.     REDIM FileNames$(10000) 'space for 10000 filenames
  69.  
  70.     '=== only show the ".." when not at root dir
  71.     IF LEN(_CWD$) <> 3 THEN
  72.         FileNames$(0) = ".."
  73.         LineCount = 1
  74.     ELSE
  75.         LineCount = 0
  76.     END IF
  77.  
  78.     '=== Open temp file
  79.     FF = FREEFILE
  80.     OPEN tmp$ FOR INPUT AS #FF
  81.  
  82.     WHILE ((LineCount < UBOUND(FileNames$)) AND (NOT EOF(FF)))
  83.         LINE INPUT #FF, rl$
  84.  
  85.         '=== load, ignoring the . entry added under Linux
  86.         IF rl$ <> "." THEN
  87.  
  88.             'also remove the ./ added at the beginning when under linux
  89.             IF INSTR(_OS$, "LINUX") THEN
  90.                 IF LEFT$(rl$, 2) = "./" THEN
  91.                     rl$ = RIGHT$(rl$, LEN(rl$) - 2)
  92.                 END IF
  93.             END IF
  94.  
  95.             FileNames$(LineCount) = "[" + rl$ + "]"
  96.             LineCount = LineCount + 1
  97.  
  98.         END IF
  99.     WEND
  100.  
  101.     CLOSE #FF
  102.  
  103.     '=== now grab list of files...
  104.     IF INSTR(_OS$, "LINUX") THEN
  105.         SHELL _HIDE "rm " + tmp$
  106.         IF Filespec$ = "*.*" THEN Filespec$ = ""
  107.         SHELL _HIDE "find -maxdepth 1 -type f -name '" + Filespec$ + "*' > " + tmp$
  108.     ELSE
  109.         SHELL _HIDE "del " + tmp$
  110.         SHELL _HIDE "dir /b /A:-D " + Filespec$ + " > " + tmp$
  111.     END IF
  112.  
  113.     '=== open temp file
  114.     FF = FREEFILE
  115.     OPEN tmp$ FOR INPUT AS #FF
  116.  
  117.     WHILE ((LineCount < UBOUND(FileNames$)) AND (NOT EOF(FF)))
  118.  
  119.         LINE INPUT #FF, rl$
  120.  
  121.         '=== load, ignoring the generated temp file...
  122.         IF rl$ <> tmp$ THEN
  123.  
  124.             'also remove the ./ added at the beginning when under linux
  125.             IF INSTR(_OS$, "LINUX") THEN
  126.                 IF LEFT$(rl$, 2) = "./" THEN
  127.                     rl$ = RIGHT$(rl$, LEN(rl$) - 2)
  128.                 END IF
  129.             END IF
  130.  
  131.             FileNames$(LineCount) = rl$
  132.             LineCount = LineCount + 1
  133.         END IF
  134.  
  135.     WEND
  136.     CLOSE #FF
  137.  
  138.     '=== Remove the temp file created
  139.     IF INSTR(_OS$, "LINUX") THEN
  140.         SHELL _HIDE "rm " + tmp$
  141.     ELSE
  142.         SHELL _HIDE "del " + tmp$
  143.     END IF
  144.  
  145.  
  146.     '=== draw a box
  147.     COLOR _RGB(100, 100, 255)
  148.     FOR l = 0 TO y2 + 1
  149.         LOCATE y + l, x: PRINT STRING$(x2 + 4, CHR$(219));
  150.     NEXT
  151.  
  152.     '=== show current working dir at top
  153.     COLOR _RGB(255, 255, 255), _RGB(100, 100, 255)
  154.     CurDir$ = _CWD$
  155.     '=== Shorten it is too long, for display purposes
  156.     IF LEN(CurDir$) > x2 - x THEN
  157.         CurDir$ = MID$(CurDir$, 1, x2 - x - 3) + "..."
  158.     END IF
  159.     LOCATE y, x + 2: PRINT CurDir$;
  160.  
  161.     '=== scroll through list...
  162.     DO
  163.  
  164.         FOR l = 0 TO (y2 - 1)
  165.  
  166.             LOCATE (y + 1) + l, (x + 2)
  167.             IF l + top = selection THEN
  168.                 COLOR _RGB(0, 0, 64), _RGB(255, 255, 255) 'selected line
  169.             ELSE
  170.                 COLOR _RGB(255, 255, 255), _RGB(0, 0, 64) 'regular
  171.                 '=== directories get a different color...
  172.                 IF MID$(FileNames$(top + l), 1, 1) = "[" THEN
  173.                     COLOR _RGB(255, 255, 0), _RGB(0, 0, 64)
  174.                 END IF
  175.             END IF
  176.  
  177.             PRINT LEFT$(FileNames$(top + l) + STRING$(x2, " "), x2);
  178.  
  179.         NEXT
  180.  
  181.         '=== Get user input
  182.  
  183.         k$ = INKEY$
  184.         SELECT CASE k$
  185.  
  186.             CASE IS = CHR$(0) + CHR$(72) 'Up arrow
  187.                 IF selection > 0 THEN selection = selection - 1
  188.                 IF selection < top THEN top = selection
  189.  
  190.             CASE IS = CHR$(0) + CHR$(80) 'Down Arrow
  191.                 IF selection < (LineCount - 1) THEN selection = selection + 1
  192.                 IF selection > (top + (y2 - 2)) THEN top = selection - y2 + 1
  193.  
  194.             CASE IS = CHR$(0) + CHR$(73) 'Page up
  195.                 top = top - y2
  196.                 selection = selection - y2
  197.                 IF top < 0 THEN top = 0
  198.                 IF selection < 0 THEN selection = 0
  199.  
  200.             CASE IS = CHR$(0) + CHR$(81) 'Page Down
  201.                 top = top + y2
  202.                 selection = selection + y2
  203.                 IF top >= LineCount - y2 THEN top = LineCount - y2
  204.                 IF top < 0 THEN top = 0
  205.                 IF selection >= LineCount THEN selection = LineCount - 1
  206.  
  207.             CASE IS = CHR$(0) + CHR$(71) 'Home
  208.                 top = 0: selection = 0
  209.  
  210.             CASE IS = CHR$(0) + CHR$(79) 'End
  211.                 selection = LineCount - 1
  212.                 top = selection - y2 + 1
  213.                 IF top < 0 THEN top = 0
  214.  
  215.             CASE IS = CHR$(27) ' ESC cancels
  216.                 FileSelect$ = ""
  217.                 EXIT DO
  218.  
  219.             CASE IS = CHR$(13) 'Enter
  220.                 '=== if .. then go up one dir
  221.                 IF RTRIM$(FileNames$(selection)) = ".." THEN
  222.                     cd$ = _CWD$
  223.                     IF INSTR(_OS$, "LINUX") THEN
  224.                         cd$ = LEFT$(cd$, _INSTRREV(cd$, "/"))
  225.                     ELSE
  226.                         cd$ = LEFT$(cd$, _INSTRREV(cd$, "\"))
  227.                     END IF
  228.                     CHDIR cd$
  229.                     ERASE FileNames$
  230.                     GOTO loadagain
  231.                 END IF
  232.  
  233.                 'see if directory
  234.                 test$ = RTRIM$(FileNames$(selection))
  235.                 IF LEFT$(test$, 1) = "[" THEN
  236.                     test$ = MID$(test$, 2, LEN(test$) - 2)
  237.                     CHDIR test$
  238.                     ERASE FileNames$
  239.                     GOTO loadagain
  240.                 ELSE
  241.                     IF INSTR(_OS$, "LINUX") THEN
  242.                         IF RIGHT$(_CWD$, 1) = "/" THEN
  243.                             C$ = _CWD$
  244.                         ELSE
  245.                             C$ = _CWD$ + "/"
  246.                         END IF
  247.                     ELSE
  248.                         IF RIGHT$(_CWD$, 1) = "\" THEN
  249.                             C$ = _CWD$
  250.                         ELSE
  251.                             C$ = _CWD$ + "\"
  252.                         END IF
  253.                     END IF
  254.  
  255.                     FileSelect$ = C$ + RTRIM$(FileNames$(selection))
  256.                     EXIT DO
  257.  
  258.                 END IF
  259.  
  260.         END SELECT
  261.  
  262.     LOOP
  263.  
  264.     _KEYCLEAR
  265.  
  266.     '=== Restore the whole screen
  267.     _MEMCOPY scr2, scr2.OFFSET, scr2.SIZE TO scr1, scr1.OFFSET
  268.     _MEMFREE scr1: _MEMFREE scr2
  269.  
  270.     '=== restore original y,x and color
  271.     LOCATE origy, origx
  272.  
  273.     COLOR fg&, bg&
  274.  
  275.  
  276.  
  277.  
« Last Edit: November 23, 2021, 09:10:39 am by Dav »

Offline johnno56

  • Forum Resident
  • Posts: 1270
  • Live long and prosper.
    • View Profile
Re: Simple File Selection box for graphical modes (Now works in Linux too)
« Reply #1 on: November 19, 2021, 02:30:02 pm »
Well, I for one, think this application is quite impressive. My first instinct was to use the mouse, but keyboard, works for me as well. Very nicely done indeed...

J
Logic is the beginning of wisdom.

Offline Dav

  • Forum Resident
  • Posts: 792
    • View Profile
Re: Simple File Selection box for graphical modes (Now works in Linux too)
« Reply #2 on: November 23, 2021, 07:39:49 am »
Thanks, @johnno56.  I'm missing something under linux it appears - no executable files are being displayed in the list.  I'm going have to study the linux file system and commands.

EDIT: I made a quick fix under Linux that seems to work  for now.  Not the best solution, but I need to uderstand more the way Linux uses wildcards to update further.  I Added this to the Linux area when getting a file list. Now all files are listed:

Code: QB64: [Select]
  1. IF Filespec$ = "*.*" THEN Filespec$ = ""

- Dav
« Last Edit: November 23, 2021, 09:10:06 am by Dav »