Use Hdy.Avatar (#253)

This commit is contained in:
Bleak Grey 2020-10-18 23:35:59 +03:00 committed by GitHub
parent 2b4fd15a25
commit 695e71ef4c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 127 additions and 100 deletions

View File

@ -1,7 +1,3 @@
.avatar {
border-radius: 4px;
}
.header .chip {
padding: 4px 12px;
border-radius: 4px;
@ -29,13 +25,17 @@
border-bottom: none;
}
.padded.app-view {
.padded.ttl-view {
margin: 32px 0 32px 0;
}
.app-view:not(.padded) .content row {
.ttl-view:not(.padded) .content row {
border-radius: 0px;
}
.app-action-bar .circular {
.ttl-action-bar .circular {
box-shadow: none;
}
.ttl-avatar-button {
padding: 0;
}

View File

@ -399,7 +399,7 @@
</packing>
</child>
<style>
<class name="app-view"/>
<class name="ttl-view"/>
</style>
</object>
</child>

View File

@ -201,7 +201,7 @@
</packing>
</child>
<style>
<class name="app-view"/>
<class name="ttl-view"/>
</style>
</object>
</child>

View File

@ -167,7 +167,7 @@
</object>
</child>
<style>
<class name="app-action-bar"/>
<class name="ttl-action-bar"/>
</style>
</object>
<packing>
@ -295,7 +295,7 @@
</object>
</child>
<style>
<class name="app-view"/>
<class name="ttl-view"/>
</style>
</object>
<template class="TootleWidgetsAccountsButton" parent="GtkMenuButton">

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.36.0 -->
<!-- Generated with glade 3.22.2 -->
<interface>
<requires lib="gtk+" version="3.20"/>
<template class="TootleWidgetsAccountsButtonItem" parent="GtkListBoxRow">
@ -25,11 +25,27 @@
<property name="column_spacing">8</property>
<property name="row_homogeneous">True</property>
<child>
<object class="TootleWidgetsAvatar" id="avatar">
<property name="visible">true</property>
<property name="size">48</property>
<signal name="clicked" handler="open_profile" swapped="no"/>
</object>
<object class="GtkButton" id="avatar_button">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="halign">start</property>
<property name="valign">start</property>
<signal name="clicked" handler="open_profile" swapped="no"/>
<child>
<object class="TootleWidgetsAvatar" id="avatar">
<property name="size">48</property>
<property name="valign">start</property>
<property name="visible">true</property>
</object>
</child>
<style>
<class name="flat"/>
<class name="image-button"/>
<class name="circular"/>
<class name="ttl-avatar-button"/>
</style>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">0</property>

View File

@ -50,19 +50,6 @@
<property name="top_attach">0</property>
</packing>
</child>
<child>
<object class="TootleWidgetsAvatar" id="avatar">
<property name="width_request">48</property>
<property name="height_request">48</property>
<property name="valign">start</property>
<property name="visible">true</property>
<signal name="clicked" handler="on_avatar_clicked" swapped="no"/>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">1</property>
</packing>
</child>
<child>
<object class="TootleWidgetsRichLabel" id="header_label">
<property name="visible">True</property>
@ -89,6 +76,7 @@
<property name="hexpand">True</property>
<property name="label" translatable="yes">Name</property>
<property name="ellipsize">end</property>
<property name="single_line_mode">True</property>
</object>
<packing>
<property name="left_attach">0</property>
@ -103,6 +91,7 @@
<property name="label" translatable="no">Handle</property>
<property name="opacity">0.5</property>
<property name="ellipsize">end</property>
<property name="single_line_mode">True</property>
</object>
<packing>
<property name="left_attach">0</property>
@ -388,6 +377,33 @@
<property name="top_attach">2</property>
</packing>
</child>
<child>
<object class="GtkButton" id="avatar_button">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="halign">start</property>
<property name="valign">start</property>
<signal name="clicked" handler="on_avatar_clicked" swapped="no"/>
<child>
<object class="TootleWidgetsAvatar" id="avatar">
<property name="size">48</property>
<property name="valign">start</property>
<property name="visible">true</property>
</object>
</child>
<style>
<class name="flat"/>
<class name="image-button"/>
<class name="circular"/>
<class name="ttl-avatar-button"/>
</style>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">1</property>
</packing>
</child>
<child>
<placeholder/>
</child>

View File

@ -4,7 +4,7 @@ using Gdk;
[GtkTemplate (ui = "/com/github/bleakgrey/tootle/ui/dialogs/main.ui")]
public class Tootle.Dialogs.MainWindow: Hdy.Window, ISavedWindow {
public const string ZOOM_CLASS = "app-scalable";
public const string ZOOM_CLASS = "ttl-scalable";
[GtkChild]
Hdy.Deck deck;

View File

@ -33,7 +33,7 @@ public class Tootle.Cache : GLib.Object {
}
}
public void unload (Reference? r) {
public void unload (ref Reference? r) {
if (r == null)
return;
@ -53,11 +53,15 @@ public class Tootle.Cache : GLib.Object {
// else {
// message (@"[-] $(r.key) - $(item.references)");
// }
r = null;
}
public void load (string? url, owned CachedResultCallback cb) {
if (url == null)
return;
if (url == null) {
cb (null);
return;
}
var key = url;
if (items.contains (key)) {

View File

@ -35,7 +35,7 @@ public class Tootle.Views.Profile : Views.Timeline {
column_view.reorder_child (hdr, 0);
var avatar = builder.get_object ("avatar") as Widgets.Avatar;
avatar.url = profile.avatar;
avatar.account = profile;
var domain = "@" + profile.domain;
menu_button.title.label = profile.handle.replace (domain, "");

View File

@ -16,7 +16,7 @@ public class Tootle.Views.TabbedBase : Views.Base {
state = "content";
states.get_parent ().remove (states);
view.get_style_context ().remove_class ("app-view");
view.get_style_context ().remove_class ("ttl-view");
scrolled.destroy ();
pack_start (states);

View File

@ -23,7 +23,7 @@ public class Tootle.Widgets.AccountsButton : Gtk.MenuButton, IAccountListener {
public Item (InstanceAccount account, AccountsButton btn) {
this.account = account;
this.button = btn;
avatar.url = account.avatar;
avatar.account = account;
title.label = account.display_name;
handle.label = account.handle;
}
@ -143,13 +143,13 @@ public class Tootle.Widgets.AccountsButton : Gtk.MenuButton, IAccountListener {
public virtual void on_account_changed (InstanceAccount? account) {
if (account == null) {
avatar.url = null;
avatar.account = null;
item_accounts.text = "<b><span size=\"large\">%s</span></b>\n%s".printf (
_("Anonymous"),
_("No active account"));
}
else {
avatar.url = account.avatar;
avatar.account = account;
item_accounts.text = @"<b><span size=\"large\">$(account.display_name)</span></b>\n$(account.handle)";
}
item_accounts.use_markup = true;

View File

@ -16,7 +16,7 @@ public class Tootle.Widgets.Attachment.Picture : DrawingArea {
Object (url: url);
}
~Picture () {
cache.unload (cached);
cache.unload (ref cached);
}
public void on_request () {

View File

@ -1,85 +1,76 @@
using Gtk;
using Gdk;
public class Tootle.Widgets.Avatar : Button {
public string? url { get; set; }
public int size { get; set; default = 48; }
public class Tootle.Widgets.Avatar : Bin {
Cache.Reference? cached;
construct {
get_style_context ().add_class ("avatar");
notify["url"].connect (on_url_updated);
notify["size"].connect (on_size_changed);
// Screen.get_default ().monitors_changed.connect (on_redraw);
on_url_updated ();
Hdy.Avatar avatar;
public int size {
get {
return avatar.size;
}
set {
avatar.size = value;
}
}
public Avatar (int size = this.size) {
Object (size: size);
queue_draw ();
public API.Account? account { get; set; }
construct {
avatar = new Hdy.Avatar (48, null, true);
add (avatar);
show_all ();
notify["account"].connect (on_invalidated);
on_invalidated ();
}
~Avatar () {
notify["url"].disconnect (on_url_updated);
// Screen.get_default ().monitors_changed.disconnect (on_redraw);
cache.unload (cached);
notify["account"].disconnect (on_invalidated);
cache.unload (ref cached);
}
void on_url_updated () {
void on_invalidated () {
if (cached != null)
cache.unload (cached);
cache.unload (ref cached);
cached = null;
queue_draw ();
cache.load (url, on_cache_result);
if (account != null)
cache.load (account.avatar, on_cache_result);
else
on_cache_result (null);
}
void on_cache_result (Cache.Reference? result) {
cached = result;
queue_draw ();
}
void on_size_changed () {
set_size_request (get_scaled_size (), get_scaled_size ());
queue_draw ();
}
public int get_scaled_size () {
return size; //return size * get_scale_factor ();
}
public override void get_preferred_height (out int min_h, out int nat_h) {
min_h = nat_h = get_scaled_size ();
}
public override void get_preferred_width (out int min_w, out int nat_w) {
min_w = nat_w = get_scaled_size ();
}
public override bool draw (Cairo.Context ctx) {
var w = get_allocated_width ();
var h = get_allocated_height ();
var style = get_style_context ();
var border_radius = style.get_property (Gtk.STYLE_PROPERTY_BORDER_RADIUS, style.get_state ()).get_int ();
Pixbuf pixbuf;
Drawing.draw_rounded_rect (ctx, 0, 0, w, h, border_radius);
if (cached != null && !cached.loading) {
pixbuf = cached.data.scale_simple (get_scaled_size (), get_scaled_size (), InterpType.BILINEAR);
if (account == null) {
// This exact string makes the avatar grey.
//
// If left null, *each* blank Hdy.Avatar receives
// a random color and hurts my eyes. No bueno.
avatar.text = "abc";
avatar.show_initials = false;
}
else if (cached != null) {
avatar.text = account.display_name;
avatar.show_initials = true;
}
avatar.set_image_load_func (avatar_set_pixbuf);
}
Pixbuf? avatar_set_pixbuf (int size) {
if (cached == null || cached.data == null)
return null;
else {
pixbuf = IconTheme.get_default ().load_icon_for_scale (
"avatar-default",
get_scaled_size (),
get_scale_factor (),
IconLookupFlags.GENERIC_FALLBACK);
var pb = cached.data;
if (pb.width != size)
return pb.scale_simple (size, size, InterpType.BILINEAR);
else
return pb;
}
Gdk.cairo_set_source_pixbuf (ctx, pixbuf, 0, 0);
ctx.fill ();
return Gdk.EVENT_STOP;
}
}

View File

@ -138,7 +138,7 @@ public class Tootle.Widgets.Status : ListBoxRow {
bind_property ("subtitle_text", handle_label, "text", BindingFlags.SYNC_CREATE);
bind_property ("date", date_label, "label", BindingFlags.SYNC_CREATE);
status.formal.bind_property ("pinned", pin_indicator, "visible", BindingFlags.SYNC_CREATE);
bind_property ("avatar_url", avatar, "url", BindingFlags.SYNC_CREATE);
status.formal.bind_property ("account", avatar, "account", BindingFlags.SYNC_CREATE);
status.formal.bind_property ("has-spoiler", this, "reveal-spoiler", BindingFlags.SYNC_CREATE, (b, src, ref target) => {
target.set_boolean (!src.get_boolean ());