Merge lp:~mterry/unity-greeter/entry-arrow into lp:unity-greeter

Proposed by Michael Terry
Status: Merged
Approved by: Robert Ancell
Approved revision: 627
Merged at revision: 644
Proposed branch: lp:~mterry/unity-greeter/entry-arrow
Merge into: lp:unity-greeter
Diff against target: 265 lines (+149/-47)
1 file modified
src/dash-entry.vala (+149/-47)
To merge this branch: bzr merge lp:~mterry/unity-greeter/entry-arrow
Reviewer Review Type Date Requested Status
Unity Greeter Development Team Pending
Review via email: mp+130622@code.launchpad.net

Description of the change

Adjust size and mechanics of entry progression arrow to avoid using the entry icon API (which conflicts with the default GTK caps lock icon usage).

To post a comment you must log in.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'src/dash-entry.vala'
2--- src/dash-entry.vala 2012-10-01 16:18:18 +0000
3+++ src/dash-entry.vala 2012-10-19 18:34:19 +0000
4@@ -21,10 +21,6 @@
5 [CCode (cheader_filename = "gtk/gtk.h")]
6 extern bool gtk_style_context_lookup_color (Gtk.StyleContext ctx, string color_name, out Gdk.RGBA color);
7
8-/* Vala's vapi for gtk3 is broken for get_icon_area (it forgets the out keyword) */
9-[CCode (cheader_filename = "gtk/gtk.h")]
10-extern void gtk_entry_get_icon_area (Gtk.Entry entry, Gtk.EntryIconPosition icon_pos, out Gdk.Rectangle icon_area);
11-
12 public class DashEntry : Gtk.Entry, Fadable
13 {
14 public static string font = "Ubuntu 14";
15@@ -47,32 +43,59 @@
16 set_state_flags (Gtk.StateFlags.ACTIVE, false);
17 else
18 unset_state_flags (Gtk.StateFlags.ACTIVE);
19- update_arrow ();
20+ queue_draw ();
21 }
22 }
23
24 private static const string NO_BORDER_CLASS = "unity-greeter-no-border";
25
26 protected FadeTracker fade_tracker { get; protected set; }
27- private Gdk.Rectangle icon_area;
28+ private static Gdk.Window arrow_win;
29+ private static Gdk.Pixbuf arrow_pixbuf;
30
31 construct
32 {
33 fade_tracker = new FadeTracker (this);
34
35- notify["can-respond"].connect (update_arrow);
36- changed.connect (update_arrow);
37- icon_press.connect (icon_press_cb);
38+ notify["can-respond"].connect (queue_draw);
39+ button_press_event.connect (button_press_event_cb);
40+
41+ if (arrow_pixbuf == null)
42+ {
43+ var filename = Path.build_filename (Config.PKGDATADIR, "arrow_right.png");
44+ try
45+ {
46+ arrow_pixbuf = new Gdk.Pixbuf.from_file (filename);
47+ }
48+ catch (Error e)
49+ {
50+ debug ("Internal error loading arrow icon: %s", e.message);
51+ }
52+ }
53
54 override_font (Pango.FontDescription.from_string (font));
55
56+ var style_ctx = get_style_context ();
57+
58+ try
59+ {
60+ var padding_provider = new Gtk.CssProvider ();
61+ var css = "* {padding-right: %dpx;}".printf (get_arrow_size ());
62+ padding_provider.load_from_data (css, -1);
63+ style_ctx.add_provider (padding_provider,
64+ Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION);
65+ }
66+ catch (Error e)
67+ {
68+ debug ("Internal error loading padding style: %s", e.message);
69+ }
70+
71 // We add the styles and classes we need for normal operation of the
72 // spinner animation. These are always "on" and we just turn them off
73 // right before drawing our parent class's draw function. This is done
74 // opt-out like that rather than just turning the styles on when we
75 // need to draw the spinner because the animation doesn't work right
76 // otherwise. See the draw() function for how we turn it off.
77- var style_ctx = get_style_context ();
78 var no_border_provider = new Gtk.CssProvider ();
79 try
80 {
81@@ -112,27 +135,44 @@
82 /* Draw activity spinner if we need to */
83 if (did_respond)
84 draw_spinner (c);
85+ else if (get_text_length () > 0)
86+ draw_arrow (c);
87
88 return false;
89 }
90
91 private void draw_spinner (Cairo.Context c)
92 {
93- Gtk.Allocation allocation;
94- get_allocation (out allocation);
95- int spinner_side = allocation.height / 2;
96- int margin = (allocation.height - spinner_side) / 2;
97+ c.save ();
98
99 var style_ctx = get_style_context ();
100- style_ctx.render_activity (c,
101- allocation.width - spinner_side - margin,
102- margin,
103- spinner_side,
104- spinner_side);
105+ var arrow_size = get_arrow_size ();
106+ Gtk.cairo_transform_to_window (c, this, arrow_win);
107+ style_ctx.render_activity (c, 0, 0, arrow_size, arrow_size);
108+
109+ c.restore ();
110+ }
111+
112+ private void draw_arrow (Cairo.Context c)
113+ {
114+ if (arrow_pixbuf == null)
115+ return;
116+
117+ c.save ();
118+
119+ var arrow_size = get_arrow_size ();
120+ Gtk.cairo_transform_to_window (c, this, arrow_win);
121+ c.translate (arrow_size - arrow_pixbuf.get_width () - 1, 0); // right align
122+ Gdk.cairo_set_source_pixbuf (c, arrow_pixbuf, 0, 0);
123+
124+ c.paint ();
125+ c.restore ();
126 }
127
128 private void draw_prompt_text (Cairo.Context c)
129 {
130+ c.save ();
131+
132 /* Position text */
133 int x, y;
134 get_layout_offsets (out x, out y);
135@@ -149,6 +189,8 @@
136 var layout = create_pango_layout (constant_placeholder_text);
137 layout.set_font_description (Pango.FontDescription.from_string ("Ubuntu 13"));
138 Pango.cairo_show_layout (c, layout);
139+
140+ c.restore ();
141 }
142
143 public override void activate ()
144@@ -165,33 +207,93 @@
145 }
146 }
147
148- private void icon_press_cb ()
149- {
150- activate ();
151- }
152-
153- private void update_arrow ()
154- {
155- show_arrow (get_text_length () != 0);
156- }
157-
158- protected void show_arrow (bool visible)
159- {
160- if (visible && can_respond && !did_respond)
161- {
162- var file = File.new_for_path (Path.build_filename (Config.PKGDATADIR, "arrow_right.png", null));
163- var icon = new FileIcon (file);
164- set_icon_from_gicon (Gtk.EntryIconPosition.SECONDARY, icon);
165- set_icon_activatable (Gtk.EntryIconPosition.SECONDARY, true);
166-
167- /* Save icon area for later use by spinner. Save it here instead of
168- * calling it each draw because GtkEntry will return 0 width areas
169- * if we hide the icon. */
170- gtk_entry_get_icon_area (this, Gtk.EntryIconPosition.SECONDARY, out icon_area);
171- }
172- else
173- {
174- set_icon_from_gicon (Gtk.EntryIconPosition.SECONDARY, null);
175- }
176+ public bool button_press_event_cb (Gdk.EventButton event)
177+ {
178+ if (event.window == arrow_win && get_text_length () > 0)
179+ {
180+ activate ();
181+ return true;
182+ }
183+ else
184+ return false;
185+ }
186+
187+ private int get_arrow_size ()
188+ {
189+ // height is larger than width for the arrow, so we measure using that
190+ if (arrow_pixbuf != null)
191+ return arrow_pixbuf.get_height ();
192+ else
193+ return 20; // Shouldn't happen
194+ }
195+
196+ private void get_arrow_location (out int x, out int y)
197+ {
198+ var arrow_size = get_arrow_size ();
199+
200+ Gtk.Allocation allocation;
201+ get_allocation (out allocation);
202+
203+ // height is larger than width for the arrow, so we measure using that
204+ var margin = (allocation.height - arrow_size) / 2;
205+
206+ x = allocation.x + allocation.width - margin - arrow_size;
207+ y = allocation.y + margin;
208+ }
209+
210+ public override void size_allocate (Gtk.Allocation allocation)
211+ {
212+ base.size_allocate (allocation);
213+
214+ if (arrow_win == null)
215+ return;
216+
217+ int arrow_x, arrow_y;
218+ get_arrow_location (out arrow_x, out arrow_y);
219+ var arrow_size = get_arrow_size ();
220+
221+ arrow_win.move_resize (arrow_x, arrow_y, arrow_size, arrow_size);
222+ }
223+
224+ public override void realize ()
225+ {
226+ base.realize ();
227+
228+ var cursor = new Gdk.Cursor (Gdk.CursorType.LEFT_PTR);
229+ var attrs = Gdk.WindowAttr ();
230+ attrs.x = 0;
231+ attrs.y = 0;
232+ attrs.width = 1;
233+ attrs.height = 1;
234+ attrs.cursor = cursor;
235+ attrs.wclass = Gdk.WindowWindowClass.INPUT_ONLY;
236+ attrs.window_type = Gdk.WindowType.CHILD;
237+ attrs.event_mask = get_events () |
238+ Gdk.EventMask.BUTTON_PRESS_MASK;
239+
240+ arrow_win = new Gdk.Window (get_window (), attrs,
241+ Gdk.WindowAttributesType.X |
242+ Gdk.WindowAttributesType.Y |
243+ Gdk.WindowAttributesType.CURSOR);
244+ arrow_win.set_user_data (this);
245+ }
246+
247+ public override void unrealize ()
248+ {
249+ arrow_win.destroy ();
250+ arrow_win = null;
251+ base.unrealize ();
252+ }
253+
254+ public override void map ()
255+ {
256+ base.map ();
257+ arrow_win.show ();
258+ }
259+
260+ public override void unmap ()
261+ {
262+ arrow_win.hide ();
263+ base.unmap ();
264 }
265 }

Subscribers

People subscribed via source and target branches