File: identicon.py

package info (click to toggle)
syncthing-gtk 0.9.4.4%2Bds%2Bgit20201209%2Bc46fbd8-1
  • links: PTS, VCS
  • area: main
  • in suites: bullseye
  • size: 3,260 kB
  • sloc: python: 7,592; sh: 259; xml: 115; makefile: 2
file content (77 lines) | stat: -rw-r--r-- 2,148 bytes parent folder | download
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))