diff --git a/README.md b/README.md index 0dcb0032..de46a574 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ inspired by Scratch written by Jens Mönig and Brian Harvey jens@moenig.org, bh@cs.berkeley.edu -Copyright (C) 2017 by Jens Mönig and Brian Harvey +Copyright (C) 2018 by Jens Mönig and Brian Harvey Snap! is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as diff --git a/history.txt b/history.txt index 5c1073dc..2fb4afea 100755 --- a/history.txt +++ b/history.txt @@ -3826,6 +3826,10 @@ Fixes: ------ * new "direction to..." primitive as variant of "distance to..." in "Sensing" +180104 +------ +* Morphic: scroll menus if they are taller than the world + v4.1.1 Features: @@ -3833,4 +3837,5 @@ v4.1.1 Features: * new "direction to..." primitive as variant of "distance to..." in "Sensing" Fixes: +* scroll menus if they are taller than the world * enabled color picker for pen trails on stage diff --git a/morphic.js b/morphic.js index 6098416a..bb040f04 100644 --- a/morphic.js +++ b/morphic.js @@ -8,7 +8,7 @@ written by Jens Mönig jens@moenig.org - Copyright (C) 2017 by Jens Mönig + Copyright (C) 2018 by Jens Mönig This file is part of Snap!. @@ -1161,7 +1161,7 @@ /*global window, HTMLCanvasElement, FileReader, Audio, FileList*/ -var morphicVersion = '2017-September-26'; +var morphicVersion = '2018-January-04'; var modules = {}; // keep track of additional loaded modules var useBlurredShadows = getBlurredShadowSupport(); // check for Chrome-bug @@ -3135,22 +3135,22 @@ Morph.prototype.setFullCenter = function (aPoint) { Morph.prototype.keepWithin = function (aMorph) { // make sure I am completely within another Morph's bounds var leftOff, rightOff, topOff, bottomOff; - leftOff = this.fullBounds().left() - aMorph.left(); - if (leftOff < 0) { - this.moveBy(new Point(-leftOff, 0)); - } rightOff = this.fullBounds().right() - aMorph.right(); if (rightOff > 0) { this.moveBy(new Point(-rightOff, 0)); } - topOff = this.fullBounds().top() - aMorph.top(); - if (topOff < 0) { - this.moveBy(new Point(0, -topOff)); + leftOff = this.fullBounds().left() - aMorph.left(); + if (leftOff < 0) { + this.moveBy(new Point(-leftOff, 0)); } bottomOff = this.fullBounds().bottom() - aMorph.bottom(); if (bottomOff > 0) { this.moveBy(new Point(0, -bottomOff)); } + topOff = this.fullBounds().top() - aMorph.top(); + if (topOff < 0) { + this.moveBy(new Point(0, -topOff)); + } }; Morph.prototype.scrollIntoView = function () { @@ -7769,16 +7769,38 @@ MenuMorph.prototype.unselectAllItems = function () { this.children.forEach(function (item) { if (item instanceof MenuItemMorph) { item.image = item.normalImage; + } else if (item instanceof ScrollFrameMorph) { + item.contents.children.forEach(function (morph) { + if (morph instanceof MenuItemMorph) { + morph.image = morph.normalImage; + } + }); } }); this.changed(); }; +// MenuMorph popping up + MenuMorph.prototype.popup = function (world, pos) { + var scroller; + this.drawNew(); this.setPosition(pos); this.addShadow(new Point(2, 2), 80); this.keepWithin(world); + + if (this.bottom() > world.bottom()) { + // scroll menu items if the menu is taller than the world + this.removeShadow(); + scroller = this.scroll(); + this.bounds.corner.y = world.bottom() - 2; + MenuMorph.uber.drawNew.call(this); + this.addShadow(new Point(2, 2), 80); + scroller.setHeight(world.bottom() - scroller.top() - 6); + scroller.adjustScrollBars(); // ? + } + if (world.activeMenu) { world.activeMenu.destroy(); } @@ -7791,6 +7813,21 @@ MenuMorph.prototype.popup = function (world, pos) { this.fullChanged(); }; +MenuMorph.prototype.scroll = function () { + // private - move all items into a scroll frame + var scroller = new ScrollFrameMorph(), + start = this.label ? 1 : 0, + first = this.children[start]; + + scroller.setPosition(first.position()); + this.children.slice(start).forEach(function (morph) { + scroller.addContents(morph); + }); + this.add(scroller); + scroller.setWidth(first.width()); + return scroller; +}; + MenuMorph.prototype.popUpAtHand = function (world) { var wrrld = world || this.world; this.popup(wrrld, wrrld.hand.position()); @@ -9620,7 +9657,7 @@ MenuItemMorph.prototype.mouseLeave = function () { MenuItemMorph.prototype.mouseDownLeft = function (pos) { if (this.isListItem()) { - this.parent.unselectAllItems(); + this.parentThatIsA(MenuMorph).unselectAllItems(); this.escalateEvent('mouseDownLeft', pos); } this.image = this.pressImage; @@ -9638,7 +9675,7 @@ MenuItemMorph.prototype.mouseClickLeft = function () { this.popUpSubmenu(); } else { if (!this.isListItem()) { - this.parent.closeRootMenu(); + this.parentThatIsA(MenuMorph).closeRootMenu(); this.world().activeMenu = null; } this.trigger(); @@ -9646,8 +9683,9 @@ MenuItemMorph.prototype.mouseClickLeft = function () { }; MenuItemMorph.prototype.isListItem = function () { - if (this.parent) { - return this.parent.isListContents; + var menu = this.parentThatIsA(MenuMorph); + if (menu) { + return menu.isListContents; } return false; };