4 using System
.Collections
;
9 public abstract class Category
: Container
{
14 protected Gtk
.HBox header
;
16 Gtk
.Button prev
, next
;
17 Gtk
.Expander headerExpander
;
18 int fewRows
, manyRows
, columns
;
20 bool extended
, expanded
;
23 public Category (Tiles
.TileGroupInfo info
, int columns
)
25 WidgetFlags
|= WidgetFlags
.NoWindow
;
27 header
= new Gtk
.HBox (false, 0);
29 headerExpander
= new Gtk
.Expander ("<big><b>" + GLib
.Markup
.EscapeText (info
.Name
) + "</b></big>");
30 ((Gtk
.Label
) headerExpander
.LabelWidget
).SetAlignment (0.0f
, 0.5f
);
31 headerExpander
.UseMarkup
= true;
32 headerExpander
.UseUnderline
= true;
33 headerExpander
.Show ();
34 header
.PackStart (headerExpander
, true, true, 0);
36 headerExpander
.Activated
+= OnActivated
;
38 scope
= Tiles
.Utils
.TileGroupToScopeType(info
.Group
);
40 position
= new Gtk
.Label ();
41 position
.ModifyFg (Gtk
.StateType
.Normal
, position
.Style
.Base (Gtk
.StateType
.Selected
));
42 header
.PackStart (position
, false, false, 0);
45 prev
= MakeButton (header
, Gtk
.Stock
.GoBack
, OnPrev
);
46 next
= MakeButton (header
, Gtk
.Stock
.GoForward
, OnNext
);
50 header
.SizeRequested
+= HeaderSizeRequested
;
52 tiles
= new SortedTileList (SortType
.Relevance
);
56 manyRows
= info
.Rows
* 2;
60 //headerExpander.Expanded = true;
64 private Gtk
.Button
MakeButton (Gtk
.HBox header
, string icon
, EventHandler handler
)
66 Gtk
.Button button
= new Gtk
.Button ();
67 Gtk
.Image img
= new Gtk
.Image (icon
, Gtk
.IconSize
.Button
);
69 button
.Relief
= Gtk
.ReliefStyle
.None
;
70 button
.Clicked
+= handler
;
72 header
.PackStart (button
, false, false, 0);
78 public bool Expanded
{
88 headerExpander
.Expanded
= expanded
;
92 protected int Columns
{
99 few
= fewRows
* columns
;
100 many
= manyRows
* columns
;
105 void HeaderSizeRequested (object obj
, Gtk
.SizeRequestedArgs args
)
107 Gtk
.Requisition req
= args
.Requisition
;
108 Gtk
.Requisition labelReq
= headerExpander
.ChildRequisition
;
110 req
.Height
= (int) (labelReq
.Height
* 1.5);
112 int icon_height
, icon_width
;
114 if (Gtk
.Icon
.SizeLookup (Gtk
.IconSize
.Button
, out icon_height
, out icon_width
) && req
.Height
< icon_height
* 1.5)
115 req
.Height
= (int) (icon_height
* 1.5);
117 args
.Requisition
= req
;
120 void UpdateButtons ()
122 if (tiles
.Count
<= FirstVisible
&& page
> 0) {
123 // The page we were viewing disappeared
127 prev
.Sensitive
= (page
!= 0);
128 next
.Sensitive
= (tiles
.Count
> LastVisible
+ 1);
130 if (tiles
.Count
> 0) {
131 if (FirstVisible
== 0 && LastVisible
+ 1 == tiles
.Count
)
132 position
.LabelProp
= String
.Format (Catalog
.GetPluralString ("{0} result", "{0} results", tiles
.Count
), tiles
.Count
);
134 position
.LabelProp
= String
.Format (Catalog
.GetString ("{0}-{1} of {2}"), FirstVisible
+ 1, LastVisible
+ 1, tiles
.Count
);
136 position
.LabelProp
= "";
139 protected override void OnAdded (Gtk
.Widget widget
)
142 widget
.ChildVisible
= false;
143 tiles
.Add ((Tiles
.Tile
)widget
);
144 widget
.Parent
= this;
149 protected override void OnRemoved (Gtk
.Widget widget
)
152 tiles
.Remove ((Tiles
.Tile
)widget
);
158 private Tiles
.Tile lastTarget
;
159 private bool hadFocus
;
164 foreach (Tiles
.Tile tile
in VisibleTiles
) {
165 if (tile
.HasFocus
|| lastTarget
== null) {
167 hadFocus
= tile
.HasFocus
;
169 tile
.ChildVisible
= false;
174 void ShowTiles (bool recenter
)
176 if (recenter
&& lastTarget
!= null) {
177 int index
= tiles
.IndexOf (lastTarget
);
178 if (hadFocus
|| page
> 0) {
182 page
= index
/ (manyRows
* columns
);
184 page
= ((index
- few
) / (manyRows
* columns
)) + 1;
188 foreach (Tiles
.Tile tile
in VisibleTiles
) {
189 tile
.ChildVisible
= true;
190 if (tile
== lastTarget
&& hadFocus
&& !tile
.HasFocus
)
198 private bool showingMany
{
200 // Show extra tiles on every page after the first, unless
201 // there are only two pages and the second one only has
202 // enough tiles to fit the "fewer" size.
203 return (page
> 0 && tiles
.Count
> 2 * few
) || extended
;
207 void OnPrev (object obj
, EventArgs args
)
212 OnActivated (obj
, args
);
217 void OnNext (object obj
, EventArgs args
)
222 OnActivated (obj
, args
);
227 protected void OnActivated (object obj
, EventArgs args
)
229 Expanded
= !Expanded
;
230 CategoryToggle (scope
);
233 public delegate void CategoryToggleDelegate (ScopeType scope
);
234 public event CategoryToggleDelegate CategoryToggle
;
236 protected int PageSize
{
238 return Math
.Min (showingMany
? many
: few
, tiles
.Count
);
242 protected int FirstVisible
{
249 return few
+ (page
- 1) * many
;
253 protected int LastVisible
{
255 return Math
.Min (FirstVisible
+ PageSize
, tiles
.Count
) - 1;
259 protected IList VisibleTiles
{
261 return tiles
.GetRange (FirstVisible
, LastVisible
- FirstVisible
+ 1);
265 public IEnumerable AllTiles
{
271 protected override void ForAll (bool include_internals
, Callback callback
)
273 foreach (Widget w
in (SortedTileList
)tiles
.Clone ())
275 if (include_internals
)
279 protected override bool OnExposeEvent (Gdk
.EventExpose evt
)
281 Rectangle headerRect
, bgRect
;
282 int headerHeight
= header
.Allocation
.Height
;
283 Gdk
.Color white
, bg
, mid
;
285 headerRect
= bgRect
= Allocation
;
286 headerRect
.Height
= headerHeight
;
287 bgRect
.Y
+= headerHeight
;
288 bgRect
.Height
-= headerHeight
;
290 GdkWindow
.DrawRectangle (Style
.BaseGC (State
), true, bgRect
);
292 white
= Style
.Base (State
);
293 bg
= Style
.Background (State
);
295 mid
= new Gdk
.Color ();
296 mid
.Red
= (ushort)((white
.Red
+ bg
.Red
) / 2);
297 mid
.Green
= (ushort)((white
.Green
+ bg
.Green
) / 2);
298 mid
.Blue
= (ushort)((white
.Blue
+ bg
.Blue
) / 2);
299 Style
.BaseGC (State
).RgbFgColor
= mid
;
300 GdkWindow
.DrawRectangle (Style
.BaseGC (State
), true, headerRect
);
301 Style
.BaseGC (State
).Foreground
= white
;
303 return base.OnExposeEvent (evt
);
308 while (tiles
.Count
> 0)
309 Remove (tiles
[tiles
.Count
- 1]);
314 return tiles
.Count
== 0;
324 public Search
.SortType Sort
{
332 public void Select (bool focus
, bool extended
)
336 this.extended
= extended
;
340 ((Gtk
.Widget
)VisibleTiles
[0]).GrabFocus ();