mirror of
https://github.com/overte-org/overte.git
synced 2025-04-20 01:24:03 +02:00
Merge pull request #9401 from zfox23/PAL_DisplayName
PAL: Editable Display Names & Immediate Update
This commit is contained in:
commit
7a568ed8a7
9 changed files with 138 additions and 26 deletions
|
@ -262,8 +262,12 @@ void AvatarMixer::broadcastAvatarData() {
|
|||
// setup a PacketList for the avatarPackets
|
||||
auto avatarPacketList = NLPacketList::create(PacketType::BulkAvatarData);
|
||||
|
||||
if (avatar.getSessionDisplayName().isEmpty() && // We haven't set it yet...
|
||||
nodeData->getReceivedIdentity()) { // ... but we have processed identity (with possible displayName).
|
||||
if (nodeData->getAvatarSessionDisplayNameMustChange()) {
|
||||
const QString& existingBaseDisplayName = nodeData->getBaseDisplayName();
|
||||
if (--_sessionDisplayNames[existingBaseDisplayName].second <= 0) {
|
||||
_sessionDisplayNames.remove(existingBaseDisplayName);
|
||||
}
|
||||
|
||||
QString baseName = avatar.getDisplayName().trimmed();
|
||||
const QRegularExpression curses{ "fuck|shit|damn|cock|cunt" }; // POC. We may eventually want something much more elaborate (subscription?).
|
||||
baseName = baseName.replace(curses, "*"); // Replace rather than remove, so that people have a clue that the person's a jerk.
|
||||
|
@ -276,11 +280,14 @@ void AvatarMixer::broadcastAvatarData() {
|
|||
QPair<int, int>& soFar = _sessionDisplayNames[baseName]; // Inserts and answers 0, 0 if not already present, which is what we want.
|
||||
int& highWater = soFar.first;
|
||||
nodeData->setBaseDisplayName(baseName);
|
||||
avatar.setSessionDisplayName((highWater > 0) ? baseName + "_" + QString::number(highWater) : baseName);
|
||||
QString sessionDisplayName = (highWater > 0) ? baseName + "_" + QString::number(highWater) : baseName;
|
||||
avatar.setSessionDisplayName(sessionDisplayName);
|
||||
highWater++;
|
||||
soFar.second++; // refcount
|
||||
nodeData->flagIdentityChange();
|
||||
sendIdentityPacket(nodeData, node); // Tell new node about its sessionUUID. Others will find out below.
|
||||
nodeData->setAvatarSessionDisplayNameMustChange(false);
|
||||
sendIdentityPacket(nodeData, node); // Tell node whose name changed about its new session display name. Others will find out below.
|
||||
qDebug() << "Giving session display name" << sessionDisplayName << "to node with ID" << node->getUUID();
|
||||
}
|
||||
|
||||
// this is an AGENT we have received head data from
|
||||
|
@ -584,7 +591,7 @@ void AvatarMixer::handleAvatarIdentityPacket(QSharedPointer<ReceivedMessage> mes
|
|||
if (avatar.processAvatarIdentity(identity)) {
|
||||
QMutexLocker nodeDataLocker(&nodeData->getMutex());
|
||||
nodeData->flagIdentityChange();
|
||||
nodeData->setReceivedIdentity();
|
||||
nodeData->setAvatarSessionDisplayNameMustChange(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -53,8 +53,8 @@ public:
|
|||
|
||||
HRCTime getIdentityChangeTimestamp() const { return _identityChangeTimestamp; }
|
||||
void flagIdentityChange() { _identityChangeTimestamp = p_high_resolution_clock::now(); }
|
||||
bool getReceivedIdentity() const { return _gotIdentity; }
|
||||
void setReceivedIdentity() { _gotIdentity = true; }
|
||||
bool getAvatarSessionDisplayNameMustChange() const { return _avatarSessionDisplayNameMustChange; }
|
||||
void setAvatarSessionDisplayNameMustChange(bool set = true) { _avatarSessionDisplayNameMustChange = set; }
|
||||
|
||||
void setFullRateDistance(float fullRateDistance) { _fullRateDistance = fullRateDistance; }
|
||||
float getFullRateDistance() const { return _fullRateDistance; }
|
||||
|
@ -112,7 +112,7 @@ private:
|
|||
std::unordered_set<QUuid> _hasReceivedFirstPacketsFrom;
|
||||
|
||||
HRCTime _identityChangeTimestamp;
|
||||
bool _gotIdentity { false };
|
||||
bool _avatarSessionDisplayNameMustChange{ false };
|
||||
|
||||
float _fullRateDistance = FLT_MAX;
|
||||
float _maxAvatarDistance = FLT_MAX;
|
||||
|
|
Binary file not shown.
|
@ -28,7 +28,7 @@ Item {
|
|||
property string uuid: ""
|
||||
property string displayName: ""
|
||||
property string userName: ""
|
||||
property int displayTextHeight: 18
|
||||
property real displayNameTextPixelSize: 18
|
||||
property int usernameTextHeight: 12
|
||||
property real audioLevel: 0.0
|
||||
property bool isMyCard: false
|
||||
|
@ -55,18 +55,112 @@ Item {
|
|||
width: parent.width - /*avatarImage.width - parent.spacing - */parent.anchors.leftMargin - parent.anchors.rightMargin
|
||||
height: childrenRect.height
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
// DisplayName Text
|
||||
|
||||
// DisplayName field for my card
|
||||
Rectangle {
|
||||
id: myDisplayName
|
||||
visible: isMyCard
|
||||
// Size
|
||||
width: parent.width + 70
|
||||
height: 35
|
||||
// Anchors
|
||||
anchors.top: parent.top
|
||||
anchors.left: parent.left
|
||||
anchors.leftMargin: -10
|
||||
// Style
|
||||
color: hifi.colors.textFieldLightBackground
|
||||
border.color: hifi.colors.blueHighlight
|
||||
border.width: 0
|
||||
TextInput {
|
||||
id: myDisplayNameText
|
||||
// Properties
|
||||
text: thisNameCard.displayName
|
||||
maximumLength: 256
|
||||
clip: true
|
||||
// Size
|
||||
width: parent.width
|
||||
height: parent.height
|
||||
// Anchors
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
anchors.left: parent.left
|
||||
anchors.leftMargin: 10
|
||||
anchors.right: parent.right
|
||||
anchors.rightMargin: editGlyph.width + editGlyph.anchors.rightMargin
|
||||
// Style
|
||||
color: hifi.colors.darkGray
|
||||
FontLoader { id: firaSansSemiBold; source: "../../fonts/FiraSans-SemiBold.ttf"; }
|
||||
font.family: firaSansSemiBold.name
|
||||
font.pixelSize: displayNameTextPixelSize
|
||||
selectionColor: hifi.colors.blueHighlight
|
||||
selectedTextColor: "black"
|
||||
// Text Positioning
|
||||
verticalAlignment: TextInput.AlignVCenter
|
||||
horizontalAlignment: TextInput.AlignLeft
|
||||
// Signals
|
||||
onEditingFinished: {
|
||||
pal.sendToScript({method: 'displayNameUpdate', params: text})
|
||||
cursorPosition = 0
|
||||
focus = false
|
||||
myDisplayName.border.width = 0
|
||||
color = hifi.colors.darkGray
|
||||
}
|
||||
}
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
acceptedButtons: Qt.LeftButton
|
||||
hoverEnabled: true
|
||||
onClicked: {
|
||||
myDisplayName.border.width = 1
|
||||
myDisplayNameText.focus ? myDisplayNameText.cursorPosition = myDisplayNameText.positionAt(mouseX, mouseY, TextInput.CursorOnCharacter) : myDisplayNameText.selectAll();
|
||||
myDisplayNameText.focus = true
|
||||
myDisplayNameText.color = "black"
|
||||
}
|
||||
onDoubleClicked: {
|
||||
myDisplayNameText.selectAll();
|
||||
myDisplayNameText.focus = true;
|
||||
}
|
||||
onEntered: myDisplayName.color = hifi.colors.lightGrayText
|
||||
onExited: myDisplayName.color = hifi.colors.textFieldLightBackground
|
||||
}
|
||||
// Edit pencil glyph
|
||||
HiFiGlyphs {
|
||||
id: editGlyph
|
||||
text: hifi.glyphs.editPencil
|
||||
// Text Size
|
||||
size: displayNameTextPixelSize*1.5
|
||||
// Anchors
|
||||
anchors.right: parent.right
|
||||
anchors.rightMargin: 5
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
// Style
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
color: hifi.colors.baseGray
|
||||
}
|
||||
}
|
||||
// Spacer for DisplayName for my card
|
||||
Rectangle {
|
||||
id: myDisplayNameSpacer
|
||||
width: myDisplayName.width
|
||||
// Anchors
|
||||
anchors.top: myDisplayName.bottom
|
||||
height: 5
|
||||
visible: isMyCard
|
||||
opacity: 0
|
||||
}
|
||||
// DisplayName Text for others' cards
|
||||
FiraSansSemiBold {
|
||||
id: displayNameText
|
||||
// Properties
|
||||
text: thisNameCard.displayName
|
||||
elide: Text.ElideRight
|
||||
visible: !isMyCard
|
||||
// Size
|
||||
width: parent.width
|
||||
// Anchors
|
||||
anchors.top: parent.top
|
||||
// Text Size
|
||||
size: thisNameCard.displayTextHeight
|
||||
size: displayNameTextPixelSize
|
||||
// Text Positioning
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
// Style
|
||||
|
@ -83,7 +177,7 @@ Item {
|
|||
// Size
|
||||
width: parent.width
|
||||
// Anchors
|
||||
anchors.top: displayNameText.bottom
|
||||
anchors.top: isMyCard ? myDisplayNameSpacer.bottom : displayNameText.bottom
|
||||
// Text Size
|
||||
size: thisNameCard.usernameTextHeight
|
||||
// Text Positioning
|
||||
|
@ -105,7 +199,7 @@ Item {
|
|||
Rectangle {
|
||||
id: nameCardVUMeter
|
||||
// Size
|
||||
width: ((gainSlider.value - gainSlider.minimumValue)/(gainSlider.maximumValue - gainSlider.minimumValue)) * parent.width
|
||||
width: isMyCard ? myDisplayName.width - 20 : ((gainSlider.value - gainSlider.minimumValue)/(gainSlider.maximumValue - gainSlider.minimumValue)) * parent.width
|
||||
height: 8
|
||||
// Anchors
|
||||
anchors.top: spacer.bottom
|
||||
|
|
|
@ -35,6 +35,17 @@ Rectangle {
|
|||
// Keep a local list of per-avatar gainSliderValueDBs. Far faster than fetching this data from the server.
|
||||
// NOTE: if another script modifies the per-avatar gain, this value won't be accurate!
|
||||
property var gainSliderValueDB: ({});
|
||||
|
||||
// The letterbox used for popup messages
|
||||
LetterboxMessage {
|
||||
id: letterboxMessage
|
||||
z: 999 // Force the popup on top of everything else
|
||||
}
|
||||
function letterbox(message) {
|
||||
letterboxMessage.text = message
|
||||
letterboxMessage.visible = true
|
||||
letterboxMessage.popupRadius = 0
|
||||
}
|
||||
|
||||
// This is the container for the PAL
|
||||
Rectangle {
|
||||
|
@ -176,8 +187,6 @@ Rectangle {
|
|||
TableViewColumn {
|
||||
visible: iAmAdmin
|
||||
role: "kick"
|
||||
// The hacky spaces used to center text over the button, since I don't know how to apply a margin
|
||||
// to column header text.
|
||||
title: "BAN"
|
||||
width: actionButtonWidth
|
||||
movable: false
|
||||
|
@ -337,11 +346,6 @@ Rectangle {
|
|||
visible: iAmAdmin
|
||||
color: hifi.colors.lightGrayText
|
||||
}
|
||||
function letterbox(message) {
|
||||
letterboxMessage.text = message;
|
||||
letterboxMessage.visible = true
|
||||
|
||||
}
|
||||
// This Rectangle refers to the [?] popup button next to "NAMES"
|
||||
Rectangle {
|
||||
color: hifi.colors.tableBackgroundLight
|
||||
|
@ -402,9 +406,6 @@ Rectangle {
|
|||
onExited: adminHelpText.color = hifi.colors.redHighlight
|
||||
}
|
||||
}
|
||||
LetterboxMessage {
|
||||
id: letterboxMessage
|
||||
}
|
||||
}
|
||||
|
||||
function findSessionIndex(sessionId, optionalData) { // no findIndex in .qml
|
||||
|
|
|
@ -312,10 +312,11 @@ Item {
|
|||
readonly property string error: "="
|
||||
readonly property string settings: "@"
|
||||
readonly property string trash: "{"
|
||||
readonly property string objectGroup: ""
|
||||
readonly property string objectGroup: "\ue000"
|
||||
readonly property string cm: "}"
|
||||
readonly property string msvg79: "~"
|
||||
readonly property string deg: "\\"
|
||||
readonly property string px: "|"
|
||||
readonly property string editPencil: "\ue00d"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1047,7 +1047,7 @@ bool AvatarData::processAvatarIdentity(const Identity& identity) {
|
|||
}
|
||||
|
||||
if (identity.displayName != _displayName) {
|
||||
setDisplayName(identity.displayName);
|
||||
_displayName = identity.displayName;
|
||||
hasIdentityChanged = true;
|
||||
}
|
||||
maybeUpdateSessionDisplayNameFromTransport(identity.sessionDisplayName);
|
||||
|
@ -1094,6 +1094,9 @@ void AvatarData::setSkeletonModelURL(const QUrl& skeletonModelURL) {
|
|||
|
||||
void AvatarData::setDisplayName(const QString& displayName) {
|
||||
_displayName = displayName;
|
||||
_sessionDisplayName = "";
|
||||
|
||||
sendIdentityPacket();
|
||||
|
||||
qCDebug(avatars) << "Changing display name for avatar to" << displayName;
|
||||
}
|
||||
|
|
|
@ -211,7 +211,8 @@ enum class AvatarMixerPacketVersion : PacketVersion {
|
|||
HandControllerJoints,
|
||||
HasKillAvatarReason,
|
||||
SessionDisplayName,
|
||||
Unignore
|
||||
Unignore,
|
||||
ImmediateSessionDisplayNameUpdates
|
||||
};
|
||||
|
||||
enum class DomainConnectRequestVersion : PacketVersion {
|
||||
|
|
|
@ -237,6 +237,11 @@ pal.fromQml.connect(function (message) { // messages are {method, params}, like
|
|||
data = message.params;
|
||||
Users.setAvatarGain(data['sessionId'], data['gain']);
|
||||
break;
|
||||
case 'displayNameUpdate':
|
||||
if (MyAvatar.displayName != message.params) {
|
||||
MyAvatar.displayName = message.params;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
print('Unrecognized message from Pal.qml:', JSON.stringify(message));
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue