// // cookies.js // // version 2.0 // // Created by Sam Gateau, 4/1/2015 // A simple ui panel that present a list of porperties and the proper widget to edit it // // Distributed under the Apache License, Version 2.0. // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // var SLIDER_RANGE_INCREMENT_SCALE = 1 / 1000; var THUMB_COLOR = { red: 150, green: 150, blue: 150 }; var THUMB_HIGHLIGHT = { red: 255, green: 255, blue: 255 }; var CHECK_MARK_COLOR = { red: 70, green: 70, blue: 90 }; // The Slider class (function() { var Slider = function(x, y, width, thumbSize) { this.background = Overlays.addOverlay("text", { backgroundColor: { red: 200, green: 200, blue: 255 }, x: x, y: y, width: width, height: thumbSize, alpha: 1.0, backgroundAlpha: 0.5, visible: true }); this.thumb = Overlays.addOverlay("text", { backgroundColor: THUMB_COLOR, x: x, y: y, width: thumbSize, height: thumbSize, alpha: 1.0, backgroundAlpha: 1.0, visible: true }); this.thumbSize = thumbSize; this.thumbHalfSize = 0.5 * thumbSize; this.minThumbX = x + this.thumbHalfSize; this.maxThumbX = x + width - this.thumbHalfSize; this.thumbX = this.minThumbX; this.minValue = 0.0; this.maxValue = 1.0; this.y = y; this.clickOffsetX = 0; this.isMoving = false; this.visible = true; }; Slider.prototype.updateThumb = function() { var thumbTruePos = this.thumbX - 0.5 * this.thumbSize; Overlays.editOverlay(this.thumb, { x: thumbTruePos }); }; Slider.prototype.isClickableOverlayItem = function(item) { return (item == this.thumb) || (item == this.background); }; Slider.prototype.onMousePressEvent = function(event, clickedOverlay) { if (!this.isClickableOverlayItem(clickedOverlay)) { this.isMoving = false; return; } this.highlight(); this.isMoving = true; var clickOffset = event.x - this.thumbX; if ((clickOffset > -this.thumbHalfSize) && (clickOffset < this.thumbHalfSize)) { this.clickOffsetX = clickOffset; } else { this.clickOffsetX = 0; this.thumbX = event.x; this.updateThumb(); this.onValueChanged(this.getValue()); } }; Slider.prototype.onMouseMoveEvent = function(event) { if (this.isMoving) { var newThumbX = event.x - this.clickOffsetX; if (newThumbX < this.minThumbX) { newThumbX = this.minThumbX; } if (newThumbX > this.maxThumbX) { newThumbX = this.maxThumbX; } this.thumbX = newThumbX; this.updateThumb(); this.onValueChanged(this.getValue()); } }; Slider.prototype.onMouseReleaseEvent = function(event) { this.isMoving = false; this.unhighlight(); }; Slider.prototype.updateWithKeys = function(direction) { this.range = this.maxThumbX - this.minThumbX; this.thumbX += direction * (this.range * SCALE); this.updateThumb(); this.onValueChanged(this.getValue()); }; Slider.prototype.highlight = function() { if (this.highlighted) { return; } Overlays.editOverlay(this.thumb, { backgroundColor: { red: 255, green: 255, blue: 255 } }); this.highlighted = true; }; Slider.prototype.unhighlight = function() { if (!this.highlighted) { return; } Overlays.editOverlay(this.thumb, { backgroundColor: THUMB_COLOR }); this.highlighted = false; }; Slider.prototype.setNormalizedValue = function(value) { if (value < 0.0) { this.thumbX = this.minThumbX; } else if (value > 1.0) { this.thumbX = this.maxThsumbX; } else { this.thumbX = value * (this.maxThumbX - this.minThumbX) + this.minThumbX; } this.updateThumb(); }; Slider.prototype.getNormalizedValue = function() { return (this.thumbX - this.minThumbX) / (this.maxThumbX - this.minThumbX); }; Slider.prototype.setValue = function(value) { var normValue = (value - this.minValue) / (this.maxValue - this.minValue); this.setNormalizedValue(normValue); }; Slider.prototype.getValue = function() { return this.getNormalizedValue() * (this.maxValue - this.minValue) + this.minValue; }; Slider.prototype.reset = function(resetValue) { this.setValue(resetValue); this.onValueChanged(resetValue); }; Slider.prototype.setMinValue = function(minValue) { var currentValue = this.getValue(); this.minValue = minValue; this.setValue(currentValue); }; Slider.prototype.getMinValue = function() { return this.minValue; }; Slider.prototype.setMaxValue = function(maxValue) { var currentValue = this.getValue(); this.maxValue = maxValue; this.setValue(currentValue); }; Slider.prototype.getMaxValue = function() { return this.maxValue; }; Slider.prototype.onValueChanged = function(value) {}; Slider.prototype.getHeight = function() { if (!this.visible) { return 0; } return 1.5 * this.thumbSize; }; Slider.prototype.moveUp = function(newY) { Overlays.editOverlay(this.background, { y: newY }); Overlays.editOverlay(this.thumb, { y: newY }); }; Slider.prototype.moveDown = function() { Overlays.editOverlay(this.background, { y: this.y }); Overlays.editOverlay(this.thumb, { y: this.y }); }; this.setThumbColor = function(color) { Overlays.editOverlay(this.thumb, { backgroundColor: { red: color.x * 255, green: color.y * 255, blue: color.z * 255 } }); }; this.setBackgroundColor = function(color) { Overlays.editOverlay(this.background, { backgroundColor: { red: color.x * 255, green: color.y * 255, blue: color.z * 255 } }); }; Slider.prototype.hide = function() { Overlays.editOverlay(this.background, { visible: false }); Overlays.editOverlay(this.thumb, { visible: false }); this.visible = false; }; Slider.prototype.show = function() { Overlays.editOverlay(this.background, { visible: true }); Overlays.editOverlay(this.thumb, { visible: true }); this.visible = true; }; Slider.prototype.destroy = function() { Overlays.deleteOverlay(this.background); Overlays.deleteOverlay(this.thumb); }; this.Slider = Slider; // The Checkbox class var Checkbox = function(x, y, width, thumbSize) { this.thumb = Overlays.addOverlay("text", { backgroundColor: THUMB_COLOR, textFontSize: 10, x: x, y: y, width: thumbSize, height: thumbSize, alpha: 1.0, backgroundAlpha: 1.0, visible: true }); this.thumbSize = thumbSize; var checkX = x + (0.25 * thumbSize); var checkY = y + (0.25 * thumbSize); this.y = y; this.boxCheckStatus = true; this.clickedBox = false; this.visible = true; this.checkMark = Overlays.addOverlay("text", { backgroundColor: CHECK_MARK_COLOR, x: checkX, y: checkY, width: thumbSize / 2.0, height: thumbSize / 2.0, alpha: 1.0, visible: true }); }; Checkbox.prototype.updateThumb = function() { Overlays.editOverlay(this.checkMark, { visible: this.boxCheckStatus }); }; Checkbox.prototype.isClickableOverlayItem = function(item) { return (item == this.thumb) || (item == this.checkMark); }; Checkbox.prototype.onMousePressEvent = function(event, clickedOverlay) { if (!this.isClickableOverlayItem(clickedOverlay)) { return; } this.boxCheckStatus = !this.boxCheckStatus; this.onValueChanged(this.getValue()); this.updateThumb(); }; Checkbox.prototype.onMouseReleaseEvent = function(event) {}; Checkbox.prototype.updateWithKeys = function() { this.boxCheckStatus = !this.boxCheckStatus; this.onValueChanged(this.getValue()); this.updateThumb(); }; Checkbox.prototype.highlight = function() { Overlays.editOverlay(this.thumb, { backgroundColor: THUMB_HIGHLIGHT }); this.highlighted = true; }; Checkbox.prototype.unhighlight = function() { Overlays.editOverlay(this.thumb, { backgroundColor: THUMB_COLOR }); this.highlighted = false; }; Checkbox.prototype.setValue = function(value) { this.boxCheckStatus = value; }; Checkbox.prototype.setterFromWidget = function(value) { this.updateThumb(); }; Checkbox.prototype.getValue = function() { return this.boxCheckStatus; }; Checkbox.prototype.reset = function(resetValue) { this.setValue(resetValue); }; Checkbox.prototype.onValueChanged = function(value) {}; Checkbox.prototype.getHeight = function() { if (!this.visible) { return 0; } return 1.5 * this.thumbSize; }; Checkbox.prototype.moveUp = function(newY) { Overlays.editOverlay(this.background, { y: newY }); Overlays.editOverlay(this.thumb, { y: newY }); Overlays.editOverlay(this.checkMark, { y: newY + (0.25 * this.thumbSize) }); Overlays.editOverlay(this.unCheckMark, { y: newY + (0.25 * this.thumbSize) }); }; Checkbox.prototype.moveDown = function() { Overlays.editOverlay(this.background, { y: this.y }); Overlays.editOverlay(this.thumb, { y: this.y }); Overlays.editOverlay(this.checkMark, { y: this.y + (0.25 * this.thumbSize) }); Overlays.editOverlay(this.unCheckMark, { y: this.y+ (0.25 * this.thumbSize) }); }; Checkbox.prototype.hide = function() { Overlays.editOverlay(this.background, { visible: false }); Overlays.editOverlay(this.thumb, { visible: false }); Overlays.editOverlay(this.checkMark, { visible: false }); Overlays.editOverlay(this.unCheckMark, { visible: false }); this.visible = false; } Checkbox.prototype.show = function() { Overlays.editOverlay(this.background, { visible: true }); Overlays.editOverlay(this.thumb, { visible: true }); Overlays.editOverlay(this.checkMark, { visible: true }); Overlays.editOverlay(this.unCheckMark, { visible: true }); this.visible = true; } Checkbox.prototype.destroy = function() { Overlays.deleteOverlay(this.background); Overlays.deleteOverlay(this.thumb); Overlays.deleteOverlay(this.checkMark); Overlays.deleteOverlay(this.unCheckMark); }; this.Checkbox = Checkbox; // The ColorBox class var ColorBox = function(x, y, width, thumbSize) { var self = this; var slideHeight = thumbSize / 3; var sliderWidth = width; this.red = new Slider(x, y, width, slideHeight); this.green = new Slider(x, y + slideHeight, width, slideHeight); this.blue = new Slider(x, y + 2 * slideHeight, width, slideHeight); this.red.setBackgroundColor({ x: 1, y: 0, z: 0 }); this.green.setBackgroundColor({ x: 0, y: 1, z: 0 }); this.blue.setBackgroundColor({ x: 0, y: 0, z: 1 }); this.red.onValueChanged = this.setterFromWidget; this.green.onValueChanged = this.setterFromWidget; this.blue.onValueChanged = this.setterFromWidget; this.visible = true; }; ColorBox.prototype.isClickableOverlayItem = function(item) { return this.red.isClickableOverlayItem(item) || this.green.isClickableOverlayItem(item) || this.blue.isClickableOverlayItem(item); }; ColorBox.prototype.onMousePressEvent = function(event, clickedOverlay) { this.red.onMousePressEvent(event, clickedOverlay); if (this.red.isMoving) { return; } this.green.onMousePressEvent(event, clickedOverlay); if (this.green.isMoving) { return; } this.blue.onMousePressEvent(event, clickedOverlay); }; ColorBox.prototype.onMouseMoveEvent = function(event) { this.red.onMouseMoveEvent(event); this.green.onMouseMoveEvent(event); this.blue.onMouseMoveEvent(event); }; ColorBox.prototype.onMouseReleaseEvent = function(event) { this.red.onMouseReleaseEvent(event); this.green.onMouseReleaseEvent(event); this.blue.onMouseReleaseEvent(event); }; ColorBox.prototype.updateWithKeys = function(direction) { this.red.updateWithKeys(direction); this.green.updateWithKeys(direction); this.blue.updateWithKeys(direction); } ColorBox.prototype.highlight = function() { this.red.highlight(); this.green.highlight(); this.blue.highlight(); this.highlighted = true; }; ColorBox.prototype.unhighlight = function() { this.red.unhighlight(); this.green.unhighlight(); this.blue.unhighlight(); this.highlighted = false; }; ColorBox.prototype.setterFromWidget = function(value) { var color = this.getValue(); this.onValueChanged(color); this.updateRGBSliders(color); }; ColorBox.prototype.onValueChanged = function(value) {}; ColorBox.prototype.updateRGBSliders = function(color) { this.red.setThumbColor({ x: color.x, y: 0, z: 0 }); this.green.setThumbColor({ x: 0, y: color.y, z: 0 }); this.blue.setThumbColor({ x: 0, y: 0, z: color.z }); }; // Public members: ColorBox.prototype.setValue = function(value) { this.red.setValue(value.x); this.green.setValue(value.y); this.blue.setValue(value.z); this.updateRGBSliders(value); }; ColorBox.prototype.getValue = function() { var value = { x: this.red.getValue(), y: this.green.getValue(), z: this.blue.getValue() }; return value; }; ColorBox.prototype.reset = function(resetValue) { this.setValue(resetValue); this.onValueChanged(resetValue); }; ColorBox.prototype.getHeight = function() { if (!this.visible) { return 0; } return 1.5 * this.thumbSize; }; ColorBox.prototype.moveUp = function(newY) { this.red.moveUp(newY); this.green.moveUp(newY); this.blue.moveUp(newY); }; ColorBox.prototype.moveDown = function() { this.red.moveDown(); this.green.moveDown(); this.blue.moveDown(); }; ColorBox.prototype.hide = function() { this.red.hide(); this.green.hide(); this.blue.hide(); this.visible = false; } ColorBox.prototype.show = function() { this.red.show(); this.green.show(); this.blue.show(); this.visible = true; } ColorBox.prototype.destroy = function() { this.red.destroy(); this.green.destroy(); this.blue.destroy(); }; this.ColorBox = ColorBox; // The DirectionBox class var DirectionBox = function(x, y, width, thumbSize) { var self = this; var slideHeight = thumbSize / 2; var sliderWidth = width; this.yaw = new Slider(x, y, width, slideHeight); this.pitch = new Slider(x, y + slideHeight, width, slideHeight); this.yaw.setThumbColor({ x: 1, y: 0, z: 0 }); this.yaw.minValue = -180; this.yaw.maxValue = +180; this.pitch.setThumbColor({ x: 0, y: 0, z: 1 }); this.pitch.minValue = -1; this.pitch.maxValue = +1; this.yaw.onValueChanged = this.setterFromWidget; this.pitch.onValueChanged = this.setterFromWidget; this.visible = true; }; DirectionBox.prototype.isClickableOverlayItem = function(item) { return this.yaw.isClickableOverlayItem(item) || this.pitch.isClickableOverlayItem(item); }; DirectionBox.prototype.onMousePressEvent = function(event, clickedOverlay) { this.yaw.onMousePressEvent(event, clickedOverlay); if (this.yaw.isMoving) { return; } this.pitch.onMousePressEvent(event, clickedOverlay); }; DirectionBox.prototype.onMouseMoveEvent = function(event) { this.yaw.onMouseMoveEvent(event); this.pitch.onMouseMoveEvent(event); }; DirectionBox.prototype.onMouseReleaseEvent = function(event) { this.yaw.onMouseReleaseEvent(event); this.pitch.onMouseReleaseEvent(event); }; DirectionBox.prototype.updateWithKeys = function(direction) { this.yaw.updateWithKeys(direction); this.pitch.updateWithKeys(direction); }; DirectionBox.prototype.highlight = function() { this.pitch.highlight(); this.yaw.highlight(); this.highlighted = true; }; DirectionBox.prototype.unhighlight = function() { this.pitch.unhighlight(); this.yaw.unhighlight(); this.highlighted = false; }; DirectionBox.prototype.setterFromWidget = function(value) { var yawPitch = this.getValue(); this.onValueChanged(yawPitch); }; DirectionBox.prototype.onValueChanged = function(value) {}; DirectionBox.prototype.setValue = function(direction) { var flatXZ = Math.sqrt(direction.x * direction.x + direction.z * direction.z); if (flatXZ > 0.0) { var flatX = direction.x / flatXZ; var flatZ = direction.z / flatXZ; var yaw = Math.acos(flatX) * 180 / Math.PI; if (flatZ < 0) { yaw = -yaw; } this.yaw.setValue(yaw); } this.pitch.setValue(direction.y); }; DirectionBox.prototype.getValue = function() { var dirZ = this.pitch.getValue(); var yaw = this.yaw.getValue() * Math.PI / 180; var cosY = Math.sqrt(1 - dirZ * dirZ); var value = { x: cosY * Math.cos(yaw), y: dirZ, z: cosY * Math.sin(yaw) }; return value; }; DirectionBox.prototype.reset = function(resetValue) { this.setValue(resetValue); this.onValueChanged(resetValue); }; DirectionBox.prototype.getHeight = function() { if (!this.visible) { return 0; } return 1.5 * this.thumbSize; }; DirectionBox.prototype.moveUp = function(newY) { this.pitch.moveUp(newY); this.yaw.moveUp(newY); }; DirectionBox.prototype.moveDown = function(newY) { this.pitch.moveDown(); this.yaw.moveDown(); }; DirectionBox.prototype.hide = function() { this.pitch.hide(); this.yaw.hide(); this.visible = false; } DirectionBox.prototype.show = function() { this.pitch.show(); this.yaw.show(); this.visible = true; } DirectionBox.prototype.destroy = function() { this.yaw.destroy(); this.pitch.destroy(); }; this.DirectionBox = DirectionBox; var textFontSize = 12; var CollapsablePanelItem = function(name, x, y, textWidth, height) { this.name = name; this.height = height; this.y = y; this.isCollapsable = true; var topMargin = (height - 1.5 * textFontSize); this.thumb = Overlays.addOverlay("image", { color: { red: 255, green: 255, blue: 255 }, imageURL: Script.getExternalPath(Script.ExternalPaths.Assets, 'images/tools/expand-ui.svg'), x: x, y: y, width: rawHeight, height: rawHeight, alpha: 1.0, visible: true }); this.title = Overlays.addOverlay("text", { backgroundColor: { red: 255, green: 255, blue: 255 }, x: x + rawHeight * 1.5, y: y, width: textWidth, height: height, alpha: 1.0, backgroundAlpha: 0.5, visible: true, text: " " + name, font: { size: textFontSize }, topMargin: topMargin }); }; CollapsablePanelItem.prototype.destroy = function() { Overlays.deleteOverlay(this.title); Overlays.deleteOverlay(this.thumb); }; CollapsablePanelItem.prototype.editTitle = function(opts) { Overlays.editOverlay(this.title, opts); }; CollapsablePanelItem.prototype.hide = function() { Overlays.editOverlay(this.title, { visible: false }); Overlays.editOverlay(this.thumb, { visible: false }); if (this.widget != null) { this.widget.hide(); } }; CollapsablePanelItem.prototype.show = function() { Overlays.editOverlay(this.title, { visible: true }); Overlays.editOverlay(this.thumb, { visible: true }); if (this.widget != null) { this.widget.show(); } }; CollapsablePanelItem.prototype.moveUp = function(newY) { Overlays.editOverlay(this.title, { y: newY }); Overlays.editOverlay(this.thumb, { y: newY }); if (this.widget != null) { this.widget.moveUp(newY); } } CollapsablePanelItem.prototype.moveDown = function() { Overlays.editOverlay(this.title, { y: this.y }); Overlays.editOverlay(this.thumb, { y: this.y }); if (this.widget != null) { this.widget.moveDown(); } } this.CollapsablePanelItem = CollapsablePanelItem; var PanelItem = function(name, setter, getter, displayer, x, y, textWidth, valueWidth, height) { //print("creating panel item: " + name); this.isCollapsable = false; this.name = name; this.y = y; this.isCollapsed = false; this.displayer = typeof displayer !== 'undefined' ? displayer : function(value) { if (value == true) { return "On"; } else if (value == false) { return "Off"; } return value.toFixed(2); }; var topMargin = (height - 1.5 * textFontSize); this.title = Overlays.addOverlay("text", { backgroundColor: { red: 255, green: 255, blue: 255 }, x: x, y: y, width: textWidth, height: height, alpha: 1.0, backgroundAlpha: 0.5, visible: true, text: " " + name, font: { size: textFontSize }, topMargin: topMargin }); this.value = Overlays.addOverlay("text", { backgroundColor: { red: 255, green: 255, blue: 255 }, x: x + textWidth, y: y, width: valueWidth, height: height, alpha: 1.0, backgroundAlpha: 0.5, visible: true, text: this.displayer(getter()), font: { size: textFontSize }, topMargin: topMargin }); this.getter = getter; this.resetValue = getter(); this.setter = function(value) { setter(value); Overlays.editOverlay(this.value, { text: this.displayer(getter()) }); if (this.widget) { this.widget.setValue(value); } //print("successfully set value of widget to " + value); }; this.setterFromWidget = function(value) { setter(value); // ANd loop back the value after the final setter has been called var value = getter(); if (this.widget) { this.widget.setValue(value); } Overlays.editOverlay(this.value, { text: this.displayer(value) }); }; this.widget = null; }; PanelItem.prototype.hide = function() { Overlays.editOverlay(this.title, { visible: false }); Overlays.editOverlay(this.value, { visible: false }); if (this.widget != null) { this.widget.hide(); } }; PanelItem.prototype.show = function() { Overlays.editOverlay(this.title, { visible: true }); Overlays.editOverlay(this.value, { visible: true }); if (this.widget != null) { this.widget.show(); } }; PanelItem.prototype.moveUp = function(newY) { Overlays.editOverlay(this.title, { y: newY }); Overlays.editOverlay(this.value, { y: newY }); if (this.widget != null) { this.widget.moveUp(newY); } }; PanelItem.prototype.moveDown = function() { Overlays.editOverlay(this.title, { y: this.y }); Overlays.editOverlay(this.value, { y: this.y }); if (this.widget != null) { this.widget.moveDown(); } }; PanelItem.prototype.destroy = function() { Overlays.deleteOverlay(this.title); Overlays.deleteOverlay(this.value); if (this.widget != null) { this.widget.destroy(); } }; this.PanelItem = PanelItem; var textWidth = 180; var valueWidth = 100; var widgetWidth = 300; var rawHeight = 20; var rawYDelta = rawHeight * 1.5; var outerPanel = true; var widgets; var Panel = function(x, y) { if (outerPanel) { widgets = []; } outerPanel = false; this.x = x; this.y = y; this.nextY = y; print("creating panel at x: " + this.x + " y: " + this.y); this.widgetX = x + textWidth + valueWidth; this.items = new Array(); this.activeWidget = null; this.visible = true; this.indentation = 30; }; Panel.prototype.mouseMoveEvent = function(event) { if (this.activeWidget) { this.activeWidget.onMouseMoveEvent(event); } }; Panel.prototype.mousePressEvent = function(event) { // Make sure we quitted previous widget if (this.activeWidget) { this.activeWidget.onMouseReleaseEvent(event); } this.activeWidget = null; var clickedOverlay = Overlays.getOverlayAtPoint({ x: event.x, y: event.y }); this.handleCollapse(clickedOverlay); // If the user clicked any of the slider background then... for (var i in this.items) { var item = this.items[i]; var widget = this.items[i].widget; if (widget.isClickableOverlayItem(clickedOverlay)) { this.activeWidget = widget; this.activeWidget.onMousePressEvent(event, clickedOverlay); break; } } }; Panel.prototype.mouseReleaseEvent = function(event) { if (this.activeWidget) { this.activeWidget.onMouseReleaseEvent(event); } this.activeWidget = null; }; // Reset panel item upon double-clicking Panel.prototype.mouseDoublePressEvent = function(event) { var clickedOverlay = Overlays.getOverlayAtPoint({ x: event.x, y: event.y }); this.handleReset(clickedOverlay); }; Panel.prototype.handleReset = function(clickedOverlay) { for (var i in this.items) { var item = this.items[i]; var widget = item.widget; if (item.isSubPanel && widget) { widget.handleReset(clickedOverlay); } if (clickedOverlay == item.title) { item.activeWidget = widget; item.activeWidget.reset(item.resetValue); break; } } }; Panel.prototype.handleCollapse = function(clickedOverlay) { for (var i in this.items) { var item = this.items[i]; var widget = item.widget; if (item.isSubPanel && widget) { widget.handleCollapse(clickedOverlay); } if (!item.isCollapsed && item.isCollapsable && clickedOverlay == item.thumb) { Overlays.editOverlay(item.thumb, { imageURL: Script.getExternalPath(Script.ExternalPaths.Assets, 'images/tools/expand-right.svg') }); this.collapse(clickedOverlay); item.isCollapsed = true; } else if (item.isCollapsed && item.isCollapsable && clickedOverlay == item.thumb) { Overlays.editOverlay(item.thumb, { imageURL: Script.getExternalPath(Script.ExternalPaths.Assets, 'images/tools/expand-ui.svg') }); this.expand(clickedOverlay); item.isCollapsed = false; } } }; Panel.prototype.collapse = function(clickedOverlay) { var keys = Object.keys(this.items); for (var i = 0; i < keys.length; ++i) { var item = this.items[keys[i]]; if (item.isCollapsable && clickedOverlay == item.thumb) { var panel = item.widget; panel.hide(); break; } } // Now recalculate new heights of subsequent widgets for (var j = i + 1; j < keys.length; ++j) { this.items[keys[j]].moveUp(this.getCurrentY(keys[j])); } }; Panel.prototype.expand = function(clickedOverlay) { var keys = Object.keys(this.items); for (var i = 0; i < keys.length; ++i) { var item = this.items[keys[i]]; if (item.isCollapsable && clickedOverlay == item.thumb) { var panel = item.widget; panel.show(); break; } } // Now recalculate new heights of subsequent widgets for (var j = i + 1; j < keys.length; ++j) { this.items[keys[j]].moveDown(); } }; Panel.prototype.onMousePressEvent = function(event, clickedOverlay) { for (var i in this.items) { var item = this.items[i]; if (item.widget.isClickableOverlayItem(clickedOverlay)) { item.activeWidget = item.widget; item.activeWidget.onMousePressEvent(event, clickedOverlay); } } }; Panel.prototype.onMouseMoveEvent = function(event) { for (var i in this.items) { var item = this.items[i]; if (item.activeWidget) { item.activeWidget.onMouseMoveEvent(event); } } }; Panel.prototype.onMouseReleaseEvent = function(event, clickedOverlay) { for (var i in this.items) { var item = this.items[i]; if (item.activeWidget) { item.activeWidget.onMouseReleaseEvent(event); } item.activeWidget = null; } }; Panel.prototype.onMouseDoublePressEvent = function(event, clickedOverlay) { for (var i in this.items) { var item = this.items[i]; if (item.activeWidget) { item.activeWidget.onMouseDoublePressEvent(event); } } }; var tabView = false; var tabIndex = 0; Panel.prototype.keyPressEvent = function(event) { if (event.text == "TAB" && !event.isShifted) { tabView = true; if (tabIndex < widgets.length) { if (tabIndex > 0 && widgets[tabIndex - 1].highlighted) { // Unhighlight previous widget widgets[tabIndex - 1].unhighlight(); } widgets[tabIndex].highlight(); tabIndex++; } else { widgets[tabIndex - 1].unhighlight(); //Wrap around to front tabIndex = 0; widgets[tabIndex].highlight(); tabIndex++; } } else if (tabView && event.isShifted) { if (tabIndex > 0) { tabIndex--; if (tabIndex < widgets.length && widgets[tabIndex + 1].highlighted) { // Unhighlight previous widget widgets[tabIndex + 1].unhighlight(); } widgets[tabIndex].highlight(); } else { widgets[tabIndex].unhighlight(); //Wrap around to end tabIndex = widgets.length - 1; widgets[tabIndex].highlight(); } } else if (event.text == "LEFT") { for (var i = 0; i < widgets.length; i++) { // Find the highlighted widget, allow control with arrow keys if (widgets[i].highlighted) { var k = -1; widgets[i].updateWithKeys(k); break; } } } else if (event.text == "RIGHT") { for (var i = 0; i < widgets.length; i++) { // Find the highlighted widget, allow control with arrow keys if (widgets[i].highlighted) { var k = 1; widgets[i].updateWithKeys(k); break; } } } }; // Widget constructors Panel.prototype.newSlider = function(name, minValue, maxValue, setValue, getValue, displayValue) { this.nextY = this.y + this.getHeight(); var item = new PanelItem(name, setValue, getValue, displayValue, this.x, this.nextY, textWidth, valueWidth, rawHeight); var slider = new Slider(this.widgetX, this.nextY, widgetWidth, rawHeight); slider.minValue = minValue; slider.maxValue = maxValue; widgets.push(slider); item.widget = slider; item.widget.onValueChanged = function(value) { item.setterFromWidget(value); }; item.setter(getValue()); this.items[name] = item; }; Panel.prototype.newCheckbox = function(name, setValue, getValue, displayValue) { var display; if (displayValue == true) { display = function() { return "On"; }; } else if (displayValue == false) { display = function() { return "Off"; }; } this.nextY = this.y + this.getHeight(); var item = new PanelItem(name, setValue, getValue, display, this.x, this.nextY, textWidth, valueWidth, rawHeight); var checkbox = new Checkbox(this.widgetX, this.nextY, widgetWidth, rawHeight); widgets.push(checkbox); item.widget = checkbox; item.widget.onValueChanged = function(value) { item.setterFromWidget(value); }; item.setter(getValue()); this.items[name] = item; //print("created Item... checkbox=" + name); }; Panel.prototype.newColorBox = function(name, setValue, getValue, displayValue) { this.nextY = this.y + this.getHeight(); var item = new PanelItem(name, setValue, getValue, displayValue, this.x, this.nextY, textWidth, valueWidth, rawHeight); var colorBox = new ColorBox(this.widgetX, this.nextY, widgetWidth, rawHeight); widgets.push(colorBox); item.widget = colorBox; item.widget.onValueChanged = function(value) { item.setterFromWidget(value); }; item.setter(getValue()); this.items[name] = item; // print("created Item... colorBox=" + name); }; Panel.prototype.newDirectionBox = function(name, setValue, getValue, displayValue) { this.nextY = this.y + this.getHeight(); var item = new PanelItem(name, setValue, getValue, displayValue, this.x, this.nextY, textWidth, valueWidth, rawHeight); var directionBox = new DirectionBox(this.widgetX, this.nextY, widgetWidth, rawHeight); widgets.push(directionBox); item.widget = directionBox; item.widget.onValueChanged = function(value) { item.setterFromWidget(value); }; item.setter(getValue()); this.items[name] = item; // print("created Item... directionBox=" + name); }; Panel.prototype.newSubPanel = function(name) { this.nextY = this.y + this.getHeight(); var item = new CollapsablePanelItem(name, this.x, this.nextY, textWidth, rawHeight); item.isSubPanel = true; this.nextY += 1.5 * item.height; var subPanel = new Panel(this.x + this.indentation, this.nextY); item.widget = subPanel; this.items[name] = item; return subPanel; // print("created Item... subPanel=" + name); }; Panel.prototype.onValueChanged = function(value) { for (var i in this.items) { this.items[i].widget.onValueChanged(value); } }; Panel.prototype.set = function(name, value) { var item = this.items[name]; if (item != null) { return item.setter(value); } return null; }; Panel.prototype.get = function(name) { var item = this.items[name]; if (item != null) { return item.getter(); } return null; }; Panel.prototype.getWidget = function(name) { var item = this.items[name]; if (item != null) { return item.widget; } return null; }; Panel.prototype.update = function(name) { var item = this.items[name]; if (item != null) { return item.setter(item.getter()); } return null; }; Panel.prototype.isClickableOverlayItem = function(item) { for (var i in this.items) { if (this.items[i].widget.isClickableOverlayItem(item)) { return true; } } return false; }; Panel.prototype.getHeight = function() { var height = 0; for (var i in this.items) { height += this.items[i].widget.getHeight(); if (this.items[i].isSubPanel && this.items[i].widget.visible) { height += 1.5 * rawHeight; } } return height; }; Panel.prototype.moveUp = function() { for (var i in this.items) { this.items[i].widget.moveUp(); } }; Panel.prototype.moveDown = function() { for (var i in this.items) { this.items[i].widget.moveDown(); } }; Panel.prototype.getCurrentY = function(key) { var height = 0; var keys = Object.keys(this.items); for (var i = 0; i < keys.indexOf(key); ++i) { var item = this.items[keys[i]]; height += item.widget.getHeight(); if (item.isSubPanel) { height += 1.5 * rawHeight; } } return this.y + height; }; Panel.prototype.hide = function() { for (var i in this.items) { if (this.items[i].isSubPanel) { this.items[i].widget.hide(); } this.items[i].hide(); } this.visible = false; }; Panel.prototype.show = function() { for (var i in this.items) { if (this.items[i].isSubPanel) { this.items[i].widget.show(); } this.items[i].show(); } this.visible = true; }; Panel.prototype.destroy = function() { for (var i in this.items) { if (this.items[i].isSubPanel) { this.items[i].widget.destroy(); } this.items[i].destroy(); } }; this.Panel = Panel; })(); Script.scriptEnding.connect(function scriptEnding() { Controller.releaseKeyEvents({ text: "left" }); Controller.releaseKeyEvents({ key: "right" }); }); Controller.captureKeyEvents({ text: "left" }); Controller.captureKeyEvents({ text: "right" });