21
21
[CCode (cheader_filename = "gtk/gtk.h")]
22
22
extern bool gtk_style_context_lookup_color (Gtk.StyleContext ctx, string color_name, out Gdk.RGBA color);
24
/* Vala's vapi for gtk3 is broken for get_icon_area (it forgets the out keyword) */
25
[CCode (cheader_filename = "gtk/gtk.h")]
26
extern void gtk_entry_get_icon_area (Gtk.Entry entry, Gtk.EntryIconPosition icon_pos, out Gdk.Rectangle icon_area);
28
24
public class DashEntry : Gtk.Entry, Fadable
30
26
public static string font = "Ubuntu 14";
47
43
set_state_flags (Gtk.StateFlags.ACTIVE, false);
49
45
unset_state_flags (Gtk.StateFlags.ACTIVE);
54
50
private static const string NO_BORDER_CLASS = "unity-greeter-no-border";
56
52
protected FadeTracker fade_tracker { get; protected set; }
57
private Gdk.Rectangle icon_area;
53
private Gdk.Window arrow_win;
54
private static Gdk.Pixbuf arrow_pixbuf;
61
58
fade_tracker = new FadeTracker (this);
63
notify["can-respond"].connect (update_arrow);
64
changed.connect (update_arrow);
65
icon_press.connect (icon_press_cb);
60
notify["can-respond"].connect (queue_draw);
61
button_press_event.connect (button_press_event_cb);
63
if (arrow_pixbuf == null)
65
var filename = Path.build_filename (Config.PKGDATADIR, "arrow_right.png");
68
arrow_pixbuf = new Gdk.Pixbuf.from_file (filename);
72
debug ("Internal error loading arrow icon: %s", e.message);
67
76
override_font (Pango.FontDescription.from_string (font));
78
var style_ctx = get_style_context ();
82
var padding_provider = new Gtk.CssProvider ();
83
var css = "* {padding-right: %dpx;}".printf (get_arrow_size ());
84
padding_provider.load_from_data (css, -1);
85
style_ctx.add_provider (padding_provider,
86
Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION);
90
debug ("Internal error loading padding style: %s", e.message);
69
93
// We add the styles and classes we need for normal operation of the
70
94
// spinner animation. These are always "on" and we just turn them off
71
95
// right before drawing our parent class's draw function. This is done
72
96
// opt-out like that rather than just turning the styles on when we
73
97
// need to draw the spinner because the animation doesn't work right
74
98
// otherwise. See the draw() function for how we turn it off.
75
var style_ctx = get_style_context ();
76
99
var no_border_provider = new Gtk.CssProvider ();
112
135
/* Draw activity spinner if we need to */
114
137
draw_spinner (c);
138
else if (can_respond && get_text_length () > 0)
119
144
private void draw_spinner (Cairo.Context c)
121
Gtk.Allocation allocation;
122
get_allocation (out allocation);
123
int spinner_side = allocation.height / 2;
124
int margin = (allocation.height - spinner_side) / 2;
126
148
var style_ctx = get_style_context ();
127
style_ctx.render_activity (c,
128
allocation.width - spinner_side - margin,
149
var arrow_size = get_arrow_size ();
150
Gtk.cairo_transform_to_window (c, this, arrow_win);
151
style_ctx.render_activity (c, 0, 0, arrow_size, arrow_size);
156
private void draw_arrow (Cairo.Context c)
158
if (arrow_pixbuf == null)
163
var arrow_size = get_arrow_size ();
164
Gtk.cairo_transform_to_window (c, this, arrow_win);
165
c.translate (arrow_size - arrow_pixbuf.get_width () - 1, 0); // right align
166
Gdk.cairo_set_source_pixbuf (c, arrow_pixbuf, 0, 0);
134
172
private void draw_prompt_text (Cairo.Context c)
136
176
/* Position text */
138
178
get_layout_offsets (out x, out y);
168
private void icon_press_cb ()
173
private void update_arrow ()
175
show_arrow (get_text_length () != 0);
178
protected void show_arrow (bool visible)
180
if (visible && can_respond && !did_respond)
182
var file = File.new_for_path (Path.build_filename (Config.PKGDATADIR, "arrow_right.png", null));
183
var icon = new FileIcon (file);
184
set_icon_from_gicon (Gtk.EntryIconPosition.SECONDARY, icon);
185
set_icon_activatable (Gtk.EntryIconPosition.SECONDARY, true);
187
/* Save icon area for later use by spinner. Save it here instead of
188
* calling it each draw because GtkEntry will return 0 width areas
189
* if we hide the icon. */
190
gtk_entry_get_icon_area (this, Gtk.EntryIconPosition.SECONDARY, out icon_area);
194
set_icon_from_gicon (Gtk.EntryIconPosition.SECONDARY, null);
210
public bool button_press_event_cb (Gdk.EventButton event)
212
if (event.window == arrow_win && get_text_length () > 0)
221
private int get_arrow_size ()
223
// height is larger than width for the arrow, so we measure using that
224
if (arrow_pixbuf != null)
225
return arrow_pixbuf.get_height ();
227
return 20; // Shouldn't happen
230
private void get_arrow_location (out int x, out int y)
232
var arrow_size = get_arrow_size ();
234
Gtk.Allocation allocation;
235
get_allocation (out allocation);
237
// height is larger than width for the arrow, so we measure using that
238
var margin = (allocation.height - arrow_size) / 2;
240
x = allocation.x + allocation.width - margin - arrow_size;
241
y = allocation.y + margin;
244
public override void size_allocate (Gtk.Allocation allocation)
246
base.size_allocate (allocation);
248
if (arrow_win == null)
251
int arrow_x, arrow_y;
252
get_arrow_location (out arrow_x, out arrow_y);
253
var arrow_size = get_arrow_size ();
255
arrow_win.move_resize (arrow_x, arrow_y, arrow_size, arrow_size);
258
public override void realize ()
262
var cursor = new Gdk.Cursor (Gdk.CursorType.LEFT_PTR);
263
var attrs = Gdk.WindowAttr ();
268
attrs.cursor = cursor;
269
attrs.wclass = Gdk.WindowWindowClass.INPUT_ONLY;
270
attrs.window_type = Gdk.WindowType.CHILD;
271
attrs.event_mask = get_events () |
272
Gdk.EventMask.BUTTON_PRESS_MASK;
274
arrow_win = new Gdk.Window (get_window (), attrs,
275
Gdk.WindowAttributesType.X |
276
Gdk.WindowAttributesType.Y |
277
Gdk.WindowAttributesType.CURSOR);
279
arrow_win.set_user_data (this);
282
public override void unrealize ()
284
if (arrow_win != null)
286
arrow_win.destroy ();
292
public override void map ()
295
if (arrow_win != null)
299
public override void unmap ()
301
if (arrow_win != null)