gnome-shell/js/ui/button.js
Marina Zhurakhinskaya babb13f603 Remove unused button width and height arguments and specify button height explicitly
minWidth and minHeight arguments of the Button class were not used.

Panel buttons need their height to be explicitly specified as
PANEL_HEIGHT to take up full panel height. This fixes the problem with the
user not being able to click at the very top edge of the panel to activate
the button.
2009-08-11 18:16:33 -04:00

221 lines
7.7 KiB
JavaScript

/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
const Big = imports.gi.Big;
const Clutter = imports.gi.Clutter;
const Lang = imports.lang;
const Mainloop = imports.mainloop;
const Shell = imports.gi.Shell;
const Tweener = imports.ui.tweener;
const DEFAULT_BUTTON_COLOR = new Clutter.Color();
DEFAULT_BUTTON_COLOR.from_pixel(0xeeddcc66);
const DEFAULT_PRESSED_BUTTON_COLOR = new Clutter.Color();
DEFAULT_PRESSED_BUTTON_COLOR.from_pixel(0xccbbaa66);
const DEFAULT_TEXT_COLOR = new Clutter.Color();
DEFAULT_TEXT_COLOR.from_pixel(0x000000ff);
const DEFAULT_FONT = 'Sans Bold 16px';
// Padding on the left and right side of the button.
const SIDE_PADDING = 14;
function Button(widget, buttonColor, pressedButtonColor, textColor, staysPressed, font) {
this._init(widget, buttonColor, pressedButtonColor, textColor, staysPressed, font);
}
Button.prototype = {
_init : function(widgetOrText, buttonColor, pressedButtonColor, textColor, staysPressed, font) {
let me = this;
this._buttonColor = buttonColor
if (buttonColor == null)
this._buttonColor = DEFAULT_BUTTON_COLOR;
this._pressedButtonColor = pressedButtonColor
if (pressedButtonColor == null)
this._pressedButtonColor = DEFAULT_PRESSED_BUTTON_COLOR;
this._textColor = textColor;
if (textColor == null)
this._textColor = DEFAULT_TEXT_COLOR;
this._staysPressed = staysPressed
if (staysPressed == null)
this._staysPressed = false;
this._font = font;
if (font == null)
this._font = DEFAULT_FONT;
// if this._staysPressed is true, this._active will be true past the first release of a button, until a subsequent one (the button
// is unpressed) or until release() is called explicitly
this._active = false;
this._isBetweenPressAndRelease = false;
this._mouseIsOverButton = false;
this.button = new Big.Box({ reactive: true,
corner_radius: 5,
padding_left: SIDE_PADDING,
padding_right: SIDE_PADDING,
orientation: Big.BoxOrientation.HORIZONTAL,
y_align: Big.BoxAlignment.CENTER
});
if (typeof widgetOrText == 'string') {
this._widget = new Clutter.Text({ font_name: this._font,
color: this._textColor,
text: widgetOrText });
} else {
this._widget = widgetOrText;
}
this.button.append(this._widget, Big.BoxPackFlags.EXPAND);
this.button.connect('button-press-event',
function(o, event) {
me._isBetweenPressAndRelease = true;
me.button.backgroundColor = me._pressedButtonColor;
return false;
});
this.button.connect('button-release-event',
function(o, event) {
me._isBetweenPressAndRelease = false;
if (!me._staysPressed || me._active) {
me.release();
} else {
me._active = true;
}
return false;
});
this.button.connect('enter-event',
function(o, event) {
me._mouseIsOverButton = true;
if (!me._active) {
me.button.backgroundColor = me._buttonColor;
}
return false;
});
this.button.connect('leave-event',
function(o, event) {
me._isBetweenPressAndRelease = false;
me._mouseIsOverButton = false;
if (!me._active) {
me.button.backgroundColor = null;
}
return false;
});
},
pressIn : function() {
if (!this._isBetweenPressAndRelease && this._staysPressed) {
this._active = true;
this.button.backgroundColor = this._pressedButtonColor;
}
},
release : function() {
if (!this._isBetweenPressAndRelease && this._staysPressed) {
this._active = false;
if (this._mouseIsOverButton) {
this.button.backgroundColor = this._buttonColor;
} else {
this.button.backgroundColor = null;
}
}
}
};
/* Delay before the icon should appear, in seconds after the pointer has entered the parent */
const ANIMATION_TIME = 0.25;
/* This is an icon button that fades in/out when mouse enters/leaves the parent.
* A delay is used before the fading starts. You can force it to be shown if needed.
*
* parent -- used to show/hide the button depending on mouse entering/leaving it
* size -- size in pixels of both the button and the icon it contains
* texture -- optional, must be used if the texture for the icon is already created (else, use setIconFromName)
*/
function iconButton(parent, size, texture) {
this._init(parent, size, texture);
}
iconButton.prototype = {
_init : function(parent, size, texture) {
this._size = size;
if (texture)
this.actor = texture;
else
this.actor = new Clutter.Texture({ width: this._size, height: this._size });
this.actor.set_reactive(true);
this.actor.set_opacity(0);
parent.connect("enter-event", Lang.bind(this, function(actor, event) {
this._shouldHide = false;
// Nothing to do if the cursor has come back from a child of the parent actor
if (actor.get_children().indexOf(Shell.get_event_related(event)) != -1)
return;
this._fadeIn();
}));
parent.connect("leave-event", Lang.bind(this, function(actor, event) {
// Nothing to do if the cursor has merely entered a child of the parent actor
if (actor.get_children().indexOf(Shell.get_event_related(event)) != -1)
return;
// Remember that we should not be visible to hide the button if forceShow is unset
if (this._forceShow) {
this._shouldHide = true;
return;
}
this._fadeOut();
}));
},
/// Private methods ///
setIconFromName : function(iconName) {
let iconTheme = Gtk.IconTheme.get_default();
let iconInfo = iconTheme.lookup_icon(iconName, this._size, 0);
if (!iconInfo)
return;
let iconPath = iconInfo.get_filename();
this.actor.set_from_file(iconPath);
},
// Useful if we want to show the button immediately,
// e.g. in case the mouse is already in the parent when the button is created
show : function() {
this.actor.set_opacity(255);
},
// If show is true, prevents the button from fading out
forceShow : function(show) {
this._forceShow = show;
// Hide the button if it should have been hidden under normal conditions
if (!this._forceShow && this._shouldHide) {
this._fadeOut();
}
},
/// Private methods ///
_fadeIn : function() {
Tweener.removeTweens(this.actor);
Tweener.addTween(this.actor, { opacity: 255,
time: ANIMATION_TIME,
transition :"easeInQuad" });
},
_fadeOut : function() {
Tweener.removeTweens(this.actor);
Tweener.addTween(this.actor, { opacity: 0,
time: ANIMATION_TIME,
transition :"easeOutQuad" });
}
};