mirror of
https://github.com/vale981/clay
synced 2025-03-05 09:31:40 -05:00
Use slugs instead of names; Backup commands; Filter on search & settings pages
This commit is contained in:
parent
fc47df518b
commit
5620e79432
6 changed files with 51 additions and 74 deletions
|
@ -36,10 +36,6 @@ hotkeys:
|
|||
song_view:
|
||||
start_filtering: /
|
||||
end_filtering: esc
|
||||
move_to_beginning: home
|
||||
move_to_end: end
|
||||
move_up: up
|
||||
move_down: down
|
||||
hide_context_menu: m
|
||||
|
||||
general_page:
|
||||
|
|
|
@ -9,7 +9,7 @@ from .clipboard import copy
|
|||
from .hotkeys import hotkey_manager
|
||||
from .notifications import notification_area
|
||||
from .playbar import PlayBar
|
||||
from .songlist import SongListBox, filter_out
|
||||
from .songlist import SongListBox
|
||||
from .pages import *
|
||||
|
||||
|
||||
|
@ -174,6 +174,11 @@ class AppWidget(urwid.Frame):
|
|||
"""
|
||||
Switch to a different tab.
|
||||
"""
|
||||
try:
|
||||
self.current_page.songlist.end_filtering()
|
||||
except AttributeError as e:
|
||||
pass
|
||||
|
||||
page = [page for page in self.pages if page.slug == slug][0]
|
||||
self.current_page = page
|
||||
self.contents['body'] = (page, None)
|
||||
|
@ -214,9 +219,6 @@ class AppWidget(urwid.Frame):
|
|||
Handle keypress.
|
||||
Can switch tabs, control playback, flags, notifications and app state.
|
||||
"""
|
||||
if filter_out(key):
|
||||
return super(AppWidget, self).keypress(size, key)
|
||||
|
||||
hotkey_manager.keypress("global", self, super(AppWidget, self), size, key)
|
||||
return None
|
||||
|
||||
|
@ -250,6 +252,7 @@ class AppWidget(urwid.Frame):
|
|||
|
||||
def show_settings(self):
|
||||
""" Show settings page. """
|
||||
|
||||
self.set_page('settings')
|
||||
|
||||
@staticmethod
|
||||
|
|
|
@ -5,6 +5,8 @@ Requires "gi" package and "Gtk" & "Keybinder" modules.
|
|||
# pylint: disable=broad-except
|
||||
from clay.core import settings_manager, logger
|
||||
|
||||
from string import ascii_letters, digits
|
||||
|
||||
def report_error(exc):
|
||||
"Print an error message to the debug screen"
|
||||
logger.error("{0}: {1}".format(exc.__class__.__name__, exc))
|
||||
|
@ -17,6 +19,7 @@ class _HotkeyManager(object):
|
|||
def __init__(self):
|
||||
self._hotkeys = self._parse_hotkeys()
|
||||
self.config = None
|
||||
self.filtering = False
|
||||
|
||||
def _parse_hotkeys(self):
|
||||
"""
|
||||
|
@ -42,6 +45,33 @@ class _HotkeyManager(object):
|
|||
return hotkeys
|
||||
|
||||
def keypress(self, name, caller, super_, size, key):
|
||||
"""
|
||||
Processes a key and sends the appropiated command back.
|
||||
|
||||
Returns:
|
||||
the letter pressed if Clay is filtering, the command or, in case a modifier key is pressed,
|
||||
the command associated with the letter after the modifier key.
|
||||
"""
|
||||
split_keys = key.split()
|
||||
if split_keys[0] == 'meta' or split_keys[0] == 'ctrl':
|
||||
self.filtering = False
|
||||
return self._lookup_key(name, caller, super_, size, ''.join(split_keys[1:]))
|
||||
|
||||
if not self.filtering:
|
||||
return self._lookup_key(name, caller, super_, size, key)
|
||||
|
||||
if key == 'backspace' or key == 'tab' or key in ascii_letters + digits + ' _-.,?()[]\'':
|
||||
if name == 'song_view':
|
||||
ret = caller.perform_filtering(key)
|
||||
else:
|
||||
ret = super_.keypress(size, key)
|
||||
|
||||
else:
|
||||
ret = self._lookup_key(name, caller, super_, size, key)
|
||||
|
||||
return ret
|
||||
|
||||
def _lookup_key(self, name, caller, super_, size, key):
|
||||
"""
|
||||
Process the pressed key by looking it up in the configuration file
|
||||
|
||||
|
|
|
@ -40,6 +40,7 @@ class SearchBox(urwid.Columns):
|
|||
"""
|
||||
Send a message to urwid to search the filled in search query
|
||||
"""
|
||||
|
||||
urwid.emit_signal(self, 'search-requested', self.query.edit_text)
|
||||
|
||||
|
||||
|
@ -71,7 +72,7 @@ class SearchPage(urwid.Pile, AbstractPage):
|
|||
def __init__(self, app):
|
||||
self.app = app
|
||||
self.songlist = SongListBox(app)
|
||||
|
||||
self._focus_position = 0
|
||||
self.search_box = SearchBox()
|
||||
|
||||
urwid.connect_signal(self.search_box, 'search-requested', self.perform_search)
|
||||
|
@ -102,9 +103,11 @@ class SearchPage(urwid.Pile, AbstractPage):
|
|||
self.app.redraw()
|
||||
|
||||
def activate(self):
|
||||
pass
|
||||
hotkey_manager.filtering = True
|
||||
|
||||
def keypress(self, size, key):
|
||||
hotkey_manager.filtering = (self.focus == self.search_box)
|
||||
|
||||
if key == 'tab':
|
||||
if self.focus == self.search_box:
|
||||
self.focus_position = 2
|
||||
|
|
|
@ -197,4 +197,4 @@ class SettingsPage(urwid.Columns, AbstractPage):
|
|||
self.app.log_in()
|
||||
|
||||
def activate(self):
|
||||
pass
|
||||
hotkey_manager.filtering = True
|
||||
|
|
|
@ -25,13 +25,6 @@ from .clipboard import copy
|
|||
|
||||
player = get_player() # pylint: disable=invalid-name
|
||||
|
||||
FILTERING = False
|
||||
def filter_out(key):
|
||||
"""
|
||||
Checks whether the keypress should be sent to the filter instead
|
||||
"""
|
||||
return FILTERING and (key == 'backspace' or key in (ascii_letters + digits + ' _-.,?!()[]\''))
|
||||
|
||||
class SongListItem(urwid.Pile):
|
||||
"""
|
||||
Widget that represents single song item.
|
||||
|
@ -183,9 +176,6 @@ class SongListItem(urwid.Pile):
|
|||
"""
|
||||
Handle keypress.
|
||||
"""
|
||||
if filter_out(key):
|
||||
return super(SongListItem, self).keypress(size, key)
|
||||
|
||||
return hotkey_manager.keypress("song_item", self, super(SongListItem, self), size, key)
|
||||
|
||||
def mouse_event(self, size, event, button, col, row, focus):
|
||||
|
@ -440,7 +430,7 @@ class SongListBox(urwid.Frame):
|
|||
self.list_box = urwid.ListBox(self.walker)
|
||||
self.filter_prefix = '> '
|
||||
self.filter_query = ''
|
||||
self.filter_box = urwid.Text(self.filter_prefix)
|
||||
self.filter_box = urwid.Text('')
|
||||
self.filter_info = urwid.Text('')
|
||||
self.filter_panel = urwid.Columns([
|
||||
self.filter_box,
|
||||
|
@ -469,16 +459,14 @@ class SongListBox(urwid.Frame):
|
|||
"""
|
||||
Starts filtering the song view
|
||||
"""
|
||||
global FILTERING
|
||||
|
||||
if not FILTERING:
|
||||
if not hotkey_manager.filtering:
|
||||
self.content.contents = [
|
||||
(self.list_box, ('weight', 1)),
|
||||
(self.filter_panel, ('pack', None))
|
||||
]
|
||||
self.app.append_cancel_action(self.end_filtering)
|
||||
self.filter_query = ''
|
||||
FILTERING = True
|
||||
hotkey_manager.filtering = True
|
||||
self.tracks_walker[:] = self.walker
|
||||
|
||||
self.filter_box.set_text(self.filter_prefix)
|
||||
|
@ -501,7 +489,7 @@ class SongListBox(urwid.Frame):
|
|||
self.walker[:] = matches
|
||||
self.walker.set_focus(0)
|
||||
|
||||
if self.app.current_page.name == 'Library':
|
||||
if self.app.current_page.slug == 'library':
|
||||
self.update_indexes()
|
||||
|
||||
def get_filtered_items(self):
|
||||
|
@ -520,14 +508,12 @@ class SongListBox(urwid.Frame):
|
|||
"""
|
||||
Exit filtering mode.
|
||||
"""
|
||||
global FILTERING
|
||||
if not FILTERING:
|
||||
if self.filter_box.text == '':
|
||||
return
|
||||
|
||||
self.content.contents = [
|
||||
(self.list_box, ('weight', 1))
|
||||
]
|
||||
FILTERING = False
|
||||
hotkey_manager.filtering = False
|
||||
self.filter_box.set_text('')
|
||||
self.filter_info.set_text('')
|
||||
self.walker[:] = self.tracks_walker
|
||||
|
@ -596,12 +582,12 @@ class SongListBox(urwid.Frame):
|
|||
# There are some pages like search library where overwriting the queue
|
||||
# doesn't make much sense. We can also assume that someone searching
|
||||
# for a specific song also wants to append.
|
||||
elif (page.append or FILTERING) and page.name != 'Queue':
|
||||
elif (page.append or hotkey_manager.filtering) and page.slug != 'queue':
|
||||
self.item_append_requested(songitem)
|
||||
else:
|
||||
player.load_queue(self.tracks, songitem.index)
|
||||
|
||||
if FILTERING:
|
||||
if hotkey_manager.filtering and page.slug != 'search':
|
||||
self.walker[:] = self.get_filtered_items()
|
||||
|
||||
@staticmethod
|
||||
|
@ -736,49 +722,8 @@ class SongListBox(urwid.Frame):
|
|||
songlistitem.set_index(i)
|
||||
|
||||
def keypress(self, size, key):
|
||||
if filter_out(key):
|
||||
self.perform_filtering(key)
|
||||
|
||||
return hotkey_manager.keypress("song_view", self, super(SongListBox, self), size, key)
|
||||
|
||||
def move_to_beginning(self):
|
||||
"""Move to the focus to beginning of the songlist"""
|
||||
self.list_box.set_focus(0, 'below')
|
||||
return False
|
||||
|
||||
def move_to_end(self):
|
||||
"""Move to the focus to end of the songlist"""
|
||||
self.list_box.set_focus(-1, 'above')
|
||||
return False
|
||||
|
||||
def move_up(self):
|
||||
"""Move the focus an item up in the playlist"""
|
||||
_, index = self.walker.get_focus()
|
||||
|
||||
if index is None:
|
||||
return False
|
||||
|
||||
if index <= 0:
|
||||
self.list_box.set_focus(len(self.walker) - 1, 'below')
|
||||
else:
|
||||
self.list_box.set_focus(index - 1, 'above')
|
||||
|
||||
return False
|
||||
|
||||
def move_down(self):
|
||||
"""Move the focus an item down in the playlist """
|
||||
_, index = self.walker.get_focus()
|
||||
|
||||
if index is None:
|
||||
return False
|
||||
|
||||
if index >= len(self.walker) - 1:
|
||||
self.list_box.set_focus(0, 'above')
|
||||
else:
|
||||
self.list_box.set_focus(index + 1, 'below')
|
||||
|
||||
return False
|
||||
|
||||
def mouse_event(self, size, event, button, col, row, focus):
|
||||
"""
|
||||
Handle mouse event.
|
||||
|
|
Loading…
Add table
Reference in a new issue