Dont add null mimetypes. Fixes bgo# 337431. The patch hasnt been officially accepted...
[beagle.git] / search / Category.cs
blob0a0ef8f12e76dfffe91b0d5ca9bc93373d387bc4
1 using Gtk;
2 using Gdk;
3 using System;
4 using System.Collections;
5 using Mono.Unix;
7 namespace Search {
9 public abstract class Category : Container {
11 SortedTileList tiles;
12 int page;
14 protected Gtk.HBox header;
15 Gtk.Label headerLabel, position;
16 Gtk.Button prev, next;
17 int fewRows, manyRows, columns;
18 int few, many;
19 bool expanded;
21 public Category (string name, int rows, int columns)
23 WidgetFlags |= WidgetFlags.NoWindow;
25 header = new Gtk.HBox (false, 0);
27 headerLabel = new Gtk.Label ();
28 headerLabel.Markup = "<big><b>" + GLib.Markup.EscapeText (name) + "</b></big>";
29 headerLabel.SetAlignment (0.0f, 0.5f);
30 headerLabel.Show ();
31 header.PackStart (headerLabel, true, true, 0);
33 position = new Gtk.Label ();
34 position.ModifyFg (Gtk.StateType.Normal, position.Style.Base (Gtk.StateType.Selected));
35 header.PackStart (position, false, false, 0);
36 position.Show ();
38 prev = MakeButton (header, Gtk.Stock.GoBack, OnPrev);
39 next = MakeButton (header, Gtk.Stock.GoForward, OnNext);
41 header.Show ();
42 header.Parent = this;
43 header.SizeRequested += HeaderSizeRequested;
45 tiles = new SortedTileList (SortType.Relevance);
46 page = 0;
48 fewRows = rows;
49 manyRows = rows * 2;
50 Columns = columns;
52 UpdateButtons ();
55 private Gtk.Button MakeButton (Gtk.HBox header, string icon, EventHandler handler)
57 Gtk.Button button = new Gtk.Button ();
58 Gtk.Image img = new Gtk.Image (icon, Gtk.IconSize.Button);
59 button.Add (img);
60 button.Relief = Gtk.ReliefStyle.None;
61 button.Clicked += handler;
63 header.PackStart (button, false, false, 0);
64 button.ShowAll ();
66 return button;
69 protected int Columns {
70 get {
71 return columns;
73 set {
74 HideTiles ();
75 columns = value;
76 few = fewRows * columns;
77 many = manyRows * columns;
78 ShowTiles (true);
82 void HeaderSizeRequested (object obj, Gtk.SizeRequestedArgs args)
84 Gtk.Requisition req = args.Requisition;
85 Gtk.Requisition labelReq = headerLabel.ChildRequisition;
87 req.Height = (int) (labelReq.Height * 1.5);
89 int icon_height, icon_width;
91 if (Gtk.Icon.SizeLookup (Gtk.IconSize.Button, out icon_height, out icon_width) && req.Height < icon_height * 1.5)
92 req.Height = (int) (icon_height * 1.5);
94 args.Requisition = req;
97 void UpdateButtons ()
99 if (tiles.Count <= FirstVisible && page > 0) {
100 // The page we were viewing disappeared
101 page--;
104 prev.Sensitive = (page != 0);
105 next.Sensitive = (tiles.Count > LastVisible + 1);
107 if (tiles.Count > 0) {
108 if (FirstVisible == 0 && LastVisible + 1 == tiles.Count)
109 position.LabelProp = String.Format (Catalog.GetPluralString ("{0} result", "{0} results", tiles.Count), tiles.Count);
110 else
111 position.LabelProp = String.Format (Catalog.GetString ("{0}-{1} of {2}"), FirstVisible + 1, LastVisible + 1, tiles.Count);
112 } else
113 position.LabelProp = "";
116 protected override void OnAdded (Gtk.Widget widget)
118 HideTiles ();
119 widget.ChildVisible = false;
120 tiles.Add ((Tiles.Tile)widget);
121 widget.Parent = this;
122 ShowTiles (true);
125 protected override void OnRemoved (Gtk.Widget widget)
127 HideTiles ();
128 tiles.Remove ((Tiles.Tile)widget);
129 widget.Unparent ();
130 ShowTiles (true);
133 private Tiles.Tile lastTarget;
134 private bool hadFocus;
136 void HideTiles ()
138 lastTarget = null;
139 foreach (Tiles.Tile tile in VisibleTiles) {
140 if (tile.HasFocus || lastTarget == null) {
141 lastTarget = tile;
142 hadFocus = tile.HasFocus;
144 tile.ChildVisible = false;
146 QueueResize ();
149 void ShowTiles (bool recenter)
151 if (recenter && lastTarget != null) {
152 int index = tiles.IndexOf (lastTarget);
153 if (hadFocus || page > 0) {
154 if (index < few)
155 page = 0;
156 else if (expanded)
157 page = index / (manyRows * columns);
158 else
159 page = ((index - few) / (manyRows * columns)) + 1;
163 foreach (Tiles.Tile tile in VisibleTiles) {
164 tile.ChildVisible = true;
165 if (tile == lastTarget && hadFocus && !tile.HasFocus)
166 tile.GrabFocus ();
169 UpdateButtons ();
170 QueueResize ();
173 private bool showingMany {
174 get {
175 // Show extra tiles on every page after the first, unless
176 // there are only two pages and the second one only has
177 // enough tiles to fit the "fewer" size.
178 return (page > 0 && tiles.Count > 2 * few) || expanded;
182 void OnPrev (object obj, EventArgs args)
184 HideTiles ();
185 page--;
186 ShowTiles (false);
189 void OnNext (object obj, EventArgs args)
191 HideTiles ();
192 page++;
193 ShowTiles (false);
196 protected int PageSize {
197 get {
198 return Math.Min (showingMany ? many : few, tiles.Count);
202 protected int FirstVisible {
203 get {
204 if (page == 0)
205 return 0;
206 else if (expanded)
207 return page * many;
208 else
209 return few + (page - 1) * many;
213 protected int LastVisible {
214 get {
215 return Math.Min (FirstVisible + PageSize, tiles.Count) - 1;
219 protected IList VisibleTiles {
220 get {
221 return tiles.GetRange (FirstVisible, LastVisible - FirstVisible + 1);
225 public IEnumerable AllTiles {
226 get {
227 return tiles;
231 protected override void ForAll (bool include_internals, Callback callback)
233 foreach (Widget w in (SortedTileList)tiles.Clone ())
234 callback (w);
235 if (include_internals)
236 callback (header);
239 protected override bool OnExposeEvent (Gdk.EventExpose evt)
241 Rectangle headerRect, bgRect;
242 int headerHeight = header.Allocation.Height;
243 Gdk.Color white, bg, mid;
245 headerRect = bgRect = Allocation;
246 headerRect.Height = headerHeight;
247 bgRect.Y += headerHeight;
248 bgRect.Height -= headerHeight;
250 GdkWindow.DrawRectangle (Style.BaseGC (State), true, bgRect);
252 white = Style.Base (State);
253 bg = Style.Background (State);
255 mid = new Gdk.Color ();
256 mid.Red = (ushort)((white.Red + bg.Red) / 2);
257 mid.Green = (ushort)((white.Green + bg.Green) / 2);
258 mid.Blue = (ushort)((white.Blue + bg.Blue) / 2);
259 Style.BaseGC (State).RgbFgColor = mid;
260 GdkWindow.DrawRectangle (Style.BaseGC (State), true, headerRect);
261 Style.BaseGC (State).Foreground = white;
263 return base.OnExposeEvent (evt);
266 public void Clear ()
268 while (tiles.Count > 0)
269 Remove (tiles[tiles.Count - 1]);
272 public bool Empty {
273 get {
274 return tiles.Count == 0;
278 public int Count {
279 get {
280 return tiles.Count;
284 public Search.SortType Sort {
285 set {
286 HideTiles ();
287 tiles.Sort = value;
288 ShowTiles (true);
292 public void Select (bool focus, bool expanded)
294 if (expanded) {
295 HideTiles ();
296 this.expanded = expanded;
297 ShowTiles (false);
299 if (focus && !Empty)
300 ((Gtk.Widget)VisibleTiles[0]).GrabFocus ();