Skip to content

Commit

Permalink
Add Application Launcher button to the top bar
Browse files Browse the repository at this point in the history
This mean adding a new shortcut Alt+L for the launcher and
modifying the look and ui behaviour to make the window more legible
  • Loading branch information
wgergely committed Oct 25, 2023
1 parent 337daf2 commit 122be03
Show file tree
Hide file tree
Showing 9 changed files with 114 additions and 59 deletions.
20 changes: 11 additions & 9 deletions bookmarks/common/ui.py
Original file line number Diff line number Diff line change
Expand Up @@ -114,21 +114,23 @@ def center_window(w):
return


def center_to_parent(w):
"""Move the given widget to the available screen geometry's middle.
def center_to_parent(widget, parent=None):
"""Move the given widget to the widget's parent's middle.
Args:
w (QWidget): The widget to center.
p (QWidget): The widget to center to.
widget (QWidget): The widget to center.
parent (QWidget): Optional. The widget to center to.
"""
if not w.parent():
if not widget.parent() and not parent:
return
if widget.parent() and not parent:
parent = widget.parent()

w.adjustSize()
g = w.parent().geometry()
r = w.rect()
w.move(g.center() + (r.topLeft() - r.center()))
widget.adjustSize()
g = parent.geometry()
r = widget.rect()
widget.move(g.center() + (r.topLeft() - r.center()))
return


Expand Down
4 changes: 4 additions & 0 deletions bookmarks/contextmenu.py
Original file line number Diff line number Diff line change
Expand Up @@ -1295,6 +1295,10 @@ def launcher_menu(self):
'icon': ui.get_icon('icon'),
'text': 'Application Launcher',
'action': actions.pick_launcher_item,
'shortcut': shortcuts.get(
shortcuts.MainWidgetShortcuts,
shortcuts.ApplicationLauncher
).key(),
}

def sg_thumbnail_menu(self):
Expand Down
16 changes: 5 additions & 11 deletions bookmarks/launcher/gallery.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@


def close():
"""Opens the :class:`LauncherGallery` editor.
"""Opens the :class:`ApplicationLauncherWidget` editor.
"""
if common.launcher_widget is None:
Expand All @@ -24,23 +24,23 @@ def close():


def show():
"""Shows the :class:`LauncherGallery` editor.
"""Shows the :class:`ApplicationLauncherWidget` editor.
"""
close()
common.launcher_widget = LauncherGallery()
common.launcher_widget = ApplicationLauncherWidget()
common.launcher_widget.open()
return common.launcher_widget


class LauncherGallery(ui.GalleryWidget):
class ApplicationLauncherWidget(ui.GalleryWidget):
"""A generic gallery widget used to let the user pick an item.
"""

def __init__(self, parent=None):
super().__init__(
'Applications',
'Application Launcher',
item_height=common.size(common.size_row_height) * 4,
parent=parent
)
Expand Down Expand Up @@ -78,9 +78,3 @@ def item_generator(self):

for k in sorted(v, key=lambda _k: v[_k]['name']):
yield v[k]['name'], v[k]['path'], v[k]['thumbnail']

def focusOutEvent(self, event):
"""Event handler.
"""
self.close()
2 changes: 2 additions & 0 deletions bookmarks/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -330,6 +330,8 @@ def _init_shortcuts(self):
connect(shortcuts.Refresh, actions.refresh)
connect(shortcuts.AltRefresh, actions.refresh)

connect(shortcuts.ApplicationLauncher, actions.pick_launcher_item)

connect(shortcuts.CopyItemPath, actions.copy_selected_path)
connect(shortcuts.CopyAltItemPath, actions.copy_selected_alt_path)
connect(shortcuts.RevealItem, actions.reveal_selected)
Expand Down
15 changes: 13 additions & 2 deletions bookmarks/rsc/stylesheet.qss
Original file line number Diff line number Diff line change
Expand Up @@ -651,10 +651,21 @@ QWidget#mainRow {{
}}


GalleryWidget QWidget:focus {{
border: {size_separator}px solid transparent;
GalleryWidget {{
border: {size_separator}px solid {color_blue};
}}

GalleryWidget,
GalleryWidget > QScrollArea,
GalleryWidget QScrollArea,
GalleryWidget QScrollArea > QWidget,
GalleryWidget QScrollArea > QWidget > QWidget
{{
background-color: {color_dark_background};
}}



Viewer,
ImageViewer {{
background-color: rgba(20,20,20,250);
Expand Down
9 changes: 9 additions & 0 deletions bookmarks/shortcuts.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@
Refresh = common.idx()
AltRefresh = common.idx()

ApplicationLauncher = common.idx()

CopyItemPath = common.idx()
CopyAltItemPath = common.idx()
RevealItem = common.idx()
Expand Down Expand Up @@ -172,6 +174,13 @@
'description': 'Refresh',
'shortcut': None,
},
ApplicationLauncher: {
'value': 'Alt+L',
'default': 'Alt+L',
'repeat': False,
'description': 'Application Launcher',
'shortcut': None,
},
CopyItemPath: {
'value': 'Ctrl+C',
'default': 'Ctrl+C',
Expand Down
44 changes: 44 additions & 0 deletions bookmarks/topbar/buttons.py
Original file line number Diff line number Diff line change
Expand Up @@ -293,3 +293,47 @@ def state(self):
return True

return False


class ApplicationLauncherButton(BaseControlButton):
"""A button used to launch applications.
"""

def __init__(self, parent=None):
s = shortcuts.string(
shortcuts.MainWidgetShortcuts,
shortcuts.ApplicationLauncher
)
super().__init__(
'icon',
f'Application Launcher - {s}',
parent=parent
)
self.clicked.connect(actions.pick_launcher_item)
self.clicked.connect(self.update)

def state(self):
"""The state of the auto-thumbnails"""
if not common.widget():
return False

model = common.widget().model().sourceModel()
p = model.source_path()
k = model.task()
t = model.data_type()

if not p or not all(p) or not k or t is None:
return False

data = common.get_task_data(p, k)
if not data:
return False

if any(
(data[common.FileItem].refresh_needed,
data[common.SequenceItem].refresh_needed)
):
return True

return False
18 changes: 9 additions & 9 deletions bookmarks/topbar/topbar.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,38 +28,38 @@
'widget': tabs.FavouritesTabButton,
'hidden': False,
},
# next(n): {
# 'widget': filters.ServersFilterButton,
# 'hidden': False,
# },
next(n): {
'widget': filters.JobsFilterButton,
'hidden': False,
'hidden': True,
},
# next(n): {
# 'widget': filters.RootsFilterButton,
# 'hidden': False,
# },
next(n): {
'widget': filters.EntityFilterButton,
'hidden': False,
'hidden': True,
},
next(n): {
'widget': filters.TaskFilterButton,
'hidden': False,
'hidden': True,
},
next(n): {
'widget': filters.SubdirFilterButton,
'hidden': False,
'hidden': True,
},
next(n): {
'widget': filters.TypeFilterButton,
'hidden': False,
'hidden': True,
},
next(n): {
'widget': buttons.FilterButton,
'hidden': False,
},
next(n): {
'widget': buttons.ApplicationLauncherButton,
'hidden': False,
},
next(n): {
'widget': buttons.RefreshButton,
'hidden': False,
Expand Down
45 changes: 17 additions & 28 deletions bookmarks/ui.py
Original file line number Diff line number Diff line change
Expand Up @@ -1379,14 +1379,20 @@ def __init__(
self._item_height = item_height

self.setWindowFlags(QtCore.Qt.Window | QtCore.Qt.FramelessWindowHint)
self.setAttribute(QtCore.Qt.WA_NoSystemBackground)
self.setAttribute(QtCore.Qt.WA_TranslucentBackground)
self.setAttribute(QtCore.Qt.WA_DeleteOnClose)
self.setWindowOpacity(0.8)
self.setWindowOpacity(0.95)

self.installEventFilter(self)

self._create_ui()
self.init_data()

def eventFilter(self, widget, event):
if event.type() == QtCore.QEvent.WindowDeactivate:
self.close()
return True
return False

def _create_ui(self):
if not self.parent():
common.set_stylesheet(self)
Expand All @@ -1406,6 +1412,7 @@ def _create_ui(self):
parent=self
)
self.layout().addWidget(label)
self.layout().addSpacing(common.size(common.size_margin) * 1.5)

_width = (
(common.size(common.size_indicator) * 2) +
Expand All @@ -1430,9 +1437,7 @@ def _create_ui(self):
)

widget = QtWidgets.QWidget(parent=self)
widget.setStyleSheet(
f'background-color: {common.rgb(common.color_separator)};'
)
widget.eventFilter = self.eventFilter

QtWidgets.QGridLayout(widget)
widget.layout().setAlignment(QtCore.Qt.AlignCenter)
Expand All @@ -1444,10 +1449,8 @@ def _create_ui(self):
self.scroll_area.setWidgetResizable(True)
self.scroll_area.setWidget(widget)

# self.layout().addSpacing(common.size(common.size_margin))
self.layout().addWidget(self.scroll_area, 1)

self.setFocusProxy(widget)
self.setFocusProxy(self.scroll_area.widget())

def init_data(self):
"""Initializes data.
Expand Down Expand Up @@ -1481,39 +1484,25 @@ def item_generator(self):
"""
raise NotImplementedError('Abstract method must be implemented by subclass.')

def paintEvent(self, event):
painter = QtGui.QPainter()
painter.begin(self)
painter.setBrush(common.color(common.color_separator))
pen = QtGui.QPen(QtGui.QColor(0, 0, 0, 150))
pen.setWidth(common.size(common.size_separator))
painter.setPen(pen)
painter.setRenderHint(QtGui.QPainter.Antialiasing)
o = common.size(common.size_indicator) * 2.0
painter.drawRoundedRect(
self.rect().marginsRemoved(QtCore.QMargins(o, o, o, o)),
o, o
)
painter.end()

def focusOutEvent(self, event):
self.accept() # or self.reject()

def showEvent(self, event):
"""Show event handler.
"""
if not self.parent():
common.center_window(self)
common.center_to_parent(self, common.main_widget)
common.move_widget_to_available_geo(self)

self.anim = QtCore.QPropertyAnimation(self, b'windowOpacity')
self.anim.setDuration(500) # Animation duration in milliseconds
self.anim.setStartValue(0)
self.anim.setEndValue(0.95)
self.anim.setEasingCurve(QtCore.QEasingCurve.OutCubic)
self.anim.start()
self.anim.start(QtCore.QAbstractAnimation.DeleteWhenStopped)

self.scroll_area.widget().setFocus(QtCore.Qt.PopupFocusReason)
self.anim.finished.connect(self.raise_)
self.anim.finished.connect(lambda: self.setFocus(QtCore.Qt.PopupFocusReason))

def done(self, r):
if r == QtWidgets.QDialog.Rejected:
Expand Down

0 comments on commit 122be03

Please sign in to comment.