mirror of
https://github.com/overte-org/overte.git
synced 2025-04-20 04:44:11 +02:00
Improve inner workings of overlay API.
More stuff is known to the C++, and a panel object in JavaScript can be gotten by ID from another thread.
This commit is contained in:
parent
055133b82e
commit
22453aa3ce
5 changed files with 110 additions and 50 deletions
|
@ -60,9 +60,9 @@
|
|||
}
|
||||
var overlay = new overlayTypes[type]();
|
||||
overlay._id = id;
|
||||
var panelID = Overlays.getAttachedPanel(id)
|
||||
if (panelID && panelID in panels) {
|
||||
panels[panelID].addChild(overlay);
|
||||
var attachedPanel = findPanel(Overlays.getAttachedPanel(id))
|
||||
if (attachedPanel) {
|
||||
attachedPanel.addChild(overlay);
|
||||
}
|
||||
overlays[id] = overlay;
|
||||
return overlay;
|
||||
|
@ -79,7 +79,7 @@
|
|||
//
|
||||
function findOverlay(id, knownOverlaysOnly, searchList) {
|
||||
if (id > 0) {
|
||||
knownOverlaysOnly = Boolean(knownOverlaysOnly) || Boolean(searchList);
|
||||
knownOverlaysOnly = Boolean(knownOverlaysOnly);
|
||||
searchList = searchList || overlays;
|
||||
var foundOverlay = searchList[id];
|
||||
if (foundOverlay) {
|
||||
|
@ -92,6 +92,47 @@
|
|||
return null;
|
||||
}
|
||||
|
||||
//
|
||||
// Create a new JavaScript object for a panel of given ID.
|
||||
//
|
||||
function makePanelFromId(id) {
|
||||
if (!Overlays.isAddedPanel(id)) {
|
||||
return null;
|
||||
}
|
||||
var panel = new FloatingUIPanel();
|
||||
panel._id = id;
|
||||
var attachedPanel = findPanel(Overlays.getAttachedPanel(id))
|
||||
if (attachedPanel) {
|
||||
attachedPanel.addChild(panel);
|
||||
}
|
||||
overlays[id] = overlay;
|
||||
return overlay;
|
||||
}
|
||||
|
||||
//
|
||||
// Get or create an overlay object from the id.
|
||||
//
|
||||
// @param knownOverlaysOnly (Optional: Boolean)
|
||||
// If true, a new object will not be created.
|
||||
// @param searchList (Optional: Object)
|
||||
// Map of overlay id's and overlay objects. Can be generated with
|
||||
// `OverlayManager.makeSearchList`.
|
||||
//
|
||||
function findPanel(id, knownPanelsOnly, searchList) {
|
||||
if (id > 0) {
|
||||
knownPanelsOnly = Boolean(knownPanelsOnly);
|
||||
searchList = searchList || panels;
|
||||
var foundPanel = searchList[id];
|
||||
if (foundPanel) {
|
||||
return foundPanel;
|
||||
}
|
||||
if (!knownPanelsOnly) {
|
||||
return makePanelFromId(id);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Perform global scoped operations on overlays, such as finding by ray intersection.
|
||||
|
@ -206,7 +247,6 @@
|
|||
} else {
|
||||
this._id = 0;
|
||||
}
|
||||
this._attachedPanelPointer = null;
|
||||
};
|
||||
|
||||
that.prototype.constructor = that;
|
||||
|
@ -219,7 +259,7 @@
|
|||
|
||||
Object.defineProperty(that.prototype, "attachedPanel", {
|
||||
get: function() {
|
||||
return this._attachedPanelPointer;
|
||||
return findPanel(Overlays.getAttachedPanel(this._id));
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -343,7 +383,6 @@
|
|||
this._children = [];
|
||||
this._visible = Boolean(params.visible);
|
||||
panels[this._id] = this;
|
||||
this._attachedPanelPointer = null;
|
||||
};
|
||||
|
||||
that.prototype.constructor = that;
|
||||
|
@ -384,7 +423,7 @@
|
|||
|
||||
Object.defineProperty(that.prototype, "attachedPanel", {
|
||||
get: function() {
|
||||
return this._attachedPanelPointer;
|
||||
return findPanel(Overlays.getAttachedPanel(this._id));
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -395,23 +434,12 @@
|
|||
});
|
||||
|
||||
that.prototype.addChild = function(child) {
|
||||
if (child instanceof Overlay && child.isPanelAttachable()) {
|
||||
if (child instanceof Overlay && child.isPanelAttachable() ||
|
||||
child instanceof FloatingUIPanel) {
|
||||
Overlays.setAttachedPanel(child._id, this._id);
|
||||
} else if (child instanceof FloatingUIPanel) {
|
||||
child.setProperties({
|
||||
anchorPosition: {
|
||||
bind: "panel",
|
||||
value: this._id
|
||||
},
|
||||
offsetRotation: {
|
||||
bind: "panel",
|
||||
value: this._id
|
||||
}
|
||||
});
|
||||
} else {
|
||||
throw new that.AddChildException("Given child is not panel attachable.");
|
||||
}
|
||||
child._attachedPanelPointer = this;
|
||||
child.visible = this.visible;
|
||||
this._children.push(child);
|
||||
return child;
|
||||
|
@ -420,19 +448,9 @@
|
|||
that.prototype.removeChild = function(child) {
|
||||
var i = this._children.indexOf(child);
|
||||
if (i >= 0) {
|
||||
if (child instanceof Overlay) {
|
||||
if (child instanceof Overlay || child instanceof FloatingUIPanel) {
|
||||
Overlays.setAttachedPanel(child._id, 0);
|
||||
} else if (child instanceof FloatingUIPanel) {
|
||||
child.setProperties({
|
||||
anchorPosition: {
|
||||
bind: "myAvatar"
|
||||
},
|
||||
offsetRotation: {
|
||||
bind: "myAvatar"
|
||||
}
|
||||
});
|
||||
}
|
||||
child._attachedPanelPointer = null;
|
||||
this._children.splice(i, 1);
|
||||
}
|
||||
};
|
||||
|
@ -465,11 +483,6 @@
|
|||
|
||||
function onPanelDeleted(id) {
|
||||
if (id in panels) {
|
||||
// Overlays will automatically delete all child overlays, but not all child panels. We
|
||||
// have to do that ourselves.
|
||||
panels[id]._children.forEach(function(child) {
|
||||
child.destroy();
|
||||
});
|
||||
if (panels[id].attachedPanel) {
|
||||
panels[id].attachedPanel.removeChild(panels[id]);
|
||||
}
|
||||
|
|
|
@ -49,6 +49,14 @@ void FloatingUIPanel::setOffsetRotation(const glm::quat& rotation) {
|
|||
});
|
||||
}
|
||||
|
||||
void FloatingUIPanel::setAttachedPanel(unsigned int panelID) {
|
||||
if (panelID) {
|
||||
attachAnchorToPanel(panelID);
|
||||
attachRotationToPanel(panelID);
|
||||
}
|
||||
_attachedPanel = panelID;
|
||||
}
|
||||
|
||||
void FloatingUIPanel::addChild(unsigned int childId) {
|
||||
if (!_children.contains(childId)) {
|
||||
_children.append(childId);
|
||||
|
@ -99,11 +107,7 @@ void FloatingUIPanel::setProperties(const QScriptValue &properties) {
|
|||
});
|
||||
}
|
||||
} else if (bindTypeString == "panel") {
|
||||
FloatingUIPanel::Pointer panel = Application::getInstance()->getOverlays()
|
||||
.getPanel(value.toVariant().toUInt());
|
||||
setAnchorPosition([panel]() -> glm::vec3 {
|
||||
return panel->getPosition();
|
||||
});
|
||||
attachAnchorToPanel(value.toVariant().toUInt());
|
||||
} else if (bindTypeString == "vec3") {
|
||||
QScriptValue x = value.property("x");
|
||||
QScriptValue y = value.property("y");
|
||||
|
@ -140,11 +144,7 @@ void FloatingUIPanel::setProperties(const QScriptValue &properties) {
|
|||
});
|
||||
}
|
||||
} else if (bindTypeString == "panel") {
|
||||
FloatingUIPanel::Pointer panel = Application::getInstance()->getOverlays()
|
||||
.getPanel(value.toVariant().toUInt());
|
||||
setOffsetRotation([panel]() -> glm::quat {
|
||||
return panel->getRotation();
|
||||
});
|
||||
attachRotationToPanel(value.toVariant().toUInt());
|
||||
} else if (bindTypeString == "quat") {
|
||||
QScriptValue x = value.property("x");
|
||||
QScriptValue y = value.property("y");
|
||||
|
@ -195,3 +195,17 @@ void FloatingUIPanel::setProperties(const QScriptValue &properties) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
void FloatingUIPanel::attachAnchorToPanel(unsigned int panelID) {
|
||||
FloatingUIPanel::Pointer panel = Application::getInstance()->getOverlays().getPanel(panelID);
|
||||
setAnchorPosition([panel]() -> glm::vec3 {
|
||||
return panel->getPosition();
|
||||
});
|
||||
}
|
||||
|
||||
void FloatingUIPanel::attachRotationToPanel(unsigned int panelID) {
|
||||
FloatingUIPanel::Pointer panel = Application::getInstance()->getOverlays().getPanel(panelID);
|
||||
setOffsetRotation([panel]() -> glm::quat {
|
||||
return panel->getRotation();
|
||||
});
|
||||
}
|
||||
|
|
|
@ -32,6 +32,7 @@ public:
|
|||
glm::quat getFacingRotation() const { return _facingRotation; }
|
||||
glm::vec3 getPosition() const;
|
||||
glm::quat getRotation() const;
|
||||
unsigned int getAttachedPanel() const { return _attachedPanel; }
|
||||
|
||||
void setAnchorPosition(const std::function<glm::vec3()>& func) { _anchorPosition = func; }
|
||||
void setAnchorPosition(const glm::vec3& position);
|
||||
|
@ -39,6 +40,7 @@ public:
|
|||
void setOffsetRotation(const glm::quat& rotation);
|
||||
void setOffsetPosition(const glm::vec3& position) { _offsetPosition = position; }
|
||||
void setFacingRotation(const glm::quat& rotation) { _facingRotation = rotation; }
|
||||
void setAttachedPanel(unsigned int panelID);
|
||||
|
||||
const QList<unsigned int>& getChildren() { return _children; }
|
||||
void addChild(unsigned int childId);
|
||||
|
@ -52,10 +54,14 @@ private:
|
|||
static std::function<glm::vec3()> const AVATAR_POSITION;
|
||||
static std::function<glm::quat()> const AVATAR_ORIENTATION;
|
||||
|
||||
void attachAnchorToPanel(unsigned int panelID);
|
||||
void attachRotationToPanel(unsigned int panelID);
|
||||
|
||||
std::function<glm::vec3()> _anchorPosition{AVATAR_POSITION};
|
||||
std::function<glm::quat()> _offsetRotation{AVATAR_ORIENTATION};
|
||||
glm::vec3 _offsetPosition{0, 0, 0};
|
||||
glm::quat _facingRotation{1, 0, 0, 0};
|
||||
unsigned int _attachedPanel{0};
|
||||
QScriptEngine* _scriptEngine;
|
||||
QList<unsigned int> _children;
|
||||
};
|
||||
|
|
|
@ -277,6 +277,8 @@ unsigned int Overlays::getAttachedPanel(unsigned int childId) const {
|
|||
auto attachable = std::dynamic_pointer_cast<PanelAttachable>(overlay);
|
||||
if (attachable) {
|
||||
return _panels.key(attachable->getAttachedPanel());
|
||||
} else if (_panels.contains(childId)) {
|
||||
return getPanel(childId)->getAttachedPanel();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -286,7 +288,7 @@ void Overlays::setAttachedPanel(unsigned int childId, unsigned int panelId) {
|
|||
auto attachable = std::dynamic_pointer_cast<PanelAttachable>(overlay);
|
||||
if (attachable) {
|
||||
if (_panels.contains(panelId)) {
|
||||
auto panel = _panels[panelId];
|
||||
auto panel = getPanel(panelId);
|
||||
panel->addChild(childId);
|
||||
attachable->setAttachedPanel(panel);
|
||||
} else {
|
||||
|
@ -296,6 +298,19 @@ void Overlays::setAttachedPanel(unsigned int childId, unsigned int panelId) {
|
|||
attachable->setAttachedPanel(nullptr);
|
||||
}
|
||||
}
|
||||
} else if (_panels.contains(childId)) {
|
||||
auto child = getPanel(childId);
|
||||
if (_panels.contains(panelId)) {
|
||||
auto panel = getPanel(panelId);
|
||||
panel->addChild(childId);
|
||||
child->setAttachedPanel(panelId);
|
||||
} else {
|
||||
auto panel = getPanel(child->getAttachedPanel());
|
||||
if (panel) {
|
||||
panel->removeChild(childId);
|
||||
child->setAttachedPanel(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -538,7 +553,7 @@ void Overlays::editPanel(unsigned int panelId, const QScriptValue& properties) {
|
|||
OverlayPropertyResult Overlays::getPanelProperty(unsigned int panelId, const QString& property) {
|
||||
OverlayPropertyResult result;
|
||||
if (_panels.contains(panelId)) {
|
||||
FloatingUIPanel::Pointer thisPanel = _panels[panelId];
|
||||
FloatingUIPanel::Pointer thisPanel = getPanel(panelId);
|
||||
QReadLocker lock(&_lock);
|
||||
result.value = thisPanel->getProperty(property);
|
||||
}
|
||||
|
@ -559,8 +574,14 @@ void Overlays::deletePanel(unsigned int panelId) {
|
|||
}
|
||||
|
||||
while (!panelToDelete->getChildren().isEmpty()) {
|
||||
deleteOverlay(panelToDelete->popLastChild());
|
||||
unsigned int childId = panelToDelete->popLastChild();
|
||||
deleteOverlay(childId);
|
||||
deletePanel(childId);
|
||||
}
|
||||
|
||||
emit panelDeleted(panelId);
|
||||
}
|
||||
|
||||
bool Overlays::isAddedOverlay(unsigned int id) {
|
||||
return _overlaysHUD.contains(id) || _overlaysWorld.contains(id);
|
||||
}
|
||||
|
|
|
@ -125,6 +125,12 @@ public slots:
|
|||
/// deletes a panel and all child overlays
|
||||
void deletePanel(unsigned int panelId);
|
||||
|
||||
/// return true if there is an overlay with that id else false
|
||||
bool isAddedOverlay(unsigned int id);
|
||||
|
||||
/// return true if there is a panel with that id else false
|
||||
bool isAddedPanel(unsigned int id) { return _panels.contains(id); }
|
||||
|
||||
signals:
|
||||
void overlayDeleted(unsigned int id);
|
||||
void panelDeleted(unsigned int id);
|
||||
|
|
Loading…
Reference in a new issue