Made a bunch of popups non-modal so that the rest of the window works when they are open
This commit is contained in:
@@ -681,6 +681,15 @@ class SublimeMusicApp(Gtk.Application):
|
||||
self.update_window()
|
||||
|
||||
def on_window_key_press(self, window, event):
|
||||
if (event.keyval == 102
|
||||
and event.state == Gdk.ModifierType.CONTROL_MASK):
|
||||
# Ctrl + F
|
||||
window.search_entry.grab_focus()
|
||||
return
|
||||
|
||||
if window.search_entry.has_focus():
|
||||
return False
|
||||
|
||||
keymap = {
|
||||
32: self.on_play_pause,
|
||||
65360: self.on_prev_track,
|
||||
|
@@ -1,6 +1,6 @@
|
||||
import gi
|
||||
gi.require_version('Gtk', '3.0')
|
||||
from gi.repository import Gio, Gtk, GObject
|
||||
from gi.repository import Gio, Gtk, GObject, Gdk
|
||||
|
||||
from . import albums, artists, playlists, player_controls
|
||||
from sublime.state_manager import ApplicationState
|
||||
@@ -57,6 +57,8 @@ class MainWindow(Gtk.ApplicationWindow):
|
||||
flowbox.pack_start(self.player_controls, False, True, 0)
|
||||
self.add(flowbox)
|
||||
|
||||
self.connect('button-release-event', self.on_button_release)
|
||||
|
||||
def update(self, state: ApplicationState, force=False):
|
||||
# Update the Connected to label on the popup menu.
|
||||
if state.config.current_server >= 0:
|
||||
@@ -99,24 +101,32 @@ class MainWindow(Gtk.ApplicationWindow):
|
||||
header.props.title = 'Sublime Music'
|
||||
|
||||
# Search
|
||||
search = Gtk.SearchEntry()
|
||||
header.pack_start(search)
|
||||
self.search_entry = Gtk.SearchEntry()
|
||||
self.search_entry.connect('focus-in-event', self.on_search_entry_focus)
|
||||
self.search_entry.connect('changed', self.on_search_entry_changed)
|
||||
self.search_entry.connect(
|
||||
'stop-search', self.on_search_entry_stop_search)
|
||||
header.pack_start(self.search_entry)
|
||||
|
||||
# Search popup
|
||||
self.create_search_popup()
|
||||
|
||||
# Stack switcher
|
||||
switcher = Gtk.StackSwitcher(stack=stack)
|
||||
header.set_custom_title(switcher)
|
||||
|
||||
# Menu button
|
||||
button = Gtk.MenuButton()
|
||||
button.set_use_popover(True)
|
||||
button.set_popover(self.create_menu())
|
||||
button.connect('clicked', self.on_menu_click)
|
||||
menu_button = Gtk.MenuButton()
|
||||
menu_button.set_use_popover(True)
|
||||
menu_button.set_popover(self.create_menu())
|
||||
menu_button.connect('clicked', self.on_menu_clicked)
|
||||
self.menu.set_relative_to(menu_button)
|
||||
|
||||
icon = Gio.ThemedIcon(name="open-menu-symbolic")
|
||||
icon = Gio.ThemedIcon(name='open-menu-symbolic')
|
||||
image = Gtk.Image.new_from_gicon(icon, Gtk.IconSize.BUTTON)
|
||||
button.add(image)
|
||||
menu_button.add(image)
|
||||
|
||||
header.pack_end(button)
|
||||
header.pack_end(menu_button)
|
||||
|
||||
return header
|
||||
|
||||
@@ -146,8 +156,61 @@ class MainWindow(Gtk.ApplicationWindow):
|
||||
|
||||
return self.menu
|
||||
|
||||
# ========== Event Listeners ==========
|
||||
def on_menu_click(self, button):
|
||||
self.menu.set_relative_to(button)
|
||||
self.menu.show_all()
|
||||
def create_search_popup(self):
|
||||
self.search_popup = Gtk.PopoverMenu(modal=False)
|
||||
|
||||
self.search_results_box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
|
||||
|
||||
self.search_popup.add(self.search_results_box)
|
||||
|
||||
self.search_popup.set_relative_to(self.search_entry)
|
||||
rect = Gdk.Rectangle()
|
||||
rect.x = 18
|
||||
rect.y = 30
|
||||
rect.width = 1
|
||||
rect.height = 1
|
||||
self.search_popup.set_pointing_to(rect)
|
||||
self.search_popup.set_position(Gtk.PositionType.BOTTOM)
|
||||
|
||||
# Event Listeners
|
||||
# =========================================================================
|
||||
def on_button_release(self, win, event):
|
||||
if not self.event_in_widget(event, self.search_entry):
|
||||
self.search_popup.popdown()
|
||||
|
||||
if not self.event_in_widget(event, self.player_controls.device_button):
|
||||
self.player_controls.device_popover.popdown()
|
||||
|
||||
if not self.event_in_widget(event,
|
||||
self.player_controls.play_queue_button):
|
||||
self.player_controls.play_queue_popover.popdown()
|
||||
|
||||
def on_menu_clicked(self, button):
|
||||
self.menu.popup()
|
||||
self.menu.show_all()
|
||||
|
||||
def on_search_entry_focus(self, entry, event):
|
||||
self.search_popup.show_all()
|
||||
self.search_popup.popup()
|
||||
|
||||
def on_search_entry_changed(self, entry):
|
||||
print('changed', entry.get_text())
|
||||
self.search_results_box.add(Gtk.Label(label=entry.get_text()))
|
||||
self.search_results_box.show_all()
|
||||
|
||||
def on_search_entry_stop_search(self, entry):
|
||||
self.search_popup.popdown()
|
||||
|
||||
# Helper Functions
|
||||
# =========================================================================
|
||||
def event_in_widget(self, event, widget):
|
||||
_, win_x, win_y = Gdk.Window.get_origin(self.get_window())
|
||||
widget_x, widget_y = widget.translate_coordinates(self, 0, 0)
|
||||
allocation = widget.get_allocation()
|
||||
|
||||
bound_x = (win_x + widget_x, win_x + widget_x + allocation.width)
|
||||
bound_y = (win_y + widget_y, win_y + widget_y + allocation.height)
|
||||
|
||||
return (
|
||||
(bound_x[0] <= event.x_root <= bound_x[1])
|
||||
and (bound_y[0] <= event.y_root <= bound_y[1]))
|
||||
|
@@ -132,16 +132,16 @@ class PlayerControls(Gtk.ActionBar):
|
||||
if state.current_song is not None:
|
||||
self.update_cover_art(state.current_song.coverArt, size='70')
|
||||
|
||||
self.song_title.set_text(util.esc(state.current_song.title))
|
||||
self.album_name.set_text(util.esc(state.current_song.album))
|
||||
self.song_title.set_markup(util.esc(state.current_song.title))
|
||||
self.album_name.set_markup(util.esc(state.current_song.album))
|
||||
artist_name = util.esc(state.current_song.artist)
|
||||
self.artist_name.set_text(artist_name or '')
|
||||
self.artist_name.set_markup(artist_name or '')
|
||||
else:
|
||||
# Clear out the cover art and song tite if no song
|
||||
self.album_art.set_from_file(None)
|
||||
self.song_title.set_text('')
|
||||
self.album_name.set_text('')
|
||||
self.artist_name.set_text('')
|
||||
self.song_title.set_markup('')
|
||||
self.album_name.set_markup('')
|
||||
self.artist_name.set_markup('')
|
||||
self.album_art.set_loading(False)
|
||||
|
||||
self.update_device_list()
|
||||
@@ -276,10 +276,12 @@ class PlayerControls(Gtk.ActionBar):
|
||||
self.emit('volume-change', scale.get_value())
|
||||
|
||||
def on_play_queue_click(self, button):
|
||||
self.play_queue_popover.set_relative_to(button)
|
||||
# TODO scroll the currently playing song into view.
|
||||
self.play_queue_popover.popup()
|
||||
self.play_queue_popover.show_all()
|
||||
if self.play_queue_popover.is_visible():
|
||||
self.play_queue_popover.popdown()
|
||||
else:
|
||||
# TODO scroll the currently playing song into view.
|
||||
self.play_queue_popover.popup()
|
||||
self.play_queue_popover.show_all()
|
||||
|
||||
def on_song_activated(self, treeview, idx, column):
|
||||
# The song ID is in the last column of the model.
|
||||
@@ -333,10 +335,12 @@ class PlayerControls(Gtk.ActionBar):
|
||||
chromecast_callback(self.chromecasts)
|
||||
|
||||
def on_device_click(self, button):
|
||||
self.device_popover.set_relative_to(button)
|
||||
self.device_popover.popup()
|
||||
self.device_popover.show_all()
|
||||
self.update_device_list()
|
||||
if self.device_popover.is_visible():
|
||||
self.device_popover.popdown()
|
||||
else:
|
||||
self.device_popover.popup()
|
||||
self.device_popover.show_all()
|
||||
self.update_device_list()
|
||||
|
||||
def on_device_refresh_click(self, button):
|
||||
self.update_device_list(force=True)
|
||||
@@ -511,12 +515,16 @@ class PlayerControls(Gtk.ActionBar):
|
||||
box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL)
|
||||
|
||||
# Device button (for chromecast)
|
||||
device_button = IconButton(
|
||||
self.device_button = IconButton(
|
||||
'video-display-symbolic', icon_size=Gtk.IconSize.LARGE_TOOLBAR)
|
||||
device_button.connect('clicked', self.on_device_click)
|
||||
box.pack_start(device_button, False, True, 5)
|
||||
self.device_button.connect('clicked', self.on_device_click)
|
||||
box.pack_start(self.device_button, False, True, 5)
|
||||
|
||||
self.device_popover = Gtk.PopoverMenu(name='device-popover')
|
||||
self.device_popover = Gtk.PopoverMenu(
|
||||
modal=False,
|
||||
name='device-popover',
|
||||
)
|
||||
self.device_popover.set_relative_to(self.device_button)
|
||||
|
||||
device_popover_box = Gtk.Box(
|
||||
orientation=Gtk.Orientation.VERTICAL,
|
||||
@@ -564,12 +572,16 @@ class PlayerControls(Gtk.ActionBar):
|
||||
self.device_popover.add(device_popover_box)
|
||||
|
||||
# Play Queue button
|
||||
play_queue_button = IconButton(
|
||||
self.play_queue_button = IconButton(
|
||||
'view-list-symbolic', icon_size=Gtk.IconSize.LARGE_TOOLBAR)
|
||||
play_queue_button.connect('clicked', self.on_play_queue_click)
|
||||
box.pack_start(play_queue_button, False, True, 5)
|
||||
self.play_queue_button.connect('clicked', self.on_play_queue_click)
|
||||
box.pack_start(self.play_queue_button, False, True, 5)
|
||||
|
||||
self.play_queue_popover = Gtk.PopoverMenu(name='up-next-popover')
|
||||
self.play_queue_popover = Gtk.PopoverMenu(
|
||||
modal=False,
|
||||
name='up-next-popover',
|
||||
)
|
||||
self.play_queue_popover.set_relative_to(self.play_queue_button)
|
||||
|
||||
play_queue_popover_box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
|
||||
play_queue_popover_header = Gtk.Box(
|
||||
|
Reference in New Issue
Block a user