Auto-scroll the flyout to the selected category

This commit is contained in:
Eric Rosenbaum 2017-08-23 16:58:05 -04:00
parent 3e18337d26
commit faa7ee8bc0
2 changed files with 41 additions and 6 deletions

View file

@ -37,6 +37,7 @@ goog.require('goog.dom');
goog.require('goog.events');
goog.require('goog.math.Rect');
goog.require('goog.userAgent');
goog.require('goog.dom.animationFrame.polyfill');
/**
@ -331,12 +332,42 @@ Blockly.VerticalFlyout.prototype.scrollToStart = function() {
this.scrollbar_.set(0);
};
/**
* Scroll the flyout to a position.
* @param {Number} pos The targeted scroll position.
*/
Blockly.VerticalFlyout.prototype.scrollTo = function(pos) {
this.scrollTarget = pos * this.workspace_.scale;
this.step();
};
/**
* Step the scrolling animation by scrolling a fraction of the way to
* a scroll target, and request the next frame if necessary.
*/
Blockly.VerticalFlyout.prototype.step = function() {
if (!this.scrollTarget) return;
var scrollYPos = -this.workspace_.scrollY;
var diff = this.scrollTarget - scrollYPos;
if (Math.abs(diff) < 1) {
this.scrollbar_.set(this.scrollTarget);
return;
}
this.scrollbar_.set(scrollYPos + diff * 0.3);
// Polyfilled by goog.dom.animationFrame.polyfill
requestAnimationFrame(this.step.bind(this));
};
/**
* Scroll the flyout.
* @param {!Event} e Mouse wheel scroll event.
* @private
*/
Blockly.VerticalFlyout.prototype.wheel_ = function(e) {
// remove scrollTarget to stop auto scrolling in step()
this.scrollTarget = null;
var delta = e.deltaY;
if (delta) {

View file

@ -325,18 +325,22 @@ Blockly.Toolbox.prototype.getSelectedItem = function() {
*/
Blockly.Toolbox.prototype.setSelectedItem = function(item) {
if (this.selectedItem_) {
// Don't do anything if they selected the already-open category.
if (this.selectedItem_ == item) {
return;
}
// They selected a different category but one was already open. Close it.
this.selectedItem_.setSelected(false);
}
this.selectedItem_ = item;
if (this.selectedItem_ != null) {
this.selectedItem_.setSelected(true);
this.flyout_.show(item.getContents());
this.flyout_.scrollToStart();
// Scroll flyout to the top of the selected category
var categoryName = item.name_;
for (var i=0; i<this.flyout_.buttons_.length; i++) {
if (this.flyout_.buttons_[i].text_ === categoryName) {
this.flyout_.scrollTo(this.flyout_.buttons_[i].position_.y);
return;
}
}
}
};
}
};