!7 sclass VoiceOutput > DynTextArea { S voice; transient JComboBox cbAnswerMode; start { if (empty(voice)) setField(voice := first(cereprocVoices())); set cereproc_printPageLoads; } visualize { bindComboBoxToLiveValue_debug.set(true); JComponent ta = super.visualize(); enableWordWrapForTextArea(textArea); jPreemptEnterKey(textArea, rThread sayIt); ret centerAndSouthWithMargins(ta, centerAndSouthWithMargin( centerAndEastWithMarginInbetween(withLabel("Voice:", jLiveValueComboBox(cereprocPlusLocalVoices(), dm_fieldLiveValue('voice))), jbutton("Say", rThread sayIt)), jrightAlignedLine(jlabel("AI should answer:"), jComboBoxOnTrimmedFileContents(ll("Always", "Sometimes", "Never"), ai_answerModeFile(), ai_answerModeDefault())))); } // API void say(S s) { temp enter(); { lock lock; setText(s); } sayIt(); } void sayIt { temp enter(); S s = trim(getText()); if (empty(s) || empty(voice)) ret; if (isCereprocVoice(voice)) cereproc(voice, s); else if (eq(voice, 'Kevin)) kevin(s); else print("Missing voice: " + voice); } void clear() { setText(""); } void setVoice(S voice) { setField(+voice); } void preload(S s) { if (isCereprocVoice(voice)) cereproc_preload(voice, s); } }