Skip to content
This repository has been archived by the owner on Jul 20, 2021. It is now read-only.

Icons theming #10

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
26 changes: 26 additions & 0 deletions config.py
@@ -0,0 +1,26 @@
import rb
from gi.repository import Gtk, Gio, GObject, PeasGtk

class TrayIconConfig(GObject.Object, PeasGtk.Configurable):

__gtype_name__ = 'TrayIconConfig'
object = GObject.property(type=GObject.Object)

options = \
{
'normal-icon': ('normal_icon', 'text', Gio.SettingsBindFlags.DEFAULT),
'play-icon': ('play_icon', 'text', Gio.SettingsBindFlags.DEFAULT),
'merge-play-icon': ('merge_play_icon', 'active', Gio.SettingsBindFlags.DEFAULT)
}

def do_create_configure_widget(self):
self.settings = Gio.Settings("org.gnome.rhythmbox.plugins.trayicon")
self.builder = Gtk.Builder()
self.builder.add_from_file(rb.find_plugin_file(self, "trayicon-prefs.ui"))

for key, (name, prop, flags) in self.options.items():
self.settings.bind(key, self.builder.get_object(name), prop, flags)

return self.builder.get_object("trayicon-prefs")

GObject.type_register(TrayIconConfig)
3 changes: 3 additions & 0 deletions debian/install
@@ -1,2 +1,5 @@
tray_icon.py usr/lib/rhythmbox/plugins/tray-icon
config.py usr/lib/rhythmbox/plugins/tray-icon
tray_icon.plugin usr/lib/rhythmbox/plugins/tray-icon
trayicon-prefs.ui usr/share/rhythmbox/plugins/tray_icon
org.gnome.rhythmbox.plugins.trayicon.gschema.xml /usr/share/glib-2.0/schemas
3 changes: 3 additions & 0 deletions debian/postinst
@@ -0,0 +1,3 @@
#!/bin/sh

glib-compile-schemas /usr/share/glib-2.0/schemas/
18 changes: 18 additions & 0 deletions org.gnome.rhythmbox.plugins.trayicon.gschema.xml
@@ -0,0 +1,18 @@
<schemalist>
<schema id="org.gnome.rhythmbox.plugins.trayicon" path="/org/gnome/rhythmbox/plugins/trayicon/">
<key name="normal-icon" type="s">
<default>'rhythmbox'</default>
<summary>Normal icon (paused/stopped)</summary>
<description>Normal icon (paused/stopped)</description>
</key>
<key name="play-icon" type="s">
<default>'media-playback-start'</default>
<summary>Play icon</summary>
<description>Play icon</description>
</key>
<key name="merge-play-icon" type="b">
<default>true</default>
</key>
<child name="source" schema="org.gnome.rhythmbox.source"/>
</schema>
</schemalist>
67 changes: 48 additions & 19 deletions tray_icon.py
@@ -1,9 +1,9 @@
from gi.repository import Gtk, Gdk, GdkPixbuf, Peas, GObject
import cairo
from gi.repository import Gtk, Gio, Gdk, GdkPixbuf, Peas, GObject
import os

iconsPath = "/usr/share/icons/"
rhythmboxIcon = iconsPath + "hicolor/32x32/apps/rhythmbox.png"
playIcon = iconsPath + "gnome/32x32/actions/media-playback-start.png"
from config import TrayIconConfig

default_icon_size = 32

class TrayIcon(GObject.Object, Peas.Activatable):

Expand Down Expand Up @@ -38,15 +38,17 @@ def hide_on_delete(self, widget, event):
return True # don't actually delete

def set_playing_icon(self, player, playing):
if playing:
self.icon.set_property("pixbuf", self.playIcon)
icon = self.play_icon if playing else self.normal_icon
if type(icon) is str:
self.icon.set_from_icon_name(icon)
else:
self.icon.set_property("pixbuf", self.normalIcon)
self.icon.set_from_pixbuf(icon)

def do_activate(self):
self.shell = self.object
self.wind = self.shell.get_property("window")
self.player = self.shell.props.shell_player
self.settings = Gio.Settings("org.gnome.rhythmbox.plugins.trayicon")

self.wind.connect("delete-event", self.hide_on_delete)

Expand All @@ -73,20 +75,47 @@ def do_activate(self):
])
ui.insert_action_group(ag)
self.popup = ui.get_widget("/PopupMenu")

s1 = cairo.ImageSurface.create_from_png(rhythmboxIcon)
s2 = cairo.ImageSurface.create_from_png(playIcon)
ctx = cairo.Context(s1)
ctx.set_source_surface(s2, 0, 0)
ctx.paint()
self.playIcon = Gdk.pixbuf_get_from_surface(s1, 0, 0, s1.get_width(), s1.get_height())

self.normalIcon = GdkPixbuf.Pixbuf.new_from_file(rhythmboxIcon)
self.icon = Gtk.StatusIcon.new_from_pixbuf(self.normalIcon)

self.icon = Gtk.StatusIcon()
self.update_icons()
self.icon.connect("scroll-event", self.scroll)
self.icon.connect("popup-menu", self.popup_menu)
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removing this whole block results in an icon that's just a "play" symbol, not a "play + Rhythmbox" symbol, which is what I was going for.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated. Options dialog has been added: choosing icons/files and drawing mode.

self.icon.connect("button-press-event", self.toggle)
self.player.connect("playing-changed", self.set_playing_icon)
self.settings.connect("changed::", lambda settings, key: self.update_icons())
Gtk.IconTheme.get_default().connect("changed", lambda theme: self.update_icons())

def read_icon(self, name, icon_as_pixbuf):
if os.path.isabs(name):
return GdkPixbuf.Pixbuf.new_from_file(name)
elif icon_as_pixbuf:
return Gtk.IconTheme.get_default().load_icon(name, default_icon_size, 0)
elif Gtk.IconTheme.get_default().has_icon(name):
return name
else:
return None

def update_icons(self):
merge = self.settings.get_boolean('merge-play-icon')
normal_name = self.settings.get_string('normal-icon')
play_name = self.settings.get_string('play-icon')

try:
self.normal_icon = self.read_icon(normal_name, merge)
self.play_icon = self.read_icon(play_name, merge)
except GObject.GError:
return

if self.normal_icon is None or self.play_icon is None:
return

if merge:
play_icon = self.normal_icon.copy()
scalex, scaley = float(self.normal_icon.props.width)/self.play_icon.props.width, float(self.normal_icon.props.height)/self.play_icon.props.height
self.play_icon.composite(play_icon, 0, 0, self.normal_icon.props.width, self.normal_icon.props.height, 0, 0, scalex, scaley, GdkPixbuf.InterpType.HYPER, 255)
self.play_icon = play_icon

self.set_playing_icon(self.player, self.player.props.playing)

def scroll(self, widget, event):
if self.player.playpause(True):
Expand All @@ -99,4 +128,4 @@ def scroll(self, widget, event):

def do_deactivate(self):
self.icon.set_visible(False)
del self.icon
del self.icon
124 changes: 124 additions & 0 deletions trayicon-prefs.ui
@@ -0,0 +1,124 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<!-- interface-requires gtk+ 3.0 -->
<object class="GtkBox" id="trayicon-prefs">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="margin_left">10</property>
<property name="margin_right">10</property>
<property name="margin_top">10</property>
<property name="margin_bottom">10</property>
<property name="orientation">vertical</property>
<property name="spacing">5</property>
<child>
<object class="GtkLabel" id="label3">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xalign">0</property>
<property name="label" translatable="yes">Icons setup</property>
<attributes>
<attribute name="weight" value="bold"/>
</attributes>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkGrid" id="grid1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="row_spacing">5</property>
<property name="column_spacing">5</property>
<child>
<object class="GtkLabel" id="label1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xalign">1</property>
<property name="label" translatable="yes">Normal icon:</property>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">0</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label2">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xalign">1</property>
<property name="label" translatable="yes">Playing:</property>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">1</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
<child>
<object class="GtkEntry" id="normal_icon">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="hexpand">True</property>
<property name="invisible_char">•</property>
<property name="invisible_char_set">True</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">0</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
<child>
<object class="GtkEntry" id="play_icon">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="hexpand">True</property>
<property name="invisible_char">•</property>
<property name="invisible_char_set">True</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">1</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
<child>
<object class="GtkCheckButton" id="merge_play_icon">
<property name="label" translatable="yes">Draw 'play' icon over 'normal'</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="halign">end</property>
<property name="xalign">0</property>
<property name="draw_indicator">True</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">2</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
<child>
<placeholder/>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
<child>
<placeholder/>
</child>
</object>
</interface>