117 lines
3.8 KiB
Python
117 lines
3.8 KiB
Python
|
#!/usr/bin/env python3
|
||
|
|
||
|
import gi
|
||
|
gi.require_version('Gtk', '3.0')
|
||
|
from gi.repository import Gtk, Gdk, GdkPixbuf
|
||
|
import os
|
||
|
import textwrap
|
||
|
|
||
|
|
||
|
# Return a pixbuf from icon name
|
||
|
def get_icon(name, size):
|
||
|
""" Return a GdkPixbuf.Pixbuf """
|
||
|
found = False
|
||
|
if name.startswith('/'):
|
||
|
try:
|
||
|
# name is an absolute pathname to a file
|
||
|
pixbuf = GdkPixbuf.Pixbuf.new_from_file(name)
|
||
|
pixbuf = pixbuf.scale_simple(size, size, GdkPixbuf.InterpType.BILINEAR)
|
||
|
found = True
|
||
|
except gi.repository.GLib.GError:
|
||
|
name = os.path.basename(name).split('.')[0]
|
||
|
|
||
|
if not found:
|
||
|
theme = Gtk.IconTheme.get_default()
|
||
|
try:
|
||
|
pixbuf = theme.load_icon(name, size, Gtk.IconLookupFlags.USE_BUILTIN)
|
||
|
except gi.repository.GLib.GError:
|
||
|
try:
|
||
|
filename = os.path.join('/usr/share/pixmaps', name)
|
||
|
pixbuf = GdkPixbuf.Pixbuf.new_from_file(filename)
|
||
|
found = True
|
||
|
except gi.repository.GLib.GError:
|
||
|
pixbuf = theme.load_icon(Gtk.STOCK_PREFERENCES, 16, 0)
|
||
|
|
||
|
if pixbuf.get_width() != size or pixbuf.get_height() != size:
|
||
|
pixbuf = pixbuf.scale_simple(size, size, GdkPixbuf.InterpType.BILINEAR)
|
||
|
|
||
|
return pixbuf
|
||
|
|
||
|
|
||
|
# My widget: icon and label wrapped in an EventBox
|
||
|
class DesktopToolWidget(Gtk.EventBox):
|
||
|
|
||
|
def __init__(self, label, icon_name, icon_size=48, orientation=Gtk.Orientation.VERTICAL, border=4, wrap=0):
|
||
|
Gtk.EventBox.__init__(self)
|
||
|
|
||
|
self.set_border_width(0)
|
||
|
self.set_events(Gdk.EventMask.BUTTON_PRESS_MASK)
|
||
|
|
||
|
vbox = Gtk.Box(orientation=orientation, spacing=border)
|
||
|
vbox.set_border_width(int(border / 2))
|
||
|
|
||
|
btn_image = Gtk.Image()
|
||
|
pixbuf = get_icon(icon_name, icon_size)
|
||
|
btn_image.set_from_pixbuf(pixbuf)
|
||
|
|
||
|
vbox.pack_start(btn_image, expand=False, fill=False, padding=0)
|
||
|
|
||
|
if label is not None:
|
||
|
label_markup = textwrap.fill(label, wrap) if wrap else label
|
||
|
btn_label = Gtk.Label(label_markup, wrap=True)
|
||
|
btn_label.set_use_markup(True)
|
||
|
vbox.pack_start(btn_label, expand=False, fill=False, padding=0)
|
||
|
|
||
|
self.add(vbox)
|
||
|
self.show_all()
|
||
|
|
||
|
def connect_clicked(self, callback, *args):
|
||
|
self.connect("button_press_event", lambda widget, event: callback(*args))
|
||
|
|
||
|
|
||
|
class Test:
|
||
|
Value = 5
|
||
|
|
||
|
def do_something(self, args):
|
||
|
print("do_something: args:", args, "value:", self.Value)
|
||
|
|
||
|
|
||
|
class MainWindow(Gtk.Window):
|
||
|
|
||
|
def __init__(self):
|
||
|
Gtk.Window.__init__(self, title="DesktopToolWidget Test")
|
||
|
self.set_border_width(10)
|
||
|
|
||
|
vbox = Gtk.VBox(spacing=8)
|
||
|
|
||
|
icon_size = 48
|
||
|
|
||
|
# Button 1
|
||
|
icon_button1 = DesktopToolWidget("<b>Hello</b>\nIconButton", 'vlc', icon_size)
|
||
|
icon_button1.set_size_request(150, 150)
|
||
|
vbox.pack_start(icon_button1, expand=False, fill=False, padding=0)
|
||
|
# Attach a callback
|
||
|
test = Test()
|
||
|
icon_button1.connect_clicked(test.do_something, "Hello")
|
||
|
|
||
|
# Button 2
|
||
|
label = "<b>Hello</b>\nIconButton Horizontal"
|
||
|
icon_button2 = DesktopToolWidget(label, 'synaptic', icon_size, Gtk.Orientation.HORIZONTAL)
|
||
|
icon_button2.set_size_request(200, 100)
|
||
|
vbox.pack_start(icon_button2, expand=False, fill=False, padding=0)
|
||
|
|
||
|
# Button 3
|
||
|
label = "<b>Hello</b>This is a very long label a very long label a very long label"
|
||
|
icon_button3 = DesktopToolWidget(label, 'synaptic', icon_size, Gtk.Orientation.HORIZONTAL, wrap=30)
|
||
|
icon_button3.set_size_request(200, 100)
|
||
|
vbox.pack_start(icon_button3, expand=False, fill=False, padding=0)
|
||
|
|
||
|
self.add(vbox)
|
||
|
|
||
|
|
||
|
if __name__ == "__main__":
|
||
|
win = MainWindow()
|
||
|
win.connect("destroy", Gtk.main_quit)
|
||
|
win.show_all()
|
||
|
Gtk.main()
|