← Back to team overview

birdie-team team mailing list archive

[Merge] lp:~danrabbit/birdie/tweetbox-refactor into lp:birdie

 

Daniel Fore has proposed merging lp:~danrabbit/birdie/tweetbox-refactor into lp:birdie.

Requested reviews:
  Birdie Developers (birdie-team)
Related bugs:
  Bug #1161665 in Birdie: "Too much white space"
  https://bugs.launchpad.net/birdie/+bug/1161665

For more details, see:
https://code.launchpad.net/~danrabbit/birdie/tweetbox-refactor/+merge/156934

This branch refactors tweetbox.vala to include the following changes:

* Uses gtk.overlay for a tighter layout that avoids shifting ui elements
* Uses organization and padding truer to Twitter's own apps
* Allows selecting text for @names
-- 
https://code.launchpad.net/~danrabbit/birdie/tweetbox-refactor/+merge/156934
Your team Birdie Developers is requested to review the proposed merge of lp:~danrabbit/birdie/tweetbox-refactor into lp:birdie.
=== modified file 'src/Widgets/TweetBox.vala'
--- src/Widgets/TweetBox.vala	2013-04-02 22:13:06 +0000
+++ src/Widgets/TweetBox.vala	2013-04-03 18:04:23 +0000
@@ -21,17 +21,18 @@
 
         private Gtk.Box tweet_box;
         private Gtk.Alignment avatar_alignment;
-        private Gtk.Image avatar_img;
-        private Gtk.Image status_img;
         private Gtk.Alignment content_alignment;
+        private Gtk.Alignment buttons_alignment;
         private Gtk.Box content_box;
         private Gtk.Label username_label;
         private Gtk.Label tweet_label;
         private Gtk.Label info_label;
-        private Gtk.Alignment right_alignment;
-        private Gtk.Box right_box;
+        private Gtk.Label time_label;
+        private Gtk.Box avatar_box;
+        private Gtk.Box header_box;
         private Gtk.Box buttons_box;
-        private Gtk.Label time_label;
+        private Gtk.Box status_box;
+        private Gtk.Overlay context_overlay;
         private Gtk.Button favorite_button;
         private Gtk.Button retweet_button;
         private Gtk.Button reply_button;
@@ -40,6 +41,8 @@
         private Gtk.Image retweet_icon;
         private Gtk.Image reply_icon;
         private Gtk.Image delete_icon;
+        private Gtk.Image avatar_img;
+        private Gtk.Image status_img;
         private Gtk.EventBox media_box;
         private Gtk.Image media;
         private Gdk.Pixbuf media_pixbuf;
@@ -72,33 +75,49 @@
 
             // avatar alignment
             this.avatar_alignment = new Gtk.Alignment (0,0,0,1);
-            this.avatar_alignment.top_padding = 0;
-            this.avatar_alignment.right_padding = 6;
-            this.avatar_alignment.bottom_padding = 0;
+            this.avatar_alignment.top_padding = 12;
+            this.avatar_alignment.right_padding = 4;
+            this.avatar_alignment.bottom_padding = 12;
             this.avatar_alignment.left_padding = 12;
             this.tweet_box.pack_start (this.avatar_alignment, false, true, 0);
 
-            // avatar image
-            this.avatar_img = new Gtk.Image ();
-            this.avatar_img.set_from_file (Environment.get_home_dir () + "/.cache/birdie/" + tweet.profile_image_file);
-            this.avatar_img.set_halign (Gtk.Align.START);
-            this.avatar_img.set_valign (Gtk.Align.CENTER);
-            this.avatar_alignment.add (this.avatar_img);
+            // avatar box
+            this.avatar_box = new Gtk.Box (Gtk.Orientation.VERTICAL, 0);
+            this.avatar_alignment.add (this.avatar_box);
+
+            // Overlay
+            this.context_overlay = new Gtk.Overlay ();
+            this.tweet_box.pack_start (this.context_overlay, true, true, 0);
 
             // content alignment
             this.content_alignment = new Gtk.Alignment (0,0,0,1);
-            this.content_alignment.top_padding = 0;
-            this.content_alignment.right_padding = 6;
-            this.content_alignment.bottom_padding = 0;
-            this.content_alignment.left_padding = 6;
-            this.content_alignment.set_valign (Gtk.Align.CENTER);
-            this.tweet_box.pack_start (this.content_alignment, false, false, 0);
+            this.content_alignment.top_padding = 12;
+            this.content_alignment.right_padding = 12;
+            this.content_alignment.bottom_padding = 12;
+            this.content_alignment.left_padding = 4;
+            this.content_alignment.xscale = 1;
+            this.content_alignment.set_valign (Gtk.Align.START);
+            this.context_overlay.add (this.content_alignment);
 
             // content box
             this.content_box = new Gtk.Box (Gtk.Orientation.VERTICAL, 0);
-            this.content_box.set_valign (Gtk.Align.CENTER);
             this.content_alignment.add (this.content_box);
 
+            // set info header
+            this.set_header ();
+
+            // avatar image
+            this.avatar_img = new Gtk.Image ();
+            this.avatar_img.set_from_file (Environment.get_home_dir () + "/.cache/birdie/" + tweet.profile_image_file);         
+            this.avatar_img.set_halign (Gtk.Align.START);
+            this.avatar_img.set_valign (Gtk.Align.START);
+            this.avatar_box.pack_start (this.avatar_img, false, false, 0);
+
+            // header box
+            this.header_box = new Gtk.Box (Gtk.Orientation.HORIZONTAL, 0);  
+            this.content_box.pack_start (this.header_box, false, false, 0);
+
+            // show symbols properly in user label
             if ("&" in tweet.user_name)
                 tweet.user_name = tweet.user_name.replace ("&", "&");
 
@@ -109,12 +128,20 @@
                 tweet.text = tweet.text.replace (" >", ">");
 
             // user label
-            this.username_label = new Gtk.Label (tweet.user_name);
+            this.username_label = new Gtk.Label ("");
             this.username_label.set_halign (Gtk.Align.START);
-            this.username_label.margin_bottom = 6;
+            this.username_label.set_valign (Gtk.Align.START);
+            this.username_label.set_selectable (true);
+            this.username_label.set_markup ("<span underline='none' color='#000' font_weight='bold' size='large'><a href='birdie://user/" + tweet.user_screen_name + "'>" + tweet.user_name + "</a></span> <span font_weight='light' color='#aaa'>@" + tweet.user_screen_name + "</span>");
+            //FIXME: Set ellipsis mode            
+            this.header_box.pack_start (this.username_label, false, true, 0);
 
-            this.username_label.set_markup ("<span underline='none' color='#000000' font_weight='bold' size='large'><a href='birdie://user/" + tweet.user_screen_name + "'>" + tweet.user_name + "</a></span> <span font_weight='light' color='#aaaaaa'>@" + tweet.user_screen_name + "</span>");
-            this.content_box.pack_start (this.username_label, false, true, 0);
+            // time label
+            this.time_label = new Gtk.Label ("");
+            this.time_label.set_halign (Gtk.Align.END);
+            this.time_label.set_valign (Gtk.Align.START);
+            this.update_date ();
+            this.header_box.pack_start (this.time_label, true, true, 0);
 
             // tweet
             this.tweet_label = new Gtk.Label (tweet.text);
@@ -123,9 +150,14 @@
             this.tweet_label.set_line_wrap (true);
             this.tweet_label.wrap_mode = Pango.WrapMode.WORD_CHAR;
             this.tweet_label.set_halign (Gtk.Align.START);
+            this.tweet_label.set_valign (Gtk.Align.START);
             this.tweet_label.xalign = 0;
             this.content_box.pack_start (this.tweet_label, false, true, 0);
 
+            // css
+            Gtk.StyleContext ctx = this.tweet_label.get_style_context();
+            ctx.add_class("tweet");
+
             // media
             if (tweet.media_url != "") {
 
@@ -146,56 +178,38 @@
                 });
             }
 
-            // css
-            Gtk.StyleContext ctx = this.tweet_label.get_style_context();
-            ctx.add_class("tweet");
-            //
-
-            // info footer
-            this.set_footer ();
-
-            // buttons alignment
-            this.right_alignment = new Gtk.Alignment (0,0,1,1);
-            this.right_alignment.top_padding = 0;
-            this.right_alignment.right_padding = 0;
-            this.right_alignment.bottom_padding = 6;
-            this.right_alignment.left_padding = 6;
-            this.right_alignment.set_valign (Gtk.Align.FILL);
-            this.tweet_box.pack_start (this.right_alignment, true, true, 0);
-
-            // right box
-            this.right_box = new Gtk.Box (Gtk.Orientation.VERTICAL, 0);
-            this.right_box.set_valign (Gtk.Align.FILL);
-            this.right_alignment.add (this.right_box);
-
-            // time label
-            this.time_label = new Gtk.Label ("");
-            this.time_label.set_halign (Gtk.Align.END);
-            this.time_label.set_valign (Gtk.Align.START);
-            this.time_label.margin_bottom = 6;
-            this.time_label.margin_top = 6;
-            this.time_label.margin_right = 12;
-            this.update_date ();
-
-            // buttons box
-            this.buttons_box = new Gtk.Box (Gtk.Orientation.VERTICAL, 0);
-            this.buttons_box.set_valign (Gtk.Align.FILL);
-            this.buttons_box.set_no_show_all (true);
-            this.buttons_box.margin_right = 12;
-            this.buttons_box.hide ();
-
+
+            // status image
             this.status_img = new Gtk.Image ();
             this.status_img.set_halign (Gtk.Align.END);
             this.status_img.set_valign (Gtk.Align.START);
 
             if ((this.tweet.favorited || this.tweet.retweeted) && !this.tweet.dm)
-                this.right_box.pack_start (this.status_img, false, false, 0);
+                this.context_overlay.add_overlay (this.status_img);
+
+            // buttons alignment
+            this.buttons_alignment = new Gtk.Alignment (0,0,0,1);
+            this.buttons_alignment.set_halign (Gtk.Align.END);
+            this.buttons_alignment.set_valign (Gtk.Align.START);
+            this.buttons_alignment.top_padding = 6;
+            this.buttons_alignment.right_padding = 6;
+            this.context_overlay.add_overlay (this.buttons_alignment);
+
+            // buttons box
+            this.buttons_box = new Gtk.Box (Gtk.Orientation.HORIZONTAL, 0);
+            this.buttons_box.set_halign (Gtk.Align.END);
+            this.buttons_box.set_valign (Gtk.Align.START);
+            this.buttons_box.set_no_show_all (true);
+            this.buttons_box.hide ();
+
+            // FIXME: Split this button crap into a method like the info header
 
             // favorite button
             if (!this.tweet.dm) {
                 this.favorite_button = new Gtk.Button ();
                 this.favorite_button.set_halign (Gtk.Align.END);
-                this.favorite_icon = new Gtk.Image.from_icon_name ("twitter-fav", Gtk.IconSize.MENU);
+                this.favorite_button.set_relief (Gtk.ReliefStyle.NONE);
+                this.favorite_icon = new Gtk.Image.from_icon_name ("twitter-fav", Gtk.IconSize.SMALL_TOOLBAR);
                 this.favorite_button.child = this.favorite_icon;
                 this.favorite_button.set_tooltip_text (_("Favorite"));
                 this.buttons_box.pack_start (favorite_button, false, true, 0);
@@ -206,7 +220,7 @@
                 });
 
                 if (this.tweet.favorited) {
-                    this.favorite_icon.set_from_icon_name ("twitter-favd", Gtk.IconSize.MENU);
+                    this.favorite_icon.set_from_icon_name ("twitter-favd", Gtk.IconSize.SMALL_TOOLBAR);
                     this.status_img.set_from_icon_name("twitter-fav-banner",  Gtk.IconSize.LARGE_TOOLBAR);
                 }
             }
@@ -216,7 +230,8 @@
                 if (!this.tweet.dm) {
                     this.retweet_button = new Gtk.Button ();
                     this.retweet_button.set_halign (Gtk.Align.END);
-                    this.retweet_icon = new Gtk.Image.from_icon_name ("twitter-retweet", Gtk.IconSize.MENU);
+                    this.retweet_button.set_relief (Gtk.ReliefStyle.NONE);
+                    this.retweet_icon = new Gtk.Image.from_icon_name ("twitter-retweet", Gtk.IconSize.SMALL_TOOLBAR);
                     this.retweet_button.child = this.retweet_icon;
                     if (birdie.service == 0)
                         this.retweet_button.set_tooltip_text (_("Retweet"));
@@ -226,7 +241,7 @@
 
                     if (this.tweet.retweeted) {
                         this.retweet_button.set_sensitive (false);
-                        this.retweet_icon.set_from_icon_name ("twitter-retweeted", Gtk.IconSize.MENU);
+                        this.retweet_icon.set_from_icon_name ("twitter-retweeted", Gtk.IconSize.SMALL_TOOLBAR);
                         this.status_img.set_from_icon_name ("twitter-ret-banner",  Gtk.IconSize.LARGE_TOOLBAR);
                     }
 
@@ -244,7 +259,8 @@
                 // reply button
                 this.reply_button = new Gtk.Button ();
                 this.reply_button.set_halign (Gtk.Align.END);
-                this.reply_icon = new Gtk.Image.from_icon_name ("twitter-reply", Gtk.IconSize.MENU);
+                this.reply_button.set_relief (Gtk.ReliefStyle.NONE);
+                this.reply_icon = new Gtk.Image.from_icon_name ("twitter-reply", Gtk.IconSize.SMALL_TOOLBAR);
                 this.reply_button.child = this.reply_icon;
                 this.reply_button.set_tooltip_text (_("Reply"));
 
@@ -258,7 +274,8 @@
                 // delete button
                 this.delete_button = new Gtk.Button ();
                 this.delete_button.set_halign (Gtk.Align.END);
-                this.delete_icon = new Gtk.Image.from_icon_name ("twitter-delete", Gtk.IconSize.MENU);
+                this.delete_button.set_relief (Gtk.ReliefStyle.NONE);
+                this.delete_icon = new Gtk.Image.from_icon_name ("twitter-delete", Gtk.IconSize.SMALL_TOOLBAR);
                 this.delete_button.child = this.delete_icon;
                 this.delete_button.set_tooltip_text (_("Delete"));
 
@@ -269,8 +286,7 @@
                 this.buttons_box.pack_start (delete_button, false, true, 0);
             }
 
-            this.right_box.pack_start (this.time_label, true, true, 0);
-            this.right_box.add (this.buttons_box);
+            this.buttons_alignment.add (this.buttons_box);
 
             set_events(Gdk.EventMask.BUTTON_RELEASE_MASK);
             set_events(Gdk.EventMask.ENTER_NOTIFY_MASK);
@@ -292,7 +308,6 @@
                 return false;
             });
 
-            this.set_size_request (-1, 150);
         }
 
         private void show_media (string media_file) {
@@ -308,12 +323,14 @@
 
         public void hide_buttons () {
             this.buttons_box.hide ();
+            this.time_label.show ();
         }
 
         public void show_buttons () {
             this.buttons_box.set_no_show_all (false);
             this.buttons_box.show_all ();
             this.buttons_box.set_no_show_all (true);
+            this.time_label.hide ();
         }
 
         private void* favorite_thread () {
@@ -327,7 +344,7 @@
                         if (this.tweet.retweeted) {
                             this.status_img.set_from_icon_name("twitter-ret-banner",  Gtk.IconSize.LARGE_TOOLBAR);
                         } else {
-                            this.right_box.remove (this.status_img);
+                            this.status_box.remove (this.status_img);
                         }
 
                         this.tweet.favorited = false;
@@ -350,15 +367,15 @@
                         if (this.tweet.retweeted) {
                             this.status_img.set_from_icon_name ("twitter-favret-banner", Gtk.IconSize.LARGE_TOOLBAR);
                         } else {
-                            this.right_box.remove (this.time_label);
-                            this.right_box.remove (this.buttons_box);
+                            this.status_box.remove (this.time_label);
+                            this.status_box.remove (this.buttons_box);
 
                             this.status_img.set_from_icon_name("twitter-fav-banner",  Gtk.IconSize.LARGE_TOOLBAR);
 
-                            this.right_box.pack_start (this.status_img, false, false, 0);
-                            this.right_box.pack_start (this.time_label, true, true, 0);
-                            this.right_box.add (this.buttons_box);
-                            this.right_box.show_all ();
+                            this.status_box.pack_start (this.status_img, false, false, 0);
+                            this.status_box.pack_start (this.time_label, true, true, 0);
+                            this.status_box.add (this.buttons_box);
+                            this.status_box.show_all ();
                         }
 
                         this.tweet.favorited = true;
@@ -384,18 +401,18 @@
                     if (this.tweet.favorited) {
                         this.status_img.set_from_icon_name("twitter-favret-banner",  Gtk.IconSize.LARGE_TOOLBAR);
                     } else {
-                        this.right_box.remove (this.time_label);
-                        this.right_box.remove (this.buttons_box);
+                        this.status_box.remove (this.time_label);
+                        this.status_box.remove (this.buttons_box);
 
                         this.status_img.set_from_icon_name("twitter-ret-banner",  Gtk.IconSize.LARGE_TOOLBAR);
 
-                        this.right_box.pack_start (this.status_img, false, false, 0);
-                        this.right_box.pack_start (this.time_label, true, true, 0);
-                        this.right_box.add (this.buttons_box);
-                        this.right_box.show_all ();
+                        this.status_box.pack_start (this.status_img, false, false, 0);
+                        this.status_box.pack_start (this.time_label, true, true, 0);
+                        this.status_box.add (this.buttons_box);
+                        this.status_box.show_all ();
                     }
 
-                    this.retweet_icon.set_from_icon_name ("twitter-retweeted", Gtk.IconSize.MENU);
+                    this.retweet_icon.set_from_icon_name ("twitter-retweeted", Gtk.IconSize.SMALL_TOOLBAR);
                     this.tweet.retweeted = true;
                 } else {
                     this.retweet_button.set_sensitive (true);
@@ -462,43 +479,44 @@
 
         public void update_display () {
             if (this.tweet.favorited) {
-                this.favorite_icon.set_from_icon_name ("twitter-favd", Gtk.IconSize.MENU);
+                this.favorite_icon.set_from_icon_name ("twitter-favd", Gtk.IconSize.SMALL_TOOLBAR);
                 this.favorite_button.set_tooltip_text (_("Unfavorite"));
             } else {
-                this.favorite_icon.set_from_icon_name ("twitter-fav", Gtk.IconSize.MENU);
+                this.favorite_icon.set_from_icon_name ("twitter-fav", Gtk.IconSize.SMALL_TOOLBAR);
                 this.favorite_button.set_tooltip_text (_("Favorite"));
             }
         }
 
-        private void set_footer () {
+        private void set_header () {
             var retweeted_by_label = "";
 
-            retweeted_by_label = ("<span color='#aaaaaa'>" + _("retweeted by %s").printf ("<span underline='none'><a href='birdie://user/" + this.tweet.retweeted_by + "'>" + this.tweet.retweeted_by_name + "</a></span>") + "</span>");
+            retweeted_by_label = ("<span color='#aaa'>" + _("retweeted by %s").printf ("<span underline='none'><a href='birdie://user/" + this.tweet.retweeted_by + "'>" + this.tweet.retweeted_by_name + "</a></span>") + "</span>");
             if (this.tweet.retweeted_by != "") {
                 var retweeted_img = new Gtk.Image ();
                 retweeted_img.set_from_icon_name ("twitter-retweet", Gtk.IconSize.MENU);
-                var retweeted_box = new Gtk.Box (Gtk.Orientation.HORIZONTAL, 0);
+                retweeted_img.set_halign (Gtk.Align.END);
+                retweeted_img.margin_bottom = 6;
                 this.info_label = new Gtk.Label ("");
                 this.info_label.set_halign (Gtk.Align.START);
+                this.info_label.margin_bottom = 6;
                 if (birdie.service == 1)
-                    retweeted_by_label = ("<span color='#aaaaaa'>" + _("repeated by %s").printf ("<span underline='none'><a href='birdie://user/" + this.tweet.retweeted_by + "'>" + this.tweet.retweeted_by_name + "</a></span>") + "</span>");
-                this.info_label.set_markup ("<span color='#aaaaaa'>" + retweeted_by_label + "</span>");
-                retweeted_box.pack_start (retweeted_img, false, false, 0);
-                retweeted_box.pack_start (this.info_label, false, false, 0);
-                retweeted_box.margin_top = 6;
-                this.content_box.add (retweeted_box);
+                    retweeted_by_label = ("<span color='#aaa'>" + _("repeated by %s").printf ("<span underline='none'><a href='birdie://user/" + this.tweet.retweeted_by + "'>" + this.tweet.retweeted_by_name + "</a></span>") + "</span>");
+                this.info_label.set_markup ("<span color='#aaa'>" + retweeted_by_label + "</span>");
+                avatar_box.pack_start (retweeted_img, false, false, 0);
+                content_box.pack_start (this.info_label, false, false, 0);
+
             } else if (this.tweet.in_reply_to_screen_name != "") {
                 var reply_img = new Gtk.Image ();
                 reply_img.set_from_icon_name ("twitter-reply", Gtk.IconSize.MENU);
-                var reply_box = new Gtk.Box (Gtk.Orientation.HORIZONTAL, 0);
+                reply_img.set_halign (Gtk.Align.END);
+                reply_img.margin_bottom = 6;
                 this.info_label = new Gtk.Label ("");
                 this.info_label.set_halign (Gtk.Align.START);
-                var in_reply_label = ("<span color='#aaaaaa'>" + _("in reply to @%s").printf ("<span underline='none'><a href='birdie://user/" + this.tweet.in_reply_to_screen_name + "'>" + this.tweet.in_reply_to_screen_name + "</a></span>") + "</span>");
+                this.info_label.margin_bottom = 6;
+                var in_reply_label = ("<span color='#aaa'>" + _("in reply to @%s").printf ("<span underline='none'><a href='birdie://user/" + this.tweet.in_reply_to_screen_name + "'>" + this.tweet.in_reply_to_screen_name + "</a></span>") + "</span>");
                 this.info_label.set_markup (in_reply_label);
-                reply_box.pack_start (reply_img, false, false, 0);
-                reply_box.pack_start (this.info_label, false, false, 0);
-                reply_box.margin_top = 6;
-                this.content_box.add (reply_box);
+                avatar_box.pack_start (reply_img, false, false, 0);
+                content_box.pack_start (this.info_label, false, false, 0);          
             } else {
             }
         }


Follow ups