144 lines
4.9 KiB
Python
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
|