structure BrowseMode = struct open AppType open DrawMessage open FileMessage open InputMessage open UpdateMessage fun stringToVec (pos, str, acc, startX, startY, windowWidth, windowHeight, r, g, b) = if pos = String.size str then acc else let val chr = String.sub (str, pos) val chrFun = Vector.sub (CozetteAscii.asciiTable, Char.ord chr) val chrVec = chrFun (startX, startY, 25.0, 25.0, windowWidth, windowHeight, r, g, b) val acc = chrVec :: acc in stringToVec ( pos + 1 , str , acc , startX + 12 , startY , windowWidth , windowHeight , r , g , b ) end fun buildFileBrowserText (pos, fileBrowser, acc, startY, windowWidth, windowHeight, selectedIdx) = if pos = Vector.length fileBrowser then Vector.concat acc else let val item = Vector.sub (fileBrowser, pos) val itemText = case item of IS_FILE str => str | IS_FOLDER str => str val acc = if pos <> selectedIdx then stringToVec ( 0 , itemText , acc , 10 , startY , windowWidth , windowHeight , 0.0 , 0.0 , 0.0 ) else stringToVec ( 0 , itemText , acc , 10 , startY , windowWidth , windowHeight , 0.35 , 0.35 , 0.75 ) in buildFileBrowserText ( pos + 1 , fileBrowser , acc , startY + 23 , windowWidth , windowHeight , selectedIdx ) end fun redrawFileBrowser (model: app_type) = let val {windowWidth, windowHeight, fileBrowser, fileBrowserIdx, ...} = model val ww = Real32.fromInt windowWidth val wh = Real32.fromInt windowHeight val textVec = buildFileBrowserText (0, fileBrowser, [], 10, ww, wh, fileBrowserIdx) val drawMsg = DRAW_MODAL_TEXT textVec in (model, [DRAW drawMsg]) end fun handleFileBrowserAndPathInBrowseMode (model, fileBrowser, path) = let val model = AppWith.fileBrowserAndPath (model, fileBrowser, path) in redrawFileBrowser model end fun browseModeArrowUp (model: app_type) = let val {fileBrowser, fileBrowserIdx, ...} = model val fileBrowserIdx = if fileBrowserIdx > 0 then fileBrowserIdx - 1 else Int.max (0, Vector.length fileBrowser - 1) val model = AppWith.fileBrowserIdx (model, fileBrowserIdx) in redrawFileBrowser model end fun browseModeArrowDown (model: app_type) = let val {fileBrowser, fileBrowserIdx, ...} = model val fileBrowserIdx = if fileBrowserIdx = Vector.length fileBrowser - 1 then 0 else fileBrowserIdx + 1 val model = AppWith.fileBrowserIdx (model, fileBrowserIdx) in redrawFileBrowser model end fun selectCurrentFileItem model = let val {fileBrowser, fileBrowserIdx, openFilePath, ...} = model in if Vector.length fileBrowser > 0 then let val path = case Vector.sub (fileBrowser, fileBrowserIdx) of IS_FILE str => str | IS_FOLDER str => str val path = String.concat [openFilePath, "/", path] val fileMsg = SELECT_PATH path in (model, [FILE fileMsg]) end else (model, []) end fun update (model: app_type, inputMsg) = case inputMsg of ARROW_UP => browseModeArrowUp model | ARROW_DOWN => browseModeArrowDown model (* todo: | ARROW_LEFT => *) | ARROW_RIGHT => selectCurrentFileItem model | KEY_ENTER => selectCurrentFileItem model | KEY_SPACE => selectCurrentFileItem model | FILE_BROWSER_AND_PATH {fileBrowser, path} => handleFileBrowserAndPathInBrowseMode (model, fileBrowser, path) | SQUARES_LOAD_ERROR => CommonUpdate.squaresLoadError model | _ => (model, []) end