abstract sclass DynAskUserQuestions extends DynModule { S question, answer; bool speak, listen; transient JButton btnSubmit; transient S lastHeard; start { dm_onTopInput_q(voidfunc(S s) { if (listen) { if "next question" ret with newQuestion(); if "no idea" { setField(answer := s); submit(); } if (isYes_1(s)) { submit(); ret; } lastHeard = s; setField(answer := s); dm_showYesToAcceptPopupAbove(btnSubmit); dm_sayInEnglish(s); } }); } visualize { if (empty(question)) newQuestion(); JLabel lblQ = fontSizePlus(3, makeBold(dm_fieldLabel('question))); componentPopupMenuItem(lblQ, "Suggest question...", r { inputText("Question", question, voidfunc(S s) { setField(question := s) }) }); ret withRightMargin(makeForm2( "", withBottomMargin(15, lblQ), "Human answer:", centerAndEastWithMargin(onEnter(dm_fieldTextField('answer), rThread submit), btnSubmit = jbutton("Submit", rThread submit)), "", withBottomMargin(withTopMargin(20, rightAlignedButtons( dm_checkBox('listen), dm_checkBox('speak), "Ask me something else", rThread newQuestion))))); } abstract S makeAQuestion(); void newQuestion enter { dm_hideYesPopupForComponent(btnSubmit); setFields(answer := "", question := makeAQuestion()); if (empty(question)) ret with infoBox("Got nothing to ask"); programLogStructure(litorderedmap(+question)); vmBus_send('showingQuestion, module(), question); if (speak) dm_sayWithAutoLanguage_splitAtQuotes(question); } void submit enter { dm_hideYesPopupForComponent(btnSubmit); programLogStructure(litorderedmap(+question, +answer)); vmBus_send('userAnsweredQuestion, module(), question, answer); dm_addQAndA(question, answer); infoBox(confirmationText()); if (speak) dm_sayInEnglish(eq(lastHeard, answer) ? "confirmed" : answer); newQuestion(); } S confirmationText() { ret "[saved] " + question + " => " + answer; } }