File Selection Dialog

Started by J7M, October 13, 2023, 18:35:52

Previous topic - Next topic

J7M

Maybe someone might be interested. From time to time I want to save or load a file. The easy way was to use INPUT to ask for a file name. But by using the FORM command a quite nice file selection dialog can be created. If you want to use it, you only have to copy the sub into your program and call it. I can also create a unit for simple use.

Here a complete program showing how it works.

OPTION BASE 1

print "Please press any key to show the file dialog"
pause

'showpage(1)  ' Uncomment this line if SHOWPAGE was used. This will enable SmallBASIC auto-update again
f = FileSelectDialog(0, 50, 50, XMAX - 100, YMAX - 100, 0)

print "We are back to the previous screen. The selected file is:"
print f




func FileSelectDialog(Type, x, y, w, h, ButtonSize)
' Displays a file select dialog. If type is 0 (LOAD) then the function
' will always return a existing file. If type is 1 (SAVE) the returned
' file might exist. If user cancel the file dialog, the function will
' return -1
'
' Type        : 0 = Load; 1 = Save
' x,y         : position on screen in pixel
' w,h         : width and height in pixel
' ButtonSize  : size of the buttons in pixel, 0 = auto
' Return value: file selected by user

    local listbox, textbox, buttons, f, GUI, ReturnValue = 0, win
    local GetFileList, cmpfunc_strings, index, Directory, FileList
    local BGColor, TextColor, ElementColor, GraphicCursor, ii
   
    BGColor = rgb(100, 100, 100)
    TextColor = rgb(255, 255, 255)
    ElementColor = rgb(80, 80, 80)
   
    x = x + 2
    y = y + 2
    w = w - 4
    h = h - 6

    win = window()
    win.graphicsScreen2()
    color 15,0
    cls
    color TextColor, BGColor
      
   
    Directory = cwd()
   
    if(ButtonSize == 0) then ButtonSize = 3 * Textwidth("W")   
   
    func cmpfunc_strings(x, y)
        x = lower(x)
        y = lower(y)
       
        if x == y
            return 0
        elseif x > y
            return 1
        else
            return -1
        endif
    end
   
    func GetFileList()
        local FileList
        FileList = files("*")
       
        for ii = 1 to ubound(FileList)
            if(isdir(FileList[ii])) then FileList[ii] = enclose(FileList[ii], "[]")               
        next
       
        sort FileList use cmpfunc_strings(x, y)
       
        insert FileList, 1, "[..]"
            
        return FileList
    end   

    listbox.type = "listbox"
    listbox.x = x
    listbox.y = y + 2*ButtonSize
    listbox.height = h - 3.5 * ButtonSize
    listbox.width = w - ButtonSize
    listbox.color = TextColor
    listbox.backgroundColor = ElementColor
    listbox.value = GetFileList()
    listbox.selectedIndex = -1
    listbox.length = ubound(listbox.value) - 1
    listbox.noFocus = 1
    f.inputs << listbox
   
    textbox.type = "text"
    textbox.x = x
    textbox.y = y + ButtonSize
    textbox.width = w - ButtonSize
    textbox.value = cwd
    textbox.color = TextColor
    textbox.backgroundColor = ElementColor
    textbox.length = 500 ' number of characters
    textbox.noFocus = 0
    f.inputs << textbox
   
    buttons.type = "button"
    buttons.x = x + w - ButtonSize
    buttons.y = y + 2*ButtonSize
    buttons.width = ButtonSize
    buttons.height = ButtonSize
    buttons.label = "/\\"
    buttons.backgroundcolor = ElementColor
    buttons.color = TextColor
    buttons.noFocus = 1
    f.inputs << buttons

    buttons.type = "button"
    buttons.x = x + w - ButtonSize
    buttons.y = y + h - 2.5*ButtonSize
    buttons.width = ButtonSize
    buttons.height = ButtonSize
    buttons.label = "\\/"
    buttons.backgroundcolor = ElementColor
    buttons.color = TextColor
    buttons.noFocus = 1
    f.inputs << buttons

    buttons.type = "button"
    buttons.x = x + w - 6.5 * ButtonSize
    buttons.y = y + h - ButtonSize
    buttons.width = ButtonSize * 3
    buttons.height = ButtonSize
    buttons.label = "SELECT"
    buttons.backgroundcolor = ElementColor
    buttons.color = TextColor
    buttons.noFocus = 1
    f.inputs << buttons

    buttons.type = "button"
    buttons.x = x + w - 3 * ButtonSize
    buttons.y = y + h - ButtonSize
    buttons.width = ButtonSize * 3
    buttons.height = ButtonSize
    buttons.label = "CANCEL"
    buttons.backgroundcolor = ElementColor
    buttons.color = TextColor
    buttons.noFocus = 1
    f.inputs << buttons   
   
    rect x - 2, y - 2 STEP w + 4, h + 6 color BGColor filled
    at x,y
    if(Type == 0)
        print "LOAD FILE:"
    else
        print "SAVE FILE:"
    endif
   
    GUI = form(f)
   
    while(ReturnValue == 0)
     
      GUI.doEvents()
     
      ' Check for value of the active input field
      if (len(GUI.value) > 0) then

        select case GUI.value
            case "/\\"
                if(GUI.inputs[1].selectedIndex > 0)
                    GUI.inputs[1].selectedIndex = GUI.inputs[1].selectedIndex - 1
                    index = GUI.inputs[1].selectedIndex + 1
                   
                    f = disclose(GUI.inputs[1].value[index], "[]")
                    if(f != "")         ' directory                 
                        GUI.inputs[2].value = cwd + f
                    else                ' file
                        GUI.inputs[2].value = cwd + GUI.inputs[1].value[index]
                    endif
                   
                    GUI.refresh(0)
                endif
            case "\\/"
                if(GUI.inputs[1].selectedIndex < GUI.inputs[1].length)
                    GUI.inputs[1].selectedIndex = GUI.inputs[1].selectedIndex + 1
                   
                    index = GUI.inputs[1].selectedIndex + 1
                    f = disclose(GUI.inputs[1].value[index], "[]")
                   
                    if(f != "")         ' directory                 
                        GUI.inputs[2].value = cwd + f
                    else                ' file
                        GUI.inputs[2].value = cwd + GUI.inputs[1].value[index]
                    endif
                   
                    GUI.refresh(0)
                endif
            case "SELECT"
                if(isdir(GUI.inputs[2].value))
                    chdir(GUI.inputs[2].value)
                    GUI.inputs[1].value = GetFileList()
                    GUI.refresh(0)
                elseif(isfile(GUI.inputs[2].value))
                    ReturnValue = GUI.inputs[2].value
                elseif(Type == 1)                     ' if Save
                    ReturnValue = GUI.inputs[2].value
                else
                    win.alert("Not a valid file or directory")
                endif
            case "CANCEL"
                ReturnValue = -1
            case else   ' user clicked on a file in the file listbox
                f = disclose(GUI.value, "[]")
                if(f != "") then
                    chdir f
                    GUI.inputs[1].value = GetFileList()
                    GUI.inputs[2].value = cwd
                    GUI.refresh(0)
                else
                    index = GUI.inputs[1].selectedIndex + 1
                    GUI.inputs[2].value = cwd + GUI.inputs[1].value[index]
                    GUI.refresh(0)
                endif
                   
        end select
       
       
      endif
     
       
    wend

    GUI.close()
   
    chdir Directory
    win.graphicsScreen1()
   
    return ReturnValue

end