Files
croccybot/src/modules/pending-rewrite/gui-cards/mixins.py

144 lines
4.9 KiB
Python

from PIL import Image, ImageDraw, ImageOps, ImageColor
from ..base import Card, Layout, fielded, Skin, FieldDesc
from ..base.Avatars import avatar_manager
from ..base.Skin import (
AssetField, RGBAAssetField, BlobField, AssetPathField, StringField, NumberField,
FontField, ColourField, PointField, ComputedField
)
@fielded
class MiniProfileSkin(Skin):
# Profile section
mini_profile_indent: NumberField = 125
mini_profile_size: ComputedField = lambda skin: (
skin.background.width - 2 * skin.mini_profile_indent,
int(skin._env['scale'] * 200)
)
mini_profile_avatar_mask: AssetField = FieldDesc(AssetField, 'mini-profile/avatar_mask.png', convert=None)
mini_profile_avatar_frame: AssetField = FieldDesc(AssetField, 'mini-profile/avatar_frame.png', convert=None)
mini_profile_avatar_sep: NumberField = 50
mini_profile_name_font: FontField = ('BoldItalic', 55)
mini_profile_name_colour: ColourField = '#DDB21D'
mini_profile_discrim_font: FontField = mini_profile_name_font
mini_profile_discrim_colour: ColourField = '#BABABA'
mini_profile_name_gap: NumberField = 20
mini_profile_badge_end: AssetField = "mini-profile/badge_end.png"
mini_profile_badge_font: FontField = ('Black', 30)
mini_profile_badge_colour: ColourField = '#FFFFFF'
mini_profile_badge_text_colour: ColourField = '#051822'
mini_profile_badge_gap: NumberField = 20
mini_profile_badge_min_sep: NumberField = 10
class MiniProfileLayout:
def _draw_profile(self) -> Image:
image = Image.new('RGBA', self.skin.mini_profile_size)
draw = ImageDraw.Draw(image)
xpos, ypos = 0, 0
frame = self.skin.mini_profile_avatar_frame
if frame.height >= image.height:
frame.thumbnail((image.height, image.height))
# Draw avatar
avatar = self.data_avatar
avatar.paste((0, 0, 0, 0), mask=self.skin.mini_profile_avatar_mask)
avatar_image = Image.new('RGBA', frame.size)
avatar_image.paste(
avatar,
(
(frame.width - avatar.width) // 2,
(frame.height - avatar.height) // 2
)
)
avatar_image.alpha_composite(frame)
avatar_image = avatar_image.resize(
(self.skin.mini_profile_size[1], self.skin.mini_profile_size[1])
)
image.alpha_composite(avatar_image, (0, 0))
xpos += avatar_image.width + self.skin.mini_profile_avatar_sep
# Draw name
name_text = self.data_name
name_length = self.skin.mini_profile_name_font.getlength(name_text + ' ')
name_height = self.skin.mini_profile_name_font.getsize(name_text)[1]
draw.text(
(xpos, ypos),
name_text,
fill=self.skin.mini_profile_name_colour,
font=self.skin.mini_profile_name_font
)
draw.text(
(xpos + name_length, ypos),
self.data_discrim,
fill=self.skin.mini_profile_discrim_colour,
font=self.skin.mini_profile_discrim_font
)
ypos += name_height + self.skin.mini_profile_name_gap
# Draw badges
_x = 0
max_x = self.skin.mini_profile_size[0] - xpos
badges = [self._draw_badge(text) for text in self.data_badges]
for badge in badges:
if badge.width + _x > max_x:
_x = 0
ypos += badge.height + self.skin.mini_profile_badge_gap
image.paste(
badge,
(xpos + _x, ypos)
)
_x += badge.width + self.skin.mini_profile_badge_min_sep
return image
def _draw_badge(self, text) -> Image:
"""
Draw a single profile badge, with the given text.
"""
text_length = self.skin.mini_profile_badge_font.getsize(text)[0]
height = self.skin.mini_profile_badge_end.height
width = text_length + self.skin.mini_profile_badge_end.width
badge = Image.new('RGBA', (width, height), color=(0, 0, 0, 0))
# Add blobs to ends
badge.paste(
self.skin.mini_profile_badge_end,
(0, 0)
)
badge.paste(
self.skin.mini_profile_badge_end,
(width - self.skin.mini_profile_badge_end.width, 0)
)
# Add rectangle to middle
draw = ImageDraw.Draw(badge)
draw.rectangle(
(
(self.skin.mini_profile_badge_end.width // 2, 0),
(width - self.skin.mini_profile_badge_end.width // 2, height),
),
fill='#FFFFFF',
width=0
)
badge.paste(ImageColor.getrgb(self.skin.mini_profile_badge_colour), mask=badge)
# Write badge text
draw.text(
(self.skin.mini_profile_badge_end.width // 2, height // 2),
text,
font=self.skin.mini_profile_badge_font,
fill=self.skin.mini_profile_badge_text_colour,
anchor='lm'
)
return badge