// MenuDataController // Responsable for interpreting the content, summary and category // data sent to it and displaying it on the MenuTextArea // it also is responsable for performing the actions that occur // when a line button is pressed that corresponds to menu data. // Copyright (C) 2005-2006 Francisco V. Saldana // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU 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 General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. // // Francisco V. Saldana can be contacted using his email account // username: dressedinblue, at domain: gmail.com // and in Second Life by IMming Christopher Omega string NULL = ""; list replaceListSlice(list dest, list src, integer start) { if (llGetListEntryType(dest, start - 1) == TYPE_INVALID) { integer len; for(len = llGetListLength(dest); len < start; len++) { dest += NULL; } } integer srcLen = llGetListLength(src); return llListInsertList(llDeleteSubList(dest, start, start + srcLen - 1), src, start); } // ========== For method invocation ========== string randomStr(string chars, integer len) { integer numChars = llStringLength(chars); string ret; integer i; for (i = 0; i < len; i++) { integer randIndex = llFloor(llFrand(numChars)); ret += llGetSubString(chars, randIndex, randIndex); } return ret; } string SEPERATOR_CHARS = "`~!@#$%^&*()-_+[]{}\|'\";/?.>,<"; integer SEPERATOR_LEN = 3; string dumpList2String(list src) { // Generate a seperator not present in any of the // elements in the list. string chars = (string) src; // Squashes all elements together. string seperator; do { seperator = randomStr(SEPERATOR_CHARS, SEPERATOR_LEN); } while (llSubStringIndex(chars, seperator) != -1); return seperator + llDumpList2String(src, seperator); } list parseStringKeepNulls(string src) { // The seperator should be the first SEPERATOR_LEN // characters in the string. return llParseStringKeepNulls(llDeleteSubString(src, 0, SEPERATOR_LEN - 1), [llGetSubString(src, 0, SEPERATOR_LEN - 1)], []); } callMethod(integer callId, string methodName, list parameters) { llMessageLinked(LINK_THIS, callId, dumpList2String(parameters), methodName); } returnValue(string methodName, integer methodIdentifyer, list value) { llMessageLinked(LINK_THIS, methodIdentifyer, dumpList2String(value), methodName + "_ret"); } // ============================================= // For displaying incoming data: trigger_setScreenWriter(string moduleName) { callMethod(0, "setScreenWriter", [moduleName]); } trigger_setMenuLineText(string moduleName, integer line, string text) { callMethod(0, "setMenuLineText", [moduleName, line, text]); } trigger_setMenuLineColor(string moduleName, integer line, vector color) { callMethod(0, "setMenuLineColor", [moduleName, line, color]); } trigger_cls(string moduleName) { callMethod(0, "cls", [moduleName]); } trigger_enableMenuLineButton(string moduleName, integer lineNumber) { callMethod(0, "enableMenuLineButton", [moduleName, lineNumber]); } trigger_disableAllMenuLineButtons(string moduleName) { callMethod(0, "disableAllMenuLineButtons", [moduleName]); } trigger_setButtonWriter(string moduleName) { callMethod(0, "setButtonWriter", [moduleName]); } // For reacting to user's request: trigger_requestMenuCategory(integer id) { callMethod(0, "requestMenuCategory", [id]); } trigger_requestMenuSummary(integer id) { callMethod(0, "requestMenuSummary", [id]); } trigger_keywordSearch(key searcher) { callMethod(0, "keywordSearch", [searcher]); } trigger_sendRepositoryContent(key destination, integer id) { callMethod(0, "sendRepositoryContent", [destination, id]); } trigger_pong(string moduleName) { callMethod(0, "pong", [moduleName]); } integer DETECTED_GROUP = 1001; integer DETECTED_KEY = 1002; integer DETECTED_NAME = 1004; integer DETECTED_POS = 1006; integer DETECTED_ROT = 1007; // Asssists with getting values from buttonPressed event's detected data. string getDetectedValue(list detectedData, integer detectedConstant) { integer index = llListFindList(detectedData, [(string) detectedConstant]); if (index != -1) { return llList2String(detectedData, index + 1); } return ""; } integer TYPE_DISABLED = 0; integer TYPE_CATEGORY = 1; integer TYPE_SUMMARY = 2; integer TYPE_CONTENT = 3; integer TYPE_SEARCH = 4; // Maps the line number of the button to // the button's function (what the button // will trigger when it is pressed.) list buttonTypes; // Contains any parameters used for the button's // function, each index in this list corresponds // to an index in the buttonTypes list, and contains // a dumped list of parameters. list buttonParams; // Contains the next available line on the screen // to write data to. integer nextLine = 0; // Clears any data pertaining to the currently displayed // menu. clearMenuData() { buttonTypes = []; buttonParams = []; nextLine = 0; } writeLine(string text, vector color, integer buttonType, list buttonParamList) { if (buttonType != TYPE_DISABLED) { trigger_enableMenuLineButton(this, nextLine); } trigger_setMenuLineColor(this, nextLine, color); trigger_setMenuLineText(this, nextLine, text); buttonTypes = replaceListSlice(buttonTypes, [buttonType], nextLine); buttonParams = replaceListSlice(buttonParams, [dumpList2String(buttonParamList)], nextLine); nextLine++; } // For readability: integer LIST_INDEX_NOT_FOUND = -1; string this; default { state_entry() { this = llGetScriptName(); state main; } } state main { link_message(integer sender, integer num, string parameters, key methodName) { if (methodName == "receivedMenuCategory") { list paramList = parseStringKeepNulls(parameters); // Method signature: // receivedMenuCategory(string menu, string categoryName, integer categoryID) string menu = llList2String(paramList, 0); string categoryName = llList2String(paramList, 1); integer categoryID = (integer) llList2String(paramList, 2); writeLine("<- " + categoryName, <0, 1, 0>, TYPE_CATEGORY, [categoryID]); } else if (methodName == "receivedMenuContent") { list paramList = parseStringKeepNulls(parameters); // Method signature // receivedMenuContent(string menu, string contentTitle, integer contentID) string menu = llList2String(paramList, 0); string contentTitle = llList2String(paramList, 1); integer contentID = (integer) llList2String(paramList, 2); writeLine("<- \"" + contentTitle + "\"", <0, 0, 1>, TYPE_CONTENT, [contentID]); } else if (methodName == "receivedMenuSummary") { list paramList = parseStringKeepNulls(parameters); // Method signature: // receivedMenuSummary(string menu, string summaryName, integer summaryID) string menu = llList2String(paramList, 0); string summaryName = llList2String(paramList, 1); integer summaryID = (integer) llList2String(paramList, 2); writeLine("<- " + summaryName, <1, 0, 0>, TYPE_SUMMARY, [summaryID]); } else if (methodName == "receivedMenuText") { list paramList = parseStringKeepNulls(parameters); // Method signature: // receivedMenuText(string menu, string text) string menu = llList2String(paramList, 0); string text = llList2String(paramList, 1); writeLine(text, <1, 1, 1>, TYPE_DISABLED, []); } else if (methodName == "receivedMenuKeywordSearch") { list paramList = parseStringKeepNulls(parameters); // Method signature: // receivedMenuKeywordSearch(string menu, string displayText) string displayText = llList2String(paramList, 1); writeLine("<- " + displayText, <1, 1, 1>, TYPE_SEARCH, []); } else if (methodName == "receivedMenuBegin") { list paramList = parseStringKeepNulls(parameters); // Method signature: // receivedMenuBegin(string menuName, string menuTitle) string menuName = llList2String(paramList, 0); string menuTitle = llList2String(paramList, 1); trigger_setScreenWriter(this); trigger_setButtonWriter(this); trigger_cls(this); trigger_disableAllMenuLineButtons(this); clearMenuData(); if (menuTitle != "") { writeLine(menuTitle, <1, 1, 1>, TYPE_DISABLED, []); } } else if (methodName == "menuLineButtonPressed") { list paramList = parseStringKeepNulls(parameters); // Method signature: // lineButtonPressed(integer lineNumber, list detectedData) integer lineNumber = (integer) llList2String(paramList, 0); list detectedData = parseStringKeepNulls(llList2String(paramList, 1)); key pusher = (key) getDetectedValue(detectedData, DETECTED_KEY); integer buttonType = llList2Integer(buttonTypes, lineNumber); list buttonParams = parseStringKeepNulls(llList2String(buttonParams, lineNumber)); if (buttonType == TYPE_CATEGORY) { integer id = (integer) llList2String(buttonParams, 0); trigger_requestMenuCategory(id); } else if (buttonType == TYPE_SUMMARY) { integer id = (integer) llList2String(buttonParams, 0); trigger_requestMenuSummary(id); } else if (buttonType == TYPE_CONTENT) { integer id = (integer) llList2String(buttonParams, 0); trigger_sendRepositoryContent(pusher, id); } else if (buttonType == TYPE_SEARCH) { trigger_keywordSearch(pusher); } } else if (methodName == "ping") { list paramList = parseStringKeepNulls(parameters); // Method signature: // ping(string moduleName) string moduleName = llList2String(paramList, 0); if (moduleName == this) trigger_pong(this); } } }