!7 module VoiceMatrix extends DynObjectTable { new TreeMap map; // module lib ID => "+" or "-" bool defaultOn = true; // for new modules start { ownResource(vmBus_onMessages(rstUpdate(), 'moduleDeleted, 'moduleLoaded)); } void update { for (O m : dm_listModules()) syncPutIfNotThere(map, dm_moduleLibID(m), "?"); setData(syncMap(map, func(S moduleID, S value) { litorderedmap( "Module ID" := moduleID, "Speech Output Enabled" := eq(value, "+") ? "Yes" : eq(value, "-") ? "No" : "Default (" + (defaultOn ? "Yes" : "No") + ")") })); } visualize { ret withUpdate(withCenteredLine(super.visualize(), tableDependButton(table, "Enable", r { setValue((S) firstValue(selected()), "+") }), tableDependButton(table, "Disable", r { setValue((S) firstValue(selected()), "-") }))); } void setValue(S moduleID, S value) { if (syncPut_trueIfChanged(map, moduleID, value)) persistMe(); } bool isModuleEnabled(O m) { S value = syncGet(map, dm_moduleLibID(m)); ret eq(value, "+" ) ? true : eq(value, "-") ? false : defaultOn; } }