/* ----------------------------------------------------------------------------- This source file is part of OpenSpace3D For the latest info, see http://www.openspace3d.com Copyright (c) 2021 I-maginer This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA, or go to http://www.gnu.org/copyleft/lesser.txt ----------------------------------------------------------------------------- */ var sDefaultFilesPath = "%documents%";; var sConfigPath = "tmp/fileslist/";; struct FLDLUnit = [ FLDLU_element : VUIListElement, FLDLU_sLabel : S, FLDLU_sValue : S, FLDLU_iDepth : I, FLDLU_lChildren : [FLDLUnit r1] ] mkFLDLUnit;; struct PlugOnlineFile = [ PFL_instance : PInstance, PFL_sPath : S, PFL_sFilesMask : S, PFL_sTitle : S, PFL_sConfPath : S, PFL_bEditServer : I, PFL_dlgstr : VUIDlg, PFL_liststr : VUIList, PFL_editstr : VUIelement, PFL_lList : [FLDLUnit r1], PFL_selected : VUIListElement, PFL_sPos : S, PFL_iOpacity : I ] mkPlugOnlineFile;; proto updateDialogSize = fun [PlugOnlineFile] I;; proto addElement = fun [PlugOnlineFile FLDLUnit S S I] FLDLUnit;; proto clearList = fun [PlugOnlineFile] I;; proto createDialog = fun [S PlugOnlineFile] I;; fun clearList(obstr)= VUIclearList obstr.PFL_liststr; set obstr.PFL_lList = nil; 0;; fun isFileInList(l, file)= if (l == nil) then 0 else ( let l -> [f n] in let getPathFile f "" -> [_ fname] in if (!strcmp fname file) then 1 else isFileInList n file; );; fun fillLocalFiles(obstr)= clearList obstr; let getFilesFromDir obstr.PFL_sPath obstr.PFL_sFilesMask::nil -> lfiles in while (lfiles != nil) do ( let hd lfiles -> file in let getPathFile file "" -> [_ fname] in addElement obstr nil fname file 0; set lfiles = tl lfiles; ); if (obstr.PFL_lList == nil) then nil else updateDialogSize obstr; 0;; fun cbRefresh(inst, from, action, param, reply, obstr)= fillLocalFiles obstr; 0;; fun cbSetPath(inst, from, action, param, reply, obstr)= set obstr.PFL_sPath = param; _storepack obstr.PFL_sPath obstr.PFL_sConfPath; 0;; /////////// INTERACE ///////////// fun getWidth(obstr, lunits, font)= let 350 -> width in let [10 0] -> [ow oh] in let hd lunits -> unitstr in let ow * unitstr.FLDLU_iDepth -> offset in ( while (lunits != nil) do ( let hd lunits -> unitstr in let VUIgetTextSize font unitstr.FLDLU_sLabel 0 iVUITEXT_HALIGNLEFT|iVUITEXT_VALIGNCENTER -> [tw th] in if (unitstr.FLDLU_lChildren == nil) then set width = max width (tw + 10 + offset) else let getWidth obstr unitstr.FLDLU_lChildren font -> childrenWidth in set width = max (max width (24 + tw + 10 + offset)) childrenWidth; set lunits = tl lunits; ); width; );; fun updateDialogSize(obstr)= let V3DgetSessionView c3dXsession -> viewstr in ( VUIupdateListElementsCoords obstr.PFL_liststr obstr.PFL_liststr.VUIL_lListElts obstr.PFL_liststr.VUIL_tScroll; let VUIgetThemeDef (getThemeFromInstance obstr.PFL_instance) "dialogBox" -> defstr in let VUIgetFontFromInterface VUIgetThemeFont defstr "label" -> lbfontstr in let [10 0] -> [ow oh] in let getWidth obstr obstr.PFL_lList lbfontstr -> sw in let obstr.PFL_liststr.VUIL_tMargin -> [mx my] in let VUIgetListFullContentSize obstr.PFL_liststr 1 -> [tw th] in let max 30 th + 25 + if (obstr.PFL_bEditServer) then 40 else 0 -> sh in let VUIgetViewSize viewstr -> [cvw cvh] in let VUIcomputeDialogBoxSize viewstr (getThemeFromInstance obstr.PFL_instance) (VUIgetElementText obstr.PFL_dlgstr.VUIDLG_title) (VUIgetElementText obstr.PFL_dlgstr.VUIDLG_frame) (if (obstr.PFL_dlgstr.VUIDLG_okBtn == nil && obstr.PFL_dlgstr.VUIDLG_cancelBtn == nil) then 0 else 1) -> [tlw tlh _ _ btnh] in let [(cvw - 20 - 30) (cvh - 30 - btnh - tlh)] -> [maxvw maxvh] in let [(min (max (max sw tlw) 400) maxvw) (min (max sh 80) maxvh)] -> [ttw tth] in let [ttw + 30 tth + btnh + tlh] -> [nw nh] in ( VUIsetElementSize obstr.PFL_dlgstr.VUIDLG_title [100.0 (itof tlh)] nil; VUIsetElementSize obstr.PFL_dlgstr.VUIDLG_frame nil [1 1 (-20) (-(10 + tlh + 10 + btnh))]; VUIsetElementPos obstr.PFL_dlgstr.VUIDLG_frame [0.0 (itof (10 + tlh))] nil nil; VUIsetContainerSize obstr.PFL_dlgstr.VUIDLG_container [(itof nw) (itof nh)] nil; ); ); 0;; fun cbDlgThemeUpdate(constr, obstr)= updateDialogSize obstr;; fun cbSetTitle(inst, from, action, param, reply, obstr)= set obstr.PFL_sTitle = if (param == nil) || (!strcmp (strtrim param) "") then nil else strtrim param; if (obstr.PFL_dlgstr == nil) then nil else ( VUIsetDialogTitle obstr.PFL_dlgstr obstr.PFL_sTitle; updateDialogSize obstr; ); 0;; fun findUnitInList(list, label)= let hd list -> unitstr in ( while (list != nil && (strcmpi unitstr.FLDLU_sLabel label) != 0) do ( set list = tl list; set unitstr = hd list; ); unitstr; );; fun addElement(obstr, parent, label, value, depth)= let mkFLDLUnit[nil label value depth nil] -> newunit in ( if parent == nil then set obstr.PFL_lList = lcat obstr.PFL_lList newunit::nil else set parent.FLDLU_lChildren = lcat parent.FLDLU_lChildren newunit::nil; if obstr.PFL_dlgstr == nil then nil else let VUIaddListElement obstr.PFL_liststr parent.FLDLU_element label value 1 -> newelem in set newunit.FLDLU_element = newelem; newunit; );; fun cbClickDlgButton(dlgstr, state, obstr)= set obstr.PFL_dlgstr = nil; if (state) then ( if ((obstr.PFL_selected == nil) || (obstr.PFL_selected.VUILE_sParam == nil) || (!strcmp obstr.PFL_selected.VUILE_sParam "")) then ( createDialog nil obstr; ) else ( SendPluginEvent obstr.PFL_instance "Hidden" nil nil; SendPluginEvent obstr.PFL_instance "File ready" obstr.PFL_selected.VUILE_sParam nil; ); ) else ( SendPluginEvent obstr.PFL_instance "Hidden" nil nil; SendPluginEvent obstr.PFL_instance "Cancelled" nil nil; ); 0;; fun cbListSelect(liststr, lselected, obstr)= let hd lselected -> selectedstr in set obstr.PFL_selected = selectedstr; 0;; fun getAlign(param)= let [1 1] -> align in let [0.0 0.0] -> pos in let strextr param -> lp in let hd lp -> lp in let 0 -> nb in ( while ((lp != nil) && (nb < 2)) do ( let hd lp -> flag in if (!strcmpi flag "top") then ( mutate align <- [_ 0]; mutate pos <- [_ 10.0]; ) else if (!strcmpi flag "bottom") then ( mutate align <- [_ 2]; mutate pos <- [_ 10.0]; ) else if (!strcmpi flag "left") then ( mutate align <- [0 _]; mutate pos <- [10.0 _]; ) else if (!strcmpi flag "right") then ( mutate align <- [2 _]; mutate pos <- [10.0 _]; ) else nil; set lp = tl lp; set nb = nb + 1; ); [pos align]; );; fun fillList(liststr, parentstr, lunits, unfold)= while (lunits != nil) do ( let hd lunits -> unitstr in let VUIaddListElement liststr parentstr unitstr.FLDLU_sLabel unitstr.FLDLU_sValue 1 -> newelem in ( set unitstr.FLDLU_element = newelem; fillList liststr newelem unitstr.FLDLU_lChildren unfold; if (!unfold || newelem.VUILE_children == nil) then nil else VUIunfoldListElement newelem 1; ); set lunits = tl lunits; ); 0;; fun cbValidateServer(eltstr, text, state, obstr)= if ((!state) || (!strcmp (strtrim text) "")) then nil else ( set obstr.PFL_sPath = text; _storepack obstr.PFL_sPath obstr.PFL_sConfPath; VUIsetElementTextContent eltstr obstr.PFL_sPath; fillLocalFiles obstr; ); 0;; fun cbFocusedServer(eltstr, state, obstr)= let VUIgetElementText eltstr -> text in if (state || (!strcmp obstr.PFL_sPath text)) then nil else cbValidateServer eltstr text 1 obstr; 0;; fun createDialog(param, obstr)= let V3DgetSessionView c3dXsession -> viewstr in let VUIgetThemeDef (getThemeFromInstance obstr.PFL_instance) "dialogBox" -> defstr in let VUIgetThemeFont defstr "label" -> fontstr in let VUIgetFontFromInterface fontstr -> lbfontstr in let if (strcmpi obstr.PFL_sTitle "") == 0 then nil else obstr.PFL_sTitle -> title in let [10 0] -> [ow oh] in let max 400 getWidth obstr obstr.PFL_lList lbfontstr -> width in let locDef "OS3DFILESLIST_C0003" "Server URL" -> serverlabel in let if (obstr.PFL_bEditServer) then VUIgetTextSize lbfontstr serverlabel 0 iVUITEXT_HALIGNLEFT|iVUITEXT_VALIGNTOP else [0 0] -> [tw th] in let max 80 (200 + th + 10) -> height in let if (obstr.PFL_bEditServer) then 30 else 0 -> edth in let VUIcreateDialogExt viewstr obstr.PFL_instance.INST_groupstr.GRP_project.PRJ_vuiGroup [width height] title (locDef "OS3DFILESLIST_C0001" "Ok") (locDef "OS3DFILESLIST_C0002" "Cancel") obstr.PFL_iOpacity (V3DgetVrMode viewstr) (mkfun3 @cbClickDlgButton obstr) "dialogBox" -> dlgstr in let VUIgetDialogFrame dlgstr -> framestr in let VUIgetElementContainer framestr -> contstr in let VUIcreateFrame contstr framestr [0.0 0.0] [(itof (tw + 10)) 0.0] [0 0 0 0 0 0 0 0] [0 0] -> serverlabelstr in let if (obstr.PFL_bEditServer) then VUIcreateEditTextExt contstr framestr [itof (tw + 10) 0.0] [100.0 (itof edth)] [0 0 1 0 0 0 (-(tw + 10)) 0] [0 0] nil [10 5] obstr.PFL_sPath 0 "common/editText" else nil -> editstr in let if (obstr.PFL_bEditServer) then (edth + 10) else 0 -> ylist in let VUIcreateListExt contstr framestr [0.0 itof ylist] [100.0 100.0] [0 0 1 1 0 0 0 (-ylist)] [0 0] [5 5] 0 [ow oh] "list" -> liststr in ( VUIsetElementText serverlabelstr fontstr serverlabel [0 0] [tw 0] [5 5] iVUITEXT_HALIGNLEFT|iVUITEXT_VALIGNTOP VUI_TextAutoHeight 1; fillList liststr nil obstr.PFL_lList 0; VUIsetListCbSelect liststr mkfun3 @cbListSelect obstr; VUIsetElementCbValidate editstr mkfun4 @cbValidateServer obstr; VUIsetElementCbFocused editstr mkfun3 @cbFocusedServer obstr; let if (!strcmp "" (strtrim param)) || param == nil then getAlign obstr.PFL_sPos else getAlign param -> [pos align] in VUIsetContainerPos contstr pos align nil; set obstr.PFL_dlgstr = dlgstr; set obstr.PFL_liststr = liststr; set obstr.PFL_selected = nil; VUIsetContainerThemeCallback contstr mkfun2 @cbDlgThemeUpdate obstr; VUIsetContainerClear contstr 0; VUIshowDialog dlgstr 1; fillLocalFiles obstr; ); 0;; fun cbVrChange(inst, viewstr, state, obstr)= if obstr.PFL_dlgstr == nil then nil else ( VUIdestroyDialogBox obstr.PFL_dlgstr; createDialog nil obstr; ); 0;; fun cbShow(inst, from, action, param, reply, obstr)= if obstr.PFL_dlgstr != nil then nil else ( createDialog param obstr; SendPluginEvent inst "Shown" nil nil; ); 0;; fun cbHide(inst, from, action, param, reply, obstr)= if obstr.PFL_dlgstr == nil then nil else ( VUIdestroyDialogBox obstr.PFL_dlgstr; set obstr.PFL_dlgstr = nil; SendPluginEvent inst "Hidden" nil nil; ); 0;; fun cbClearList(inst, from, action, param, reply, obstr)= clearList obstr; if (obstr.PFL_dlgstr == nil) then nil else updateDialogSize obstr; 0;; fun cbChooseDir(dlg, obstr, path)= set obstr.PFL_sPath = path; _storepack obstr.PFL_sPath obstr.PFL_sConfPath; addLogMessage path; if (path == nil) then nil else cbShow obstr.PFL_instance nil nil nil nil obstr; 0;; fun cbChoosePath(inst, from, action, param, reply, obstr)= _DLGrflopenDir (_DLGOpenDir _channel nil obstr.PFL_sPath "") @cbChooseDir obstr; 0;; fun deleteOb(inst, obstr)= VUIdestroyDialogBox obstr.PFL_dlgstr; 0;; fun newOb(inst)= let getPluginInstanceParam inst "title" -> title in let if (title == nil) then "" else title -> title in let getPluginInstanceParam inst "path" -> path in let if (path == nil) then sDefaultFilesPath else path -> path in let atoi (getPluginInstanceParam inst "editsrv") -> editsrv in let if (editsrv == nil) then 1 else editsrv -> editsrv in let getPluginInstanceParam inst "mask" -> mask in let if (mask == nil) || (!strcmp mask "") then "*.*" else mask -> mask in let atoi (getPluginInstanceParam inst "show") -> show in let if (show == nil) then 1 else show -> show in let atoi (getPluginInstanceParam inst "valign") -> valign in let if valign == nil then 1 else valign -> valign in let atoi (getPluginInstanceParam inst "halign") -> halign in let if halign == nil then 1 else halign -> halign in let if (valign == 0) then "top" else if (valign == 2) then "bottom" else "center" -> vpos in let if (halign == 0) then "left" else if (halign == 2) then "right" else "center" -> hpos in let atoi (getPluginInstanceParam inst "opacity") -> opacity in let if (opacity == nil) then 100 else opacity -> opacity in let strcatn sConfigPath::(getPluginInstanceFullname inst)::".conf"::nil -> confpath in let mkPlugOnlineFile [inst path mask title confpath editsrv nil nil nil nil nil (strcatn vpos::" "::hpos::nil) opacity] -> obstr in ( if ((_checkpack confpath) == nil) then nil else set obstr.PFL_sPath = _getpack (_checkpack confpath); if (!show) then nil else cbShow inst nil nil nil nil obstr; PluginRegisterAction inst "Show" mkfun6 @cbShow obstr; PluginRegisterAction inst "Hide" mkfun6 @cbHide obstr; PluginRegisterAction inst "Choose path" mkfun6 @cbChoosePath obstr; PluginRegisterAction inst "Set path" mkfun6 @cbSetPath obstr; PluginRegisterAction inst "Refresh" mkfun6 @cbRefresh obstr; setPluginInstanceCbVrModeChanged inst mkfun4 @cbVrChange obstr; setPluginInstanceCbDel inst mkfun2 @deleteOb obstr; ); 0;; fun IniPlug(file)= PlugRegister @newOb nil; setPluginEditor @dynamicedit; 0;;