diff --git a/bec_widgets/widgets/text_box/text_box.py b/bec_widgets/widgets/text_box/text_box.py index f5785022..b1446d29 100644 --- a/bec_widgets/widgets/text_box/text_box.py +++ b/bec_widgets/widgets/text_box/text_box.py @@ -1,8 +1,30 @@ import re +from pydantic import Field, field_validator from qtpy.QtWidgets import QTextEdit -from bec_widgets.utils import BECConnector +from bec_widgets.utils.bec_connector import BECConnector, ConnectionConfig +from bec_widgets.utils.colors import Colors + + +class TextBoxConfig(ConnectionConfig): + + theme: str = Field("dark", description="The theme of the figure widget.") + font_color: str = Field("#FFF", description="The font color of the text") + background_color: str = Field("#000", description="The background color of the widget.") + font_size: int = Field(16, description="The font size of the text in the widget.") + text: str = Field("", description="The text to display in the widget.") + + @classmethod + @field_validator("theme") + def validate_theme(cls, v): + """Validate the theme of the figure widget.""" + if v not in ["dark", "light"]: + raise ValueError("Theme must be either 'dark' or 'light'") + return v + + _validate_font_color = field_validator("font_color")(Colors.validate_color) + _validate_background_color = field_validator("background_color")(Colors.validate_color) class TextBox(BECConnector, QTextEdit): @@ -10,48 +32,76 @@ class TextBox(BECConnector, QTextEdit): USER_ACCESS = ["set_color", "set_text", "set_font_size"] def __init__(self, text: str = "", parent=None, client=None, config=None, gui_id=None): + if config is None: + config = TextBoxConfig(widget_class=self.__class__.__name__) + else: + if isinstance(config, dict): + config = TextBoxConfig(**config) + self.config = config super().__init__(client=client, config=config, gui_id=gui_id) QTextEdit.__init__(self, parent=parent) + self.config = config self.setReadOnly(True) - self._background_color = "#FFF" - self._font_color = "#000" - self._font_size = 12 - self.set_color(self._background_color, self._font_color) self.setGeometry(self.rect()) - self._text = text + self.set_color(self.config.background_color, self.config.font_color) + if not text: + text = "

Welcome to the BEC Widget TextBox

A widget that allows user to display text in plain and HTML format.

This is an example of displaying HTML text.

" self.set_text(text) + def change_theme(self) -> None: + """ + Change the theme of the figure widget. + """ + if self.config.theme == "dark": + theme = "light" + font_color = "#000" + background_color = "#FFF" + else: + theme = "dark" + font_color = "#FFF" + background_color = "#000" + self.config.theme = theme + self.set_color(background_color, font_color) + def set_color(self, background_color: str, font_color: str) -> None: - """Set the background color of the Widget. + """Set the background color of the widget. Args: background_color (str): The color to set the background in HEX. font_color (str): The color to set the font in HEX. """ - self._background_color = background_color - self._font_color = font_color + self.config.background_color = background_color + self.config.font_color = font_color self._update_stylesheet() def set_font_size(self, size: int) -> None: - """Set the font size of the text in the Widget.""" - self._font_size = size + """Set the font size of the text in the widget. + + Args: + size (int): The font size to set. + """ + self.config.font_size = size self._update_stylesheet() def _update_stylesheet(self): """Update the stylesheet of the widget.""" self.setStyleSheet( - f"background-color: {self._background_color}; color: {self._font_color}; font-size: {self._font_size}px" + f"background-color: {self.config.background_color}; color: {self.config.font_color}; font-size: {self.config.font_size}px" ) def set_text(self, text: str) -> None: - """Set the text of the Widget""" + """Set the text of the widget. + + Args: + text (str): The text to set. + """ if self.is_html(text): self.setHtml(text) else: self.setPlainText(text) - self._text = text + self.config.text = text def is_html(self, text: str) -> bool: """Check if the text contains HTML tags. diff --git a/tests/unit_tests/test_text_box_widget.py b/tests/unit_tests/test_text_box_widget.py index 95fa0877..51af87a4 100644 --- a/tests/unit_tests/test_text_box_widget.py +++ b/tests/unit_tests/test_text_box_widget.py @@ -18,26 +18,38 @@ def text_box_widget(qtbot, mocked_client): def test_textbox_widget(text_box_widget): - - text_box_widget.set_text("Hello World!") - # pylint: disable=protected-access - assert text_box_widget._text == "Hello World!" + """Test the TextBox widget.""" + text = "Hello World!" + text_box_widget.set_text(text) + assert text_box_widget.toPlainText() == text text_box_widget.set_color("#FFDDC1", "#123456") text_box_widget.set_font_size(20) assert ( text_box_widget.styleSheet() == "background-color: #FFDDC1; color: #123456; font-size: 20px" ) + text_box_widget.set_color("white", "blue") + text_box_widget.set_font_size(14) + assert text_box_widget.styleSheet() == "background-color: white; color: blue; font-size: 14px" + text = "

Welcome to PyQt6

This is an example of displaying HTML text.

" + with mock.patch.object(text_box_widget, "setHtml") as mocked_set_html: + text_box_widget.set_text(text) + assert mocked_set_html.call_count == 1 + assert mocked_set_html.call_args == mock.call(text) - with mock.patch.object(text_box_widget, "setHtml") as mock_set_plain_text: - text_box_widget.set_text( - "

Welcome to PyQt6

This is an example of displaying HTML text.

" - ) - assert mock_set_plain_text.call_args == mock.call( - "

Welcome to PyQt6

This is an example of displaying HTML text.

" - ) - # pylint: disable=protected-access - assert ( - text_box_widget._text - == "

Welcome to PyQt6

This is an example of displaying HTML text.

" - ) + +def test_textbox_change_theme(text_box_widget): + """Test change theme functionaility""" + # Default is dark theme + text_box_widget.change_theme() + assert text_box_widget.config.theme == "light" + assert ( + text_box_widget.styleSheet() + == f"background-color: #FFF; color: #000; font-size: {text_box_widget.config.font_size}px" + ) + text_box_widget.change_theme() + assert text_box_widget.config.theme == "dark" + assert ( + text_box_widget.styleSheet() + == f"background-color: #000; color: #FFF; font-size: {text_box_widget.config.font_size}px" + )