summaryrefslogtreecommitdiff
path: root/src/player/AreaNode.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/player/AreaNode.cpp')
-rw-r--r--src/player/AreaNode.cpp350
1 files changed, 350 insertions, 0 deletions
diff --git a/src/player/AreaNode.cpp b/src/player/AreaNode.cpp
new file mode 100644
index 0000000..b09f4a6
--- /dev/null
+++ b/src/player/AreaNode.cpp
@@ -0,0 +1,350 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "AreaNode.h"
+
+#include "Event.h"
+#include "CursorEvent.h"
+#include "MouseEvent.h"
+#include "DivNode.h"
+#include "ArgList.h"
+#include "TypeDefinition.h"
+#include "TypeRegistry.h"
+#include "BoostPython.h"
+
+#include "../base/MathHelper.h"
+#include "../base/Logger.h"
+#include "../base/Exception.h"
+#include "../base/ObjectCounter.h"
+
+#include "../graphics/GLContext.h"
+
+#include <object.h>
+#include <compile.h>
+#include <eval.h>
+
+#include <iostream>
+
+using namespace boost;
+
+using namespace std;
+
+namespace avg {
+
+void AreaNode::registerType()
+{
+ TypeDefinition def = TypeDefinition("areanode", "node")
+ .addArg(Arg<float>("x", 0.0, false, offsetof(AreaNode, m_RelViewport.tl.x)))
+ .addArg(Arg<float>("y", 0.0, false, offsetof(AreaNode, m_RelViewport.tl.y)))
+ .addArg(Arg<glm::vec2>("pos", glm::vec2(0.0, 0.0)))
+ .addArg(Arg<float>("width", 0.0, false, offsetof(AreaNode, m_UserSize.x)))
+ .addArg(Arg<float>("height", 0.0, false, offsetof(AreaNode, m_UserSize.y)))
+ .addArg(Arg<glm::vec2>("size", glm::vec2(0.0, 0.0)))
+ .addArg(Arg<float>("angle", 0.0, false, offsetof(AreaNode, m_Angle)))
+ .addArg(Arg<glm::vec2>("pivot", glm::vec2(-32767, -32767), false,
+ offsetof(AreaNode, m_Pivot)))
+ .addArg(Arg<string>("elementoutlinecolor", "", false,
+ offsetof(AreaNode, m_sElementOutlineColor)));
+ TypeRegistry::get()->registerType(def);
+}
+
+AreaNode::AreaNode()
+ : m_RelViewport(0,0,0,0),
+ m_Transform(glm::mat4(0)),
+ m_bTransformChanged(true)
+{
+ ObjectCounter::get()->incRef(&typeid(*this));
+}
+
+AreaNode::~AreaNode()
+{
+ ObjectCounter::get()->decRef(&typeid(*this));
+}
+
+void AreaNode::setArgs(const ArgList& args)
+{
+ Node::setArgs(args);
+ args.getOverlayedArgVal(&m_RelViewport.tl, "pos", "x", "y", getID());
+ args.getOverlayedArgVal(&m_UserSize, "size", "width", "height", getID());
+ m_RelViewport.setWidth(m_UserSize.x);
+ m_RelViewport.setHeight(m_UserSize.y);
+ m_bHasCustomPivot = ((m_Pivot.x != -32767) && (m_Pivot.y != -32767));
+ setElementOutlineColor(m_sElementOutlineColor);
+}
+
+void AreaNode::connectDisplay()
+{
+ IntPoint MediaSize = getMediaSize();
+ if (m_UserSize.x == 0.0) {
+ m_RelViewport.setWidth(float(MediaSize.x));
+ } else {
+ m_RelViewport.setWidth(float(m_UserSize.x));
+ }
+ if (m_UserSize.y == 0.0) {
+ m_RelViewport.setHeight(float(MediaSize.y));
+ } else {
+ m_RelViewport.setHeight(float(m_UserSize.y));
+ }
+ if (m_UserSize.x == 0.0 || m_UserSize.y == 0) {
+ notifySubscribers("SIZE_CHANGED", m_RelViewport.size());
+ }
+ m_bTransformChanged = true;
+ Node::connectDisplay();
+}
+
+float AreaNode::getX() const
+{
+ return m_RelViewport.tl.x;
+}
+
+void AreaNode::setX(float x)
+{
+ setViewport(x, -32767, -32767, -32767);
+}
+
+float AreaNode::getY() const
+{
+ return m_RelViewport.tl.y;
+}
+
+void AreaNode::setY(float y)
+{
+ setViewport(-32767, y, -32767, -32767);
+}
+
+const glm::vec2& AreaNode::getPos() const
+{
+ return m_RelViewport.tl;
+}
+
+void AreaNode::setPos(const glm::vec2& pt)
+{
+ setViewport(pt.x, pt.y, -32767, -32767);
+}
+
+float AreaNode::getWidth() const
+{
+ return getRelViewport().width();
+}
+
+void AreaNode::setWidth(float width)
+{
+ m_UserSize.x = width;
+ setViewport(-32767, -32767, -32767, -32767);
+}
+
+float AreaNode::getHeight() const
+{
+ return getRelViewport().height();
+}
+
+void AreaNode::setHeight(float height)
+{
+ m_UserSize.y = height;
+ setViewport(-32767, -32767, -32767, -32767);
+}
+
+glm::vec2 AreaNode::getSize() const
+{
+ return getRelViewport().size();
+}
+
+void AreaNode::setSize(const glm::vec2& pt)
+{
+ m_UserSize = pt;
+ setViewport(-32767, -32767, -32767, -32767);
+}
+
+float AreaNode::getAngle() const
+{
+ return m_Angle;
+}
+
+void AreaNode::setAngle(float angle)
+{
+ m_Angle = fmod(angle, 2*PI);
+ m_bTransformChanged = true;
+}
+
+glm::vec2 AreaNode::getPivot() const
+{
+ if (m_bHasCustomPivot) {
+ return m_Pivot;
+ } else {
+ return getSize()/2.f;
+ }
+}
+
+void AreaNode::setPivot(const glm::vec2& pt)
+{
+ m_Pivot.x = pt.x;
+ m_Pivot.y = pt.y;
+ m_bHasCustomPivot = true;
+ m_bTransformChanged = true;
+}
+
+const std::string& AreaNode::getElementOutlineColor() const
+{
+ return m_sElementOutlineColor;
+}
+
+void AreaNode::setElementOutlineColor(const std::string& sColor)
+{
+ m_sElementOutlineColor = sColor;
+ if (sColor == "") {
+ m_ElementOutlineColor = Pixel32(0,0,0,0);
+ } else {
+ m_ElementOutlineColor = colorStringToColor(m_sElementOutlineColor);
+ }
+}
+
+glm::vec2 AreaNode::toLocal(const glm::vec2& globalPos) const
+{
+ glm::vec2 localPos = globalPos-m_RelViewport.tl;
+ return getRotatedPivot(localPos, -getAngle(), getPivot());
+}
+
+glm::vec2 AreaNode::toGlobal(const glm::vec2& localPos) const
+{
+ glm::vec2 globalPos = getRotatedPivot(localPos, getAngle(), getPivot());
+ return globalPos+m_RelViewport.tl;
+}
+
+void AreaNode::getElementsByPos(const glm::vec2& pos, vector<NodePtr>& pElements)
+{
+ if (pos.x >= 0 && pos.y >= 0 && pos.x < getSize().x && pos.y < getSize().y &&
+ reactsToMouseEvents())
+ {
+ pElements.push_back(getSharedThis());
+ }
+}
+
+void AreaNode::maybeRender(const glm::mat4& parentTransform)
+{
+ AVG_ASSERT(getState() == NS_CANRENDER);
+ if (isVisible()) {
+ calcTransform();
+ m_Transform = parentTransform*m_LocalTransform;
+ render();
+ }
+}
+
+void AreaNode::renderOutlines(const VertexArrayPtr& pVA, Pixel32 parentColor)
+{
+ Pixel32 effColor = getEffectiveOutlineColor(parentColor);
+ if (effColor != Pixel32(0,0,0,0)) {
+ glm::vec2 size = getSize();
+ glm::vec2 p0 = getAbsPos(glm::vec2(0.5, 0.5));
+ glm::vec2 p1 = getAbsPos(glm::vec2(size.x+0.5,0.5));
+ glm::vec2 p2 = getAbsPos(glm::vec2(size.x+0.5,size.y+0.5));
+ glm::vec2 p3 = getAbsPos(glm::vec2(0.5,size.y+0.5));
+ pVA->addLineData(effColor, p0, p1, 1);
+ pVA->addLineData(effColor, p1, p2, 1);
+ pVA->addLineData(effColor, p2, p3, 1);
+ pVA->addLineData(effColor, p3, p0, 1);
+ }
+}
+
+void AreaNode::setViewport(float x, float y, float width, float height)
+{
+ glm::vec2 oldSize = getRelViewport().size();
+ if (x == -32767) {
+ x = getRelViewport().tl.x;
+ }
+ if (y == -32767) {
+ y = getRelViewport().tl.y;
+ }
+ glm::vec2 mediaSize = glm::vec2(getMediaSize());
+ if (width == -32767) {
+ if (m_UserSize.x == 0.0) {
+ width = mediaSize.x;
+ } else {
+ width = m_UserSize.x;
+ }
+ }
+ if (height == -32767) {
+ if (m_UserSize.y == 0.0) {
+ height = mediaSize.y;
+ } else {
+ height = m_UserSize.y;
+ }
+ }
+ if (width < 0 || height < 0) {
+ throw Exception(AVG_ERR_OUT_OF_RANGE, "Negative size for a node.");
+ }
+ m_RelViewport = FRect(x, y, x+width, y+height);
+ if (oldSize != m_RelViewport.size()) {
+ notifySubscribers("SIZE_CHANGED", m_RelViewport.size());
+ }
+ m_bTransformChanged = true;
+}
+
+const FRect& AreaNode::getRelViewport() const
+{
+// cerr << "Node " << getID() << ": " << m_RelViewport << endl;
+ return m_RelViewport;
+}
+
+string AreaNode::dump(int indent)
+{
+ string dumpStr = Node::dump(indent);
+ char sz[256];
+ sprintf (sz, ", x=%.1f, y=%.1f, width=%.1f, height=%.1f\n",
+ m_RelViewport.tl.x, m_RelViewport.tl.y,
+ m_RelViewport.width(), m_RelViewport.height());
+ dumpStr += sz;
+
+ return dumpStr;
+}
+
+const glm::mat4& AreaNode::getTransform() const
+{
+ return m_Transform;
+}
+
+glm::vec2 AreaNode::getUserSize() const
+{
+ return m_UserSize;
+}
+
+Pixel32 AreaNode::getEffectiveOutlineColor(Pixel32 parentColor) const
+{
+ if (m_ElementOutlineColor == Pixel32(0,0,0,0)) {
+ return parentColor;
+ } else {
+ return m_ElementOutlineColor;
+ }
+}
+
+void AreaNode::calcTransform()
+{
+ if (m_bTransformChanged) {
+ glm::vec3 pos(m_RelViewport.tl.x, m_RelViewport.tl.y, 0);
+ glm::vec3 pivot(getPivot().x, getPivot().y, 0);
+ glm::mat4 transform = glm::translate(glm::mat4(1.0f), pos);
+ transform = glm::translate(transform, pivot);
+ transform = glm::rotate(transform, (180.f/PI)*m_Angle, glm::vec3(0,0,1));
+ m_LocalTransform = glm::translate(transform, -pivot);
+ m_bTransformChanged = false;
+ }
+}
+
+}