/* ----------------------------------------------------------------------------- This source file is part of OpenSpace3D For the latest info, see http://www.openspace3d.com Copyright (c) 2018 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 InterfaceChatUser = [ ICU_element : VUIListElement, ICU_sLabel : S, ICU_uID : S, ICU_sBuffer : S ] mkInterfaceChatUser;; struct PlugInterfaceChat = [ PIC_instance : PInstance, PIC_netcomm : NetComm, PIC_contstr : VUIcontainer, PIC_liststr : VUIList, PIC_inputstr : VUIelement, PIC_display : VUIelement, PIC_lList : [InterfaceChatUser r1], PIC_posstr : InterfacePos, PIC_sBuffer : S, PIC_lastSelectedUser : InterfaceChatUser, PIC_bState : I ]mkPlugInterfaceChat;; fun deleteOb(inst, obstr)= VUIdestroyContainer obstr.PIC_contstr; 0;; fun findUnitInList(l, label)= if (l == nil) || (label == nil) then nil else ( let hd l -> uidstr in if (!strcmpi uidstr.ICU_sLabel label) then uidstr else findUnitInList tl l label; );; fun findUnitInListWithuID(l, uID)= if (l == nil) || (uID == nil) then nil else ( let hd l -> uidstr in if (!strcmpi uidstr.ICU_uID uID) then uidstr else findUnitInList tl l uID; );; fun cbListSelectElement(leltstr, p)= let p -> [obstr uidstr] in let leltstr.VUILE_element -> eltstr in if ((hd obstr.PIC_liststr.VUIL_lSelected) != uidstr.ICU_element) || (eltstr.VUIE_iCheckState) then nil else ( set eltstr.VUIE_resource.VUIR_iCurCol = 1; VUIelementNeedUpdate eltstr 0; ); 0;; fun addUserInList(obstr, uidstr)= if (obstr.PIC_contstr == nil) then nil else let VUIaddListElement obstr.PIC_liststr nil uidstr.ICU_sLabel nil 1 -> newelem in ( set uidstr.ICU_element = newelem; set newelem.VUILE_element.VUIE_Text.VUIT_tMargin = [2 2]; VUIsetListElementCbSelect newelem mkfun2 @cbListSelectElement [obstr uidstr]; if (obstr.PIC_liststr.VUIL_lSelected != nil) then nil else ( VUIsetElementCheckState newelem.VUILE_element 1; set obstr.PIC_lastSelectedUser = uidstr; ); ); 0;; fun addUser(obstr, uidstr)= set obstr.PIC_lList = uidstr::obstr.PIC_lList; addUserInList obstr uidstr; 0;; fun addChatText(obstr, text, stream)= let hd obstr.PIC_liststr.VUIL_lSelected -> selectelt in let findUnitInList obstr.PIC_lList selectelt.VUILE_sValue -> suidstr in ( if ((sizelist (strextr obstr.PIC_sBuffer)) < 200) then nil else set obstr.PIC_sBuffer = ""; if (!stream) then set obstr.PIC_sBuffer = strcatn obstr.PIC_sBuffer::text::"\n"::nil else set obstr.PIC_sBuffer = strcat obstr.PIC_sBuffer text; // update text display if ((atoi suidstr.ICU_uID) != -1) then nil else ( VUIsetElementTextContent obstr.PIC_display obstr.PIC_sBuffer; VUIupdateElement (VUIgetElementContainer obstr.PIC_display) obstr.PIC_display; VUIscrollText obstr.PIC_display (-1000); ); ); 0;; fun addChatPrivateText(obstr, uidstr, text)= if ((sizelist (strextr uidstr.ICU_sBuffer)) < 200) then nil else set uidstr.ICU_sBuffer = ""; set uidstr.ICU_sBuffer = strcatn uidstr.ICU_sBuffer::text::"\n"::nil; // update text display let hd obstr.PIC_liststr.VUIL_lSelected -> selectelt in let findUnitInList obstr.PIC_lList selectelt.VUILE_sValue -> suidstr in ( if (suidstr != uidstr) then ( let _checkpack strcatn (getPluginDirectory (getInstancePlugin obstr.PIC_instance))::"/res/"::"notification.png"::nil -> respath in VUImakeResource uidstr.ICU_element.VUILE_element nil nil nil respath VUI_ResSplited 1 2 nil nil; 0; ) else ( VUIsetElementTextContent obstr.PIC_display uidstr.ICU_sBuffer; VUIupdateElement (VUIgetElementContainer obstr.PIC_display) obstr.PIC_display; VUIscrollText obstr.PIC_display (-1000); 0; ); ); 0;; fun cbLoginChanged(inst, netstr, userstr, newlogin, obstr)= let netUserGetLogin userstr -> login in if (!strcmp login newlogin) then nil else ( addChatText obstr strcatn login::" >> "::newlogin::nil 0; let findUnitInList obstr.PIC_lList login -> uidstr in if (uidstr == nil) then nil else ( set uidstr.ICU_sLabel = newlogin; let VUIgetListElement obstr.PIC_liststr login -> lestr in ( /*if (lestr == nil) then addLogMessage strcat "Not found : " login else addLogMessage "Found!";*/ VUIrenameListElement lestr newlogin; ); ); ); 0;; fun cbAddUser(inst, netstr, userstr, obstr)= if (userstr == (netThisUser netstr)) then nil else let netUserGetLogin userstr -> login in ( addChatText obstr strcatn ">> "::login::" "::(loc "OS3DINTERFACECHAT_0003")::nil 0; let itoa netUserGetId userstr -> id in let mkInterfaceChatUser[nil login id ""] -> uidstr in addUser obstr uidstr; ); 0;; fun cbDelUser(inst, netstr, userstr, obstr)= let netUserGetLogin userstr -> login in ( addChatText obstr strcatn ">> "::login::" "::(loc "OS3DINTERFACECHAT_0004")::nil 0; let findUnitInList obstr.PIC_lList login -> uidstr in if (uidstr == nil) then nil else ( if (obstr.PIC_contstr == nil) then nil else VUIremoveListElement uidstr.ICU_element; set obstr.PIC_lList = remove_from_list obstr.PIC_lList uidstr ); ); 0;; fun cbRoomChanged(inst, netstr, room, obstr)= addChatText obstr strcatn (loc "OS3DINTERFACECHAT_0043")::" "::(netThisLogin netstr)::" "::(strcat (loc "OS3DINTERFACECHAT_0005") " ")::room::"."::nil 0; 0;; fun cbDisconnected(inst, netstr, obstr)= if(!obstr.PIC_bState) then nil else addChatText obstr strcatn "<<< "::(loc "OS3DINTERFACECHAT_0007")::nil 0; set obstr.PIC_bState = 0; 0;; fun cbSConnected(inst, netstr, obstr)= set obstr.PIC_bState = 1; addChatText obstr strcatn "<<< "::(loc "OS3DINTERFACECHAT_0008")::nil 0; 0;; fun cbGetMessage(inst, from, action, param, reply, obstr)= if (param == nil) || (!strcmp (strtrim param) "") then nil else addChatText obstr param 0; 0;; fun cbGetStreamMessage(inst, from, action, param, reply, obstr)= if (param == nil) || (!strcmp (strtrim param) "") then nil else addChatText obstr param 1; 0;; fun cbGetPrivateMessage(inst, from, action, param, reply, obstr)= let strfind " " param 0 -> pos in let substr param 0 pos -> uid in let findUnitInListWithuID obstr.PIC_lList uid -> uidstr in let substr param pos + 1 ((strlen param) - pos) -> message in ( addChatPrivateText obstr uidstr message; ); 0;; fun cbDisplayMessage(inst, from, action, param, reply, obstr)= addChatText obstr param 0; 0;; fun cbDisplayStreamMessage(inst, from, action, param, reply, obstr)= addChatText obstr param 1; 0;; fun cbListSelect(liststr, lselected, obstr)= let hd lselected -> selectelt in let findUnitInList obstr.PIC_lList selectelt.VUILE_sValue -> uidstr in ( if ((atoi uidstr.ICU_uID) == -1) then ( VUIsetElementTextContent obstr.PIC_display obstr.PIC_sBuffer; 0; ) else ( VUIsetElementTextContent obstr.PIC_display uidstr.ICU_sBuffer; let uidstr.ICU_element.VUILE_element -> eltstr in let VUIgetThemeDef (getThemeFromInstance obstr.PIC_instance) "list" -> defstr in ( VUIsetElementTheme uidstr.ICU_element.VUILE_element defstr "listElementCheck"; set eltstr.VUIE_resource.VUIR_iCurCol = 1; VUIelementNeedUpdate eltstr 0; ); 0; ); if (obstr.PIC_lastSelectedUser == nil) || (obstr.PIC_lastSelectedUser == uidstr) then nil else let obstr.PIC_lastSelectedUser.ICU_element.VUILE_element -> eltstr in if (!eltstr.VUIE_resource.VUIR_iCurCol) then nil else ( set eltstr.VUIE_resource.VUIR_iCurCol = 0; VUIelementNeedUpdate eltstr 0; ); set obstr.PIC_lastSelectedUser = uidstr; ); VUIupdateElement (VUIgetElementContainer obstr.PIC_display) obstr.PIC_display; VUIscrollText obstr.PIC_display (-1000); 0;; fun cbValidate(eltstr, val, state, obstr)= if (!state) then nil else ( let hd obstr.PIC_liststr.VUIL_lSelected -> selectelt in let findUnitInList obstr.PIC_lList selectelt.VUILE_sValue -> uidstr in let if ((uidstr == nil) || ((atoi uidstr.ICU_uID) == -1)) then 0 else 1 -> private in let if (obstr.PIC_netcomm.NC_status == iStatusDisconnected) then (_getress "DefaultName") else "%login%" -> login in if (!private && (strcmp val "") && (val != nil)) then ( if (!strcmp "/" (substr val 0 1)) then ( SendPluginEvent obstr.PIC_instance "Command" (substr val 1 ((strlen val) - 1)) nil; SendPluginEvent obstr.PIC_instance "Message" strcatn login::" << "::(substr val 1 ((strlen val) - 1))::nil nil; ) else ( SendPluginEvent obstr.PIC_instance "Message" strcatn login::" > "::val::nil nil; SendPluginEvent obstr.PIC_instance "Text" val nil; ); ) else if (private && (strcmp val "") && (val != nil)) then ( let uidstr.ICU_uID -> uid in let netGetUserById obstr.PIC_netcomm (atoi uid) -> duser in if (!strcmp "/" (substr val 0 1)) then ( SendPluginEvent obstr.PIC_instance "Command" (substr val 1 ((strlen val) - 1)) nil; if (duser == nil) then nil else ( addChatPrivateText obstr uidstr strcatn (netThisLogin obstr.PIC_netcomm)::" << "::(substr val 1 ((strlen val) - 1))::nil; SendPluginEvent obstr.PIC_instance "PrivateMessage" strcatn uid::" "::login::" << "::(substr val 1 ((strlen val) - 1))::nil nil; 0; ); ) else ( if (duser != nil) then ( addChatPrivateText obstr uidstr strcatn (netThisLogin obstr.PIC_netcomm)::" > "::val::nil; SendPluginEvent obstr.PIC_instance "PrivateMessage" strcatn uid::" "::login::" > "::val::nil nil; SendPluginEvent obstr.PIC_instance "Text" val nil; 0; ) else ( addChatPrivateText obstr uidstr strcatn "<<< "::(loc "OS3DINTERFACECHAT_0006")::nil; 0; ); ); ) else nil; VUIsetElementTextContent eltstr ""; ); 0;; fun fillList(liststr, l, obstr)= if (l == nil) then nil else ( let hd l -> uidstr in addUserInList obstr uidstr; fillList liststr (tl l) obstr; ); 0;; fun cbShow(inst, from, action, param, reply, obstr)= VUIshowContainer obstr.PIC_contstr 1; if (obstr.PIC_posstr.IP_iMode != 3) then nil else let obstr.PIC_posstr.IP_posvrstr -> posvrstr in VUIrefreshVrContainerPosition c3dXsession obstr.PIC_contstr posvrstr.IPVR_tSize posvrstr.IPVR_fScale posvrstr.IPVR_iZorder; SendPluginEvent inst "Shown" nil nil; 0;; fun cbHide(inst, from, action, param, reply, obstr)= VUIshowContainer obstr.PIC_contstr 0; SendPluginEvent inst "Hidden" nil nil; 0;; fun createGui(inst, obstr)= set obstr.PIC_contstr = crInterfacePosContainer inst obstr.PIC_posstr c3dXsession; let VUIgetThemeDef (getThemeFromInstance obstr.PIC_instance) "common" -> defstr in let VUIgetThemeFont defstr "label" -> lbfontstr in let VUIcreateList obstr.PIC_contstr nil [5.0 5.0] [140.0 100.0] [0 0 0 1 0 0 0 (-10)] [0 0] [5 5] 0 nil -> liststr in let VUIcreateFrame obstr.PIC_contstr nil [150.0 5.0] [100.0 100.0] [0 0 1 1 0 0 (-155) (-45)] [0 0] -> txtstr in let VUIcreateEditText obstr.PIC_contstr nil [150.0 5.0] [100.0 30.0] [0 0 1 0 0 0 (-155) 0] [0 2] nil [0 0] "" 0 -> editstr in ( fillList liststr obstr.PIC_lList obstr; VUIsetListCbSelect liststr mkfun3 @cbListSelect obstr; VUIsetElementTheme txtstr defstr "background"; VUIsetElementText txtstr lbfontstr obstr.PIC_sBuffer [0 0] [0 0] [5 5] iVUITEXT_HALIGNLEFT|iVUITEXT_VALIGNTOP VUI_TextStatic 1; VUIsetElementCbValidate editstr mkfun4 @cbValidate obstr; set obstr.PIC_liststr = liststr; set obstr.PIC_inputstr = editstr; set obstr.PIC_display = txtstr; ); 0;; fun cbVrChange(inst, viewstr, state, obstr)= if obstr.PIC_contstr == nil then nil else ( VUIdestroyContainer obstr.PIC_contstr; createGui inst obstr; ); 0;; fun newOb(inst)= let atoi (getPluginInstanceParam inst "init") -> oninit in let loadInterfacePos inst c3dXsession -> posstr in let mkPlugInterfaceChat[inst netcomOS3D nil nil nil nil nil posstr "" nil 0] -> obstr in ( createGui inst obstr; if !oninit then nil else cbShow inst nil nil nil nil obstr; let mkInterfaceChatUser[nil "ALL" "-1" ""] -> uidstr in ( set obstr.PIC_lList = lcat obstr.PIC_lList uidstr::nil; if (obstr.PIC_contstr == nil) then nil else addUserInList obstr uidstr; ); setPluginInstanceCbNetUserChangeLogin inst mkfun5 @cbLoginChanged obstr; setPluginInstanceCbNetRoomChanged inst mkfun4 @cbRoomChanged obstr; setPluginInstanceCbNetSConnected inst mkfun3 @cbSConnected obstr; setPluginInstanceCbNetClosed inst mkfun3 @cbDisconnected obstr; setPluginInstanceCbNetNewUser inst mkfun4 @cbAddUser obstr; setPluginInstanceCbNetDelUser inst mkfun4 @cbDelUser obstr; //setPluginInstanceCbVrModeChanged inst mkfun4 @cbVrChange obstr; PluginRegisterAction inst "Get message" mkfun6 @cbGetMessage obstr; PluginRegisterAction inst "Get stream message" mkfun6 @cbGetStreamMessage obstr; PluginRegisterAction inst "Get private message" mkfun6 @cbGetPrivateMessage obstr; PluginRegisterAction inst "Display message" mkfun6 @cbDisplayMessage obstr; PluginRegisterAction inst "Display stream message" mkfun6 @cbDisplayStreamMessage obstr; PluginRegisterAction inst "Show" mkfun6 @cbShow obstr; PluginRegisterAction inst "Hide" mkfun6 @cbHide obstr; setPluginInstanceCbDel inst mkfun2 @deleteOb obstr; SendPluginEvent inst "Loaded" nil nil; ); 0;; fun IniPlug(file)= VUIsetEnable c3dXsession 1; PlugRegister @newOb nil; setPluginEditor @dynamicedit; 0;;