overte-HifiExperiments/interface/resources/qml/hifi/avatarapp/AdjustWearables.qml
2018-07-24 23:19:11 +03:00

359 lines
11 KiB
QML

import Hifi 1.0 as Hifi
import QtQuick 2.5
import "../../styles-uit"
import "../../controls-uit" as HifiControlsUit
import "../../controls" as HifiControls
Rectangle {
id: root;
visible: false;
width: 480
height: 706
color: 'white'
signal wearableUpdated(var id, int index, var properties);
signal wearableSelected(var id);
signal wearableDeleted(string avatarName, var id);
signal adjustWearablesOpened(var avatarName);
signal adjustWearablesClosed(bool status, var avatarName);
property bool modified: false;
Component.onCompleted: {
modified = false;
}
property var jointNames;
property string avatarName: ''
property var wearablesModel;
function open(avatar) {
adjustWearablesOpened(avatar.name);
visible = true;
avatarName = avatar.name;
wearablesModel = avatar.wearables;
refresh(avatar);
}
function refresh(avatar) {
wearablesCombobox.model.clear();
for(var i = 0; i < avatar.wearables.count; ++i) {
var wearable = avatar.wearables.get(i).properties;
for(var j = (wearable.modelURL.length - 1); j >= 0; --j) {
if(wearable.modelURL[j] === '/') {
wearable.text = wearable.modelURL.substring(j + 1) + ' [%jointIndex%]'.replace('%jointIndex%', jointNames[wearable.parentJointIndex]);
break;
}
}
wearablesCombobox.model.append(wearable);
}
wearablesCombobox.currentIndex = 0;
}
function refreshWearable(wearableID, wearableIndex, properties, updateUI) {
if(wearableIndex === -1) {
wearableIndex = wearablesCombobox.model.findIndexById(wearableID);
}
var wearable = wearablesCombobox.model.get(wearableIndex);
if(!wearable) {
return;
}
var wearableModelItemProperties = wearablesModel.get(wearableIndex).properties;
for(var prop in properties) {
wearable[prop] = properties[prop];
wearableModelItemProperties[prop] = wearable[prop];
if(updateUI) {
if(prop === 'localPosition') {
position.set(wearable[prop]);
} else if(prop === 'localRotationAngles') {
rotation.set(wearable[prop]);
} else if(prop === 'dimensions') {
scalespinner.set(wearable[prop].x / wearable.naturalDimensions.x);
}
}
}
wearablesModel.setProperty(wearableIndex, 'properties', wearableModelItemProperties);
}
function getCurrentWearable() {
return wearablesCombobox.model.get(wearablesCombobox.currentIndex)
}
function selectWearableByID(entityID) {
for(var i = 0; i < wearablesCombobox.model.count; ++i) {
var wearable = wearablesCombobox.model.get(i);
if(wearable.id === entityID) {
wearablesCombobox.currentIndex = i;
break;
}
}
}
function close(status) {
visible = false;
adjustWearablesClosed(status, avatarName);
}
HifiConstants { id: hifi }
// This object is always used in a popup.
// This MouseArea is used to prevent a user from being
// able to click on a button/mouseArea underneath the popup.
MouseArea {
anchors.fill: parent;
propagateComposedEvents: false;
hoverEnabled: true;
}
Column {
anchors.top: parent.top
anchors.topMargin: 15
anchors.horizontalCenter: parent.horizontalCenter
spacing: 20
width: parent.width - 30 * 2
HifiControlsUit.ComboBox {
id: wearablesCombobox
anchors.left: parent.left
anchors.right: parent.right
comboBox.textRole: "text"
model: ListModel {
function findIndexById(id) {
for(var i = 0; i < count; ++i) {
var wearable = get(i);
if(wearable.id === id) {
return i;
}
}
return -1;
}
}
comboBox.onCurrentIndexChanged: {
var currentWearable = getCurrentWearable();
if(currentWearable) {
position.set(currentWearable.localPosition);
rotation.set(currentWearable.localRotationAngles);
scalespinner.set(currentWearable.dimensions.x / currentWearable.naturalDimensions.x)
wearableSelected(currentWearable.id);
}
}
}
Column {
width: parent.width
spacing: 5
Row {
spacing: 20
// TextStyle5
FiraSansSemiBold {
id: positionLabel
size: 22;
text: "Position"
}
// TextStyle7
FiraSansRegular {
size: 18;
lineHeightMode: Text.FixedHeight
lineHeight: 16.9;
text: "m"
anchors.verticalCenter: positionLabel.verticalCenter
}
}
Vector3 {
id: position
backgroundColor: "lightgray"
function set(localPosition) {
notify = false;
xvalue = localPosition.x
yvalue = localPosition.y
zvalue = localPosition.z
notify = true;
}
function notifyPositionChanged() {
modified = true;
var properties = {
localPosition: { 'x' : xvalue, 'y' : yvalue, 'z' : zvalue }
};
wearableUpdated(getCurrentWearable().id, wearablesCombobox.currentIndex, properties);
}
property bool notify: false;
onXvalueChanged: if(notify) notifyPositionChanged();
onYvalueChanged: if(notify) notifyPositionChanged();
onZvalueChanged: if(notify) notifyPositionChanged();
decimals: 2
realFrom: -10
realTo: 10
realStepSize: 0.01
}
}
Column {
width: parent.width
spacing: 5
Row {
spacing: 20
// TextStyle5
FiraSansSemiBold {
id: rotationLabel
size: 22;
text: "Rotation"
}
// TextStyle7
FiraSansRegular {
size: 18;
lineHeightMode: Text.FixedHeight
lineHeight: 16.9;
text: "deg"
anchors.verticalCenter: rotationLabel.verticalCenter
}
}
Vector3 {
id: rotation
backgroundColor: "lightgray"
function set(localRotationAngles) {
notify = false;
xvalue = localRotationAngles.x
yvalue = localRotationAngles.y
zvalue = localRotationAngles.z
notify = true;
}
function notifyRotationChanged() {
modified = true;
var properties = {
localRotationAngles: { 'x' : xvalue, 'y' : yvalue, 'z' : zvalue }
};
wearableUpdated(getCurrentWearable().id, wearablesCombobox.currentIndex, properties);
}
property bool notify: false;
onXvalueChanged: if(notify) notifyRotationChanged();
onYvalueChanged: if(notify) notifyRotationChanged();
onZvalueChanged: if(notify) notifyRotationChanged();
decimals: 0
realFrom: -180
realTo: 180
realStepSize: 1
}
}
Column {
width: parent.width
spacing: 5
// TextStyle5
FiraSansSemiBold {
size: 22;
text: "Scale"
}
Item {
width: parent.width
height: childrenRect.height
HifiControlsUit.SpinBox {
id: scalespinner
decimals: 2
realStepSize: 0.1
realFrom: 0.1
realTo: 3.0
realValue: 1.0
backgroundColor: "lightgray"
width: position.spinboxWidth
colorScheme: hifi.colorSchemes.light
property bool notify: false;
onValueChanged: if(notify) notifyScaleChanged();
function set(value) {
notify = false;
realValue = value
notify = true;
}
function notifyScaleChanged() {
modified = true;
var currentWearable = getCurrentWearable();
var naturalDimensions = currentWearable.naturalDimensions;
var properties = {
dimensions: {
'x' : realValue * naturalDimensions.x,
'y' : realValue * naturalDimensions.y,
'z' : realValue * naturalDimensions.z
}
};
wearableUpdated(currentWearable.id, wearablesCombobox.currentIndex, properties);
}
}
HifiControlsUit.Button {
fontSize: 18
height: 40
anchors.right: parent.right
color: hifi.buttons.red;
colorScheme: hifi.colorSchemes.light;
text: "TAKE IT OFF"
onClicked: wearableDeleted(root.avatarName, getCurrentWearable().id);
enabled: wearablesCombobox.model.count !== 0
anchors.verticalCenter: scalespinner.verticalCenter
}
}
}
}
DialogButtons {
anchors.bottom: parent.bottom
anchors.bottomMargin: 30
anchors.left: parent.left
anchors.leftMargin: 30
anchors.right: parent.right
anchors.rightMargin: 30
yesText: "SAVE"
noText: "CANCEL"
onYesClicked: function() {
root.close(true);
}
onNoClicked: function() {
root.close(false);
}
}
}