82 lines
2.5 KiB
JavaScript
82 lines
2.5 KiB
JavaScript
|
/* -*- 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);
|