You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
373 lines
9.3 KiB
373 lines
9.3 KiB
From 7cfcb26cd31f43ad93d32d3354787e6c2915b5e3 Mon Sep 17 00:00:00 2001
|
|
From: Chris Rivera <crivera@novell.com>
|
|
Date: Tue, 26 May 2009 21:07:24 +0000
|
|
Subject: Grow/shrink the number beagle-search results based on window size
|
|
|
|
Rework the size requsitioning to always take all available window
|
|
space for results, and to dynamically grow and shrink based on the
|
|
size of the window. Fixes bgo #582354 and #328440.
|
|
---
|
|
diff --git a/beagle/search/Beagle.Search/Category.cs b/beagle/search/Beagle.Search/Category.cs
|
|
index 3a920ab..06e8724 100644
|
|
--- a/beagle/search/Beagle.Search/Category.cs
|
|
+++ b/beagle/search/Beagle.Search/Category.cs
|
|
@@ -18,17 +18,14 @@ namespace Beagle.Search {
|
|
|
|
public abstract class Category : Container {
|
|
|
|
- private SortedTileList tiles = null;
|
|
- private int page = 0;
|
|
-
|
|
protected Gtk.HBox header;
|
|
+ private SortedTileList tiles;
|
|
private Gtk.Label position;
|
|
private Gtk.Button prev, next;
|
|
private Gtk.Expander headerExpander;
|
|
- private int fewRows, manyRows, columns;
|
|
- private int few, many;
|
|
private bool extended, expanded;
|
|
private ScopeType scope;
|
|
+ private int columns, tileIndex, tileHeight;
|
|
|
|
public Category (Tiles.TileGroupInfo info, int columns)
|
|
{
|
|
@@ -60,14 +57,9 @@ namespace Beagle.Search {
|
|
header.SizeRequested += HeaderSizeRequested;
|
|
|
|
tiles = new SortedTileList (Beagle.Search.SortType.Relevance);
|
|
- page = 0;
|
|
-
|
|
- fewRows = info.Rows;
|
|
- manyRows = info.Rows * 2;
|
|
Columns = columns;
|
|
|
|
UpdateButtons ();
|
|
- //headerExpander.Expanded = true;
|
|
Expanded = true;
|
|
}
|
|
|
|
@@ -91,7 +83,7 @@ namespace Beagle.Search {
|
|
expanded = value;
|
|
|
|
if (expanded)
|
|
- ShowTiles (false);
|
|
+ ShowTiles ();
|
|
else
|
|
HideTiles ();
|
|
|
|
@@ -103,12 +95,10 @@ namespace Beagle.Search {
|
|
get { return columns; }
|
|
set {
|
|
HideTiles ();
|
|
-
|
|
columns = value;
|
|
- few = fewRows * columns;
|
|
- many = manyRows * columns;
|
|
|
|
- ShowTiles (true);
|
|
+ if (Expanded)
|
|
+ ShowTiles ();
|
|
}
|
|
}
|
|
|
|
@@ -127,14 +117,9 @@ namespace Beagle.Search {
|
|
args.Requisition = req;
|
|
}
|
|
|
|
- void UpdateButtons ()
|
|
+ private void UpdateButtons ()
|
|
{
|
|
- if (tiles.Count <= FirstVisible && page > 0) {
|
|
- // The page we were viewing disappeared
|
|
- page--;
|
|
- }
|
|
-
|
|
- prev.Sensitive = (page != 0);
|
|
+ prev.Sensitive = tileIndex != 0;
|
|
next.Sensitive = (tiles.Count > LastVisible + 1);
|
|
|
|
if (tiles.Count > 0) {
|
|
@@ -156,7 +141,7 @@ namespace Beagle.Search {
|
|
tiles.Add ((Tiles.Tile)widget);
|
|
|
|
if (Expanded)
|
|
- ShowTiles (true);
|
|
+ ShowTiles ();
|
|
}
|
|
|
|
protected override void OnRemoved (Gtk.Widget widget)
|
|
@@ -168,41 +153,31 @@ namespace Beagle.Search {
|
|
tiles.Remove ((Tiles.Tile)widget);
|
|
|
|
if (Expanded)
|
|
- ShowTiles (true);
|
|
+ ShowTiles ();
|
|
}
|
|
|
|
private Tiles.Tile lastTarget;
|
|
private bool hadFocus;
|
|
|
|
- void HideTiles ()
|
|
+ private void HideTiles ()
|
|
{
|
|
lastTarget = null;
|
|
- foreach (Tiles.Tile tile in VisibleTiles) {
|
|
+ foreach (Tiles.Tile tile in AllTiles) {
|
|
if (tile.HasFocus || lastTarget == null) {
|
|
lastTarget = tile;
|
|
hadFocus = tile.HasFocus;
|
|
}
|
|
tile.ChildVisible = false;
|
|
}
|
|
+
|
|
QueueResize ();
|
|
}
|
|
|
|
- void ShowTiles (bool recenter)
|
|
+ private void ShowTiles ()
|
|
{
|
|
- if (recenter && lastTarget != null) {
|
|
- int index = tiles.IndexOf (lastTarget);
|
|
- if (hadFocus || page > 0) {
|
|
- if (index < few)
|
|
- page = 0;
|
|
- else if (extended)
|
|
- page = index / (manyRows * columns);
|
|
- else
|
|
- page = ((index - few) / (manyRows * columns)) + 1;
|
|
- }
|
|
- }
|
|
-
|
|
foreach (Tiles.Tile tile in VisibleTiles) {
|
|
tile.ChildVisible = true;
|
|
+
|
|
if (tile == lastTarget && hadFocus && !tile.HasFocus)
|
|
tile.GrabFocus ();
|
|
}
|
|
@@ -211,33 +186,26 @@ namespace Beagle.Search {
|
|
QueueResize ();
|
|
}
|
|
|
|
- private bool showingMany {
|
|
- get {
|
|
- // Show extra tiles on every page after the first, unless
|
|
- // there are only two pages and the second one only has
|
|
- // enough tiles to fit the "fewer" size.
|
|
- return (page > 0 && tiles.Count > 2 * few) || extended;
|
|
- }
|
|
- }
|
|
-
|
|
- void OnPrev (object obj, EventArgs args)
|
|
+ private void OnPrev (object obj, EventArgs args)
|
|
{
|
|
HideTiles ();
|
|
- page--;
|
|
+ tileIndex = Math.Max (0, tileIndex - PageSize);
|
|
+
|
|
if (!Expanded)
|
|
OnActivated (obj, args);
|
|
else
|
|
- ShowTiles (false);
|
|
+ ShowTiles ();
|
|
}
|
|
|
|
- void OnNext (object obj, EventArgs args)
|
|
+ private void OnNext (object obj, EventArgs args)
|
|
{
|
|
HideTiles ();
|
|
- page++;
|
|
+ tileIndex = Math.Min (tiles.Count - 1, tileIndex + PageSize);
|
|
+
|
|
if (!Expanded)
|
|
OnActivated (obj, args);
|
|
else
|
|
- ShowTiles (false);
|
|
+ ShowTiles ();
|
|
}
|
|
|
|
protected void OnActivated (object obj, EventArgs args)
|
|
@@ -246,27 +214,56 @@ namespace Beagle.Search {
|
|
CategoryToggle (scope);
|
|
}
|
|
|
|
+ public void SetMaxDisplayHeight (int height)
|
|
+ {
|
|
+ if (tileHeight != height) {
|
|
+ tileHeight = height;
|
|
+ HideTiles ();
|
|
+
|
|
+ if (Expanded)
|
|
+ ShowTiles ();
|
|
+ }
|
|
+ }
|
|
+
|
|
+ public int GetPotentialDisplayHeight ()
|
|
+ {
|
|
+ if (tiles.Count == 0)
|
|
+ return 0;
|
|
+
|
|
+ Requisition headerReq = header.SizeRequest ();
|
|
+ Requisition tileReq = tiles[0].SizeRequest ();
|
|
+ return headerReq.Height + (tiles.Count / Columns) * tileReq.Height;
|
|
+ }
|
|
+
|
|
public delegate void CategoryToggleDelegate (ScopeType scope);
|
|
public event CategoryToggleDelegate CategoryToggle;
|
|
|
|
protected int PageSize {
|
|
get {
|
|
- return Math.Min (showingMany ? many : few, tiles.Count);
|
|
+ if (tiles.Count == 0)
|
|
+ return 0;
|
|
+
|
|
+ if (tileHeight == 0)
|
|
+ return Math.Min (2 * Columns, tiles.Count);
|
|
+
|
|
+ Requisition sizeReq = tiles[0].SizeRequest ();
|
|
+ int ps = Math.Min (tileHeight / sizeReq.Height * Columns, tiles.Count);
|
|
+
|
|
+ // Display at least two rows if we have the hits for it.
|
|
+ if (ps < 2 * Columns)
|
|
+ ps = Math.Min (2 * Columns, tiles.Count);
|
|
+
|
|
+ return ps;
|
|
}
|
|
}
|
|
|
|
- protected int FirstVisible {
|
|
+ private int FirstVisible {
|
|
get {
|
|
- if (page == 0)
|
|
- return 0;
|
|
- else if (extended)
|
|
- return page * many;
|
|
- else
|
|
- return few + (page - 1) * many;
|
|
+ return tileIndex;
|
|
}
|
|
}
|
|
|
|
- protected int LastVisible {
|
|
+ private int LastVisible {
|
|
get {
|
|
return Math.Min (FirstVisible + PageSize, tiles.Count) - 1;
|
|
}
|
|
@@ -337,7 +334,7 @@ namespace Beagle.Search {
|
|
set {
|
|
HideTiles ();
|
|
tiles.SortType = value;
|
|
- ShowTiles (true);
|
|
+ ShowTiles ();
|
|
}
|
|
}
|
|
|
|
@@ -346,7 +343,7 @@ namespace Beagle.Search {
|
|
if (extended) {
|
|
HideTiles ();
|
|
this.extended = extended;
|
|
- ShowTiles (false);
|
|
+ ShowTiles ();
|
|
}
|
|
if (focus && !Empty)
|
|
((Gtk.Widget)VisibleTiles[0]).GrabFocus ();
|
|
diff --git a/beagle/search/Beagle.Search/GroupView.cs b/beagle/search/Beagle.Search/GroupView.cs
|
|
index d9d6319..e0620da 100644
|
|
--- a/beagle/search/Beagle.Search/GroupView.cs
|
|
+++ b/beagle/search/Beagle.Search/GroupView.cs
|
|
@@ -25,6 +25,9 @@ namespace Beagle.Search {
|
|
private Gtk.SizeGroup tileSizeGroup;
|
|
private Gtk.Widget selection;
|
|
|
|
+ private int[] maxHeight;
|
|
+ private int[] displayHeight;
|
|
+
|
|
public event CategoryToggledDelegate CategoryToggled;
|
|
public event TileHandler TileSelected;
|
|
|
|
@@ -47,8 +50,68 @@ namespace Beagle.Search {
|
|
|
|
categories [info.Group] = box;
|
|
}
|
|
+
|
|
+ maxHeight = new int[Children.Length];
|
|
+ displayHeight = new int[Children.Length];
|
|
}
|
|
|
|
+ public void AdjustCategories (int height)
|
|
+ {
|
|
+ Category last = null;
|
|
+ int visible = 0, totalHeight = height, childLen = Children.Length;
|
|
+ ulong mask = ~0UL;
|
|
+
|
|
+ for (int i = 0; i < childLen; i++) {
|
|
+ displayHeight[i] = maxHeight[i] = 0;
|
|
+ Category c = (Category) Children[i];
|
|
+ if (!c.Expanded || c.Count == 0) {
|
|
+ mask ^= 1UL << i;
|
|
+ continue;
|
|
+ }
|
|
+
|
|
+ last = c;
|
|
+ visible++;
|
|
+ maxHeight[i] = c.GetPotentialDisplayHeight ();
|
|
+ }
|
|
+
|
|
+ if (visible == 0) {
|
|
+ return;
|
|
+ } else if (visible == 1) {
|
|
+ last.SetMaxDisplayHeight (height);
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ // Split the available height among the visible categories
|
|
+ for (int active = visible; active > 0 && totalHeight > active;) {
|
|
+ int avg_height = totalHeight / active;
|
|
+
|
|
+ for (int i = 0; i < childLen; i++) {
|
|
+ if ((mask & 1UL << i) == 0)
|
|
+ continue;
|
|
+
|
|
+ int diff = maxHeight[i] - displayHeight[i];
|
|
+ if (diff <= avg_height) {
|
|
+ displayHeight[i] += diff;
|
|
+ totalHeight -= diff;
|
|
+ mask ^= 1UL << i;
|
|
+ } else {
|
|
+ displayHeight[i] += avg_height;
|
|
+ totalHeight -= avg_height;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ for (int j = active = 0; j < childLen; j++)
|
|
+ if ((mask & 1UL << j) != 0)
|
|
+ active++;
|
|
+ }
|
|
+
|
|
+ // Tell each category how much height it has to work with
|
|
+ for (int i = 0; i < childLen; i++) {
|
|
+ Category c = (Category) Children[i];
|
|
+ c.SetMaxDisplayHeight (displayHeight[i]);
|
|
+ }
|
|
+ }
|
|
+
|
|
public void AddHit (Tile tile)
|
|
{
|
|
tile.Show ();
|
|
diff --git a/beagle/search/Beagle.Search/Panes.cs b/beagle/search/Beagle.Search/Panes.cs
|
|
index 3ae5b7e..4b6a554 100644
|
|
--- a/beagle/search/Beagle.Search/Panes.cs
|
|
+++ b/beagle/search/Beagle.Search/Panes.cs
|
|
@@ -92,6 +92,10 @@ namespace Beagle.Search {
|
|
Gtk.Widget focusChild = mainChild.FocusChild;
|
|
mainChild.FocusChild = null;
|
|
mainChild.FocusChild = focusChild;
|
|
+
|
|
+ GroupView gv = mainChild as GroupView;
|
|
+ if (gv != null)
|
|
+ gv.AdjustCategories (args.Allocation.Height);
|
|
}
|
|
}
|
|
|
|
--
|
|
cgit v0.8.3.1
|