- image helper creates a mask image for later processing
- image helper can force transparency - added option for semitransparent avatars
This commit is contained in:
parent
729f7ebd92
commit
d1560d57a8
5 changed files with 147 additions and 78 deletions
|
|
@ -21,6 +21,7 @@ import PIL
|
|||
import PIL.Image as Image
|
||||
import os
|
||||
import io
|
||||
import copy
|
||||
gi.require_version('GdkPixbuf', '2.0')
|
||||
# pylint: disable=wrong-import-position
|
||||
from gi.repository import Gio, GdkPixbuf # nopep8
|
||||
|
|
@ -37,7 +38,7 @@ class SurfaceGetter():
|
|||
self.url = url
|
||||
self.size = size
|
||||
|
||||
def get_url(self):
|
||||
def get_url(self, alpha):
|
||||
"""Downloads and decodes"""
|
||||
try:
|
||||
resp = requests.get(
|
||||
|
|
@ -48,9 +49,9 @@ class SurfaceGetter():
|
|||
)
|
||||
raw = resp.raw
|
||||
image = Image.open(raw)
|
||||
surface = from_pil(image)
|
||||
(surface, mask) = from_pil(image, alpha)
|
||||
|
||||
self.func(self.identifier, surface)
|
||||
self.func(self.identifier, surface, mask)
|
||||
except requests.HTTPError:
|
||||
log.error("Unable to open %s", self.url)
|
||||
except requests.TooManyRedirects:
|
||||
|
|
@ -66,7 +67,7 @@ class SurfaceGetter():
|
|||
except PIL.UnidentifiedImageError:
|
||||
log.error("Unknown image type")
|
||||
|
||||
def get_file(self):
|
||||
def get_file(self, alpha):
|
||||
locations = [os.path.expanduser('~/.local/'), '/usr/', '/app']
|
||||
for prefix in locations:
|
||||
mixpath = os.path.join(prefix, self.url)
|
||||
|
|
@ -82,56 +83,53 @@ class SurfaceGetter():
|
|||
except FileNotFoundError:
|
||||
log.error("File not found: %s", mixpath)
|
||||
if image:
|
||||
surface = from_pil(image)
|
||||
(surface, mask) = from_pil(image, alpha)
|
||||
if surface:
|
||||
self.func(self.identifier, surface)
|
||||
self.func(self.identifier, surface, mask)
|
||||
return
|
||||
|
||||
|
||||
def from_pil(image, alpha=1.0):
|
||||
def from_pil(image, alpha):
|
||||
"""
|
||||
:param im: Pillow Image
|
||||
:param alpha: 0..1 alpha to add to non-alpha images
|
||||
:param format: Pixel format for output surface
|
||||
"""
|
||||
arr = bytearray()
|
||||
mask = bytearray()
|
||||
if 'A' not in image.getbands():
|
||||
image.putalpha(int(alpha * 256.))
|
||||
arr = bytearray(image.tobytes('raw', 'BGRa'))
|
||||
image.putalpha(int(alpha * 255.0))
|
||||
arr = bytearray(image.tobytes('raw', 'BGRa'))
|
||||
mask = arr
|
||||
else:
|
||||
arr = bytearray(image.tobytes('raw', 'BGRa'))
|
||||
mask = copy.deepcopy((arr))
|
||||
idx = 3
|
||||
while idx < len(arr):
|
||||
if arr[idx] > 0:
|
||||
mask[idx] = 255
|
||||
else:
|
||||
mask[idx] = 0
|
||||
arr[idx] = int(arr[idx] * alpha)
|
||||
idx += 4
|
||||
surface = cairo.ImageSurface.create_for_data(
|
||||
arr, cairo.FORMAT_ARGB32, image.width, image.height)
|
||||
return surface
|
||||
mask = cairo.ImageSurface.create_for_data(
|
||||
mask, cairo.FORMAT_ARGB32, image.width, image.height)
|
||||
return (surface, mask)
|
||||
|
||||
|
||||
def get_surface(func, identifier, ava, size):
|
||||
def get_surface(func, identifier, ava, size, alpha=1.0):
|
||||
"""Download to cairo surface"""
|
||||
image_getter = SurfaceGetter(func, identifier, ava, size)
|
||||
if identifier.startswith('http'):
|
||||
thread = threading.Thread(target=image_getter.get_url, args=())
|
||||
thread = threading.Thread(target=image_getter.get_url, args=[alpha])
|
||||
thread.start()
|
||||
else:
|
||||
thread = threading.Thread(target=image_getter.get_file, args=())
|
||||
thread = threading.Thread(target=image_getter.get_file, args=[alpha])
|
||||
thread.start()
|
||||
|
||||
|
||||
def make_surface_from_raw(raw, size):
|
||||
"""Create surface from raw notification data"""
|
||||
width = raw[0]
|
||||
height = raw[1]
|
||||
rowstride = raw[2]
|
||||
hasalpha = raw[3]
|
||||
bitspersample = raw[4]
|
||||
channels = raw[5]
|
||||
image_raw_dbus = raw[6]
|
||||
image_raw = bytes(image_raw_dbus)
|
||||
image = None
|
||||
if hasalpha:
|
||||
image = Image.frombytes('RGBA', [width, height], image_raw, 'raw')
|
||||
else:
|
||||
image = Image.frombytes('RGB', [width, height], image_raw, 'raw')
|
||||
surface = from_pil(image)
|
||||
return surface
|
||||
|
||||
|
||||
def get_aspected_size(img, width, height, anchor=0, hanchor=0):
|
||||
"""Get dimensions of image keeping current aspect ratio"""
|
||||
pic_width = img.get_width()
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ import re
|
|||
import cairo
|
||||
import math
|
||||
import gi
|
||||
from .image_getter import get_surface, draw_img_to_rect, get_aspected_size, make_surface_from_raw
|
||||
from .image_getter import get_surface, draw_img_to_rect, get_aspected_size
|
||||
from .overlay import OverlayWindow
|
||||
gi.require_version("Gtk", "3.0")
|
||||
gi.require_version('PangoCairo', '1.0')
|
||||
|
|
@ -67,8 +67,8 @@ class NotificationOverlayWindow(OverlayWindow):
|
|||
self.redraw()
|
||||
|
||||
def set_blank(self):
|
||||
self.content=[]
|
||||
self.needsredraw=True
|
||||
self.content = []
|
||||
self.needsredraw = True
|
||||
|
||||
def tick(self):
|
||||
# This doesn't really belong in overlay or settings
|
||||
|
|
@ -164,7 +164,7 @@ class NotificationOverlayWindow(OverlayWindow):
|
|||
get_surface(self.recv_icon, icon, icon,
|
||||
self.icon_size)
|
||||
|
||||
def recv_icon(self, identifier, pix):
|
||||
def recv_icon(self, identifier, pix, mask):
|
||||
"""
|
||||
Called when image_getter has downloaded an image
|
||||
"""
|
||||
|
|
|
|||
|
|
@ -56,8 +56,8 @@ class TextOverlayWindow(OverlayWindow):
|
|||
self.redraw()
|
||||
|
||||
def set_blank(self):
|
||||
self.content=[]
|
||||
self.needsredraw=True
|
||||
self.content = []
|
||||
self.needsredraw = True
|
||||
|
||||
def tick(self):
|
||||
if len(self.attachment) > self.line_limit:
|
||||
|
|
@ -181,7 +181,7 @@ class TextOverlayWindow(OverlayWindow):
|
|||
self.warned_filetypes.append(message['type'])
|
||||
return ret
|
||||
|
||||
def recv_attach(self, identifier, pix):
|
||||
def recv_attach(self, identifier, pix, mask):
|
||||
"""
|
||||
Called when an image has been downloaded by image_getter
|
||||
"""
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@ class VoiceOverlayWindow(OverlayWindow):
|
|||
OverlayWindow.__init__(self, discover, piggyback)
|
||||
|
||||
self.avatars = {}
|
||||
self.avatar_masks = {}
|
||||
|
||||
self.dummy_data = []
|
||||
mostly_false = [False, False, False, False, False, False, False, True]
|
||||
|
|
@ -75,6 +76,7 @@ class VoiceOverlayWindow(OverlayWindow):
|
|||
self.order = None
|
||||
self.def_avatar = None
|
||||
self.channel_icon = None
|
||||
self.channel_mask = None
|
||||
self.overflow = None
|
||||
self.use_dummy = False
|
||||
self.dummy_count = 10
|
||||
|
|
@ -83,6 +85,7 @@ class VoiceOverlayWindow(OverlayWindow):
|
|||
self.show_disconnected = True
|
||||
self.channel_title = ""
|
||||
self.border_width = 2
|
||||
self.icon_transparency = 0.0
|
||||
|
||||
self.round_avatar = True
|
||||
self.icon_only = True
|
||||
|
|
@ -101,10 +104,24 @@ class VoiceOverlayWindow(OverlayWindow):
|
|||
self.force_location()
|
||||
get_surface(self.recv_avatar,
|
||||
"share/icons/hicolor/256x256/apps/discover-overlay-default.png",
|
||||
'def', self.avatar_size)
|
||||
'def', self.avatar_size, self.icon_transparency)
|
||||
self.set_title("Discover Voice")
|
||||
self.redraw()
|
||||
|
||||
def set_icon_transparency(self, trans):
|
||||
self.icon_transparency = trans
|
||||
get_surface(self.recv_avatar,
|
||||
"share/icons/hicolor/256x256/apps/discover-overlay-default.png",
|
||||
'def', self.avatar_size, self.icon_transparency)
|
||||
|
||||
self.avatars = {}
|
||||
self.avatar_masks = {}
|
||||
|
||||
self.channel_icon = None
|
||||
self.channel_mask = None
|
||||
|
||||
self.needsredraw = True
|
||||
|
||||
def set_blank(self):
|
||||
self.userlist = []
|
||||
self.needsredraw = True
|
||||
|
|
@ -317,12 +334,11 @@ class VoiceOverlayWindow(OverlayWindow):
|
|||
"""
|
||||
Change the icon for channel
|
||||
"""
|
||||
print("set_channel_icon : %s" % (url))
|
||||
if not url:
|
||||
self.channel_icon = None
|
||||
else:
|
||||
get_surface(self.recv_avatar, url, "channel",
|
||||
self.avatar_size)
|
||||
self.avatar_size, self.icon_transparency)
|
||||
|
||||
def set_user_list(self, userlist, alt):
|
||||
"""
|
||||
|
|
@ -550,17 +566,19 @@ class VoiceOverlayWindow(OverlayWindow):
|
|||
context.restore()
|
||||
self.context = None
|
||||
|
||||
def recv_avatar(self, identifier, pix):
|
||||
def recv_avatar(self, identifier, pix, mask):
|
||||
"""
|
||||
Called when image_getter has downloaded an image
|
||||
"""
|
||||
print(identifier)
|
||||
if identifier == 'def':
|
||||
self.def_avatar = pix
|
||||
self.def_avatar_mask = mask
|
||||
elif identifier == 'channel':
|
||||
self.channel_icon = pix
|
||||
self.channel_mask = mask
|
||||
else:
|
||||
self.avatars[identifier] = pix
|
||||
self.avatar_masks[identifier] = mask
|
||||
self.needsredraw = True
|
||||
|
||||
def delete_avatar(self, identifier):
|
||||
|
|
@ -587,7 +605,7 @@ class VoiceOverlayWindow(OverlayWindow):
|
|||
self.title_font
|
||||
)
|
||||
if self.channel_icon:
|
||||
self.draw_avatar_pix(context, self.channel_icon,
|
||||
self.draw_avatar_pix(context, self.channel_icon, self.channel_mask,
|
||||
pos_x, pos_y, None, avatar_size)
|
||||
return tw
|
||||
|
||||
|
|
@ -629,12 +647,13 @@ class VoiceOverlayWindow(OverlayWindow):
|
|||
url = "https://cdn.discordapp.com/avatars/%s/%s.png" % (
|
||||
user['id'], user['avatar'])
|
||||
get_surface(self.recv_avatar, url, user["id"],
|
||||
self.avatar_size)
|
||||
self.avatar_size, self.icon_transparency)
|
||||
|
||||
# Set the key with no value to avoid spamming requests
|
||||
self.avatars[user["id"]] = None
|
||||
self.avatar_masks[user["id"]] = None
|
||||
|
||||
colour = self.border_col
|
||||
colour = None
|
||||
mute = False
|
||||
deaf = False
|
||||
bg_col = None
|
||||
|
|
@ -655,8 +674,10 @@ class VoiceOverlayWindow(OverlayWindow):
|
|||
fg_col = self.text_col
|
||||
|
||||
pix = None
|
||||
mask = None
|
||||
if user["id"] in self.avatars:
|
||||
pix = self.avatars[user["id"]]
|
||||
mask = self.avatar_masks[user["id"]]
|
||||
if not self.horizontal:
|
||||
if not self.icon_only:
|
||||
tw = self.draw_text(
|
||||
|
|
@ -668,7 +689,8 @@ class VoiceOverlayWindow(OverlayWindow):
|
|||
avatar_size,
|
||||
self.text_font
|
||||
)
|
||||
self.draw_avatar_pix(context, pix, pos_x, pos_y, colour, avatar_size)
|
||||
self.draw_avatar_pix(context, pix, mask, pos_x,
|
||||
pos_y, colour, avatar_size)
|
||||
if deaf:
|
||||
self.draw_deaf(context, pos_x, pos_y, [
|
||||
0.0, 0.0, 0.0, 0.5], avatar_size)
|
||||
|
|
@ -748,16 +770,25 @@ class VoiceOverlayWindow(OverlayWindow):
|
|||
context.fill()
|
||||
context.restore()
|
||||
|
||||
def draw_avatar_pix(self, context, pixbuf, pos_x, pos_y, border_colour, avatar_size):
|
||||
def draw_avatar_pix(self, context, pixbuf, mask, pos_x, pos_y, border_colour, avatar_size):
|
||||
"""
|
||||
Draw avatar image at given position
|
||||
"""
|
||||
|
||||
# Empty the space for this
|
||||
self.blank_avatar(context, pos_x, pos_y, avatar_size)
|
||||
|
||||
# fallback default or fallback further to no image here
|
||||
if not pixbuf:
|
||||
pixbuf = self.def_avatar
|
||||
if not pixbuf:
|
||||
return
|
||||
context.set_operator(cairo.OPERATOR_OVER)
|
||||
if not mask:
|
||||
mask = self.def_avatar_mask
|
||||
if not mask:
|
||||
return
|
||||
|
||||
# Draw the "border" by doing a scaled-up copy in a flat colour
|
||||
if border_colour:
|
||||
border_size = avatar_size + (self.border_width * 2)
|
||||
border_x = pos_x - self.border_width
|
||||
|
|
@ -769,17 +800,30 @@ class VoiceOverlayWindow(OverlayWindow):
|
|||
(border_size / 2), border_size / 2, 0, 2 * math.pi)
|
||||
context.clip()
|
||||
self.col(border_colour)
|
||||
draw_img_to_mask(pixbuf, context, border_x, border_y,
|
||||
context.set_operator(cairo.OPERATOR_OVER)
|
||||
draw_img_to_mask(mask, context, border_x, border_y,
|
||||
border_size, border_size)
|
||||
context.restore()
|
||||
|
||||
# Cut the image back out
|
||||
context.save()
|
||||
if self.round_avatar:
|
||||
context.new_path()
|
||||
context.arc(pos_x + (avatar_size / 2), pos_y +
|
||||
(avatar_size / 2), avatar_size / 2, 0, 2 * math.pi)
|
||||
context.clip()
|
||||
self.col([0.0, 0.0, 0.0, 0.0])
|
||||
context.set_operator(cairo.OPERATOR_SOURCE)
|
||||
draw_img_to_mask(mask, context, pos_x, pos_y,
|
||||
avatar_size, avatar_size)
|
||||
context.restore()
|
||||
# Draw the image
|
||||
context.save()
|
||||
if self.round_avatar:
|
||||
context.new_path()
|
||||
context.arc(pos_x + (avatar_size / 2), pos_y +
|
||||
(avatar_size / 2), avatar_size / 2, 0, 2 * math.pi)
|
||||
context.clip()
|
||||
|
||||
context.set_operator(cairo.OPERATOR_OVER)
|
||||
draw_img_to_rect(pixbuf, context, pos_x, pos_y,
|
||||
avatar_size, avatar_size)
|
||||
context.restore()
|
||||
|
|
@ -797,6 +841,7 @@ class VoiceOverlayWindow(OverlayWindow):
|
|||
context.rectangle(0.0, 0.0, 1.0, 1.0)
|
||||
self.col(bg_col)
|
||||
context.fill()
|
||||
context.set_operator(cairo.OPERATOR_OVER)
|
||||
|
||||
self.set_mute_col()
|
||||
context.save()
|
||||
|
|
@ -846,6 +891,7 @@ class VoiceOverlayWindow(OverlayWindow):
|
|||
context.arc(0.3, 0.7, 0.035, .25 * math.pi, 1.25 * math.pi)
|
||||
context.close_path()
|
||||
context.fill()
|
||||
context.set_fill_rule(cairo.FILL_RULE_WINDING)
|
||||
|
||||
context.restore()
|
||||
|
||||
|
|
@ -862,6 +908,7 @@ class VoiceOverlayWindow(OverlayWindow):
|
|||
context.rectangle(0.0, 0.0, 1.0, 1.0)
|
||||
self.col(bg_col)
|
||||
context.fill()
|
||||
context.set_operator(cairo.OPERATOR_OVER)
|
||||
|
||||
self.set_mute_col()
|
||||
context.save()
|
||||
|
|
@ -904,6 +951,7 @@ class VoiceOverlayWindow(OverlayWindow):
|
|||
context.arc(0.3, 0.7, 0.035, .25 * math.pi, 1.25 * math.pi)
|
||||
context.close_path()
|
||||
context.fill()
|
||||
context.set_fill_rule(cairo.FILL_RULE_WINDING)
|
||||
|
||||
context.restore()
|
||||
|
||||
|
|
|
|||
|
|
@ -86,6 +86,7 @@ class VoiceSettingsWindow(SettingsWindow):
|
|||
self.show_title = None
|
||||
self.show_disconnected = None
|
||||
self.border_width = 2
|
||||
self.icon_transparency = 1.0
|
||||
|
||||
self.init_config()
|
||||
self.create_gui()
|
||||
|
|
@ -167,6 +168,8 @@ class VoiceSettingsWindow(SettingsWindow):
|
|||
self.show_disconnected = config.getboolean(
|
||||
"main", "show_disconnected", fallback=False)
|
||||
self.border_width = config.getint("main", "border_width", fallback=2)
|
||||
self.icon_transparency = config.getfloat(
|
||||
"main", "icon_transparency", fallback=1.0)
|
||||
|
||||
# Pass all of our config over to the overlay
|
||||
self.overlay.set_align_x(self.align_x)
|
||||
|
|
@ -200,6 +203,7 @@ class VoiceSettingsWindow(SettingsWindow):
|
|||
self.overlay.set_show_title(self.show_title)
|
||||
self.overlay.set_show_disconnected(self.show_disconnected)
|
||||
self.overlay.set_border_width(self.border_width)
|
||||
self.overlay.set_icon_transparency(self.icon_transparency)
|
||||
|
||||
self.overlay.set_floating(
|
||||
self.floating, self.floating_x, self.floating_y, self.floating_w, self.floating_h)
|
||||
|
|
@ -262,6 +266,8 @@ class VoiceSettingsWindow(SettingsWindow):
|
|||
config.set("main", "show_disconnected", "%d" %
|
||||
(int(self.show_disconnected)))
|
||||
config.set("main", "border_width", "%s" % (int(self.border_width)))
|
||||
config.set("main", "icon_transparency", "%.2f" %
|
||||
(self.icon_transparency))
|
||||
|
||||
with open(self.config_file, 'w') as file:
|
||||
config.write(file)
|
||||
|
|
@ -293,10 +299,10 @@ class VoiceSettingsWindow(SettingsWindow):
|
|||
outer_box.attach(dummy_box, 0, 2, 2, 1)
|
||||
|
||||
# Autohide
|
||||
#autohide_label = Gtk.Label.new("Hide on mouseover")
|
||||
#autohide = Gtk.CheckButton.new()
|
||||
# autohide_label = Gtk.Label.new("Hide on mouseover")
|
||||
# autohide = Gtk.CheckButton.new()
|
||||
# autohide.set_active(self.autohide)
|
||||
#autohide.connect("toggled", self.change_hide_on_mouseover)
|
||||
# autohide.connect("toggled", self.change_hide_on_mouseover)
|
||||
|
||||
# Font chooser
|
||||
font_label = Gtk.Label.new(_("Font"))
|
||||
|
|
@ -455,8 +461,8 @@ class VoiceSettingsWindow(SettingsWindow):
|
|||
avatar_size = Gtk.SpinButton.new(avatar_adjustment, 0, 0)
|
||||
avatar_size.connect("value-changed", self.change_avatar_size)
|
||||
|
||||
avatar_box.attach(avatar_size_label, 0, 0, 1, 1)
|
||||
avatar_box.attach(avatar_size, 1, 0, 1, 1)
|
||||
avatar_box.attach(avatar_size_label, 0, 1, 1, 1)
|
||||
avatar_box.attach(avatar_size, 1, 1, 1, 1)
|
||||
|
||||
# Avatar shape
|
||||
square_avatar_label = Gtk.Label.new(_("Square Avatar"))
|
||||
|
|
@ -465,8 +471,8 @@ class VoiceSettingsWindow(SettingsWindow):
|
|||
square_avatar.set_active(self.square_avatar)
|
||||
square_avatar.connect("toggled", self.change_square_avatar)
|
||||
|
||||
avatar_box.attach(square_avatar_label, 0, 2, 1, 1)
|
||||
avatar_box.attach(square_avatar, 1, 2, 1, 1)
|
||||
avatar_box.attach(square_avatar_label, 0, 3, 1, 1)
|
||||
avatar_box.attach(square_avatar, 1, 3, 1, 1)
|
||||
|
||||
# Display icon only
|
||||
icon_only_label = Gtk.Label.new(_("Display Icon Only"))
|
||||
|
|
@ -475,8 +481,8 @@ class VoiceSettingsWindow(SettingsWindow):
|
|||
icon_only.set_active(self.icon_only)
|
||||
icon_only.connect("toggled", self.change_icon_only)
|
||||
|
||||
avatar_box.attach(icon_only_label, 0, 1, 1, 1)
|
||||
avatar_box.attach(icon_only, 1, 1, 1, 1)
|
||||
avatar_box.attach(icon_only_label, 0, 2, 1, 1)
|
||||
avatar_box.attach(icon_only, 1, 2, 1, 1)
|
||||
|
||||
# Display Speaker only
|
||||
only_speaking_label = Gtk.Label.new(_("Display Speakers Only"))
|
||||
|
|
@ -485,8 +491,8 @@ class VoiceSettingsWindow(SettingsWindow):
|
|||
only_speaking.set_active(self.only_speaking)
|
||||
only_speaking.connect("toggled", self.change_only_speaking)
|
||||
|
||||
avatar_box.attach(only_speaking_label, 0, 3, 1, 1)
|
||||
avatar_box.attach(only_speaking, 1, 3, 1, 1)
|
||||
alignment_box.attach(only_speaking_label, 0, 8, 1, 1)
|
||||
alignment_box.attach(only_speaking, 1, 8, 1, 1)
|
||||
|
||||
# Highlight self
|
||||
highlight_self_label = Gtk.Label.new(_("Highlight Self"))
|
||||
|
|
@ -495,8 +501,8 @@ class VoiceSettingsWindow(SettingsWindow):
|
|||
highlight_self.set_active(self.highlight_self)
|
||||
highlight_self.connect("toggled", self.change_highlight_self)
|
||||
|
||||
avatar_box.attach(highlight_self_label, 0, 4, 1, 1)
|
||||
avatar_box.attach(highlight_self, 1, 4, 1, 1)
|
||||
avatar_box.attach(highlight_self_label, 0, 5, 1, 1)
|
||||
avatar_box.attach(highlight_self, 1, 5, 1, 1)
|
||||
|
||||
# Order avatars
|
||||
order_label = Gtk.Label.new(_("Order Avatars By"))
|
||||
|
|
@ -512,8 +518,8 @@ class VoiceSettingsWindow(SettingsWindow):
|
|||
order.pack_start(renderer_text, True)
|
||||
order.add_attribute(renderer_text, "text", 0)
|
||||
|
||||
avatar_box.attach(order_label, 0, 5, 1, 1)
|
||||
avatar_box.attach(order, 1, 5, 1, 1)
|
||||
avatar_box.attach(order_label, 0, 6, 1, 1)
|
||||
avatar_box.attach(order, 1, 6, 1, 1)
|
||||
|
||||
# Icon spacing
|
||||
icon_spacing_label = Gtk.Label.new(_("Icon Spacing"))
|
||||
|
|
@ -580,8 +586,20 @@ class VoiceSettingsWindow(SettingsWindow):
|
|||
border_width = Gtk.SpinButton.new(border_width_adjustment, 0, 0)
|
||||
border_width.connect("value-changed", self.change_border_width)
|
||||
|
||||
avatar_box.attach(border_width_label, 0, 6, 1, 1)
|
||||
avatar_box.attach(border_width, 1, 6, 1, 1)
|
||||
avatar_box.attach(border_width_label, 0, 7, 1, 1)
|
||||
avatar_box.attach(border_width, 1, 7, 1, 1)
|
||||
|
||||
# Icon Transparency
|
||||
icon_transparency_label = Gtk.Label.new(_("Icon Opacity"))
|
||||
icon_transparency_label.set_xalign(0)
|
||||
icon_transparency_adjustment = Gtk.Adjustment.new(
|
||||
self.icon_transparency, 0.5, 1.0, 0.01, 0.1, 0.0)
|
||||
icon_transparency = Gtk.HScale.new(icon_transparency_adjustment)
|
||||
icon_transparency.connect(
|
||||
"value-changed", self.change_icon_transparency)
|
||||
|
||||
avatar_box.attach(icon_transparency_label, 0, 0, 1, 1)
|
||||
avatar_box.attach(icon_transparency, 1, 0, 1, 1)
|
||||
|
||||
# Display icon horizontally
|
||||
horizontal_label = Gtk.Label.new(_("Display Horizontally"))
|
||||
|
|
@ -607,8 +625,8 @@ class VoiceSettingsWindow(SettingsWindow):
|
|||
overflow.pack_start(renderer_text, True)
|
||||
overflow.add_attribute(renderer_text, "text", 0)
|
||||
|
||||
avatar_box.attach(overflow_label, 0, 7, 1, 1)
|
||||
avatar_box.attach(overflow, 1, 7, 1, 1)
|
||||
avatar_box.attach(overflow_label, 0, 8, 1, 1)
|
||||
avatar_box.attach(overflow, 1, 8, 1, 1)
|
||||
|
||||
# Show Title
|
||||
show_title_label = Gtk.Label.new(_("Show Title"))
|
||||
|
|
@ -617,8 +635,8 @@ class VoiceSettingsWindow(SettingsWindow):
|
|||
show_title.set_active(self.show_title)
|
||||
show_title.connect("toggled", self.change_show_title)
|
||||
|
||||
avatar_box.attach(show_title_label, 0, 8, 1, 1)
|
||||
avatar_box.attach(show_title, 1, 8, 1, 1)
|
||||
avatar_box.attach(show_title_label, 0, 9, 1, 1)
|
||||
avatar_box.attach(show_title, 1, 9, 1, 1)
|
||||
|
||||
# Show Connection
|
||||
show_connection_label = Gtk.Label.new(_("Show Connection Status"))
|
||||
|
|
@ -627,8 +645,8 @@ class VoiceSettingsWindow(SettingsWindow):
|
|||
show_connection.set_active(self.show_connection)
|
||||
show_connection.connect("toggled", self.change_show_connection)
|
||||
|
||||
avatar_box.attach(show_connection_label, 0, 9, 1, 1)
|
||||
avatar_box.attach(show_connection, 1, 9, 1, 1)
|
||||
avatar_box.attach(show_connection_label, 0, 10, 1, 1)
|
||||
avatar_box.attach(show_connection, 1, 10, 1, 1)
|
||||
|
||||
# Show Disconnected
|
||||
show_disconnected_label = Gtk.Label.new(_("Show while disconnected"))
|
||||
|
|
@ -637,8 +655,8 @@ class VoiceSettingsWindow(SettingsWindow):
|
|||
show_disconnected.set_active(self.show_disconnected)
|
||||
show_disconnected.connect("toggled", self.change_show_disconnected)
|
||||
|
||||
avatar_box.attach(show_disconnected_label, 0, 10, 1, 1)
|
||||
avatar_box.attach(show_disconnected, 1, 10, 1, 1)
|
||||
avatar_box.attach(show_disconnected_label, 0, 11, 1, 1)
|
||||
avatar_box.attach(show_disconnected, 1, 11, 1, 1)
|
||||
|
||||
# use dummy
|
||||
dummy_label = Gtk.Label.new(_("Show test content"))
|
||||
|
|
@ -909,6 +927,11 @@ class VoiceSettingsWindow(SettingsWindow):
|
|||
self.border_width = button.get_value()
|
||||
self.save_config()
|
||||
|
||||
def change_icon_transparency(self, button):
|
||||
self.overlay.set_icon_transparency(button.get_value())
|
||||
self.icon_transparency = button.get_value()
|
||||
self.save_config()
|
||||
|
||||
def on_guild_selection_changed(self, tree, number, selection):
|
||||
model, treeiter = tree.get_selection().get_selected()
|
||||
if treeiter is not None:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue