~ubuntu-branches/ubuntu/utopic/unity-greeter/utopic

« back to all changes in this revision

Viewing changes to src/dash-entry.vala

  • Committer: Package Import Robot
  • Author(s): Michael Terry
  • Date: 2013-01-04 10:37:29 UTC
  • mto: This revision was merged to the branch mainline in revision 51.
  • Revision ID: package-import@ubuntu.com-20130104103729-ydal31wfuhirb8zb
Tags: upstream-13.04.0
ImportĀ upstreamĀ versionĀ 13.04.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
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);
23
23
 
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);
27
 
 
28
24
public class DashEntry : Gtk.Entry, Fadable
29
25
{
30
26
    public static string font = "Ubuntu 14";
47
43
                set_state_flags (Gtk.StateFlags.ACTIVE, false);
48
44
            else
49
45
                unset_state_flags (Gtk.StateFlags.ACTIVE);
50
 
            update_arrow ();
 
46
            queue_draw ();
51
47
        }
52
48
    }
53
49
 
54
50
    private static const string NO_BORDER_CLASS = "unity-greeter-no-border";
55
51
 
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;
58
55
 
59
56
    construct
60
57
    {
61
58
        fade_tracker = new FadeTracker (this);
62
59
 
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);
 
62
 
 
63
        if (arrow_pixbuf == null)
 
64
        {
 
65
            var filename = Path.build_filename (Config.PKGDATADIR, "arrow_right.png");
 
66
            try
 
67
            {
 
68
                arrow_pixbuf = new Gdk.Pixbuf.from_file (filename);
 
69
            }
 
70
            catch (Error e)
 
71
            {
 
72
                debug ("Internal error loading arrow icon: %s", e.message);
 
73
            }
 
74
        }
66
75
 
67
76
        override_font (Pango.FontDescription.from_string (font));
68
77
 
 
78
        var style_ctx = get_style_context ();
 
79
 
 
80
        try
 
81
        {
 
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);
 
87
        }
 
88
        catch (Error e)
 
89
        {
 
90
            debug ("Internal error loading padding style: %s", e.message);
 
91
        }
 
92
 
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 ();
77
100
        try
78
101
        {
112
135
        /* Draw activity spinner if we need to */
113
136
        if (did_respond)
114
137
            draw_spinner (c);
 
138
        else if (can_respond && get_text_length () > 0)
 
139
            draw_arrow (c);
115
140
 
116
141
        return false;
117
142
    }
118
143
 
119
144
    private void draw_spinner (Cairo.Context c)
120
145
    {
121
 
        Gtk.Allocation allocation;
122
 
        get_allocation (out allocation);
123
 
        int spinner_side = allocation.height / 2;
124
 
        int margin = (allocation.height - spinner_side) / 2;
 
146
        c.save ();
125
147
 
126
148
        var style_ctx = get_style_context ();
127
 
        style_ctx.render_activity (c,
128
 
                                   allocation.width - spinner_side - margin,
129
 
                                   margin,
130
 
                                   spinner_side,
131
 
                                   spinner_side);
 
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);
 
152
 
 
153
        c.restore ();
 
154
    }
 
155
 
 
156
    private void draw_arrow (Cairo.Context c)
 
157
    {
 
158
        if (arrow_pixbuf == null)
 
159
            return;
 
160
 
 
161
        c.save ();
 
162
 
 
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);
 
167
 
 
168
        c.paint ();
 
169
        c.restore ();
132
170
    }
133
171
 
134
172
    private void draw_prompt_text (Cairo.Context c)
135
173
    {
 
174
        c.save ();
 
175
 
136
176
        /* Position text */
137
177
        int x, y;
138
178
        get_layout_offsets (out x, out y);
149
189
        var layout = create_pango_layout (constant_placeholder_text);
150
190
        layout.set_font_description (Pango.FontDescription.from_string ("Ubuntu 13"));
151
191
        Pango.cairo_show_layout (c, layout);
 
192
 
 
193
        c.restore ();
152
194
    }
153
195
 
154
196
    public override void activate ()
165
207
        }
166
208
    }
167
209
 
168
 
    private void icon_press_cb ()
169
 
    {
170
 
        activate ();
171
 
    }
172
 
 
173
 
    private void update_arrow ()
174
 
    {
175
 
        show_arrow (get_text_length () != 0);
176
 
    }
177
 
 
178
 
    protected void show_arrow (bool visible)
179
 
    {
180
 
        if (visible && can_respond && !did_respond)
181
 
        {
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);
186
 
 
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);
191
 
        }
192
 
        else
193
 
        {
194
 
            set_icon_from_gicon (Gtk.EntryIconPosition.SECONDARY, null);
195
 
        }
 
210
    public bool button_press_event_cb (Gdk.EventButton event)
 
211
    {
 
212
        if (event.window == arrow_win && get_text_length () > 0)
 
213
        {
 
214
            activate ();
 
215
            return true;
 
216
        }
 
217
        else
 
218
            return false;
 
219
    }
 
220
 
 
221
    private int get_arrow_size ()
 
222
    {
 
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 ();
 
226
        else
 
227
            return 20; // Shouldn't happen
 
228
    }
 
229
 
 
230
    private void get_arrow_location (out int x, out int y)
 
231
    {
 
232
        var arrow_size = get_arrow_size ();
 
233
 
 
234
        Gtk.Allocation allocation;
 
235
        get_allocation (out allocation);
 
236
 
 
237
        // height is larger than width for the arrow, so we measure using that
 
238
        var margin = (allocation.height - arrow_size) / 2;
 
239
 
 
240
        x = allocation.x + allocation.width - margin - arrow_size;
 
241
        y = allocation.y + margin;
 
242
    }
 
243
 
 
244
    public override void size_allocate (Gtk.Allocation allocation)
 
245
    {
 
246
        base.size_allocate (allocation);
 
247
 
 
248
        if (arrow_win == null)
 
249
            return;
 
250
 
 
251
        int arrow_x, arrow_y;
 
252
        get_arrow_location (out arrow_x, out arrow_y);
 
253
        var arrow_size = get_arrow_size ();
 
254
 
 
255
        arrow_win.move_resize (arrow_x, arrow_y, arrow_size, arrow_size);
 
256
    }
 
257
 
 
258
    public override void realize ()
 
259
    {
 
260
        base.realize ();
 
261
 
 
262
        var cursor = new Gdk.Cursor (Gdk.CursorType.LEFT_PTR);
 
263
        var attrs = Gdk.WindowAttr ();
 
264
        attrs.x = 0;
 
265
        attrs.y = 0;
 
266
        attrs.width = 1;
 
267
        attrs.height = 1;
 
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;
 
273
 
 
274
        arrow_win = new Gdk.Window (get_window (), attrs,
 
275
                                    Gdk.WindowAttributesType.X |
 
276
                                    Gdk.WindowAttributesType.Y |
 
277
                                    Gdk.WindowAttributesType.CURSOR);
 
278
        arrow_win.ref ();
 
279
        arrow_win.set_user_data (this);
 
280
    }
 
281
 
 
282
    public override void unrealize ()
 
283
    {
 
284
        if (arrow_win != null)
 
285
        {
 
286
            arrow_win.destroy ();
 
287
            arrow_win = null;
 
288
        }
 
289
        base.unrealize ();
 
290
    }
 
291
 
 
292
    public override void map ()
 
293
    {
 
294
        base.map ();
 
295
        if (arrow_win != null)
 
296
            arrow_win.show ();
 
297
    }
 
298
 
 
299
    public override void unmap ()
 
300
    {
 
301
        if (arrow_win != null)
 
302
            arrow_win.hide ();
 
303
        base.unmap ();
196
304
    }
197
305
}