mirror of
https://github.com/overte-org/overte.git
synced 2025-04-21 06:24:43 +02:00
Merge branch 'master' of https://github.com/highfidelity/hifi into temp0
This commit is contained in:
commit
0973d197cf
19 changed files with 981 additions and 141 deletions
561
examples/html/entityProperties.html
Normal file
561
examples/html/entityProperties.html
Normal file
|
@ -0,0 +1,561 @@
|
|||
<html>
|
||||
<head>
|
||||
<link rel="stylesheet" type="text/css" href="style.css">
|
||||
<script>
|
||||
function enableChildren(el, selector) {
|
||||
els = el.querySelectorAll(selector);
|
||||
for (var i = 0; i < els.length; i++) {
|
||||
els[i].removeAttribute('disabled');
|
||||
}
|
||||
}
|
||||
function disableChildren(el, selector) {
|
||||
els = el.querySelectorAll(selector);
|
||||
for (var i = 0; i < els.length; i++) {
|
||||
els[i].setAttribute('disabled', 'disabled');
|
||||
}
|
||||
}
|
||||
|
||||
function createEmitCheckedPropertyUpdateFunction(propertyName) {
|
||||
return function() {
|
||||
EventBridge.emitWebEvent(
|
||||
'{ "type":"update", "properties":{"' + propertyName + '":' + this.checked + '}}'
|
||||
);
|
||||
};
|
||||
}
|
||||
function createEmitNumberPropertyUpdateFunction(propertyName) {
|
||||
return function() {
|
||||
EventBridge.emitWebEvent(
|
||||
'{ "type":"update", "properties":{"' + propertyName + '":' + this.value + '}}'
|
||||
);
|
||||
};
|
||||
}
|
||||
function createEmitTextPropertyUpdateFunction(propertyName) {
|
||||
return function() {
|
||||
EventBridge.emitWebEvent(
|
||||
'{ "type":"update", "properties":{"' + propertyName + '":"' + this.value + '"}}'
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
function createEmitVec3PropertyUpdateFunction(property, elX, elY, elZ) {
|
||||
return function() {
|
||||
var data = {
|
||||
type: "update",
|
||||
properties: {
|
||||
}
|
||||
};
|
||||
data.properties[property] = {
|
||||
x: elX.value,
|
||||
y: elY.value,
|
||||
z: elZ.value,
|
||||
};
|
||||
EventBridge.emitWebEvent(JSON.stringify(data));
|
||||
}
|
||||
};
|
||||
|
||||
function createEmitColorPropertyUpdateFunction(property, elRed, elGreen, elBlue) {
|
||||
return function() {
|
||||
var data = {
|
||||
type: "update",
|
||||
properties: {
|
||||
}
|
||||
};
|
||||
data.properties[property] = {
|
||||
red: elRed.value,
|
||||
green: elGreen.value,
|
||||
blue: elBlue.value,
|
||||
};
|
||||
EventBridge.emitWebEvent(JSON.stringify(data));
|
||||
}
|
||||
};
|
||||
|
||||
function loaded() {
|
||||
var elType = document.getElementById("property-type");
|
||||
var elLocked = document.getElementById("property-locked");
|
||||
var elVisible = document.getElementById("property-visible");
|
||||
var elPositionX = document.getElementById("property-pos-x");
|
||||
var elPositionY = document.getElementById("property-pos-y");
|
||||
var elPositionZ = document.getElementById("property-pos-z");
|
||||
|
||||
var elDimensionsX = document.getElementById("property-dim-x");
|
||||
var elDimensionsY = document.getElementById("property-dim-y");
|
||||
var elDimensionsZ = document.getElementById("property-dim-z");
|
||||
|
||||
var elRegistrationX = document.getElementById("property-reg-x");
|
||||
var elRegistrationY = document.getElementById("property-reg-y");
|
||||
var elRegistrationZ = document.getElementById("property-reg-z");
|
||||
|
||||
var elLinearVelocityX = document.getElementById("property-lvel-x");
|
||||
var elLinearVelocityY = document.getElementById("property-lvel-y");
|
||||
var elLinearVelocityZ = document.getElementById("property-lvel-z");
|
||||
var elLinearDamping = document.getElementById("property-ldamping");
|
||||
|
||||
var elAngularVelocityX = document.getElementById("property-avel-x");
|
||||
var elAngularVelocityY = document.getElementById("property-avel-y");
|
||||
var elAngularVelocityZ = document.getElementById("property-avel-z");
|
||||
var elAngularDamping = document.getElementById("property-adamping");
|
||||
|
||||
var elGravityX = document.getElementById("property-grav-x");
|
||||
var elGravityY = document.getElementById("property-grav-y");
|
||||
var elGravityZ = document.getElementById("property-grav-z");
|
||||
|
||||
var elMass = document.getElementById("property-mass");
|
||||
var elIgnoreForCollisions = document.getElementById("property-ignore-for-collisions");
|
||||
var elCollisionsWillMove = document.getElementById("property-collisions-will-move");
|
||||
var elLifetime = document.getElementById("property-lifetime");
|
||||
|
||||
var elBoxSection = document.getElementById("box-section");
|
||||
var elBoxColorRed = document.getElementById("property-box-red");
|
||||
var elBoxColorGreen = document.getElementById("property-box-green");
|
||||
var elBoxColorBlue = document.getElementById("property-box-blue");
|
||||
|
||||
var elLightSection = document.getElementById('light-section');
|
||||
var elLightSpotLight = document.getElementById("property-light-spot-light");
|
||||
var elLightDiffuseRed = document.getElementById("property-light-diffuse-red");
|
||||
var elLightDiffuseGreen = document.getElementById("property-light-diffuse-green");
|
||||
var elLightDiffuseBlue = document.getElementById("property-light-diffuse-blue");
|
||||
|
||||
var elLightAmbientRed = document.getElementById("property-light-ambient-red");
|
||||
var elLightAmbientGreen = document.getElementById("property-light-ambient-green");
|
||||
var elLightAmbientBlue = document.getElementById("property-light-ambient-blue");
|
||||
|
||||
var elLightSpecularRed = document.getElementById("property-light-specular-red");
|
||||
var elLightSpecularGreen = document.getElementById("property-light-specular-green");
|
||||
var elLightSpecularBlue = document.getElementById("property-light-specular-blue");
|
||||
|
||||
var elLightConstantAttenuation = document.getElementById("property-light-constant-attenuation");
|
||||
var elLightLinearAttenuation = document.getElementById("property-light-linear-attenuation");
|
||||
var elLightQuadraticAttenuation = document.getElementById("property-light-quadratic-attenuation");
|
||||
var elLightExponent = document.getElementById("property-light-exponent");
|
||||
var elLightCutoff = document.getElementById("property-light-cutoff");
|
||||
|
||||
var elModelSection = document.getElementById("model-section");
|
||||
var elModelURL = document.getElementById("property-model-url");
|
||||
var elModelAnimationURL = document.getElementById("property-model-animation-url");
|
||||
var elModelAnimationPlaying = document.getElementById("property-model-animation-playing");
|
||||
var elModelAnimationFPS = document.getElementById("property-model-animation-fps");
|
||||
|
||||
if (window.EventBridge !== undefined) {
|
||||
EventBridge.scriptEventReceived.connect(function(data) {
|
||||
data = JSON.parse(data);
|
||||
if (data.type == "update") {
|
||||
if (data.properties === undefined) {
|
||||
disableChildren(document.getElementById("properties"), 'input');
|
||||
} else {
|
||||
var properties = data.properties;
|
||||
|
||||
elType.innerHTML = properties.type;
|
||||
|
||||
elLocked.checked = properties.locked;
|
||||
|
||||
if (properties.locked) {
|
||||
disableChildren(document.getElementById("properties"), 'input');
|
||||
elLocked.removeAttribute('disabled');
|
||||
} else {
|
||||
enableChildren(document.getElementById("properties"), 'input');
|
||||
|
||||
elVisible.checked = properties.visible;
|
||||
|
||||
elPositionX.value = properties.position.x.toFixed(2);
|
||||
elPositionY.value = properties.position.y.toFixed(2);
|
||||
elPositionZ.value = properties.position.z.toFixed(2);
|
||||
|
||||
elDimensionsX.value = properties.dimensions.x.toFixed(2);
|
||||
elDimensionsY.value = properties.dimensions.y.toFixed(2);
|
||||
elDimensionsZ.value = properties.dimensions.z.toFixed(2);
|
||||
|
||||
elRegistrationX.value = properties.registrationPoint.x.toFixed(2);
|
||||
elRegistrationY.value = properties.registrationPoint.y.toFixed(2);
|
||||
elRegistrationZ.value = properties.registrationPoint.z.toFixed(2);
|
||||
|
||||
elLinearVelocityX.value = properties.velocity.x.toFixed(2);
|
||||
elLinearVelocityY.value = properties.velocity.y.toFixed(2);
|
||||
elLinearVelocityZ.value = properties.velocity.z.toFixed(2);
|
||||
elLinearDamping.value = properties.damping.toFixed(2);
|
||||
|
||||
elAngularVelocityX.value = properties.angularVelocity.x.toFixed(2);
|
||||
elAngularVelocityY.value = properties.angularVelocity.y.toFixed(2);
|
||||
elAngularVelocityZ.value = properties.angularVelocity.z.toFixed(2);
|
||||
elAngularDamping.value = properties.angularDamping.toFixed(2);
|
||||
|
||||
elGravityX.value = properties.gravity.x.toFixed(2);
|
||||
elGravityY.value = properties.gravity.y.toFixed(2);
|
||||
elGravityZ.value = properties.gravity.z.toFixed(2);
|
||||
|
||||
elMass.value = properties.mass.toFixed(2);
|
||||
elIgnoreForCollisions.checked = properties.ignoreForCollisions;
|
||||
elCollisionsWillMove.checked = properties.collisionsWillMove;
|
||||
elLifetime.value = properties.lifetime;
|
||||
|
||||
if (properties.type != "Box") {
|
||||
elBoxSection.style.display = 'none';
|
||||
} else {
|
||||
elBoxSection.style.display = 'block';
|
||||
|
||||
elBoxColorRed.value = properties.color.red;
|
||||
elBoxColorGreen.value = properties.color.green;
|
||||
elBoxColorBlue.value = properties.color.blue;
|
||||
}
|
||||
|
||||
if (properties.type != "Model") {
|
||||
elModelSection.style.display = 'none';
|
||||
} else {
|
||||
elModelSection.style.display = 'block';
|
||||
|
||||
elModelURL.value = properties.modelURL;
|
||||
elModelAnimationURL.value = properties.animationURL;
|
||||
elModelAnimationPlaying.checked = properties.animationPlaying;
|
||||
elModelAnimationFPS.value = properties.animationFPS;
|
||||
}
|
||||
|
||||
if (properties.type != "Light") {
|
||||
elLightSection.style.display = 'none';
|
||||
} else {
|
||||
elLightSection.style.display = 'block';
|
||||
|
||||
elLightDiffuseRed.value = properties.diffuseColor.red;
|
||||
elLightDiffuseGreen.value = properties.diffuseColor.green;
|
||||
elLightDiffuseBlue.value = properties.diffuseColor.blue;
|
||||
|
||||
elLightAmbientRed.value = properties.ambientColor.red;
|
||||
elLightAmbientGreen.value = properties.ambientColor.green;
|
||||
elLightAmbientBlue.value = properties.ambientColor.blue;
|
||||
|
||||
elLightSpecularRed.value = properties.specularColor.red;
|
||||
elLightSpecularGreen.value = properties.specularColor.green;
|
||||
elLightSpecularBlue.value = properties.specularColor.blue;
|
||||
|
||||
elLightConstantAttenuation.value = properties.constantAttenuation;
|
||||
elLightLinearAttenuation.value = properties.linearAttenuation;
|
||||
elLightQuadraticAttenuation.value = properties.quadraticAttenuation;
|
||||
elLightExponent.value = properties.exponent;
|
||||
elLightCutoff.value = properties.cutoff;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
elLocked.addEventListener('change', createEmitCheckedPropertyUpdateFunction('locked'));
|
||||
elVisible.addEventListener('change', createEmitCheckedPropertyUpdateFunction('visible'));
|
||||
|
||||
var positionChangeFunction = createEmitVec3PropertyUpdateFunction(
|
||||
'position', elPositionX, elPositionY, elPositionZ);
|
||||
elPositionX.addEventListener('change', positionChangeFunction);
|
||||
elPositionY.addEventListener('change', positionChangeFunction);
|
||||
elPositionZ.addEventListener('change', positionChangeFunction);
|
||||
|
||||
var dimensionsChangeFunction = createEmitVec3PropertyUpdateFunction(
|
||||
'dimensions', elDimensionsX, elDimensionsY, elDimensionsZ);
|
||||
elDimensionsX.addEventListener('change', dimensionsChangeFunction);
|
||||
elDimensionsY.addEventListener('change', dimensionsChangeFunction);
|
||||
elDimensionsZ.addEventListener('change', dimensionsChangeFunction);
|
||||
|
||||
var registrationChangeFunction = createEmitVec3PropertyUpdateFunction(
|
||||
'registrationPoint', elRegistrationX, elRegistrationY, elRegistrationZ);
|
||||
elRegistrationX.addEventListener('change', registrationChangeFunction);
|
||||
elRegistrationY.addEventListener('change', registrationChangeFunction);
|
||||
elRegistrationZ.addEventListener('change', registrationChangeFunction);
|
||||
|
||||
var velocityChangeFunction = createEmitVec3PropertyUpdateFunction(
|
||||
'velocity', elLinearVelocityX, elLinearVelocityY, elLinearVelocityZ);
|
||||
elLinearVelocityX.addEventListener('change', velocityChangeFunction);
|
||||
elLinearVelocityY.addEventListener('change', velocityChangeFunction);
|
||||
elLinearVelocityZ.addEventListener('change', velocityChangeFunction);
|
||||
elLinearDamping.addEventListener('change', createEmitNumberPropertyUpdateFunction('damping'));
|
||||
|
||||
var angularVelocityChangeFunction = createEmitVec3PropertyUpdateFunction(
|
||||
'angularVelocity', elAngularVelocityX, elAngularVelocityY, elAngularVelocityZ);
|
||||
elAngularVelocityX.addEventListener('change', angularVelocityChangeFunction);
|
||||
elAngularVelocityY.addEventListener('change', angularVelocityChangeFunction);
|
||||
elAngularVelocityZ.addEventListener('change', angularVelocityChangeFunction);
|
||||
elAngularDamping.addEventListener('change', createEmitNumberPropertyUpdateFunction('angularDamping'))
|
||||
|
||||
var gravityChangeFunction = createEmitVec3PropertyUpdateFunction(
|
||||
'gravity', elGravityX, elGravityY, elGravityZ);
|
||||
elGravityX.addEventListener('change', gravityChangeFunction);
|
||||
elGravityY.addEventListener('change', gravityChangeFunction);
|
||||
elGravityZ.addEventListener('change', gravityChangeFunction);
|
||||
|
||||
elMass.addEventListener('change', createEmitNumberPropertyUpdateFunction('mass'));
|
||||
elIgnoreForCollisions.addEventListener('change', createEmitCheckedPropertyUpdateFunction('ignoreForCollisions'));
|
||||
elCollisionsWillMove.addEventListener('change', createEmitCheckedPropertyUpdateFunction('collisionsWillMove'));
|
||||
elLifetime.addEventListener('change', createEmitNumberPropertyUpdateFunction('lifetime'));
|
||||
|
||||
var boxColorChangeFunction = createEmitColorPropertyUpdateFunction(
|
||||
'color', elBoxColorRed, elBoxColorGreen, elBoxColorBlue);
|
||||
elBoxColorRed.addEventListener('change', boxColorChangeFunction);
|
||||
elBoxColorGreen.addEventListener('change', boxColorChangeFunction);
|
||||
elBoxColorBlue.addEventListener('change', boxColorChangeFunction);
|
||||
|
||||
elLightSpotLight.addEventListener('change', createEmitCheckedPropertyUpdateFunction('isSpotlight'));
|
||||
|
||||
var lightDiffuseChangeFunction = createEmitColorPropertyUpdateFunction(
|
||||
'diffuseColor', elLightDiffuseRed, elLightDiffuseGreen, elLightDiffuseBlue);
|
||||
elLightDiffuseRed.addEventListener('change', lightDiffuseChangeFunction);
|
||||
elLightDiffuseGreen.addEventListener('change', lightDiffuseChangeFunction);
|
||||
elLightDiffuseBlue.addEventListener('change', lightDiffuseChangeFunction);
|
||||
|
||||
var lightAmbientChangeFunction = createEmitColorPropertyUpdateFunction(
|
||||
'ambientColor', elLightAmbientRed, elLightAmbientGreen, elLightAmbientBlue);
|
||||
elLightAmbientRed.addEventListener('change', lightAmbientChangeFunction);
|
||||
elLightAmbientGreen.addEventListener('change', lightAmbientChangeFunction);
|
||||
elLightAmbientBlue.addEventListener('change', lightAmbientChangeFunction);
|
||||
|
||||
var lightSpecularChangeFunction = createEmitColorPropertyUpdateFunction(
|
||||
'specularColor', elLightSpecularRed, elLightSpecularGreen, elLightSpecularBlue);
|
||||
elLightSpecularRed.addEventListener('change', lightSpecularChangeFunction);
|
||||
elLightSpecularGreen.addEventListener('change', lightSpecularChangeFunction);
|
||||
elLightSpecularBlue.addEventListener('change', lightSpecularChangeFunction);
|
||||
|
||||
elLightConstantAttenuation.addEventListener('change', createEmitNumberPropertyUpdateFunction('constantAttenuation'));
|
||||
elLightLinearAttenuation.addEventListener('change', createEmitNumberPropertyUpdateFunction('linearAttenuation'));
|
||||
elLightQuadraticAttenuation.addEventListener('change', createEmitNumberPropertyUpdateFunction('quadraticAttenuation'));
|
||||
elLightExponent.addEventListener('change', createEmitNumberPropertyUpdateFunction('exponent'));
|
||||
elLightCutoff.addEventListener('change', createEmitNumberPropertyUpdateFunction('cutoff'));
|
||||
|
||||
elModelURL.addEventListener('change', createEmitTextPropertyUpdateFunction('modelURL'));
|
||||
elModelAnimationURL.addEventListener('change', createEmitTextPropertyUpdateFunction('animationURL'));
|
||||
elModelAnimationPlaying.addEventListener('change', createEmitCheckedPropertyUpdateFunction('animationIsPlaying'));
|
||||
elModelAnimationFPS.addEventListener('change', createEmitNumberPropertyUpdateFunction('animationFPS'));
|
||||
elModelAnimationFrame.addEventListener('change', createEmitNumberPropertyUpdateFunction('animationFrameIndex'));
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body onload='loaded();'>
|
||||
<div class="section-header">
|
||||
<label>Entity Properties</label>
|
||||
</div>
|
||||
<div id="properties" class="grid-section">
|
||||
<div class="property-section">
|
||||
<label>Type</label>
|
||||
<span>
|
||||
<label id="property-type"></input>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="property-section">
|
||||
<label>Locked</label>
|
||||
<span>
|
||||
<input type='checkbox' id="property-locked">
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="property-section">
|
||||
<label>Visible</label>
|
||||
<span>
|
||||
<input type='checkbox' id="property-visible">
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="property-section">
|
||||
<label>Position</label>
|
||||
<span>
|
||||
X <input class="coord" type='number' id="property-pos-x"></input>
|
||||
Y <input class="coord" type='number' id="property-pos-y"></input>
|
||||
Z <input class="coord" type='number' id="property-pos-z"></input>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="property-section">
|
||||
<label>Registration</label>
|
||||
<span>
|
||||
X <input class="coord" type='number' id="property-reg-x"></input>
|
||||
Y <input class="coord" type='number' id="property-reg-y"></input>
|
||||
Z <input class="coord" type='number' id="property-reg-z"></input>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="property-section">
|
||||
<label>Width</label>
|
||||
<span>
|
||||
<input class="coord" type='number' id="property-dim-x"></input>
|
||||
</span>
|
||||
</div>
|
||||
<div class="property-section">
|
||||
<label>Height</label>
|
||||
<span>
|
||||
<input class="coord" type='number' id="property-dim-y"></input>
|
||||
</span>
|
||||
</div>
|
||||
<div class="property-section">
|
||||
<label>Depth</label>
|
||||
<span>
|
||||
<input class="coord" type='number' id="property-dim-z"></input>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="property-section">
|
||||
<label>Linear</label>
|
||||
<span>
|
||||
X <input class="coord" type='number' id="property-lvel-x"></input>
|
||||
Y <input class="coord" type='number' id="property-lvel-y"></input>
|
||||
Z <input class="coord" type='number' id="property-lvel-z"></input>
|
||||
</span>
|
||||
</div>
|
||||
<div class="property-section">
|
||||
<label>Linear Damping</label>
|
||||
<span>
|
||||
<input class="coord" type='number' id="property-ldamping"></input>
|
||||
</span>
|
||||
</div>
|
||||
<div class="property-section">
|
||||
<label>Angular</label>
|
||||
<span>
|
||||
Pitch <input class="coord" type='number' id="property-avel-x"></input>
|
||||
Roll <input class="coord" type='number' id="property-avel-z"></input>
|
||||
Yaw <input class="coord" type='number' id="property-avel-y"></input>
|
||||
</span>
|
||||
</div>
|
||||
<div class="property-section">
|
||||
<label>Angular Damping</label>
|
||||
<span>
|
||||
<input class="coord" type='number' id="property-adamping"></input>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="property-section">
|
||||
<label>Gravity</label>
|
||||
<span>
|
||||
X <input class="coord" type='number' id="property-grav-x"></input>
|
||||
Y <input class="coord" type='number' id="property-grav-y"></input>
|
||||
Z <input class="coord" type='number' id="property-grav-z"></input>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="property-section">
|
||||
<label>Mass</label>
|
||||
<span>
|
||||
<input type='number' id="property-mass"></input>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="property-section">
|
||||
<label>Ignore For Collisions</label>
|
||||
<span>
|
||||
<input type='checkbox' id="property-ignore-for-collisions"></input>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="property-section">
|
||||
<label>Collisions Will Move</label>
|
||||
<span>
|
||||
<input type='checkbox' id="property-collisions-will-move"></input>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="property-section">
|
||||
<label>Lifetime</label>
|
||||
<span>
|
||||
<input type='number' id="property-lifetime"></input>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
|
||||
<div id="box-section" class="multi-property-section">
|
||||
<div class="property-section">
|
||||
<label>Color</label>
|
||||
<span>
|
||||
Red <input class="coord" type='number' id="property-box-red"></input>
|
||||
Green <input class="coord" type='number' id="property-box-green"></input>
|
||||
Blue <input class="coord" type='number' id="property-box-blue"></input>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div id="model-section" class="multi-property-section">
|
||||
<div class="property-section">
|
||||
<label>Model URL</label>
|
||||
<span>
|
||||
<input type="text" id="property-model-url"></input>
|
||||
</span>
|
||||
</div>
|
||||
<div class="property-section">
|
||||
<label>Animation URL</label>
|
||||
<span>
|
||||
<input type="text" id="property-model-animation-url"></input>
|
||||
</span>
|
||||
</div>
|
||||
<div class="property-section">
|
||||
<label>Animation Playing</label>
|
||||
<span>
|
||||
<input type='checkbox' id="property-model-animation-playing">
|
||||
</span>
|
||||
</div>
|
||||
<div class="property-section">
|
||||
<label>Animation FPS</label>
|
||||
<span>
|
||||
<input class="coord" type='number' id="property-model-animation-fps"></input>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div id="light-section" class="multi-property-section">
|
||||
<div class="property-section">
|
||||
<label>Spot Light</label>
|
||||
<span>
|
||||
<input type='checkbox' id="property-light-spot-light">
|
||||
</span>
|
||||
</div>
|
||||
<div class="property-section">
|
||||
<label>Diffuse</label>
|
||||
<span>
|
||||
Red <input class="coord" type='number' id="property-light-diffuse-red"></input>
|
||||
Green <input class="coord" type='number' id="property-light-diffuse-green"></input>
|
||||
Blue <input class="coord" type='number' id="property-light-diffuse-blue"></input>
|
||||
</span>
|
||||
</div>
|
||||
<div class="property-section">
|
||||
<label>Ambient</label>
|
||||
<span>
|
||||
Red <input class="coord" type='number' id="property-light-ambient-red"></input>
|
||||
Green <input class="coord" type='number' id="property-light-ambient-green"></input>
|
||||
Blue <input class="coord" type='number' id="property-light-ambient-blue"></input>
|
||||
</span>
|
||||
</div>
|
||||
<div class="property-section">
|
||||
<label>Specular</label>
|
||||
<span>
|
||||
Red <input class="coord" type='number' id="property-light-specular-red"></input>
|
||||
Green <input class="coord" type='number' id="property-light-specular-green"></input>
|
||||
Blue <input class="coord" type='number' id="property-light-specular-blue"></input>
|
||||
</span>
|
||||
</div>
|
||||
<div class="property-section">
|
||||
<label>Constant Attenuation</label>
|
||||
<span>
|
||||
<input class="coord" type='number' id="property-light-constant-attenuation"></input>
|
||||
</span>
|
||||
</div>
|
||||
<div class="property-section">
|
||||
<label>Linear Attenuation</label>
|
||||
<span>
|
||||
<input class="coord" type='number' id="property-light-linear-attenuation"></input>
|
||||
</span>
|
||||
</div>
|
||||
<div class="property-section">
|
||||
<label>Quadratic Attenuation</label>
|
||||
<span>
|
||||
<input class="coord" type='number' id="property-light-quadratic-attenuation"></input>
|
||||
</span>
|
||||
</div>
|
||||
<div class="property-section">
|
||||
<label>Exponent</label>
|
||||
<span>
|
||||
<input class="coord" type='number' id="property-light-exponent"></input>
|
||||
</span>
|
||||
</div>
|
||||
<div class="property-section">
|
||||
<label>Cutoff (degrees)</label>
|
||||
<span>
|
||||
<input class="coord" type='number' id="property-light-cutoff"></input>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -1,5 +1,6 @@
|
|||
<html>
|
||||
<head>
|
||||
<link rel="stylesheet" type="text/css" href="style.css">
|
||||
<script>
|
||||
function loaded() {
|
||||
var gridColor = { red: 0, green: 0, blue: 0 };
|
||||
|
@ -17,13 +18,14 @@
|
|||
gridOn = document.getElementById("grid-on");
|
||||
snapToGrid = document.getElementById("snap-to-grid");
|
||||
hGridVisible = document.getElementById("horiz-grid-visible");
|
||||
|
||||
bMoveToSelection = document.getElementById("move-to-selection");
|
||||
bMoveToAvatar = document.getElementById("move-to-avatar");
|
||||
|
||||
if (window.EventBridge !== undefined) {
|
||||
EventBridge.scriptEventReceived.connect(function(data) {
|
||||
data = JSON.parse(data);
|
||||
if (data.origin) {
|
||||
|
||||
if (data.origin) {
|
||||
var origin = data.origin;
|
||||
posY.value = origin.y;
|
||||
}
|
||||
|
@ -69,6 +71,19 @@
|
|||
hGridVisible.addEventListener("change", emitUpdate);
|
||||
snapToGrid.addEventListener("change", emitUpdate);
|
||||
|
||||
bMoveToAvatar.addEventListener("click", function() {
|
||||
EventBridge.emitWebEvent(JSON.stringify({
|
||||
type: "action",
|
||||
action: "moveToAvatar",
|
||||
}));
|
||||
});
|
||||
bMoveToSelection.addEventListener("click", function() {
|
||||
EventBridge.emitWebEvent(JSON.stringify({
|
||||
type: "action",
|
||||
action: "moveToSelection",
|
||||
}));
|
||||
});
|
||||
|
||||
var gridColorBox = document.getElementById('grid-color');
|
||||
|
||||
for (var i = 0; i < gridColors.length; i++) {
|
||||
|
@ -88,105 +103,63 @@
|
|||
EventBridge.emitWebEvent(JSON.stringify({ type: 'init' }));
|
||||
}
|
||||
</script>
|
||||
<style>
|
||||
* {
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
|
||||
background: #DDD;
|
||||
font-family: Sans-Serif;
|
||||
font-size: 12px;
|
||||
|
||||
-webkit-touch-callout: none;
|
||||
-webkit-user-select: none;
|
||||
-khtml-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
input {
|
||||
line-height: 2;
|
||||
}
|
||||
|
||||
.input-left {
|
||||
display: inline-block;
|
||||
width: 20px;
|
||||
}
|
||||
|
||||
.color-box {
|
||||
display: inline-block;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
border: 1px solid black;
|
||||
background: blue;
|
||||
margin: 2px;
|
||||
}
|
||||
|
||||
.color-box.highlight {
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
border: 2px solid black;
|
||||
}
|
||||
|
||||
.section-header {
|
||||
background: #AAA;
|
||||
border-bottom: 1px solid #CCC;
|
||||
}
|
||||
|
||||
.section-header label {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.grid-section {
|
||||
border-top: 1px solid #DDD;
|
||||
padding: 4px 0px 4px 20px;
|
||||
background: #DDD;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body onload='loaded();'>
|
||||
<div class="section-header">
|
||||
<input type='checkbox' id="horiz-grid-visible">
|
||||
<label>Horizontal Grid</label>
|
||||
</div>
|
||||
|
||||
<div class="grid-section">
|
||||
|
||||
<label>Snap to grid</label>
|
||||
<div>
|
||||
<div class="input-left">
|
||||
</div>
|
||||
<input type='checkbox' id="snap-to-grid">
|
||||
<div class="property-section">
|
||||
<label>Visible</label>
|
||||
<span>
|
||||
<input type='checkbox' id="horiz-grid-visible">
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<label>Position (Y Axis)</label>
|
||||
<div id="horizontal-position">
|
||||
<div class="input-left">
|
||||
</div>
|
||||
<input type='number' id="horiz-y" class="number" value="0.0" step="0.1"></input>
|
||||
<div class="property-section">
|
||||
<label>Snap to grid</label>
|
||||
<span>
|
||||
<input type='checkbox' id="snap-to-grid">
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<label>Minor Grid Size</label>
|
||||
<div>
|
||||
<div class="input-left">
|
||||
</div>
|
||||
<input type='number' id="minor-spacing" min="0" step="0.01", ></input>
|
||||
<div id="horizontal-position" class="property-section">
|
||||
<label>Position (Y Axis)</label>
|
||||
<span>
|
||||
<input type='number' id="horiz-y" class="number" value="0.0" step="0.1"></input>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<label>Major Grid Every</label>
|
||||
<div>
|
||||
<div class="input-left">
|
||||
</div>
|
||||
<input type='number' id="major-spacing" min="2" step="1", ></input>
|
||||
<div class="property-section">
|
||||
<label>Minor Grid Size</label>
|
||||
<span>
|
||||
<input type='number' id="minor-spacing" min="0" step="0.01", ></input>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<label>Grid Color</label>
|
||||
<div id="grid-colors">
|
||||
<div class="input-left">
|
||||
</div>
|
||||
<div class="property-section">
|
||||
<label>Major Grid Every</label>
|
||||
<span>
|
||||
<input type='number' id="major-spacing" min="2" step="1", ></input>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="property-section">
|
||||
<label>Grid Color</label>
|
||||
<span id="grid-colors"></span>
|
||||
</div>
|
||||
|
||||
<div class="property-section">
|
||||
<span>
|
||||
<input type="button" id="move-to-selection" value="Move to Selection">
|
||||
</span>
|
||||
</div>
|
||||
<div class="property-section">
|
||||
<span>
|
||||
<input type="button" id="move-to-avatar" value="Move to Avatar">
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
|
|
95
examples/html/style.css
Normal file
95
examples/html/style.css
Normal file
|
@ -0,0 +1,95 @@
|
|||
* {
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
|
||||
background-color: #efefef;
|
||||
font-family: Sans-Serif;
|
||||
font-size: 12px;
|
||||
|
||||
-webkit-touch-callout: none;
|
||||
-webkit-user-select: none;
|
||||
-khtml-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
input {
|
||||
line-height: 2;
|
||||
}
|
||||
|
||||
.input-left {
|
||||
display: inline-block;
|
||||
width: 20px;
|
||||
}
|
||||
|
||||
.color-box {
|
||||
display: inline-block;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
border: 1px solid black;
|
||||
margin: 2px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.color-box.highlight {
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
border: 2px solid black;
|
||||
}
|
||||
|
||||
.section-header {
|
||||
background: #AAA;
|
||||
border-bottom: 1px solid #CCC;
|
||||
background-color: #333333;
|
||||
color: #999;
|
||||
padding: 4px;
|
||||
}
|
||||
|
||||
.section-header label {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.multi-property-section {
|
||||
}
|
||||
.property-section {
|
||||
display: block;
|
||||
margin: 10 10;
|
||||
height: 30px;
|
||||
}
|
||||
|
||||
.property-section label {
|
||||
font-weight: bold;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.property-section span {
|
||||
float: right;
|
||||
}
|
||||
|
||||
.grid-section {
|
||||
border-top: 1px solid #DDD;
|
||||
background-color: #efefef;
|
||||
}
|
||||
|
||||
input[type=button] {
|
||||
cursor: pointer;
|
||||
background-color: #608e96;
|
||||
border-color: #608e96;
|
||||
border-radius: 5px;
|
||||
padding: 5px 10px;
|
||||
border: 0;
|
||||
color: #fff;
|
||||
font-weight: bold;
|
||||
margin: 0 2px;
|
||||
margin-top: 5px;
|
||||
font-size: .9em;
|
||||
}
|
||||
|
||||
input.coord {
|
||||
width: 6em;
|
||||
height: 2em;
|
||||
}
|
|
@ -23,12 +23,13 @@ SelectionManager = (function() {
|
|||
|
||||
that.savedProperties = {};
|
||||
|
||||
that.eventListener = null;
|
||||
that.selections = [];
|
||||
// These are selections that don't have a known ID yet
|
||||
that.pendingSelections = [];
|
||||
var pendingSelectionTimer = null;
|
||||
|
||||
var listeners = [];
|
||||
|
||||
that.localRotation = Quat.fromPitchYawRollDegrees(0, 0, 0);
|
||||
that.localPosition = { x: 0, y: 0, z: 0 };
|
||||
that.localDimensions = { x: 0, y: 0, z: 0 };
|
||||
|
@ -46,8 +47,8 @@ SelectionManager = (function() {
|
|||
}
|
||||
};
|
||||
|
||||
that.setEventListener = function(func) {
|
||||
that.eventListener = func;
|
||||
that.addEventListener = function(func) {
|
||||
listeners.push(func);
|
||||
};
|
||||
|
||||
that.hasSelection = function() {
|
||||
|
@ -187,8 +188,12 @@ SelectionManager = (function() {
|
|||
SelectionDisplay.setSpaceMode(SPACE_WORLD);
|
||||
}
|
||||
|
||||
if (that.eventListener) {
|
||||
that.eventListener();
|
||||
for (var i = 0; i < listeners.length; i++) {
|
||||
try {
|
||||
listeners[i]();
|
||||
} catch (e) {
|
||||
print("got exception");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -31,6 +31,7 @@ Grid = function(opts) {
|
|||
that.getMajorIncrement = function() { return minorGridSpacing * majorGridEvery; };
|
||||
|
||||
that.visible = false;
|
||||
that.enabled = false;
|
||||
|
||||
that.getOrigin = function() {
|
||||
return origin;
|
||||
|
@ -38,6 +39,11 @@ Grid = function(opts) {
|
|||
|
||||
that.getSnapToGrid = function() { return snapToGrid; };
|
||||
|
||||
that.setEnabled = function(enabled) {
|
||||
that.enabled = enabled;
|
||||
updateGrid();
|
||||
}
|
||||
|
||||
that.setVisible = function(visible, noUpdate) {
|
||||
that.visible = visible;
|
||||
updateGrid();
|
||||
|
@ -127,7 +133,7 @@ Grid = function(opts) {
|
|||
function updateGrid() {
|
||||
Overlays.editOverlay(gridOverlay, {
|
||||
position: { x: origin.y, y: origin.y, z: -origin.y },
|
||||
visible: that.visible,
|
||||
visible: that.visible && that.enabled,
|
||||
minorGridWidth: minorGridSpacing,
|
||||
majorGridEvery: majorGridEvery,
|
||||
color: gridColor,
|
||||
|
@ -159,7 +165,7 @@ GridTool = function(opts) {
|
|||
var listeners = [];
|
||||
|
||||
var url = Script.resolvePath('html/gridControls.html');
|
||||
var webView = new WebWindow(url, 200, 280);
|
||||
var webView = new WebWindow('Grid', url, 200, 280);
|
||||
|
||||
horizontalGrid.addListener(function(data) {
|
||||
webView.eventBridge.emitScriptEvent(JSON.stringify(data));
|
||||
|
@ -174,6 +180,15 @@ GridTool = function(opts) {
|
|||
for (var i = 0; i < listeners.length; i++) {
|
||||
listeners[i](data);
|
||||
}
|
||||
} else if (data.type == "action") {
|
||||
var action = data.action;
|
||||
if (action == "moveToAvatar") {
|
||||
grid.setPosition(MyAvatar.position);
|
||||
} else if (action == "moveToSelection") {
|
||||
var newPosition = selectionManager.worldPosition;
|
||||
newPosition = Vec3.subtract(newPosition, { x: 0, y: selectionManager.worldDimensions.y * 0.5, z: 0 });
|
||||
grid.setPosition(newPosition);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
@ -39,7 +39,7 @@ Script.include("libraries/gridTool.js");
|
|||
var grid = Grid();
|
||||
gridTool = GridTool({ horizontalGrid: grid });
|
||||
|
||||
selectionManager.setEventListener(selectionDisplay.updateHandles);
|
||||
selectionManager.addEventListener(selectionDisplay.updateHandles);
|
||||
|
||||
var windowDimensions = Controller.getViewportDimensions();
|
||||
var toolIconUrl = HIFI_PUBLIC_BUCKET + "images/tools/";
|
||||
|
@ -55,13 +55,11 @@ var wantEntityGlow = false;
|
|||
var SPAWN_DISTANCE = 1;
|
||||
var DEFAULT_DIMENSION = 0.20;
|
||||
|
||||
var MENU_GRID_TOOL_ENABLED = 'Grid Tool';
|
||||
var MENU_INSPECT_TOOL_ENABLED = "Inspect Tool";
|
||||
var MENU_EASE_ON_FOCUS = "Ease Orientation on Focus";
|
||||
|
||||
var SETTING_INSPECT_TOOL_ENABLED = "inspectToolEnabled";
|
||||
var SETTING_EASE_ON_FOCUS = "cameraEaseOnFocus";
|
||||
var SETTING_GRID_TOOL_ENABLED = 'GridToolEnabled';
|
||||
|
||||
var modelURLs = [
|
||||
HIFI_PUBLIC_BUCKET + "models/entities/2-Terrain:%20Alder.fbx",
|
||||
|
@ -272,11 +270,15 @@ var toolBar = (function () {
|
|||
isActive = !isActive;
|
||||
if (!isActive) {
|
||||
gridTool.setVisible(false);
|
||||
grid.setEnabled(false);
|
||||
propertiesTool.setVisible(false);
|
||||
selectionManager.clearSelections();
|
||||
cameraManager.disable();
|
||||
} else {
|
||||
cameraManager.enable();
|
||||
gridTool.setVisible(Menu.isOptionChecked(MENU_GRID_TOOL_ENABLED));
|
||||
gridTool.setVisible(true);
|
||||
grid.setEnabled(true);
|
||||
propertiesTool.setVisible(true);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -608,10 +610,6 @@ function setupModelMenus() {
|
|||
Menu.addMenuItem({ menuName: "File", menuItemName: "Import Models", shortcutKey: "CTRL+META+I", afterItem: "Export Models" });
|
||||
Menu.addMenuItem({ menuName: "Developer", menuItemName: "Debug Ryans Rotation Problems", isCheckable: true });
|
||||
|
||||
Menu.addMenuItem({ menuName: "View", menuItemName: MENU_GRID_TOOL_ENABLED, afterItem: "Edit Entities Help...", isCheckable: true,
|
||||
isChecked: Settings.getValue(SETTING_GRID_TOOL_ENABLED) == 'true'});
|
||||
Menu.addMenuItem({ menuName: "View", menuItemName: MENU_INSPECT_TOOL_ENABLED, afterItem: MENU_GRID_TOOL_ENABLED,
|
||||
isCheckable: true, isChecked: Settings.getValue(SETTING_INSPECT_TOOL_ENABLED) == "true" });
|
||||
Menu.addMenuItem({ menuName: "View", menuItemName: MENU_EASE_ON_FOCUS, afterItem: MENU_INSPECT_TOOL_ENABLED,
|
||||
isCheckable: true, isChecked: Settings.getValue(SETTING_EASE_ON_FOCUS) == "true" });
|
||||
}
|
||||
|
@ -636,8 +634,6 @@ function cleanupModelMenus() {
|
|||
Menu.removeMenuItem("File", "Import Models");
|
||||
Menu.removeMenuItem("Developer", "Debug Ryans Rotation Problems");
|
||||
|
||||
Settings.setValue(SETTING_GRID_TOOL_ENABLED, Menu.isOptionChecked(MENU_GRID_TOOL_ENABLED));
|
||||
Menu.removeMenuItem("View", MENU_GRID_TOOL_ENABLED);
|
||||
Menu.removeMenuItem("View", MENU_INSPECT_TOOL_ENABLED);
|
||||
Menu.removeMenuItem("View", MENU_EASE_ON_FOCUS);
|
||||
}
|
||||
|
@ -749,10 +745,6 @@ function handeMenuEvent(menuItem) {
|
|||
}
|
||||
} else if (menuItem == "Import Models") {
|
||||
modelImporter.doImport();
|
||||
} else if (menuItem == MENU_GRID_TOOL_ENABLED) {
|
||||
if (isActive) {
|
||||
gridTool.setVisible(Menu.isOptionChecked(MENU_GRID_TOOL_ENABLED));
|
||||
}
|
||||
}
|
||||
tooltip.show(false);
|
||||
}
|
||||
|
@ -911,3 +903,43 @@ function pushCommandForSelections(createdEntityData, deletedEntityData) {
|
|||
}
|
||||
UndoStack.pushCommand(applyEntityProperties, undoData, applyEntityProperties, redoData);
|
||||
}
|
||||
|
||||
PropertiesTool = function(opts) {
|
||||
var that = {};
|
||||
|
||||
var url = Script.resolvePath('html/entityProperties.html');
|
||||
var webView = new WebWindow('Entity Properties', url, 200, 280);
|
||||
|
||||
var visible = false;
|
||||
|
||||
webView.setVisible(visible);
|
||||
|
||||
that.setVisible = function(newVisible) {
|
||||
visible = newVisible;
|
||||
webView.setVisible(visible);
|
||||
};
|
||||
|
||||
selectionManager.addEventListener(function() {
|
||||
data = {
|
||||
type: 'update',
|
||||
};
|
||||
if (selectionManager.hasSelection()) {
|
||||
data.properties = Entities.getEntityProperties(selectionManager.selections[0]);
|
||||
}
|
||||
webView.eventBridge.emitScriptEvent(JSON.stringify(data));
|
||||
});
|
||||
|
||||
webView.eventBridge.webEventReceived.connect(function(data) {
|
||||
print(data);
|
||||
data = JSON.parse(data);
|
||||
if (data.type == "update") {
|
||||
Entities.editEntity(selectionManager.selections[0], data.properties);
|
||||
selectionManager._update();
|
||||
}
|
||||
});
|
||||
|
||||
return that;
|
||||
};
|
||||
|
||||
propertiesTool = PropertiesTool();
|
||||
|
||||
|
|
|
@ -194,20 +194,23 @@ print("Cube overlay color =\n"
|
|||
+ "green: " + cubeColor.green + "\n"
|
||||
+ "blue: " + cubeColor.blue
|
||||
);
|
||||
var modelOverlayProperties = {
|
||||
textures: {
|
||||
filename1: "http://url1",
|
||||
filename2: "http://url2"
|
||||
}
|
||||
}
|
||||
var modelOverlay = Overlays.addOverlay("model", modelOverlayProperties);
|
||||
var textures = Overlays.getProperty(modelOverlay, "textures");
|
||||
var textureValues = "";
|
||||
for (key in textures) {
|
||||
textureValues += "\n" + key + ": " + textures[key];
|
||||
}
|
||||
print("Model overlay textures =" + textureValues);
|
||||
Overlays.deleteOverlay(modelOverlay);
|
||||
|
||||
// This model overlay example causes intermittent crashes in NetworkGeometry::setTextureWithNameToURL()
|
||||
//var modelOverlayProperties = {
|
||||
// textures: {
|
||||
// filename1: HIFI_PUBLIC_BUCKET + "images/testing-swatches.svg",
|
||||
// filename2: HIFI_PUBLIC_BUCKET + "images/hifi-interface-tools.svg"
|
||||
// }
|
||||
//}
|
||||
//var modelOverlay = Overlays.addOverlay("model", modelOverlayProperties);
|
||||
//var textures = Overlays.getProperty(modelOverlay, "textures");
|
||||
//var textureValues = "";
|
||||
//for (key in textures) {
|
||||
// textureValues += "\n" + key + ": " + textures[key];
|
||||
//}
|
||||
//print("Model overlay textures =" + textureValues);
|
||||
//Overlays.deleteOverlay(modelOverlay);
|
||||
|
||||
print("Unknown overlay property =\n" + Overlays.getProperty(1000, "text")); // value = undefined
|
||||
|
||||
// When our script shuts down, we should clean up all of our overlays
|
||||
|
|
|
@ -124,7 +124,7 @@ void messageHandler(QtMsgType type, const QMessageLogContext& context, const QSt
|
|||
QString logMessage = LogHandler::getInstance().printMessage((LogMsgType) type, context, message);
|
||||
|
||||
if (!logMessage.isEmpty()) {
|
||||
Application::getInstance()->getLogger()->addMessage(qPrintable(logMessage));
|
||||
Application::getInstance()->getLogger()->addMessage(qPrintable(logMessage + "\n"));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -373,6 +373,10 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) :
|
|||
// enable mouse tracking; otherwise, we only get drag events
|
||||
_glWidget->setMouseTracking(true);
|
||||
|
||||
_toolWindow = new ToolWindow();
|
||||
_toolWindow->setWindowFlags(_toolWindow->windowFlags() | Qt::WindowStaysOnTopHint);
|
||||
_toolWindow->setWindowTitle("Tools");
|
||||
|
||||
// initialization continues in initializeGL when OpenGL context is ready
|
||||
|
||||
// Tell our voxel edit sender about our known jurisdictions
|
||||
|
|
|
@ -82,6 +82,7 @@
|
|||
#include "ui/overlays/Overlays.h"
|
||||
#include "ui/ApplicationOverlay.h"
|
||||
#include "ui/RunningScriptsWidget.h"
|
||||
#include "ui/ToolWindow.h"
|
||||
#include "ui/VoxelImportDialog.h"
|
||||
#include "voxels/VoxelFade.h"
|
||||
#include "voxels/VoxelHideShowThread.h"
|
||||
|
@ -246,6 +247,8 @@ public:
|
|||
void lockOctreeSceneStats() { _octreeSceneStatsLock.lockForRead(); }
|
||||
void unlockOctreeSceneStats() { _octreeSceneStatsLock.unlock(); }
|
||||
|
||||
ToolWindow* getToolWindow() { return _toolWindow ; }
|
||||
|
||||
GeometryCache* getGeometryCache() { return &_geometryCache; }
|
||||
AnimationCache* getAnimationCache() { return &_animationCache; }
|
||||
TextureCache* getTextureCache() { return &_textureCache; }
|
||||
|
@ -459,6 +462,8 @@ private:
|
|||
MainWindow* _window;
|
||||
GLCanvas* _glWidget; // our GLCanvas has a couple extra features
|
||||
|
||||
ToolWindow* _toolWindow;
|
||||
|
||||
BandwidthMeter _bandwidthMeter;
|
||||
|
||||
QThread* _nodeThread;
|
||||
|
|
|
@ -41,7 +41,7 @@ void FileLogger::addMessage(QString message) {
|
|||
QFile file(_fileName);
|
||||
if (file.open(QIODevice::WriteOnly | QIODevice::Append | QIODevice::Text)) {
|
||||
QTextStream out(&file);
|
||||
out << message << "\n";
|
||||
out << message;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -247,6 +247,12 @@ Menu::Menu() :
|
|||
_chatWindow = new ChatWindow(Application::getInstance()->getWindow());
|
||||
#endif
|
||||
|
||||
addActionToQMenuAndActionHash(toolsMenu,
|
||||
MenuOption::ToolWindow,
|
||||
Qt::CTRL | Qt::ALT | Qt::Key_T,
|
||||
this,
|
||||
SLOT(toggleToolWindow()));
|
||||
|
||||
addActionToQMenuAndActionHash(toolsMenu,
|
||||
MenuOption::Console,
|
||||
Qt::CTRL | Qt::ALT | Qt::Key_J,
|
||||
|
@ -1464,6 +1470,11 @@ void Menu::toggleConsole() {
|
|||
_jsConsole->setVisible(!_jsConsole->isVisible());
|
||||
}
|
||||
|
||||
void Menu::toggleToolWindow() {
|
||||
QMainWindow* toolWindow = Application::getInstance()->getToolWindow();
|
||||
toolWindow->setVisible(!toolWindow->isVisible());
|
||||
}
|
||||
|
||||
void Menu::audioMuteToggled() {
|
||||
QAction *muteAction = _actionHash.value(MenuOption::MuteAudio);
|
||||
if (muteAction) {
|
||||
|
|
|
@ -224,6 +224,7 @@ private slots:
|
|||
void showScriptEditor();
|
||||
void showChat();
|
||||
void toggleConsole();
|
||||
void toggleToolWindow();
|
||||
void toggleChat();
|
||||
void audioMuteToggled();
|
||||
void displayNameLocationResponse(const QString& errorString);
|
||||
|
@ -490,6 +491,7 @@ namespace MenuOption {
|
|||
const QString StringHair = "String Hair";
|
||||
const QString SuppressShortTimings = "Suppress Timings Less than 10ms";
|
||||
const QString TestPing = "Test Ping";
|
||||
const QString ToolWindow = "Tool Window";
|
||||
const QString TransmitterDrive = "Transmitter Drive";
|
||||
const QString TurnWithHead = "Turn using Head";
|
||||
const QString UploadAttachment = "Upload Attachment Model";
|
||||
|
|
|
@ -11,9 +11,13 @@
|
|||
|
||||
#include <QVBoxLayout>
|
||||
#include <QApplication>
|
||||
#include <QMainWindow>
|
||||
#include <QDockWidget>
|
||||
#include <QWebFrame>
|
||||
#include <QWebView>
|
||||
#include <QListWidget>
|
||||
|
||||
#include "Application.h"
|
||||
#include "WindowScriptingInterface.h"
|
||||
#include "WebWindowClass.h"
|
||||
|
||||
|
@ -28,29 +32,34 @@ void ScriptEventBridge::emitScriptEvent(const QString& data) {
|
|||
emit scriptEventReceived(data);
|
||||
}
|
||||
|
||||
WebWindowClass::WebWindowClass(const QString& url, int width, int height)
|
||||
|
||||
WebWindowClass::WebWindowClass(const QString& title, const QString& url, int width, int height)
|
||||
: QObject(NULL),
|
||||
_window(new QWidget(NULL, Qt::Tool)),
|
||||
_eventBridge(new ScriptEventBridge(this)) {
|
||||
|
||||
QWebView* webView = new QWebView(_window);
|
||||
ToolWindow* toolWindow = Application::getInstance()->getToolWindow();
|
||||
|
||||
_dockWidget = new QDockWidget(title, toolWindow);
|
||||
_dockWidget->setFeatures(QDockWidget::DockWidgetMovable);
|
||||
QWebView* webView = new QWebView(_dockWidget);
|
||||
webView->page()->mainFrame()->addToJavaScriptWindowObject("EventBridge", _eventBridge);
|
||||
webView->setUrl(url);
|
||||
QVBoxLayout* layout = new QVBoxLayout(_window);
|
||||
_window->setLayout(layout);
|
||||
layout->addWidget(webView);
|
||||
layout->setSpacing(0);
|
||||
layout->setContentsMargins(0, 0, 0, 0);
|
||||
_window->setGeometry(0, 0, width, height);
|
||||
_dockWidget->setWidget(webView);
|
||||
|
||||
connect(this, &WebWindowClass::destroyed, _window, &QWidget::deleteLater);
|
||||
toolWindow->addDockWidget(Qt::RightDockWidgetArea, _dockWidget);
|
||||
|
||||
connect(this, &WebWindowClass::destroyed, _dockWidget, &QWidget::deleteLater);
|
||||
}
|
||||
|
||||
WebWindowClass::~WebWindowClass() {
|
||||
}
|
||||
|
||||
void WebWindowClass::setVisible(bool visible) {
|
||||
QMetaObject::invokeMethod(_window, "setVisible", Qt::BlockingQueuedConnection, Q_ARG(bool, visible));
|
||||
if (visible) {
|
||||
QMetaObject::invokeMethod(
|
||||
Application::getInstance()->getToolWindow(), "setVisible", Qt::BlockingQueuedConnection, Q_ARG(bool, visible));
|
||||
}
|
||||
QMetaObject::invokeMethod(_dockWidget, "setVisible", Qt::BlockingQueuedConnection, Q_ARG(bool, visible));
|
||||
}
|
||||
|
||||
QScriptValue WebWindowClass::constructor(QScriptContext* context, QScriptEngine* engine) {
|
||||
|
@ -59,8 +68,9 @@ QScriptValue WebWindowClass::constructor(QScriptContext* context, QScriptEngine*
|
|||
QMetaObject::invokeMethod(WindowScriptingInterface::getInstance(), "doCreateWebWindow", Qt::BlockingQueuedConnection,
|
||||
Q_RETURN_ARG(WebWindowClass*, retVal),
|
||||
Q_ARG(const QString&, file),
|
||||
Q_ARG(int, context->argument(1).toInteger()),
|
||||
Q_ARG(int, context->argument(2).toInteger()));
|
||||
Q_ARG(QString, context->argument(1).toString()),
|
||||
Q_ARG(int, context->argument(2).toInteger()),
|
||||
Q_ARG(int, context->argument(3).toInteger()));
|
||||
|
||||
connect(engine, &QScriptEngine::destroyed, retVal, &WebWindowClass::deleteLater);
|
||||
|
||||
|
|
|
@ -34,7 +34,7 @@ class WebWindowClass : public QObject {
|
|||
Q_OBJECT
|
||||
Q_PROPERTY(QObject* eventBridge READ getEventBridge)
|
||||
public:
|
||||
WebWindowClass(const QString& url, int width, int height);
|
||||
WebWindowClass(const QString& title, const QString& url, int width, int height);
|
||||
~WebWindowClass();
|
||||
|
||||
static QScriptValue constructor(QScriptContext* context, QScriptEngine* engine);
|
||||
|
@ -44,7 +44,7 @@ public slots:
|
|||
ScriptEventBridge* getEventBridge() const { return _eventBridge; }
|
||||
|
||||
private:
|
||||
QWidget* _window;
|
||||
QDockWidget* _dockWidget;
|
||||
ScriptEventBridge* _eventBridge;
|
||||
};
|
||||
|
||||
|
|
|
@ -34,8 +34,8 @@ WindowScriptingInterface::WindowScriptingInterface() :
|
|||
{
|
||||
}
|
||||
|
||||
WebWindowClass* WindowScriptingInterface::doCreateWebWindow(const QString& url, int width, int height) {
|
||||
return new WebWindowClass(url, width, height);
|
||||
WebWindowClass* WindowScriptingInterface::doCreateWebWindow(const QString& title, const QString& url, int width, int height) {
|
||||
return new WebWindowClass(title, url, width, height);
|
||||
}
|
||||
|
||||
QScriptValue WindowScriptingInterface::hasFocus() {
|
||||
|
|
|
@ -78,7 +78,7 @@ private slots:
|
|||
void nonBlockingFormAccepted() { _nonBlockingFormActive = false; _formResult = QDialog::Accepted; emit nonBlockingFormClosed(); }
|
||||
void nonBlockingFormRejected() { _nonBlockingFormActive = false; _formResult = QDialog::Rejected; emit nonBlockingFormClosed(); }
|
||||
|
||||
WebWindowClass* doCreateWebWindow(const QString& url, int width, int height);
|
||||
WebWindowClass* doCreateWebWindow(const QString& title, const QString& url, int width, int height);
|
||||
|
||||
private:
|
||||
WindowScriptingInterface();
|
||||
|
|
82
interface/src/ui/ToolWindow.cpp
Normal file
82
interface/src/ui/ToolWindow.cpp
Normal file
|
@ -0,0 +1,82 @@
|
|||
//
|
||||
// ToolWindow.cpp
|
||||
// interface/src/ui
|
||||
//
|
||||
// Created by Ryan Huffman on 11/13/14.
|
||||
// Copyright 2014 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#include "Application.h"
|
||||
#include "ToolWindow.h"
|
||||
#include "UIUtil.h"
|
||||
|
||||
const int DEFAULT_WIDTH = 300;
|
||||
|
||||
ToolWindow::ToolWindow(QWidget* parent) :
|
||||
QMainWindow(parent),
|
||||
_hasShown(false),
|
||||
_lastGeometry() {
|
||||
}
|
||||
|
||||
bool ToolWindow::event(QEvent* event) {
|
||||
QEvent::Type type = event->type();
|
||||
if (type == QEvent::Show) {
|
||||
if (!_hasShown) {
|
||||
_hasShown = true;
|
||||
|
||||
QMainWindow* mainWindow = Application::getInstance()->getWindow();
|
||||
QRect mainGeometry = mainWindow->geometry();
|
||||
|
||||
int titleBarHeight = UIUtil::getWindowTitleBarHeight(this);
|
||||
int menuBarHeight = Menu::getInstance()->geometry().height();
|
||||
int topMargin = titleBarHeight + menuBarHeight;
|
||||
|
||||
_lastGeometry = QRect(mainGeometry.topLeft().x(), mainGeometry.topLeft().y() + topMargin,
|
||||
DEFAULT_WIDTH, mainGeometry.height() - topMargin);
|
||||
}
|
||||
setGeometry(_lastGeometry);
|
||||
return true;
|
||||
} else if (type == QEvent::Hide) {
|
||||
_lastGeometry = geometry();
|
||||
return true;
|
||||
}
|
||||
|
||||
return QMainWindow::event(event);
|
||||
}
|
||||
|
||||
void ToolWindow::onChildVisibilityUpdated(bool visible) {
|
||||
if (visible) {
|
||||
setVisible(true);
|
||||
} else {
|
||||
bool hasVisible = false;
|
||||
QList<QDockWidget*> dockWidgets = findChildren<QDockWidget*>();
|
||||
for (int i = 0; i < dockWidgets.count(); i++) {
|
||||
if (dockWidgets[i]->isVisible()) {
|
||||
hasVisible = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
setVisible(hasVisible);
|
||||
}
|
||||
}
|
||||
|
||||
void ToolWindow::addDockWidget(Qt::DockWidgetArea area, QDockWidget* dockWidget) {
|
||||
QMainWindow::addDockWidget(area, dockWidget);
|
||||
|
||||
connect(dockWidget, &QDockWidget::visibilityChanged, this, &ToolWindow::onChildVisibilityUpdated);
|
||||
}
|
||||
|
||||
void ToolWindow::addDockWidget(Qt::DockWidgetArea area, QDockWidget* dockWidget, Qt::Orientation orientation) {
|
||||
QMainWindow::addDockWidget(area, dockWidget, orientation);
|
||||
|
||||
connect(dockWidget, &QDockWidget::visibilityChanged, this, &ToolWindow::onChildVisibilityUpdated);
|
||||
}
|
||||
|
||||
void ToolWindow::removeDockWidget(QDockWidget* dockWidget) {
|
||||
QMainWindow::removeDockWidget(dockWidget);
|
||||
|
||||
disconnect(dockWidget, &QDockWidget::visibilityChanged, this, &ToolWindow::onChildVisibilityUpdated);
|
||||
}
|
40
interface/src/ui/ToolWindow.h
Normal file
40
interface/src/ui/ToolWindow.h
Normal file
|
@ -0,0 +1,40 @@
|
|||
//
|
||||
// ToolWindow.h
|
||||
// interface/src/ui
|
||||
//
|
||||
// Created by Ryan Huffman on 11/13/14.
|
||||
// Copyright 2014 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#ifndef hifi_ToolWindow_h
|
||||
#define hifi_ToolWindow_h
|
||||
|
||||
#include <QDockWidget>
|
||||
#include <QEvent>
|
||||
#include <QMainWindow>
|
||||
#include <QRect>
|
||||
#include <QWidget>
|
||||
|
||||
class ToolWindow : public QMainWindow {
|
||||
Q_OBJECT
|
||||
public:
|
||||
ToolWindow(QWidget* parent = NULL);
|
||||
|
||||
virtual bool event(QEvent* event);
|
||||
virtual void addDockWidget(Qt::DockWidgetArea area, QDockWidget* dockWidget);
|
||||
virtual void addDockWidget(Qt::DockWidgetArea area, QDockWidget* dockWidget, Qt::Orientation orientation);
|
||||
virtual void removeDockWidget(QDockWidget* dockWidget);
|
||||
|
||||
public slots:
|
||||
void onChildVisibilityUpdated(bool visible);
|
||||
|
||||
|
||||
private:
|
||||
bool _hasShown;
|
||||
QRect _lastGeometry;
|
||||
};
|
||||
|
||||
#endif // hifi_ToolWindow_h
|
|
@ -119,6 +119,8 @@ QString LogHandler::printMessage(LogMsgType type, const QMessageLogContext& cont
|
|||
char dateString[100];
|
||||
strftime(dateString, sizeof(dateString), DATE_STRING_FORMAT, localTime);
|
||||
|
||||
prefixString.append(QString(" [%1]").arg(dateString));
|
||||
|
||||
if (_shouldOutputPID) {
|
||||
prefixString.append(QString(" [%1").arg(getpid()));
|
||||
|
||||
|
|
Loading…
Reference in a new issue