Merge lp:~mterry/unity-greeter/scrolling-update into lp:unity-greeter

Proposed by Michael Terry
Status: Merged
Merged at revision: 241
Proposed branch: lp:~mterry/unity-greeter/scrolling-update
Merge into: lp:unity-greeter
Diff against target: 621 lines (+249/-139)
3 files modified
src/Makefile.am (+1/-0)
src/animate-timer.vala (+112/-0)
src/user-list.vala (+136/-139)
To merge this branch: bzr merge lp:~mterry/unity-greeter/scrolling-update
Reviewer Review Type Date Requested Status
Unity Greeter Development Team Pending
Review via email: mp+86288@code.launchpad.net

Description of the change

This branch updates the scrolling animation a bit to more closely match the video in bug 844050.

Specifically, the following bits are done when switching users:
1) The current password box disappears (no animation)
2) The current username and gear scroll up or down and off the highlight box
3) The next username and gear scroll up or down into the highlight box to rest where they should
4) the new password box appears (no animation)

There are bits in the bug that aren't done in this branch. But this was a good checkpoint, so I thought no harm in having this reviewed/merged.

Specifically, the things that aren't done:
5) When first appearing, the greeter scrolls from the top of the list to the default user
6) Final speed and tweening adjustments

There are some slight rough edges because (6) isn't done. Notably, if your are scrolling past multiple users (like you clicked at the top of the list, it looks a little odd because each name that scrolls by changes speed as it passes through the box). This isn't worse than the current code really, it just isn't perfect yet.

Notable things that this branch does:
 * Make more sections of code aware of when we are scrolling
 * Consolidate some entry drawing code and have smaller code branches for in-box drawing
 * Slowed speed a tad from 5.0 to 4.0. 5.0 made things move too fast on the screen I thought.

To post a comment you must log in.
241. By Michael Terry

make animation match Unity speed/easing

242. By Michael Terry

fix race condition when starting and showing old background

243. By Michael Terry

scroll to first user after we are realized

244. By Michael Terry

remove some unused code

Revision history for this message
Michael Terry (mterry) wrote :

Just pushed an update that fixes (5) and (6).

245. By Michael Terry

merge from trunk

246. By Michael Terry

start scrolling before we try to show the prompt so that the entry box hides during scrolling again

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'src/Makefile.am'
--- src/Makefile.am 2012-01-10 09:31:10 +0000
+++ src/Makefile.am 2012-01-11 13:58:24 +0000
@@ -6,6 +6,7 @@
6 config.vapi \6 config.vapi \
7 fixes.vapi \7 fixes.vapi \
8 indicator.vapi \8 indicator.vapi \
9 animate-timer.vala \
9 settings-daemon.vala \10 settings-daemon.vala \
10 unity-greeter.vala \11 unity-greeter.vala \
11 user-list.vala12 user-list.vala
1213
=== added file 'src/animate-timer.vala'
--- src/animate-timer.vala 1970-01-01 00:00:00 +0000
+++ src/animate-timer.vala 2012-01-11 13:58:24 +0000
@@ -0,0 +1,112 @@
1/* -*- Mode: Vala; indent-tabs-mode: nil; tab-width: 4 -*-
2 *
3 * Copyright (C) 2011,2012 Canonical Ltd
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 3 as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 *
17 * Authors: Robert Ancell <robert.ancell@canonical.com>
18 * Michael Terry <michael.terry@canonical.com>
19 */
20
21private class AnimateTimer : Object
22{
23 public enum Speed
24 {
25 INSTANT, /* Good for animations that don't convey any information */
26 FAST, /* Good for animations that convey duplicated information (e.g. scrolling) */
27 NORMAL,
28 SLOW, /* Good for animations that convey information that is only presented in the animation */
29 }
30
31 public Speed speed {get; construct;}
32 public bool is_running { get { return timeout != 0; } }
33
34 /* progress is from 0.0 to 1.0 */
35 public signal void animate (double progress);
36
37 public AnimateTimer (Speed speed)
38 {
39 Object (speed: speed);
40 }
41
42 public void reset ()
43 {
44 stop ();
45 timeout = Timeout.add (16, animate_cb);
46
47 start_time = GLib.get_monotonic_time ();
48
49 /* The following are the same intervals that Unity uses */
50 switch (speed)
51 {
52 default:
53 case Speed.INSTANT:
54 length = 150 * TimeSpan.MILLISECOND;
55 break;
56 case Speed.FAST:
57 length = 250 * TimeSpan.MILLISECOND;
58 break;
59 case Speed.NORMAL:
60 length = 500 * TimeSpan.MILLISECOND;
61 break;
62 case Speed.SLOW:
63 length = 1000 * TimeSpan.MILLISECOND;
64 break;
65 }
66 }
67
68 public void stop ()
69 {
70 if (timeout != 0)
71 Source.remove (timeout);
72 timeout = 0;
73 }
74
75 private uint timeout = 0;
76 private TimeSpan start_time = 0;
77 private TimeSpan length = 0;
78
79 private bool animate_cb ()
80 {
81 var time = normalize_time ();
82 var progress = normalize_progress (time);
83
84 animate (progress);
85
86 if (progress >= 1.0)
87 {
88 timeout = 0;
89 return false;
90 }
91 else
92 return true;
93 }
94
95 /* Returns 0.0 to 1.0 where 1.0 is at or past end_time */
96 private double normalize_time ()
97 {
98 var now = GLib.get_monotonic_time ();
99 return (((double)(now - start_time)) / length).clamp (0.0, 1.0);
100 }
101
102 /* Returns 0.0 to 1.0 where 1.0 is done.
103 time is normalized time from 0.0 to 1.0. */
104 private double normalize_progress (double time)
105 {
106 /* Use a sine wave function similar to what Unity uses. They call it
107 'easing' and is designed to make the animation start and end slower
108 than in the middle. */
109 return ((-1 * Math.cos (Math.PI * time) + 1) / 2).clamp (0.0, 1.0);
110 }
111}
112
0113
=== modified file 'src/user-list.vala'
--- src/user-list.vala 2012-01-10 09:31:10 +0000
+++ src/user-list.vala 2012-01-11 13:58:24 +0000
@@ -25,43 +25,6 @@
25 return (int) (size % grid_size) / 2;25 return (int) (size % grid_size) / 2;
26}26}
2727
28private class AnimateTimer
29{
30 private Timer timer;
31 private uint timeout = 0;
32 private double last_timestep;
33
34 public signal void animate (double timestep);
35
36 private bool animate_cb ()
37 {
38 var t = timer.elapsed ();
39 var timestep = t - last_timestep;
40 last_timestep = t;
41
42 animate (timestep);
43
44 return true;
45 }
46
47 public bool is_running { get { return timeout != 0; } }
48
49 public void reset ()
50 {
51 stop ();
52 last_timestep = 0.0;
53 timer = new Timer ();
54 timeout = Timeout.add (10, animate_cb);
55 }
56
57 public void stop ()
58 {
59 if (timeout != 0)
60 Source.remove (timeout);
61 timeout = 0;
62 }
63}
64
65private class UserEntry28private class UserEntry
66{29{
67 /* Unique name for this entry */30 /* Unique name for this entry */
@@ -298,6 +261,7 @@
298 private UserEntry? selected_entry = null;261 private UserEntry? selected_entry = null;
299 262
300 private double scroll_target_location;263 private double scroll_target_location;
264 private double scroll_start_location;
301 private double scroll_location;265 private double scroll_location;
302 private double scroll_direction;266 private double scroll_direction;
303267
@@ -324,8 +288,10 @@
324288
325 private Gtk.Entry prompt_entry;289 private Gtk.Entry prompt_entry;
326 private Gtk.Button login_button;290 private Gtk.Button login_button;
291 private Gtk.Widget prompt_widget_to_show;
327 private Gtk.Button options_button;292 private Gtk.Button options_button;
328 private Gtk.Menu options_menu;293 private Gtk.Menu options_menu;
294 private Gdk.Pixbuf options_pixbuf;
329 unowned GLib.SList<SessionMenuItem> session_group = null;295 unowned GLib.SList<SessionMenuItem> session_group = null;
330296
331 private bool complete = false;297 private bool complete = false;
@@ -432,14 +398,22 @@
432 login_button.clicked.connect (login_button_clicked_cb);398 login_button.clicked.connect (login_button_clicked_cb);
433 add (login_button);399 add (login_button);
434400
401 try {
402 options_pixbuf = new Gdk.Pixbuf.from_file (Path.build_filename (Config.PKGDATADIR, "cog.png", null));
403 }
404 catch (Error e) {
405 debug ("Error loading cog image: %s", e.message);
406 }
407
435 options_button = new Gtk.Button ();408 options_button = new Gtk.Button ();
436 options_button.focus_on_click = false;409 options_button.focus_on_click = false;
437 options_button.get_accessible ().set_name (_("Session Options"));410 options_button.get_accessible ().set_name (_("Session Options"));
438 var image = new Gtk.Image.from_file (Path.build_filename (Config.PKGDATADIR, "cog.png", null));411 var image = new Gtk.Image.from_pixbuf (options_pixbuf);
439 image.show ();412 image.show ();
440 options_button.relief = Gtk.ReliefStyle.NONE;413 options_button.relief = Gtk.ReliefStyle.NONE;
441 options_button.add (image);414 options_button.add (image);
442 options_button.clicked.connect (options_button_clicked_cb);415 options_button.clicked.connect (options_button_clicked_cb);
416 options_button.show ();
443 add (options_button);417 add (options_button);
444418
445 options_menu = new Gtk.Menu ();419 options_menu = new Gtk.Menu ();
@@ -449,9 +423,9 @@
449423
450 backgrounds = new HashTable<string?, Background> (str_hash, str_equal);424 backgrounds = new HashTable<string?, Background> (str_hash, str_equal);
451425
452 scroll_timer = new AnimateTimer ();426 scroll_timer = new AnimateTimer (AnimateTimer.Speed.FAST);
453 scroll_timer.animate.connect (scroll_animate_cb);427 scroll_timer.animate.connect (scroll_animate_cb);
454 background_timer = new AnimateTimer ();428 background_timer = new AnimateTimer (AnimateTimer.Speed.INSTANT);
455 background_timer.animate.connect (background_animate_cb);429 background_timer.animate.connect (background_animate_cb);
456430
457 setup_indicators ();431 setup_indicators ();
@@ -662,11 +636,15 @@
662 public void show_prompt (string text, bool secret = false)636 public void show_prompt (string text, bool secret = false)
663 {637 {
664 login_button.hide ();638 login_button.hide ();
639 prompt_entry.hide ();
665 message = text;640 message = text;
666 prompt_entry.text = "";641 prompt_entry.text = "";
667 prompt_entry.sensitive = true;642 prompt_entry.sensitive = true;
668 prompt_entry.show ();
669 prompt_entry.visibility = !secret;643 prompt_entry.visibility = !secret;
644 if (scroll_timer.is_running)
645 prompt_widget_to_show = prompt_entry;
646 else
647 prompt_entry.show ();
670 var accessible = prompt_entry.get_accessible ();648 var accessible = prompt_entry.get_accessible ();
671 if (selected_entry.name != null)649 if (selected_entry.name != null)
672 accessible.set_name (_("Enter password for %s").printf (selected_entry.layout.get_text ()));650 accessible.set_name (_("Enter password for %s").printf (selected_entry.layout.get_text ()));
@@ -684,8 +662,12 @@
684 public void show_authenticated ()662 public void show_authenticated ()
685 {663 {
686 prompt_entry.hide ();664 prompt_entry.hide ();
665 login_button.hide ();
687 message = "";666 message = "";
688 login_button.show ();667 if (scroll_timer.is_running)
668 prompt_widget_to_show = login_button;
669 else
670 login_button.show();
689 var accessible = login_button.get_accessible ();671 var accessible = login_button.get_accessible ();
690 accessible.set_name (_("Login as %s").printf (selected_entry.layout.get_text ()));672 accessible.set_name (_("Login as %s").printf (selected_entry.layout.get_text ()));
691 login_button.grab_focus ();673 login_button.grab_focus ();
@@ -879,61 +861,43 @@
879 options_menu.popup (null, null, options_menu_position_cb, 0, Gtk.get_current_event_time ());861 options_menu.popup (null, null, options_menu_position_cb, 0, Gtk.get_current_event_time ());
880 }862 }
881863
882 private void scroll_animate_cb (double timestep)864 private void scroll_animate_cb (double progress)
883 {865 {
884 if (scroll_location != scroll_target_location)866 /* Total height of list */
885 {867 var h = entries.length ();
886 var speed = 5.0;868
887869 /* How far we have to go in total, either up or down with wrapping */
888 var delta = timestep * speed;870 var distance = scroll_target_location - scroll_start_location;
889871 if (scroll_direction * distance < 0)
890 /* Total height of list */872 distance += scroll_direction * h;
891 var h = (double) entries.length ();873
892874 /* How far we've gone so far */
893 var distance = scroll_target_location - scroll_location;875 distance *= progress;
894 if (scroll_direction < 0.0)876
895 distance = -distance;877 /* Go that far and wrap around */
896 if (distance < 0)878 scroll_location = scroll_start_location + distance;
897 distance += h;879 if (scroll_location > h)
898880 scroll_location -= h;
899 /* If close enough finish moving */881 if (scroll_location < 0)
900 if (distance <= delta)882 scroll_location += h;
901 scroll_location = scroll_target_location;883
902 else884 /* And finally, redraw */
903 {885 redraw_user_list ();
904 scroll_location += delta * scroll_direction;886
905887 /* Stop when we get there */
906 /* Wrap around */888 if (progress >= 1.0)
907 if (scroll_location > h)889 finished_animating ();
908 scroll_location -= h;
909 if (scroll_location < 0)
910 scroll_location += h;
911 }
912
913 redraw_user_list ();
914 }
915
916 /* Stop when we get there */
917 if (scroll_location == scroll_target_location)
918 scroll_timer.stop ();
919 }890 }
920891
921 private void background_animate_cb (double timestep)892 private void background_animate_cb (double progress)
922 {893 {
923 var speed = 5.0;894 background_alpha = progress;
924
925 background_alpha += timestep * speed;
926 if (background_alpha > 1.0)
927 background_alpha = 1.0;
928895
929 redraw_background ();896 redraw_background ();
930897
931 /* Stop when we get there */898 /* Stop when we get there */
932 if (background_alpha == 1.0)899 if (background_alpha >= 1.0)
933 {
934 old_background = background;900 old_background = background;
935 background_timer.stop ();
936 }
937 }901 }
938 902
939 private bool change_background_timeout_cb ()903 private bool change_background_timeout_cb ()
@@ -970,14 +934,33 @@
970 change_background_timeout_cb ();934 change_background_timeout_cb ();
971 }935 }
972936
937 private void finished_animating ()
938 {
939 if (prompt_widget_to_show != null) {
940 prompt_widget_to_show.show ();
941 prompt_widget_to_show = null;
942 }
943 options_button.show ();
944 }
945
973 private void select_entry (UserEntry entry, double direction)946 private void select_entry (UserEntry entry, double direction)
974 {947 {
948 if (get_realized ())
949 {
950 scroll_target_location = entries.index (entry);
951 scroll_start_location = scroll_location;
952 scroll_direction = direction;
953 if (scroll_location != scroll_target_location)
954 scroll_timer.reset ();
955 }
956
975 if (selected_entry != entry)957 if (selected_entry != entry)
976 {958 {
977 selected_entry = entry;959 selected_entry = entry;
978960
979 prompt_entry.hide ();961 prompt_entry.hide ();
980 login_button.hide ();962 login_button.hide ();
963 options_button.hide ();
981964
982 if (get_realized ())965 if (get_realized ())
983 {966 {
@@ -985,15 +968,6 @@
985 user_selected (selected_entry.name);968 user_selected (selected_entry.name);
986 }969 }
987 }970 }
988
989 scroll_target_location = entries.index (selected_entry);
990 scroll_direction = direction;
991 /* Move straight there if not drawn yet */
992 if (frame_count == 0)
993 scroll_location = scroll_target_location;
994
995 if (scroll_location != scroll_target_location && !scroll_timer.is_running)
996 scroll_timer.reset ();
997 }971 }
998972
999 public override void add (Gtk.Widget widget)973 public override void add (Gtk.Widget widget)
@@ -1023,6 +997,8 @@
1023997
1024 set_realized (true);998 set_realized (true);
1025999
1000 select_entry (selected_entry, 1);
1001
1026 Gtk.Allocation allocation;1002 Gtk.Allocation allocation;
1027 get_allocation (out allocation);1003 get_allocation (out allocation);
10281004
@@ -1093,7 +1069,6 @@
1093 child_allocation.width = grid_size;1069 child_allocation.width = grid_size;
1094 child_allocation.height = grid_size;1070 child_allocation.height = grid_size;
1095 options_button.size_allocate (child_allocation);1071 options_button.size_allocate (child_allocation);
1096 options_button.show ();
10971072
1098 /* Regenerate backgrounds */1073 /* Regenerate backgrounds */
1099 if (resized)1074 if (resized)
@@ -1104,11 +1079,11 @@
1104 }1079 }
1105 }1080 }
11061081
1107 private void draw_entry (Cairo.Context c, UserEntry entry, double alpha = 0.5)1082 private void draw_entry (Cairo.Context c, UserEntry entry, double alpha = 0.5, bool in_box = false)
1108 {1083 {
1109 c.save ();1084 c.save ();
1110 1085
1111 if (high_contrast_item.active)1086 if (high_contrast_item.active || in_box)
1112 alpha = 1.0;1087 alpha = 1.0;
11131088
1114 if (entry.is_active)1089 if (entry.is_active)
@@ -1124,11 +1099,17 @@
1124 int w, h;1099 int w, h;
1125 entry.layout.get_pixel_size (out w, out h);1100 entry.layout.get_pixel_size (out w, out h);
11261101
1127 var bw = (box_width - 0.5) * grid_size; 1102 var bw = (box_width - (in_box ? 1.1 : 0.5)) * grid_size;
1128 if (w > bw)1103 if (w > bw)
1129 {1104 {
1130 var mask = new Cairo.Pattern.linear (0, 0, bw, 0);1105 var mask = new Cairo.Pattern.linear (0, 0, bw, 0);
1131 mask.add_color_stop_rgba (1.0 - 64.0 / bw, 1.0, 1.0, 1.0, alpha);1106 if (in_box)
1107 {
1108 mask.add_color_stop_rgba (1.0 - 27.0 / bw, 1.0, 1.0, 1.0, 1.0);
1109 mask.add_color_stop_rgba (1.0 - 21.6 / bw, 1.0, 1.0, 1.0, 0.5);
1110 }
1111 else
1112 mask.add_color_stop_rgba (1.0 - 64.0 / bw, 1.0, 1.0, 1.0, alpha);
1132 mask.add_color_stop_rgba (1.0, 1.0, 1.0, 1.0, 0.0);1113 mask.add_color_stop_rgba (1.0, 1.0, 1.0, 1.0, 0.0);
1133 c.set_source (mask);1114 c.set_source (mask);
1134 }1115 }
@@ -1140,6 +1121,17 @@
1140 Pango.cairo_show_layout (c, entry.layout);1121 Pango.cairo_show_layout (c, entry.layout);
11411122
1142 c.restore ();1123 c.restore ();
1124
1125 /* Now draw options button if we're animating in the box */
1126 if (in_box && scroll_timer.is_running && options_pixbuf != null) {
1127 c.save ();
1128 var xpadding = (grid_size - options_pixbuf.width) / 2;
1129 var ypadding = (grid_size - options_pixbuf.height) / 2;
1130 c.translate (box_width * grid_size - grid_size - grid_size / 4 + xpadding, grid_size / 4 - ypadding);
1131 Gdk.cairo_set_source_pixbuf (c, options_pixbuf, 0, 0);
1132 c.paint ();
1133 c.restore ();
1134 }
1143 }1135 }
11441136
1145 private void background_loaded_cb (Background b)1137 private void background_loaded_cb (Background b)
@@ -1188,12 +1180,15 @@
1188 background_timer.reset ();1180 background_timer.reset ();
11891181
1190 c.set_source_rgb (0x2C, 0x00, 0x1E);1182 c.set_source_rgb (0x2C, 0x00, 0x1E);
1183 var old_not_loaded = false;
11911184
1192 /* Draw old background */1185 /* Draw old background */
1193 if (background_alpha < 1.0)1186 if (background_alpha < 1.0)
1194 {1187 {
1195 if (old_background.load ())1188 if (old_background.load ())
1196 c.set_source (old_background.pattern);1189 c.set_source (old_background.pattern);
1190 else
1191 old_not_loaded = true;
1197 c.paint ();1192 c.paint ();
1198 }1193 }
11991194
@@ -1201,11 +1196,12 @@
1201 if (background.load () && background_alpha > 0.0)1196 if (background.load () && background_alpha > 0.0)
1202 {1197 {
1203 c.set_source (background.pattern);1198 c.set_source (background.pattern);
1204 c.paint_with_alpha (background_alpha);1199 c.paint_with_alpha (old_not_loaded ? 1.0 : background_alpha);
1205 }1200 }
1206 }1201 }
12071202
1208 private void draw_entry_at_position (Cairo.Context c, UserEntry entry, double position)1203 private void draw_entry_at_position (Cairo.Context c, UserEntry entry,
1204 double position, bool in_box = false)
1209 {1205 {
1210 c.save ();1206 c.save ();
1211 c.translate (0, position * grid_size);1207 c.translate (0, position * grid_size);
@@ -1214,7 +1210,7 @@
1214 alpha = 1.0 + position / (n_above + 1);1210 alpha = 1.0 + position / (n_above + 1);
1215 else1211 else
1216 alpha = 1.0 - (position - 2) / (n_below + 1); 1212 alpha = 1.0 - (position - 2) / (n_below + 1);
1217 draw_entry (c, entry, alpha);1213 draw_entry (c, entry, alpha, in_box);
1218 c.restore ();1214 c.restore ();
1219 }1215 }
12201216
@@ -1231,26 +1227,45 @@
12311227
1232 c.translate (box_x, box_y);1228 c.translate (box_x, box_y);
12331229
1230 var border = 4;
1231
1234 var index = 0;1232 var index = 0;
1235 foreach (var entry in entries)1233 foreach (var entry in entries)
1236 {1234 {
1235 var position = index - scroll_location;
1236
1237 /* Draw entries above the box */1237 /* Draw entries above the box */
1238 var h_above = (double) (n_above + 1) * grid_size;1238 var h_above = (double) (n_above + 1) * grid_size;
1239 c.save ();1239 c.save ();
12401240
1241 c.rectangle (0, -h_above, box_width * grid_size, h_above);1241 c.rectangle (0, -h_above, box_width * grid_size, h_above);
1242 c.clip ();1242 c.clip ();
1243 draw_entry_at_position (c, entry, index - scroll_location);1243 draw_entry_at_position (c, entry, position);
12441244
1245 c.restore ();1245 c.restore ();
12461246
1247 /* Draw entries in the box */
1248 if (position > -1 && position < 1 && scroll_timer.is_running) {
1249 c.save ();
1250 c.translate (0, border);
1251 c.rectangle (0, border * 2, box_width * grid_size, box_height * grid_size - border * 5);
1252 c.clip ();
1253
1254 if (position <= 0) /* top of box, normal pace */
1255 draw_entry_at_position (c, entry, position, true);
1256 else /* bottom of box; pace must put across bottom halfway through animation */
1257 draw_entry_at_position (c, entry, position * box_height * 2, true);
1258
1259 c.restore ();
1260 }
1261
1247 /* Draw entries below the box */1262 /* Draw entries below the box */
1248 var h_below = (double) (n_below + 1) * grid_size;1263 var h_below = (double) (n_below + 1) * grid_size;
1249 c.save ();1264 c.save ();
12501265
1251 c.rectangle (0, box_height * grid_size, box_width * grid_size, h_below);1266 c.rectangle (0, box_height * grid_size, box_width * grid_size, h_below);
1252 c.clip ();1267 c.clip ();
1253 draw_entry_at_position (c, entry, index - scroll_location + 2);1268 draw_entry_at_position (c, entry, position + box_height - 1);
12541269
1255 c.restore ();1270 c.restore ();
12561271
@@ -1259,47 +1274,29 @@
12591274
1260 /* Draw box */1275 /* Draw box */
1261 c.save ();1276 c.save ();
1262 var border = 4;
1263 c.translate (-border, -border);1277 c.translate (-border, -border);
1264 c.set_source (box_pattern);1278 c.set_source (box_pattern);
1265 c.paint ();1279 c.paint ();
1266 c.restore ();1280 c.restore ();
12671281
1268 /* Selected item */1282 /* Selected item */
1269 if (selected_entry != null)1283 if (selected_entry != null && !scroll_timer.is_running)
1270 {1284 {
1271 int w, h;1285 var text_y = border;
1272 selected_entry.layout.get_pixel_size (out w, out h);1286
1273 var text_y = grid_size - (grid_size - border - h) / 4 - h;1287 c.save ();
12741288 c.rectangle (border, border, box_width * grid_size - border * 2, box_height * grid_size - border * 2);
1275 if (selected_entry.is_active)1289 c.clip ();
1276 {1290
1277 c.move_to (8, text_y + h / 2 + 0.5 - 4);1291 c.save ();
1278 c.rel_line_to (5, 4);1292 c.translate (0, text_y);
1279 c.rel_line_to (-5, 4);1293 draw_entry (c, selected_entry, 1.0);
1280 c.close_path ();1294 c.restore ();
1281 c.set_source_rgb (1.0, 1.0, 1.0);1295
1282 c.fill ();1296 c.restore();
1283 }
1284
1285 c.move_to (grid_size / 2, text_y);
1286
1287 var bw = (box_width - 1.1) * grid_size;
1288 if (w > bw)
1289 {
1290 var mask = new Cairo.Pattern.linear (0, 0, bw, 0);
1291 mask.add_color_stop_rgba (1.0 - 27.0 / bw, 1.0, 1.0, 1.0, 1.0);
1292 mask.add_color_stop_rgba (1.0 - 21.6 / bw, 1.0, 1.0, 1.0, 0.5);
1293 mask.add_color_stop_rgba (1.0, 1.0, 1.0, 1.0, 0.0);
1294 c.set_source (mask);
1295 }
1296 else
1297 c.set_source_rgba (1.0, 1.0, 1.0, 1.0);
1298
1299 Pango.cairo_show_layout (c, selected_entry.layout);
1300 }1297 }
13011298
1302 if (error != null || message != null)1299 if ((error != null || message != null) && !scroll_timer.is_running)
1303 {1300 {
1304 string text;1301 string text;
1305 if (error == null)1302 if (error == null)

Subscribers

People subscribed via source and target branches