diff --git a/configure.py b/configure.py index 965ed23..786631e 100644 --- a/configure.py +++ b/configure.py @@ -29,12 +29,7 @@ def parse_args(argv=None): '''Parse the command-line options.''' parser = argparse.ArgumentParser(description='Styles to configure for a Qt application.') - parser.add_argument( - '-v', - '--version', - action='version', - version=f'%(prog)s {__version__}' - ) + parser.add_argument('-v', '--version', action='version', version=f'%(prog)s {__version__}') parser.add_argument( '--styles', help='comma-separate list of styles to configure. pass `all` to build all themes', @@ -68,12 +63,10 @@ def parse_args(argv=None): 'Note: building for PyQt6 requires PySide6-rcc to be installed.' ), choices=['pyqt5', 'pyqt6', 'pyside2', 'pyside6'], - default='pyqt5' + default='pyqt5', ) parser.add_argument( - '--clean', - help='clean dist directory prior to configuring themes.', - action='store_true' + '--clean', help='clean dist directory prior to configuring themes.', action='store_true' ) parser.add_argument( '--rcc', @@ -81,7 +74,7 @@ def parse_args(argv=None): 'path to the rcc executable. ' 'Overrides rcc of chosen framework. ' 'Only use if system cannot find the rcc exe.' - ) + ), ) parser.add_argument( '--compiled-resource', @@ -135,11 +128,13 @@ def read_template_dir(directory): # Need to find all the values inside the image. keys = re.findall(r'\^[0-9a-zA-Z_-]+\^', svg) replacements = [i[1:-1] for i in keys] - data['icons'].append({ - 'name': name, - 'svg': svg, - 'replacements': replacements, - }) + data['icons'].append( + { + 'name': name, + 'svg': svg, + 'replacements': replacements, + } + ) return data @@ -262,11 +257,11 @@ def replace_by_index(contents, theme, colors): # parse the color, get the correct value, and use only that # for the replacement. if key.endswith(':hex'): - color = theme[key[:-len(':hex')]] + color = theme[key[: -len(':hex')]] rgb = [f'{i:02x}' for i in parse_color(color)[:3]] value = f'#{"".join(rgb)}' elif key.endswith(':opacity'): - color = theme[key[:-len(':opacity')]] + color = theme[key[: -len(':opacity')]] value = str(parse_color(color)[3]) else: value = theme[key] @@ -384,7 +379,10 @@ def compile_resource(args): 'Required rcc for PySide6 & PyQt6: PySide6-rcc', 'Required rcc for PySide2: PySide2-rcc', '', - 'if using venv, activate it or provide path to rcc.', sep='\n', file=sys.stderr) + 'if using venv, activate it or provide path to rcc.', + sep='\n', + file=sys.stderr, + ) raise SystemExit from error if args.qt_framework == 'pyqt6': @@ -398,12 +396,7 @@ def configure(args): shutil.rmtree(args.output_dir, ignore_errors=True) # Need to convert our styles accordingly. - config = { - 'themes': {}, - 'templates': [], - 'no_qrc': args.no_qrc, - 'resource': args.resource - } + config = {'themes': {}, 'templates': [], 'no_qrc': args.no_qrc, 'resource': args.resource} config['templates'].append(read_template_dir(template_dir)) for style in args.styles: config['themes'][style] = load_json(f'{theme_dir}/{style}.json') diff --git a/example/advanced-dock.py b/example/advanced-dock.py index 1ecdf67..693f6cd 100644 --- a/example/advanced-dock.py +++ b/example/advanced-dock.py @@ -37,15 +37,13 @@ parser = shared.create_parser() parser.add_argument( - '--use-internal', - help='''use the dock manager internal stylesheet.''', - action='store_true' + '--use-internal', help='''use the dock manager internal stylesheet.''', action='store_true' ) # https://github.com/githubuser0xFFFF/Qt-Advanced-Docking-System/blob/master/doc/user-guide.md#configuration-flags parser.add_argument( '--focus-highlighting', help='''use the focus highlighting (and other configuration flags).''', - action='store_true' + action='store_true', ) # setConfigFlag args, unknown = shared.parse_args(parser) diff --git a/example/branchless/application.py b/example/branchless/application.py index 379bb71..94fbeef 100644 --- a/example/branchless/application.py +++ b/example/branchless/application.py @@ -77,18 +77,9 @@ def main(): # setup ui ui = widgets.Ui() ui.setup(window) - ui.bt_delay_popup.addActions([ - ui.actionAction, - ui.actionAction_C - ]) - ui.bt_instant_popup.addActions([ - ui.actionAction, - ui.actionAction_C - ]) - ui.bt_menu_button_popup.addActions([ - ui.actionAction, - ui.actionAction_C - ]) + ui.bt_delay_popup.addActions([ui.actionAction, ui.actionAction_C]) + ui.bt_instant_popup.addActions([ui.actionAction, ui.actionAction_C]) + ui.bt_menu_button_popup.addActions([ui.actionAction, ui.actionAction_C]) window.setWindowTitle('Sample BreezeStyleSheets application.') # Add event triggers diff --git a/example/breeze_theme.py b/example/breeze_theme.py index 6784909..bd95085 100644 --- a/example/breeze_theme.py +++ b/example/breeze_theme.py @@ -104,7 +104,8 @@ def is_light_color(r: int, g: int, b: int) -> bool: Returns: If the color is perceived as light. ''' - return (((5 * g) + (2 * r) + b) > (8 * 128)) + return ((5 * g) + (2 * r) + b) > (8 * 128) + # region windows @@ -390,6 +391,7 @@ def _listen_child_macos() -> None: class Observer(NSObject): '''Custom namespace key observer.''' + def observeValueForKeyPath_ofObject_change_context_( # pylint: disable=invalid-name self, path, obj, changeDescription, context ): @@ -502,6 +504,7 @@ def _listener_dummy(callback: CallbackFn) -> None: '''Register an event listener for dark/light theme changes (always unimplemented).''' _ = callback + # endregion diff --git a/example/dial.py b/example/dial.py index ae194d8..3a385cb 100644 --- a/example/dial.py +++ b/example/dial.py @@ -38,9 +38,7 @@ parser = shared.create_parser() parser.add_argument( - '--no-align', - help='''allow larger widgets without forcing alignment.''', - action='store_true' + '--no-align', help='''allow larger widgets without forcing alignment.''', action='store_true' ) args, unknown = shared.parse_args(parser) QtCore, QtGui, QtWidgets = shared.import_qt(args) diff --git a/example/lcd.py b/example/lcd.py index 990a2d1..98a2ad7 100644 --- a/example/lcd.py +++ b/example/lcd.py @@ -37,9 +37,7 @@ parser = shared.create_parser() parser.add_argument( - '--no-align', - help='''allow larger widgets without forcing alignment.''', - action='store_true' + '--no-align', help='''allow larger widgets without forcing alignment.''', action='store_true' ) args, unknown = shared.parse_args(parser) QtCore, QtGui, QtWidgets = shared.import_qt(args) diff --git a/example/placeholder_text.py b/example/placeholder_text.py index fc1fc87..a1cec31 100644 --- a/example/placeholder_text.py +++ b/example/placeholder_text.py @@ -41,14 +41,12 @@ parser = shared.create_parser() parser.add_argument( - '--set-app-palette', - help='''set the placeholder text palette globally.''', - action='store_true' + '--set-app-palette', help='''set the placeholder text palette globally.''', action='store_true' ) parser.add_argument( '--set-widget-palette', help='''set the placeholder text palette for the affected widgets.''', - action='store_true' + action='store_true', ) args, unknown = shared.parse_args(parser) QtCore, QtGui, QtWidgets = shared.import_qt(args) diff --git a/example/shared.py b/example/shared.py index 03c0134..a3a24a7 100644 --- a/example/shared.py +++ b/example/shared.py @@ -22,9 +22,7 @@ def create_parser(): '''Create an argparser with the base settings for all Qt applications.''' - parser = argparse.ArgumentParser( - description='Configurations for the Qt5 application.' - ) + parser = argparse.ArgumentParser(description='Configurations for the Qt5 application.') parser.add_argument( '--stylesheet', help='stylesheet name (`dark`, `light`, `native`, `auto`, ...)', @@ -38,16 +36,8 @@ def create_parser(): help='application style (`Fusion`, `Windows`, `native`, ...)', default='native', ) - parser.add_argument( - '--font-size', - help='font size for the application', - type=float, - default=-1 - ) - parser.add_argument( - '--font-family', - help='the font family' - ) + parser.add_argument('--font-size', help='font size for the application', type=float, default=-1) + parser.add_argument('--font-family', help='the font family') parser.add_argument( '--scale', help='scale factor for the UI', @@ -61,14 +51,10 @@ def create_parser(): 'Note: building for PyQt6 requires PySide6-rcc to be installed.' ), choices=['pyqt5', 'pyqt6', 'pyside2', 'pyside6'], - default='pyqt5' + default='pyqt5', ) # Linux or Unix-like only. - parser.add_argument( - '--use-x11', - help='force the use of x11 on compatible systems.', - action='store_true' - ) + parser.add_argument('--use-x11', help='force the use of x11 on compatible systems.', action='store_true') return parser diff --git a/example/standard_icons.py b/example/standard_icons.py index f36e5bc..b00db10 100644 --- a/example/standard_icons.py +++ b/example/standard_icons.py @@ -106,22 +106,26 @@ def setup(self, MainWindow): # pylint: disable=too-many-statements self.tool_box.addItem(self.page1, 'Overwritten Icons') self.layout.addWidget(self.tool_box) - add_standard_buttons(self, self.page1, [ - 'SP_ArrowLeft', - 'SP_ArrowDown', - 'SP_ArrowRight', - 'SP_ArrowUp', - 'SP_DockWidgetCloseButton', - 'SP_DialogCancelButton', - 'SP_DialogCloseButton', - 'SP_DialogDiscardButton', - 'SP_DialogHelpButton', - 'SP_DialogNoButton', - 'SP_DialogOkButton', - 'SP_DialogOpenButton', - 'SP_DialogResetButton', - 'SP_DialogSaveButton', - ]) + add_standard_buttons( + self, + self.page1, + [ + 'SP_ArrowLeft', + 'SP_ArrowDown', + 'SP_ArrowRight', + 'SP_ArrowUp', + 'SP_DockWidgetCloseButton', + 'SP_DialogCancelButton', + 'SP_DialogCloseButton', + 'SP_DialogDiscardButton', + 'SP_DialogHelpButton', + 'SP_DialogNoButton', + 'SP_DialogOkButton', + 'SP_DialogOpenButton', + 'SP_DialogResetButton', + 'SP_DialogSaveButton', + ], + ) self.page2 = QtWidgets.QListWidget() self.tool_box.addItem(self.page2, 'Default Icons') diff --git a/example/titlebar.py b/example/titlebar.py index 18f3eda..95db87b 100644 --- a/example/titlebar.py +++ b/example/titlebar.py @@ -289,6 +289,7 @@ def size_less(x, y): '''Compare 2 sizes, determining if any bounds of x are less than y.''' return x.width() < y.width() or x.height() < y.height() + # UI WIDGETS # These are just to populate the views: these could be anything. @@ -431,6 +432,7 @@ def launch_fontdialog(self, edit): if ok: edit.setText(font.family()) + # RESIZE HELPERS @@ -638,6 +640,7 @@ def end_frame(self, window_type): '''End the window frame resize state.''' setattr(self, f'_{window_type}_frame', None) + # EVENT HANDLES @@ -727,6 +730,7 @@ def window_mouse_release_event(self, event, window, window_type): end_drag(window, window_type) return super(type(self), self).mouseReleaseEvent(event) + # WINDOW WIDGETS @@ -852,14 +856,16 @@ def __init__(self, window, parent=None, flags=None): # pylint: disable=(too-man self._top_action.toggled.connect(self.toggle_keep_above) self._close_action = action('&Close', self, close_icon(self)) self._close_action.triggered.connect(self._window.close) - self._main_menu.addActions([ - self._restore_action, - self._move_action, - self._size_action, - self._min_action, - self._max_action, - self._top_action, - ]) + self._main_menu.addActions( + [ + self._restore_action, + self._move_action, + self._size_action, + self._min_action, + self._max_action, + self._top_action, + ] + ) self._main_menu.addSeparator() self._main_menu.addAction(self._close_action) self._menu.setMenu(self._main_menu) @@ -1253,73 +1259,73 @@ def is_active(self): def is_on_top(self, pos, rect): '''Determine if the cursor is on the top of the widget.''' return ( - pos.x() >= rect.x() + self._border_width and - pos.x() <= rect.x() + rect.width() - self._border_width and - pos.y() >= rect.y() and - pos.y() <= rect.y() + self._border_width + pos.x() >= rect.x() + self._border_width + and pos.x() <= rect.x() + rect.width() - self._border_width + and pos.y() >= rect.y() + and pos.y() <= rect.y() + self._border_width ) def is_on_bottom(self, pos, rect): '''Determine if the cursor is on the bottom of the widget.''' return ( - pos.x() >= rect.x() + self._border_width and - pos.x() <= rect.x() + rect.width() - self._border_width and - pos.y() >= rect.y() + rect.height() - self._border_width and - pos.y() <= rect.y() + rect.height() + pos.x() >= rect.x() + self._border_width + and pos.x() <= rect.x() + rect.width() - self._border_width + and pos.y() >= rect.y() + rect.height() - self._border_width + and pos.y() <= rect.y() + rect.height() ) def is_on_left(self, pos, rect): '''Determine if the cursor is on the left of the widget.''' return ( - pos.x() >= rect.x() - self._border_width and - pos.x() <= rect.x() + self._border_width and - pos.y() >= rect.y() + self._border_width and - pos.y() <= rect.y() + rect.height() - self._border_width + pos.x() >= rect.x() - self._border_width + and pos.x() <= rect.x() + self._border_width + and pos.y() >= rect.y() + self._border_width + and pos.y() <= rect.y() + rect.height() - self._border_width ) def is_on_right(self, pos, rect): '''Determine if the cursor is on the right of the widget.''' return ( - pos.x() >= rect.x() + rect.width() - self._border_width and - pos.x() <= rect.x() + rect.width() and - pos.y() >= rect.y() + self._border_width and - pos.y() <= rect.y() + rect.height() - self._border_width + pos.x() >= rect.x() + rect.width() - self._border_width + and pos.x() <= rect.x() + rect.width() + and pos.y() >= rect.y() + self._border_width + and pos.y() <= rect.y() + rect.height() - self._border_width ) def is_on_top_left(self, pos, rect): '''Determine if the cursor is on the top left of the widget.''' return ( - pos.x() >= rect.x() and - pos.x() <= rect.x() + self._border_width and - pos.y() >= rect.y() and - pos.y() <= rect.y() + self._border_width + pos.x() >= rect.x() + and pos.x() <= rect.x() + self._border_width + and pos.y() >= rect.y() + and pos.y() <= rect.y() + self._border_width ) def is_on_top_right(self, pos, rect): '''Determine if the cursor is on the top right of the widget.''' return ( - pos.x() >= rect.x() + rect.width() - self._border_width and - pos.x() <= rect.x() + rect.width() and - pos.y() >= rect.y() and - pos.y() <= rect.y() + self._border_width + pos.x() >= rect.x() + rect.width() - self._border_width + and pos.x() <= rect.x() + rect.width() + and pos.y() >= rect.y() + and pos.y() <= rect.y() + self._border_width ) def is_on_bottom_left(self, pos, rect): '''Determine if the cursor is on the bottom left of the widget.''' return ( - pos.x() >= rect.x() and - pos.x() <= rect.x() + self._border_width and - pos.y() >= rect.y() + rect.height() - self._border_width and - pos.y() <= rect.y() + rect.height() + pos.x() >= rect.x() + and pos.x() <= rect.x() + self._border_width + and pos.y() >= rect.y() + rect.height() - self._border_width + and pos.y() <= rect.y() + rect.height() ) def is_on_bottom_right(self, pos, rect): '''Determine if the cursor is on the bottom right of the widget.''' return ( - pos.x() >= rect.x() + rect.width() - self._border_width and - pos.x() <= rect.x() + rect.width() and - pos.y() >= rect.y() + rect.height() - self._border_width and - pos.y() <= rect.y() + rect.height() + pos.x() >= rect.x() + rect.width() - self._border_width + and pos.x() <= rect.x() + rect.width() + and pos.y() >= rect.y() + rect.height() - self._border_width + and pos.y() <= rect.y() + rect.height() ) def cursor_position(self, pos, rect): # pylint: disable=too-many-return-statements) diff --git a/example/url.py b/example/url.py index 0670e2b..4256744 100644 --- a/example/url.py +++ b/example/url.py @@ -38,14 +38,12 @@ parser = shared.create_parser() parser.add_argument( - '--set-app-palette', - help='''set the placeholder text palette globally.''', - action='store_true' + '--set-app-palette', help='''set the placeholder text palette globally.''', action='store_true' ) parser.add_argument( '--set-widget-palette', help='''set the placeholder text palette for the affected widgets.''', - action='store_true' + action='store_true', ) args, unknown = shared.parse_args(parser) QtCore, QtGui, QtWidgets = shared.import_qt(args) diff --git a/example/widgets.py b/example/widgets.py index 5f0b931..3705b3d 100644 --- a/example/widgets.py +++ b/example/widgets.py @@ -527,18 +527,9 @@ def main(): # setup ui ui = Ui() ui.setup(window) - ui.bt_delay_popup.addActions([ - ui.actionAction, - ui.actionAction_C - ]) - ui.bt_instant_popup.addActions([ - ui.actionAction, - ui.actionAction_C - ]) - ui.bt_menu_button_popup.addActions([ - ui.actionAction, - ui.actionAction_C - ]) + ui.bt_delay_popup.addActions([ui.actionAction, ui.actionAction_C]) + ui.bt_instant_popup.addActions([ui.actionAction, ui.actionAction_C]) + ui.bt_menu_button_popup.addActions([ui.actionAction, ui.actionAction_C]) window.setWindowTitle('Sample BreezeStyleSheets application.') # Add event triggers diff --git a/scripts/fmt.sh b/scripts/fmt.sh index 05ec486..8a8cda6 100755 --- a/scripts/fmt.sh +++ b/scripts/fmt.sh @@ -1,14 +1,14 @@ #!/usr/bin/env bash # # Run our automatic code formatters. +# +# This requires black and isort to be installed. set -eux pipefail scripts_home="$(dirname "$(realpath "${BASH_SOURCE[0]}")")" project_home="$(dirname "${scripts_home}")" -cd "${project_home}/example" +cd "${project_home}" -if [[ ! -v PYTHON ]]; then - PYTHON=python -fi -# TODO: Here, use black \ No newline at end of file +isort ./*.py example/*.py example/**/*.py +black --config pyproject.toml example/ ./*.py \ No newline at end of file diff --git a/scripts/lint.sh b/scripts/lint.sh index 9ebb727..2793f1a 100755 --- a/scripts/lint.sh +++ b/scripts/lint.sh @@ -10,9 +10,6 @@ project_home="$(dirname "${scripts_home}")" cd "${project_home}" # run our python lint checks -if [[ ! -v PYTHON ]]; then - PYTHON=python -fi pylint ./*.py example/*.py example/**/*.py pyright example/breeze_theme.py flake8 diff --git a/vcs.py b/vcs.py index eeccca2..2a747b2 100644 --- a/vcs.py +++ b/vcs.py @@ -233,12 +233,7 @@ def parse_args(argv=None): '''Parse the command-line options.''' parser = argparse.ArgumentParser(description='Git configuration changes.') - parser.add_argument( - '-v', - '--version', - action='version', - version=f'%(prog)s {__version__}' - ) + parser.add_argument('-v', '--version', action='version', version=f'%(prog)s {__version__}') dist = parser.add_mutually_exclusive_group() dist.add_argument( '--track-dist', @@ -284,23 +279,27 @@ def call(command, ignore_errors=True): def assume_unchanged(git, file): '''Assume a version-controlled file is unchanged.''' - return call([ - git, - 'update-index', - '--assume-unchanged', - file, - ]) + return call( + [ + git, + 'update-index', + '--assume-unchanged', + file, + ] + ) def no_assume_unchanged(git, file): '''No longer assume a version-controlled file is unchanged.''' - return call([ - git, - 'update-index', - '--no-assume-unchanged', - file, - ]) + return call( + [ + git, + 'update-index', + '--no-assume-unchanged', + file, + ] + ) def write_gitignore(entries):