From d1df08089a9ff2ffbf9f062a7469a5929bcee768 Mon Sep 17 00:00:00 2001 From: Spudmn Date: Tue, 8 Nov 2022 17:25:28 +1300 Subject: [PATCH] User Question Buttons This is an update to the user.prompt. It allows up to 3 optional buttons to be displayed. The button text is returned when clicked. A typical example. sAnswewr = user.prompt('Is the LED on?',text_input=False,button_1_text="Yes",button_2_text="No",button_3_text="Cancel") Will ask the question 'Is the LED on?' and the user can click "Yes", "No" or "Cancel" --- .../app/plugs/user-input-plug.component.html | 26 ++++++++++++++ .../app/plugs/user-input-plug.component.ts | 36 +++++++++++++++++++ openhtf/plugs/user_input.py | 28 ++++++++++++--- 3 files changed, 85 insertions(+), 5 deletions(-) diff --git a/openhtf/output/web_gui/src/app/plugs/user-input-plug.component.html b/openhtf/output/web_gui/src/app/plugs/user-input-plug.component.html index b82be7454..51e93b411 100644 --- a/openhtf/output/web_gui/src/app/plugs/user-input-plug.component.html +++ b/openhtf/output/web_gui/src/app/plugs/user-input-plug.component.html @@ -45,11 +45,37 @@
+ + + + + + +
diff --git a/openhtf/output/web_gui/src/app/plugs/user-input-plug.component.ts b/openhtf/output/web_gui/src/app/plugs/user-input-plug.component.ts index 2113d3985..056d42047 100644 --- a/openhtf/output/web_gui/src/app/plugs/user-input-plug.component.ts +++ b/openhtf/output/web_gui/src/app/plugs/user-input-plug.component.ts @@ -45,6 +45,10 @@ export declare interface UserInputPlugState { message: string; 'text-input': string; 'image-url': string; + 'is-user-question': string; + 'button-1-text': string; + 'button-2-text': string; + 'button-3-text': string; } /** @@ -99,6 +103,38 @@ export class UserInputPlugComponent extends BasePlug { return this.getPlugState()['image-url']; } + is_user_question() { + return (((this.getPlugState()['button-1-text'] !== null) && (this.getPlugState()['button-1-text'].length !== 0)) + ||((this.getPlugState()['button-2-text'] !== null) && (this.getPlugState()['button-2-text'].length !== 0)) + ||((this.getPlugState()['button-3-text'] !== null) && (this.getPlugState()['button-3-text'].length !== 0)) + ); + } + + + Button_1() { + return this.getPlugState()['button-1-text']; + } + + Button_2() { + return this.getPlugState()['button-2-text']; + } + + Button_3() { + return this.getPlugState()['button-3-text']; + } + + + sendAnswer(input: string) { + const promptId = this.getPlugState().id; + let response: string; + if (this.is_user_question()) { + response = input.trim(); + } else { + response = ''; + } + this.respond('respond', [promptId, response]); + } + sendResponse(input: HTMLInputElement) { const promptId = this.getPlugState().id; let response: string; diff --git a/openhtf/plugs/user_input.py b/openhtf/plugs/user_input.py index 37a21e32d..6aa5d68b2 100644 --- a/openhtf/plugs/user_input.py +++ b/openhtf/plugs/user_input.py @@ -59,6 +59,9 @@ class Prompt(object): message = attr.ib(type=Text) text_input = attr.ib(type=bool) image_url = attr.ib(type=Optional[Text], default=None) + button_1_text = attr.ib(type=Optional[Text], default=None) + button_2_text = attr.ib(type=Optional[Text], default=None) + button_3_text = attr.ib(type=Optional[Text], default=None) class ConsolePrompt(threading.Thread): @@ -156,7 +159,11 @@ def _asdict(self) -> Optional[Dict[Text, Any]]: return { 'id': self._prompt.id, 'message': self._prompt.message, - 'text-input': self._prompt.text_input + 'text-input': self._prompt.text_input, + 'image-url': self._prompt.image_url, + 'button-1-text': self._prompt.button_1_text, + 'button-2-text': self._prompt.button_2_text, + 'button-3-text': self._prompt.button_3_text } def tearDown(self) -> None: @@ -176,7 +183,10 @@ def prompt(self, text_input: bool = False, timeout_s: Union[int, float, None] = None, cli_color: Text = '', - image_url: Optional[Text] = None) -> Text: + image_url: Optional[Text] = None, + button_1_text: Optional[Text] = None, + button_2_text: Optional[Text] = None, + button_3_text: Optional[Text] = None) -> Text: """Display a prompt and wait for a response. Args: @@ -185,6 +195,7 @@ def prompt(self, timeout_s: Seconds to wait before raising a PromptUnansweredError. cli_color: An ANSI color code, or the empty string. image_url: Optional image URL to display or None. + button_x_text: Optional. Show up to 3 buttons. The button text is returned when clicked Returns: A string response, or the empty string if text_input was False. @@ -193,14 +204,17 @@ def prompt(self, MultiplePromptsError: There was already an existing prompt. PromptUnansweredError: Timed out waiting for the user to respond. """ - self.start_prompt(message, text_input, cli_color, image_url) + self.start_prompt(message, text_input, cli_color, image_url,button_1_text,button_2_text,button_3_text) return self.wait_for_prompt(timeout_s) def start_prompt(self, message: Text, text_input: bool = False, cli_color: Text = '', - image_url: Optional[Text] = None) -> Text: + image_url: Optional[Text] = None, + button_1_text: Optional[Text] = None, + button_2_text: Optional[Text] = None, + button_3_text: Optional[Text] = None) -> Text: """Display a prompt. Args: @@ -208,6 +222,7 @@ def start_prompt(self, text_input: A boolean indicating whether the user must respond with text. cli_color: An ANSI color code, or the empty string. image_url: Optional image URL to display or None. + button_x_text: Optional. Show up to 3 buttons. The button text is returned when clicked Raises: MultiplePromptsError: There was already an existing prompt. @@ -228,7 +243,10 @@ def start_prompt(self, id=prompt_id, message=message, text_input=text_input, - image_url=image_url) + image_url=image_url, + button_1_text=button_1_text, + button_2_text=button_2_text, + button_3_text=button_3_text) if sys.stdin.isatty(): self._console_prompt = ConsolePrompt( message, functools.partial(self.respond, prompt_id), cli_color)