components.js

来自「在线编辑器」· JavaScript 代码 · 共 1,006 行 · 第 1/3 页

JS
1,006
字号
        if (this.attributes.orientation == th.HORIZONTAL) {            this.topNib.bounds = { x: 0, y: 0, height: d.b.w, width: d.b.w }            this.bottomNib.bounds = { x: 0, y: this.bounds.height - d.b.w, height: d.b.w, width: d.b.w }            if (this.scrollbar && this.scrollbar.shouldLayout()) {                this.scrollbar.bounds = { x: 0, y: this.topNib.bounds.height, height: d.b.h - (this.topNib.bounds.height * 2), width: d.b.w };            }        } else {            this.topNib.bounds = { x: 0, y: 0, height: d.b.h, width: d.b.h }            this.bottomNib.bounds = { x: d.b.w - d.b.h, y: 0, height: d.b.h, width: d.b.h }            if (this.label) {                this.label.bounds = { x: this.topNib.bounds.x + this.topNib.bounds.width, y: 0, height: d.b.h, width: d.b.w - (d.b.h * 2) }            }        }    },    paintSelf: function(ctx) {        var d = this.d();        if (this.attributes.orientation == th.VERTICAL) {            ctx.fillStyle = "rgb(73, 72, 66)";            ctx.fillRect(0, 0, d.b.w, 1);            ctx.fillStyle = "black";            ctx.fillRect(0, d.b.h - 1, d.b.w, 1);            var gradient = ctx.createLinearGradient(0, 1, 0, d.b.h - 1);            gradient.addColorStop(0, "rgb(50, 48, 42)");            gradient.addColorStop(1, "rgb(22, 22, 19)");            ctx.fillStyle = gradient;            ctx.fillRect(0, 1, d.b.w, d.b.h - 2);        } else {            ctx.fillStyle = "rgb(105, 105, 99)";            ctx.fillRect(0, 0, 1, d.b.h);            ctx.fillStyle = "black";            ctx.fillRect(d.b.w - 1, 0, 1, d.b.h);            var gradient = ctx.createLinearGradient(1, 0, d.b.w - 2, 0);            gradient.addColorStop(0, "rgb(56, 55, 49)");            gradient.addColorStop(1, "rgb(62, 61, 55)");            ctx.fillStyle = gradient;            ctx.fillRect(1, 0, d.b.w - 2, d.b.h);        }    }});dojo.declare("th.components.SplitPanelContainer", th.components.Panel, {    constructor: function(parms) {        this.splitter = new th.components.Splitter({ attributes: { orientation: this.attributes.orientation }, label: parms.label });    },    getContents: function() {                                                         var childrenWithoutSplitter = dojo.filter(this.children,             dojo.hitch(this, function(item){ return item != this.splitter; })        );        if (childrenWithoutSplitter.length > 0) return childrenWithoutSplitter[0];    },    layout: function() {        var childrenWithoutSplitter = dojo.filter(this.children,             dojo.hitch(this, function(item){ return item != this.splitter; })        );        if (this.children.length == childrenWithoutSplitter.length) this.add(this.splitter);        var slength = (this.attributes.orientation == th.HORIZONTAL) ?                      this.splitter.getPreferredWidth(this.bounds.height) :                      this.splitter.getPreferredHeight(this.bounds.width);        if (this.splitter.shouldLayout()) {            if (this.attributes.orientation == th.HORIZONTAL) {                this.splitter.bounds = { x: this.bounds.width - slength, y: 0, height: this.bounds.height, width: slength };             } else {                this.splitter.bounds = { x: 0, y: this.bounds.height - slength, height: slength, width: this.bounds.width };            }        } else {            slength = 0;        }        // only the first non-splitter child is laid out        if (childrenWithoutSplitter.length > 0) {            if (this.attributes.orientation == th.HORIZONTAL) {                childrenWithoutSplitter[0].bounds = { x: 0, y: 0, height: this.bounds.height, width: this.bounds.width - slength }            } else {                childrenWithoutSplitter[0].bounds = { x: 0, y: 0, height: this.bounds.height - slength, width: this.bounds.width }            }        }    }});/*    A component that allocates all visible space to two or more nested regions. */dojo.declare("th.components.SplitPanel", th.components.Panel, {    constructor: function(parms) {        if (!this.attributes.orientation) this.attributes.orientation = th.HORIZONTAL;        if (!this.attributes.regions) this.attributes.regions = [{},{}];    },    ondragstart: function(e) {        var container = e.thComponent.parent; // splitter -> splitpanecontainer        container.region.startSize = container.region.size;    },    ondrag: function(e) {        var container = e.thComponent.parent; // splitter -> splitpanecontainer        var delta = (this.attributes.orientation == th.HORIZONTAL) ? e.currentPos.x - e.startPos.x : e.currentPos.y - e.startPos.y;        container.region.size = container.region.startSize + delta;        this.render();    },    ondragstop: function(e) {        var container = e.thComponent.parent; // splitter -> splitpanecontainer        delete container.region.startSize;    },    layout: function() {        this.remove(this.children); // remove any of the existing region panels        /*           iterate through each region, performing a couple of tasks:            - create a container for each region if it doesn't already have one            - put the value of the contents property of region into the container if necessary            - hide the splitter on the last region         */        for (var i = 0; i < this.attributes.regions.length; i++) {            var region = this.attributes.regions[i];            if (!region.container) {                region.container = new th.components.SplitPanelContainer({ attributes: { orientation: this.attributes.orientation }, label: region.label });                region.container.region = region;   // give the container a reference back to the region                // capture the start size of the region when the nib's drag starts                this.bus.bind("dragstart", region.container.splitter, this.ondragstart, this);                this.bus.bind("drag", region.container.splitter, this.ondrag, this);                this.bus.bind("dragstop", region.container.splitter, this.ondragstop, this);            }            // update the content panel for the split panel container            if (region.contents && (region.contents != region.container.getContents())) {                region.container.removeAll();                region.container.add(region.contents);            }            // make the last container's splitter invisible            if (i == this.attributes.regions.length - 1) region.container.splitter.style.display = "none";            this.add(region.container);        }        var containerSize = (this.attributes.orientation == th.HORIZONTAL) ? this.bounds.width : this.bounds.height;        // size the regions        var totalSize = 0;        for (var i = 0; i < this.attributes.regions.length; i++) {            var r = this.attributes.regions[i];            if (!r.size) {                r.size = (this.attributes.defaultSize || (100 / this.attributes.regions.length) + "%");            }            if (th.helpers.isPercentage(r.size)) {                // percentage lengths are allowed, but will be immediately converted to pixels                r.size = Math.floor((parseInt(r.size) / 100) * containerSize);             }            // enforce a minimum width            if (r.size < 30) r.size = 30;            totalSize += r.size;        }        if (totalSize > containerSize) {   // if the regions are bigger than the split pane size, shrink 'em, right-to-left            var diff = totalSize - containerSize;            for (var i = this.attributes.regions.length - 1; i >= 0; i--) {                var r = this.attributes.regions[i];                var originalSize = r.size;                r.size -= diff;                if (r.size < 30) r.size = 30;                diff -= (originalSize - r.size);                if (diff <= 0) break;            }        } else if (totalSize < containerSize) {    // if the regions are smaller, grow 'em, all in the last one            var r = this.attributes.regions[this.attributes.regions.length - 1].size += (containerSize - totalSize);        }        var startPx = 0;        for (var i = 0; i < this.attributes.regions.length; i++) {            var region = this.attributes.regions[i];            if (this.attributes.orientation == th.HORIZONTAL) {                region.container.bounds = { x: startPx, y: 0, width: region.size, height: this.bounds.height };            } else {                region.container.bounds = { x: 0, y: startPx, width: this.bounds.width, height: region.size };            }            startPx += region.size;        }            }});dojo.declare("th.components.Label", th.components.Panel, {    constructor: function(parms) {         if (!parms) parms = {};        if (!this.border) this.border = new th.borders.EmptyBorder({ insets: { left: 5, right: 5, top: 2, bottom: 2 }});        this.attributes.text = parms.text || "";        if (!this.style.font) this.style.font = "12pt Arial";        if (!this.style.color) this.style.color = "black";     },    styleContext: function(ctx) {        if (!ctx) return;        ctx.font = this.style.font;        ctx.fillStyle = this.style.color;                return ctx;    },    getPreferredWidth: function(height) {        var ctx = this.styleContext(this.parent.getScratchContext());        // the +2 is to compensate for anti-aliasing on Windows, which isn't taken into account in measurements; this fudge factor should eventually become platform-specific        var w = ctx.measureText(this.attributes.text).width + 2;        return w + this.getInsets().left + this.getInsets().right;    },    getPreferredHeight: function(width) {        var ctx = this.styleContext(this.parent.getScratchContext());        var h = Math.floor(ctx.measureText(this.attributes.text).ascent * 1.5);   // multiplying by 2 to fake a descent and leading        return h + this.getInsets().top + this.getInsets().bottom;    },    paint: function(ctx) {        var d = this.d();        if (this.style.backgroundColor) this.inherited(arguments);         this.styleContext(ctx);        var textMetrics = ctx.measureText(this.attributes.text);        var textToRender = this.attributes.text;        var lastLength = textToRender.length - 2;        while (textMetrics.width > (d.b.w - d.i.w)) {            if (lastLength == 0) {                textToRender = "...";                break;            }            var left = Math.floor(lastLength / 2);            var right = left + (lastLength % 2);            textToRender = this.attributes.text.substring(0, left) + "..." + this.attributes.text.substring(this.attributes.text.length - right);            textMetrics = ctx.measureText(textToRender);            lastLength -= 1;        }        ctx.fillText(textToRender, this.getInsets().left, this.getInsets().top + textMetrics.ascent);    }});dojo.declare("th.components.ExpandingInfoPanel", th.components.Panel, {    getMinimumRowHeight: function() {        return 40;    },    getMinimumColumnWidth: function() {            },    layout: function() {        if (this.children.length == 0) return;        var d = this.d();        var rows = Math.floor(Math.sqrt(this.children.length));        var height = Math.floor(d.b.h / rows);        while (height < this.getMinimumRowHeight() && rows > 1) {            rows--;            height = Math.floor(d.b.h / rows);         }        var perRow = Math.floor(this.children.length / rows);        var remainder = this.children.length % rows;        // TODO: verify a minimum height (and perhaps width)        var currentChild = 0;        var heightRemainder = d.b.h % rows;        var currentY = 0;        for (var i = 0; i < rows; i++) {            var h = (i == rows - 1) ? height + heightRemainder : height;            var cols = (remainder > 0) ? perRow + 1 : perRow;            remainder--;            var width = Math.floor(d.b.w / cols);            var widthRemainder = d.b.w % cols;            var currentX = 0;            for (var z = 0; z < cols; z++) {                var w = (z == cols - 1) ? width + widthRemainder : width;                this.children[currentChild++].bounds = { x: currentX, y: currentY, width: w, height: h };                currentX += w;            }            currentY += h;        }    }});dojo.declare("th.components.List", th.Container, {    constructor: function(parms) {        if (!parms) parms = {};        this.items = parms.items || [];        this.scrollTop = 0;        this.bus.bind("mousedown", this, this.onmousedown, this);                  this.renderer = new th.components.Label({ style: { border: new th.borders.EmptyBorder({ size: 3 }) }});    },    onmousedown: function(e) {        var item = this.getItemForPosition({ x: e.componentX, y: e.componentY });        if (item != this.selected) {            if (item) this.selected = item; else delete this.selected;            this.bus.fire("itemselected", { container: this, item: this.selected }, this);             this.repaint();        }    },

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?