new GTK gui
This commit is contained in:
parent
03c5822c4c
commit
2e95986047
8 changed files with 712 additions and 498 deletions
|
|
@ -1,4 +1,4 @@
|
||||||
#!/usr/bin/python
|
#!/usr/bin/env python
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
47
data/de.coderkun.MCG.gschema.xml
Normal file
47
data/de.coderkun.MCG.gschema.xml
Normal file
|
|
@ -0,0 +1,47 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<schemalist>
|
||||||
|
<schema path="/de/coderkun/mcg/" id="de.coderkun.mcg" gettext-domain="mcg">
|
||||||
|
<key type="ai" name="window-size">
|
||||||
|
<default>[800, 600]</default>
|
||||||
|
<summary>Window size</summary>
|
||||||
|
<description>Window size (width and height).</description>
|
||||||
|
</key>
|
||||||
|
<key type="b" name="window-maximized">
|
||||||
|
<default>false</default>
|
||||||
|
<summary>Window maximized</summary>
|
||||||
|
<description>Window maximized state.</description>
|
||||||
|
</key>
|
||||||
|
<key type="i" name="profile">
|
||||||
|
<default>0</default>
|
||||||
|
<summary>Last selected profile</summary>
|
||||||
|
<description>The index of the last selected profile used to connect to the MPD server.</description>
|
||||||
|
</key>
|
||||||
|
<key type="i" name="panel">
|
||||||
|
<range min="1" max="3"/>
|
||||||
|
<default>1</default>
|
||||||
|
<summary>Last selected panel</summary>
|
||||||
|
<description>The index of the last selected panel.</description>
|
||||||
|
</key>
|
||||||
|
<key type="i" name="item-size">
|
||||||
|
<range min="100" max="1000" />
|
||||||
|
<default>150</default>
|
||||||
|
<summary>Size of library items</summary>
|
||||||
|
<description>The size of items displayed in the library.</description>
|
||||||
|
</key>
|
||||||
|
<key type="s" name="sort-order">
|
||||||
|
<default>'year'</default>
|
||||||
|
<choices>
|
||||||
|
<choice value='artist' />
|
||||||
|
<choice value='title' />
|
||||||
|
<choice value='year' />
|
||||||
|
</choices>
|
||||||
|
<summary>Sort criterium for library items</summary>
|
||||||
|
<description>The sort criterium of items displayed in the library.</description>
|
||||||
|
</key>
|
||||||
|
<key type="b" name="sort-type">
|
||||||
|
<default>true</default>
|
||||||
|
<summary>Sort type for library items</summary>
|
||||||
|
<description>The sort type of items displayed in the library.</description>
|
||||||
|
</key>
|
||||||
|
</schema>
|
||||||
|
</schemalist>
|
||||||
BIN
data/gschemas.compiled
Normal file
BIN
data/gschemas.compiled
Normal file
Binary file not shown.
|
Before Width: | Height: | Size: 78 KiB After Width: | Height: | Size: 78 KiB |
5
gui/__init__.py
Normal file
5
gui/__init__.py
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
#!/usr/bin/env python
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
1278
gui/gtk.py
1278
gui/gtk.py
File diff suppressed because it is too large
Load diff
33
mcg.py
33
mcg.py
|
|
@ -144,6 +144,12 @@ class MCGClient(MCGBase, mpd.MPDClient):
|
||||||
self._add_action(self._play_album, album)
|
self._add_action(self._play_album, album)
|
||||||
|
|
||||||
|
|
||||||
|
def seek(self, pos, time):
|
||||||
|
"""Seeks to a song at a position
|
||||||
|
"""
|
||||||
|
self._add_action(self._seek, pos, time)
|
||||||
|
|
||||||
|
|
||||||
def stop(self):
|
def stop(self):
|
||||||
self._add_action(self._stop)
|
self._add_action(self._stop)
|
||||||
|
|
||||||
|
|
@ -340,6 +346,10 @@ class MCGClient(MCGBase, mpd.MPDClient):
|
||||||
self._call('playid', track_ids[0])
|
self._call('playid', track_ids[0])
|
||||||
|
|
||||||
|
|
||||||
|
def _seek(self, pos, time):
|
||||||
|
self._call('seek', pos, time)
|
||||||
|
|
||||||
|
|
||||||
def _stop(self):
|
def _stop(self):
|
||||||
self._call('stop')
|
self._call('stop')
|
||||||
|
|
||||||
|
|
@ -766,6 +776,8 @@ class MCGProfileConfig(MCGConfig):
|
||||||
self.add_section(section)
|
self.add_section(section)
|
||||||
for attribute in profile.get_attributes():
|
for attribute in profile.get_attributes():
|
||||||
self.set(section, attribute, str(profile.get(attribute)))
|
self.set(section, attribute, str(profile.get(attribute)))
|
||||||
|
for section in self.sections()[len(self._profiles)+1:]:
|
||||||
|
self.remove_section(section)
|
||||||
super().save()
|
super().save()
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -825,13 +837,15 @@ class MCGProfile(MCGConfigurable):
|
||||||
class MCGCache():
|
class MCGCache():
|
||||||
DIRNAME = '~/.cache/mcg/'
|
DIRNAME = '~/.cache/mcg/'
|
||||||
SIZE_FILENAME = 'size'
|
SIZE_FILENAME = 'size'
|
||||||
|
_lock = threading.Lock()
|
||||||
|
|
||||||
|
|
||||||
def __init__(self, host, size):
|
def __init__(self, host, size):
|
||||||
|
self._host = host
|
||||||
|
self._size = size
|
||||||
self._dirname = os.path.expanduser(os.path.join(MCGCache.DIRNAME, host))
|
self._dirname = os.path.expanduser(os.path.join(MCGCache.DIRNAME, host))
|
||||||
if not os.path.exists(self._dirname):
|
if not os.path.exists(self._dirname):
|
||||||
os.makedirs(self._dirname)
|
os.makedirs(self._dirname)
|
||||||
self._size = size
|
|
||||||
self._read_size()
|
self._read_size()
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -841,23 +855,28 @@ class MCGCache():
|
||||||
|
|
||||||
def _read_size(self):
|
def _read_size(self):
|
||||||
size = 100
|
size = 100
|
||||||
|
MCGCache._lock.acquire()
|
||||||
|
# Read old size
|
||||||
filename = os.path.join(self._dirname, MCGCache.SIZE_FILENAME)
|
filename = os.path.join(self._dirname, MCGCache.SIZE_FILENAME)
|
||||||
if os.path.exists(filename):
|
if os.path.exists(filename):
|
||||||
with open(filename, 'r') as f:
|
with open(filename, 'r') as f:
|
||||||
size = int(f.readline())
|
size = int(f.readline())
|
||||||
|
# Clear cache if size has changed
|
||||||
if size != self._size:
|
if size != self._size:
|
||||||
self._clear()
|
self._clear()
|
||||||
with open(filename, 'w') as f:
|
# Write new size
|
||||||
f.write(str(self._size))
|
with open(filename, 'w') as f:
|
||||||
|
f.write(str(self._size))
|
||||||
|
MCGCache._lock.release()
|
||||||
|
|
||||||
|
|
||||||
def _clear(self):
|
def _clear(self):
|
||||||
for filename in os.listdir(self._dirname):
|
for filename in os.listdir(self._dirname):
|
||||||
path = os.path.join(self._dirname, filename)
|
path = os.path.join(self._dirname, filename)
|
||||||
try:
|
if os.path.isfile(path):
|
||||||
if os.path.isfile(path):
|
try:
|
||||||
os.unlink(path)
|
os.unlink(path)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print("clear:", e)
|
print("clear:", e)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
29
mcgGtk.py
29
mcgGtk.py
|
|
@ -6,24 +6,33 @@
|
||||||
__author__ = "coderkun"
|
__author__ = "coderkun"
|
||||||
__email__ = "<olli@coderkun.de>"
|
__email__ = "<olli@coderkun.de>"
|
||||||
__license__ = "GPL"
|
__license__ = "GPL"
|
||||||
__version__ = "0.3"
|
__version__ = "0.4"
|
||||||
__status__ = "Development"
|
__status__ = "Development"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
|
||||||
from gi.repository import Gtk, Gdk, GObject
|
from gi.repository import Gtk, Gdk, GObject
|
||||||
|
|
||||||
import gui.gtk
|
from gui import gtk
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# Set environment
|
||||||
|
srcdir = os.path.abspath(os.path.join(os.path.dirname(gtk.__file__), '..'))
|
||||||
|
if not os.environ.get('GSETTINGS_SCHEMA_DIR'):
|
||||||
|
os.environ['GSETTINGS_SCHEMA_DIR'] = os.path.join(srcdir, 'data')
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
GObject.threads_init()
|
# Start application
|
||||||
Gdk.threads_init()
|
app = gtk.Application()
|
||||||
mcgg = gui.gtk.MCGGtk()
|
exit_status = app.run(sys.argv)
|
||||||
mcgg.show_all()
|
sys.exit(exit_status)
|
||||||
try:
|
|
||||||
Gtk.main()
|
|
||||||
except (KeyboardInterrupt, SystemExit):
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue