/* ----------------------------------------------------------------------------- This source file is part of OpenSpace3D For the latest info, see http://www.openspace3d.com Copyright (c) 2012 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 ----------------------------------------------------------------------------- */ struct DialogListUnit = [ DLU_element : VUIListElement, DLU_sLabel : S, DLU_sValue : S, DLU_iDepth : I, DLU_lChildren : [DialogListUnit r1] ] mkDialogListUnit;; struct PlugDialogList = [ PDLGL_instance : PInstance, PDLGL_dlgstr : VUIDlg, PDLGL_liststr : VUIList, PDLGL_lList : [DialogListUnit r1], PDLGL_selected : VUIListElement, PDLGL_lthemeelts : [S r1], PDLGL_sTitle : S, PDLGL_bOkButton : I, PDLGL_tChildOffset : [I I], PDLGL_bUnfold : I, PDLGL_sPos : S, PDLGL_iOpacity : I, PDLGL_iFadeSpeed : I, PDLGL_bMultiselect : I ] mkPlugDialogList;; fun deleteOb(inst, obstr)= VUIdestroyDialogBox obstr.PDLGL_dlgstr; 0;; fun getWidth(obstr, lunits, font)= let 350 -> width in let obstr.PDLGL_tChildOffset -> [ow oh] in let hd lunits -> unitstr in let ow * unitstr.DLU_iDepth -> offset in ( while (lunits != nil) do ( let hd lunits -> unitstr in let VUIgetTextSize font unitstr.DLU_sLabel 0 iVUITEXT_HALIGNLEFT|iVUITEXT_VALIGNCENTER -> [tw th] in if (unitstr.DLU_lChildren == nil) then set width = max width (tw + 10 + offset) else let getWidth obstr unitstr.DLU_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.PDLGL_liststr obstr.PDLGL_liststr.VUIL_lListElts obstr.PDLGL_liststr.VUIL_tScroll; let VUIgetThemeDef (getThemeFromInstance obstr.PDLGL_instance) "dialogBox" -> defstr in let VUIgetFontFromInterface VUIgetThemeFont defstr "label" -> lbfontstr in let getWidth obstr obstr.PDLGL_lList lbfontstr -> sw in let obstr.PDLGL_liststr.VUIL_tMargin -> [mx my] in let VUIgetListFullContentSize obstr.PDLGL_liststr 1 -> [tw th] in let max 30 th + 20 -> sh in let VUIgetViewSize viewstr -> [cvw cvh] in let VUIcomputeDialogBoxSize viewstr (getThemeFromInstance obstr.PDLGL_instance) (VUIgetElementText obstr.PDLGL_dlgstr.VUIDLG_title) (VUIgetElementText obstr.PDLGL_dlgstr.VUIDLG_frame) (if (obstr.PDLGL_dlgstr.VUIDLG_okBtn == nil && obstr.PDLGL_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) 200) maxvw) (min (max sh 70) maxvh)] -> [ttw tth] in let [ttw + 30 tth + btnh + tlh] -> [nw nh] in ( VUIsetElementSize obstr.PDLGL_dlgstr.VUIDLG_title [100.0 (itof tlh)] nil; VUIsetElementSize obstr.PDLGL_dlgstr.VUIDLG_frame nil [1 1 (-20) (-(10 + tlh + 10 + btnh))]; VUIsetElementPos obstr.PDLGL_dlgstr.VUIDLG_frame [0.0 (itof (10 + tlh))] nil nil; VUIsetContainerSize obstr.PDLGL_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.PDLGL_sTitle = if (param == nil) || (!strcmp (strtrim param) "") then nil else strtrim param; if (obstr.PDLGL_dlgstr == nil) then nil else ( VUIsetDialogTitle obstr.PDLGL_dlgstr obstr.PDLGL_sTitle; updateDialogSize obstr; ); 0;; fun findUnitInList(list, label)= let hd list -> unitstr in ( while (list != nil && (strcmpi unitstr.DLU_sLabel label) != 0) do ( set list = tl list; set unitstr = hd list; ); unitstr; );; fun cbRemoveElement(inst, from, action, param, reply, obstr)= let 0 -> start in let 0 -> notfound in let nil -> parent in if (param == nil) then nil else ( let strfind2List param ">" 0 -> poslist in while (poslist != nil && notfound != 1) do ( let hd poslist -> end in let strtrim (substr param start (end - start)) -> label in let if parent == nil then obstr.PDLGL_lList else parent.DLU_lChildren -> list in let findUnitInList list label -> unitstr in ( if unitstr == nil then set notfound = 1 else ( set parent = unitstr; 0; ); set start = end + 1; ); set poslist = tl poslist; ); let strtrim (substr param start ((strlen param) - start)) -> label in let if parent == nil then obstr.PDLGL_lList else parent.DLU_lChildren -> list in let findUnitInList list label -> unitstr in if (notfound == 1 || unitstr == nil) then nil else ( if (obstr.PDLGL_dlgstr == nil) then nil else VUIremoveListElement unitstr.DLU_element; if (parent == nil) then set obstr.PDLGL_lList = remove_from_list obstr.PDLGL_lList unitstr else set parent.DLU_lChildren = remove_from_list parent.DLU_lChildren unitstr; ); ); if (obstr.PDLGL_dlgstr == nil) then nil else updateDialogSize obstr; 0;; fun addElement(obstr, parent, label, value, depth)= let mkDialogListUnit[nil label value depth nil] -> newunit in ( if parent == nil then set obstr.PDLGL_lList = lcat obstr.PDLGL_lList newunit::nil else set parent.DLU_lChildren = lcat parent.DLU_lChildren newunit::nil; if obstr.PDLGL_dlgstr == nil then nil else let VUIaddListElement obstr.PDLGL_liststr parent.DLU_element label value 1 -> newelem in ( set newunit.DLU_element = newelem; if (!obstr.PDLGL_bUnfold || parent == nil) then nil else VUIunfoldListElement parent.DLU_element 1; ); newunit; );; fun cbAddElement(inst, from, action, param, reply, obstr)= if (param == nil) then nil else let lineextr param -> lparam in let hd lparam -> name in let strtrim linebuild tl lparam -> value in let 0 -> start in let 0 -> depth in let nil -> parent in ( let strfind2List name ">" 0 -> poslist in while (poslist != nil) do ( let hd poslist -> end in let strtrim (substr name start (end - start)) -> label in let if parent == nil then obstr.PDLGL_lList else parent.DLU_lChildren -> list in let findUnitInList list label -> unitstr in ( if unitstr == nil then set parent = addElement obstr parent label "" depth else set parent = unitstr; set depth = depth + 1; set start = end + 1; ); set poslist = tl poslist; ); let strtrim (substr name start ((strlen name) - start)) -> label in addElement obstr parent label value depth; ); if (obstr.PDLGL_dlgstr == nil) then nil else updateDialogSize obstr; 0;; fun cbClickDlg(dlgstr, state, obstr)= set obstr.PDLGL_dlgstr = nil; SendPluginEvent obstr.PDLGL_instance "Selected label" obstr.PDLGL_selected.VUILE_sValue nil; SendPluginEvent obstr.PDLGL_instance "Selected value" obstr.PDLGL_selected.VUILE_sParam nil; SendPluginEvent obstr.PDLGL_instance "Hidden" nil nil; 0;; fun cbListSelect(liststr, lselected, obstr)= let hd lselected -> selectedstr in ( set obstr.PDLGL_selected = selectedstr; if obstr.PDLGL_bOkButton then nil else ( SendPluginEvent obstr.PDLGL_instance "Selected label" selectedstr.VUILE_sValue nil; SendPluginEvent obstr.PDLGL_instance "Selected value" selectedstr.VUILE_sParam nil; ); ); 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.DLU_sLabel unitstr.DLU_sValue 1 -> newelem in ( set unitstr.DLU_element = newelem; fillList liststr newelem unitstr.DLU_lChildren unfold; if (!unfold || newelem.VUILE_children == nil) then nil else VUIunfoldListElement newelem 1; ); set lunits = tl lunits; ); 0;; fun createDialog(param, obstr, show)= let V3DgetSessionView c3dXsession -> viewstr in let VUIgetThemeDef (getThemeFromInstance obstr.PDLGL_instance) "dialogBox" -> defstr in let VUIgetFontFromInterface VUIgetThemeFont defstr "label" -> lbfontstr in let if (strcmpi obstr.PDLGL_sTitle "") == 0 then nil else obstr.PDLGL_sTitle -> title in let if (obstr.PDLGL_bOkButton) then loc "OS3DDLIST_C0001" else nil -> okbutton in let getWidth obstr obstr.PDLGL_lList lbfontstr -> width in let 200 -> height in let VUIcreateDialogExt viewstr (getVUIgroupFromInstance obstr.PDLGL_instance) [width height] title okbutton nil obstr.PDLGL_iOpacity (V3DgetVrMode viewstr) (mkfun3 @cbClickDlg obstr) (hd obstr.PDLGL_lthemeelts) -> dlgstr in let VUIgetDialogFrame dlgstr -> framestr in let VUIgetElementContainer framestr -> contstr in let VUIcreateListExt contstr framestr [0.0 0.0] [100.0 100.0] [0 0 1 1 0 0 0 0] [0 0] [5 5] obstr.PDLGL_bMultiselect obstr.PDLGL_tChildOffset (hd tl obstr.PDLGL_lthemeelts) -> liststr in ( fillList liststr nil obstr.PDLGL_lList obstr.PDLGL_bUnfold; VUIsetListCbSelect liststr mkfun3 @cbListSelect obstr; let if (!strcmp "" (strtrim param)) || param == nil then getAlign obstr.PDLGL_sPos else getAlign param -> [pos align] in VUIsetContainerPos contstr pos align nil; set obstr.PDLGL_dlgstr = dlgstr; set obstr.PDLGL_liststr = liststr; set obstr.PDLGL_selected = nil; VUIsetContainerThemeCallback contstr mkfun2 @cbDlgThemeUpdate obstr; VUIsetContainerClear contstr 0; updateDialogSize obstr; VUIsetContainerFadeSpeed obstr.PDLGL_dlgstr.VUIDLG_container obstr.PDLGL_iFadeSpeed; VUIshowContainerBase obstr.PDLGL_dlgstr.VUIDLG_container show; ); 0;; fun cbVrChange(inst, viewstr, state, obstr)= if obstr.PDLGL_dlgstr == nil then nil else ( VUIdestroyDialogBox obstr.PDLGL_dlgstr; createDialog nil obstr 1; ); 0;; fun cbCameraTeleport(inst, viewstr, camera, obstr)= if obstr.PDLGL_dlgstr == nil then nil else ( VUIdestroyDialogBox obstr.PDLGL_dlgstr; createDialog nil obstr 1; ); 0;; fun cbDialogVisibility(contstr, state, obstr)= if (state) then nil else ( VUIdestroyDialogBox obstr.PDLGL_dlgstr; setPluginInstanceCbResizeView obstr.PDLGL_instance nil; set obstr.PDLGL_dlgstr = nil; ); SendPluginEvent obstr.PDLGL_instance if (state) then "Shown" else "Hidden" nil nil; 0;; fun cbShow(inst, from, action, param, reply, obstr)= if obstr.PDLGL_dlgstr == nil then nil else VUIdestroyDialogBox obstr.PDLGL_dlgstr; createDialog param obstr 0; VUIshowContainerExt obstr.PDLGL_dlgstr.VUIDLG_container 1 mkfun3 @cbDialogVisibility obstr; 0;; fun cbHide(inst, from, action, param, reply, obstr)= VUIshowContainerExt obstr.PDLGL_dlgstr.VUIDLG_container 0 mkfun3 @cbDialogVisibility obstr; 0;; fun cbClearList(inst, from, action, param, reply, obstr)= VUIclearList obstr.PDLGL_liststr; set obstr.PDLGL_lList = nil; if (obstr.PDLGL_dlgstr == nil) then nil else updateDialogSize obstr; 0;; fun loadList(obstr, type, suffix)= let if suffix == nil then "" else suffix -> suffix in let if type == nil then 0 else type -> type in let nil -> list in let 0 -> i in let 0 -> end in ( while end != 1 do ( let (strcatn suffix::"_"::(itoa i)::nil) -> newsuffix in let getPluginInstanceParam obstr.PDLGL_instance strcat "label" newsuffix -> label in let getPluginInstanceParam obstr.PDLGL_instance strcat "value" newsuffix -> value in if label == nil then set end = 1 else ( let loadList obstr (type + 1) newsuffix -> lchildren in let mkDialogListUnit [nil label value type lchildren] -> newUnit in set list = newUnit::list; 0; ); set i = i + 1; ); revertlist list; );; fun newOb(inst)= let getPluginInstanceParam inst "title" -> title in let if title == nil then "" else title -> title in let atoi (getPluginInstanceParam inst "okbtn") -> okbtn in let if (okbtn == nil) then 1 else okbtn -> okbtn in let atoi (getPluginInstanceParam inst "levelxoffset") -> levelxoffset in let if (levelxoffset == nil) then 10 else levelxoffset -> levelxoffset in let atoi (getPluginInstanceParam inst "levelyoffset") -> levelyoffset in let if (levelyoffset == nil) then 0 else levelyoffset -> levelyoffset in let atoi (getPluginInstanceParam inst "unfold") -> unfold in let if (unfold == nil) then 0 else unfold -> unfold in let loadThemeEltSelectorValues inst "dialogBox"::"list"::nil -> lthemeelts 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 atoi (getPluginInstanceParam inst "opacity") -> opacity in let if (opacity == nil) then 100 else opacity -> opacity in let atoi (getPluginInstanceParam inst "fadespeed") -> fadespeed in let if (fadespeed == nil) then 0 else fadespeed -> fadespeed in //let atoi (getPluginInstanceParam inst "multiselect") -> multiselect in //let if (multiselect == nil) then 0 else multiselect -> multiselect in let atoi (getPluginInstanceParam inst "show") -> show in let if (show == nil) then 1 else show -> show 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 mkPlugDialogList [inst nil nil nil nil lthemeelts title okbtn [levelxoffset levelyoffset] unfold (strcatn vpos::" "::hpos::nil) opacity fadespeed /*multiselect*/ 0] -> obstr in ( set obstr.PDLGL_lList = loadList obstr nil nil; 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 "Set title" mkfun6 @cbSetTitle obstr; PluginRegisterAction inst "Add element to list" mkfun6 @cbAddElement obstr; PluginRegisterAction inst "Remove element from list" mkfun6 @cbRemoveElement obstr; PluginRegisterAction inst "Clear" mkfun6 @cbClearList obstr; setPluginInstanceCbVrModeChanged inst mkfun4 @cbVrChange obstr; setPluginInstanceCbCameraTeleport inst mkfun4 @cbCameraTeleport obstr; setPluginInstanceCbDel inst mkfun2 @deleteOb obstr; ); 0;; fun IniPlug(file)= VUIsetEnable c3dXsession 1; PlugRegister @newOb nil; setPluginEditor @dynamicedit; 0;;