From 45ad64424c0bd0c27955e94295a20cb301124d34 Mon Sep 17 00:00:00 2001 From: Ro Date: Thu, 8 Feb 2024 14:45:06 -0500 Subject: [PATCH] WIP: styling --- .../gui/conversation/export/export_wizard.py | 50 +++++------ .../conversation/export/export_wizard_page.py | 18 ++-- .../gui/conversation/export/wizard.css | 23 ++---- .../gui/conversation/export/wizard_button.css | 82 +++++++------------ .../conversation/export/wizard_message.css | 4 +- 5 files changed, 66 insertions(+), 111 deletions(-) diff --git a/client/securedrop_client/gui/conversation/export/export_wizard.py b/client/securedrop_client/gui/conversation/export/export_wizard.py index ee50efbd9c..839406d7c1 100644 --- a/client/securedrop_client/gui/conversation/export/export_wizard.py +++ b/client/securedrop_client/gui/conversation/export/export_wizard.py @@ -33,6 +33,7 @@ class ExportWizard(QWizard): FILENAME_WIDTH_PX = 260 FILE_OPTIONS_FONT_SPACING = 1.6 BUTTON_CSS = resource_string(__name__, "wizard_button.css").decode("utf-8") + WIZARD_CSS = resource_string(__name__, "wizard.css").decode("utf-8") # If the drive is unlocked, we don't need a passphrase; if we do need one, # it's populated later. @@ -73,62 +74,53 @@ def text(self) -> str: def _style_buttons(self) -> None: button_font = QFont() - button_font.setLetterSpacing( - QFont.AbsoluteSpacing, self.FILE_OPTIONS_FONT_SPACING - ) + button_font.setLetterSpacing(QFont.AbsoluteSpacing, self.FILE_OPTIONS_FONT_SPACING) self.next_button = self.button(QWizard.WizardButton.NextButton) - self.next_button.setMinimumSize(QSize(142, 43)) - self.next_button.clicked.connect(self.request_export) + self.next_button.setObjectName("QWizardButton_PrimaryButton") self.next_button.setStyleSheet(self.BUTTON_CSS) - self.next_button.setText(_("CONTINUE")) - self.next_button.setFont(button_font) + self.next_button.setMinimumSize(QSize(130, 24)) + self.next_button.clicked.connect(self.request_export) self.cancel_button = self.button(QWizard.WizardButton.CancelButton) + self.cancel_button.setObjectName("QWizardButton_GenericButton") self.cancel_button.setStyleSheet(self.BUTTON_CSS) - self.cancel_button.setMinimumSize(QSize(142, 43)) - self.cancel_button.setText(_("CANCEL")) - self.cancel_button.setFont(button_font) - + self.cancel_button.setMinimumSize(QSize(130, 24)) + self.back_button = self.button(QWizard.WizardButton.BackButton) + self.back_button.setObjectName("QWizardButton_GenericButton") self.back_button.setStyleSheet(self.BUTTON_CSS) - self.back_button.setMinimumSize(QSize(142, 43)) - self.back_button.setText(_("BACK")) # TODO - self.back_button.setFont(button_font) + self.back_button.setMinimumSize(QSize(130, 24)) self.finish_button = self.button(QWizard.WizardButton.FinishButton) - self.finish_button.setMinimumSize(QSize(142, 43)) + self.finish_button.setObjectName("QWizardButton_GenericButton") + self.finish_button.setMinimumSize(QSize(135, 25)) self.finish_button.setStyleSheet(self.BUTTON_CSS) - self.finish_button.setText(_("DONE")) - self.finish_button.setFont(button_font) - # Activestate animation self.button_animation = load_movie("activestate-wide.gif") self.button_animation.setScaledSize(QSize(32, 32)) self.button_animation.frameChanged.connect(self.animate_activestate) + # It's not button styling. I wish I could tell you why. + self.setButtonText(self.next_button, _("CONTINUE")) + self.setButtonText(self.cancel_button, _("CANCEL")) + self.setButtonText(self.finish_button, _("DONE")) + self.setButtonText(self.back_button, _("BACK")) # TODO + def animate_activestate(self) -> None: self.next_button.setIcon(QIcon(self.button_animation.currentPixmap())) def start_animate_activestate(self) -> None: self.button_animation.start() - self.next_button.setMinimumSize(QSize(142, 43)) - # Reset widget stylesheets - self.next_button.setStyleSheet("") - self.next_button.setObjectName("ModalDialog_primary_button_active") - self.next_button.setStyleSheet(self.BUTTON_CSS) def stop_animate_activestate(self) -> None: self.next_button.setIcon(QIcon()) self.button_animation.stop() - # Reset widget stylesheets - self.next_button.setStyleSheet("") - self.next_button.setObjectName("ModalDialog_primary_button") - self.next_button.setStyleSheet(self.BUTTON_CSS) def _set_layout(self) -> None: self.setWindowTitle(f"Export {self.summary_text}") + self.setStyleSheet(self.WIZARD_CSS) self.setModal(False) self.setOptions( QWizard.NoBackButtonOnLastPage @@ -146,10 +138,6 @@ def _set_pages(self) -> None: ]: self.setPage(id, page) - # Nice to have, but steals the focus from the password field after 1 character is typed. - # Probably another way to have it be based on validating the status - # page.completeChanged.connect(lambda: self._set_focus(QWizard.WizardButton.NextButton)) - @pyqtSlot(int) def _set_focus(self, which: QWizard.WizardButton) -> None: self.button(which).setFocus() diff --git a/client/securedrop_client/gui/conversation/export/export_wizard_page.py b/client/securedrop_client/gui/conversation/export/export_wizard_page.py index a9d8dca835..ce091fcd37 100644 --- a/client/securedrop_client/gui/conversation/export/export_wizard_page.py +++ b/client/securedrop_client/gui/conversation/export/export_wizard_page.py @@ -93,25 +93,25 @@ def _build_layout(self) -> QVBoxLayout: header_container_layout = QHBoxLayout() header_container.setLayout(header_container_layout) self.header_icon = SvgLabel("blank.svg", svg_size=QSize(64, 64)) - self.header_icon.setObjectName("ModalDialog_header_icon") + self.header_icon.setObjectName("QWizard_header_icon") self.header_spinner = QPixmap() self.header_spinner_label = QLabel() - self.header_spinner_label.setObjectName("ModalDialog_header_spinner") + self.header_spinner_label.setObjectName("QWizard_header_spinner") self.header_spinner_label.setMinimumSize(64, 64) self.header_spinner_label.setVisible(False) self.header_spinner_label.setPixmap(self.header_spinner) self.header = QLabel() - self.header.setObjectName("ModalDialog_header") + self.header.setObjectName("QWizard_header") header_container_layout.addWidget(self.header, alignment=Qt.AlignCenter) header_container_layout.addWidget(self.header_icon) header_container_layout.addWidget(self.header_spinner_label) header_container_layout.addStretch() self.header_line = QWidget() - self.header_line.setObjectName("ModalDialog_header_line") + self.header_line.setObjectName("QWizard_header_line") # Body to display instructions and forms self.body = QLabel() - self.body.setObjectName("ModalDialog_body") + self.body.setObjectName("QWizard_body") self.body.setWordWrap(True) self.body.setScaledContents(True) @@ -127,7 +127,7 @@ def _build_layout(self) -> QVBoxLayout: # Widget for displaying error messages (hidden by default) self.error_details = QLabel() - self.error_details.setObjectName("ModalDialog_error_details") + self.error_details.setObjectName("QWizard_error_details") self.error_details.setStyleSheet(self.ERROR_DETAILS_CSS) self.error_details.setContentsMargins( self.NO_MARGIN, self.NO_MARGIN, self.NO_MARGIN, self.NO_MARGIN @@ -163,7 +163,7 @@ def animate_activestate(self) -> None: def start_animate_activestate(self) -> None: self.error_details.setStyleSheet("") - self.error_details.setObjectName("ModalDialog_error_details_active") + self.error_details.setObjectName("QWizard_error_details_active") self.error_details.setStyleSheet(self.ERROR_DETAILS_CSS) def start_animate_header(self) -> None: @@ -173,7 +173,7 @@ def start_animate_header(self) -> None: def stop_animate_activestate(self) -> None: self.error_details.setStyleSheet("") - self.error_details.setObjectName("ModalDialog_error_details") + self.error_details.setObjectName("QWizard_error_details") self.error_details.setStyleSheet(self.ERROR_DETAILS_CSS) def stop_animate_header(self) -> None: @@ -394,7 +394,7 @@ def _build_layout(self) -> QVBoxLayout: # Passphrase Form self.passphrase_form = QWidget() - self.passphrase_form.setObjectName("ModalDialog_passphrase_form") + self.passphrase_form.setObjectName("QWizard_passphrase_form") passphrase_form_layout = QVBoxLayout() passphrase_form_layout.setContentsMargins( self.NO_MARGIN, self.NO_MARGIN, self.NO_MARGIN, self.NO_MARGIN diff --git a/client/securedrop_client/gui/conversation/export/wizard.css b/client/securedrop_client/gui/conversation/export/wizard.css index 1814ed903d..214cadd5e0 100644 --- a/client/securedrop_client/gui/conversation/export/wizard.css +++ b/client/securedrop_client/gui/conversation/export/wizard.css @@ -1,4 +1,4 @@ -#ModalDialog { +#QWizard { min-width: 800px; max-width: 800px; min-height: 300px; @@ -6,7 +6,7 @@ background-color: #fff; } -#ModalDialog_header_icon, #ModalDialog_header_spinner { +#QWizard_header_icon, #QWizard_header_spinner { min-width: 80px; max-width: 80px; min-height: 64px; @@ -14,7 +14,7 @@ margin: 0px 0px 0px 30px; } -#ModalDialog_header { +#QWizard_header { min-height: 68px; max-height: 68px; margin: 0; @@ -24,7 +24,7 @@ color: #2a319d; } -#ModalDialog_header_line { +#QWizard_header_line { margin: 0; min-height: 2px; max-height: 2px; @@ -32,7 +32,7 @@ border: none; } -#ModalDialog_body { +#QWizard_body { font-family: 'Montserrat'; font-size: 16px; color: #302aa3; @@ -40,7 +40,7 @@ padding: 0; } -#ModalDialogConfirmation { +#QWizardConfirmation { font-family: 'Montserrat'; font-size: 16px; font-weight: 600; @@ -48,15 +48,8 @@ margin: 0; } -#ModalDialog.dangerous #ModalDialogConfirmation { - color: #ff3366; -} - -#ModalDialog_button_box { - border: 1px solid #ff0000; -} -#ModalDialog_button_box QPushButton { +#QWizard_button_box QWizardButton { margin: 0px 0px 0px 12px; height: 40px; margin: 0; @@ -69,7 +62,7 @@ color: #2a319d; } -#ModalDialog_button_box QPushButton::disabled { +#QWizard_button_box QWizardButton::disabled { border: 2px solid rgba(42, 49, 157, 0.4); color: rgba(42, 49, 157, 0.4); } diff --git a/client/securedrop_client/gui/conversation/export/wizard_button.css b/client/securedrop_client/gui/conversation/export/wizard_button.css index bc2f04526c..605a055692 100644 --- a/client/securedrop_client/gui/conversation/export/wizard_button.css +++ b/client/securedrop_client/gui/conversation/export/wizard_button.css @@ -1,71 +1,45 @@ -#QWizard_button_box QWizardButton#QWizard_primary_button { +#QWizardButton_PrimaryButton { background-color: #2a319d; - color: #fff; + color: #f1f1f6; + border: 2px solid #2a319d; font-family: 'Montserrat'; + font-weight: 500; + margin: 0px; + font-size: 15px; + padding: 11px 18px; + height: 24px; } -#QWizard_button_box QWizardButton#QWizard_primary_button::disabled { - border: 2px solid #c2c4e3; - background-color: #c2c4e3; - color: #e1e2f1; - font-family: 'Montserrat'; +#QWizardButton_PrimaryButton:hover { + background-color: #05a6fe; + border: 2px solid #05a6fe; } -#QWizard_button_box QWizardButton#QWizard_primary_button_active { - background-color: #f1f1f6; - color: #fff; - border: 2px solid #f1f1f6; - margin: 0; - height: 40px; - font-family: 'Montserrat'; +#QWizardButton_PrimaryButton:disabled { + border: 2px solid rgba(42, 49, 157, 0.4); + background-color: 2px solid rgba(42, 49, 157, 0.4); + color: #c2c4e3; } - -QWizard.WizardButton.NextButton { - background-color: #2a319d; - color: #fff; - font-family: 'Montserrat'; -} - -QWizard.WizardButton.NextButton::active { +#QWizardButton_GenericButton { background-color: #f1f1f6; - color: #fff; - border: 2px solid #f1f1f6; + color: #2a319d; + border: 2px solid #2a319d; margin: 0; - height: 40px; + height: 24px; font-family: 'Montserrat'; + font-weight: 500; + font-size: 15px; + padding: 11px 18px; } -#QWizardButton#QWizard_primary_button::disabled { +#QWizardButton_GenericButton:hover { + color: #05a6fe; + border: 2px solid #05a6fe; +} + +#QWizardButton_GenericButton:disabled { border: 2px solid #c2c4e3; background-color: #c2c4e3; color: #e1e2f1; - font-family: 'Montserrat'; -} - -QWizard.WizardButton.BackButton { - background-color: #f1f1f6; - color: #fff; - border: 2px solid #f1f1f6; - margin: 0; - height: 40px; - font-family: 'Montserrat'; -} - -QWizard.WizardButton.FinishedButton { - background-color: #f1f1f6; - color: #fff; - border: 2px solid #f1f1f6; - margin: 0; - height: 40px; - font-family: 'Montserrat'; -} - -QWizard.WizardButton.NextButton { - background-color: #f1f1f6; - color: #fff; - border: 2px solid #f1f1f6; - margin: 0; - height: 40px; - font-family: 'Montserrat'; } diff --git a/client/securedrop_client/gui/conversation/export/wizard_message.css b/client/securedrop_client/gui/conversation/export/wizard_message.css index 20415fe9b9..fa0aa8d355 100644 --- a/client/securedrop_client/gui/conversation/export/wizard_message.css +++ b/client/securedrop_client/gui/conversation/export/wizard_message.css @@ -1,11 +1,11 @@ -#ModalDialog_error_details { +#QWizard_error_details { margin: 0px 40px 0px 36px; font-family: 'Montserrat'; font-size: 16px; color: #ff0064; } -#ModalDialog_error_details_active { +#QWizard_error_details_active { margin: 0px 40px 0px 36px; font-family: 'Montserrat'; font-size: 16px;