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 + -
显示快捷键?