<commit_before>module('lively.morphic.Layout').requires('lively.morphic.Core', 'lively.morphic.Widgets'/*for Window*/ /*, 'apps.dwarfcassowary.js.DwarfCassowary'*/).toRun(function() {

lively.morphic.Morph.addMethods(
'layouting', {
    // if you want a specific morph not be layouted (morph being part of a layout,
    // set this to false)
    isLayoutable: true,

    noLayoutDuring: function(func) {
        var orig = this.isInLayoutCycle, self = this;
        function enableLayouting() { self.isInLayoutCycle = orig; }
        this.isInLayoutCycle = false;
        try {
            return func.length ? func.call(this, enableLayouting) : func.call(this);
        } finally { if (!func.length) enableLayouting(); }
    },

    adjustForNewBounds: function() {
        // resizeVertical, resizeHorizontal, moveVertical, moveHorizontal

        if (this.getLayouter()) {
            this.applyLayout();
            return;
        }

        var newExtent = this.getShape().getBounds().extent();
        if (!this.priorExtent) {
            this.priorExtent = newExtent;
            return;
        }

        var scalePt = newExtent.scaleByPt(this.priorExtent.invertedSafely()),
            diff = newExtent.subPt(this.priorExtent);

        for (var i = 0; i < this.submorphs.length; i++) {
            var morph = this.submorphs[i], spec = morph.layout;
            if (!spec || morph.isInLayoutCycle) continue;
            var moveX = 0, moveY = 0, resizeX = 0, resizeY = 0;

            if (spec.centeredHorizontal)
                moveX = this.innerBounds().center().x - morph.bounds().center().x;
            if (spec.centeredVertical)
                moveY = this.innerBounds().center().y - morph.bounds().center().y;

            if (spec.moveHorizontal) moveX = diff.x;
            if (spec.moveVertical) moveY = diff.y;
            if (spec.resizeWidth) resizeX = diff.x;
            if (spec.resizeHeight) resizeY = diff.y;

            if (spec.scaleHorizontal || spec.scaleVertical) {
                var morphScale = pt(
                    spec.scaleHorizontal ? scalePt.x : 1,
                    spec.scaleVertical ? scalePt.y : 1);
                morph.setPosition(morph.getPosition().scaleByPt(morphScale));
                morph.setExtent(morph.getExtent().scaleByPt(morphScale));
            }

            if (moveX || moveY) morph.moveBy(pt(moveX, moveY));
            if (resizeX || resizeY) morph.setExtent(morph.getExtent().addXY(resizeX, resizeY));
        }

        this.priorExtent = newExtent;
    },

    setLayouter: function(layouter) {
        if (!this.layout) {
            this.layout = {};
        }
        if (layouter && !(layouter instanceof lively.morphic.Layout.Layout) && layouter.type) {
            var klass;
            switch (layouter.type) {
                case 'vertical': klass = lively.morphic.Layout.VerticalLayout; break;
                case 'horizontal': klass = lively.morphic.Layout.HorizontalLayout; break;
                case 'tiling': klass = lively.morphic.Layout.TileLayout; break;
                default: klass = lively.morphic.Layout.TileLayout; break;
            }
            var l = new klass(this);
            l.setBorderSize(layouter.border || 3);
            l.setSpacing(layouter.spacing || 3);
            layouter = l;
        }
        this.layout.layouter = layouter;
    },

    getLayouter: function() {
        return this.layout ? this.layout.layouter: undefined;
    },

    getMinWidth: function() {
        if (!this.doesResize('width')) return this.getExtent().x;
        if (!this.getLayouter()) return 0;
        if (lively.morphic.Layout.widthClipHidden(this)) return 0;
        return this.getLayouter().getMinWidth(this, this.getLayoutableSubmorphs());
    },

    getMinHeight: function() {
        if (!this.doesResize('height')) return this.getExtent().y;
        if (!this.getLayouter()) return 0;
        if (lively.morphic.Layout.heightClipHidden(this)) return 0;
        return this.getLayouter().getMinHeight(this, this.getLayoutableSubmorphs());
    },

    submorphResized: function(aSubmorph) {
        // my submorph aSubmorph has changed its size
        var layouter = this.getLayouter();
        if (layouter && layouter.handlesSubmorphResized()) {
            layouter.onSubmorphResized(this, aSubmorph, this.getLayoutableSubmorphs());
        }
    },
    submorphDragged: function(aMorph, evt) {
        // this is very generic code called in the lively.morphic.Events
        // maybe this code should go elsewhere?
        this.applyLayout();
    },
    applyLayout: function() {
        var layouter = this.getLayouter();
        layouter && layouter.layout(this, this.getLayoutableSubmorphs());
    },

    setPositionTopLeft: function(pos) {
          this.setPosition(this.getOrigin().addPt(pos));
    },
    setPositionCentered: function(pos) {
        this.setPosition(pos.subPt(this.innerBounds().center()));
    },

    getLayoutableSubmorphs: function() {
        // reject is damn slow..., optimize it!
        return this.submorphs.select(function (m) {
            return !m.isEpiMorph && !m.isBeingDragged && m.isLayoutable
        })
    },

    getPositionInWorld: function() {
        // renamed to make absolutely sure it does not collide with Magnet>>getGlobalPosition..
        return this.getGlobalTransform().transformPoint(pt(0,0).subPt(this.getOrigin()));
    },

    obtainPlaceholder: function(forMorph) {
        return this.placeholder || (this.placeholder = this.createPlaceholder());
    },

    createPlaceholder: function() {
        // use grab shadow as placeholder; or fall back to normal morphic copy
        this.placeholder = this.getGrabShadow() || this.copy();
        this.placeholder.isBeingDragged = false;
        this.placeholder.isPlaceholder = true;
        this.placeholder.ignoreEvents();
        this.placeholder.applyStyle({
            fill: Color.gray,
            borderWidth: 0,
            enableDropping: false
        });
        return this.placeholder;
    },

    destroyPlaceholder: function() {
        var placeholder = this.placeholder;
        if (!placeholder) return;
        delete this.placeholder;
        var owner = placeholder.owner;
        placeholder.remove();
        if (owner && owner.layout && owner.layout.extentWithoutPlaceholder) {<commit_msg>setPositionInWorld<commit_after>module('lively.morphic.Layout').requires('lively.morphic.Core', 'lively.morphic.Widgets'/*for Window*/ /*, 'apps.dwarfcassowary.js.DwarfCassowary'*/).toRun(function() {

lively.morphic.Morph.addMethods(
'layouting', {
    // if you want a specific morph not be layouted (morph being part of a layout,
    // set this to false)
    isLayoutable: true,

    noLayoutDuring: function(func) {
        var orig = this.isInLayoutCycle, self = this;
        function enableLayouting() { self.isInLayoutCycle = orig; }
        this.isInLayoutCycle = false;
        try {
            return func.length ? func.call(this, enableLayouting) : func.call(this);
        } finally { if (!func.length) enableLayouting(); }
    },

    adjustForNewBounds: function() {
        // resizeVertical, resizeHorizontal, moveVertical, moveHorizontal

        if (this.getLayouter()) {
            this.applyLayout();
            return;
        }

        var newExtent = this.getShape().getBounds().extent();
        if (!this.priorExtent) {
            this.priorExtent = newExtent;
            return;
        }

        var scalePt = newExtent.scaleByPt(this.priorExtent.invertedSafely()),
            diff = newExtent.subPt(this.priorExtent);

        for (var i = 0; i < this.submorphs.length; i++) {
            var morph = this.submorphs[i], spec = morph.layout;
            if (!spec || morph.isInLayoutCycle) continue;
            var moveX = 0, moveY = 0, resizeX = 0, resizeY = 0;

            if (spec.centeredHorizontal)
                moveX = this.innerBounds().center().x - morph.bounds().center().x;
            if (spec.centeredVertical)
                moveY = this.innerBounds().center().y - morph.bounds().center().y;

            if (spec.moveHorizontal) moveX = diff.x;
            if (spec.moveVertical) moveY = diff.y;
            if (spec.resizeWidth) resizeX = diff.x;
            if (spec.resizeHeight) resizeY = diff.y;

            if (spec.scaleHorizontal || spec.scaleVertical) {
                var morphScale = pt(
                    spec.scaleHorizontal ? scalePt.x : 1,
                    spec.scaleVertical ? scalePt.y : 1);
                morph.setPosition(morph.getPosition().scaleByPt(morphScale));
                morph.setExtent(morph.getExtent().scaleByPt(morphScale));
            }

            if (moveX || moveY) morph.moveBy(pt(moveX, moveY));
            if (resizeX || resizeY) morph.setExtent(morph.getExtent().addXY(resizeX, resizeY));
        }

        this.priorExtent = newExtent;
    },

    setLayouter: function(layouter) {
        if (!this.layout) {
            this.layout = {};
        }
        if (layouter && !(layouter instanceof lively.morphic.Layout.Layout) && layouter.type) {
            var klass;
            switch (layouter.type) {
                case 'vertical': klass = lively.morphic.Layout.VerticalLayout; break;
                case 'horizontal': klass = lively.morphic.Layout.HorizontalLayout; break;
                case 'tiling': klass = lively.morphic.Layout.TileLayout; break;
                default: klass = lively.morphic.Layout.TileLayout; break;
            }
            var l = new klass(this);
            l.setBorderSize(layouter.border || 3);
            l.setSpacing(layouter.spacing || 3);
            layouter = l;
        }
        this.layout.layouter = layouter;
    },

    getLayouter: function() {
        return this.layout ? this.layout.layouter: undefined;
    },

    getMinWidth: function() {
        if (!this.doesResize('width')) return this.getExtent().x;
        if (!this.getLayouter()) return 0;
        if (lively.morphic.Layout.widthClipHidden(this)) return 0;
        return this.getLayouter().getMinWidth(this, this.getLayoutableSubmorphs());
    },

    getMinHeight: function() {
        if (!this.doesResize('height')) return this.getExtent().y;
        if (!this.getLayouter()) return 0;
        if (lively.morphic.Layout.heightClipHidden(this)) return 0;
        return this.getLayouter().getMinHeight(this, this.getLayoutableSubmorphs());
    },

    submorphResized: function(aSubmorph) {
        // my submorph aSubmorph has changed its size
        var layouter = this.getLayouter();
        if (layouter && layouter.handlesSubmorphResized()) {
            layouter.onSubmorphResized(this, aSubmorph, this.getLayoutableSubmorphs());
        }
    },
    submorphDragged: function(aMorph, evt) {
        // this is very generic code called in the lively.morphic.Events
        // maybe this code should go elsewhere?
        this.applyLayout();
    },
    applyLayout: function() {
        var layouter = this.getLayouter();
        layouter && layouter.layout(this, this.getLayoutableSubmorphs());
    },

    setPositionTopLeft: function(pos) {
          this.setPosition(this.getOrigin().addPt(pos));
    },
    setPositionCentered: function(pos) {
        this.setPosition(pos.subPt(this.innerBounds().center()));
    },

    getLayoutableSubmorphs: function() {
        // reject is damn slow..., optimize it!
        return this.submorphs.select(function (m) {
            return !m.isEpiMorph && !m.isBeingDragged && m.isLayoutable
        })
    },

    getPositionInWorld: function() {
        // renamed to make absolutely sure it does not collide with Magnet>>getGlobalPosition..
        return this.getGlobalTransform().transformPoint(pt(0,0).subPt(this.getOrigin()));
    },
    setPositionInWorld: function(worldPt) {
        // the inverse of getPositionInWorld...
        var localPos = this.getGlobalTransform().inverse().transformPoint(worldPt),
            originOffset = this.getPosition().subPt(this.getOrigin()).addPt(localPos.negated());
        return this.setPosition(originOffset);
    },

    obtainPlaceholder: function(forMorph) {
        return this.placeholder || (this.placeholder = this.createPlaceholder());
    },

    createPlaceholder: function() {
        // use grab shadow as placeholder; or fall back to normal morphic copy
        this.placeholder = this.getGrabShadow() || this.copy();
        this.placeholder.isBeingDragged = false;
        this.placeholder.isPlaceholder = true;
        this.placeholder.ignoreEvents();
        this.placeholder.applyStyle({
            fill: Color.gray,
            borderWidth: 0,
            enableDropping: false
        });
        return this.placeholder;
    },

    destroyPlaceholder: function() {
        var placeholder = this.placeholder;
        if (!placeholder) return;
        delete this.placeholder;
        var owner = placeholder.owner;
        placeholder.remove();
        if (owner && owner.layout && owner.layout.extentWithoutPlaceholder) {
{'fraction_non_alphanumeric': 0.1235998158661961, 'fraction_numerical': 0.0024551173852999848, 'mean_word_length': 2.3312036800408893, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 2, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1756628', 'n_tokens_mistral': 3882, 'n_tokens_neox': 3738, 'n_words': 757}