/* Plugin term3d - version 1.0 - part Client */ /* by iri : info@irizone.net - 02/2004 */ /* by iri : info@irizone.net - rev. 05/2004 */ /* by iri : info@irizone.net - rev. 08/2004 */ /* Licence : Cette création est mise à disposition selon le Contrat Paternité - Partage des Conditions Initiales à l'Identique disponible en ligne http://creativecommons.org/licenses/by-sa/2.0/fr/deed.fr ou par courrier postal à Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA. */ /* limitations / bugs : - longueur max des messages saisis dépend de la largeur attribuée à l'affichage du term3d et de la taille des caractères utilisées, l'affichage ne sera donc pas forcément identique si deux clients ont des tailles et/ou des types de font différents. - l'affichage de l'historique ancien n'est pas encore parfait (page up/down) mais il est amélioré - l'affichage des smileys n'est pas ultra précise : devrait se faire en fonction de la taille de la police + séparation de la phrase en morceau avec le smiley entre ? - l'optimisation du code */ /* corrections / ajouts (05/2004) : - divers corrections et changements (08/04) - passerelle avec le ColorTerm (08/04) - compatibilité avec le dynEditor (menu conectuel) (08/04) - pas de déplacement involontaire lors d'un clic dans le menu contextuel (08/04) - absence de menu contextuel si la souris pointe sur un avatar (08/04) - ajout d'un espace après un smiley pour éviter que la lettre suivante ne le colle (08/04) - affichage automatique de smileys (si l'user le désire) - gestion des URLs (http:// ou scol://) [juin 2004] - correction du transfert de la couleur du dernier client enregistré. - ajout de l'item personnalisé du menu contextuel - interface transparente ou non - affichage des liens (objets 3d ou autres avatars) - le pseudo cliqué change de couleur - scroll sur la liste des avatars - le clic sur un pseudo dirige l'avatar vers ce dernier - ajout du pseudo "Away/Back" - ajout de la liste des avatars - fonctions Ignore ajoutées - le client peut changer la position et la taille du term (si cette possibilité a été validée dans l'éditeur) - affichage en mode fullscreen peut être différent qu'en mode fenêtré (position du term, cf FSbottom) - si le message saisi ne peut tenir sur une ligne, celui-ci est coupé automatiquement - le pseudo ne peut pas être effacé lors de la saisie (touche backspace) - event 'log' corrigé - historique accessible sur 'maxHistoric' (50) lignes : touche page up/down - le choix des couleurs est sauvé dans un fichier du Cache client : la couleur est ainsi retrouvé de site en site et de cellule 3d en cellule 3d - intégration avec globalTerm3d - gestion des caractères spéciaux - prise en compte de la backspace (supprime le dernier caractère saisi) - correction de l'invisibilité des privateMsg venus par lien (module.action => c3d.term3d.privateMsg) : affichage en couleur par défaut (D_color) */ /* La transparence s'effectue sur la couleur NOIRE (0) automatiquement ie si la transparence est activée, les différents fond de l'interface seront noirs autrement, la couleur de fond de scène ('cel.Cel3dback') est appliquée */ /*** ordre des blocs dans ce fichier : - déclarations - initialisation de variables - miscellaneous - gestion des smileys - gestion de la liste des avatars présents - affichage des liens dans la 3d par le plugin - fenêtre d'aide - fonctions de gestion des macros - couleur des message envoyés par le client - taille et type de la font choisie par le client - configuration de la position et de la taille du term3d par le client - enregistrement du chat sur le HD - fonctions 'Ignore' - gestion des URLs - gestion du Term 3d - création et gestion du menu contextuel - callbacks plugin - gestion du plugin ***/ /* Touches clavier (KEYBOARD) : TAB : show / hide ENTER : send text SUPPR : change color BACKSPACE : backspace ARROWS : not used in the Term3d (used to move in the view 3d) PAGE DOWN/UP : scroll historique HOME : Help END : Configuration Term3d INSER : config macros F1 <-> F9 : macros */ /* CLAVIER AZERTY : (QWERTY ?) - pause break : 65299 - scroll lock : 65300 - escape (ESC): 65307 - HOME : 65360 - arrow LEFT : 65361 - arrow UP : 65362 - arrow RIGHT : 65363 - arrow DOWN : 65364 - page UP : 65365 - page DOWN : 65366 - end : 65367 - inser : 65379 - verr. num : 65407 - F1 to F9 : 65470 to 65478 - CAPS LOCK : 65509 - SUPPR : 65535 - F10 to F12 : / - Print : / - SHIFT : / cf '_keybdstate' in the Scol language - CTRL : / cf '_keybdstate' in the Scol language - ALT : / cf '_keybdstate' in the Scol language - others : ASCII code */ /* see 'util.pkg', in same directory */ typeof plugin = S;; typeof class = S;; typeof font = ObjFont;; /* font du term */ typeof fontAv = ObjFont;; /* font de la liste des avatars présents dans la cellule 3d */ typeof message = S;; /* message saisi lettre par lettre */ typeof messageTerm = [S r1];; /* historique affichée (la taille de la liste dépend de la hauteur défini dans l'éditeur) */ typeof historic = [S r1];; /* historique complet */ typeof color = I;; /* couleur des messages envoyés par le client */ typeof cliColor = [[S I] r1];; /* liste des correspondances entre login S et couleur I */ typeof menu = ObjMenu;; /* menu contextuel */ typeof menuSave = ObjMenuItem;; /* item menu : enregistrement ou non des messages */ typeof menuAway = ObjMenuItem;; /* item menu : mise en absence par le visiteur */ typeof menuTrans = ObjMenuItem;; /* item menu : transparence */ typeof menuURL = ObjMenuItem;; /* item menu : ouvre les URLs automatiquement ou pas */ typeof menuSmileys = ObjMenuItem;; /* item menu : affiche les smileys ou pas */ typeof specialKey = [[I I] r1];; /* key (touche clavier) I action faite si la touche est enfoncée I */ typeof myMacros = [S r1];; /* macros */ typeof macro = ObjText;; typeof pathSaveFile = S;; /* path du chat enregistré : fileSave + jour mois année _ heure minute seconde */ typeof FSbottom = I;; /* si 1 alors le term doit toujours resté à la même distance du bas de la 3d (mode fullscreen) */ typeof ChgCliSize = I;; /* si 1 le client peut changer la position et la taille du term (dans certaine limite) */ typeof displayLinks = I;; /* le plug gère ou non l'affichage des liens dans la 3d */ typeof transparence = I;; /* l'affichage des liens et de la liste des avatars se fait-elle sur un fond transparent (1) ou opaque (0) */ typeof defaultSize = [I I I I];; /* position et taille par défaut du term (celles définies dans l'éditeur) */ typeof ignoreList = [S r1];; /* liste des pseudos à ignorer */ typeof displayAvList = I;; /* affiche (1) ou pas (0) la liste des avatars présents */ typeof CoordAvList = [I I I I];; /* position et taille de l'objet contenant la liste des avatars présents [x y w h] */ typeof CoordAvListDefault = [I I I I];; /* ... default (valeurs de l'éditeur) */ typeof bmpAvBG = ObjBitmap;; /* bitmap liste des avatars présents */ typeof pathBgAvTop = S;; /* path scroll up */ typeof pathBgAvDown = S;; /* path scroll down */ typeof colorAv = I;; /* couleur d'affichage des pseudos et des liens (couleur par défaut définie dans l'éditeur */ typeof colorAvHilite = I;; /* couleur de mise en évidence du pseudo cliqué */ typeof cpteurAv = I;; /* compteur pour l'affichage des pseudos */ typeof listCelAv = [S r1];; /* liste des pseudos présents dans la cellule 3d */ typeof bmpLinksBG = ObjBitmap;; /* bitmap affichage du lien 3d */ typeof displayAvListInit = I;; /* affiche ou pas la liste des avatars (valeur initiale) */ typeof displayCustomItem = I;; /* présence ou non d'un item personnalisé dans le menu contextuel */ typeof nameCustomItem = S;; /* nom de l'item personnalisé du menu contextuel */ typeof lSmileys = [S r1];; /* liste des smileys */ typeof lMsgSmileys = [[S I I I] r1];; /* liste des smileys à insérer et leurs positions respectives pour chaque ligne */ typeof lSmileyDisplayed = [ObjBitmap r1];; typeof TextCursorWIN = ObjCursor;; /* curseur texte windows */ typeof TextCursorMAC = ObjCursor;; /* curseur texte mac */ typeof idMove = I;; /* id fun callback souris move / c3d3 */ typeof idClic = I;; /* id fun callback souris clic / c3d3 */ typeof objIsAvatar = I;; /* l'objet est-il un avatar (1) ou un autre objet (0) */ var fileMacros = "locked/conf/term3d/term3dmacros.txt";; var fileColor = "locked/conf/term3d/term3dcolor.txt";; var fileSave = "tmp/term3d/";; var premier = 0;; /* dès qu'une première touche est enfoncée passe à 1 */ var colorOpened = 0;; /* booléen pour ne pas ouvrir deux fois en même temps la fenêtre de choix de la couleur */ var bMenuSave = 0;; /* booleen : check menuSave item */ var bMenuAway = 0;; /* booleen : check menuAway item */ var maxHistoric = 50;; /* nombre de lignes de l'historique complet */ var posHistoric = 0;; /* position de la 1er ligne affichée de l'historique complet */ var useHistoric = 0;; /* 1 si les touches historiques (à l'origine Page down/up) viennent d'être utilisées 0 autrement */ var posListAv = 0;; /* position dans la liste du 1er pseudo affiché */ var nbRSC = 0;; /* nombre de ressources téléchargées */ var openUrl = 1;; /* ouvre les urls saisis dans le term (1) ou pas (0) */ var setSmileys = 0;; /* smileys autorisés (1) ou pas (0) */ var ENterm3d = 1;; /* enable (1) ou disable (0) le tchat et le menu contextuel */ struct Tdata = [ D_posX : I, /* X position of the term3d */ D_posY : I, /* Y position of the term3d */ D_width : I, /* width of the term3d */ D_heigth : I, /* heigth of the term3d */ D_font : S, /* name of font */ D_size : I, /* fontSize */ D_type : I, /* fontType */ D_color : I, /* fontColor (default value) */ D_onoff : I, /* term3d shown / hidden */ D_fond : ObjBitmap /* background bitmap (fixed) */ ] mkData;; /***********************/ /* Debuggage (inactif) */ /***********************/ /* fun [[[S I] r1]] S */ fun testClicolor(ll)= if ll == nil then _fooS strcat ">>>clicolor>>>_" "nil" else let ll -> [[login col] q] in (_fooS strcatn ">>>clicolor>>>_"::login::"__"::(itoa col)::"_"::nil; testClicolor q);; /*******************************/ /* Initialisation de variables */ /*******************************/ /* initialise les actions en fonctions des touches initialise les macros */ fun initKey()= let lineextr _getpack _checkpack fileMacros -> l in if l == nil then set myMacros = (_loc this "term3d_macro1" nil):: (_loc this "term3d_macro2" nil):: (_loc this "term3d_macro3" nil):: (_loc this "term3d_macro4" nil):: (_loc this "term3d_macro5" nil):: (_loc this "term3d_macro6" nil):: (_loc this "term3d_macro7" nil):: (_loc this "term3d_macro8" nil):: (_loc this "term3d_macro9" nil):: nil else set myMacros = l; set specialKey = [13 1]:: /* retour chariot / entrer */ [9 2]:: /* tab */ [8 3]:: /* backspace */ [65535 4]:: /* suppr */ [65361 5]:: /* left */ [65362 5]:: /* up */ [65363 5]:: /* right */ [65364 5]:: /* down */ [65379 7]:: /* inser */ [65470 6]:: /* F1 -> */ [65471 6]:: [65472 6]:: [65473 6]:: [65474 6]:: [65475 6]:: [65476 6]:: [65477 6]:: [65478 6]:: /* -> F9 */ [65360 8]:: /* home */ [65367 11]:: /* end */ [65365 9]:: /* page up */ [65366 10]:: /* page down */ [65407 5]:: [65307 5]:: [65300 5]:: [65299 5]:: [65409 5]:: nil;; /* teste si le dossier d'enregistrement ne devient pas lourd ( > 10 Mo) et envoie un message au client le cas échéant */ /* function not used */ fun testCache()= let _listoffiles fileSave -> l in let sizelist l -> size in let 0 -> i in let 0 -> SIZE in ( while i <= size do (set SIZE = SIZE + (_fileSize _checkpack nth_list l i); set i = i+1); if SIZE > (10 * 1024 * 1024) then (_DLGMessageBox _channel w3d.V3dwin "Avertissement" strcat (_loc this "term3d_alertCache" nil) fileSave 0; 0) else 0);; /******************/ /* Divers (MISC.) */ /******************/ /* k -> I key I <- action */ fun searchKey(k, i)= if i <= (sizelist specialKey) then let nth_list specialKey i -> [n action] in if k == n then action else searchKey k i+1 else 0;; /* ll -> [[S I] r1] p -> [S r1] new login :: old login not used <- */ /* Remplace l'ancien login par le nouveau */ fun myreplace_login_in_listC(ll, p)= let lineextr p -> [newLogin[oldLogin _]] in if ll == nil then nil else let ll -> [[login c] q] in if !strcmp oldLogin login then set cliColor = myreplace_in_list cliColor [oldLogin c] [newLogin c] else myreplace_login_in_listC q p;; /* conversion des valeurs relatives en valeurs absolues */ fun convertPourCent(z)= let getView3dSize w3d -> [w3 h3] in let if z.D_width > 100 then w3 else (z.D_width * w3)/100 -> w in let if z.D_heigth > 100 then h3 else (z.D_heigth * h3)/100 -> h in ( set z.D_width = w; set z.D_heigth = h );; /* cherche le dernier / d'une chaîne et retourne sa position+1 */ /* fun [S I] I */ fun searchSlash(string, pos)= let strfind "/" string pos -> r in if r != nil then searchSlash string r+1 else pos;; /* recherche si le plugin DynEditor est intégré au c3d3 */ fun searchDynEd(list, name)= if list == nil then 0 else let list -> [plug suite] in if !strcmp name (PLUG_GetClass plug) then 1 else searchDynEd suite name;; /* retourne le login dans une contribution reçue */ fun searchLogin(string)= let strfind ">" string 1 -> r in substr string 1 r-1;; /* détruit une liste de bitmap */ fun dsBmp(l)= if l == nil then 0 else ( _DSbitmap hd l; dsBmp tl l );; /***********************/ /* Gestion des smileys */ /***********************/ /*** fun calcPosSmiley(n)= fun [S] I;; détermine la position horizontale du smiley en fonction du nombre de caractères le précédent fun calcWidthSmiley(bmp)= fun [ObjBitmap] I;; détermine la largeur du bitmap passé en argument fun extractSmileyLine(m, i, z, c)= fun [S I TData I] I;; ajoute au bitmap global la phrase avec le smiley écrit en couleur de fond de scène (donc invisible) m : le message, i : la position du msg dans la liste messageTerm, z : la structure TData, c : la couleur dans laquelle la phrase doit être affichée fun openSmiley(o, s) = fun [Ob S] ObjBitmap;; crée le bitmap correspondant au smiley contenu dans le message fun destroySmiley(bmp) = fun [ObjBitmap] I;; détruit le bitmap précédemment crée fun getSmileyDisplayed(list, n, o, win)= fun [[S r1] I Ob ObjWin] I;; affiche les bitmaps des smileys et leur nom respectif fun cbwinSmileys(btn, u)= fun [ObjButton [ObjWin ObjCheck]] I;; fermeture avec destruction des bitmaps et sauvegarde du choix utilisateur (smileys affichés ou pas) fun displaySmileys(o)= fun [Ob] I;; création de la fenêtre des smileys fun getSmileys2(o, list, name)= fun[Ob [S r1] S] [ObjBitmap I];; donne la position du smiley dans la chaine fun getSmileys(o, name) = fun [Ob S] [ObjBitmap I];; fun searchSmileys(m, pos) = fun [S I] I;; recherche si le message contient un smiley fun endDownloadSmileys(file) = fun [S] I;; lorsque chaque fichier est téléchargé chez le client, il est ajouté à la liste fun donwloadSmileys(files, path) = fun [S S] I;; télécharge les fichiers correspondant à chaque smiley ***/ fun calcPosSmiley(s)= let _GETstringSize font s -> [w _] in w;; fun calcWidthSmiley(bmp)= let _GETbitmapSize bmp -> [w _] in w;; fun extractSmileyLine(m, i, z, c)= let lMsgSmileys -> [[name pos nchar n] suite] in if !n then let substr m 0 nchar -> m1 in let substr m nchar+(strlen name) strlen m -> m2 in (set z.D_fond = _DRAWtext z.D_fond font 5 ((z.D_size+2)*((sizelist messageTerm)-i)) 0 c m1; set z.D_fond = _DRAWtext z.D_fond font (calcPosSmiley m1) + (calcPosSmiley name) ((z.D_size+2)*((sizelist messageTerm)-i)) 0 c m2; set z.D_fond = _DRAWtext z.D_fond font calcPosSmiley m1 ((z.D_size+2)*((sizelist messageTerm)-i)) 0 cel.Cel3dback strcat name " "; set lMsgSmileys = [name pos nchar 1]::suite; 0) else 0;; fun openSmiley(o, p)= let hd UgetParam ObUi o "pathsmileys" -> path in let substr p 1 (strlen p)-2 -> s in /* enlève les espace au début et à la fin du smiley*/ if (_LDbitmap _channel _checkpack strcatn path::"/"::s::".bmp"::nil) != nil then _LDbitmap _channel _checkpack strcatn path::"/"::s::".bmp"::nil else _LDjpeg _channel _checkpack strcatn path::"/"::s::".jpg"::nil;; fun destroySmiley(bmp)= _DSbitmap bmp;; fun getSmileyDisplayed(list, n, o, win)= if list == nil then (_PAINTwindow win; 0) else let list -> [name suite] in let hd UgetParam ObUi o "pathsmileys" -> path in let if (_LDbitmap _channel _checkpack strcatn path::"/"::name::".bmp"::nil) != nil then _LDbitmap _channel _checkpack strcatn path::"/"::name::".bmp"::nil else _LDjpeg _channel _checkpack strcatn path::"/"::name::".jpg"::nil -> bmp in (_BLTbitmap win bmp 5+(mod((sizelist lSmileys)-(sizelist list)) 5)*50 (((sizelist lSmileys)-(sizelist list))/5)*45; _TXTout win font 5+(mod((sizelist lSmileys)-(sizelist list)) 5)*50 25+(((sizelist lSmileys)-(sizelist list))/5)*45 0 0 name; set lSmileyDisplayed = bmp::lSmileyDisplayed; getSmileyDisplayed suite n o win);; fun cbwinSmileys(btn, u)= let u -> [win chSmiley] in let 0 -> i in (while i <= (sizelist lSmileyDisplayed) do let nth_list lSmileyDisplayed i -> bmp in (destroySmiley bmp; set i = i+1); set setSmileys = _GETcheck chSmiley; _DSwindow win; _SETfocus w3d.V3dwin; 0);; fun displaySmileys(o)= let sizelist lSmileys -> n in let _CRwindow _channel w3d.V3dwin 100 100 250 ((n/5)+2)*45 0 "Smileys" -> winSmileys in let _CRcheck _channel winSmileys 5 ((n/5)+1)*45 240 20 CH_LEFT|CH_DOWN (_loc this "term3d_setSmileys" nil) -> chSmiley in (getSmileyDisplayed lSmileys n o winSmileys; _SETcheck chSmiley setSmileys; _CBbutton _CRbutton _channel winSmileys 5 20+((n/5)+1)*45 240 20 0 (_loc this "term3d_close" nil) @cbwinSmileys [winSmileys chSmiley]); 0;; fun getSmileys2(o, list, name)= if list == nil then nil else let list -> [[elt pos _ _] suite] in if !strcmp elt name then [openSmiley o name pos] else getSmileys2 o suite name;; fun getSmileys(o, name)= getSmileys2 o lMsgSmileys name;; fun searchSmileys(m, z, c, pos, line)= let 0 -> i in while i <= (sizelist lSmileys) do let strcat strcat " " nth_list lSmileys i " " -> s in /* seuls les smileys indépendants sont pris en compte : ' lol ' et pas 'lola' */ let strfind s m pos -> r in (if r != nil then let substr m 0 r+2 -> m1 in (set lMsgSmileys = [s calcPosSmiley m1 r 0]::lMsgSmileys; extractSmileyLine m line z c; 0) else 0; set i = i+1);; fun endDownloadSmileys(file)= let if (strfind ".jpg" file 0) != nil then strfind ".jpg" file 0 else strfind ".bmp" file 0 -> r in let substr file 0 r -> s in let searchSlash s 0 -> poslastslash in let substr s poslastslash strlen s -> name in set lSmileys = name::lSmileys; 0;; fun donwloadSmileys(files)= let 0 -> i in while i < (sizelist files) do let nth_list files i -> file in (_RSCdownload this file file @endDownloadSmileys 1; set i = i+1);; /********************************************/ /* Gestion de la liste des avatars présents */ /********************************************/ /*** fun updatelist(o) : fun [Ob] I;; fonction appelée pour la mise à jour de la liste (nouvel arrivant, sortie, changement de pseudo, changement des paramètres ...) liste les pseudos présents dans la cellule appelle la fonction 'displayListAv'. fun addlist(o, i) : fun [Ob I] I;; détermine le pseudo de chaque avatar et l'ajoute à la liste. fun displayListAv(hilite) : fun [I] I;; fonction appelée par 'updatelist'. appelle la finction 'creaAvList' puis écrit les pseudos dont le nombre dépend de la hauteur précisée dans l'éditeur l'argument 'hilite' donne le numéro du pseudo devant être mis en évidence. fun creaAvList() : fun [] I;; fonction appellée par 'creaAvList'. détruit l'affichage actuelle et le recrée avec la bonne couleur (selon la transparence) inscrit le nombre de connectés dans la cellule intègre les boutons pour le scroll. fun clicAvUp() : fun [] I;; fun clicAvDown() : fun [] I;; l'user clique sur un des boutons de scroll. Fonction appelée par 'clicWin'. Ajoute (respectivement soustrait) une unité à la position du 1er pseudo affichée. Appelle 'displayListAv' pour le nouvel affichage. fun cliconlogin(x, y, i) : fun [I I I] I;; Fonction appelée par 'clicWin' lorsque l'user clique dans la zone d'affichage des pseudos. Détermine le numéro d'ordre du pseudo cliqué et appelle 'cbclicListAv' & 'displayListAv'. fun cbclicListAv(item) : fun [I] I;; Fonction appelée par 'cliconlogin'. Dirige l'user vers l'avatar du pseudo cliqué. fun calculCoordAvList(c) : fun [[I I I I]] idem Calcule les coord. x et y de la liste d'avatar en fonction de l'emplacement défini dans l'éditeur. ***/ fun calculCoordAvList(c)= let c -> [hautgauche basgauche w h] in let w3d.V3dsize -> [w3 h3] in let if hautgauche then 0 else w3-w -> x in let if basgauche then h3-h else 0 -> y in set CoordAvList = [x y w h];; fun creaAvList()= let CoordAvList -> [x y w h] in let _LDjpeg _channel _checkpack pathBgAvTop -> topBMP in let _LDjpeg _channel _checkpack pathBgAvDown -> downBMP in let sizeav C3DobList -> nb in ( _DSbitmap bmpAvBG; if transparence then set bmpAvBG = _FILLbitmap _CRbitmap _channel w h cel.Cel3dback else set bmpAvBG = _FILLbitmap _CRbitmap _channel w h if cel.Cel3dback == 0 then cel.Cel3dback+8 else cel.Cel3dback; _DRAWtext bmpAvBG fontAv 0 0 TD_TOP colorAv strcatn ">> "::(itoa nb)::" "::(if nb <= 1 then _loc this "term3d_PEOPLE1" nil else _loc this "term3d_PEOPLE2" nil)::nil; _CPbitmap16 bmpAvBG w-18 0 topBMP 0 0 64 18 0; _CPbitmap16 bmpAvBG w-18 h-18 downBMP 0 0 64 17 0; 0);; /* affichage de la liste des avatars présents dans la cellule 3d '14' : hauteur pour l'affichage de la ligne "nb de connectés" '13' : hauteur pour l'affichage d'un pseudo 'nbMaxDisplayed' : nb max de pseudo pouvant être affiché suivant la hauteur du bitmap (bmpAvBG) */ /* hilite -> I (ligne du pseudo cliqué) I <- 0 (non utilisée) */ fun displayListAv(hilite)= let 0 -> i in let CoordAvList -> [_ _ _ h] in let (h-14)/13 -> nbMaxDisplayed in ( set cpteurAv = posListAv; creaAvList; while i <= nbMaxDisplayed do (if i <= (sizelist listCelAv) then (if cpteurAv == hilite then _DRAWtext bmpAvBG fontAv 0 (i*13)+14 TD_TOP colorAvHilite nth_list listCelAv cpteurAv else _DRAWtext bmpAvBG fontAv 0 (i*13)+14 TD_TOP colorAv nth_list listCelAv cpteurAv; set cpteurAv = cpteurAv+1; set i=i+1) else set i = nbMaxDisplayed+1); 0);; /* les 2 prochaines fonctions sont des fonctions adaptées de celles du C3D3 (c3d3c.pkg) */ fun sizeav(l)= if l==nil then 0 else let l->[o nxt] in o.avOb+sizeav nxt;; /* ajoute les pseudos à la liste */ fun addlist(o, i)= if !o.avOb then nil else let if o==owner then strcat strcat "[ " o.pseudoOb " ]" else o.pseudoOb -> name in (set listCelAv = add_nth_in_list listCelAv sizelist listCelAv name; 0);; fun updatelist(o)= set listCelAv = nil; apply_on_list C3DobList @addlist 0; displayListAv nil; 0;; fun clicAvUp()= if posListAv > 0 then (set posListAv = posListAv-1; displayListAv nil; 0) else 0;; fun clicAvDown()= let CoordAvList -> [_ _ _ h] in let (h-14)/13 -> nbMaxDisplayed in if posListAv < ((sizelist listCelAv)-nbMaxDisplayed-1) then (set posListAv = posListAv+1; displayListAv nil; 0) else 0;; /* dirige face à l'avatar cliqué dans la liste (si différent de soi-même) */ /* item -> I numero du pseudo dans la liste */ fun cbclicListAv(item)= displayListAv item; let nth_moblist C3DobList item -> o in if o == owner then nil else targetOb owner o;; /* x -> I abscisse du clic y -> I ordonnée du clic i -> I compteur I <- 0 */ fun cliconlogin(x, y, i)= let sizeav C3DobList -> nb in if i <= nb then let CoordAvList -> [xAv yAv wAv hAv] in if (y > (yAv+14+(i*13))) && (y < (yAv+14+13+(i*13))) then (cbclicListAv i; displayListAv i; 0) else cliconlogin x y i+1 else 0;; /************************************************/ /* Affichage des liens dans la 3d par le plugin */ /************************************************/ /*** fun fDisplayLink(link) : fun [S] I;; Fonction appelée lorsque l'affichage ou le non affichage d'un lien (objet ou avatar) est requis. ***/ /* link -> S (lien à afficher) I <- 0 (non utilisée) */ fun fDisplayLink(link)= let CoordAvList -> [xAv yAv wAv hAv] in (_DSbitmap bmpLinksBG; set bmpLinksBG = _FILLbitmap _CRbitmap _channel wAv 20 if transparence then 0 else if cel.Cel3dback == 0 then cel.Cel3dback+8 else cel.Cel3dback; set bmpLinksBG = _DRAWtext bmpLinksBG fontAv wAv/2 3 TD_TOP|TD_CENTER colorAv link; /* begin 12/2004 : correction erreur 'PaintBuffer' à NIL */ displayListAv nil; set bmpAvBG = _CPbitmap16 _CRbitmap _channel wAv hAv+30 0 0 bmpAvBG 0 0 wAv hAv 0; _CPbitmap16 bmpAvBG 0 hAv+10 bmpLinksBG 0 0 wAv 20 0; /* end 12/2004 */ ); 0;; /******************/ /* fenêtre d'aide */ /******************/ /*** fun helpme() : fun [] I; Fonction appelée pour la création de la popup d'aide. Définition de la callback de destruction. fun _endHelp(win, u) : fun [ObjWin I] ObjWin;; Fonction callback de destruction de la popup d'aide. Détruit la fenêtre. ***/ /* win -> ObjWin u -> U0 (user param) */ fun _endHelp(win, u)= _DSwindow win; _SETfocus w3d.V3dwin; 0;; fun helpme()= let _getress "DefaultLanguage" -> lang in if !strcmp lang "french" then _DMSevent this strcat class ".helpFR" nil nil else _DMSevent this strcat class ".helpUK" nil nil; let _CRwindow _channel w3d.V3dwin 200 150 250 135 WN_MENU "Help Term3d !" -> winHelp in ( _CRtext _channel winHelp 0 0 250 135 ET_BORDER (_loc this "term3d_txtHelp" nil); _CBwinDestroy winHelp @_endHelp 0 ); 0;; /***********************************/ /* fonctions de gestion des MACROS */ /***********************************/ /*** fun configMacro() : fun [] I;; Appelée lors de la sélection correspondante dans le menu contextuel ou par le raccourci clavier. crée l'interface de configuration des macros et défini les callbacks nécessaires. fun _closeMacro(b, w) : fun [ObjButton ObjWin] I;; fun _endMacro(w, u) : fun [ObjWin I] I;; Callbacks de fermeture. Ferme la fenêtre et appelle l'enregistrement des macros sur HD de l'user. fun saveFileMacro() : fun [] I;; Sauvegarde les macros sur le disque client. fun _saveMacro(b, c) : fun [ObjButton ObjBox] I;; Callback bouton 'validation'. Met à jour la liste des macros. fun _comboKeyMacro(c, text, i, s) : fun [ObjBox ObjText I S] ObjText;; Callback du combo. Affiche la macro correspondant à la touche clavier. fun affichMacro(key, o) : fun [I Ob] I;; Fonction appelée lorsqu'une des touches de fonction du clavier est enfoncée (F1 -> F9). Crée le message contenant la macro envoie ce message au serveur pour l'afficher chez tous les clients. ***/ fun saveFileMacro()= _createpack linebuild myMacros _getmodifypack fileMacros;; fun _saveMacro(b, c)= let _GETcombo c -> [i s] in let _GETtext macro -> mess in set myMacros = replace_nth_in_list myMacros i mess; 0;; /* c -> ObjBox comboKey text -> ObjText macro i -> I combo selected (number) s -> S combo selected (string) ObjText <- text macro */ fun _comboKeyMacro(c, text, i, s)= _SETtext text nth_list myMacros i;; fun _endMacro(w, u)= _DSwindow w; _SETfocus w3d.V3dwin; saveFileMacro; 0;; fun _closeMacro(b, w)= _endMacro w 0;; fun configMacro()= let _CRwindow _channel w3d.V3dwin 200 200 350 100 WN_MENU "Configuration macro" -> winConfig in let _GETwindowPositionSize winConfig -> [x y w h] in ( _CRtext _channel winConfig 5 5 w-10 40 ET_ALIGN_LEFT|ET_BORDER (_loc this "term3d_txtConfigMacro" nil); let _CRcombo _channel winConfig 5 50 70 200 CB_NOEDIT|CB_DOWN "..." -> comboKey in ( _ADDcombo comboKey 0 "SHIFT+F1"; _ADDcombo comboKey 1 "SHIFT+F2"; _ADDcombo comboKey 2 "SHIFT+F3"; _ADDcombo comboKey 3 "SHIFT+F4"; _ADDcombo comboKey 4 "SHIFT+F5"; _ADDcombo comboKey 5 "SHIFT+F6"; _ADDcombo comboKey 6 "SHIFT+F7"; _ADDcombo comboKey 7 "SHIFT+F8"; _ADDcombo comboKey 8 "SHIFT+F9"; _SELcombo comboKey 0; set macro = _CReditLine _channel winConfig 80 50 w-85 20 ET_DOWN nth_list myMacros 0; _CBcombo comboKey @_comboKeyMacro macro; _CBbutton _CRbutton _channel winConfig w/3 75 ((2*w/3)-5) 20 0 (_loc this "term3d_save" nil) @_saveMacro comboKey; _CBbutton _CRbutton _channel winConfig 5 75 ((w/3)-10) 20 0 (_loc this "term3d_close" nil) @_closeMacro winConfig ); _CBwinDestroy winConfig @_endMacro 0 ); 0;; /* pour le code des touches cf l'en-tête de ce fichier */ fun affichMacro(key, o)= let key-65470 -> k in set message = strcatn "<"::DMSlogin::"> "::(nth_list myMacros k)::nil; UsendMessage ObUi o "command" message; set message = strcatn "<"::DMSlogin::"> "::nil; 0;; /*********************************************/ /* Couleur des message envoyés par le client */ /*********************************************/ /*** fun showColor(z, o) : fun [TData Ob] I;; Appelée par sélection correspondate du menu contextuel et par raccourci clavier. affiche l'interface de choix de la couleur, définit la callback correspondante avec ajout d'un second paramète (mkfun2) pour le passge de la struct. Ob fun _endColor(c, p) : fun [I [Ob TData]] I;; Callback de destruction de l'interface de choix de couleur. Définit la couleur des messages envoyés par le client le fait savoir au serveur (lui envoie un message) ***/ fun _endColor(c, p)= let p -> [o z] in (set colorOpened = 0; if c != nil then let (cel.Cel3dback - 500) -> a in let (cel.Cel3dback + 500) -> b in if (c > a) && (c < b) then if a < 0 then set color = 500 else set color = (cel.Cel3dback - 500) else ( set color = c; UsendMessage ObUi o "chgColor" linebuild DMSlogin::(itoa color)::nil; 0 ) else nil; let (itoa color)::(itoa z.D_size)::(itoa z.D_type)::nil -> l in _createpack linebuild l _getmodifypack fileColor );; fun showColor(z, o)= if !colorOpened then (set colorOpened = 1; _CRcolorMap _channel w3d.V3dwin 100 100 "Color ?" mkfun2 @_endColor [o z] (if color == nil then z.D_color else color) ) else nil;; /***************************************************/ /* Taille et type de la font choisie par le client */ /***************************************************/ /*** fun configTexte(z, o) : fun [TData Ob] I;; Fonction appelée lorsque l'user demande la configuration de la taille et du type de la font du tchat. Crée l'interface et définit les callbacks nécessaires. fun _cbCloseText(b, w) : fun [ObjButton ObjWin] I;; fun _endText(w, u) : fun [ObjWin U0] I;; Callbacks de fermeture de la fenêtre. Détruit la fenêtre de configuration. fun _cbSaveText(a, b) : fun [ObjButton [ObjBox ObjBox TData]] I;; Callback du bouton "OK". Récupère les valeurs choisies par l'user, les affecte à la structure TData appelle la fonction 'saveConfigText' pour leurs sauvegardes. fun saveConfigText(l) : fun [[S r1]] I;; Enregistrement de la configuration Texte chez le client. ***/ fun saveConfigText(l)= _createpack linebuild l _getmodifypack fileColor;; fun _cbSaveText(a, b)= let b -> [cSize cType z] in let _GETcombo cSize -> [is ss] in let _GETcombo cType -> [it st] in let (itoa color)::ss::(itoa it)::nil -> myConfig in ( set z.D_size = atoi ss; set z.D_type = it; _DSfont font; set font = _CRfont _channel z.D_size 0 z.D_type z.D_font; saveConfigText myConfig ); 0;; fun _endText(w, u)= _DSwindow w; _SETfocus w3d.V3dwin; 0;; fun _cbCloseText(b, w)= _endText w 0;; fun configTexte(z, o)= let [200 100] -> [w h] in let _CRwindow _channel w3d.V3dwin 200 200 w h WN_MENU "Configuration Term3d" -> winText in ( _CRtext _channel winText 5 5 w-10 40 ET_ALIGN_CENTER|ET_BORDER (_loc this "term3d_txtText" nil); let _CRcombo _channel winText 5 50 50 220 CB_NOEDIT|CB_DOWN "..." -> comboSize in let _CRcombo _channel winText 60 50 w-60 80 CB_NOEDIT|CB_DOWN "..." -> comboType in ( _ADDcombo comboSize 0 "8"; _ADDcombo comboSize 1 "9"; _ADDcombo comboSize 2 "10"; _ADDcombo comboSize 3 "11"; _ADDcombo comboSize 4 "12"; _ADDcombo comboSize 5 "13"; _ADDcombo comboSize 6 "14"; _ADDcombo comboSize 7 "15"; _ADDcombo comboSize 8 "16"; _ADDcombo comboSize 9 "17"; _SSELcombo comboSize itoa z.D_size; _ADDcombo comboType 0 (_loc this "term3d_plain" nil); _ADDcombo comboType 1 (_loc this "term3d_italic" nil); _ADDcombo comboType 2 (_loc this "term3d_bold" nil); _SELcombo comboType z.D_type; _CBbutton _CRbutton _channel winText 5 75 50 20 0 (_loc this "term3d_close" nil) @_cbCloseText winText; _CBbutton _CRbutton _channel winText w-55 75 50 20 0 "OK" @_cbSaveText [comboSize comboType z] ); _CBwinDestroy winText @_endText 0 ); 0;; /************************************************************************/ /* Configuration de la position et de la taille du term3d par le client */ /************************************************************************/ /*** fun configDisplay(z, o) : fun [TData Ob] I;; Appelée lorsque l'user demande ce type de configuration. Crée l'interface de configuration de l'affichage du term3d par le client. Définit les callbacks nécessaires (la callback de destruction est celle de la fenêtre de configuration de la taille et du type de la font). fun _defaultDisplay(btn, u) : fun [ObjButton [ObjText objText ObjText ObjText]] I;; Callback bouton "Défaut". Remet les valeurs par défaut. fun _okDisplay(btn, u) : fun [ObjButton [ObjText objText ObjText ObjText TData ObjWin]] I;; Callback bouton "OK". Affecte les valeurs saisies par l'utilisateur dans certaines limites le taille doit être au moins de 100 x 100 le term ne doit pas être partiellement en dehors de la vue 3d détruit la fenêtre. ***/ fun _okDisplay(btn, u)= let u -> [textX textY textW textH z wn] in let _GETsurfaceSize w3d.V3dbuf -> [w3 h3] in let atoi _GETtext textX -> x in let atoi _GETtext textY -> y in let atoi _GETtext textW -> w in let atoi _GETtext textH -> h in /* let h3-y-h -> y in */ ( if w > 100 then set z.D_width = w else set z.D_width = 100; if h > 100 then set z.D_heigth = h else set z.D_heigth = 100; if (x+z.D_width) < w3 then set z.D_posX = x else set z.D_posX = w3-z.D_width; if (y-h3) < 0 then set z.D_posY = h3-h-y else set z.D_posY = z.D_heigth; _DSbitmap z.D_fond; set z.D_fond = _CRbitmap _channel z.D_width z.D_heigth; _DSwindow wn; 0 );; fun _defaultDisplay(btn, u)= let u -> [textX textY textW textH] in let defaultSize -> [x y w h] in ( _SETtext textX itoa x; _SETtext textY itoa y; _SETtext textW itoa w; _SETtext textH itoa h; 0 );; fun configDisplay(z, o)= let [350 180] -> [w h] in let _GETsurfaceSize w3d.V3dbuf -> [w3 h3] in let _CRwindow _channel w3d.V3dwin 200 200 w h WN_MENU "Configuration display" -> winDisplay in ( _CRtext _channel winDisplay 5 5 w-10 40 ET_ALIGN_CENTER|ET_BORDER (_loc this "term3d_displayText" nil); _CRtext _channel winDisplay 5 50 w-60 20 0 (_loc this "term3d_displayPosX" nil); _CRtext _channel winDisplay 5 75 w-60 20 0 (_loc this "term3d_displayPosY" nil); _CRtext _channel winDisplay 5 100 w-60 20 0 (_loc this "term3d_displayW" nil); _CRtext _channel winDisplay 5 125 w-60 20 0 (_loc this "term3d_displayH" nil); let _CReditLine _channel winDisplay w-55 50 50 20 ET_DOWN|ET_NUMBER itoa z.D_posX -> posX in let _CReditLine _channel winDisplay w-55 75 50 20 ET_DOWN|ET_NUMBER itoa (h3-z.D_posY-z.D_heigth) -> posY in let _CReditLine _channel winDisplay w-55 100 50 20 ET_DOWN|ET_NUMBER itoa z.D_width -> posW in let _CReditLine _channel winDisplay w-55 125 50 20 ET_DOWN|ET_NUMBER itoa z.D_heigth -> posH in ( _CBbutton _CRbutton _channel winDisplay 5 160 w-60 20 0 (_loc this "term3d_displayDefault" nil) @_defaultDisplay [posX posY posW posH]; _CBbutton _CRbutton _channel winDisplay w-55 160 50 20 0 "OK" @_okDisplay [posX posY posW posH z winDisplay]; _CBwinDestroy winDisplay @_endText 0 )); 0;; /************************************/ /* Enregistrement du chat sur le HD */ /************************************/ /* fun [] I;; sauvegarde le tchat dans le cache client (tmp/term3d/xxx.txt , le nom du fichier dépendant notamment de la date et de l'heure de création */ fun saveMsgFile(m)= _appendpack strcat m "\n" _getmodifypack pathSaveFile;; /********************/ /* Fonctions IGNORE */ /********************/ /*** fun cliByLogin(currentLogin, userLogin) : fun [S S] I;; compare le login avec les logins déjà présents dans la liste fun searchIfIgnored(login) : fun [S] I;; recherche si le login est dans la liste des logins à ignorer fun msgPass(s) : fun [S] I;; récupère le login dans le message. Si celui-ci n'est pas ignoré (1), le message sera accepté. fun ChangeNameIgnList (oldname, newname, IgnList) : fun [S S [S r1]] I;; change le login ignoré lorsque celui-ci est modifié fun updateLogin(oldname,newname) : fun [S S] I;; fun updateIgnoreList(type, name, state) : fun [S S S] I;; Mise à jour de la liste des pseudos ignorés. ***/ fun cliByLogin(currentLogin, userLogin) = !strcmp currentLogin userLogin;; fun searchIfIgnored(login)= search_in_list ignoreList @cliByLogin login;; fun msgPass(s)= let strfind ">" s 1 -> pos in let substr s 1 (pos-1) -> login in if (searchIfIgnored login) != nil then 0 else 1;; fun ChangeNameIgnList (oldname, newname, IgnList)= if IgnList == nil then 0 else let IgnList -> [currentname NIgnList] in if !strcmp oldname currentname then (mutate IgnList <- [newname _]; 1) else ChangeNameIgnList oldname newname NIgnList;; fun updateLogin(oldname,newname)= ChangeNameIgnList oldname newname ignoreList; 0;; fun updateIgnoreList(type, name, state)= if !strcmp type "ChatIn" then if atoi state then set ignoreList = name::(removef_from_list ignoreList @cliByLogin name) else set ignoreList = removef_from_list ignoreList @cliByLogin name else nil; 0;; /**********************/ /* Gestion des URLs */ /**********************/ /* fun [MessageBox [Ob S] I] I */ /* si l'user est Ok, ouvre l'url dans son navigateur favori */ fun cbFoundUrl(dlb, url, reponse)= if reponse then _openbrowserhttp url else nil;; /* fun [Ob S] I */ /* ouvre une boite de dialogue : ouvrir ou non cette url ? */ fun foundUrl(url)= _DLGrflmessage _DLGMessageBox _channel w3d.V3dwin (_loc this "term3d_titleurl" nil) strcat (_loc this "term3d_msgurl" nil) url 2 @cbFoundUrl url; 0;; /* fun [Ob I] I */ /* extrait l'url du message complet */ fun extractUrl(o, pos, mess) = let substr mess pos strlen mess -> s in let strfind "\ " s 7 -> r in if r != nil then foundUrl substr s 0 r /* messge derrière l'url */ else foundUrl s;; /* pas de msg après l'url */ /* fun [Ob] I */ /* vérifie si une url (protocole http ou scol) est présente dans le message reçu */ fun searchUrl(o, mess)= let strfind "http://" mess 0 -> r in let strfind "scol://" mess 0 -> r2 in if (r != nil) || (r2 != nil) then if r != nil then extractUrl o r mess else extractUrl o r2 mess else 0;; /**********************/ /* Gestion du Term 3d */ /**********************/ /*** cf chaque fonction ***/ /* ll -> [[S I] r1] datas s -> S login défini dans la ligne à afficher z -> struct TData I <- couleur de la ligne à afficher */ fun getColor2(ll, s, z)= if ll == nil then z.D_color else let ll -> [[l c] q] in if !strcmp l s then c else getColor2 q s z ;; /* s -> S ligne à afficher dans l'historique z -> struct TData I <- couleur de la ligne à afficher */ fun getColor(s, z)= let strfind ">" s 1 -> r in if r != nil then let substr s 1 r-1 -> login in if !strcmp login DMSlogin then color else getColor2 cliColor login z else z.D_color;; /* crée une chaine avec un nombre d'espace déterminé (longueur du login) */ /* i -> I s -> S S <- s */ /* fonction non utilisée (cf fonction longMessage) */ fun addspace(i, s)= if i == 0 then s else (set s = strcat s "\ "; addspace i-1 s);; /* old -> S ancien login */ /* lorsque le client change de login, remplace l'ancien pseudo par le nouveau en tête de la ligne de saisie */ fun chgLogin(old)= if premier then let strlen(strcatn "<"::old::"> "::nil) -> longold in let substr message longold strlen message -> saisie in set message = strcatn "<"::DMSlogin::"> "::saisie::nil else nil; 0;; /* retourne la largeur et la hauteur du rectangle pouvant contenir le texte selon la font utilisée */ /* s -> S [I I] <- [w h] */ fun testLong(s)= _GETstringSize font s;; /* teste la longueur du message reçu d'un autre client en fonction de la taille du tchat */ /* z -> TData m -> S i -> I tmp -> S login -> S [S r1] <- */ fun longueurMessageRecu(z, m, i, tmp, login)= if i <= (strlen m) then let substr m 0 i -> string in let testLong string -> [w _] in if w < (z.D_width - z.D_size) then longueurMessageRecu z m i+1 string login else let substr m i-1 strlen m -> fin in let strcatn "<"::login::"> "::fin::nil -> fin in (set messageTerm = tmp::messageTerm; longueurMessageRecu z fin 0 nil login) else if tmp == nil then set messageTerm = m::messageTerm else set messageTerm = tmp::messageTerm;; /* si le message en cours de saisie est trop long, la phrase est coupée et la 1ere partie est affichée */ fun longueurMessage(z, o)= let testLong message -> [w _] in let substr message (2 + strlen DMSlogin) strlen message -> m in /* suppr le " " du message */ if w > (z.D_width - z.D_size) then (UsendMessage ObUi o "command" message; _DMSevent this strcat class ".log" message nil; _DMSevent this strcat class ".message" m nil; set message = strcatn "<"::DMSlogin::"> "::nil; 0) else 0;; /* fun [Tdata Ob [[S I] r1] I] I ajoute les smileys sur le bitmap général */ fun addSmiley(z, o, list, i)= if list == nil then 0 else let list -> [[s _ _ _] suite] in let getSmileys o s -> [bmp pos] in let _GETbitmapSize bmp -> [w h] in (set z.D_fond = _CPbitmap16 z.D_fond pos ((z.D_size+2)*((sizelist messageTerm)-i)) bmp 0 0 w h 0xffffff; destroySmiley bmp; addSmiley z o suite i);; /* z -> struct TData o -> Ob I <- not used */ /* affiche les caractères saisis les uns après les autres affiche les messages dans l'historique et les smileys s'il y a lieu */ fun text(z, o)= if transparence then set z.D_fond = _FILLbitmap z.D_fond cel.Cel3dback else set z.D_fond = _FILLbitmap z.D_fond if cel.Cel3dback == 0 then cel.Cel3dback+8 else cel.Cel3dback; /* new message */ set z.D_fond = _DRAWtext z.D_fond font 5 z.D_heigth-z.D_size 0 z.D_color message; /* olds messages */ let sizelist messageTerm -> i in while i > -1 do ( let nth_list messageTerm i -> s in let getColor s z -> c in ( set lMsgSmileys = nil; if setSmileys then /* smileys activé */ (searchSmileys s z c 0 i; 0) else 0; if lMsgSmileys == nil then (set z.D_fond = _DRAWtext z.D_fond font 5 ((z.D_size+2)*((sizelist messageTerm)-i)) 0 c s; 0) else 0; /* smileys */ if (sizelist lMsgSmileys) > 0 then /* si smileys */ addSmiley z o lMsgSmileys i else 0 ); set i = i-1 ); 0;; /* rendu général (affichage du plugin). calcule les position du chat et de la liste des avatars en fonction de la taille de l'ObjSurface si mode fenêtré ou si mode fullscreen le term reste à la même position par rapport au bas de la 3d */ fun cbBlitTerm(o, b, p) = let p -> [z] in ( if z.D_onoff && ENterm3d then (text z o; if FSbottom then let _GETsurfaceSize w3d.V3dbuf -> [_ h] in _Bitmap2Surface w3d.V3dbuf z.D_posX (/*h-z.D_heigth-*/z.D_posY) z.D_fond 0 0 z.D_width z.D_heigth cel.Cel3dback else _Bitmap2Surface w3d.V3dbuf z.D_posX z.D_posY z.D_fond 0 0 z.D_width z.D_heigth cel.Cel3dback; 0) else 0; if displayAvList then (calculCoordAvList CoordAvListDefault; let CoordAvList -> [x y w h] in if displayLinks then // let _CRbitmap _channel w h+30 -> temp in let CoordAvListDefault -> [_ yAv _ _] in if yAv then /* si la liste des avatars est affichée en bas (1) ou en haut (0) de l'écran */ (/*_CPbitmap16 temp 0 30 bmpAvBG 0 0 w h nil; _CPbitmap16 temp 0 0 bmpLinksBG 0 0 w 20 nil;*/ _Bitmap2Surface w3d.V3dbuf x y-30 bmpAvBG 0 0 w h+30 0) else (/*_CPbitmap16 temp 0 0 bmpAvBG 0 0 w h nil; _CPbitmap16 temp 0 h+10 bmpLinksBG 0 0 w 20 nil;*/ _Bitmap2Surface w3d.V3dbuf x y bmpAvBG 0 0 w h+30 0) else _Bitmap2Surface w3d.V3dbuf x y bmpAvBG 0 0 w h 0) else nil; 0);; /* détermine la taille de la liste des contributions à afficher. Si trop long elle est amputée de la plus ancienne */ fun sizeMessageTerm(z)= let sizelist messageTerm -> size in if (size*(z.D_size+2)) > (z.D_heigth-(3*(z.D_size))) then set messageTerm = remove_nth_from_list messageTerm size-1 else nil;; /* devrait revenir à l'affichage normal chat après l'utilisation des touches "historiques" */ fun lastMessageTerm(z, i)= let sizelist messageTerm -> size in if (size*(z.D_size+2)) > (z.D_heigth-(3*(z.D_size))) then messageTerm else (set messageTerm = (nth_list historic i)::messageTerm; lastMessageTerm z i+1);; /* z -> struct Tdata */ /* supprime la ligne la plus ancienne de l'historique affichée si nécessaire */ fun verifLongMessageTerm(z)= if useHistoric then (/*set messageTerm = ""::nil;*/ lastMessageTerm z 0; set useHistoric = 0; nil) else sizeMessageTerm z;; /* Gère l'affichage de l'ancien historique lorsque demandé */ fun affichHistoric(sens, z)= let sizelist messageTerm -> size in (/*set messageTerm = remove_nth_from_list messageTerm size-1;*/ if !sens then (if posHistoric < 0 then set posHistoric = 1 else 0; let nth_list historic posHistoric -> s in if (s != nil) && (posHistoric < maxHistoric) then (set posHistoric = posHistoric+1; /* set messageTerm = remove_nth_from_list messageTerm size-1;*/ set messageTerm = s::messageTerm) else nil) else if sens then (if posHistoric >= (sizelist messageTerm) then set posHistoric = (sizelist messageTerm)-1 else 0; let nth_list historic posHistoric -> s in if (s != nil) && (posHistoric >= 0) then (set posHistoric = posHistoric-1; /* set messageTerm = remove_nth_from_list messageTerm size-1;*/ set messageTerm = s::messageTerm) else nil) else nil); sizeMessageTerm z; 0;; /* z -> struct Tdata I <- 0 */ /*supprime la ligne la plus ancienne de l'historique complet si nécessaire ajoute la nouvelle ligne à l'historique complet */ fun verifLongHistoric(s)= let sizelist historic -> size in if size >= maxHistoric then remove_nth_from_list historic size-1 else nil; set historic = s::historic; set posHistoric = posHistoric+1; 0;; /* génère l'évenement shown/hidden lorsque le term change d'état */ fun ishidden(z)= if z.D_onoff then _DMSevent this strcat class ".shown" nil nil else _DMSevent this strcat class ".hidden" nil nil; 0;; /* touche backspace : efface le caractère si ce n'est pas le pseudo */ fun suppr()= let strlen(strcatn "<"::DMSlogin::"> "::nil) -> longlogin in if longlogin < (strlen message) then set message = substr message 0 (strlen message)-1 else nil;; /* o -> Ob b -> [I I] p -> [struct TData] I <- not used */ /* teste la valeur retournée (touche clavier enfoncée) appelle la fonction associée à la touche entrée (cf fun initKey) */ fun cbKey(o, b, p)= if ENterm3d then let b -> [a k] in let p -> [z] in ( if k == 9 then (set z.D_onoff = !z.D_onoff; ishidden z) else nil; if z.D_onoff then ( if !premier then (set premier = 1; set message = strcatn "<"::DMSlogin::"> "::nil) else nil; let searchKey k 0 -> action in if action == 1 then (verifLongMessageTerm z; /* verifLongHistoric message;*/ set posHistoric = 0; UsendMessage ObUi o "command" message; _DMSevent this strcat class ".log" message nil; let substr message (2 + strlen DMSlogin) strlen message -> m in /* suppr le " " du message */ _DMSevent this strcat class ".message" m nil; set message = strcatn "<"::DMSlogin::"> "::nil; 0) else if action == 2 then 0 else if action == 3 then (suppr; nil) else if action == 4 then (showColor z o; 0) else if action == 5 then 0 else if (action == 6) && (_keybdstate == 1) then affichMacro k o else if action == 6 then 0 else if action == 7 then configMacro else if action == 8 then helpme else if action == 9 then if posHistoric >= 0 then (set useHistoric = 1; affichHistoric 1 z) else nil else if action == 10 then if posHistoric < (sizelist historic) then (set useHistoric = 1; affichHistoric 0 z) else nil else if action == 11 then (configTexte z o; 0) else (set message = strcat message ctoa k; set posHistoric = posHistoric+1; 0); longueurMessage z o; text z o ) else nil) else nil; 0;; /******************************************/ /* Création et gestion du menu contextuel */ /******************************************/ /*** fun creaMenu(o, z) : fun [Ob TData] I;; Appelée lors d'un clic droit dans la vue 3d. Création et affichage du menu contextuel, définition des callbacks associées. fun cbMenu(m, p) : fun [ObjMenuItem [S Ob Tdata]] I;; Callback du menu contextuel. Le paramètre utilisateur est un 3-tuple dont le 1er élément est le nom de l'item. Appelle les fonctions adéquates. ***/ fun cbMenu(m, p)= let p -> [s o z] in (if !strcmp s "Color" then (showColor z o; 0) else if !strcmp s "Text" then (configTexte z o; 0) else if !strcmp s "Size" then (configDisplay z o; 0) else if !strcmp s "Macros" then configMacro else if !strcmp s "Show" then (set z.D_onoff = !z.D_onoff; ishidden z) else if !strcmp s "ShowAv" then if displayAvList then (_DSbitmap bmpAvBG; set displayAvList = !displayAvList) else (updatelist o; set displayAvList = !displayAvList) else if !strcmp s "Trans" then (set transparence = !transparence; _CHKmenu menuTrans transparence; updatelist o; fDisplayLink nil; 0) else if !strcmp s "Smileys" then (displaySmileys o; 0) else if !strcmp s "url" then (set openUrl = !openUrl; _CHKmenu menuURL openUrl; 0) else if !strcmp s "Away" then (_CHKmenu menuAway !bMenuAway; set bMenuAway = _GETcheckMenu menuAway; if bMenuAway then _DMSevent this strcat class ".away" nil nil else _DMSevent this strcat class ".back" nil nil) else if !strcmp s "Custom" then (_DMSevent this strcat class ".custom" nil nil; 0) else if !strcmp s "Help" then helpme else if !strcmp s "Save" then (_CHKmenu menuSave !(bMenuSave); set bMenuSave = _GETcheckMenu menuSave; if bMenuSave then (let localtime time -> [s mn h d m y _ _] in set pathSaveFile = strcatn fileSave::DMSname::"_"::(itoa d)::" "::(itoa m)::" "::(itoa y)::"_"::(itoa h)::" "::(itoa mn)::" "::(itoa s)::".txt"::nil; _storepack "" pathSaveFile) else nil; 0) else 0; OB_ReleaseMouse o; 0);; fun creaMenu(o, z)= _DSmenu menu; set menu = _CRpopupMenu _channel; _CBmenu _APPitem _channel menu ME_ENABLED (_loc this "term3d_contextColor" nil) @cbMenu ["Color" o z]; _CBmenu _APPitem _channel menu ME_ENABLED (_loc this "term3d_contextText" nil) @cbMenu ["Text" o z]; _CBmenu _APPitem _channel menu if ChgCliSize then ME_ENABLED else ME_DISABLED (_loc this "term3d_contextSize" nil) @cbMenu ["Size" o z]; _CBmenu _APPitem _channel menu ME_ENABLED (_loc this "term3d_contextMacros" nil) @cbMenu ["Macros" o z]; _CBmenu _APPitem _channel menu ME_ENABLED (_loc this "term3d_contextShow" nil) @cbMenu ["Show" o z]; if displayAvListInit then _CBmenu _APPitem _channel menu ME_ENABLED (_loc this "term3d_contextShowAv" nil) @cbMenu ["ShowAv" o z] else nil; set menuTrans = _APPitem _channel menu ME_ENABLED (_loc this "term3d_contextTrans" nil); _CBmenu menuTrans @cbMenu ["Trans" o z]; _CHKmenu menuTrans transparence; set menuSmileys = _APPitem _channel menu ME_ENABLED "Smileys"; _CBmenu menuSmileys @cbMenu ["Smileys" o z]; _CHKmenu menuSmileys setSmileys; set menuURL = _APPitem _channel menu ME_ENABLED (_loc this "term3d_contextUrl" nil); _CBmenu menuURL @cbMenu ["url" o z]; _CHKmenu menuURL openUrl; set menuAway = _APPitem _channel menu ME_ENABLED (_loc this "term3d_contextAway" nil); if displayCustomItem then _CBmenu _APPitem _channel menu ME_ENABLED nameCustomItem @cbMenu ["Custom" o z] else nil; _CBmenu _APPitem _channel menu ME_ENABLED (_loc this "term3d_contextHelp" nil) @cbMenu ["Help" o z]; set menuSave = _APPitem _channel menu ME_ENABLED (_loc this "term3d_contectSave" nil); _CHKmenu menuSave bMenuSave; _CBmenu menuSave @cbMenu ["Save" o z]; _CHKmenu menuAway bMenuAway; _CBmenu menuAway @cbMenu ["Away" o z]; let _GETscreenPos -> [x y] in if _GETsurfaceState == SURFACE_FULLSCREEN then _DRAWmenu w3d.V3dwin menu x y PM_SCREEN|PM_LEFT_ALIGN|PM_TOP_ALIGN else _DRAWmenu w3d.V3dwin menu x y-20 PM_SCREEN|PM_LEFT_ALIGN|PM_TOP_ALIGN; 0;; /*******************/ /* Callbacks plugin*/ /*******************/ /*** fun cbControlMove(o, p) = fun [Ob [Ob H3d HMat3d]] I;; Callback clic sur un objet 3d. Retourne si l'objet cliqué est un avatar (1) ou non (0). fun cbClicWin(x, y, btn, p) = fun [I I I [Ob Tdata]] I;; Callback clic sur la fenêtre 3d. teste si le clic a lieu dans la zone d'affichage des pseudos ou sur les boutons du scroll (bouton gauche) ou ouvre le menu contextuel (bouton droit) si la souris n'est pas sur un avatar. Si le plugin "DynamicEditor" est intégré à la scène 3d, le menu s'affichera avec la combinaison SHIFT + clic droit. Si le menu doit être affiché, l'event clic souris est réservé et n'est pas transmis aux autres puis est relaché ensuite. fun cbMoveWin(x, y, btn, p) = fun[I I I [Ob Tdata]] I;; Callback curseur move sur la 3d. Fait apparaître un curseur différent si la souris survole la ligne de saisie du chat. fun moveOb(o, h, m) = fun [Ob H3d HMat3d] I;; Callback ObCbMove. Lorsque le curseur passe sur un objet ... si les liens doivent être affichés, appel de la fonction 'fDisplayLink'. LINK_Search & LINK_ExtractOne sont des fonctions du C3D. Fonction non utilisée. fun cbClick(o, h, p) = fun [Ob [H3d HMat3d I] TData] I;; Callback ObCbClick. Le menu contextuel ne s'affichera que si l'utilisateur : - clique sur un objet 3d - que cet objet ne soit pas un lien déjà défini dans le C3D. Fonction non utilisée. ***/ fun clicWinOk(o, z)= if ENterm3d then (OB_TakeMouse o; /* prise en charge exclusive du clic par la seule instance du Term3d. Evite le déplacement involontaire de l'avatar lorsque l'user clic sur un item du menu */ creaMenu o z) else 0;; fun cbClick(o, h, p)= /* not used */ let h -> [h mat b] in if b == 2 then let p -> [z] in creaMenu o z else 0;; fun cbControlMove(o, p)= let p -> [obj h m] in if (OB_SearchObj3DAvatar ObList h) == nil then set objIsAvatar = 0 /* autre objet 3d */ else set objIsAvatar = 1;; /* avatar */ fun cbClicWin(x, y, btn, p)= let p -> [o z] in ( ObControlMove o; if (btn == 2) && !(searchDynEd plugins "Dynamic\ Editor") && !objIsAvatar then clicWinOk o z else if (btn == 1) && (searchDynEd plugins "Dynamic\ Editor") && (_keybdstate == 1) && !objIsAvatar then clicWinOk o z else let CoordAvList -> [xAv yAv wAv hAv] in if (x > xAv) && (x < (xAv+wAv-18)) && (y > yAv) && (y < (yAv+hAv)) then cliconlogin x y 0 else if (x > xAv+wAv-18) && (x < xAv+wAv) && (y > yAv) && (y < yAv+18) then clicAvUp else if (x > xAv+wAv-18) && (x < xAv+wAv) && (y > yAv+hAv-18) && (y < yAv+hAv) then clicAvDown else (OB_ReleaseMouse o; /* prise en charge du clic non exclusive par le term3d */ 0); 0);; fun cbMoveWin(x, y, btn, p)= let p -> [o z] in if (x > z.D_posX) && (x < z.D_posX + z.D_width) && (y > z.D_posY + z.D_heigth - z.D_size) && (y < z.D_posY + z.D_heigth) then if _platform == 3 then /* MAC */ (OB_TakeCursor o; OB_SetCursor o TextCursorMAC) else (OB_TakeCursor o; OB_SetCursor o TextCursorWIN) else /* curseur 'standard' (flèche) */ (OB_ReleaseCursor o; OB_SetCursor o StdCursor); 0;; fun moveOb(o, h, m)= /* not used */ _showconsole; if displayLinks then let LINK_Search links @LINK_ExtractOne h m -> c in let c->[_ _ link i] in if c==nil || i==0 then nil else fDisplayLink link else nil; 0;; /*********************/ /* Gestion du plugin */ /*********************/ /*** fun cbcomm(ui, action, param, p) : fun [UserI S S [Tdata Ob]] I;; Gère les communications intramodules (server / client). fun activate(o, from, action, param, reply, p) : fun [Ob DMI S S S TData];; Gère les communications intermodules (actions). fun cbRegistered (ui, action, param, o) : fun [UserI S S Ob];; Le plugin client s'est enregistré auprès du plugin server. Récupération des données contenu dans le fichier .dms Initialisations de variables Déclaration des callbacks principales. fun _close() : fun [] I;; Fonction appelée avant que le plug ne soit détruit. Supprime les fonctions de gestion clic ajoutées au C3D3 par le plugin récupère et envoi le contenu de l'historique (typiquement vers le module "GlobalTerm") fun endDownload(file, o) : [S Ob] I;; Envoi une message d'enregistrement uprès du server une fois les ressources téléchargés. fun newOb(o) : fun [Ob] I;; Nouvelle instance. Télécharge les ressources. Reçoit le messages "register / registered" de et depuis le server, génère un event "in" du plugin pour le lier à "setTerm" du module globalTerm fun IniPlug(file) : fun[S] I;; Création de l'instance chez le client (appelée par le server). ***/ fun cbcomm(ui, action, param, p)= let p -> [z o] in if !strcmp action "incomingMsg" then if msgPass param then (let searchLogin param -> login in longueurMessageRecu z param 0 nil login; /*set messageTerm = param::messageTerm;*/ if openUrl then searchUrl o param else 0; verifLongHistoric param; verifLongMessageTerm z; if bMenuSave then saveMsgFile param else nil; 0) else 0 else if !strcmp action "broadInfo" then (set messageTerm = (strcat ">>> " param)::messageTerm; verifLongMessageTerm z; verifLongHistoric param; 0) else if !strcmp action "colorChanged" then let lineextr param -> [a[b _]] in (set cliColor = myreplace_in_list cliColor [a nil] [a atoi b]; 0) else if !strcmp action "addUser" then (let lineextr param -> [a[b _]] in set cliColor = [a atoi b]::cliColor; updatelist o; 0) else if !strcmp action "loginChanged" then (myreplace_login_in_listC cliColor param; UsendMessage ObUi o "updatedAv" nil; 0) else if !strcmp action "chgPseudo" then (chgLogin param; 0) else if !strcmp action "updateAv" then (updatelist o; 0) else if !strcmp action "donwloadSmileys" then (donwloadSmileys lineextr param; set setSmileys = 1) else 0;; fun activate(o, from, action, param, reply, z)= if !strcmp action (strcat class ".setTerm") then (set messageTerm = lineextr param; 0) else if !strcmp action (strcat class ".IgnoreFlag") then let lineextr param -> [type[id[name[state _]]]] in updateIgnoreList type name state else if !strcmp action (strcat class ".IgnChgLogin") then let lineextr param -> [oldName[newName _]] in updateLogin oldName newName else if !strcmp action (strcat class ".IgnLogout") then let lineextr param -> [id[name _]] in (set ignoreList = removef_from_list ignoreList @cliByLogin name; 0) else if !strcmp action (strcat class ".getLink") then (if param != nil then /* param = strbuild ("ref"::"link"::nil)::("userparam"::"code") */ let strextr param -> l in let hd switchstr l "ref" -> link in let atoi hd switchstr l "userParam" -> code in if code != 0 then fDisplayLink link /* lien sur un objet (code 1) ou avatar (code 2) */ else nil /* lien caché par un avatar ou lien invisible (code 0) */ else fDisplayLink nil; /* pas de lien à afficher */ 0) else if !strcmp action (strcat class ".enable") then (set ENterm3d = 1; set z.D_onoff = 1) else if !strcmp action (strcat class ".disable") then (set ENterm3d = 0; set z.D_onoff = 0) else 0;; fun cbRegistered (ui, action, param, o) = /* taille de la vue 3d */ let getView3dSize w3d -> [w3 h3] in /* lecture des données du fichier .dms */ let atoi hd UgetParam ObUi o "x" -> x in let atoi hd UgetParam ObUi o "y" -> y in let atoi hd UgetParam ObUi o "w" -> w in let atoi hd UgetParam ObUi o "h" -> h in let hd UgetParam ObUi o "font" -> fontS in let atoi hd UgetParam ObUi o "size" -> size in let atoi hd UgetParam ObUi o "color" -> fontColor in let hd UgetParam ObUi o "initTxt" -> initTxt in let _CRbitmap _channel w h -> fond in /* background du chat */ let h3-y-h -> y in /* l'y définit dans l'éditeur doit être la distance ente le bas du term et le bas de la 3d ... */ let mkData[x y w h fontS size 0 fontColor 1 fond] -> z in let atoi hd UgetParam ObUi o "xAvList" -> xAvList in let atoi hd UgetParam ObUi o "yAvList" -> yAvList in let atoi hd UgetParam ObUi o "wAvList" -> wAvList in let atoi hd UgetParam ObUi o "hAvList" -> zAvList in let atoi hd UgetParam ObUi o "colorHilite" -> colorHilite in ( set FSbottom = atoi hd UgetParam ObUi o "FSbottom"; set ChgCliSize = atoi hd UgetParam ObUi o "ChgCliSize"; set displayAvList = atoi hd UgetParam ObUi o "displayAvList"; set displayLinks = atoi hd UgetParam ObUi o "displayLinks"; set transparence = atoi hd UgetParam ObUi o "trans"; set displayCustomItem = atoi hd UgetParam ObUi o "customItem"; set nameCustomItem = hd UgetParam ObUi o "customItemName"; set displayAvListInit = displayAvList; set defaultSize = [x h3-h-y w h]; calculCoordAvList [xAvList yAvList wAvList zAvList]; set CoordAvListDefault = [xAvList yAvList wAvList zAvList]; /* définitions des com' intraplugin et avec les autres modules / plugins */ UcbComm this ObUi o mkfun4 @cbcomm [z o]; ObRegisterAction o (strcat class ".setTerm") mkfun6 @activate z; ObRegisterAction o (strcat class ".IgnoreFlag") mkfun6 @activate z; ObRegisterAction o (strcat class ".IgnChgLogin") mkfun6 @activate z; ObRegisterAction o (strcat class ".IgnLogout") mkfun6 @activate z; ObRegisterAction o (strcat class ".getLink") mkfun6 @activate z; ObRegisterAction o (strcat class ".enable") mkfun6 @activate z; ObRegisterAction o (strcat class ".disable") mkfun6 @activate z; /* callbacks internes au plugin */ ObCbPostRenderPriority o mkfun3 @cbBlitTerm [z] 100; ObCbControlKeyDown o mkfun3 @cbKey [z]; ObCbControlMove o @cbControlMove; set idMove = V3D_AddCBmouseMove mkfun4 @cbMoveWin [o z]; set idClic = V3D_AddCBmouseClick mkfun4 @cbClicWin [o z]; /* initialisation */ if initTxt == nil then set message = _loc this "term3d_initMessage" nil else set message = initTxt; let lineextr _getpack _checkpack fileColor -> [l1[l2[l3 _]]] in ( set color = if l1 == nil then z.D_color else atoi l1; set z.D_size = if l2 == nil then z.D_size else atoi l2; set z.D_type = if l3 == nil then z.D_type else atoi l3 ); set font = _CRfont _channel z.D_size 0 z.D_type z.D_font; set colorAv = z.D_color; set colorAvHilite = colorHilite; initKey; set fontAv = _CRfont _channel 12 0 0 "Arial"; set cpteurAv = 0; if displayAvList then updatelist o else nil; /*testCache;*/ /* not used : folder 'public' only ... */ 0 ) ;; fun _close()= V3D_RemoveCBmouseMove idMove; V3D_RemoveCBmouseClick idClic; dsBmp bmpAvBG::bmpLinksBG::lSmileyDisplayed; _DMSevent this strcat class ".getTerm" linebuild messageTerm nil; 0;; fun endDownload(file, p)= let p -> [o n] in (set nbRSC = nbRSC+n; if nbRSC == 2 then let lineextr _getpack _checkpack fileColor -> [col _] in /* correctif : ajout de la couleur au msg srv */ UsendMessage ObUi o "register" col else nil); 0;; fun endDownloadCursW(file)= let _LDbitmap _channel _checkpack file -> bmp in set TextCursorWIN = _CRcursor _channel bmp 0 16 0 0xFFFFFF; 0;; fun endDownloadCursM(file)= let _LDbitmap _channel _checkpack file -> bmp in set TextCursorMAC = _CRcursor _channel bmp 0 8 0 0xFFFFFF; 0;; fun newOb(o) = /* téléchargement des ressources */ let hd UgetParam ObUi o "pathBgAv" -> pathBgAv in (if pathBgAv == nil then set pathBgAv = "dms/3d/plugins/term3d/" else (if (strfind "/" pathBgAv (strlen pathBgAv)-2) == nil then set pathBgAv = strcat pathBgAv "/" else nil); set pathBgAvTop = strcat pathBgAv "top.jpg"; set pathBgAvDown = strcat pathBgAv "down.jpg"; _RSCdownload this pathBgAvTop pathBgAvTop (mkfun2 @endDownload [o 1]) 1; _RSCdownload this pathBgAvDown pathBgAvDown (mkfun2 @endDownload [o 1]) 1); _RSCdownload this "dms/3d/plugins/term3d/profcursor.bmp" "dms/3d/plugins/term3d/profcursor.bmp" @endDownloadCursW 1; _RSCdownload this "dms/3d/plugins/term3d/profcursorMAC.bmp" "dms/3d/plugins/term3d/profcursorMAC.bmp" @endDownloadCursM 1; UcbMessage ObUi o ["registered" mkfun4 @cbRegistered o]::nil; _DMSevent this strcat class ".in" nil nil; 0 ;; fun IniPlug(file)= set plugin=file; set class=getInfo strextr _getpack _checkpack file "name"; PlugRegister class @newOb @_close; 0 ;;