- Changed all one or two character long variable names to be more clear what they are
- Limited line lengths - Fixed #95
This commit is contained in:
parent
3dd4fdb4ee
commit
719dc6c19e
11 changed files with 497 additions and 447 deletions
|
|
@ -21,16 +21,12 @@ from gi.repository import Gtk, Gdk
|
|||
class DraggableWindow(Gtk.Window):
|
||||
"""An X11 window which can be moved and resized"""
|
||||
|
||||
def __init__(self, x=0, y=0, w=300, h=300, message="Message", settings=None):
|
||||
def __init__(self, pos_x=0, pos_y=0, width=300, height=300, message="Message", settings=None):
|
||||
Gtk.Window.__init__(self, type=Gtk.WindowType.POPUP)
|
||||
if w < 100:
|
||||
w = 100
|
||||
if h < 100:
|
||||
h = 100
|
||||
self.x = x
|
||||
self.y = y
|
||||
self.w = w
|
||||
self.h = h
|
||||
self.pos_x = pos_x
|
||||
self.pos_y = pos_y
|
||||
self.width = max(100, width)
|
||||
self.height = max(100, height)
|
||||
self.settings = settings
|
||||
self.message = message
|
||||
self.set_size_request(50, 50)
|
||||
|
|
@ -60,48 +56,51 @@ class DraggableWindow(Gtk.Window):
|
|||
self.show_all()
|
||||
|
||||
def force_location(self):
|
||||
"""Move the window to previously given co-ords. Also double check sanity on layer & decorations"""
|
||||
"""
|
||||
Move the window to previously given co-ords.
|
||||
Also double check sanity on layer & decorations
|
||||
"""
|
||||
|
||||
self.set_decorated(False)
|
||||
self.set_keep_above(True)
|
||||
self.move(self.x, self.y)
|
||||
self.resize(self.w, self.h)
|
||||
self.move(self.pos_x, self.pos_y)
|
||||
self.resize(self.width, self.height)
|
||||
|
||||
def drag(self, _w, event):
|
||||
"""Called by GTK while mouse is moving over window. Used to resize and move"""
|
||||
if event.state & Gdk.ModifierType.BUTTON1_MASK:
|
||||
if self.drag_type == 1:
|
||||
# Center is move
|
||||
self.x = event.x_root - self.drag_x
|
||||
self.y = event.y_root - self.drag_y
|
||||
self.pos_x = event.x_root - self.drag_x
|
||||
self.pos_y = event.y_root - self.drag_y
|
||||
self.force_location()
|
||||
elif self.drag_type == 2:
|
||||
# Right edge
|
||||
self.w += event.x - self.drag_x
|
||||
self.width += event.x - self.drag_x
|
||||
self.drag_x = event.x
|
||||
self.force_location()
|
||||
elif self.drag_type == 3:
|
||||
# Bottom edge
|
||||
self.h += event.y - self.drag_y
|
||||
self.height += event.y - self.drag_y
|
||||
self.drag_y = event.y
|
||||
self.force_location()
|
||||
else:
|
||||
# Bottom Right
|
||||
self.w += event.x - self.drag_x
|
||||
self.h += event.y - self.drag_y
|
||||
self.width += event.x - self.drag_x
|
||||
self.height += event.y - self.drag_y
|
||||
self.drag_x = event.x
|
||||
self.drag_y = event.y
|
||||
self.force_location()
|
||||
|
||||
def button_press(self, w, event):
|
||||
def button_press(self, _widget, event):
|
||||
"""Called when a mouse button is pressed on this window"""
|
||||
(w, h) = self.get_size()
|
||||
(width, height) = self.get_size()
|
||||
if not self.drag_type:
|
||||
self.drag_type = 1
|
||||
# Where in the window did we press?
|
||||
if event.y > h - 32:
|
||||
if event.y > height - 32:
|
||||
self.drag_type += 2
|
||||
if event.x > w - 32:
|
||||
if event.x > width - 32:
|
||||
self.drag_type += 1
|
||||
self.drag_x = event.x
|
||||
self.drag_y = event.y
|
||||
|
|
@ -118,24 +117,26 @@ class DraggableWindow(Gtk.Window):
|
|||
context.paint()
|
||||
context.set_operator(cairo.OPERATOR_OVER)
|
||||
# Get size of window
|
||||
(sw, sh) = self.get_size()
|
||||
(window_width, window_height) = self.get_size()
|
||||
|
||||
# Draw text
|
||||
context.set_source_rgba(0.0, 0.0, 0.0, 1.0)
|
||||
_xb, _yb, w, h, _dx, _dy = context.text_extents(self.message)
|
||||
context.move_to(sw / 2 - w / 2, sh / 2 - h / 2)
|
||||
_xb, _yb, text_width, text_height, _dx, _dy = context.text_extents(
|
||||
self.message)
|
||||
context.move_to(window_width / 2 - text_width / 2,
|
||||
window_height / 2 - text_height / 2)
|
||||
context.show_text(self.message)
|
||||
|
||||
# Draw resizing edges
|
||||
context.set_source_rgba(0.0, 0.0, 1.0, 0.5)
|
||||
context.rectangle(sw - 32, 0, 32, sh)
|
||||
context.rectangle(window_width - 32, 0, 32, window_height)
|
||||
context.fill()
|
||||
|
||||
context.rectangle(0, sh - 32, sw, 32)
|
||||
context.rectangle(0, window_height - 32, window_width, 32)
|
||||
context.fill()
|
||||
|
||||
def get_coords(self):
|
||||
"""Return window position and size"""
|
||||
(x, y) = self.get_position()
|
||||
(w, h) = self.get_size()
|
||||
return (x, y, w, h)
|
||||
(pos_x, pos_y) = self.get_position()
|
||||
(width, height) = self.get_size()
|
||||
return (pos_x, pos_y, width, height)
|
||||
|
|
|
|||
|
|
@ -25,16 +25,12 @@ except ImportError:
|
|||
class DraggableWindowWayland(Gtk.Window):
|
||||
"""A Wayland full-screen window which can be moved and resized"""
|
||||
|
||||
def __init__(self, x=0, y=0, w=300, h=300, message="Message", settings=None):
|
||||
def __init__(self, pos_x=0, pos_y=0, width=300, height=300, message="Message", settings=None):
|
||||
Gtk.Window.__init__(self, type=Gtk.WindowType.TOPLEVEL)
|
||||
if w < 100:
|
||||
w = 100
|
||||
if h < 100:
|
||||
h = 100
|
||||
self.x = x
|
||||
self.y = y
|
||||
self.w = w
|
||||
self.h = h
|
||||
self.pos_x = pos_x
|
||||
self.pos_y = pos_y
|
||||
self.width = max(100, width)
|
||||
self.height = max(100, height)
|
||||
self.settings = settings
|
||||
self.message = message
|
||||
self.set_size_request(50, 50)
|
||||
|
|
@ -63,14 +59,10 @@ class DraggableWindowWayland(Gtk.Window):
|
|||
def force_location(self):
|
||||
"""Move the window to previously given co-ords. In wayland just clip to current screen"""
|
||||
(size_x, size_y) = self.get_size()
|
||||
if self.x < 0:
|
||||
self.x = 0
|
||||
if self.y < 0:
|
||||
self.y = 0
|
||||
if self.x + self.w > size_x:
|
||||
self.x = size_x - self.w
|
||||
if self.y + self.h > size_y:
|
||||
self.y = size_y - self.h
|
||||
self.pos_x = max(0, self.pos_x)
|
||||
self.pos_x = min(size_x - self.width, self.pos_x)
|
||||
self.pos_y = max(0, self.pos_y)
|
||||
self.pos_y = min(size_y - self.height, self.pos_y)
|
||||
self.queue_draw()
|
||||
|
||||
def drag(self, _w, event):
|
||||
|
|
@ -78,43 +70,43 @@ class DraggableWindowWayland(Gtk.Window):
|
|||
if event.state & Gdk.ModifierType.BUTTON1_MASK:
|
||||
if self.drag_type == 1:
|
||||
# Center is move
|
||||
self.x += event.x - self.drag_x
|
||||
self.y += event.y - self.drag_y
|
||||
self.pos_x += event.x - self.drag_x
|
||||
self.pos_y += event.y - self.drag_y
|
||||
self.drag_x = event.x
|
||||
self.drag_y = event.y
|
||||
|
||||
self.force_location()
|
||||
elif self.drag_type == 2:
|
||||
# Right edge
|
||||
self.w += event.x - self.drag_x
|
||||
self.width += event.x - self.drag_x
|
||||
self.drag_x = event.x
|
||||
self.force_location()
|
||||
elif self.drag_type == 3:
|
||||
# Bottom edge
|
||||
self.h += event.y - self.drag_y
|
||||
self.height += event.y - self.drag_y
|
||||
self.drag_y = event.y
|
||||
self.force_location()
|
||||
else:
|
||||
# Bottom Right
|
||||
self.w += event.x - self.drag_x
|
||||
self.h += event.y - self.drag_y
|
||||
self.width += event.x - self.drag_x
|
||||
self.height += event.y - self.drag_y
|
||||
self.drag_x = event.x
|
||||
self.drag_y = event.y
|
||||
self.force_location()
|
||||
|
||||
def button_press(self, _w, event):
|
||||
"""Called when a mouse button is pressed on this window"""
|
||||
px = event.x - self.x
|
||||
py = event.y - self.y
|
||||
press_x = event.x - self.pos_x
|
||||
press_y = event.y - self.pos_y
|
||||
|
||||
if not self.drag_type:
|
||||
self.drag_type = 1
|
||||
# Where in the window did we press?
|
||||
if px < 20 and py < 20:
|
||||
if press_x < 20 and press_y < 20:
|
||||
self.settings.change_placement(None)
|
||||
if py > self.h - 32:
|
||||
if press_y > self.height - 32:
|
||||
self.drag_type += 2
|
||||
if px > self.w - 32:
|
||||
if press_x > self.width - 32:
|
||||
self.drag_type += 1
|
||||
self.drag_x = event.x
|
||||
self.drag_y = event.y
|
||||
|
|
@ -124,10 +116,14 @@ class DraggableWindowWayland(Gtk.Window):
|
|||
self.drag_type = None
|
||||
|
||||
def dodraw(self, _widget, context):
|
||||
"""Draw our window. For wayland we're secretly a fullscreen app and need to draw only a single rectangle of the overlay"""
|
||||
context.translate(self.x, self.y)
|
||||
"""
|
||||
Draw our window. For wayland we're secretly a
|
||||
fullscreen app and need to draw only a single
|
||||
rectangle of the overlay
|
||||
"""
|
||||
context.translate(self.pos_x, self.pos_y)
|
||||
context.save()
|
||||
context.rectangle(0, 0, self.w, self.h)
|
||||
context.rectangle(0, 0, self.width, self.height)
|
||||
context.clip()
|
||||
|
||||
context.set_source_rgba(1.0, 1.0, 0.0, 0.7)
|
||||
|
|
@ -139,15 +135,16 @@ class DraggableWindowWayland(Gtk.Window):
|
|||
# Draw text
|
||||
context.set_source_rgba(0.0, 0.0, 0.0, 1.0)
|
||||
_xb, _yb, width, height, _dx, _dy = context.text_extents(self.message)
|
||||
context.move_to(self.w / 2 - width / 2, self.h / 2 - height / 2)
|
||||
context.move_to(self.width / 2 - width / 2,
|
||||
self.height / 2 - height / 2)
|
||||
context.show_text(self.message)
|
||||
|
||||
# Draw resizing edges
|
||||
context.set_source_rgba(0.0, 0.0, 1.0, 0.5)
|
||||
context.rectangle(self.w - 32, 0, 32, self.h)
|
||||
context.rectangle(self.width - 32, 0, 32, self.height)
|
||||
context.fill()
|
||||
|
||||
context.rectangle(0, self.h - 32, self.w, 32)
|
||||
context.rectangle(0, self.height - 32, self.width, 32)
|
||||
context.fill()
|
||||
|
||||
# Draw Done!
|
||||
|
|
@ -158,4 +155,4 @@ class DraggableWindowWayland(Gtk.Window):
|
|||
|
||||
def get_coords(self):
|
||||
"""Return the position and size of the window"""
|
||||
return (self.x, self.y, self.w, self.h)
|
||||
return (self.pos_x, self.pos_y, self.width, self.height)
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ import gi
|
|||
from .settings import SettingsWindow
|
||||
from .autostart import Autostart
|
||||
gi.require_version("Gtk", "3.0")
|
||||
# pylint: disable=wrong-import-position
|
||||
# pylint: disable=wrong-import-position,wrong-import-order
|
||||
from gi.repository import Gtk
|
||||
|
||||
|
||||
|
|
@ -28,19 +28,18 @@ class GeneralSettingsWindow(SettingsWindow):
|
|||
self.overlay = overlay
|
||||
self.overlay2 = overlay2
|
||||
self.xshape = None
|
||||
self.autostart = None
|
||||
self.set_size_request(400, 200)
|
||||
self.connect("destroy", self.close_window)
|
||||
self.connect("delete-event", self.close_window)
|
||||
self.init_config()
|
||||
self.a = Autostart("discover_overlay")
|
||||
self.autostart_helper = Autostart("discover_overlay")
|
||||
self.placement_window = None
|
||||
|
||||
self.create_gui()
|
||||
|
||||
def read_config(self):
|
||||
config = ConfigParser(interpolation=None)
|
||||
config.read(self.configFile)
|
||||
config.read(self.config_file)
|
||||
self.xshape = config.getboolean("general", "xshape", fallback=False)
|
||||
|
||||
# Pass all of our config over to the overlay
|
||||
|
|
@ -49,13 +48,13 @@ class GeneralSettingsWindow(SettingsWindow):
|
|||
|
||||
def save_config(self):
|
||||
config = ConfigParser(interpolation=None)
|
||||
config.read(self.configFile)
|
||||
config.read(self.config_file)
|
||||
if not config.has_section("general"):
|
||||
config.add_section("general")
|
||||
|
||||
config.set("general", "xshape", "%d" % (int(self.xshape)))
|
||||
|
||||
with open(self.configFile, 'w') as file:
|
||||
with open(self.config_file, 'w') as file:
|
||||
config.write(file)
|
||||
|
||||
def create_gui(self):
|
||||
|
|
@ -64,7 +63,7 @@ class GeneralSettingsWindow(SettingsWindow):
|
|||
# Auto start
|
||||
autostart_label = Gtk.Label.new("Autostart on boot")
|
||||
autostart = Gtk.CheckButton.new()
|
||||
autostart.set_active(self.a.is_auto())
|
||||
autostart.set_active(self.autostart_helper.is_auto())
|
||||
autostart.connect("toggled", self.change_autostart)
|
||||
|
||||
# Force XShape
|
||||
|
|
@ -81,8 +80,8 @@ class GeneralSettingsWindow(SettingsWindow):
|
|||
self.add(box)
|
||||
|
||||
def change_autostart(self, button):
|
||||
self.autostart = button.get_active()
|
||||
self.a.set_autostart(self.autostart)
|
||||
autostart = button.get_active()
|
||||
self.autostart_helper.set_autostart(autostart)
|
||||
|
||||
def change_xshape(self, button):
|
||||
self.overlay.set_force_xshape(button.get_active())
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ class ImageGetter():
|
|||
|
||||
def __init__(self, func, url, identifier, size):
|
||||
self.func = func
|
||||
self.id = identifier
|
||||
self.identifier = identifier
|
||||
self.url = url
|
||||
self.size = size
|
||||
|
||||
|
|
@ -46,7 +46,7 @@ class ImageGetter():
|
|||
pixbuf = pixbuf.scale_simple(self.size, self.size,
|
||||
GdkPixbuf.InterpType.BILINEAR)
|
||||
|
||||
self.func(self.id, pixbuf)
|
||||
self.func(self.identifier, pixbuf)
|
||||
except urllib.error.URLError as exception:
|
||||
logging.error(
|
||||
"Could not access : %s", self.url)
|
||||
|
|
@ -58,20 +58,24 @@ class SurfaceGetter():
|
|||
|
||||
def __init__(self, func, url, identifier, size):
|
||||
self.func = func
|
||||
self.id = identifier
|
||||
self.identifier = identifier
|
||||
self.url = url
|
||||
self.size = size
|
||||
|
||||
def get_url(self):
|
||||
"""Downloads and decodes"""
|
||||
try:
|
||||
resp = requests.get(self.url, stream=True, headers={
|
||||
'Referer': 'https://streamkit.discord.com/overlay/voice', 'User-Agent': 'Mozilla/5.0'})
|
||||
resp = requests.get(
|
||||
self.url, stream=True, headers={
|
||||
'Referer': 'https://streamkit.discord.com/overlay/voice',
|
||||
'User-Agent': 'Mozilla/5.0'
|
||||
}
|
||||
)
|
||||
raw = resp.raw
|
||||
im = Image.open(raw)
|
||||
surf = self.from_pil(im)
|
||||
image = Image.open(raw)
|
||||
surface = self.from_pil(image)
|
||||
|
||||
self.func(self.id, surf)
|
||||
self.func(self.identifier, surface)
|
||||
except requests.HTTPError:
|
||||
logging.error("Unable to open %s", self.url)
|
||||
except requests.TooManyRedirects:
|
||||
|
|
@ -85,84 +89,86 @@ class SurfaceGetter():
|
|||
except TypeError:
|
||||
logging.error("Unable to read %s", self.url)
|
||||
|
||||
def from_pil(self, im, alpha=1.0):
|
||||
def from_pil(self, image, alpha=1.0):
|
||||
"""
|
||||
:param im: Pillow Image
|
||||
:param alpha: 0..1 alpha to add to non-alpha images
|
||||
:param format: Pixel format for output surface
|
||||
"""
|
||||
if 'A' not in im.getbands():
|
||||
im.putalpha(int(alpha * 256.))
|
||||
arr = bytearray(im.tobytes('raw', 'BGRa'))
|
||||
if 'A' not in image.getbands():
|
||||
image.putalpha(int(alpha * 256.))
|
||||
arr = bytearray(image.tobytes('raw', 'BGRa'))
|
||||
surface = cairo.ImageSurface.create_for_data(
|
||||
arr, cairo.FORMAT_ARGB32, im.width, im.height)
|
||||
arr, cairo.FORMAT_ARGB32, image.width, image.height)
|
||||
return surface
|
||||
|
||||
|
||||
def get_image(func, identifier, ava, size):
|
||||
"""Download to GDK Pixmap"""
|
||||
image_getter = ImageGetter(func, identifier, ava, size)
|
||||
t = threading.Thread(target=image_getter.get_url, args=())
|
||||
t.start()
|
||||
thread = threading.Thread(target=image_getter.get_url, args=())
|
||||
thread.start()
|
||||
|
||||
|
||||
def get_surface(func, identifier, ava, size):
|
||||
"""Download to cairo surface"""
|
||||
image_getter = SurfaceGetter(func, identifier, ava, size)
|
||||
t = threading.Thread(target=image_getter.get_url, args=())
|
||||
t.start()
|
||||
thread = threading.Thread(target=image_getter.get_url, args=())
|
||||
thread.start()
|
||||
|
||||
|
||||
def get_aspected_size(img, w, h, anchor=0, hanchor=0):
|
||||
def get_aspected_size(img, width, height, anchor=0, hanchor=0):
|
||||
"""Get dimensions of image keeping current aspect ratio"""
|
||||
px = img.get_width()
|
||||
py = img.get_height()
|
||||
if py < 1 or h < 1:
|
||||
pic_width = img.get_width()
|
||||
pic_height = img.get_height()
|
||||
if pic_height < 1 or height < 1:
|
||||
return (0, 0, 0, 0)
|
||||
img_aspect = px / py
|
||||
rect_aspect = w / h
|
||||
img_aspect = pic_width / pic_height
|
||||
rect_aspect = width / height
|
||||
|
||||
y = 0
|
||||
x = 0
|
||||
offset_y = 0
|
||||
offset_x = 0
|
||||
if img_aspect > rect_aspect:
|
||||
oh = h
|
||||
h = w / img_aspect
|
||||
old_height = height
|
||||
height = width / img_aspect
|
||||
if anchor == 0:
|
||||
y = y + (oh - h)
|
||||
offset_y = offset_y + (old_height - height)
|
||||
if anchor == 1:
|
||||
y = y + ((oh - h) / 2)
|
||||
offset_y = offset_y + ((old_height - height) / 2)
|
||||
elif img_aspect < rect_aspect:
|
||||
ow = w
|
||||
w = h * img_aspect
|
||||
old_width = width
|
||||
width = height * img_aspect
|
||||
if hanchor == 2:
|
||||
x = x + (ow - w)
|
||||
offset_x = offset_x + (old_width - width)
|
||||
if hanchor == 1:
|
||||
x = x + ((ow - w) / 2)
|
||||
return (x, y, w, h)
|
||||
offset_x = offset_x + ((old_width - width) / 2)
|
||||
return (offset_x, offset_y, width, height)
|
||||
|
||||
|
||||
def draw_img_to_rect(img, ctx, x, y, w, h, path=False, aspect=False, anchor=0, hanchor=0):
|
||||
def draw_img_to_rect(img, ctx,
|
||||
pos_x, pos_y,
|
||||
width, height,
|
||||
path=False, aspect=False,
|
||||
anchor=0, hanchor=0):
|
||||
"""Draw cairo surface onto context"""
|
||||
# Path - only add the path do not fill : True/False
|
||||
# Aspect - keep aspect ratio : True/False
|
||||
# Anchor - with aspect : 0=left 1=middle 2=right
|
||||
# HAnchor - with apect : 0=bottom 1=middle 2=top
|
||||
ctx.save()
|
||||
px = img.get_width()
|
||||
py = img.get_height()
|
||||
x_off = 0
|
||||
y_off = 0
|
||||
offset_x = 0
|
||||
offset_y = 0
|
||||
if aspect:
|
||||
(x_off, y_off, w, h) = get_aspected_size(
|
||||
img, w, h, anchor=anchor, hanchor=hanchor)
|
||||
(offset_x, offset_y, width, height) = get_aspected_size(
|
||||
img, width, height, anchor=anchor, hanchor=hanchor)
|
||||
|
||||
ctx.translate(x + x_off, y + y_off)
|
||||
ctx.scale(w, h)
|
||||
ctx.scale(1 / px, 1 / py)
|
||||
ctx.translate(pos_x + offset_x, pos_y + offset_y)
|
||||
ctx.scale(width, height)
|
||||
ctx.scale(1 / img.get_width(), 1 / img.get_height())
|
||||
ctx.set_source_surface(img, 0, 0)
|
||||
|
||||
ctx.rectangle(0, 0, px, py)
|
||||
ctx.rectangle(0, 0, img.get_width(), img.get_height())
|
||||
if not path:
|
||||
ctx.fill()
|
||||
ctx.restore()
|
||||
return (w, h)
|
||||
return (width, height)
|
||||
|
|
|
|||
|
|
@ -10,13 +10,16 @@
|
|||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
"""Overlay parent class. Helpful if we need more overlay types without copy-and-pasting too much code"""
|
||||
"""
|
||||
Overlay parent class. Helpful if we need more overlay
|
||||
types without copy-and-pasting too much code
|
||||
"""
|
||||
import sys
|
||||
import logging
|
||||
import gi
|
||||
import cairo
|
||||
gi.require_version("Gtk", "3.0")
|
||||
# pylint: disable=wrong-import-position
|
||||
# pylint: disable=wrong-import-position,wrong-import-order
|
||||
from gi.repository import Gtk, Gdk
|
||||
try:
|
||||
from gi.repository import GtkLayerShell
|
||||
|
|
@ -25,7 +28,10 @@ except ImportError:
|
|||
|
||||
|
||||
class OverlayWindow(Gtk.Window):
|
||||
"""Overlay parent class. Helpful if we need more overlay types without copy-and-pasting too much code"""
|
||||
"""
|
||||
Overlay parent class. Helpful if we need more overlay
|
||||
types without copy-and-pasting too much code
|
||||
"""
|
||||
|
||||
def detect_type(self):
|
||||
window = Gtk.Window()
|
||||
|
|
@ -43,10 +49,10 @@ class OverlayWindow(Gtk.Window):
|
|||
self.compositing = False
|
||||
self.text_font = None
|
||||
self.text_size = None
|
||||
self.x = None
|
||||
self.y = None
|
||||
self.w = None
|
||||
self.h = None
|
||||
self.pos_x = None
|
||||
self.pos_y = None
|
||||
self.width = None
|
||||
self.height = None
|
||||
|
||||
self.set_size_request(50, 50)
|
||||
self.connect('draw', self.overlay_draw)
|
||||
|
|
@ -97,24 +103,23 @@ class OverlayWindow(Gtk.Window):
|
|||
self.text_size = size
|
||||
self.redraw()
|
||||
|
||||
def set_floating(self, floating, x, y, w, h):
|
||||
def set_floating(self, floating, pos_x, pos_y, width, height):
|
||||
self.floating = floating
|
||||
self.x = x
|
||||
self.y = y
|
||||
self.w = w
|
||||
self.h = h
|
||||
self.pos_x = pos_x
|
||||
self.pos_y = pos_y
|
||||
self.width = width
|
||||
self.height = height
|
||||
self.force_location()
|
||||
|
||||
def set_untouchable(self):
|
||||
(w, h) = self.get_size()
|
||||
surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, w, h)
|
||||
(width, height) = self.get_size()
|
||||
surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, width, height)
|
||||
surface_ctx = cairo.Context(surface)
|
||||
surface_ctx.set_source_rgba(0.0, 0.0, 0.0, 0.0)
|
||||
surface_ctx.set_operator(cairo.OPERATOR_SOURCE)
|
||||
surface_ctx.paint()
|
||||
reg = Gdk.cairo_region_create_from_surface(surface)
|
||||
self.input_shape_combine_region(reg)
|
||||
# self.shape_combine_region(reg)
|
||||
|
||||
def unset_shape(self):
|
||||
self.get_window().shape_combine_region(None, 0, 0)
|
||||
|
|
@ -129,43 +134,38 @@ class OverlayWindow(Gtk.Window):
|
|||
geometry = monitor.get_geometry()
|
||||
scale_factor = monitor.get_scale_factor()
|
||||
if not self.floating:
|
||||
w = scale_factor * geometry.width
|
||||
h = scale_factor * geometry.height
|
||||
x = geometry.x
|
||||
y = geometry.y
|
||||
self.resize(w, h)
|
||||
self.move(x, y)
|
||||
width = scale_factor * geometry.width
|
||||
height = scale_factor * geometry.height
|
||||
pos_x = geometry.x
|
||||
pos_y = geometry.y
|
||||
self.resize(width, height)
|
||||
self.move(pos_x, pos_y)
|
||||
else:
|
||||
self.move(self.x, self.y)
|
||||
self.resize(self.w, self.h)
|
||||
self.move(self.pos_x, self.pos_y)
|
||||
self.resize(self.width, self.height)
|
||||
else:
|
||||
if not self.floating:
|
||||
screen = display.get_default_screen()
|
||||
w = screen.width()
|
||||
h = screen.height()
|
||||
x = 0
|
||||
y = 0
|
||||
else:
|
||||
self.move(self.x, self.y)
|
||||
self.resize(self.w, self.h)
|
||||
if self.floating:
|
||||
self.move(self.pos_x, self.pos_y)
|
||||
self.resize(self.width, self.height)
|
||||
|
||||
if not self.floating:
|
||||
(w, h) = self.get_size()
|
||||
self.w = w
|
||||
self.h = h
|
||||
(width, height) = self.get_size()
|
||||
self.width = width
|
||||
self.height = height
|
||||
self.redraw()
|
||||
|
||||
def redraw(self):
|
||||
gdkwin = self.get_window()
|
||||
if not self.floating:
|
||||
(w, h) = self.get_size()
|
||||
self.w = w
|
||||
self.h = h
|
||||
(width, height) = self.get_size()
|
||||
self.width = width
|
||||
self.height = height
|
||||
|
||||
if gdkwin:
|
||||
if not self.compositing or self.force_xshape:
|
||||
(w, h) = self.get_size()
|
||||
surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, w, h)
|
||||
(width, height) = self.get_size()
|
||||
surface = cairo.ImageSurface(
|
||||
cairo.FORMAT_ARGB32, width, height)
|
||||
surface_ctx = cairo.Context(surface)
|
||||
self.overlay_draw(None, surface_ctx)
|
||||
reg = Gdk.cairo_region_create_from_surface(surface)
|
||||
|
|
@ -182,18 +182,18 @@ class OverlayWindow(Gtk.Window):
|
|||
self.force_location()
|
||||
self.redraw()
|
||||
|
||||
def set_align_x(self, b):
|
||||
self.align_right = b
|
||||
def set_align_x(self, align_right):
|
||||
self.align_right = align_right
|
||||
self.force_location()
|
||||
self.redraw()
|
||||
|
||||
def set_align_y(self, i):
|
||||
self.align_vert = i
|
||||
def set_align_y(self, align_vert):
|
||||
self.align_vert = align_vert
|
||||
self.force_location()
|
||||
self.redraw()
|
||||
|
||||
def col(self, c, a=1.0):
|
||||
self.context.set_source_rgba(c[0], c[1], c[2], c[3] * a)
|
||||
def col(self, col, alpha=1.0):
|
||||
self.context.set_source_rgba(col[0], col[1], col[2], col[3] * alpha)
|
||||
|
||||
def set_force_xshape(self, force):
|
||||
self.force_xshape = force
|
||||
|
|
|
|||
|
|
@ -10,7 +10,10 @@
|
|||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
"""Settings tab parent class. Helpful if we need more overlay types without copy-and-pasting too much code"""
|
||||
"""
|
||||
Settings tab parent class. Helpful if we need more
|
||||
overlay types without copy-and-pasting too much code
|
||||
"""
|
||||
import os
|
||||
import logging
|
||||
import gi
|
||||
|
|
@ -26,13 +29,16 @@ except ModuleNotFoundError:
|
|||
|
||||
|
||||
class SettingsWindow(Gtk.VBox):
|
||||
"""Settings tab parent class. Helpful if we need more overlay types without copy-and-pasting too much code"""
|
||||
"""
|
||||
Settings tab parent class. Helpful if we need more
|
||||
overlay types without copy-and-pasting too much code
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
Gtk.VBox.__init__(self)
|
||||
self.placement_window = None
|
||||
self.configDir = None
|
||||
self.configFile = None
|
||||
self.config_dir = None
|
||||
self.config_file = None
|
||||
self.overlay = None
|
||||
self.floating_x = None
|
||||
self.floating_y = None
|
||||
|
|
@ -40,20 +46,20 @@ class SettingsWindow(Gtk.VBox):
|
|||
self.floating_h = None
|
||||
|
||||
def init_config(self):
|
||||
self.configDir = os.path.join(xdg_config_home, "discover_overlay")
|
||||
os.makedirs(self.configDir, exist_ok=True)
|
||||
self.configFile = os.path.join(self.configDir, "config.ini")
|
||||
self.config_dir = os.path.join(xdg_config_home, "discover_overlay")
|
||||
os.makedirs(self.config_dir, exist_ok=True)
|
||||
self.config_file = os.path.join(self.config_dir, "config.ini")
|
||||
self.read_config()
|
||||
|
||||
def close_window(self, _a=None, _b=None):
|
||||
if self.placement_window:
|
||||
(x, y) = self.placement_window.get_position()
|
||||
(w, h) = self.placement_window.get_size()
|
||||
self.floating_x = x
|
||||
self.floating_y = y
|
||||
self.floating_w = w
|
||||
self.floating_h = h
|
||||
self.overlay.set_floating(True, x, y, w, h)
|
||||
(pos_x, pos_y) = self.placement_window.get_position()
|
||||
(width, height) = self.placement_window.get_size()
|
||||
self.floating_x = pos_x
|
||||
self.floating_y = pos_y
|
||||
self.floating_w = width
|
||||
self.floating_h = height
|
||||
self.overlay.set_floating(True, pos_x, pos_y, width, height)
|
||||
self.save_config()
|
||||
self.placement_window.close()
|
||||
self.placement_window = None
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ from .voice_settings import VoiceSettingsWindow
|
|||
from .text_settings import TextSettingsWindow
|
||||
from .general_settings import GeneralSettingsWindow
|
||||
gi.require_version("Gtk", "3.0")
|
||||
# pylint: disable=wrong-import-position
|
||||
# pylint: disable=wrong-import-position,wrong-import-order
|
||||
from gi.repository import Gtk
|
||||
|
||||
|
||||
|
|
@ -36,26 +36,26 @@ class MainSettingsWindow(Gtk.Window):
|
|||
self.set_default_size(280, 180)
|
||||
|
||||
# Create
|
||||
nb = Gtk.Notebook()
|
||||
notebook = Gtk.Notebook()
|
||||
# nb.set_tab_pos(Gtk.POS_TOP)
|
||||
|
||||
self.voice_settings = VoiceSettingsWindow(self.voice_overlay)
|
||||
nb.append_page(self.voice_settings)
|
||||
nb.set_tab_label_text(self.voice_settings, "Voice")
|
||||
notebook.append_page(self.voice_settings)
|
||||
notebook.set_tab_label_text(self.voice_settings, "Voice")
|
||||
self.text_settings = TextSettingsWindow(self.text_overlay)
|
||||
nb.append_page(self.text_settings)
|
||||
nb.set_tab_label_text(self.text_settings, "Text")
|
||||
notebook.append_page(self.text_settings)
|
||||
notebook.set_tab_label_text(self.text_settings, "Text")
|
||||
self.core_settings = GeneralSettingsWindow(
|
||||
self.text_overlay, self.voice_overlay)
|
||||
nb.append_page(self.core_settings)
|
||||
nb.set_tab_label_text(self.core_settings, "Core")
|
||||
self.add(nb)
|
||||
self.nb = nb
|
||||
notebook.append_page(self.core_settings)
|
||||
notebook.set_tab_label_text(self.core_settings, "Core")
|
||||
self.add(notebook)
|
||||
self.notebook = notebook
|
||||
|
||||
def close_window(self, a=None, b=None):
|
||||
self.text_settings.close_window(a, b)
|
||||
self.voice_settings.close_window(a, b)
|
||||
self.core_settings.close_window(a, b)
|
||||
def close_window(self, widget=None, event=None):
|
||||
self.text_settings.close_window(widget, event)
|
||||
self.voice_settings.close_window(widget, event)
|
||||
self.core_settings.close_window(widget, event)
|
||||
self.hide()
|
||||
return True
|
||||
|
||||
|
|
@ -63,5 +63,5 @@ class MainSettingsWindow(Gtk.Window):
|
|||
self.voice_settings.present_settings()
|
||||
self.text_settings.present_settings()
|
||||
self.core_settings.present_settings()
|
||||
self.nb.show()
|
||||
self.notebook.show()
|
||||
self.show()
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ 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')
|
||||
# pylint: disable=wrong-import-position
|
||||
# pylint: disable=wrong-import-position,wrong-import-order
|
||||
from gi.repository import Pango, PangoCairo
|
||||
|
||||
|
||||
|
|
@ -47,20 +47,20 @@ class TextOverlayWindow(OverlayWindow):
|
|||
self.fg_col = [1.0, 1.0, 1.0, 1.0]
|
||||
self.attachment = {}
|
||||
|
||||
self.imgList = []
|
||||
self.imgFinder = re.compile(r"`")
|
||||
self.image_list = []
|
||||
self.img_finder = re.compile(r"`")
|
||||
self.set_title("Discover Text")
|
||||
|
||||
def set_text_time(self, t):
|
||||
self.text_time = t
|
||||
def set_text_time(self, timer):
|
||||
self.text_time = timer
|
||||
|
||||
def set_text_list(self, tlist, alt):
|
||||
def set_text_list(self, tlist, altered):
|
||||
self.content = tlist
|
||||
if alt:
|
||||
if altered:
|
||||
self.redraw()
|
||||
|
||||
def set_enabled(self, en):
|
||||
if en:
|
||||
def set_enabled(self, enabled):
|
||||
if enabled:
|
||||
self.show_all()
|
||||
else:
|
||||
self.hide()
|
||||
|
|
@ -73,12 +73,12 @@ class TextOverlayWindow(OverlayWindow):
|
|||
self.bg_col = bg_col
|
||||
self.redraw()
|
||||
|
||||
def set_show_attach(self, att):
|
||||
self.show_attach = att
|
||||
def set_show_attach(self, attachment):
|
||||
self.show_attach = attachment
|
||||
self.redraw()
|
||||
|
||||
def set_popup_style(self, b):
|
||||
self.popup_style = b
|
||||
def set_popup_style(self, boolean):
|
||||
self.popup_style = boolean
|
||||
|
||||
def set_font(self, name, size):
|
||||
self.text_font = name
|
||||
|
|
@ -88,48 +88,50 @@ class TextOverlayWindow(OverlayWindow):
|
|||
self.pango_rect.height = self.text_size * Pango.SCALE
|
||||
self.redraw()
|
||||
|
||||
def make_line(self, msg):
|
||||
def make_line(self, message):
|
||||
ret = ""
|
||||
if isinstance(msg, list):
|
||||
for a in msg:
|
||||
ret = "%s%s" % (ret, self.make_line(a))
|
||||
elif isinstance(msg, str):
|
||||
ret = msg
|
||||
elif msg['type'] == 'strong':
|
||||
ret = "<b>%s</b>" % (self.make_line(msg['content']))
|
||||
elif msg['type'] == 'text':
|
||||
ret = self.santize_string(msg['content'])
|
||||
elif msg['type'] == 'link':
|
||||
ret = "<u>%s</u>" % (self.make_line(msg['content']))
|
||||
elif msg['type'] == 'emoji':
|
||||
if 'surrogate' in msg:
|
||||
if isinstance(message, list):
|
||||
for inner_message in message:
|
||||
ret = "%s%s" % (ret, self.make_line(inner_message))
|
||||
elif isinstance(message, str):
|
||||
ret = message
|
||||
elif message['type'] == 'strong':
|
||||
ret = "<b>%s</b>" % (self.make_line(message['content']))
|
||||
elif message['type'] == 'text':
|
||||
ret = self.sanitize_string(message['content'])
|
||||
elif message['type'] == 'link':
|
||||
ret = "<u>%s</u>" % (self.make_line(message['content']))
|
||||
elif message['type'] == 'emoji':
|
||||
if 'surrogate' in message:
|
||||
# ['src'] is SVG URL
|
||||
#ret = msg
|
||||
ret = msg['surrogate']
|
||||
# ret = msg
|
||||
ret = message['surrogate']
|
||||
else:
|
||||
### Add Image ###
|
||||
url = ("https://cdn.discordapp.com/emojis/%s.png?v=1" %
|
||||
(msg['emojiId']))
|
||||
(message['emojiId']))
|
||||
img = {"url": url}
|
||||
self.imgList.append(img)
|
||||
self.image_list.append(img)
|
||||
ret = "`"
|
||||
elif msg['type'] == 'inlineCode' or msg['type'] == 'codeBlock' or msg['type'] == 'blockQuote':
|
||||
elif (message['type'] == 'inlineCode' or
|
||||
message['type'] == 'codeBlock' or
|
||||
message['type'] == 'blockQuote'):
|
||||
ret = "<span font_family=\"monospace\" background=\"#0004\">%s</span>" % (
|
||||
self.make_line(msg['content']))
|
||||
elif msg['type'] == 'u':
|
||||
ret = "<u>%s</u>" % (self.make_line(msg['content']))
|
||||
elif msg['type'] == 'em':
|
||||
ret = "<i>%s</i>" % (self.make_line(msg['content']))
|
||||
elif msg['type'] == 's':
|
||||
ret = "<s>%s</s>" % (self.make_line(msg['content']))
|
||||
elif msg['type'] == 'channel':
|
||||
ret = self.make_line(msg['content'])
|
||||
elif msg['type'] == 'mention':
|
||||
ret = self.make_line(msg['content'])
|
||||
elif msg['type'] == 'br':
|
||||
self.make_line(message['content']))
|
||||
elif message['type'] == 'u':
|
||||
ret = "<u>%s</u>" % (self.make_line(message['content']))
|
||||
elif message['type'] == 'em':
|
||||
ret = "<i>%s</i>" % (self.make_line(message['content']))
|
||||
elif message['type'] == 's':
|
||||
ret = "<s>%s</s>" % (self.make_line(message['content']))
|
||||
elif message['type'] == 'channel':
|
||||
ret = self.make_line(message['content'])
|
||||
elif message['type'] == 'mention':
|
||||
ret = self.make_line(message['content'])
|
||||
elif message['type'] == 'br':
|
||||
ret = '\n'
|
||||
else:
|
||||
logging.error("Unknown text type : %s", msg["type"])
|
||||
logging.error("Unknown text type : %s", message["type"])
|
||||
return ret
|
||||
|
||||
def recv_attach(self, identifier, pix):
|
||||
|
|
@ -139,7 +141,7 @@ class TextOverlayWindow(OverlayWindow):
|
|||
def overlay_draw(self, _w, context, data=None):
|
||||
self.context = context
|
||||
context.set_antialias(cairo.ANTIALIAS_GOOD)
|
||||
(w, h) = self.get_size()
|
||||
(width, height) = self.get_size()
|
||||
# Make background transparent
|
||||
context.set_source_rgba(0.0, 0.0, 0.0, 0.0)
|
||||
context.set_operator(cairo.OPERATOR_SOURCE)
|
||||
|
|
@ -150,19 +152,19 @@ class TextOverlayWindow(OverlayWindow):
|
|||
# The window is full-screen regardless of what the user has selected. Because Wayland
|
||||
# We need to set a clip and a transform to imitate original behaviour
|
||||
|
||||
w = self.w
|
||||
h = self.h
|
||||
context.translate(self.x, self.y)
|
||||
context.rectangle(0, 0, w, h)
|
||||
width = self.width
|
||||
height = self.height
|
||||
context.translate(self.pos_x, self.pos_y)
|
||||
context.rectangle(0, 0, width, height)
|
||||
context.clip()
|
||||
|
||||
cy = h
|
||||
current_y = height
|
||||
tnow = time.time()
|
||||
for line in reversed(self.content):
|
||||
if self.popup_style and tnow - line['time'] > self.text_time:
|
||||
break
|
||||
out_line = ""
|
||||
self.imgList = []
|
||||
self.image_list = []
|
||||
|
||||
col = "#fff"
|
||||
if 'nick_col' in line and line['nick_col']:
|
||||
|
|
@ -170,98 +172,106 @@ class TextOverlayWindow(OverlayWindow):
|
|||
for in_line in line['content']:
|
||||
out_line = "%s%s" % (out_line, self.make_line(in_line))
|
||||
if line['attach'] and self.show_attach:
|
||||
at = line['attach'][0]
|
||||
url = at['url']
|
||||
attachment = line['attach'][0]
|
||||
url = attachment['url']
|
||||
if url in self.attachment:
|
||||
cy = self.draw_attach(cy, url)
|
||||
current_y = self.draw_attach(current_y, url)
|
||||
else:
|
||||
get_surface(self.recv_attach,
|
||||
url,
|
||||
url, None)
|
||||
# cy = self.draw_text(cy, "%s" % (line['attach']))
|
||||
cy = self.draw_text(cy, "<span foreground='%s'>%s</span>: %s" % (self.santize_string(col),
|
||||
self.santize_string(line["nick"]), out_line))
|
||||
if cy <= 0:
|
||||
message = "<span foreground='%s'>%s</span>: %s" % (self.sanitize_string(col),
|
||||
self.sanitize_string(
|
||||
line["nick"]),
|
||||
out_line)
|
||||
current_y = self.draw_text(current_y, message)
|
||||
if current_y <= 0:
|
||||
# We've done enough
|
||||
break
|
||||
if self.is_wayland:
|
||||
context.restore()
|
||||
|
||||
def draw_attach(self, y, url):
|
||||
def draw_attach(self, pos_y, url):
|
||||
if url in self.attachment and self.attachment[url]:
|
||||
pix = self.attachment[url]
|
||||
iw = pix.get_width()
|
||||
ih = pix.get_height()
|
||||
iw = min(iw, self.w)
|
||||
ih = min(ih, (self.h * .7))
|
||||
(_ax, _ay, _aw, ah) = get_aspected_size(pix, iw, ih)
|
||||
image_width = min(pix.get_width(), self.width)
|
||||
image_height = min(pix.get_height(), (self.height * .7))
|
||||
(_ax, _ay, _aw, aspect_height) = get_aspected_size(
|
||||
pix, image_width, image_height)
|
||||
self.col(self.bg_col)
|
||||
self.context.rectangle(0, y - ah, self.w, ah)
|
||||
self.context.rectangle(0, pos_y - aspect_height,
|
||||
self.width, aspect_height)
|
||||
|
||||
self.context.fill()
|
||||
self.context.set_operator(cairo.OPERATOR_OVER)
|
||||
_new_w, new_h = draw_img_to_rect(
|
||||
pix, self.context, 0, y - ih, iw, ih, aspect=True)
|
||||
return y - new_h
|
||||
return y
|
||||
pix, self.context, 0, pos_y - image_height, image_width, image_height, aspect=True)
|
||||
return pos_y - new_h
|
||||
return pos_y
|
||||
|
||||
def draw_text(self, y, text):
|
||||
def draw_text(self, pos_y, text):
|
||||
|
||||
layout = self.create_pango_layout(text)
|
||||
layout.set_markup(text, -1)
|
||||
attr = layout.get_attributes()
|
||||
|
||||
layout.set_width(Pango.SCALE * self.w)
|
||||
layout.set_width(Pango.SCALE * self.width)
|
||||
layout.set_spacing(Pango.SCALE * 3)
|
||||
if(self.text_font):
|
||||
if self.text_font:
|
||||
font = Pango.FontDescription(
|
||||
"%s %s" % (self.text_font, self.text_size))
|
||||
layout.set_font_description(font)
|
||||
_tw, th = layout.get_pixel_size()
|
||||
_tw, text_height = layout.get_pixel_size()
|
||||
self.col(self.bg_col)
|
||||
self.context.rectangle(0, y - th, self.w, th)
|
||||
self.context.rectangle(0, pos_y - text_height, self.width, text_height)
|
||||
self.context.fill()
|
||||
self.context.set_operator(cairo.OPERATOR_OVER)
|
||||
self.col(self.fg_col)
|
||||
|
||||
self.context.move_to(0, y - th)
|
||||
self.context.move_to(0, pos_y - text_height)
|
||||
PangoCairo.context_set_shape_renderer(
|
||||
self.get_pango_context(), self.render_custom, None)
|
||||
|
||||
text = layout.get_text()
|
||||
count = 0
|
||||
|
||||
for loc in self.imgFinder.finditer(text):
|
||||
for loc in self.img_finder.finditer(text):
|
||||
idx = loc.start()
|
||||
|
||||
if len(self.imgList) <= count:
|
||||
if len(self.image_list) <= count:
|
||||
break # We fucked up. Who types ` anyway
|
||||
#url = self.imgList[count]
|
||||
# url = self.imgList[count]
|
||||
|
||||
at = Pango.attr_shape_new_with_data(
|
||||
attachment = Pango.attr_shape_new_with_data(
|
||||
self.pango_rect, self.pango_rect, count, None)
|
||||
at.start_index = idx
|
||||
at.end_index = idx + 1
|
||||
attr.insert(at)
|
||||
attachment.start_index = idx
|
||||
attachment.end_index = idx + 1
|
||||
attr.insert(attachment)
|
||||
count += 1
|
||||
layout.set_attributes(attr)
|
||||
|
||||
PangoCairo.show_layout(self.context, layout)
|
||||
return y - th
|
||||
return pos_y - text_height
|
||||
|
||||
def render_custom(self, ctx, shape, path, _data):
|
||||
key = self.imgList[shape.data]['url']
|
||||
key = self.image_list[shape.data]['url']
|
||||
if key not in self.attachment:
|
||||
get_surface(self.recv_attach,
|
||||
key,
|
||||
key, None)
|
||||
return
|
||||
pix = self.attachment[key]
|
||||
(x, y) = ctx.get_current_point()
|
||||
draw_img_to_rect(pix, ctx, x, y - self.text_size, self.text_size,
|
||||
(pos_x, pos_y) = ctx.get_current_point()
|
||||
draw_img_to_rect(pix, ctx, pos_x, pos_y - self.text_size, self.text_size,
|
||||
self.text_size, path=path)
|
||||
return True
|
||||
|
||||
def santize_string(self, string):
|
||||
def sanitize_string(self, string):
|
||||
# I hate that Pango has nothing for this.
|
||||
return string.replace("&", "&").replace("<", "<").replace(">", ">").replace("'", "'").replace("\"", """)
|
||||
string.replace("&", "&")
|
||||
string.replace("<", "<")
|
||||
string .replace(">", ">")
|
||||
string.replace("'", "'")
|
||||
string.replace("\"", """)
|
||||
return string
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ from .draggable_window_wayland import DraggableWindowWayland
|
|||
from .settings import SettingsWindow
|
||||
|
||||
gi.require_version("Gtk", "3.0")
|
||||
# pylint: disable=wrong-import-position
|
||||
# pylint: disable=wrong-import-position,wrong-import-order
|
||||
from gi.repository import Gtk, Gdk, Pango
|
||||
|
||||
|
||||
|
|
@ -80,26 +80,26 @@ class TextSettingsWindow(SettingsWindow):
|
|||
# if no guild is specified, populate channel list with every channel from each guild
|
||||
if self.guild == GUILD_DEFAULT_VALUE:
|
||||
c_model.append([guild_name, False])
|
||||
for c in self.list_channels_keys:
|
||||
chan = self.list_channels[c]
|
||||
for channel_key in self.list_channels_keys:
|
||||
chan = self.list_channels[channel_key]
|
||||
if chan['guild_id'] == guild_id:
|
||||
c_model.append([chan["name"], True])
|
||||
self.channel_lookup.append(c)
|
||||
self.channel_lookup.append(channel_key)
|
||||
|
||||
# if a guild is specified, poulate channel list with every channel from *just that guild*
|
||||
if self.guild != GUILD_DEFAULT_VALUE:
|
||||
for c in self.list_channels_keys:
|
||||
chan = self.list_channels[c]
|
||||
for channel_key in self.list_channels_keys:
|
||||
chan = self.list_channels[channel_key]
|
||||
if chan['guild_id'] == self.guild:
|
||||
c_model.append([chan["name"], True])
|
||||
self.channel_lookup.append(c)
|
||||
self.channel_lookup.append(channel_key)
|
||||
|
||||
self.channel_widget.set_model(c_model)
|
||||
self.channel_model = c_model
|
||||
|
||||
idx = 0
|
||||
for c in self.channel_lookup:
|
||||
if c == self.channel:
|
||||
for channel in self.channel_lookup:
|
||||
if channel == self.channel:
|
||||
self.ignore_channel_change = True
|
||||
self.channel_widget.set_active(idx)
|
||||
self.ignore_channel_change = False
|
||||
|
|
@ -180,7 +180,7 @@ class TextSettingsWindow(SettingsWindow):
|
|||
|
||||
def read_config(self):
|
||||
config = ConfigParser(interpolation=None)
|
||||
config.read(self.configFile)
|
||||
config.read(self.config_file)
|
||||
self.enabled = config.getboolean("text", "enabled", fallback=False)
|
||||
self.align_x = config.getboolean("text", "rightalign", fallback=True)
|
||||
self.align_y = config.getint("text", "topalign", fallback=2)
|
||||
|
|
@ -222,7 +222,7 @@ class TextSettingsWindow(SettingsWindow):
|
|||
|
||||
def save_config(self):
|
||||
config = ConfigParser(interpolation=None)
|
||||
config.read(self.configFile)
|
||||
config.read(self.config_file)
|
||||
if not config.has_section("text"):
|
||||
config.add_section("text")
|
||||
|
||||
|
|
@ -246,7 +246,7 @@ class TextSettingsWindow(SettingsWindow):
|
|||
if self.font:
|
||||
config.set("text", "font", self.font)
|
||||
|
||||
with open(self.configFile, 'w') as file:
|
||||
with open(self.config_file, 'w') as file:
|
||||
config.write(file)
|
||||
|
||||
def create_gui(self):
|
||||
|
|
@ -311,9 +311,9 @@ class TextSettingsWindow(SettingsWindow):
|
|||
monitor = Gtk.ComboBox.new_with_model(monitor_store)
|
||||
monitor.set_active(self.get_monitor_index(self.monitor))
|
||||
monitor.connect("changed", self.change_monitor)
|
||||
rt = Gtk.CellRendererText()
|
||||
monitor.pack_start(rt, True)
|
||||
monitor.add_attribute(rt, "text", 0)
|
||||
renderer_text = Gtk.CellRendererText()
|
||||
monitor.pack_start(renderer_text, True)
|
||||
monitor.add_attribute(renderer_text, "text", 0)
|
||||
|
||||
align_x_store = Gtk.ListStore(str)
|
||||
align_x_store.append(["Left"])
|
||||
|
|
@ -321,9 +321,9 @@ class TextSettingsWindow(SettingsWindow):
|
|||
align_x = Gtk.ComboBox.new_with_model(align_x_store)
|
||||
align_x.set_active(True if self.align_x else False)
|
||||
align_x.connect("changed", self.change_align_x)
|
||||
rt = Gtk.CellRendererText()
|
||||
align_x.pack_start(rt, True)
|
||||
align_x.add_attribute(rt, "text", 0)
|
||||
renderer_text = Gtk.CellRendererText()
|
||||
align_x.pack_start(renderer_text, True)
|
||||
align_x.add_attribute(renderer_text, "text", 0)
|
||||
|
||||
align_y_store = Gtk.ListStore(str)
|
||||
align_y_store.append(["Top"])
|
||||
|
|
@ -332,9 +332,9 @@ class TextSettingsWindow(SettingsWindow):
|
|||
align_y = Gtk.ComboBox.new_with_model(align_y_store)
|
||||
align_y.set_active(self.align_y)
|
||||
align_y.connect("changed", self.change_align_y)
|
||||
rt = Gtk.CellRendererText()
|
||||
align_y.pack_start(rt, True)
|
||||
align_y.add_attribute(rt, "text", 0)
|
||||
renderer_text = Gtk.CellRendererText()
|
||||
align_y.pack_start(renderer_text, True)
|
||||
align_y.add_attribute(renderer_text, "text", 0)
|
||||
|
||||
align_placement_button = Gtk.Button.new_with_label("Place Window")
|
||||
|
||||
|
|
@ -346,19 +346,19 @@ class TextSettingsWindow(SettingsWindow):
|
|||
channel = Gtk.ComboBox.new()
|
||||
|
||||
channel.connect("changed", self.change_channel)
|
||||
rt = Gtk.CellRendererText()
|
||||
channel.pack_start(rt, True)
|
||||
channel.add_attribute(rt, "text", 0)
|
||||
channel.add_attribute(rt, 'sensitive', 1)
|
||||
renderer_text = Gtk.CellRendererText()
|
||||
channel.pack_start(renderer_text, True)
|
||||
channel.add_attribute(renderer_text, "text", 0)
|
||||
channel.add_attribute(renderer_text, 'sensitive', 1)
|
||||
|
||||
guild_label = Gtk.Label.new("Server")
|
||||
guild = Gtk.ComboBox.new()
|
||||
|
||||
guild.connect("changed", self.change_guild)
|
||||
rt = Gtk.CellRendererText()
|
||||
guild.pack_start(rt, True)
|
||||
guild.add_attribute(rt, "text", 0)
|
||||
guild.add_attribute(rt, 'sensitive', 1)
|
||||
renderer_text = Gtk.CellRendererText()
|
||||
guild.pack_start(renderer_text, True)
|
||||
guild.add_attribute(renderer_text, "text", 0)
|
||||
guild.add_attribute(renderer_text, 'sensitive', 1)
|
||||
|
||||
# Show Attachments
|
||||
show_attach_label = Gtk.Label.new("Show Attachments")
|
||||
|
|
@ -406,10 +406,10 @@ class TextSettingsWindow(SettingsWindow):
|
|||
def change_font(self, button):
|
||||
font = button.get_font()
|
||||
desc = Pango.FontDescription.from_string(font)
|
||||
s = desc.get_size()
|
||||
size = desc.get_size()
|
||||
if not desc.get_size_is_absolute():
|
||||
s = s / Pango.SCALE
|
||||
self.overlay.set_font(desc.get_family(), s)
|
||||
size = size / Pango.SCALE
|
||||
self.overlay.set_font(desc.get_family(), size)
|
||||
|
||||
self.font = desc.to_string()
|
||||
self.save_config()
|
||||
|
|
@ -418,9 +418,9 @@ class TextSettingsWindow(SettingsWindow):
|
|||
if self.ignore_channel_change:
|
||||
return
|
||||
|
||||
c = self.channel_lookup[button.get_active()]
|
||||
self.connector.start_listening_text(c)
|
||||
self.channel = c
|
||||
channel = self.channel_lookup[button.get_active()]
|
||||
self.connector.start_listening_text(channel)
|
||||
self.channel = channel
|
||||
self.save_config()
|
||||
|
||||
def change_guild(self, button):
|
||||
|
|
@ -433,12 +433,12 @@ class TextSettingsWindow(SettingsWindow):
|
|||
|
||||
def change_placement(self, button):
|
||||
if self.placement_window:
|
||||
(x, y, w, h) = self.placement_window.get_coords()
|
||||
self.floating_x = x
|
||||
self.floating_y = y
|
||||
self.floating_w = w
|
||||
self.floating_h = h
|
||||
self.overlay.set_floating(True, x, y, w, h)
|
||||
(pos_x, pos_y, width, height) = self.placement_window.get_coords()
|
||||
self.floating_x = pos_x
|
||||
self.floating_y = pos_y
|
||||
self.floating_w = width
|
||||
self.floating_h = height
|
||||
self.overlay.set_floating(True, pos_x, pos_y, width, height)
|
||||
self.save_config()
|
||||
if not self.overlay.is_wayland:
|
||||
button.set_label("Place Window")
|
||||
|
|
@ -448,13 +448,13 @@ class TextSettingsWindow(SettingsWindow):
|
|||
else:
|
||||
if self.overlay.is_wayland:
|
||||
self.placement_window = DraggableWindowWayland(
|
||||
x=self.floating_x, y=self.floating_y,
|
||||
w=self.floating_w, h=self.floating_h,
|
||||
pos_x=self.floating_x, pos_y=self.floating_y,
|
||||
width=self.floating_w, height=self.floating_h,
|
||||
message="Place & resize this window then press Green!", settings=self)
|
||||
else:
|
||||
self.placement_window = DraggableWindow(
|
||||
x=self.floating_x, y=self.floating_y,
|
||||
w=self.floating_w, h=self.floating_h,
|
||||
pos_x=self.floating_x, pos_y=self.floating_y,
|
||||
width=self.floating_w, height=self.floating_h,
|
||||
message="Place & resize this window then press Save!", settings=self)
|
||||
if not self.overlay.is_wayland:
|
||||
button.set_label("Save this position")
|
||||
|
|
@ -535,19 +535,19 @@ class TextSettingsWindow(SettingsWindow):
|
|||
return self.channel
|
||||
|
||||
def change_bg(self, button):
|
||||
c = button.get_rgba()
|
||||
c = [c.red, c.green, c.blue, c.alpha]
|
||||
self.overlay.set_bg(c)
|
||||
colour = button.get_rgba()
|
||||
colour = [colour.red, colour.green, colour.blue, colour.alpha]
|
||||
self.overlay.set_bg(colour)
|
||||
|
||||
self.bg_col = c
|
||||
self.bg_col = colour
|
||||
self.save_config()
|
||||
|
||||
def change_fg(self, button):
|
||||
c = button.get_rgba()
|
||||
c = [c.red, c.green, c.blue, c.alpha]
|
||||
self.overlay.set_fg(c)
|
||||
colour = button.get_rgba()
|
||||
colour = [colour.red, colour.green, colour.blue, colour.alpha]
|
||||
self.overlay.set_fg(colour)
|
||||
|
||||
self.fg_col = c
|
||||
self.fg_col = colour
|
||||
self.save_config()
|
||||
|
||||
def change_show_attach(self, button):
|
||||
|
|
|
|||
|
|
@ -54,20 +54,20 @@ class VoiceOverlayWindow(OverlayWindow):
|
|||
'def', self.avatar_size)
|
||||
self.set_title("Discover Voice")
|
||||
|
||||
def set_bg(self, bg):
|
||||
self.norm_col = bg
|
||||
def set_bg(self, background_colour):
|
||||
self.norm_col = background_colour
|
||||
self.redraw()
|
||||
|
||||
def set_fg(self, fg):
|
||||
self.text_col = fg
|
||||
def set_fg(self, foreground_colour):
|
||||
self.text_col = foreground_colour
|
||||
self.redraw()
|
||||
|
||||
def set_tk(self, tk):
|
||||
self.talk_col = tk
|
||||
def set_tk(self, talking_colour):
|
||||
self.talk_col = talking_colour
|
||||
self.redraw()
|
||||
|
||||
def set_mt(self, mt):
|
||||
self.mute_col = mt
|
||||
def set_mt(self, mute_colour):
|
||||
self.mute_col = mute_colour
|
||||
self.redraw()
|
||||
|
||||
def set_avatar_size(self, size):
|
||||
|
|
@ -116,11 +116,11 @@ class VoiceOverlayWindow(OverlayWindow):
|
|||
def set_norm_col(self):
|
||||
self.col(self.norm_col)
|
||||
|
||||
def set_talk_col(self, a=1.0):
|
||||
self.col(self.talk_col, a)
|
||||
def set_talk_col(self, alpha=1.0):
|
||||
self.col(self.talk_col, alpha)
|
||||
|
||||
def set_mute_col(self, a=1.0):
|
||||
self.col(self.mute_col, a)
|
||||
def set_mute_col(self, alpha=1.0):
|
||||
self.col(self.mute_col, alpha)
|
||||
|
||||
def set_user_list(self, userlist, alt):
|
||||
self.userlist = userlist
|
||||
|
|
@ -137,10 +137,10 @@ class VoiceOverlayWindow(OverlayWindow):
|
|||
else: # Name sort
|
||||
self.userlist.sort(key=lambda x: x["friendlyname"])
|
||||
screen = self.get_screen()
|
||||
c = screen.is_composited()
|
||||
if not self.compositing == c:
|
||||
# Check if composite state has changed
|
||||
if not self.compositing == screen.is_composited():
|
||||
alt = True
|
||||
self.compositing = c
|
||||
self.compositing = screen.is_composited()
|
||||
if alt:
|
||||
self.redraw()
|
||||
|
||||
|
|
@ -154,7 +154,7 @@ class VoiceOverlayWindow(OverlayWindow):
|
|||
self.context = context
|
||||
context.set_antialias(cairo.ANTIALIAS_GOOD)
|
||||
# Get size of window
|
||||
(w, h) = self.get_size()
|
||||
(width, height) = self.get_size()
|
||||
# Make background transparent
|
||||
self.set_wind_col()
|
||||
# Don't layer drawing over each other, always replace
|
||||
|
|
@ -166,10 +166,10 @@ class VoiceOverlayWindow(OverlayWindow):
|
|||
# The window is full-screen regardless of what the user has selected. Because Wayland
|
||||
# We need to set a clip and a transform to imitate original behaviour
|
||||
|
||||
w = self.w
|
||||
h = self.h
|
||||
context.translate(self.x, self.y)
|
||||
context.rectangle(0, 0, w, h)
|
||||
width = self.width
|
||||
height = self.height
|
||||
context.translate(self.pos_x, self.pos_y)
|
||||
context.rectangle(0, 0, width, height)
|
||||
context.clip()
|
||||
|
||||
context.set_operator(cairo.OPERATOR_OVER)
|
||||
|
|
@ -206,25 +206,25 @@ class VoiceOverlayWindow(OverlayWindow):
|
|||
self.users_to_draw.insert(0, self_user)
|
||||
|
||||
# Calculate height needed to show overlay
|
||||
height = (len(self.users_to_draw) * self.avatar_size) + \
|
||||
needed_height = (len(self.users_to_draw) * self.avatar_size) + \
|
||||
(len(self.users_to_draw) + 1) * self.icon_spacing
|
||||
|
||||
# Choose where to start drawing
|
||||
rh = 0 + self.vert_edge_padding
|
||||
current_y = 0 + self.vert_edge_padding
|
||||
if self.align_vert == 1:
|
||||
# Ignore padding?
|
||||
rh = (h / 2) - (height / 2)
|
||||
current_y = (height / 2) - (needed_height / 2)
|
||||
elif self.align_vert == 2:
|
||||
rh = h - height - self.vert_edge_padding
|
||||
current_y = height - needed_height - self.vert_edge_padding
|
||||
|
||||
for user in self.users_to_draw:
|
||||
self.draw_avatar(context, user, rh)
|
||||
self.draw_avatar(context, user, current_y)
|
||||
# Shift the relative position down to next location
|
||||
rh += self.avatar_size + self.icon_spacing
|
||||
current_y += self.avatar_size + self.icon_spacing
|
||||
|
||||
# Don't hold a ref
|
||||
if self.is_wayland:
|
||||
context.restore()
|
||||
# Don't hold a ref
|
||||
self.context = None
|
||||
|
||||
def recv_avatar(self, identifier, pix):
|
||||
|
|
@ -238,7 +238,7 @@ class VoiceOverlayWindow(OverlayWindow):
|
|||
if id in self.avatars:
|
||||
del self.avatars[identifier]
|
||||
|
||||
def draw_avatar(self, context, user, y):
|
||||
def draw_avatar(self, context, user, pos_y):
|
||||
# Ensure pixbuf for avatar
|
||||
if user["id"] not in self.avatars and user["avatar"]:
|
||||
url = "https://cdn.discordapp.com/avatars/%s/%s.jpg" % (
|
||||
|
|
@ -249,7 +249,7 @@ class VoiceOverlayWindow(OverlayWindow):
|
|||
# Set the key with no value to avoid spamming requests
|
||||
self.avatars[user["id"]] = None
|
||||
|
||||
c = None
|
||||
colour = None
|
||||
mute = False
|
||||
deaf = False
|
||||
|
||||
|
|
@ -258,94 +258,125 @@ class VoiceOverlayWindow(OverlayWindow):
|
|||
if "deaf" in user and user["deaf"]:
|
||||
deaf = True
|
||||
if "speaking" in user and user["speaking"] and not deaf and not mute:
|
||||
c = self.talk_col
|
||||
colour = self.talk_col
|
||||
pix = None
|
||||
if user["id"] in self.avatars:
|
||||
pix = self.avatars[user["id"]]
|
||||
if self.align_right:
|
||||
if not self.icon_only:
|
||||
self.draw_text(
|
||||
context, user["friendlyname"], self.w - self.avatar_size - self.horz_edge_padding, y)
|
||||
context, user["friendlyname"],
|
||||
self.width - self.avatar_size - self.horz_edge_padding,
|
||||
pos_y
|
||||
)
|
||||
self.draw_avatar_pix(
|
||||
context, pix, self.w - self.avatar_size - self.horz_edge_padding, y, c)
|
||||
context, pix,
|
||||
self.width - self.avatar_size - self.horz_edge_padding,
|
||||
pos_y,
|
||||
colour
|
||||
)
|
||||
if deaf:
|
||||
self.draw_deaf(context, self.w - self.avatar_size -
|
||||
self.horz_edge_padding, y)
|
||||
self.draw_deaf(context, self.width - self.avatar_size -
|
||||
self.horz_edge_padding, pos_y)
|
||||
elif mute:
|
||||
self.draw_mute(context, self.w - self.avatar_size -
|
||||
self.horz_edge_padding, y)
|
||||
self.draw_mute(context, self.width - self.avatar_size -
|
||||
self.horz_edge_padding, pos_y)
|
||||
else:
|
||||
if not self.icon_only:
|
||||
self.draw_text(
|
||||
context, user["friendlyname"], self.avatar_size + self.horz_edge_padding, y)
|
||||
context,
|
||||
user["friendlyname"],
|
||||
self.avatar_size + self.horz_edge_padding,
|
||||
pos_y
|
||||
)
|
||||
self.draw_avatar_pix(
|
||||
context, pix, self.horz_edge_padding, y, c)
|
||||
context, pix, self.horz_edge_padding, pos_y, colour
|
||||
)
|
||||
if deaf:
|
||||
self.draw_deaf(context, self.horz_edge_padding, y)
|
||||
self.draw_deaf(context, self.horz_edge_padding, pos_y)
|
||||
elif mute:
|
||||
self.draw_mute(context, self.horz_edge_padding, y)
|
||||
self.draw_mute(context, self.horz_edge_padding, pos_y)
|
||||
|
||||
def draw_text(self, context, string, x, y):
|
||||
def draw_text(self, context, string, pos_x, pos_y):
|
||||
if self.text_font:
|
||||
context.set_font_face(cairo.ToyFontFace(
|
||||
self.text_font, cairo.FontSlant.NORMAL, cairo.FontWeight.NORMAL))
|
||||
context.set_font_size(self.text_size)
|
||||
_xb, _yb, w, h, _dx, _dy = context.text_extents(string)
|
||||
ho = (self.avatar_size / 2) - (h / 2)
|
||||
_xb, _yb, width, height, _dx, _dy = context.text_extents(string)
|
||||
height_offset = (self.avatar_size / 2) - (height / 2)
|
||||
if self.align_right:
|
||||
context.move_to(0, 0)
|
||||
self.set_norm_col()
|
||||
context.rectangle(x - w - (self.text_pad * 2), y + ho - self.text_pad,
|
||||
w + (self.text_pad * 4), h + (self.text_pad * 2))
|
||||
context.rectangle(
|
||||
pos_x - width - (self.text_pad * 2),
|
||||
pos_y + height_offset - self.text_pad,
|
||||
width + (self.text_pad * 4),
|
||||
height + (self.text_pad * 2)
|
||||
)
|
||||
context.fill()
|
||||
|
||||
self.set_text_col()
|
||||
context.move_to(x - w - self.text_pad, y + ho + h)
|
||||
context.move_to(
|
||||
pos_x - width - self.text_pad,
|
||||
pos_y + height_offset + height
|
||||
)
|
||||
context.show_text(string)
|
||||
else:
|
||||
context.move_to(0, 0)
|
||||
self.set_norm_col()
|
||||
context.rectangle(x - (self.text_pad * 2), y + ho - self.text_pad,
|
||||
w + (self.text_pad * 4), h + (self.text_pad * 2))
|
||||
context.rectangle(
|
||||
pos_x - (self.text_pad * 2),
|
||||
pos_y + height_offset - self.text_pad,
|
||||
width + (self.text_pad * 4),
|
||||
height + (self.text_pad * 2)
|
||||
)
|
||||
context.fill()
|
||||
|
||||
self.set_text_col()
|
||||
context.move_to(x + self.text_pad, y + ho + h)
|
||||
context.move_to(pos_x + self.text_pad,
|
||||
pos_y + height_offset + height)
|
||||
context.show_text(string)
|
||||
|
||||
def draw_avatar_pix(self, context, pixbuf, x, y, c):
|
||||
def draw_avatar_pix(self, context, pixbuf, pos_x, pos_y, border_colour):
|
||||
if not pixbuf:
|
||||
pixbuf = self.def_avatar
|
||||
if not pixbuf:
|
||||
return
|
||||
context.move_to(x, y)
|
||||
context.move_to(pos_x, pos_y)
|
||||
context.save()
|
||||
if self.round_avatar:
|
||||
context.arc(x + (self.avatar_size / 2), y +
|
||||
context.arc(pos_x + (self.avatar_size / 2), pos_y +
|
||||
(self.avatar_size / 2), self.avatar_size / 2, 0, 2 * math.pi)
|
||||
context.clip()
|
||||
|
||||
self.set_norm_col()
|
||||
context.set_operator(cairo.OPERATOR_SOURCE)
|
||||
context.rectangle(x, y, self.avatar_size, self.avatar_size)
|
||||
context.rectangle(pos_x, pos_y, self.avatar_size, self.avatar_size)
|
||||
context.fill()
|
||||
draw_img_to_rect(pixbuf, context, x, y,
|
||||
draw_img_to_rect(pixbuf, context, pos_x, pos_y,
|
||||
self.avatar_size, self.avatar_size)
|
||||
context.restore()
|
||||
if c:
|
||||
if border_colour:
|
||||
if self.round_avatar:
|
||||
context.arc(x + (self.avatar_size / 2), y +
|
||||
(self.avatar_size / 2), self.avatar_size / 2, 0, 2 * math.pi)
|
||||
self.col(c)
|
||||
context.arc(
|
||||
pos_x + (self.avatar_size / 2),
|
||||
pos_y + (self.avatar_size / 2),
|
||||
self.avatar_size / 2,
|
||||
0, 2 * math.pi
|
||||
)
|
||||
self.col(border_colour)
|
||||
context.stroke()
|
||||
else:
|
||||
context.rectangle(x, y, self.avatar_size, self.avatar_size)
|
||||
self.col(c)
|
||||
context.rectangle(
|
||||
pos_x, pos_y,
|
||||
self.avatar_size, self.avatar_size
|
||||
)
|
||||
self.col(border_colour)
|
||||
context.stroke()
|
||||
|
||||
def draw_mute(self, context, x, y):
|
||||
def draw_mute(self, context, pos_x, pos_y):
|
||||
context.save()
|
||||
context.translate(x, y)
|
||||
context.translate(pos_x, pos_y)
|
||||
context.scale(self.avatar_size, self.avatar_size)
|
||||
self.set_mute_col()
|
||||
context.save()
|
||||
|
|
@ -397,9 +428,9 @@ class VoiceOverlayWindow(OverlayWindow):
|
|||
|
||||
context.restore()
|
||||
|
||||
def draw_deaf(self, context, x, y):
|
||||
def draw_deaf(self, context, pos_x, pos_y):
|
||||
context.save()
|
||||
context.translate(x, y)
|
||||
context.translate(pos_x, pos_y)
|
||||
context.scale(self.avatar_size, self.avatar_size)
|
||||
self.set_mute_col()
|
||||
context.save()
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ from .draggable_window import DraggableWindow
|
|||
from .draggable_window_wayland import DraggableWindowWayland
|
||||
from .settings import SettingsWindow
|
||||
gi.require_version("Gtk", "3.0")
|
||||
# pylint: disable=wrong-import-position
|
||||
# pylint: disable=wrong-import-position,wrong-import-order
|
||||
from gi.repository import Gtk, Gdk, Pango
|
||||
|
||||
|
||||
|
|
@ -70,7 +70,7 @@ class VoiceSettingsWindow(SettingsWindow):
|
|||
|
||||
def read_config(self):
|
||||
config = ConfigParser(interpolation=None)
|
||||
config.read(self.configFile)
|
||||
config.read(self.config_file)
|
||||
self.align_x = config.getboolean("main", "rightalign", fallback=True)
|
||||
self.align_y = config.getint("main", "topalign", fallback=1)
|
||||
self.bg_col = json.loads(config.get(
|
||||
|
|
@ -130,14 +130,14 @@ class VoiceSettingsWindow(SettingsWindow):
|
|||
|
||||
if self.font:
|
||||
desc = Pango.FontDescription.from_string(self.font)
|
||||
s = desc.get_size()
|
||||
size = desc.get_size()
|
||||
if not desc.get_size_is_absolute():
|
||||
s = s / Pango.SCALE
|
||||
self.overlay.set_font(desc.get_family(), s)
|
||||
size = size / Pango.SCALE
|
||||
self.overlay.set_font(desc.get_family(), size)
|
||||
|
||||
def save_config(self):
|
||||
config = ConfigParser(interpolation=None)
|
||||
config.read(self.configFile)
|
||||
config.read(self.config_file)
|
||||
if not config.has_section("main"):
|
||||
config.add_section("main")
|
||||
|
||||
|
|
@ -168,7 +168,7 @@ class VoiceSettingsWindow(SettingsWindow):
|
|||
config.set("main", "floating_h", "%s" % (self.floating_h))
|
||||
config.set("main", "order", "%s" % (self.order))
|
||||
|
||||
with open(self.configFile, 'w') as file:
|
||||
with open(self.config_file, 'w') as file:
|
||||
config.write(file)
|
||||
|
||||
def create_gui(self):
|
||||
|
|
@ -231,9 +231,9 @@ class VoiceSettingsWindow(SettingsWindow):
|
|||
monitor = Gtk.ComboBox.new_with_model(monitor_store)
|
||||
monitor.set_active(self.get_monitor_index(self.monitor))
|
||||
monitor.connect("changed", self.change_monitor)
|
||||
rt = Gtk.CellRendererText()
|
||||
monitor.pack_start(rt, True)
|
||||
monitor.add_attribute(rt, "text", 0)
|
||||
renderer_text = Gtk.CellRendererText()
|
||||
monitor.pack_start(renderer_text, True)
|
||||
monitor.add_attribute(renderer_text, "text", 0)
|
||||
|
||||
align_x_store = Gtk.ListStore(str)
|
||||
align_x_store.append(["Left"])
|
||||
|
|
@ -241,9 +241,9 @@ class VoiceSettingsWindow(SettingsWindow):
|
|||
align_x = Gtk.ComboBox.new_with_model(align_x_store)
|
||||
align_x.set_active(True if self.align_x else False)
|
||||
align_x.connect("changed", self.change_align_x)
|
||||
rt = Gtk.CellRendererText()
|
||||
align_x.pack_start(rt, True)
|
||||
align_x.add_attribute(rt, "text", 0)
|
||||
renderer_text = Gtk.CellRendererText()
|
||||
align_x.pack_start(renderer_text, True)
|
||||
align_x.add_attribute(renderer_text, "text", 0)
|
||||
|
||||
align_y_store = Gtk.ListStore(str)
|
||||
align_y_store.append(["Top"])
|
||||
|
|
@ -252,9 +252,9 @@ class VoiceSettingsWindow(SettingsWindow):
|
|||
align_y = Gtk.ComboBox.new_with_model(align_y_store)
|
||||
align_y.set_active(self.align_y)
|
||||
align_y.connect("changed", self.change_align_y)
|
||||
rt = Gtk.CellRendererText()
|
||||
align_y.pack_start(rt, True)
|
||||
align_y.add_attribute(rt, "text", 0)
|
||||
renderer_text = Gtk.CellRendererText()
|
||||
align_y.pack_start(renderer_text, True)
|
||||
align_y.add_attribute(renderer_text, "text", 0)
|
||||
|
||||
align_placement_button = Gtk.Button.new_with_label("Place Window")
|
||||
|
||||
|
|
@ -329,9 +329,9 @@ class VoiceSettingsWindow(SettingsWindow):
|
|||
order = Gtk.ComboBox.new_with_model(order_store)
|
||||
order.set_active(self.order)
|
||||
order.connect("changed", self.change_order)
|
||||
rt = Gtk.CellRendererText()
|
||||
order.pack_start(rt, True)
|
||||
order.add_attribute(rt, "text", 0)
|
||||
renderer_text = Gtk.CellRendererText()
|
||||
order.pack_start(renderer_text, True)
|
||||
order.add_attribute(renderer_text, "text", 0)
|
||||
|
||||
box.attach(font_label, 0, 0, 1, 1)
|
||||
box.attach(font, 1, 0, 1, 1)
|
||||
|
|
@ -374,12 +374,12 @@ class VoiceSettingsWindow(SettingsWindow):
|
|||
|
||||
def change_placement(self, button):
|
||||
if self.placement_window:
|
||||
(x, y, w, h) = self.placement_window.get_coords()
|
||||
self.floating_x = x
|
||||
self.floating_y = y
|
||||
self.floating_w = w
|
||||
self.floating_h = h
|
||||
self.overlay.set_floating(True, x, y, w, h)
|
||||
(pos_x, pos_y, width, height) = self.placement_window.get_coords()
|
||||
self.floating_x = pos_x
|
||||
self.floating_y = pos_y
|
||||
self.floating_w = width
|
||||
self.floating_h = height
|
||||
self.overlay.set_floating(True, pos_x, pos_y, width, height)
|
||||
self.save_config()
|
||||
if not self.overlay.is_wayland:
|
||||
button.set_label("Place Window")
|
||||
|
|
@ -388,13 +388,13 @@ class VoiceSettingsWindow(SettingsWindow):
|
|||
else:
|
||||
if self.overlay.is_wayland:
|
||||
self.placement_window = DraggableWindowWayland(
|
||||
x=self.floating_x, y=self.floating_y,
|
||||
w=self.floating_w, h=self.floating_h,
|
||||
pos_x=self.floating_x, pos_y=self.floating_y,
|
||||
width=self.floating_w, height=self.floating_h,
|
||||
message="Place & resize this window then press Green!", settings=self)
|
||||
else:
|
||||
self.placement_window = DraggableWindow(
|
||||
x=self.floating_x, y=self.floating_y,
|
||||
w=self.floating_w, h=self.floating_h,
|
||||
pos_x=self.floating_x, pos_y=self.floating_y,
|
||||
width=self.floating_w, height=self.floating_h,
|
||||
message="Place & resize this window then press Save!", settings=self)
|
||||
if not self.overlay.is_wayland:
|
||||
button.set_label("Save this position")
|
||||
|
|
@ -428,44 +428,44 @@ class VoiceSettingsWindow(SettingsWindow):
|
|||
def change_font(self, button):
|
||||
font = button.get_font()
|
||||
desc = Pango.FontDescription.from_string(font)
|
||||
s = desc.get_size()
|
||||
size = desc.get_size()
|
||||
if not desc.get_size_is_absolute():
|
||||
s = s / Pango.SCALE
|
||||
self.overlay.set_font(desc.get_family(), s)
|
||||
size = size / Pango.SCALE
|
||||
self.overlay.set_font(desc.get_family(), size)
|
||||
|
||||
self.font = desc.to_string()
|
||||
self.save_config()
|
||||
|
||||
def change_bg(self, button):
|
||||
c = button.get_rgba()
|
||||
c = [c.red, c.green, c.blue, c.alpha]
|
||||
self.overlay.set_bg(c)
|
||||
colour = button.get_rgba()
|
||||
colour = [colour.red, colour.green, colour.blue, colour.alpha]
|
||||
self.overlay.set_bg(colour)
|
||||
|
||||
self.bg_col = c
|
||||
self.bg_col = colour
|
||||
self.save_config()
|
||||
|
||||
def change_fg(self, button):
|
||||
c = button.get_rgba()
|
||||
c = [c.red, c.green, c.blue, c.alpha]
|
||||
self.overlay.set_fg(c)
|
||||
colour = button.get_rgba()
|
||||
colour = [colour.red, colour.green, colour.blue, colour.alpha]
|
||||
self.overlay.set_fg(colour)
|
||||
|
||||
self.fg_col = c
|
||||
self.fg_col = colour
|
||||
self.save_config()
|
||||
|
||||
def change_tk(self, button):
|
||||
c = button.get_rgba()
|
||||
c = [c.red, c.green, c.blue, c.alpha]
|
||||
self.overlay.set_tk(c)
|
||||
colour = button.get_rgba()
|
||||
colour = [colour.red, colour.green, colour.blue, colour.alpha]
|
||||
self.overlay.set_tk(colour)
|
||||
|
||||
self.tk_col = c
|
||||
self.tk_col = colour
|
||||
self.save_config()
|
||||
|
||||
def change_mt(self, button):
|
||||
c = button.get_rgba()
|
||||
c = [c.red, c.green, c.blue, c.alpha]
|
||||
self.overlay.set_mt(c)
|
||||
colour = button.get_rgba()
|
||||
colour = [colour.red, colour.green, colour.blue, colour.alpha]
|
||||
self.overlay.set_mt(colour)
|
||||
|
||||
self.mt_col = c
|
||||
self.mt_col = colour
|
||||
self.save_config()
|
||||
|
||||
def change_avatar_size(self, button):
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue