Use a separate icon image as a drag actor instead of using the clone of the icon

Clutter no longer allows using a clone of an actor that is not a part of
the scene graph. This is what used to happen when we created a clone for
the icon of the item that was being dragged, and then closed the More panes
with the original item, removing the icon from the scene graph. This was
also when happened when the user hit Esc while dragging, which prompted the
overlay to close, removing the original icon from the scene graph.

Rename getIcon() methods to createIcon() to better reflect on the fact that
a new icon is created each time the method is called (we do use cache in
some cases).

Remove a stray log message in overlay.js

Fixes http://bugzilla.gnome.org/show_bug.cgi?id=585490
and http://bugzilla.gnome.org/show_bug.cgi?id=585489
This commit is contained in:
Marina Zhurakhinskaya 2009-06-29 15:08:48 -04:00
parent 2ae89f3b36
commit 858a82fcdd
7 changed files with 33 additions and 46 deletions

View File

@ -27,7 +27,7 @@ AppInfo.prototype = {
this._gicon = this._gAppInfo.get_icon();
},
getIcon : function(size) {
createIcon : function(size) {
if (this._gicon)
return Shell.TextureCache.get_default().load_gicon(this._gicon, size);
else

View File

@ -21,7 +21,7 @@ DocInfo.prototype = {
this.mimeType = recentInfo.get_mime_type();
},
getIcon : function(size) {
createIcon : function(size) {
let icon = new Clutter.Texture();
let iconPixbuf;

View File

@ -41,8 +41,7 @@ AppDisplayItem.prototype = {
GenericDisplay.GenericDisplayItem.prototype._init.call(this, availableWidth);
this._appInfo = appInfo;
this._setItemInfo(appInfo.name, appInfo.description,
appInfo.getIcon(GenericDisplay.ITEM_DISPLAY_ICON_SIZE));
this._setItemInfo(appInfo.name, appInfo.description);
},
//// Public method overrides ////
@ -54,6 +53,11 @@ AppDisplayItem.prototype = {
//// Protected method overrides ////
// Returns an icon for the item.
_createIcon : function() {
return this._appInfo.createIcon(GenericDisplay.ITEM_DISPLAY_ICON_SIZE);
},
// Ensures the preview icon is created.
_ensurePreviewIconCreated : function() {
if (!this._showPreview || this._previewIcon)
@ -447,7 +451,7 @@ WellDisplayItem.prototype = {
let draggable = DND.makeDraggable(this.actor);
this._icon = appInfo.getIcon(APP_ICON_SIZE);
this._icon = appInfo.createIcon(APP_ICON_SIZE);
this.actor.append(this._icon, Big.BoxPackFlags.NONE);
@ -475,8 +479,7 @@ WellDisplayItem.prototype = {
// Draggable interface - FIXME deduplicate with GenericDisplay
getDragActor: function(stageX, stageY) {
this.dragActor = new Clutter.Clone({ source: this._icon });
[this.dragActor.width, this.dragActor.height] = this._icon.get_transformed_size();
this.dragActor = this.appInfo.createIcon(APP_ICON_SIZE);
// If the user dragged from the icon itself, then position
// the dragActor over the original icon. Otherwise center it

View File

@ -27,8 +27,7 @@ DocDisplayItem.prototype = {
GenericDisplay.GenericDisplayItem.prototype._init.call(this, availableWidth);
this._docInfo = docInfo;
this._setItemInfo(docInfo.name, "",
docInfo.getIcon(GenericDisplay.ITEM_DISPLAY_ICON_SIZE));
this._setItemInfo(docInfo.name, "");
},
//// Public methods ////
@ -42,10 +41,15 @@ DocDisplayItem.prototype = {
//// Protected method overrides ////
// Returns an icon for the item.
_createIcon : function() {
return this._docInfo.createIcon(GenericDisplay.ITEM_DISPLAY_ICON_SIZE);
},
// Ensures the preview icon is created.
_ensurePreviewIconCreated : function() {
if (!this._previewIcon)
this._previewIcon = this._docInfo.getIcon(GenericDisplay.PREVIEW_ICON_SIZE);
this._previewIcon = this._docInfo.createIcon(GenericDisplay.PREVIEW_ICON_SIZE);
},
// Creates and returns a large preview icon, but only if this._docInfo is an image file

View File

@ -126,8 +126,7 @@ GenericDisplayItem.prototype = {
// Returns a cloned texture of the item's icon to represent the item as it
// is being dragged.
getDragActor: function(stageX, stageY) {
this.dragActor = new Clutter.Clone({ source: this._icon });
[this.dragActor.width, this.dragActor.height] = this._icon.get_transformed_size();
this.dragActor = this._createIcon();
// If the user dragged from the icon itself, then position
// the dragActor over the original icon. Otherwise center it
@ -142,8 +141,10 @@ GenericDisplayItem.prototype = {
return this.dragActor;
},
// Returns the original icon that is being used as a source for the cloned texture
// that represents the item as it is being dragged.
// Returns the item icon, a separate copy of which is used to
// represent the item as it is being dragged. This is used to
// determine a snap-back location for the drag icon if it does
// not get accepted by any drop target.
getDragActorSource: function() {
return this._icon;
},
@ -238,9 +239,8 @@ GenericDisplayItem.prototype = {
*
* nameText - name of the item
* descriptionText - short description of the item
* iconActor - ClutterTexture containing the icon image which should be ITEM_DISPLAY_ICON_SIZE size
*/
_setItemInfo: function(nameText, descriptionText, iconActor) {
_setItemInfo: function(nameText, descriptionText) {
if (this._name != null) {
// this also removes this._name from the parent container,
// so we don't need to call this.actor.remove_actor(this._name) directly
@ -263,7 +263,7 @@ GenericDisplayItem.prototype = {
this._previewIcon = null;
}
this._icon = iconActor;
this._icon = this._createIcon();
this.actor.add_actor(this._icon);
let textWidth = this._availableWidth - (ITEM_DISPLAY_ICON_SIZE + 4) - INFORMATION_BUTTON_SIZE - ITEM_DISPLAY_PADDING_RIGHT;
@ -294,6 +294,11 @@ GenericDisplayItem.prototype = {
//// Pure virtual protected methods ////
// Returns an icon for the item.
_createIcon: function() {
throw new Error("Not implemented");
},
// Ensures the preview icon is created.
_ensurePreviewIconCreated: function() {
throw new Error("Not implemented");
@ -588,32 +593,8 @@ GenericDisplay.prototype = {
this.selectUp();
}
if (displayItem.dragActor) {
// The user might be handling a dragActor when the list of items
// changes (for example, if the dragging caused us to transition
// from an expanded overlay view to the regular view). So we need
// to keep the item around so that the drag and drop action initiated
// by the user can be completed. However, we remove the item from the list.
//
// For some reason, just removing the displayItem.actor
// is not enough to get displayItem._icon.visible
// to return false, so we hide the display item and
// all its children first. (We check displayItem._icon.visible
// when deciding if a dragActor has a place to snap back to
// in case the drop was not accepted by any actor.)
displayItem.actor.hide_all();
this._grid.remove_actor(displayItem.actor);
// We should not destroy the item up-front, because that would also
// destroy the icon that was used to clone the image for the drag actor.
// We destroy it once the dragActor is destroyed instead.
displayItem.dragActor.connect('destroy',
function(item) {
displayItem.destroy();
});
} else {
displayItem.destroy();
}
displayItem.destroy();
delete this._displayedItems[itemId];
this._displayedItemsCount--;
},

View File

@ -762,7 +762,6 @@ Overlay.prototype = {
// the item on any workspace.
handleDragOver : function(source, actor, x, y, time) {
if (source instanceof GenericDisplay.GenericDisplayItem) {
log("unsetting more mode");
this._dash.unsetMoreMode();
return true;
}

View File

@ -182,7 +182,7 @@ LauncherWidget.prototype = {
spacing: ITEM_SPACING,
reactive: true });
item._info = info;
item.append(info.getIcon(ITEM_ICON_SIZE), Big.BoxPackFlags.NONE);
item.append(info.createIcon(ITEM_ICON_SIZE), Big.BoxPackFlags.NONE);
item.append(new Clutter.Text({ color: ITEM_NAME_COLOR,
font_name: "Sans 14px",
ellipsize: Pango.EllipsizeMode.END,
@ -203,7 +203,7 @@ LauncherWidget.prototype = {
padding: ITEM_PADDING,
reactive: true });
item._info = info;
item.append(info.getIcon(COLLAPSED_WIDTH - 2 * ITEM_PADDING),
item.append(info.createIcon(COLLAPSED_WIDTH - 2 * ITEM_PADDING),
Big.BoxPackFlags.NONE);
this.collapsedActor.append(item, Big.BoxPackFlags.NONE);