mirror of
https://github.com/lubosz/overte.git
synced 2025-04-24 09:23:17 +02:00
Merge pull request #11029 from cain-kilgore/dominant-hands
WL 21453 - Add a "Dominant Hand" setting
This commit is contained in:
commit
9421e6ebb6
9 changed files with 232 additions and 2 deletions
71
interface/resources/qml/controls-uit/RadioButton.qml
Normal file
71
interface/resources/qml/controls-uit/RadioButton.qml
Normal file
|
@ -0,0 +1,71 @@
|
|||
//
|
||||
// RadioButton.qml
|
||||
//
|
||||
// Created by Cain Kilgore on 20th July 2017
|
||||
// Copyright 2017 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
|
||||
//
|
||||
|
||||
import QtQuick 2.5
|
||||
import QtQuick.Controls 1.4 as Original
|
||||
import QtQuick.Controls.Styles 1.4
|
||||
|
||||
import "../styles-uit"
|
||||
import "../controls-uit" as HifiControls
|
||||
|
||||
Original.RadioButton {
|
||||
id: radioButton
|
||||
HifiConstants { id: hifi }
|
||||
|
||||
property int colorScheme: hifi.colorSchemes.light
|
||||
readonly property bool isLightColorScheme: colorScheme == hifi.colorSchemes.light
|
||||
|
||||
readonly property int boxSize: 14
|
||||
readonly property int boxRadius: 3
|
||||
readonly property int checkSize: 10
|
||||
readonly property int checkRadius: 2
|
||||
|
||||
style: RadioButtonStyle {
|
||||
indicator: Rectangle {
|
||||
id: box
|
||||
width: boxSize
|
||||
height: boxSize
|
||||
radius: 7
|
||||
gradient: Gradient {
|
||||
GradientStop {
|
||||
position: 0.2
|
||||
color: pressed || hovered
|
||||
? (radioButton.isLightColorScheme ? hifi.colors.checkboxDarkStart : hifi.colors.checkboxLightStart)
|
||||
: (radioButton.isLightColorScheme ? hifi.colors.checkboxLightStart : hifi.colors.checkboxDarkStart)
|
||||
}
|
||||
GradientStop {
|
||||
position: 1.0
|
||||
color: pressed || hovered
|
||||
? (radioButton.isLightColorScheme ? hifi.colors.checkboxDarkFinish : hifi.colors.checkboxLightFinish)
|
||||
: (radioButton.isLightColorScheme ? hifi.colors.checkboxLightFinish : hifi.colors.checkboxDarkFinish)
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: check
|
||||
width: checkSize
|
||||
height: checkSize
|
||||
radius: 7
|
||||
anchors.centerIn: parent
|
||||
color: "#00B4EF"
|
||||
border.width: 1
|
||||
border.color: "#36CDFF"
|
||||
visible: checked && !pressed || !checked && pressed
|
||||
}
|
||||
}
|
||||
|
||||
label: RalewaySemiBold {
|
||||
text: control.text
|
||||
size: hifi.fontSizes.inputLabel
|
||||
color: isLightColorScheme ? hifi.colors.lightGray : hifi.colors.lightGrayText
|
||||
x: radioButton.boxSize / 2
|
||||
}
|
||||
}
|
||||
}
|
17
interface/resources/qml/controls/RadioButton.qml
Normal file
17
interface/resources/qml/controls/RadioButton.qml
Normal file
|
@ -0,0 +1,17 @@
|
|||
import QtQuick.Controls 1.3 as Original
|
||||
import QtQuick.Controls.Styles 1.3
|
||||
import "../styles"
|
||||
import "."
|
||||
Original.RadioButton {
|
||||
text: "Radio Button"
|
||||
style: RadioButtonStyle {
|
||||
indicator: FontAwesome {
|
||||
text: control.checked ? "\uf046" : "\uf096"
|
||||
}
|
||||
label: Text {
|
||||
text: control.text
|
||||
renderType: Text.QtRendering
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,101 @@
|
|||
//
|
||||
// PrimaryHandPreference.qml
|
||||
//
|
||||
// Created by Cain Kilgore on 20th July 2017
|
||||
// Copyright 2017 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
|
||||
//
|
||||
|
||||
import QtQuick 2.5
|
||||
|
||||
import "../../controls-uit"
|
||||
|
||||
Preference {
|
||||
id: root
|
||||
property alias box1: box1
|
||||
property alias box2: box2
|
||||
|
||||
height: control.height + hifi.dimensions.controlInterlineHeight
|
||||
|
||||
Component.onCompleted: {
|
||||
if (preference.value == "left") {
|
||||
box1.checked = true;
|
||||
} else {
|
||||
box2.checked = true;
|
||||
}
|
||||
}
|
||||
|
||||
function save() {
|
||||
if (box1.checked && !box2.checked) {
|
||||
preference.value = "left";
|
||||
}
|
||||
if (!box1.checked && box2.checked) {
|
||||
preference.value = "right";
|
||||
}
|
||||
preference.save();
|
||||
}
|
||||
|
||||
Item {
|
||||
id: control
|
||||
anchors {
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
bottom: parent.bottom
|
||||
}
|
||||
height: Math.max(labelName.height, box1.height, box2.height)
|
||||
|
||||
Label {
|
||||
id: labelName
|
||||
text: root.label + ":"
|
||||
colorScheme: hifi.colorSchemes.dark
|
||||
anchors {
|
||||
left: parent.left
|
||||
right: box1.left
|
||||
rightMargin: hifi.dimensions.labelPadding
|
||||
verticalCenter: parent.verticalCenter
|
||||
}
|
||||
horizontalAlignment: Text.AlignRight
|
||||
wrapMode: Text.Wrap
|
||||
}
|
||||
|
||||
RadioButton {
|
||||
id: box1
|
||||
text: "Left"
|
||||
width: 60
|
||||
anchors {
|
||||
right: box2.left
|
||||
verticalCenter: parent.verticalCenter
|
||||
}
|
||||
onClicked: {
|
||||
if (box2.checked) {
|
||||
box2.checked = false;
|
||||
}
|
||||
if (!box1.checked && !box2.checked) {
|
||||
box1.checked = true;
|
||||
}
|
||||
}
|
||||
colorScheme: hifi.colorSchemes.dark
|
||||
}
|
||||
|
||||
RadioButton {
|
||||
id: box2
|
||||
text: "Right"
|
||||
width: 60
|
||||
anchors {
|
||||
right: parent.right
|
||||
verticalCenter: parent.verticalCenter
|
||||
}
|
||||
onClicked: {
|
||||
if (box1.checked) {
|
||||
box1.checked = false;
|
||||
}
|
||||
if (!box1.checked && !box2.checked) {
|
||||
box2.checked = true;
|
||||
}
|
||||
}
|
||||
colorScheme: hifi.colorSchemes.dark
|
||||
}
|
||||
}
|
||||
}
|
|
@ -73,6 +73,7 @@ Preference {
|
|||
property var buttonBuilder: Component { ButtonPreference { } }
|
||||
property var comboBoxBuilder: Component { ComboBoxPreference { } }
|
||||
property var spinnerSliderBuilder: Component { SpinnerSliderPreference { } }
|
||||
property var primaryHandBuilder: Component { PrimaryHandPreference { } }
|
||||
property var preferences: []
|
||||
property int checkBoxCount: 0
|
||||
|
||||
|
@ -134,6 +135,11 @@ Preference {
|
|||
checkBoxCount = 0;
|
||||
builder = spinnerSliderBuilder;
|
||||
break;
|
||||
|
||||
case Preference.PrimaryHand:
|
||||
checkBoxCount++;
|
||||
builder = primaryHandBuilder;
|
||||
break;
|
||||
};
|
||||
|
||||
if (builder) {
|
||||
|
|
|
@ -82,6 +82,7 @@ Preference {
|
|||
property var buttonBuilder: Component { ButtonPreference { } }
|
||||
property var comboBoxBuilder: Component { ComboBoxPreference { } }
|
||||
property var spinnerSliderBuilder: Component { SpinnerSliderPreference { } }
|
||||
property var primaryHandBuilder: Component { PrimaryHandPreference { } }
|
||||
property var preferences: []
|
||||
property int checkBoxCount: 0
|
||||
|
||||
|
@ -144,10 +145,16 @@ Preference {
|
|||
//to be not overlapped when drop down is active
|
||||
zpos = root.z + 1000 - itemNum
|
||||
break;
|
||||
|
||||
case Preference.SpinnerSlider:
|
||||
checkBoxCount = 0;
|
||||
builder = spinnerSliderBuilder;
|
||||
break;
|
||||
|
||||
case Preference.PrimaryHand:
|
||||
checkBoxCount++;
|
||||
builder = primaryHandBuilder;
|
||||
break;
|
||||
};
|
||||
|
||||
if (builder) {
|
||||
|
|
|
@ -255,6 +255,12 @@ MyAvatar::~MyAvatar() {
|
|||
_lookAtTargetAvatar.reset();
|
||||
}
|
||||
|
||||
void MyAvatar::setDominantHand(const QString& hand) {
|
||||
if (hand == DOMINANT_LEFT_HAND || hand == DOMINANT_RIGHT_HAND) {
|
||||
_dominantHand = hand;
|
||||
}
|
||||
}
|
||||
|
||||
void MyAvatar::registerMetaTypes(QScriptEngine* engine) {
|
||||
QScriptValue value = engine->newQObject(this, QScriptEngine::QtOwnership, QScriptEngine::ExcludeDeleteLater | QScriptEngine::ExcludeChildObjects);
|
||||
engine->globalObject().setProperty("MyAvatar", value);
|
||||
|
@ -926,6 +932,7 @@ void MyAvatar::saveData() {
|
|||
Settings settings;
|
||||
settings.beginGroup("Avatar");
|
||||
|
||||
settings.setValue("dominantHand", _dominantHand);
|
||||
settings.setValue("headPitch", getHead()->getBasePitch());
|
||||
|
||||
settings.setValue("scale", _targetScale);
|
||||
|
@ -1122,7 +1129,7 @@ void MyAvatar::loadData() {
|
|||
setCollisionSoundURL(settings.value("collisionSoundURL", DEFAULT_AVATAR_COLLISION_SOUND_URL).toString());
|
||||
setSnapTurn(settings.value("useSnapTurn", _useSnapTurn).toBool());
|
||||
setClearOverlayWhenMoving(settings.value("clearOverlayWhenMoving", _clearOverlayWhenMoving).toBool());
|
||||
|
||||
setDominantHand(settings.value("dominantHand", _dominantHand).toString().toLower());
|
||||
settings.endGroup();
|
||||
|
||||
setEnableMeshVisible(Menu::getInstance()->isOptionChecked(MenuOption::MeshVisible));
|
||||
|
|
|
@ -43,6 +43,7 @@ enum AudioListenerMode {
|
|||
FROM_CAMERA,
|
||||
CUSTOM
|
||||
};
|
||||
|
||||
Q_DECLARE_METATYPE(AudioListenerMode);
|
||||
|
||||
class MyAvatar : public Avatar {
|
||||
|
@ -141,6 +142,9 @@ class MyAvatar : public Avatar {
|
|||
Q_PROPERTY(float hmdRollControlDeadZone READ getHMDRollControlDeadZone WRITE setHMDRollControlDeadZone)
|
||||
Q_PROPERTY(float hmdRollControlRate READ getHMDRollControlRate WRITE setHMDRollControlRate)
|
||||
|
||||
const QString DOMINANT_LEFT_HAND = "left";
|
||||
const QString DOMINANT_RIGHT_HAND = "right";
|
||||
|
||||
public:
|
||||
enum DriveKeys {
|
||||
TRANSLATE_X = 0,
|
||||
|
@ -339,6 +343,9 @@ public:
|
|||
Q_INVOKABLE bool getClearOverlayWhenMoving() const { return _clearOverlayWhenMoving; }
|
||||
Q_INVOKABLE void setClearOverlayWhenMoving(bool on) { _clearOverlayWhenMoving = on; }
|
||||
|
||||
Q_INVOKABLE void setDominantHand(const QString& hand);
|
||||
Q_INVOKABLE QString getDominantHand() const { return _dominantHand; }
|
||||
|
||||
Q_INVOKABLE void setHMDLeanRecenterEnabled(bool value) { _hmdLeanRecenterEnabled = value; }
|
||||
Q_INVOKABLE bool getHMDLeanRecenterEnabled() const { return _hmdLeanRecenterEnabled; }
|
||||
|
||||
|
@ -424,7 +431,6 @@ public:
|
|||
Q_INVOKABLE QString getFullAvatarModelName() const { return _fullAvatarModelName; }
|
||||
void resetFullAvatarURL();
|
||||
|
||||
|
||||
virtual void setAttachmentData(const QVector<AttachmentData>& attachmentData) override;
|
||||
|
||||
MyCharacterController* getCharacterController() { return &_characterController; }
|
||||
|
@ -720,6 +726,7 @@ private:
|
|||
QUrl _fstAnimGraphOverrideUrl;
|
||||
bool _useSnapTurn { true };
|
||||
bool _clearOverlayWhenMoving { true };
|
||||
QString _dominantHand { DOMINANT_RIGHT_HAND };
|
||||
|
||||
const float ROLL_CONTROL_DEAD_ZONE_DEFAULT = 8.0f; // deg
|
||||
const float ROLL_CONTROL_RATE_DEFAULT = 2.5f; // deg/sec/deg
|
||||
|
|
|
@ -181,6 +181,11 @@ void setupPreferences() {
|
|||
preference->setStep(1);
|
||||
preferences->addPreference(preference);
|
||||
}
|
||||
{
|
||||
auto getter = [=]()->QString { return myAvatar->getDominantHand(); };
|
||||
auto setter = [=](const QString& value) { myAvatar->setDominantHand(value); };
|
||||
preferences->addPreference(new PrimaryHandPreference(AVATAR_TUNING, "Dominant Hand", getter, setter));
|
||||
}
|
||||
{
|
||||
auto getter = [=]()->float { return myAvatar->getUniformScale(); };
|
||||
auto setter = [=](float value) { myAvatar->setTargetScale(value); };
|
||||
|
|
|
@ -56,6 +56,7 @@ public:
|
|||
Checkbox,
|
||||
Button,
|
||||
ComboBox,
|
||||
PrimaryHand,
|
||||
// Special casing for an unusual preference
|
||||
Avatar
|
||||
};
|
||||
|
@ -339,6 +340,14 @@ public:
|
|||
Type getType() override { return Checkbox; }
|
||||
};
|
||||
|
||||
class PrimaryHandPreference : public StringPreference {
|
||||
Q_OBJECT
|
||||
public:
|
||||
PrimaryHandPreference(const QString& category, const QString& name, Getter getter, Setter setter)
|
||||
: StringPreference(category, name, getter, setter) { }
|
||||
Type getType() override { return PrimaryHand; }
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue