1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135
|
# encoding: utf-8
# title: Spec buttons for apps
# description: Adds configurable mini toolbar buttons
# version: 0.8.2
# depends: streamtuner2 >= 2.2.0
# type: feature
# category: ui
# config:
# { name: specbutton_rows, value: 2, max: 4, type: int, description: "Number of rows to arrange buttons in." }
# { name: specbuttons, type: dict, columns: "Icon,Command", description: "Icons can be `<a href='http://www.pygtk.org/pygtk2reference/gtk-stock-items.html'>gtk-xyz</a>` internal names. Else use `/usr/share/icon/*.png` file names. Icon file basenames will be expanded into full paths." }
# documentation:
# http://fossil.include-once.org/streamtuner2/info/43b36ed35b1488d5
#
# Adds the mini/extra buttons in the toolbar, which allow to control your
# audio player or run other system commands.
#
# [Icon] [Cmd]
#
# volume pavucontrol
#
# up amixer sset Master 5%+
#
# kill pkill vlc
#
# Icons can be gtk-xyz icon names or /usr/share/icon/* PNG files.
# Each command may use streamtuner2 placeholders like %g or %url and $title.
import os.path
import subprocess
import math
import re
from config import conf, log, plugin_meta
import action
from uikit import gtk
# Extra/mini buttons in toolbar
class specbuttons(object):
meta = plugin_meta()
module = 'specbuttons'
# Hook toolbar label
def __init__(self, parent):
if not parent:
return
self.parent = parent
conf.add_plugin_defaults(self.meta, self.module)
self.specbuttons = parent.get_widget("specbuttons")
parent.hooks["init"].append(self.update_buttons)
parent.hooks["config_save"].append(self.update_paths)
parent.specbuttons.show()
# Extra buttons
def update_buttons(self, parent):
# define table width (2 rows default)
y = conf.specbuttons_rows if "specbuttons_rows" in conf else 2
y = max(min(int(conf.specbutton_rows), 4), 1) # 1 <= y <= 4
self.specbuttons.resize(y, int(math.ceil(len(conf.specbuttons) / y)))
# clean up
for widget in self.specbuttons.get_children():
widget.destroy()
# add icon buttons
#for xy, (btn, cmd) in enumerate(conf.specbuttons.items()):
for xy, (btn) in enumerate( sorted ( conf.specbuttons )):
cmd = conf.specbuttons [btn]
#log.IN(btn, cmd)
w_btn = gtk.Button()
w_btn.set_image(self.icon(btn))
w_btn.connect("clicked", lambda x0, cmd=cmd, *x: self.action(cmd))
self.specbuttons.attach(
child = w_btn,
left_attach = int(xy / y),
right_attach = int(xy / y) + 1,
top_attach = xy % y,
bottom_attach = (xy % y) + 1,
xoptions = gtk.EXPAND,
yoptions = gtk.EXPAND,
xpadding = 1,
ypadding = 1
)
self.specbuttons.show_all()
# Instantiate Image from gtk-* string or path
def icon(self, btn):
wi = gtk.Image()
if (btn.find("gtk-") == 0):
wi.set_from_stock(btn, gtk.ICON_SIZE_SMALL_TOOLBAR)
else:
if not os.path.exists(btn):
btn = self.locate(btn)
log.DATA(btn)
if btn:
wi.set_from_file(btn)
else:
wi.set_from_stock("gtk-image-missing", gtk.ICON_SIZE_SMALL_TOOLBAR)
return wi
# Look for image basename (e.g. "play") in /usr/share/icons/*.* and /pixmaps/*
def locate(self, btn, f=None):
try:
f = subprocess.Popen(["locate", "/usr/share/[pi]*s/*%s*.*" % btn], stdout=subprocess.PIPE)
except:
return None
path, err = f.communicate()
if not err:
return path.split("\n")[0]
# Update paths when saving config dialog
def update_paths(self):
r = {}
for btn, cmd in conf.specbuttons.items():
# replace "gtk." to "gtk-"
if re.match("^gtk\.\w+", btn, re.I):
btn = re.sub("[._]+", "-", btn).lower()
# not /path or gtk-
elif not re.match("^(/|\./|gtk-|\w:[\\\\/])", btn):
path = self.locate(btn)
if path:
btn = path
else:
log.WARN("Extra button icon '%s' could not be found" % btn)
r[btn] = cmd
conf.specbuttons = r
self.update_buttons(self.parent)
# Button callback, allow for %url/%title placeholders
def action(self, cmd):
if re.search("[%$]", cmd):
row = self.parent.channel().row()
cmd = action.run_fmt_url(cmd, row=row, add_default=False, cmd=cmd)
action.run(cmd)
|