Fixes for GenericDisplay
GenericDisplay wasn't quite completely converted to the ShellOverflowList model. Since the list now holds all actors, the indexing/wrapping was incorrect. Add a property which lets us keep track of how many items are displayed, use this in genericDisplay. Avoid setting selectedIndex to -2 when going up with no items. If we're not displaying any results at all, don't attempt keynav (for now).
This commit is contained in:
parent
f7a82d6400
commit
2161e90cda
@ -351,7 +351,6 @@ GenericDisplay.prototype = {
|
|||||||
this._matchedItems = [];
|
this._matchedItems = [];
|
||||||
// map<itemId, GenericDisplayItem>
|
// map<itemId, GenericDisplayItem>
|
||||||
this._displayedItems = {};
|
this._displayedItems = {};
|
||||||
this._displayedItemsCount = 0;
|
|
||||||
this._selectedIndex = -1;
|
this._selectedIndex = -1;
|
||||||
// These two are public - .actor is the normal "actor subclass" property,
|
// These two are public - .actor is the normal "actor subclass" property,
|
||||||
// but we also expose a .displayControl actor which is separate.
|
// but we also expose a .displayControl actor which is separate.
|
||||||
@ -397,10 +396,11 @@ GenericDisplay.prototype = {
|
|||||||
// to the bottom one. Returns true if the selection actually moved up, false if it wrapped
|
// to the bottom one. Returns true if the selection actually moved up, false if it wrapped
|
||||||
// around to the bottom.
|
// around to the bottom.
|
||||||
selectUp: function() {
|
selectUp: function() {
|
||||||
|
let count = this._list.displayedCount;
|
||||||
let selectedUp = true;
|
let selectedUp = true;
|
||||||
let prev = this._selectedIndex - 1;
|
let prev = this._selectedIndex - 1;
|
||||||
if (this._selectedIndex <= 0) {
|
if (this._selectedIndex <= 0) {
|
||||||
prev = this._displayedItemsCount - 1;
|
prev = count - 1;
|
||||||
selectedUp = false;
|
selectedUp = false;
|
||||||
}
|
}
|
||||||
this._selectIndex(prev);
|
this._selectIndex(prev);
|
||||||
@ -411,9 +411,10 @@ GenericDisplay.prototype = {
|
|||||||
// to the top one. Returns true if the selection actually moved down, false if it wrapped
|
// to the top one. Returns true if the selection actually moved down, false if it wrapped
|
||||||
// around to the top.
|
// around to the top.
|
||||||
selectDown: function() {
|
selectDown: function() {
|
||||||
|
let count = this._list.displayedCount;
|
||||||
let selectedDown = true;
|
let selectedDown = true;
|
||||||
let next = this._selectedIndex + 1;
|
let next = this._selectedIndex + 1;
|
||||||
if (this._selectedIndex == this._displayedItemsCount - 1) {
|
if (this._selectedIndex == count - 1) {
|
||||||
next = 0;
|
next = 0;
|
||||||
selectedDown = false;
|
selectedDown = false;
|
||||||
}
|
}
|
||||||
@ -429,8 +430,9 @@ GenericDisplay.prototype = {
|
|||||||
|
|
||||||
// Selects the last item among the displayed items.
|
// Selects the last item among the displayed items.
|
||||||
selectLastItem: function() {
|
selectLastItem: function() {
|
||||||
|
let count = this._list.displayedCount;
|
||||||
if (this.hasItems())
|
if (this.hasItems())
|
||||||
this._selectIndex(this._displayedItemsCount - 1);
|
this._selectIndex(count - 1);
|
||||||
},
|
},
|
||||||
|
|
||||||
// Returns true if the display has some item selected.
|
// Returns true if the display has some item selected.
|
||||||
@ -445,7 +447,7 @@ GenericDisplay.prototype = {
|
|||||||
|
|
||||||
// Returns true if the display has any displayed items.
|
// Returns true if the display has any displayed items.
|
||||||
hasItems: function() {
|
hasItems: function() {
|
||||||
return this._displayedItemsCount > 0;
|
return this._list.displayedCount > 0;
|
||||||
},
|
},
|
||||||
|
|
||||||
// Updates the displayed items and makes the display actor visible.
|
// Updates the displayed items and makes the display actor visible.
|
||||||
@ -541,15 +543,15 @@ GenericDisplay.prototype = {
|
|||||||
}));
|
}));
|
||||||
this._list.add_actor(displayItem.actor);
|
this._list.add_actor(displayItem.actor);
|
||||||
this._displayedItems[itemId] = displayItem;
|
this._displayedItems[itemId] = displayItem;
|
||||||
this._displayedItemsCount++;
|
|
||||||
},
|
},
|
||||||
|
|
||||||
// Removes an item identifed by the itemId from the displayed items.
|
// Removes an item identifed by the itemId from the displayed items.
|
||||||
_removeDisplayItem: function(itemId) {
|
_removeDisplayItem: function(itemId) {
|
||||||
|
let count = this._list.displayedCount;
|
||||||
let displayItem = this._displayedItems[itemId];
|
let displayItem = this._displayedItems[itemId];
|
||||||
let displayItemIndex = this._getIndexOfDisplayedActor(displayItem.actor);
|
let displayItemIndex = this._getIndexOfDisplayedActor(displayItem.actor);
|
||||||
|
|
||||||
if (this.hasSelected() && (this._displayedItemsCount == 1 || !this._list.visible)) {
|
if (this.hasSelected() && (count == 1 || !this._list.visible)) {
|
||||||
this.unsetSelected();
|
this.unsetSelected();
|
||||||
} else if (this.hasSelected() && displayItemIndex < this._selectedIndex) {
|
} else if (this.hasSelected() && displayItemIndex < this._selectedIndex) {
|
||||||
this.selectUp();
|
this.selectUp();
|
||||||
@ -558,7 +560,6 @@ GenericDisplay.prototype = {
|
|||||||
displayItem.destroy();
|
displayItem.destroy();
|
||||||
|
|
||||||
delete this._displayedItems[itemId];
|
delete this._displayedItems[itemId];
|
||||||
this._displayedItemsCount--;
|
|
||||||
},
|
},
|
||||||
|
|
||||||
// Removes all displayed items.
|
// Removes all displayed items.
|
||||||
@ -707,6 +708,7 @@ GenericDisplay.prototype = {
|
|||||||
*/
|
*/
|
||||||
_updateDisplayControl: function(resetDisplayControl) {
|
_updateDisplayControl: function(resetDisplayControl) {
|
||||||
if (resetDisplayControl) {
|
if (resetDisplayControl) {
|
||||||
|
this._selectedIndex = -1;
|
||||||
this.displayControl.remove_all();
|
this.displayControl.remove_all();
|
||||||
let nPages = this._list.n_pages;
|
let nPages = this._list.n_pages;
|
||||||
let pageNumber = this._list.page;
|
let pageNumber = this._list.page;
|
||||||
@ -744,8 +746,7 @@ GenericDisplay.prototype = {
|
|||||||
// Returns a display item based on its index in the ordering of the
|
// Returns a display item based on its index in the ordering of the
|
||||||
// display children.
|
// display children.
|
||||||
_findDisplayedByIndex: function(index) {
|
_findDisplayedByIndex: function(index) {
|
||||||
let displayedActors = this._list.get_children();
|
let actor = this._list.get_displayed_actor(index);
|
||||||
let actor = displayedActors[index];
|
|
||||||
return this._findDisplayedByActor(actor);
|
return this._findDisplayedByActor(actor);
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -775,7 +776,8 @@ GenericDisplay.prototype = {
|
|||||||
// Selects (e.g. highlights) a display item at the provided index,
|
// Selects (e.g. highlights) a display item at the provided index,
|
||||||
// updates this.selectedItemDetails actor, and emits 'selected' signal.
|
// updates this.selectedItemDetails actor, and emits 'selected' signal.
|
||||||
_selectIndex: function(index) {
|
_selectIndex: function(index) {
|
||||||
if (this._selectedIndex != -1) {
|
let count = this._list.displayedCount;
|
||||||
|
if (this._selectedIndex >= 0) {
|
||||||
let prev = this._findDisplayedByIndex(this._selectedIndex);
|
let prev = this._findDisplayedByIndex(this._selectedIndex);
|
||||||
prev.markSelected(false);
|
prev.markSelected(false);
|
||||||
// Calling destroy() gets large image previews released as quickly as
|
// Calling destroy() gets large image previews released as quickly as
|
||||||
@ -787,12 +789,15 @@ GenericDisplay.prototype = {
|
|||||||
|
|
||||||
this.selectedItemDetails.remove_all();
|
this.selectedItemDetails.remove_all();
|
||||||
}
|
}
|
||||||
this._selectedIndex = index;
|
if (index < count) {
|
||||||
if (index != -1 && index < this._displayedItemsCount) {
|
this._selectedIndex = index;
|
||||||
let item = this._findDisplayedByIndex(index);
|
if (index >= 0) {
|
||||||
item.markSelected(true);
|
let item = this._findDisplayedByIndex(index);
|
||||||
this.selectedItemDetails.append(item.createDetailsActor(this._availableWidthForItemDetails, this._availableHeightForItemDetails), Big.BoxPackFlags.NONE);
|
item.markSelected(true);
|
||||||
this.emit('selected');
|
this.selectedItemDetails.append(item.createDetailsActor(this._availableWidthForItemDetails,
|
||||||
|
this._availableHeightForItemDetails), Big.BoxPackFlags.NONE);
|
||||||
|
this.emit('selected');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -332,6 +332,8 @@ Dash.prototype = {
|
|||||||
me.emit('activated');
|
me.emit('activated');
|
||||||
return true;
|
return true;
|
||||||
} else if (symbol == Clutter.Up) {
|
} else if (symbol == Clutter.Up) {
|
||||||
|
if (!me._resultsShowing())
|
||||||
|
return true;
|
||||||
// selectUp and selectDown wrap around in their respective displays
|
// selectUp and selectDown wrap around in their respective displays
|
||||||
// too, but there doesn't seem to be any flickering if we first select
|
// too, but there doesn't seem to be any flickering if we first select
|
||||||
// something in one display, but then unset the selection, and move
|
// something in one display, but then unset the selection, and move
|
||||||
@ -342,13 +344,17 @@ Dash.prototype = {
|
|||||||
me._resultsAppsSection.display.selectUp();
|
me._resultsAppsSection.display.selectUp();
|
||||||
else
|
else
|
||||||
me._resultsDocsSection.display.selectUp();
|
me._resultsDocsSection.display.selectUp();
|
||||||
|
return true;
|
||||||
} else if (symbol == Clutter.Down) {
|
} else if (symbol == Clutter.Down) {
|
||||||
|
if (!me._resultsShowing())
|
||||||
|
return true;
|
||||||
if (me._resultsDocsSection.display.hasSelected())
|
if (me._resultsDocsSection.display.hasSelected())
|
||||||
me._resultsDocsSection.display.selectDown();
|
me._resultsDocsSection.display.selectDown();
|
||||||
else if (me._resultsAppsSection.display.hasItems())
|
else if (me._resultsAppsSection.display.hasItems())
|
||||||
me._resultsAppsSection.display.selectDown();
|
me._resultsAppsSection.display.selectDown();
|
||||||
else
|
else
|
||||||
me._resultsDocsSection.display.selectDown();
|
me._resultsDocsSection.display.selectDown();
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
|
@ -10,6 +10,7 @@ enum {
|
|||||||
PROP_0,
|
PROP_0,
|
||||||
PROP_SPACING,
|
PROP_SPACING,
|
||||||
PROP_ITEM_HEIGHT,
|
PROP_ITEM_HEIGHT,
|
||||||
|
PROP_DISPLAYED_COUNT,
|
||||||
PROP_PAGE,
|
PROP_PAGE,
|
||||||
PROP_N_PAGES
|
PROP_N_PAGES
|
||||||
};
|
};
|
||||||
@ -20,8 +21,36 @@ struct _ShellOverflowListPrivate {
|
|||||||
guint page;
|
guint page;
|
||||||
guint n_pages;
|
guint n_pages;
|
||||||
guint items_per_page;
|
guint items_per_page;
|
||||||
|
guint displayed_count;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static void
|
||||||
|
recalc_displayed_count (ShellOverflowList *self)
|
||||||
|
{
|
||||||
|
GList *children;
|
||||||
|
int n_children;
|
||||||
|
int displayed_count;
|
||||||
|
int page, n_pages;
|
||||||
|
|
||||||
|
children = clutter_container_get_children (CLUTTER_CONTAINER (self));
|
||||||
|
n_children = g_list_length (children);
|
||||||
|
g_list_free (children);
|
||||||
|
|
||||||
|
page = self->priv->page;
|
||||||
|
n_pages = self->priv->n_pages;
|
||||||
|
if (page < n_pages-1)
|
||||||
|
displayed_count = self->priv->items_per_page;
|
||||||
|
else if (n_pages > 0)
|
||||||
|
displayed_count = n_children - (self->priv->items_per_page * (n_pages-1));
|
||||||
|
else
|
||||||
|
displayed_count = 0;
|
||||||
|
if (displayed_count != self->priv->displayed_count)
|
||||||
|
{
|
||||||
|
self->priv->displayed_count = displayed_count;
|
||||||
|
g_object_notify (G_OBJECT (self), "displayed-count");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
shell_overflow_list_set_property(GObject *object,
|
shell_overflow_list_set_property(GObject *object,
|
||||||
guint prop_id,
|
guint prop_id,
|
||||||
@ -43,6 +72,7 @@ shell_overflow_list_set_property(GObject *object,
|
|||||||
break;
|
break;
|
||||||
case PROP_PAGE:
|
case PROP_PAGE:
|
||||||
priv->page = g_value_get_uint (value);
|
priv->page = g_value_get_uint (value);
|
||||||
|
recalc_displayed_count (self);
|
||||||
clutter_actor_queue_redraw (CLUTTER_ACTOR (self));
|
clutter_actor_queue_redraw (CLUTTER_ACTOR (self));
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -68,6 +98,9 @@ shell_overflow_list_get_property(GObject *object,
|
|||||||
case PROP_ITEM_HEIGHT:
|
case PROP_ITEM_HEIGHT:
|
||||||
g_value_set_float (value, priv->spacing);
|
g_value_set_float (value, priv->spacing);
|
||||||
break;
|
break;
|
||||||
|
case PROP_DISPLAYED_COUNT:
|
||||||
|
g_value_set_uint (value, priv->displayed_count);
|
||||||
|
break;
|
||||||
case PROP_PAGE:
|
case PROP_PAGE:
|
||||||
g_value_set_uint (value, priv->page);
|
g_value_set_uint (value, priv->page);
|
||||||
break;
|
break;
|
||||||
@ -135,12 +168,15 @@ shell_overflow_list_allocate (ClutterActor *actor,
|
|||||||
}
|
}
|
||||||
|
|
||||||
priv->items_per_page = n_fits;
|
priv->items_per_page = n_fits;
|
||||||
|
|
||||||
if (n_pages != priv->n_pages)
|
if (n_pages != priv->n_pages)
|
||||||
{
|
{
|
||||||
priv->n_pages = n_pages;
|
priv->n_pages = n_pages;
|
||||||
g_object_notify (G_OBJECT (self), "n-pages");
|
g_object_notify (G_OBJECT (self), "n-pages");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
recalc_displayed_count (self);
|
||||||
|
|
||||||
g_list_free (children);
|
g_list_free (children);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -173,14 +209,9 @@ static void
|
|||||||
shell_overflow_list_pick (ClutterActor *actor,
|
shell_overflow_list_pick (ClutterActor *actor,
|
||||||
const ClutterColor *color)
|
const ClutterColor *color)
|
||||||
{
|
{
|
||||||
ShellOverflowList *self = SHELL_OVERFLOW_LIST (actor);
|
|
||||||
ShellOverflowListPrivate *priv = self->priv;
|
|
||||||
GList *children, *iter;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
(CLUTTER_ACTOR_CLASS (g_type_class_peek (clutter_actor_get_type ())))->pick (actor, color);
|
(CLUTTER_ACTOR_CLASS (g_type_class_peek (clutter_actor_get_type ())))->pick (actor, color);
|
||||||
|
|
||||||
shell_overflow_list_paint (self);
|
shell_overflow_list_paint (actor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -289,6 +320,14 @@ shell_overflow_list_class_init (ShellOverflowListClass *klass)
|
|||||||
0.0, G_MAXFLOAT, 0.0,
|
0.0, G_MAXFLOAT, 0.0,
|
||||||
G_PARAM_READWRITE));
|
G_PARAM_READWRITE));
|
||||||
|
|
||||||
|
g_object_class_install_property (gobject_class,
|
||||||
|
PROP_DISPLAYED_COUNT,
|
||||||
|
g_param_spec_uint ("displayed-count",
|
||||||
|
"Displayed count",
|
||||||
|
"Number of items displayed on current page",
|
||||||
|
0, G_MAXUINT, 0,
|
||||||
|
G_PARAM_READWRITE));
|
||||||
|
|
||||||
g_object_class_install_property (gobject_class,
|
g_object_class_install_property (gobject_class,
|
||||||
PROP_PAGE,
|
PROP_PAGE,
|
||||||
g_param_spec_uint ("page",
|
g_param_spec_uint ("page",
|
||||||
@ -301,7 +340,7 @@ shell_overflow_list_class_init (ShellOverflowListClass *klass)
|
|||||||
PROP_N_PAGES,
|
PROP_N_PAGES,
|
||||||
g_param_spec_uint ("n-pages",
|
g_param_spec_uint ("n-pages",
|
||||||
"Number of pages",
|
"Number of pages",
|
||||||
"Number of pagest",
|
"Number of pages",
|
||||||
0, G_MAXUINT, 0,
|
0, G_MAXUINT, 0,
|
||||||
G_PARAM_READABLE));
|
G_PARAM_READABLE));
|
||||||
|
|
||||||
@ -318,3 +357,31 @@ shell_overflow_list_init (ShellOverflowList *self)
|
|||||||
self->priv->n_pages = 1;
|
self->priv->n_pages = 1;
|
||||||
self->priv->page = 0;
|
self->priv->page = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* shell_overflow_list_get_displayed_actor:
|
||||||
|
* @self:
|
||||||
|
* @index: 0-based index for displayed list
|
||||||
|
*
|
||||||
|
* Returns the actor at the given index on the current page.
|
||||||
|
*
|
||||||
|
* Return value: (transfer none): #ClutterActor at index
|
||||||
|
*/
|
||||||
|
ClutterActor *
|
||||||
|
shell_overflow_list_get_displayed_actor (ShellOverflowList *self,
|
||||||
|
guint index)
|
||||||
|
{
|
||||||
|
GList *children, *iter;
|
||||||
|
|
||||||
|
children = clutter_container_get_children (CLUTTER_CONTAINER (self));
|
||||||
|
|
||||||
|
if (children == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
iter = g_list_nth (children, index + (self->priv->page * self->priv->items_per_page));
|
||||||
|
|
||||||
|
if (!iter)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
return iter->data;
|
||||||
|
}
|
||||||
|
@ -36,6 +36,8 @@ struct _ShellOverflowListClass
|
|||||||
|
|
||||||
GType shell_overflow_list_get_type (void) G_GNUC_CONST;
|
GType shell_overflow_list_get_type (void) G_GNUC_CONST;
|
||||||
|
|
||||||
|
ClutterActor *shell_overflow_list_get_displayed_actor (ShellOverflowList *list, guint index);
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
||||||
#endif /* __SHELL_OVERFLOW_LIST_H__ */
|
#endif /* __SHELL_OVERFLOW_LIST_H__ */
|
||||||
|
Loading…
Reference in New Issue
Block a user