components.js

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

JS
1,006
字号
//  ***** BEGIN LICENSE BLOCK *****// Version: MPL 1.1// // The contents of this file are subject to the Mozilla Public License  // Version// 1.1 (the "License"); you may not use this file except in compliance  // with// the License. You may obtain a copy of the License at// http://www.mozilla.org/MPL/// // Software distributed under the License is distributed on an "AS IS"  // basis,// WITHOUT WARRANTY OF ANY KIND, either express or implied. See the  // License// for the specific language governing rights and limitations under the// License.// // The Original Code is Bespin.// // The Initial Developer of the Original Code is Mozilla.// Portions created by the Initial Developer are Copyright (C) 2009// the Initial Developer. All Rights Reserved.// // Contributor(s):// // ***** END LICENSE BLOCK *****// dojo.provide("th.components");dojo.declare("th.components.Button", th.Component, {    paint: function(ctx) {        var d = this.d();        if (this.style.topImage && this.style.middleImage && this.style.bottomImage) {            if (d.b.h >= this.style.topImage.height + this.style.bottomImage.height) {                ctx.drawImage(this.style.topImage, 0, 0);                if (d.b.h > this.style.topImage.height + this.style.bottomImage.height) {                    ctx.drawImage(this.style.middleImage, 0, this.style.topImage.height, this.style.middleImage.width, d.b.h - this.style.topImage.height - this.style.bottomImage.height);                }                ctx.drawImage(this.style.bottomImage, 0, d.b.h - this.style.bottomImage.height);            }        } else if (this.style.backgroundImage) {            ctx.drawImage(this.style.backgroundImage, 0, 0);        } else {            ctx.fillStyle = "red";            ctx.fillRect(0, 0, d.b.w, d.b.h);        }    }});dojo.declare("th.components.Scrollbar", th.Container, {    constructor: function(parms) {        if (!parms) parms = {};        this.orientation = parms.orientation || th.VERTICAL;        this.value = parms.value || 0;        this.min = parms.min || 0;        this.max = parms.max || 100;        this.extent = parms.extent || 0.1;        this.increment = parms.increment || 2;        this.up = new th.components.Button();        this.down = new th.components.Button();        this.bar = new th.components.Button();        this.add([ this.up, this.down, this.bar ]);        this.bus.bind("click", this.up, this.scrollup, this);        this.bus.bind("click", this.down, this.scrolldown, this);        this.bus.bind("mousedrag", this.bar, this.onmousedrag, this);        this.bus.bind("mouseup", this.bar, this.onmouseup, this);    },    onmousedrag: function(e) {        var currentPosition = (this.orientation == th.VERTICAL) ? e.clientY : e.clientX;        if (this.dragstart_value == undefined) {            this.dragstart_value = this.value;            this.dragstart_mouse = currentPosition;            return;        }        var diff = currentPosition - this.dragstart_mouse;  // difference in pixels; needs to be translated to a difference in value        var pixel_range = this.bounds.height - this.up.bounds.height - this.down.bounds.height - this.bar.bounds.height; // total number of pixels that map to the value range        var pixel_to_value_ratio = (this.max - this.min) / pixel_range;        this.value = this.dragstart_value + Math.floor(diff * pixel_to_value_ratio);        if (this.value < this.min) this.value = this.min;        if (this.value > this.max) this.value = this.max;        if (this.scrollable) this.scrollable.scrollTop = this.value;        this.render();        if (this.scrollable) this.scrollable.repaint();    },    onmouseup: function(e) {        delete this.dragstart_value;        delete this.dragstart_mouse;    },    scrollup: function(e) {        if (this.value > this.min) {            this.value = Math.max(this.min, this.value - this.increment);            if (this.scrollable) this.scrollable.scrollTop = this.value;            this.render();            if (this.scrollable) this.scrollable.repaint();        }    },    scrolldown: function(e) {        if (this.value < this.max) {            this.value = Math.min(this.max, this.value + this.increment);            if (this.scrollable) this.scrollable.scrollTop = this.value;            this.render();            if (this.scrollable) this.scrollable.repaint();        }    },    layout: function() {        var d = this.d();        // check if there's a scrollable attached; if so, refresh state        if (this.scrollable) {            var view_height = this.scrollable.bounds.height;            var scrollable_info = this.scrollable.getScrollInfo();            this.min = 0;            this.max = scrollable_info.scrollHeight - view_height;            this.value = scrollable_info.scrollTop;            this.extent = (scrollable_info.scrollHeight - view_height) / scrollable_info.scrollHeight;        }        // if the maximum value is less than the minimum, we're in an invalid state and won't paint anything        if (this.max < this.min) {            for (var i = 0; i < this.children.length; i++) delete this.children[i].bounds;            return;        }        if (this.orientation == th.VERTICAL) {            var w = d.b.iw;            var h = 12;            this.up.bounds = { x: d.i.l + 1, y: d.i.t, width: w, height: h };            this.down.bounds = { x: d.i.l + 1, y: d.b.ih - h, width: w, height: h };            var scroll_track_height = d.b.ih - this.up.bounds.height - this.down.bounds.height;            var extent_length = Math.min(Math.floor(scroll_track_height - (this.extent * scroll_track_height), d.b.ih - this.up.bounds.height - this.down.bounds.height));            var extent_top = Math.floor(this.up.bounds.height + Math.min( (this.value / (this.max - this.min)) * (scroll_track_height - extent_length) ));            this.bar.bounds = { x: d.i.l + 1, y: extent_top, width: d.b.iw, height: extent_length }        } else {        }    },    paint: function(ctx) {        if (this.max < 0) return;        // paint the track        if (this.style.scrollTopImage) ctx.drawImage(this.style.scrollTopImage, 1, this.up.bounds.height);        if (this.style.scrollMiddleImage) ctx.drawImage(this.style.scrollMiddleImage, 1, this.up.bounds.height + this.style.scrollTopImage.height, this.style.scrollMiddleImage.width, this.down.bounds.y - this.down.bounds.height - (this.up.bounds.x - this.up.bounds.height));        if (this.style.scrollBottomImage) ctx.drawImage(this.style.scrollBottomImage, 1, this.down.bounds.y - this.style.scrollBottomImage.height);        // propagate the styles to the children if not already there        if (this.style.scrollHandleTopImage && !this.bar.style.topImage) {            this.bar.style.topImage = this.style.scrollHandleTopImage;            this.bar.style.middleImage = this.style.scrollHandleMiddleImage;            this.bar.style.bottomImage = this.style.scrollHandleBottomImage;            this.up.style.backgroundImage = this.style.scrollUpArrow;            this.down.style.backgroundImage = this.style.scrollDownArrow;        }        this.inherited(arguments);    }     });    dojo.declare("th.components.Panel", th.Container, {    paintSelf: function(ctx) {        if (this.style.backgroundColor) {            ctx.fillStyle = this.style.backgroundColor;            var x = 0;            var y = 0;            var w = this.bounds.width;            var h = this.bounds.height;            ctx.fillRect(x, y, w, h);        }    }   });  dojo.declare("th.components.ResizeNib", th.Component, {     constructor: function(parms) {        this.bus.bind("mousedown", this, this.onmousedown, this);        this.bus.bind("mouseup", this, this.onmouseup, this);        this.bus.bind("mousedrag", this, this.onmousedrag, this);    },    onmousedown: function(e) {        this.startPos = { x: e.clientX, y: e.clientY};    },    onmousedrag: function(e) {        if (this.startPos) {            if (!this.firedDragStart) {                this.bus.fire("dragstart", this.startPos, this);                this.firedDragStart = true;            }            this.bus.fire("drag", { startPos: this.startPos, currentPos: { x: e.clientX, y: e.clientY } }, this);        }    },    onmouseup: function(e) {        if (this.startPos && this.firedDragStart) {            this.bus.fire("dragstop", { startPos: this.startPos, currentPos: { x: e.clientX, y: e.clientY } }, this);            delete this.firedDragStart;        }        delete this.startPos;    },    paint: function(ctx) {        var d = this.d();          if (this.attributes.orientation == th.VERTICAL) {            var bw = 7;            var x = Math.floor((d.b.w / 2) - (bw / 2));            var y = 7;            ctx.fillStyle = "rgb(185, 180, 158)";            for (var i = 0; i < 3; i++) {                ctx.fillRect(x, y, bw, 1);                y += 3;            }            y = 8;            ctx.fillStyle = "rgb(10, 10, 8)";            for (var i = 0; i < 3; i++) {                ctx.fillRect(x, y, bw, 1);                y += 3;            }        } else {            var bh = 7;            var dw = 8; // width of the bar area            var dh = bh + 2; // height of the bar area            var x = Math.floor(d.b.w / 2 - (dw / 2));            var y = Math.floor(d.b.h / 2 - (dh / 2));            // lay down the shadowy bits            var cx = x;            ctx.fillStyle = "rgba(0, 0, 0, 0.1)";            for (var i = 0; i < 3; i++) {                ctx.fillRect(cx, y, 1, dh);                cx += 3;            }            // lay down the black shadow            var cx = x + 1;            ctx.fillStyle = "black";            for (var i = 0; i < 3; i++) {                ctx.fillRect(cx, y + dh - 1, 1, 1);                cx += 3;            }            // draw the bars            var cx = x + 1;            ctx.fillStyle = "rgb(183, 180, 160)";            for (var i = 0; i < 3; i++) {                ctx.fillRect(cx, y + 1, 1, bh);                cx += 3;            }        }    }    });/*    A "splitter" that visually demarcates areas of an interface. Can also have some "nibs" on its ends to facilitate resizing.    Provides "dragstart", "drag", and "dragstop" events that are fired when a nib is dragged. Orientation is in terms of a container and    is confusing; HORIZONTAL means the splitter is actually displayed taller than wide--what might be called vertically, and similarly    VERTICAL means the splitter is wider than it is tall, i.e., horizontally. This is because the *container* is laid out such that    different regions are stacked horizontally or vertically, and the splitter demarcates those areas.    This bit of confusion was deemed better than having the orientation for a hierarchy of components be different but contributing to the    same end.    Note also that this component uses getPreferredHeight() and getPreferredWidth() differently than most; only one of the methods is    valid for a particular orientation. I.e., when in HORIZONTAL orientation, getPreferredWidth() should be used and getPreferredHeight()    ignored. */ dojo.declare("th.components.Splitter", th.Container, {     constructor: function(parms) {        this.topNib = new th.components.ResizeNib({ attributes: { orientation: this.attributes.orientation } });        this.bottomNib = new th.components.ResizeNib({ attributes: { orientation: this.attributes.orientation } });        this.add(this.topNib, this.bottomNib);        this.label = parms.label;        if (this.label) this.add(this.label);        this.scrollbar = parms.scrollbar;        if (this.scrollbar) this.add(this.scrollbar);        this.bus.bind("drag", [ this.topNib, this.bottomNib ], this.ondrag, this);        this.bus.bind("dragstart", [ this.topNib, this.bottomNib ], this.ondragstart, this);        this.bus.bind("dragstop", [ this.topNib, this.bottomNib ], this.ondragstop, this);    },    ondrag: function(e) {        this.bus.fire("drag", e, this);    },    ondragstart: function(e) {        this.bus.fire("dragstart", e, this);    },    ondragstop: function(e) {        this.bus.fire("dragstop", e, this);    },    getPreferredHeight: function(width) {        return 20;    },    getPreferredWidth: function(height) {        return 16;    },    layout: function() {        var d = this.d();        // if the orientation isn't explicitly set, guess it by examining the ratio        if (!this.attributes.orientation) this.attributes.orientation = (this.bounds.height > this.bounds.width) ? th.HORIZONTAL : th.VERTICAL;

⌨️ 快捷键说明

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