Fix behavior of More... links by adding a Link class
We had problems because the More links were reacting on press but other elements were reacting on release. (Often the link would trigger *and* an item.) Just connecting to ::button-release-event on ClutterText gives a stuck grab (since ClutterText gets the press but not the release), so we need more complicated code that we encapsulate into a new class. link.js: new "pseudo-widget" that implements a clickable link. overlay.js: Use Link.Link for the More.. links http://bugzilla.gnome.org/show_bug.cgi?id=573323
This commit is contained in:
parent
6676260308
commit
cb4ad9a963
81
js/ui/link.js
Normal file
81
js/ui/link.js
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
|
||||||
|
|
||||||
|
const Clutter = imports.gi.Clutter;
|
||||||
|
const Lang = imports.lang;
|
||||||
|
const Signals = imports.signals;
|
||||||
|
|
||||||
|
// Link is a clickable link. Right now it just handles properly capturing
|
||||||
|
// press and release events and short-circuiting the button handling in
|
||||||
|
// ClutterText, but more features like different colors for hover/pressed states
|
||||||
|
// or a different mouse cursor could be implemented.
|
||||||
|
//
|
||||||
|
// The properties passed in are forwarded to the Clutter.Text() constructor,
|
||||||
|
// so can include, 'text', 'font_name', etc.
|
||||||
|
function Link(props) {
|
||||||
|
this._init(props);
|
||||||
|
}
|
||||||
|
|
||||||
|
Link.prototype = {
|
||||||
|
_init : function(props) {
|
||||||
|
let realProps = { reactive: true };
|
||||||
|
// The user can pass in reactive: false to override the above and get
|
||||||
|
// a non-reactive link (a link to the current page, perhaps)
|
||||||
|
Lang.copyProperties(props, realProps);
|
||||||
|
|
||||||
|
this.actor = new Clutter.Text(realProps);
|
||||||
|
this.actor._delegate = this;
|
||||||
|
this.actor.connect('button-press-event', Lang.bind(this, this._onButtonPress));
|
||||||
|
this.actor.connect('button-release-event', Lang.bind(this, this._onButtonRelease));
|
||||||
|
this.actor.connect('enter-event', Lang.bind(this, this._onEnter));
|
||||||
|
this.actor.connect('leave-event', Lang.bind(this, this._onLeave));
|
||||||
|
|
||||||
|
this._buttonDown = false;
|
||||||
|
this._havePointer = false;
|
||||||
|
},
|
||||||
|
|
||||||
|
// Update the text of the link
|
||||||
|
setText : function(text) {
|
||||||
|
this.actor.text = text;
|
||||||
|
},
|
||||||
|
|
||||||
|
// We want to react on buttonDown, but if we override button-release-event for
|
||||||
|
// ClutterText, but not button-press-event, we get a stuck grab. Tracking
|
||||||
|
// buttonDown and doing the grab isn't really necessary, but doing it makes
|
||||||
|
// the behavior perfectly correct if the user clicks on one actor, drags
|
||||||
|
// to another and releases - that should not trigger either actor.
|
||||||
|
_onButtonPress : function(actor, event) {
|
||||||
|
this._buttonDown = true;
|
||||||
|
this._havePointer = true; // Hack to work around poor enter/leave tracking in Clutter
|
||||||
|
Clutter.grab_pointer(actor);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
|
||||||
|
_onButtonRelease : function(actor, event) {
|
||||||
|
if (this._buttonDown) {
|
||||||
|
this._buttonDown = false;
|
||||||
|
Clutter.ungrab_pointer(actor);
|
||||||
|
|
||||||
|
if (this._havePointer)
|
||||||
|
this.emit('clicked');
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
|
||||||
|
_onEnter : function(actor, event) {
|
||||||
|
if (event.get_source() == actor)
|
||||||
|
this._havePointer = true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
},
|
||||||
|
|
||||||
|
_onLeave : function(actor, event) {
|
||||||
|
if (event.get_source() == actor)
|
||||||
|
this._havePointer = false;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Signals.addSignalMethods(Link.prototype);
|
@ -11,6 +11,7 @@ const Signals = imports.signals;
|
|||||||
const AppDisplay = imports.ui.appDisplay;
|
const AppDisplay = imports.ui.appDisplay;
|
||||||
const DocDisplay = imports.ui.docDisplay;
|
const DocDisplay = imports.ui.docDisplay;
|
||||||
const GenericDisplay = imports.ui.genericDisplay;
|
const GenericDisplay = imports.ui.genericDisplay;
|
||||||
|
const Link = imports.ui.link;
|
||||||
const Main = imports.ui.main;
|
const Main = imports.ui.main;
|
||||||
const Panel = imports.ui.panel;
|
const Panel = imports.ui.panel;
|
||||||
const Tweener = imports.ui.tweener;
|
const Tweener = imports.ui.tweener;
|
||||||
@ -198,12 +199,11 @@ Sideshow.prototype = {
|
|||||||
this._appsSection.append(this._appDisplay.actor, Big.BoxPackFlags.EXPAND);
|
this._appsSection.append(this._appDisplay.actor, Big.BoxPackFlags.EXPAND);
|
||||||
|
|
||||||
let moreAppsBox = new Big.Box({x_align: Big.BoxAlignment.END});
|
let moreAppsBox = new Big.Box({x_align: Big.BoxAlignment.END});
|
||||||
this._moreAppsText = new Clutter.Text({ color: SIDESHOW_TEXT_COLOR,
|
this._moreAppsLink = new Link.Link({ color: SIDESHOW_TEXT_COLOR,
|
||||||
font_name: "Sans Bold 14px",
|
font_name: "Sans Bold 14px",
|
||||||
text: "More...",
|
text: "More...",
|
||||||
height: LABEL_HEIGHT,
|
height: LABEL_HEIGHT });
|
||||||
reactive: true});
|
moreAppsBox.append(this._moreAppsLink.actor, Big.BoxPackFlags.EXPAND);
|
||||||
moreAppsBox.append(this._moreAppsText, Big.BoxPackFlags.EXPAND);
|
|
||||||
this._appsSection.append(moreAppsBox, Big.BoxPackFlags.EXPAND);
|
this._appsSection.append(moreAppsBox, Big.BoxPackFlags.EXPAND);
|
||||||
|
|
||||||
this.actor.add_actor(this._appsSection);
|
this.actor.add_actor(this._appsSection);
|
||||||
@ -226,12 +226,11 @@ Sideshow.prototype = {
|
|||||||
this._docsSection.append(this._docDisplay.actor, Big.BoxPackFlags.EXPAND);
|
this._docsSection.append(this._docDisplay.actor, Big.BoxPackFlags.EXPAND);
|
||||||
|
|
||||||
let moreDocsBox = new Big.Box({x_align: Big.BoxAlignment.END});
|
let moreDocsBox = new Big.Box({x_align: Big.BoxAlignment.END});
|
||||||
this._moreDocsText = new Clutter.Text({ color: SIDESHOW_TEXT_COLOR,
|
this._moreDocsLink = new Link.Link({ color: SIDESHOW_TEXT_COLOR,
|
||||||
font_name: "Sans Bold 14px",
|
font_name: "Sans Bold 14px",
|
||||||
text: "More...",
|
text: "More...",
|
||||||
height: LABEL_HEIGHT,
|
height: LABEL_HEIGHT });
|
||||||
reactive: true});
|
moreDocsBox.append(this._moreDocsLink.actor, Big.BoxPackFlags.EXPAND);
|
||||||
moreDocsBox.append(this._moreDocsText, Big.BoxPackFlags.EXPAND);
|
|
||||||
this._docsSection.append(moreDocsBox, Big.BoxPackFlags.EXPAND);
|
this._docsSection.append(moreDocsBox, Big.BoxPackFlags.EXPAND);
|
||||||
|
|
||||||
this.actor.add_actor(this._docsSection);
|
this.actor.add_actor(this._docsSection);
|
||||||
@ -267,24 +266,22 @@ Sideshow.prototype = {
|
|||||||
me._appDisplay.selectFirstItem();
|
me._appDisplay.selectFirstItem();
|
||||||
});
|
});
|
||||||
|
|
||||||
this._moreAppsText.connect('button-press-event',
|
this._moreAppsLink.connect('clicked',
|
||||||
function(o, event) {
|
function(o, event) {
|
||||||
if (me._moreAppsMode) {
|
if (me._moreAppsMode) {
|
||||||
me._unsetMoreAppsMode();
|
me._unsetMoreAppsMode();
|
||||||
} else {
|
} else {
|
||||||
me._setMoreAppsMode();
|
me._setMoreAppsMode();
|
||||||
}
|
}
|
||||||
return true;
|
|
||||||
});
|
});
|
||||||
|
|
||||||
this._moreDocsText.connect('button-press-event',
|
this._moreDocsLink.connect('clicked',
|
||||||
function(o, event) {
|
function(o, event) {
|
||||||
if (me._moreDocsMode) {
|
if (me._moreDocsMode) {
|
||||||
me._unsetMoreDocsMode();
|
me._unsetMoreDocsMode();
|
||||||
} else {
|
} else {
|
||||||
me._setMoreDocsMode();
|
me._setMoreDocsMode();
|
||||||
}
|
}
|
||||||
return true;
|
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -319,7 +316,7 @@ Sideshow.prototype = {
|
|||||||
|
|
||||||
this._docsSection.set_clip(0, 0, this._docsSection.width, this._docsSection.height);
|
this._docsSection.set_clip(0, 0, this._docsSection.width, this._docsSection.height);
|
||||||
|
|
||||||
this._moreAppsText.hide();
|
this._moreAppsLink.actor.hide();
|
||||||
this._appsSection.set_clip(0, 0, this._appsSection.width, this._appsSection.height);
|
this._appsSection.set_clip(0, 0, this._appsSection.width, this._appsSection.height);
|
||||||
|
|
||||||
// Move the selection to the applications section if it was in the docs section.
|
// Move the selection to the applications section if it was in the docs section.
|
||||||
@ -356,7 +353,7 @@ Sideshow.prototype = {
|
|||||||
|
|
||||||
this._moreAppsMode = false;
|
this._moreAppsMode = false;
|
||||||
|
|
||||||
this._moreAppsText.hide();
|
this._moreAppsLink.actor.hide();
|
||||||
|
|
||||||
this._appsSection.set_clip(0, 0, this._appsSection.width, this._appsSection.height);
|
this._appsSection.set_clip(0, 0, this._appsSection.width, this._appsSection.height);
|
||||||
|
|
||||||
@ -410,12 +407,12 @@ Sideshow.prototype = {
|
|||||||
this._appDisplay.updateDimensions(this._width + this._additionalWidth,
|
this._appDisplay.updateDimensions(this._width + this._additionalWidth,
|
||||||
this._itemDisplayHeight + SIDESHOW_SECTION_MISC_HEIGHT,
|
this._itemDisplayHeight + SIDESHOW_SECTION_MISC_HEIGHT,
|
||||||
EXPANDED_SIDESHOW_COLUMNS);
|
EXPANDED_SIDESHOW_COLUMNS);
|
||||||
this._moreAppsText.text = "Less...";
|
this._moreAppsLink.setText("Less...");
|
||||||
} else {
|
} else {
|
||||||
this._appDisplay.updateDimensions(this._width, this._appsSectionDefaultHeight - SIDESHOW_SECTION_MISC_HEIGHT, SIDESHOW_COLUMNS);
|
this._appDisplay.updateDimensions(this._width, this._appsSectionDefaultHeight - SIDESHOW_SECTION_MISC_HEIGHT, SIDESHOW_COLUMNS);
|
||||||
this._moreAppsText.text = "More...";
|
this._moreAppsLink.setText("More...");
|
||||||
}
|
}
|
||||||
this._moreAppsText.show();
|
this._moreAppsLink.actor.show();
|
||||||
},
|
},
|
||||||
|
|
||||||
// Sets the 'More' mode for browsing documents. Updates the documents section to have more items.
|
// Sets the 'More' mode for browsing documents. Updates the documents section to have more items.
|
||||||
@ -430,7 +427,7 @@ Sideshow.prototype = {
|
|||||||
if (!this._appsSection.has_clip)
|
if (!this._appsSection.has_clip)
|
||||||
this._appsSection.set_clip(0, 0, this._appsSection.width, this._appsSection.height);
|
this._appsSection.set_clip(0, 0, this._appsSection.width, this._appsSection.height);
|
||||||
|
|
||||||
this._moreDocsText.hide();
|
this._moreDocsLink.actor.hide();
|
||||||
this._docsSection.set_clip(0, 0, this._docsSection.width, this._docsSection.height);
|
this._docsSection.set_clip(0, 0, this._docsSection.width, this._docsSection.height);
|
||||||
|
|
||||||
// Move the selection to the docs section if it was in the apps section.
|
// Move the selection to the docs section if it was in the apps section.
|
||||||
@ -469,7 +466,7 @@ Sideshow.prototype = {
|
|||||||
|
|
||||||
this._moreDocsMode = false;
|
this._moreDocsMode = false;
|
||||||
|
|
||||||
this._moreDocsText.hide();
|
this._moreDocsLink.actor.hide();
|
||||||
|
|
||||||
this._docsSection.set_clip(0, 0, this._docsSection.width, this._docsSection.height);
|
this._docsSection.set_clip(0, 0, this._docsSection.width, this._docsSection.height);
|
||||||
|
|
||||||
@ -520,12 +517,12 @@ Sideshow.prototype = {
|
|||||||
this._docDisplay.updateDimensions(this._width + this._additionalWidth,
|
this._docDisplay.updateDimensions(this._width + this._additionalWidth,
|
||||||
this._itemDisplayHeight + SIDESHOW_SECTION_MISC_HEIGHT,
|
this._itemDisplayHeight + SIDESHOW_SECTION_MISC_HEIGHT,
|
||||||
EXPANDED_SIDESHOW_COLUMNS);
|
EXPANDED_SIDESHOW_COLUMNS);
|
||||||
this._moreDocsText.text = "Less...";
|
this._moreDocsLink.setText("Less...");
|
||||||
} else {
|
} else {
|
||||||
this._docDisplay.updateDimensions(this._width, this._docsSectionDefaultHeight - SIDESHOW_SECTION_MISC_HEIGHT, SIDESHOW_COLUMNS);
|
this._docDisplay.updateDimensions(this._width, this._docsSectionDefaultHeight - SIDESHOW_SECTION_MISC_HEIGHT, SIDESHOW_COLUMNS);
|
||||||
this._moreDocsText.text = "More...";
|
this._moreDocsLink.setText("More...");
|
||||||
}
|
}
|
||||||
this._moreDocsText.show();
|
this._moreDocsLink.actor.show();
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user