Skip to content

Commit

Permalink
Document GUI Standards. (#7)
Browse files Browse the repository at this point in the history
* Document GUI Standards.

* update pics

* update view and docs

* move helper classes

* remove required style if default value
  • Loading branch information
searscr authored and ktactac-ornl committed Mar 5, 2024
1 parent 0a6218c commit f4fc2c9
Show file tree
Hide file tree
Showing 22 changed files with 477 additions and 6 deletions.
200 changes: 200 additions & 0 deletions docs/source/GUI_standards.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,200 @@
GUI Standards
**************

.. contents:: Table of Contents
:local:
:depth: 3

.. _gui_standards:


Validation Strategy
===================

GUI validation is a process aimed at ensuring the accuracy, functionality, and consistency of
the graphical elements within a software application's user interface. It involves systematically
examining and verifying that the graphical components, such as buttons, menus, and screens, behave
as intended and meet specified design standards. Enforcing consistency is a key aspect, ensuring
that the visual elements maintain a uniform appearance and behavior across different parts of
the application, contributing to a cohesive and user-friendly interface.

Effective GUI view validation is crucial for delivering a reliable and user-friendly software
product, ensuring that the visual elements not only meet design specifications but also contribute
to a positive and intuitive user experience. It is often an integral part of the software testing
process, providing assurance that the graphical interface functions seamlessly and enhances the
overall usability of the application.

Helper functions streamline and standardize validation in software development. By encapsulating
validation logic, they ensure consistency, reduce redundancy, and promote code reusability. These
functions simplify maintenance, enhance code readability, and contribute to a modular and scalable
code structure. We plan to create and implement these helper functions to optimize the validation
process in our software development practices.

Validation Items
================

Fields
######

In the user interface all fields will have tooltips with brief information about
the usage of the fields in the workflows. Additionally, a placeholder text with an
example value can be added in fields the describe complex ideas (e.g. x,y,z). The above
will guide the users seamlessly through the data input process while ensuring clarity and
adherence to form submission requirements.

.. figure:: images/optional.png
:align: center
:alt: Optional Fields

Optional Field with tooltip and placeholder text.


Required Fields
################

Required fields will be marked with an asterisk (*) at the end of the label. Required fields
with no default values (text fields) will feature a light yellow background, serving as a widely
adopted convention to visually cue users. This combination of visual indication, through both
asterisks and background color enhances user experience.

.. figure:: images/required.png
:align: center
:alt: Required Fields

Required Field with asterisk and light yellow background.

.. figure:: images/req-w-default.png
:align: center
:alt: Required Field with default value

Required Field with default value and tooltip.


Buttons
#######

In Qt applications, a best practice is to disable QPushButton, and similar objects,
when associated required fields are empty or fail validation. This approach prevents
users from attempting form submission with incomplete or incorrect data, promoting a
more user-friendly experience by guiding them to address validation issues before proceeding.
It ensures data integrity and contributes to a smoother interaction flow within the application.

Buttons should also be given meaningful names, such as “Load Experiment Plan” rather than
generic names like “Load”. If multiple buttons exist in the View, it should be clear to the
use which input/output fields correspond to each button. This can be achieved through grouping
fields and clear labels.

.. figure:: images/button-disabled.png
:align: center
:alt: Button invalid

Button with meaningful name and disabled state.

.. figure:: images/button-enabled.png
:align: center
:alt: Button valid

Button enabled after all fields are valid.

Field Validation
################

Implementing field validation with a red border for invalid entries is a visual cue
that enhances user feedback in interfaces. This approach communicates validation errors
immediately, aiding users in identifying and correcting input issues efficiently. The red
border not only draws attention to the problematic fields but also ensures a clear and
intuitive visual representation of where corrections are needed. Additionally, the status
bar will dynamically change to provide hints on how to rectify the validation errors,
contributing to a more user-friendly and error-tolerant design. The format of the message
will follow this convention:

<field_label1> : <error_message1>

<field_label2> : <error_message2>

Types of Validation
-------------------

Field Validation
++++++++++++++++

Field validation, includes basic checks such as checks for minimum and maximum values or
adherence to specific ranges, ensures data integrity in user input. This validation process
runs as data is entered and enables buttons to become active only when the entered data meets
predefined criteria.

.. figure:: images/1invalid.png
:align: center
:alt: Field Validation

Field validation with red border and status bar message for one invalid field.

.. figure:: images/2invalid.png
:align: center
:alt: Field Validation

Field validation with red border and status bar message for two invalid fields.


Data Input Validation
++++++++++++++++++++++++++

Data input validation occurs after enabling and pressing the button.
This type of validation requires more complexity and can include things such as checking
symmetry operations, valid file paths, and workspace existence. These inputs
may include multiple criteria and require more than a cursory check to ensure they meet the
underlying algorithm's requirements. If validation fails, the execution halts, prompting
the user to update the failing values before proceeding.

.. figure:: images/novalidation.png
:align: center
:alt: Data Input Validation

Data input validation will occur after the button has been enabled and pressed.

.. figure:: images/algo-fail-validation.png
:align: center
:alt: Data Input Validation

If a field fails validation after the button has been invoked, a popup will appear to notify
user and the field will be marked.

.. figure:: images/red-until-after.png
:align: center
:alt: Data Input Validation

After failing validation, button remains enabled and the fields that failed validation
will be marked until the button is pressed again.

.. figure:: images/all-valid.png
:align: center
:alt: Data Input Validation

After pressing the button, the field will be revalidated and if valid, the field
will be marked as valid and the algorith will run.

Common Validation Items
-----------------------

Implementing common field validations, such as minimum and maximum values, is essential
for data integrity. To streamline and reduce code redundancy, helper functions will be
created that are dedicated to these types of validation. These functions not only promote
consistency across the codebase but also enhance maintainability, making it easier to manage
and update validation rules consistently throughout the software application.

Error Handling
##############

Error handling involves utilizing both log messages and popups to enhance the debugging
process and user experience. Log messages provide users and developers with detailed
information about errors, warnings, and information for effective debugging. Popups
offer users clear and concise error notifications when a process ends prematurely or
with an error status, guiding users on how to proceed or address the issue. This dual
approach ensures a comprehensive error management system, promoting smoother application
functionality and facilitating efficient issue resolution.

.. figure:: images/error-popup.png
:align: center
:alt: Error Handling

Error handling with popup explaining the error.
Binary file added docs/source/images/1invalid.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/source/images/2invalid.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/source/images/algo-fail-validation.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/source/images/all-valid.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/source/images/button-disabled.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/source/images/button-enabled.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/source/images/error-popup.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/source/images/novalidation.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/source/images/optional.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/source/images/red-until-after.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/source/images/req-w-default.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/source/images/required.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions docs/source/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -45,3 +45,4 @@ Contents

getting_started
reference
GUI_standards
9 changes: 9 additions & 0 deletions docs/source/reference.rst
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,12 @@ Home

.. automodule:: garnet.home.model
:members:


Base Qt Objects
---------------
.. automodule:: garnet.helpers.ui_elements.base_lineedit
:members:

.. automodule:: garnet.helpers.ui_elements.base_statusbar
:members:
1 change: 1 addition & 0 deletions src/garnet/helpers/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
"""__init__.py"""
1 change: 1 addition & 0 deletions src/garnet/helpers/ui_elements/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
"""__init__.py"""
81 changes: 81 additions & 0 deletions src/garnet/helpers/ui_elements/base_lineedit.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
"""BaseLineEdit
------------
This module defines the BaseLineEdit class, a customized QLineEdit with setup and helper functions for
QLineEdits used in Garnet.
""" # noqa D205

from typing import Any, Optional

from qtpy.QtWidgets import QLineEdit, QWidget

INVALID_QLINEEDIT = """
QLineEdit {
border-color: red;
border-style: outset;
border-width: 2px;
border-radius: 4px;
padding-left: -1px;
padding-right: -1px;
padding-top: 1px;
padding-bottom: 1px;
}
"""

REQUIRED_QLINEEDIT = """
QLineEdit {
background-color: lightyellow;
}
"""


class BaseLineEdit(QLineEdit):
"""BaseLineEdit that inherits the QLineEdit.
This class includes setup and helper functions for QLineEdits used in Garnet.
:param required: Indicate whether the field is required. Defaults to False.
:type required: bool, optional
:param default_value: Set the default value for the field. Defaults to None.
:type default_value: Any, optional
:param parent: The parent object that holds the QLineEdit. Defaults to None.
:type parent: Any, optional
"""

def __init__(
self: Any,
required: Optional[bool] = False,
default_value: Optional[Any] = None, # noqa ANN401
parent: Optional[QWidget] = None,
) -> None:
"""Initialize the BaseLineEdit."""
super().__init__(parent)
self.required = required
self.default_value = default_value
if default_value is not None:
self.setText(str(default_value))
self.reset_style()

def set_invalid_style(self: Any) -> None:
"""Set field style as invalid
If a validator determines the field is invalid, this function will be called
and the field will be marked with a red border.
"""
self.setStyleSheet(INVALID_QLINEEDIT)

def set_required_style(self: Any) -> None:
"""If a field is required, the background will be set to light-yellow."""
self.setStyleSheet(REQUIRED_QLINEEDIT)

def set_empty_style(self: Any) -> None:
"""Once the field has been validated, the style will be cleared."""
self.setStyleSheet("")

def reset_style(self: Any) -> None:
"""Reset the style to its default."""
if self.required and self.default_value is None:
self.set_required_style()
else:
self.set_empty_style()
58 changes: 58 additions & 0 deletions src/garnet/helpers/ui_elements/base_statusbar.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
"""BaseStatusBar
-------------
This module defines the BaseStatusBar class, a custom status bar for PyQt applications.
The BaseStatusBar provides functionality for displaying error messages and additional information
through QLabel widgets. It includes methods to update the status label with error messages
and the CWE (Caution, Warnings or Error) label with relevant information.
""" # noqa D205

from typing import Any, Dict, Optional

from qtpy.QtWidgets import QLabel, QStatusBar, QWidget


class BaseStatusBar(QStatusBar):
"""Custom status bar for displaying error messages and additional information."""

def __init__(self: Any, parent: Optional[QWidget] = None) -> None:
"""Initialize the BaseStatusBar.
:param parent: The parent widget. Defaults to None.
:type parent: QWidget, optional
"""
super().__init__(parent)
self.error_text: Dict[object, str] = {}
self.setFixedWidth(600)
self.cwe_label = QLabel("", self)
self.status_label = QLabel("", self)
self.addWidget(self.status_label)
self.addPermanentWidget(self.cwe_label)

def update_status_label(self: Any, error_text: Optional[Dict[object, str]] = None) -> bool:
"""Update the status_label with the provided error_text.
:param error_text: Dictionary of error messages. Defaults to None.
:type error_text: Dict[object, str], optional
:return bool: True if there are any invalid entries, False otherwise.
"""
if error_text is not None:
for key in error_text:
self.error_text[key] = error_text[key]

self.error_text = {k: v for k, v in self.error_text.items() if v != ""}
has_invalid = any(self.error_text.values())
self.status_label.setText("\n".join(self.error_text.values()))
return has_invalid

def update_cwe_label(self: Any, text: str) -> None:
"""Update the cwe_label with the provided text.
:param text: The text to be displayed in the Caution, Warning, Error label.
:type text: str
"""
self.cwe_label.setText(text)
Loading

0 comments on commit f4fc2c9

Please sign in to comment.