~do-win/do/test-paths

« back to all changes in this revision

Viewing changes to Do/src/Do.UI/SearchEntry.cs

  • Committer: Hardeep S
  • Date: 2009-06-23 05:57:47 UTC
  • Revision ID: ootz0rz@gmail.com-20090623055747-3srobsuq3q8wbn81
initial adding of Do core stuff

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
//
 
2
// SearchEntry.cs
 
3
//
 
4
// Author:
 
5
//   Aaron Bockover <abockover@novell.com>
 
6
//   Gabriel Burt <gburt@novell.com>
 
7
//
 
8
// Copyright (C) 2007 Novell, Inc.
 
9
//
 
10
// Permission is hereby granted, free of charge, to any person obtaining
 
11
// a copy of this software and associated documentation files (the
 
12
// "Software"), to deal in the Software without restriction, including
 
13
// without limitation the rights to use, copy, modify, merge, publish,
 
14
// distribute, sublicense, and/or sell copies of the Software, and to
 
15
// permit persons to whom the Software is furnished to do so, subject to
 
16
// the following conditions:
 
17
//
 
18
// The above copyright notice and this permission notice shall be
 
19
// included in all copies or substantial portions of the Software.
 
20
//
 
21
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 
22
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 
23
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 
24
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
 
25
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
 
26
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 
27
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
28
//
 
29
 
 
30
using System;
 
31
using Gtk;
 
32
 
 
33
namespace Do.UI
 
34
{
 
35
    public class SearchEntry : EventBox
 
36
    {
 
37
        private HBox box;
 
38
        private Entry entry;
 
39
        private HoverImageButton clear_button;
 
40
 
 
41
        private uint changed_timeout_id = 0;
 
42
        
 
43
        private string empty_message;
 
44
        private bool ready = false;
 
45
 
 
46
        private event EventHandler entry_changed;
 
47
 
 
48
        public event EventHandler Changed {
 
49
            add { entry_changed += value; }
 
50
            remove { entry_changed -= value; }
 
51
        }
 
52
 
 
53
        public event EventHandler Activated {
 
54
            add { entry.Activated += value; }
 
55
            remove { entry.Activated -= value; }
 
56
        }
 
57
 
 
58
        public SearchEntry()
 
59
        {
 
60
            AppPaintable = true;
 
61
 
 
62
            BuildWidget();
 
63
            
 
64
            NoShowAll = true;
 
65
        }
 
66
            
 
67
        private void BuildWidget()
 
68
        {
 
69
            box = new HBox();
 
70
            entry = new FramelessEntry(this);
 
71
                        clear_button = new HoverImageButton(IconSize.Menu, new string [] { "edit-clear", Stock.Clear });
 
72
 
 
73
                        box.PackStart(entry, true, true, 0);
 
74
            box.PackStart(clear_button, false, false, 0);
 
75
 
 
76
            Add(box);
 
77
            box.ShowAll();
 
78
 
 
79
            entry.StyleSet += OnInnerEntryStyleSet;
 
80
            entry.StateChanged += OnInnerEntryStateChanged;
 
81
            entry.FocusInEvent += OnInnerEntryFocusEvent;
 
82
            entry.FocusOutEvent += OnInnerEntryFocusEvent;
 
83
            entry.Changed += OnInnerEntryChanged;
 
84
 
 
85
            clear_button.Image.Xpad = 2;
 
86
            clear_button.CanFocus = false;
 
87
 
 
88
            clear_button.ButtonReleaseEvent += OnButtonReleaseEvent;
 
89
            clear_button.Clicked += OnClearButtonClicked;
 
90
 
 
91
            clear_button.Visible = false;
 
92
        }
 
93
 
 
94
        private void ShowHideButtons()
 
95
        {
 
96
            clear_button.Visible = entry.Text.Length > 0;
 
97
        }
 
98
 
 
99
        private void OnInnerEntryChanged(object o, EventArgs args)
 
100
        {
 
101
            ShowHideButtons();
 
102
 
 
103
            if(changed_timeout_id > 0) {
 
104
                GLib.Source.Remove(changed_timeout_id);
 
105
            }
 
106
 
 
107
            if (Ready)
 
108
                changed_timeout_id = GLib.Timeout.Add(25, OnChangedTimeout);
 
109
        }
 
110
 
 
111
        private bool OnChangedTimeout()
 
112
        {
 
113
            OnChanged();
 
114
            return false;
 
115
        }
 
116
 
 
117
        private void UpdateStyle ()
 
118
        {
 
119
            Gdk.Color color = entry.Style.Base (entry.State);
 
120
            clear_button.ModifyBg (entry.State, color);
 
121
            
 
122
            box.BorderWidth = (uint)entry.Style.XThickness;
 
123
        }
 
124
        
 
125
        private void OnInnerEntryStyleSet (object o, StyleSetArgs args)
 
126
        {
 
127
            UpdateStyle ();
 
128
        }
 
129
        
 
130
        private void OnInnerEntryStateChanged (object o, EventArgs args)
 
131
        {
 
132
            UpdateStyle ();
 
133
        }
 
134
        
 
135
        private void OnInnerEntryFocusEvent(object o, EventArgs args)
 
136
        {
 
137
            QueueDraw();
 
138
        }
 
139
 
 
140
        private void OnButtonReleaseEvent(object o, ButtonReleaseEventArgs args)
 
141
        {
 
142
            if(args.Event.Button != 1) {
 
143
                return;
 
144
            }
 
145
 
 
146
            entry.HasFocus = true;
 
147
        }
 
148
 
 
149
        private void OnClearButtonClicked(object o, EventArgs args)
 
150
        {
 
151
            entry.Text = String.Empty;
 
152
        }
 
153
 
 
154
        protected override bool OnExposeEvent(Gdk.EventExpose evnt)
 
155
        {
 
156
            PropagateExpose(Child, evnt);
 
157
            Style.PaintShadow(entry.Style, GdkWindow, StateType.Normal, 
 
158
                ShadowType.In, evnt.Area, entry, "entry",
 
159
                0, 0, Allocation.Width, Allocation.Height); 
 
160
            return true;
 
161
        }
 
162
 
 
163
        protected override void OnShown()
 
164
        {
 
165
            base.OnShown();
 
166
            ShowHideButtons();
 
167
        }
 
168
 
 
169
        protected virtual void OnChanged()
 
170
        {
 
171
            if(!Ready) {
 
172
                return;
 
173
            }
 
174
 
 
175
            EventHandler handler = entry_changed;
 
176
            if(handler != null) {
 
177
                handler(this, EventArgs.Empty);
 
178
            }
 
179
        }
 
180
 
 
181
        public string EmptyMessage {
 
182
            get { return empty_message; }
 
183
            set {
 
184
                empty_message = value;
 
185
                entry.QueueDraw();
 
186
            }
 
187
        }
 
188
 
 
189
        public string Query {
 
190
            get { return entry.Text.Trim(); }
 
191
            set { entry.Text = value.Trim(); }
 
192
        }
 
193
 
 
194
        public bool IsQueryAvailable {
 
195
            get { return Query != null && Query != String.Empty; }
 
196
        }
 
197
 
 
198
        public bool Ready {
 
199
            get { return ready; }
 
200
            set { ready = value; }
 
201
        }
 
202
        
 
203
        public new bool HasFocus {
 
204
            get { return entry.HasFocus; }
 
205
            set { entry.HasFocus = true; }
 
206
        }
 
207
 
 
208
        
 
209
        public Entry InnerEntry {
 
210
            get { return entry; }
 
211
        }
 
212
 
 
213
        private class FramelessEntry : Entry
 
214
        {
 
215
            private Gdk.Window text_window;
 
216
            private SearchEntry parent;
 
217
            private Pango.Layout layout;
 
218
            private Gdk.GC text_gc;
 
219
 
 
220
            public FramelessEntry(SearchEntry parent) : base()
 
221
            {
 
222
                this.parent = parent;
 
223
                HasFrame = false;
 
224
                
 
225
                layout = new Pango.Layout(PangoContext);
 
226
                layout.FontDescription = PangoContext.FontDescription.Copy();
 
227
 
 
228
                parent.StyleSet += OnParentStyleSet;
 
229
                WidthChars = 1;
 
230
            }
 
231
 
 
232
            private void OnParentStyleSet(object o, EventArgs args)
 
233
            {
 
234
                RefreshGC();
 
235
                QueueDraw();
 
236
            }
 
237
 
 
238
            private void RefreshGC()
 
239
            {
 
240
                if(text_window == null) {
 
241
                    return;
 
242
                }
 
243
 
 
244
                text_gc = new Gdk.GC(text_window);
 
245
                text_gc.Copy(Style.TextGC(StateType.Normal));
 
246
                //Gdk.Color color_a = parent.Style.Base(StateType.Normal);
 
247
                //Gdk.Color color_b = parent.Style.Text(StateType.Normal);
 
248
                                text_gc.RgbFgColor = new Gdk.Color (0,0,0);
 
249
                //text_gc.RgbFgColor = Hyena.Gui.GtkUtilities.ColorBlend(color_a, color_b);
 
250
            }
 
251
                        
 
252
            protected override bool OnExposeEvent(Gdk.EventExpose evnt)
 
253
            {
 
254
                // The Entry's GdkWindow is the top level window onto which
 
255
                // the frame is drawn; the actual text entry is drawn into a
 
256
                // separate window, so we can ensure that for themes that don't
 
257
                // respect HasFrame, we never ever allow the base frame drawing
 
258
                // to happen
 
259
                if(evnt.Window == GdkWindow) {
 
260
                    return true;
 
261
                }
 
262
 
 
263
                bool ret = base.OnExposeEvent(evnt);
 
264
 
 
265
                if(text_gc == null || evnt.Window != text_window) {
 
266
                    text_window = evnt.Window;
 
267
                    RefreshGC();
 
268
                }
 
269
 
 
270
                if(Text.Length > 0 || HasFocus || parent.EmptyMessage == null) {
 
271
                    return ret;
 
272
                }
 
273
 
 
274
                int width, height;
 
275
                layout.SetMarkup(parent.EmptyMessage);
 
276
                layout.GetPixelSize(out width, out height);
 
277
                evnt.Window.DrawLayout(text_gc, 2, (SizeRequest().Height - height) / 2, layout);
 
278
 
 
279
                return ret;
 
280
            }
 
281
        }
 
282
    }
 
283
}