From e330e60f83e6e46bbc3d320711709f2448b802e7 Mon Sep 17 00:00:00 2001 From: Marvin W Date: Fri, 18 Oct 2019 16:52:29 +0200 Subject: Base avatars and names on conversation, not JID. Fixes #598 --- main/src/ui/avatar_generator.vala | 270 -------------------------------------- 1 file changed, 270 deletions(-) (limited to 'main/src/ui/avatar_generator.vala') diff --git a/main/src/ui/avatar_generator.vala b/main/src/ui/avatar_generator.vala index 2a6aa397..e69de29b 100644 --- a/main/src/ui/avatar_generator.vala +++ b/main/src/ui/avatar_generator.vala @@ -1,270 +0,0 @@ -using Cairo; -using Gee; -using Gdk; -using Gtk; - -using Dino.Entities; -using Xmpp; -using Xmpp.Util; - -namespace Dino.Ui { - -public class AvatarGenerator { - - private const string COLOR_GREY = "E0E0E0"; - private const string GROUPCHAT_ICON = "system-users-symbolic"; - - StreamInteractor? stream_interactor; - bool greyscale = false; - bool stateless = false; - int width; - int height; - int scale_factor; - - public AvatarGenerator(int width, int height, int scale_factor = 1) { - this.width = width; - this.height = height; - this.scale_factor = scale_factor; - } - - public async ImageSurface draw_jid(StreamInteractor stream_interactor, Jid jid_, Account account) { - Jid? jid = jid_; - this.stream_interactor = stream_interactor; - Jid? real_jid = stream_interactor.get_module(MucManager.IDENTITY).get_real_jid(jid, account); - if (real_jid != null && stream_interactor.get_module(AvatarManager.IDENTITY).has_avatar(account, real_jid)) { - jid = real_jid; - } - ImageSurface surface = crop_corners(yield draw_tile(jid, account, width * scale_factor, height * scale_factor), 3 * scale_factor); - surface.set_device_scale(scale_factor, scale_factor); - return surface; - } - - public async ImageSurface draw_message(StreamInteractor stream_interactor, Message message) { - if (message.real_jid != null && stream_interactor.get_module(AvatarManager.IDENTITY).has_avatar(message.account, message.real_jid)) { - return yield draw_jid(stream_interactor, message.real_jid, message.account); - } - return yield draw_jid(stream_interactor, message.from, message.account); - } - - public async ImageSurface draw_conversation(StreamInteractor stream_interactor, Conversation conversation) { - return yield draw_jid(stream_interactor, conversation.counterpart, conversation.account); - } - - public async ImageSurface draw_account(StreamInteractor stream_interactor, Account account) { - return yield draw_jid(stream_interactor, account.bare_jid, account); - } - - public ImageSurface draw_text(string text) { - ImageSurface surface = draw_colored_rectangle_text(COLOR_GREY, text, width, height); - return crop_corners(surface, 3 * scale_factor); - } - - public AvatarGenerator set_greyscale(bool greyscale) { - this.greyscale = greyscale; - return this; - } - - public AvatarGenerator set_stateless(bool stateless) { - this.stateless = stateless; - return this; - } - - private int get_left_border() { - return (int)Math.floor(scale_factor/2.0); - } - - private int get_right_border() { - return (int)Math.ceil(scale_factor/2.0); - } - - private async void add_tile_to_pixbuf(Pixbuf pixbuf, Jid jid, Account account, int width, int height, int x, int y) { - Pixbuf tile = pixbuf_get_from_surface(yield draw_chat_tile(jid, account, width, height), 0, 0, width, height); - tile.copy_area(0, 0, width, height, pixbuf, x, y); - } - - private async ImageSurface draw_tile(Jid jid, Account account, int width, int height) { - ImageSurface surface; - if (stream_interactor.get_module(MucManager.IDENTITY).is_groupchat(jid, account)) { - surface = yield draw_groupchat_tile(jid, account, width, height); - } else { - surface = yield draw_chat_tile(jid, account, width, height); - } - return surface; - } - - private async ImageSurface draw_chat_tile(Jid jid, Account account, int width, int height) { - Pixbuf? pixbuf = yield stream_interactor.get_module(AvatarManager.IDENTITY).get_avatar(account, jid); - if (pixbuf != null) { - double desired_ratio = (double) width / height; - double avatar_ratio = (double) pixbuf.width / pixbuf.height; - if (avatar_ratio > desired_ratio) { - int comp_width = width * pixbuf.height / height; - pixbuf = new Pixbuf.subpixbuf(pixbuf, pixbuf.width / 2 - comp_width / 2, 0, comp_width, pixbuf.height); - } else if (avatar_ratio < desired_ratio) { - int comp_height = height * pixbuf.width / width; - pixbuf = new Pixbuf.subpixbuf(pixbuf, 0, pixbuf.height / 2 - comp_height / 2, pixbuf.width, comp_height); - } - pixbuf = pixbuf.scale_simple(width, height, InterpType.BILINEAR); - Context ctx = new Context(new ImageSurface(Format.ARGB32, pixbuf.width, pixbuf.height)); - cairo_set_source_pixbuf(ctx, pixbuf, 0, 0); - ctx.paint(); - ImageSurface avatar_surface = (ImageSurface) ctx.get_target(); - if (greyscale) avatar_surface = convert_to_greyscale(avatar_surface); - return avatar_surface; - } else { - string display_name = Util.get_display_name(stream_interactor, jid, account); - string color = greyscale ? COLOR_GREY : Util.get_avatar_hex_color(stream_interactor, account, jid); - return draw_colored_rectangle_text(color, display_name.get_char(0).toupper().to_string(), width, height); - } - } - - private async ImageSurface draw_groupchat_tile(Jid jid, Account account, int width, int height) { - Gee.List? occupants = stream_interactor.get_module(MucManager.IDENTITY).get_other_occupants(jid, account); - if (stateless || occupants == null || occupants.size == 0) { - return yield draw_chat_tile(jid, account, width, height); - } - - for (int i = 0; i < occupants.size && i < 4; i++) { - Jid? real_jid = stream_interactor.get_module(MucManager.IDENTITY).get_real_jid(occupants[i], account); - if (real_jid != null && stream_interactor.get_module(AvatarManager.IDENTITY).has_avatar(account, real_jid)) { - occupants[i] = real_jid; - } - } - Pixbuf pixbuf = initialize_pixbuf(width, height); - if (occupants.size == 1 || occupants.size == 2 || occupants.size == 3) { - yield add_tile_to_pixbuf(pixbuf, occupants[0], account, width / 2 - get_right_border(), height, 0, 0); - if (occupants.size == 1) { - yield add_tile_to_pixbuf(pixbuf, account.bare_jid, account, width / 2 - get_left_border(), height, width / 2 + get_left_border(), 0); - } else if (occupants.size == 2) { - yield add_tile_to_pixbuf(pixbuf, occupants[1], account, width / 2 - get_left_border(), height, width / 2 + get_left_border(), 0); - } else if (occupants.size == 3) { - yield add_tile_to_pixbuf(pixbuf, occupants[1], account, width / 2 - get_left_border(), height / 2 - get_right_border(), width / 2 + get_left_border(), 0); - yield add_tile_to_pixbuf(pixbuf, occupants[2], account, width / 2 - get_left_border(), height / 2 - get_left_border(), width / 2 + get_left_border(), height / 2 + get_left_border()); - } - } else if (occupants.size >= 4) { - yield add_tile_to_pixbuf(pixbuf, occupants[0], account, width / 2 - get_right_border(), height / 2 - get_right_border(), 0, 0); - yield add_tile_to_pixbuf(pixbuf, occupants[1], account, width / 2 - get_left_border(), height / 2 - get_right_border(), width / 2 + get_left_border(), 0); - yield add_tile_to_pixbuf(pixbuf, occupants[2], account, width / 2 - get_right_border(), height / 2 - get_left_border(), 0, height / 2 + get_left_border()); - if (occupants.size == 4) { - yield add_tile_to_pixbuf(pixbuf, occupants[3], account, width / 2 - get_left_border(), height / 2 - get_left_border(), width / 2 + get_left_border(), height / 2 + get_left_border()); - } else if (occupants.size > 4) { - ImageSurface plus_surface = draw_colored_rectangle_text("555753", "+", width / 2 - get_left_border(), height / 2 - get_left_border()); - if (greyscale) plus_surface = convert_to_greyscale(plus_surface); - pixbuf_get_from_surface(plus_surface, 0, 0, plus_surface.get_width(), plus_surface.get_height()).copy_area(0, 0, width / 2 - get_left_border(), height / 2 - get_left_border(), pixbuf, width / 2 + get_left_border(), height / 2 + get_left_border()); - } - } - Context ctx = new Context(new ImageSurface(Format.ARGB32, pixbuf.width, pixbuf.height)); - cairo_set_source_pixbuf(ctx, pixbuf, 0, 0); - ctx.paint(); - return (ImageSurface) ctx.get_target(); - } - - public ImageSurface draw_colored_icon(string hex_color, string icon, int width, int height) { - int ICON_SIZE = width > 20 * scale_factor ? 17 * scale_factor : 14 * scale_factor; - - Context rectancle_context = new Context(new ImageSurface(Format.ARGB32, width, height)); - draw_colored_rectangle(rectancle_context, hex_color, width, height); - - try { - Pixbuf icon_pixbuf = IconTheme.get_default().load_icon(icon, ICON_SIZE, IconLookupFlags.FORCE_SIZE); - Surface icon_surface = cairo_surface_create_from_pixbuf(icon_pixbuf, 1, null); - Context context = new Context(icon_surface); - context.set_operator(Operator.IN); - context.set_source_rgba(1, 1, 1, 1); - context.rectangle(0, 0, width, height); - context.fill(); - - rectancle_context.set_source_surface(icon_surface, width / 2 - ICON_SIZE / 2, height / 2 - ICON_SIZE / 2); - rectancle_context.paint(); - } catch (Error e) { warning(@"Icon $icon does not exist"); } - - return (ImageSurface) rectancle_context.get_target(); - } - - public ImageSurface draw_colored_rectangle_text(string hex_color, string text, int width, int height) { - Context ctx = new Context(new ImageSurface(Format.ARGB32, width, height)); - draw_colored_rectangle(ctx, hex_color, width, height); - draw_center_text(ctx, text, width < 40 * scale_factor ? 17 * scale_factor : 25 * scale_factor, width, height); - return (ImageSurface) ctx.get_target(); - } - - private static void draw_center_text(Context ctx, string text, int fontsize, int width, int height) { - ctx.select_font_face("Sans", Cairo.FontSlant.NORMAL, Cairo.FontWeight.NORMAL); - ctx.set_font_size(fontsize); - Cairo.TextExtents extents; - ctx.text_extents(text, out extents); - double x_pos = width/2 - (extents.width/2 + extents.x_bearing); - double y_pos = height/2 - (extents.height/2 + extents.y_bearing); - ctx.move_to(x_pos, y_pos); - ctx.set_source_rgba(1, 1, 1, 1); - ctx.show_text(text); - } - - private static void draw_colored_rectangle(Context ctx, string hex_color, int width, int height) { - set_source_hex_color(ctx, hex_color); - ctx.rectangle(0, 0, width, height); - ctx.fill(); - } - - private static ImageSurface convert_to_greyscale(ImageSurface surface) { - Context context = new Context(surface); - // convert to greyscale - context.set_operator(Operator.HSL_COLOR); - context.set_source_rgb(1, 1, 1); - context.rectangle(0, 0, surface.get_width(), surface.get_height()); - context.fill(); - // make the visible part more light - context.set_operator(Operator.ATOP); - context.set_source_rgba(1, 1, 1, 0.7); - context.rectangle(0, 0, surface.get_width(), surface.get_height()); - context.fill(); - return (ImageSurface) context.get_target(); - } - - public static Pixbuf crop_corners_pixbuf(Pixbuf pixbuf, double radius = 3) { - Context ctx = new Context(new ImageSurface(Format.ARGB32, pixbuf.width, pixbuf.height)); - cairo_set_source_pixbuf(ctx, pixbuf, 0, 0); - double degrees = Math.PI / 180.0; - ctx.new_sub_path(); - ctx.arc(pixbuf.width - radius, radius, radius, -90 * degrees, 0 * degrees); - ctx.arc(pixbuf.width - radius, pixbuf.height - radius, radius, 0 * degrees, 90 * degrees); - ctx.arc(radius, pixbuf.height - radius, radius, 90 * degrees, 180 * degrees); - ctx.arc(radius, radius, radius, 180 * degrees, 270 * degrees); - ctx.close_path(); - ctx.clip(); - ctx.paint(); - return pixbuf_get_from_surface(ctx.get_target(), 0, 0, pixbuf.width, pixbuf.height); - } - - public static ImageSurface crop_corners(ImageSurface surface, double radius = 3) { - Context ctx = new Context(new ImageSurface(Format.ARGB32, surface.get_width(), surface.get_height())); - ctx.set_source_surface(surface, 0, 0); - double degrees = Math.PI / 180.0; - ctx.new_sub_path(); - ctx.arc(surface.get_width() - radius, radius, radius, -90 * degrees, 0 * degrees); - ctx.arc(surface.get_width() - radius, surface.get_height() - radius, radius, 0 * degrees, 90 * degrees); - ctx.arc(radius, surface.get_height() - radius, radius, 90 * degrees, 180 * degrees); - ctx.arc(radius, radius, radius, 180 * degrees, 270 * degrees); - ctx.close_path(); - ctx.clip(); - ctx.paint(); - return (ImageSurface) ctx.get_target(); - } - - private static Pixbuf initialize_pixbuf(int width, int height) { - Context ctx = new Context(new ImageSurface(Format.ARGB32, width, height)); - ctx.set_source_rgba(1, 1, 1, 0); - ctx.rectangle(0, 0, width, height); - ctx.fill(); - return pixbuf_get_from_surface(ctx.get_target(), 0, 0, width, height); - } - - private static void set_source_hex_color(Context ctx, string hex_color) { - ctx.set_source_rgba((double) from_hex(hex_color.substring(0, 2)) / 255, - (double) from_hex(hex_color.substring(2, 2)) / 255, - (double) from_hex(hex_color.substring(4, 2)) / 255, - hex_color.length > 6 ? (double) from_hex(hex_color.substring(6, 2)) / 255 : 1); - } -} - -} -- cgit v1.2.3-54-g00ecf