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
|
#!/usr/bin/env python3
"""
Syncthing-GTK - Ident Icon
Custom widget derived from Gtk.DrawingArea.
Draws Ident Icon on transparent background.
Most of drawing code is ported from
https://github.com/syncthing/syncthing/blob/master/gui/scripts/syncthing/core/directives/identiconDirective.js"""
from gi.repository import Gtk
from syncthing_gtk.infobox import InfoBox
import re
class IdentIcon(Gtk.DrawingArea):
def __init__(self, device_id):
Gtk.DrawingArea.__init__(self)
self.value = re.sub(r'[\W_]', "", device_id, 1)
self.color = (1, 1, 0.95, 1) # icon color, rgba
self.size = 5
def set_color_hex(self, hx):
""" Expects AABBCC or #AABBCC format """
self.set_color(*InfoBox.hex2color(hx))
def set_color(self, r, g, b, a):
""" Expects floats """
self.color = (r, g, b, a)
self.queue_draw()
def do_get_preferred_width(self):
# Icon scales to whatever you give, but preferred
# size is always 22x22
return (22, 22)
def do_get_preferred_height(self):
# Rectangle...
return self.do_get_preferred_width()
def do_get_request_mode(self):
return Gtk.SizeRequestMode.CONSTANT_SIZE
def do_draw(self, cr):
def fill_rect_at(row, col):
cr.rectangle(
offset_x + (col * rect_size),
offset_y + (row * rect_size),
rect_size, rect_size
)
cr.fill()
def should_fill_rect_at(row, col):
return not (ord(self.value[row + col * self.size]) % 2)
def should_mirror_rect_at(row, col):
return not (self.size % 2 and col == middle_col)
def mirror_col_for(col):
return self.size - col - 1
# Prepare stuff
allocation = self.get_allocation()
rect_size = min(allocation.width, allocation.height) / self.size
offset_x = (allocation.width // 2) - (rect_size * self.size // 2)
offset_y = (allocation.height // 2) - (rect_size * self.size // 2)
middle_col = self.size // 2
# Set color
cr.set_source_rgba(*self.color)
# Do drawing
for row in range(0, self.size):
for col in range(0, middle_col + 1):
if should_fill_rect_at(row, col):
fill_rect_at(row, col)
if should_mirror_rect_at(row, col):
fill_rect_at(row, mirror_col_for(col))
|