Retouch the game bar pop-overs

This change makes the popover menus in the game bar look the same as
the ones in the header-bar, with the usual menu-y styling.

Because my OCD, that's why!
This commit is contained in:
Daniel Johnson 2023-03-25 10:20:06 -04:00
parent 0fc50e6cb2
commit 3ca51d77e3
3 changed files with 70 additions and 87 deletions

View file

@ -7,7 +7,6 @@ from lutris import runners, services
from lutris.database.games import get_game_by_field, get_game_for_service
from lutris.game import Game
from lutris.game_actions import GameActions
from lutris.gui.widgets.utils import get_link_button
from lutris.util.strings import gtk_safe
@ -96,20 +95,55 @@ class GameBar(Gtk.Box):
hbox.pack_start(self.get_playtime_label(), False, False, 0)
hbox.show_all()
def get_popover(self, buttons, parent):
"""Return the popover widget containing a list of link buttons"""
if not buttons:
return None
popover = Gtk.Popover()
vbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, visible=True)
@staticmethod
def get_popover_box(primary_button, popover_buttons, primary_opens_popover=False):
"""Creates a box that contains a primary button and a second button that
opens a popover with the popover_buttons in it; these have a linked
style so this looks like a single button.
for action in buttons:
vbox.pack_end(buttons[action], False, False, 1)
popover.add(vbox)
popover.set_position(Gtk.PositionType.TOP)
popover.set_constrain_to(Gtk.PopoverConstraint.NONE)
popover.set_relative_to(parent)
return popover
If primary_opens_popover is true, this method also handled the 'clicked' signal
of the primary button to trigger the popover as well."""
def get_popover(parent):
# Creates the popover widget containing the list of link buttons
pop = Gtk.Popover()
vbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, visible=True)
vbox.set_border_width(9)
vbox.set_spacing(3)
for button in popover_buttons.values():
vbox.pack_end(button, False, False, 0)
pop.add(vbox)
pop.set_position(Gtk.PositionType.TOP)
pop.set_constrain_to(Gtk.PopoverConstraint.NONE)
pop.set_relative_to(parent)
return pop
box = Gtk.HBox(visible=True)
style_context = box.get_style_context()
style_context.add_class("linked")
box.pack_start(primary_button, False, False, 0)
if popover_buttons:
popover_button = Gtk.MenuButton(direction=Gtk.ArrowType.UP, visible=True)
popover_button.set_size_request(32, 32)
popover = get_popover(popover_button)
popover_button.set_popover(popover)
box.pack_start(popover_button, False, False, 0)
if primary_opens_popover:
primary_button.connect("clicked", lambda _x: popover_button.emit("clicked"))
return box
@staticmethod
def get_link_button(text):
"""Return a suitable button for a menu popover; this must be
a ModelButton to be styled correctly."""
button = Gtk.ModelButton(text, visible=True, xalign=0.0)
return button
def get_game_name_label(self):
"""Return the label with the game's title"""
@ -121,26 +155,14 @@ class GameBar(Gtk.Box):
def get_runner_button(self):
icon_name = self.game.runner.name + "-symbolic"
runner_icon = Gtk.Image.new_from_icon_name(icon_name, Gtk.IconSize.MENU)
runner_icon.show()
box = Gtk.HBox(visible=True)
runner_button = Gtk.Button(visible=True)
popover = self.get_popover(self.get_runner_buttons(), runner_button)
if popover:
runner_button.set_image(runner_icon)
popover_button = Gtk.MenuButton(visible=True)
popover_button.set_size_request(32, 32)
popover_button.props.direction = Gtk.ArrowType.UP
popover_button.set_popover(popover)
runner_button.connect("clicked", lambda _x: popover_button.emit("clicked"))
box.add(runner_button)
box.add(popover_button)
style_context = box.get_style_context()
style_context.add_class("linked")
else:
runner_icon.set_margin_left(49)
runner_icon.set_margin_right(6)
box.add(runner_icon)
return box
runner_popover_buttons = self.get_runner_buttons()
if runner_popover_buttons:
runner_button = Gtk.Button(image=runner_icon, visible=True)
return GameBar.get_popover_box(runner_button, runner_popover_buttons, primary_opens_popover=True)
runner_icon.set_margin_left(49)
runner_icon.set_margin_right(6)
return runner_icon
def get_platform_label(self):
platform_label = Gtk.Label(visible=True)
@ -169,25 +191,9 @@ class GameBar(Gtk.Box):
last_played_label.set_markup(_("Last played:\n<b>%s</b>") % lastplayed.strftime("%b %-d %Y"))
return last_played_label
def get_popover_button(self):
"""Return the popover button+menu for the Play button"""
popover_button = Gtk.MenuButton(visible=True)
popover_button.set_size_request(32, 32)
popover_button.props.direction = Gtk.ArrowType.UP
return popover_button
def get_popover_box(self):
"""Return a container for a button + a popover button attached to it"""
box = Gtk.HBox(visible=True)
style_context = box.get_style_context()
style_context.add_class("linked")
return box
def get_locate_installed_game_button(self, game_actions):
"""Return a button to locate an existing install"""
button = get_link_button("Locate installed game")
button.show()
button = GameBar.get_link_button(_("Locate installed game"))
button.connect("clicked", game_actions.on_locate_installed_game, self.game)
return {"locate": button}
@ -195,9 +201,10 @@ class GameBar(Gtk.Box):
"""Return the widget for install/play/stop and game config"""
button = Gtk.Button(visible=True)
button.set_size_request(120, 32)
box = self.get_popover_box()
popover_button = self.get_popover_button()
game_buttons = None
if self.game.is_installed:
game_buttons = self.get_game_buttons(game_actions)
if self.game.state == self.game.STATE_STOPPED:
button.set_label(_("Play"))
button.connect("clicked", game_actions.on_game_launch)
@ -215,19 +222,13 @@ class GameBar(Gtk.Box):
# Local services don't show an install dialog, they can be launched directly
button.set_label(_("Play"))
if self.service.drm_free:
button.set_size_request(84, 32)
box.add(button)
popover = self.get_popover(self.get_locate_installed_game_button(game_actions), popover_button)
popover_button.set_popover(popover)
box.add(popover_button)
return box
return button
button.set_size_request(84, 32)
box.add(button)
popover = self.get_popover(self.get_game_buttons(game_actions), popover_button)
popover_button.set_popover(popover)
box.add(popover_button)
return box
game_buttons = self.get_locate_installed_game_button(game_actions)
if game_buttons:
button.set_size_request(84, 32)
box = GameBar.get_popover_box(button, game_buttons)
return box
return button
def get_game_buttons(self, game_actions):
"""Return a dictionary of buttons to use in the panel"""
@ -237,11 +238,8 @@ class GameBar(Gtk.Box):
action_id, label, callback = action
if action_id in ("play", "stop", "install"):
continue
button = get_link_button(label)
if displayed.get(action_id):
button.show()
else:
button.hide()
button = GameBar.get_link_button(label)
button.set_visible(displayed.get(action_id))
buttons[action_id] = button
button.connect("clicked", self.on_link_button_clicked, callback)
return buttons
@ -252,8 +250,7 @@ class GameBar(Gtk.Box):
runner = runners.import_runner(self.game.runner_name)(self.game.config)
for entry in runner.context_menu_entries:
name, label, callback = entry
button = get_link_button(label)
button.show()
button = GameBar.get_link_button(label)
button.connect("clicked", self.on_link_button_clicked, callback)
buttons[name] = button
return buttons

View file

@ -257,16 +257,6 @@ def image2pixbuf(image):
return GdkPixbuf.Pixbuf.new_from_data(image_array, GdkPixbuf.Colorspace.RGB, True, 8, width, height, width * 4)
def get_link_button(text):
"""Return a transparent text button for the side panels"""
button = Gtk.Button(text, visible=True)
button.props.relief = Gtk.ReliefStyle.NONE
button.get_children()[0].set_alignment(0, 0.5)
button.get_style_context().add_class("panel-button")
button.set_size_request(-1, 24)
return button
def load_icon_theme():
"""Add the lutris icon folder to the default theme"""
icon_theme = Gtk.IconTheme.get_default()

View file

@ -18,10 +18,6 @@
border: 0;
}
.panel-button label {
font-weight: normal;
}
.info-pill {
background-color: alpha(currentColor, .07);
border-radius: 5px;