mirror of
https://github.com/4ian/GDevelop.git
synced 2025-10-15 10:19:04 +00:00
Anchor behavior for native games (#275)
* Add AnchorBehavior * Improve the AnchorBehavior * Add an icon to the AnchorBehavior * Code cleaning in AnchorBehavior * Add more icons for the AnchorBehavior
This commit is contained in:

committed by
Florian Rival

parent
d12924daaf
commit
d7c897b488
Binary file not shown.
After Width: | Height: | Size: 308 B |
Binary file not shown.
After Width: | Height: | Size: 226 B |
Binary file not shown.
After Width: | Height: | Size: 303 B |
315
Extensions/AnchorBehavior/AnchorBehavior.cpp
Normal file
315
Extensions/AnchorBehavior/AnchorBehavior.cpp
Normal file
@@ -0,0 +1,315 @@
|
||||
/**
|
||||
|
||||
GDevelop - Anchor Behavior Extension
|
||||
Copyright (c) 2016 Victor Levasseur (victorlevasseur52@gmail.com)
|
||||
This project is released under the MIT License.
|
||||
*/
|
||||
|
||||
#include <memory>
|
||||
#include <iostream>
|
||||
#include <set>
|
||||
#include "AnchorBehavior.h"
|
||||
#include "GDCore/Tools/Localization.h"
|
||||
#include "GDCpp/Extensions/Builtin/MathematicalTools.h"
|
||||
#include "GDCpp/Runtime/Project/Layout.h"
|
||||
#include "GDCpp/Runtime/Serialization/SerializerElement.h"
|
||||
#include "GDCpp/Runtime/RuntimeScene.h"
|
||||
#include "GDCpp/Runtime/RuntimeObject.h"
|
||||
#include "GDCpp/Runtime/CommonTools.h"
|
||||
#include <SFML/Window.hpp>
|
||||
#include "GDCore/CommonTools.h"
|
||||
#include <iostream>
|
||||
#include <cmath>
|
||||
#include <algorithm>
|
||||
#if defined(GD_IDE_ONLY)
|
||||
#include <map>
|
||||
#include "GDCore/IDE/Dialogs/PropertyDescriptor.h"
|
||||
#endif
|
||||
|
||||
AnchorBehavior::AnchorBehavior() :
|
||||
m_leftEdgeAnchor(ANCHOR_HORIZONTAL_NONE),
|
||||
m_rightEdgeAnchor(ANCHOR_HORIZONTAL_NONE),
|
||||
m_topEdgeAnchor(ANCHOR_VERTICAL_NONE),
|
||||
m_bottomEdgeAnchor(ANCHOR_VERTICAL_NONE),
|
||||
m_invalidDistances(true),
|
||||
m_leftEdgeDistance(0.f),
|
||||
m_rightEdgeDistance(0.f),
|
||||
m_topEdgeDistance(0.f),
|
||||
m_bottomEdgeDistance(0.f),
|
||||
m_oldWindowSize(-1, -1)
|
||||
{
|
||||
}
|
||||
|
||||
void AnchorBehavior::OnActivate()
|
||||
{
|
||||
m_invalidDistances = true;
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
sf::Vector2f mapFloatPixelToCoords(const sf::Vector2f& point, const sf::RenderTarget & target, const sf::View& view)
|
||||
{
|
||||
// First, convert from viewport coordinates to homogeneous coordinates
|
||||
sf::Vector2f normalized;
|
||||
sf::IntRect viewport = target.getViewport(view);
|
||||
normalized.x = -1.f + 2.f * (point.x - static_cast<float>(viewport.left)) / static_cast<float>(viewport.width);
|
||||
normalized.y = 1.f - 2.f * (point.y - static_cast<float>(viewport.top)) / static_cast<float>(viewport.height);
|
||||
|
||||
// Then transform by the inverse of the view matrix
|
||||
return view.getInverseTransform().transformPoint(normalized);
|
||||
}
|
||||
|
||||
sf::Vector2f mapCoordsToFloatPixel(const sf::Vector2f & point, const sf::RenderTarget & target, const sf::View & view)
|
||||
{
|
||||
//Note: almost the same as RenderTarget::mapCoordsToPixel except that the result is sf::Vector2f
|
||||
|
||||
//First, transform the point by the view matrix
|
||||
sf::Vector2f normalized = view.getTransform().transformPoint(point);
|
||||
|
||||
//Then convert to viewport coordinates
|
||||
sf::Vector2f pixel;
|
||||
sf::IntRect viewport = target.getViewport(view);
|
||||
pixel.x = ( normalized.x + 1.f) / 2.f * static_cast<float>(viewport.width) + static_cast<float>(viewport.left);
|
||||
pixel.y = (-normalized.y + 1.f) / 2.f * static_cast<float>(viewport.height) + static_cast<float>(viewport.top);
|
||||
|
||||
return pixel;
|
||||
}
|
||||
}
|
||||
|
||||
void AnchorBehavior::DoStepPreEvents(RuntimeScene & scene)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void AnchorBehavior::DoStepPostEvents(RuntimeScene & scene)
|
||||
{
|
||||
sf::Vector2u windowSize = scene.renderWindow->getSize();
|
||||
const RuntimeLayer & layer = scene.GetRuntimeLayer(object->GetLayer());
|
||||
const RuntimeCamera & firstCamera = layer.GetCamera(0);
|
||||
|
||||
if(m_invalidDistances)
|
||||
{
|
||||
//Calculate the distances from the window's bounds.
|
||||
sf::Vector2f topLeftPixel = mapCoordsToFloatPixel(
|
||||
sf::Vector2f(object->GetDrawableX(), object->GetDrawableY()),
|
||||
*(scene.renderWindow),
|
||||
firstCamera.GetSFMLView());
|
||||
|
||||
sf::Vector2f bottomRightPixel = mapCoordsToFloatPixel(
|
||||
sf::Vector2f(object->GetDrawableX() + object->GetWidth(), object->GetDrawableY() + object->GetHeight()),
|
||||
*(scene.renderWindow),
|
||||
firstCamera.GetSFMLView());
|
||||
|
||||
//Left edge
|
||||
if(m_leftEdgeAnchor == ANCHOR_HORIZONTAL_WINDOW_LEFT)
|
||||
m_leftEdgeDistance = topLeftPixel.x;
|
||||
else if(m_leftEdgeAnchor == ANCHOR_HORIZONTAL_WINDOW_RIGHT)
|
||||
m_leftEdgeDistance = static_cast<float>(windowSize.x) - topLeftPixel.x;
|
||||
else if(m_leftEdgeAnchor == ANCHOR_HORIZONTAL_PROPORTIONAL)
|
||||
m_leftEdgeDistance = topLeftPixel.x / windowSize.x;
|
||||
|
||||
//Right edge
|
||||
if(m_rightEdgeAnchor == ANCHOR_HORIZONTAL_WINDOW_LEFT)
|
||||
m_leftEdgeDistance = bottomRightPixel.x;
|
||||
else if(m_rightEdgeAnchor == ANCHOR_HORIZONTAL_WINDOW_RIGHT)
|
||||
m_rightEdgeDistance = static_cast<float>(windowSize.x) - bottomRightPixel.x;
|
||||
else if(m_rightEdgeAnchor == ANCHOR_HORIZONTAL_PROPORTIONAL)
|
||||
m_rightEdgeDistance = bottomRightPixel.x / windowSize.x;
|
||||
|
||||
//Top edge
|
||||
if(m_topEdgeAnchor == ANCHOR_VERTICAL_WINDOW_TOP)
|
||||
m_topEdgeDistance = topLeftPixel.y;
|
||||
else if(m_topEdgeAnchor == ANCHOR_VERTICAL_WINDOW_BOTTOM)
|
||||
m_topEdgeDistance = static_cast<float>(windowSize.y) - topLeftPixel.y;
|
||||
else if(m_topEdgeAnchor = ANCHOR_VERTICAL_PROPORTIONAL)
|
||||
m_topEdgeDistance = topLeftPixel.y / static_cast<float>(windowSize.y);
|
||||
|
||||
//Bottom edge
|
||||
if(m_bottomEdgeAnchor == ANCHOR_VERTICAL_WINDOW_TOP)
|
||||
m_bottomEdgeDistance = bottomRightPixel.y;
|
||||
else if(m_bottomEdgeAnchor == ANCHOR_VERTICAL_WINDOW_BOTTOM)
|
||||
m_bottomEdgeDistance = static_cast<float>(windowSize.y) - bottomRightPixel.y;
|
||||
else if(m_bottomEdgeAnchor = ANCHOR_VERTICAL_PROPORTIONAL)
|
||||
m_bottomEdgeDistance = bottomRightPixel.y / static_cast<float>(windowSize.y);
|
||||
|
||||
m_invalidDistances = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
//Move and resize the object if needed
|
||||
sf::Vector2f topLeftPixel;
|
||||
sf::Vector2f bottomRightPixel;
|
||||
|
||||
//Left edge
|
||||
if(m_leftEdgeAnchor == ANCHOR_HORIZONTAL_WINDOW_LEFT)
|
||||
topLeftPixel.x = m_leftEdgeDistance;
|
||||
else if(m_leftEdgeAnchor == ANCHOR_HORIZONTAL_WINDOW_RIGHT)
|
||||
topLeftPixel.x = static_cast<float>(windowSize.x) - m_leftEdgeDistance;
|
||||
else if(m_leftEdgeAnchor == ANCHOR_HORIZONTAL_PROPORTIONAL)
|
||||
topLeftPixel.x = m_leftEdgeDistance * static_cast<float>(windowSize.x);
|
||||
|
||||
//Top edge
|
||||
if(m_topEdgeAnchor == ANCHOR_VERTICAL_WINDOW_TOP)
|
||||
topLeftPixel.y = m_topEdgeDistance;
|
||||
else if(m_topEdgeAnchor == ANCHOR_VERTICAL_WINDOW_BOTTOM)
|
||||
topLeftPixel.y = static_cast<float>(windowSize.y) - m_topEdgeDistance;
|
||||
else if(m_topEdgeAnchor == ANCHOR_VERTICAL_PROPORTIONAL)
|
||||
topLeftPixel.y = m_topEdgeDistance * static_cast<float>(windowSize.y);
|
||||
|
||||
//Right edge
|
||||
if(m_rightEdgeAnchor == ANCHOR_HORIZONTAL_WINDOW_LEFT)
|
||||
bottomRightPixel.x = m_rightEdgeDistance;
|
||||
else if(m_rightEdgeAnchor == ANCHOR_HORIZONTAL_WINDOW_RIGHT)
|
||||
bottomRightPixel.x = static_cast<float>(windowSize.x) - m_rightEdgeDistance;
|
||||
else if(m_rightEdgeAnchor == ANCHOR_HORIZONTAL_PROPORTIONAL)
|
||||
bottomRightPixel.x = m_rightEdgeDistance * static_cast<float>(windowSize.x);
|
||||
|
||||
//Bottom edge
|
||||
if(m_bottomEdgeAnchor == ANCHOR_VERTICAL_WINDOW_TOP)
|
||||
bottomRightPixel.y = m_bottomEdgeDistance;
|
||||
else if(m_bottomEdgeAnchor == ANCHOR_VERTICAL_WINDOW_BOTTOM)
|
||||
bottomRightPixel.y = static_cast<float>(windowSize.y) - m_bottomEdgeDistance;
|
||||
else if(m_bottomEdgeAnchor == ANCHOR_VERTICAL_PROPORTIONAL)
|
||||
bottomRightPixel.y = m_bottomEdgeDistance * static_cast<float>(windowSize.y);
|
||||
|
||||
sf::Vector2f topLeftCoord = mapFloatPixelToCoords(topLeftPixel, (*scene.renderWindow), firstCamera.GetSFMLView());
|
||||
sf::Vector2f bottomRightCoord = mapFloatPixelToCoords(bottomRightPixel, (*scene.renderWindow), firstCamera.GetSFMLView());
|
||||
|
||||
//Move and resize the object accordingly to the anchors
|
||||
if(m_rightEdgeAnchor != ANCHOR_HORIZONTAL_NONE)
|
||||
object->SetWidth(bottomRightCoord.x - topLeftCoord.x);
|
||||
if(m_bottomEdgeAnchor != ANCHOR_VERTICAL_NONE)
|
||||
object->SetHeight(bottomRightCoord.y - topLeftCoord.y);
|
||||
if(m_leftEdgeAnchor != ANCHOR_HORIZONTAL_NONE)
|
||||
object->SetX(topLeftCoord.x + object->GetX() - object->GetDrawableX());
|
||||
if(m_topEdgeAnchor != ANCHOR_VERTICAL_NONE)
|
||||
object->SetY(topLeftCoord.y + object->GetY() - object->GetDrawableY());
|
||||
}
|
||||
}
|
||||
|
||||
void AnchorBehavior::UnserializeFrom(const gd::SerializerElement & element)
|
||||
{
|
||||
m_leftEdgeAnchor = static_cast<HorizontalAnchor>(element.GetIntAttribute("leftEdgeAnchor"));
|
||||
m_rightEdgeAnchor = static_cast<HorizontalAnchor>(element.GetIntAttribute("rightEdgeAnchor"));
|
||||
m_topEdgeAnchor = static_cast<VerticalAnchor>(element.GetIntAttribute("topEdgeAnchor"));
|
||||
m_bottomEdgeAnchor = static_cast<VerticalAnchor>(element.GetIntAttribute("bottomEdgeAnchor"));
|
||||
}
|
||||
|
||||
#if defined(GD_IDE_ONLY)
|
||||
void AnchorBehavior::SerializeTo(gd::SerializerElement & element) const
|
||||
{
|
||||
element.SetAttribute("leftEdgeAnchor", static_cast<int>(m_leftEdgeAnchor));
|
||||
element.SetAttribute("rightEdgeAnchor", static_cast<int>(m_rightEdgeAnchor));
|
||||
element.SetAttribute("topEdgeAnchor", static_cast<int>(m_topEdgeAnchor));
|
||||
element.SetAttribute("bottomEdgeAnchor", static_cast<int>(m_bottomEdgeAnchor));
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
gd::String GetAnchorAsString(AnchorBehavior::HorizontalAnchor anchor)
|
||||
{
|
||||
if(anchor == AnchorBehavior::ANCHOR_HORIZONTAL_WINDOW_LEFT)
|
||||
return _("Window left");
|
||||
else if(anchor == AnchorBehavior::ANCHOR_HORIZONTAL_WINDOW_RIGHT)
|
||||
return _("Window right");
|
||||
else if(anchor == AnchorBehavior::ANCHOR_HORIZONTAL_PROPORTIONAL)
|
||||
return _("Proportional");
|
||||
else
|
||||
return _("No anchor");
|
||||
}
|
||||
|
||||
gd::String GetAnchorAsString(AnchorBehavior::VerticalAnchor anchor)
|
||||
{
|
||||
if(anchor == AnchorBehavior::ANCHOR_VERTICAL_WINDOW_TOP)
|
||||
return _("Window top");
|
||||
else if(anchor == AnchorBehavior::ANCHOR_VERTICAL_WINDOW_BOTTOM)
|
||||
return _("Window bottom");
|
||||
else if(anchor == AnchorBehavior::ANCHOR_VERTICAL_PROPORTIONAL)
|
||||
return _("Proportional");
|
||||
else
|
||||
return _("No anchor");
|
||||
}
|
||||
}
|
||||
|
||||
std::map<gd::String, gd::PropertyDescriptor> AnchorBehavior::GetProperties(gd::Project & project) const
|
||||
{
|
||||
std::map<gd::String, gd::PropertyDescriptor> properties;
|
||||
|
||||
properties[_("Left edge anchor")]
|
||||
.SetValue(GetAnchorAsString(m_leftEdgeAnchor))
|
||||
.SetType("Choice")
|
||||
.AddExtraInfo(_("No anchor"))
|
||||
.AddExtraInfo(_("Window left"))
|
||||
.AddExtraInfo(_("Window right"))
|
||||
.AddExtraInfo(_("Proportional"));
|
||||
|
||||
properties[_("Right edge anchor")]
|
||||
.SetValue(GetAnchorAsString(m_rightEdgeAnchor))
|
||||
.SetType("Choice")
|
||||
.AddExtraInfo(_("No anchor"))
|
||||
.AddExtraInfo(_("Window left"))
|
||||
.AddExtraInfo(_("Window right"))
|
||||
.AddExtraInfo(_("Proportional"));
|
||||
|
||||
properties[_("Top edge anchor")]
|
||||
.SetValue(GetAnchorAsString(m_topEdgeAnchor))
|
||||
.SetType("Choice")
|
||||
.AddExtraInfo(_("No anchor"))
|
||||
.AddExtraInfo(_("Window top"))
|
||||
.AddExtraInfo(_("Window bottom"))
|
||||
.AddExtraInfo(_("Proportional"));
|
||||
|
||||
properties[_("Bottom edge anchor")]
|
||||
.SetValue(GetAnchorAsString(m_bottomEdgeAnchor))
|
||||
.SetType("Choice")
|
||||
.AddExtraInfo(_("No anchor"))
|
||||
.AddExtraInfo(_("Window top"))
|
||||
.AddExtraInfo(_("Window bottom"))
|
||||
.AddExtraInfo(_("Proportional"));
|
||||
|
||||
return properties;
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
AnchorBehavior::HorizontalAnchor GetHorizontalAnchorFromString(const gd::String & value)
|
||||
{
|
||||
if(value == _("Window left"))
|
||||
return AnchorBehavior::ANCHOR_HORIZONTAL_WINDOW_LEFT;
|
||||
else if(value == _("Window right"))
|
||||
return AnchorBehavior::ANCHOR_HORIZONTAL_WINDOW_RIGHT;
|
||||
else if(value == _("Proportional"))
|
||||
return AnchorBehavior::ANCHOR_HORIZONTAL_PROPORTIONAL;
|
||||
else
|
||||
return AnchorBehavior::ANCHOR_HORIZONTAL_NONE;
|
||||
}
|
||||
|
||||
AnchorBehavior::VerticalAnchor GetVerticalAnchorFromString(const gd::String & value)
|
||||
{
|
||||
if(value == _("Window top"))
|
||||
return AnchorBehavior::ANCHOR_VERTICAL_WINDOW_TOP;
|
||||
else if(value == _("Window bottom"))
|
||||
return AnchorBehavior::ANCHOR_VERTICAL_WINDOW_BOTTOM;
|
||||
else if(value == _("Proportional"))
|
||||
return AnchorBehavior::ANCHOR_VERTICAL_PROPORTIONAL;
|
||||
else
|
||||
return AnchorBehavior::ANCHOR_VERTICAL_NONE;
|
||||
}
|
||||
}
|
||||
|
||||
bool AnchorBehavior::UpdateProperty(const gd::String & name, const gd::String & value, gd::Project & project)
|
||||
{
|
||||
if ( name == _("Left edge anchor") )
|
||||
m_leftEdgeAnchor = GetHorizontalAnchorFromString(value);
|
||||
else if ( name == _("Right edge anchor") )
|
||||
m_rightEdgeAnchor = GetHorizontalAnchorFromString(value);
|
||||
else if ( name == _("Top edge anchor") )
|
||||
m_topEdgeAnchor = GetVerticalAnchorFromString(value);
|
||||
else if ( name == _("Bottom edge anchor") )
|
||||
m_bottomEdgeAnchor = GetVerticalAnchorFromString(value);
|
||||
else
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
#endif
|
84
Extensions/AnchorBehavior/AnchorBehavior.h
Normal file
84
Extensions/AnchorBehavior/AnchorBehavior.h
Normal file
@@ -0,0 +1,84 @@
|
||||
/**
|
||||
GDevelop - Anchor Behavior Extension
|
||||
Copyright (c) 2016 Victor Levasseur (victorlevasseur52@gmail.com)
|
||||
This project is released under the MIT License.
|
||||
*/
|
||||
|
||||
#ifndef ANCHORBEHAVIOR_H
|
||||
#define ANCHORBEHAVIOR_H
|
||||
|
||||
#include "GDCpp/Runtime/Project/Behavior.h"
|
||||
#include "GDCpp/Runtime/Project/Object.h"
|
||||
#include <SFML/Graphics/RenderTarget.hpp>
|
||||
#include <SFML/Graphics/View.hpp>
|
||||
#include <SFML/System/Vector2.hpp>
|
||||
#include <vector>
|
||||
namespace gd { class Layout; }
|
||||
class RuntimeScene;
|
||||
namespace gd { class SerializerElement; }
|
||||
class RuntimeScenePlatformData;
|
||||
|
||||
/**
|
||||
* \brief Allow to anchor objects to the window's bounds.
|
||||
*/
|
||||
class GD_EXTENSION_API AnchorBehavior : public Behavior
|
||||
{
|
||||
public:
|
||||
enum HorizontalAnchor
|
||||
{
|
||||
ANCHOR_HORIZONTAL_NONE = 0,
|
||||
ANCHOR_HORIZONTAL_WINDOW_LEFT = 1,
|
||||
ANCHOR_HORIZONTAL_WINDOW_RIGHT = 2,
|
||||
ANCHOR_HORIZONTAL_PROPORTIONAL = 3
|
||||
};
|
||||
|
||||
enum VerticalAnchor
|
||||
{
|
||||
ANCHOR_VERTICAL_NONE = 0,
|
||||
ANCHOR_VERTICAL_WINDOW_TOP = 1,
|
||||
ANCHOR_VERTICAL_WINDOW_BOTTOM = 2,
|
||||
ANCHOR_VERTICAL_PROPORTIONAL = 3
|
||||
};
|
||||
|
||||
AnchorBehavior();
|
||||
virtual ~AnchorBehavior() {};
|
||||
virtual Behavior* Clone() const { return new AnchorBehavior(*this); }
|
||||
|
||||
/**
|
||||
* \brief Unserialize the behavior
|
||||
*/
|
||||
virtual void UnserializeFrom(const gd::SerializerElement & element);
|
||||
|
||||
#if defined(GD_IDE_ONLY)
|
||||
/**
|
||||
* \brief Serialize the behavior
|
||||
*/
|
||||
virtual void SerializeTo(gd::SerializerElement & element) const;
|
||||
|
||||
virtual std::map<gd::String, gd::PropertyDescriptor> GetProperties(gd::Project & project) const;
|
||||
virtual bool UpdateProperty(const gd::String & name, const gd::String & value, gd::Project & project);
|
||||
#endif
|
||||
|
||||
virtual void OnActivate();
|
||||
|
||||
private:
|
||||
virtual void DoStepPreEvents(RuntimeScene & scene) override;
|
||||
virtual void DoStepPostEvents(RuntimeScene & scene) override;
|
||||
|
||||
HorizontalAnchor m_leftEdgeAnchor;
|
||||
HorizontalAnchor m_rightEdgeAnchor;
|
||||
VerticalAnchor m_topEdgeAnchor;
|
||||
VerticalAnchor m_bottomEdgeAnchor;
|
||||
|
||||
bool m_invalidDistances;
|
||||
//Distances (in window's units) from the XXX edge of the object to side of the window the edge is anchored on.
|
||||
//Note: If the edge anchor is set to PROPORTIONAL, then it contains the ratio of the distance to the window size.
|
||||
float m_leftEdgeDistance;
|
||||
float m_rightEdgeDistance;
|
||||
float m_topEdgeDistance;
|
||||
float m_bottomEdgeDistance;
|
||||
|
||||
sf::Vector2u m_oldWindowSize;
|
||||
};
|
||||
|
||||
#endif // ANCHORBEHAVIOR_H
|
25
Extensions/AnchorBehavior/CMakeLists.txt
Normal file
25
Extensions/AnchorBehavior/CMakeLists.txt
Normal file
@@ -0,0 +1,25 @@
|
||||
cmake_minimum_required(VERSION 2.6)
|
||||
cmake_policy(SET CMP0015 NEW)
|
||||
|
||||
project(AnchorBehavior)
|
||||
gd_add_extension_includes()
|
||||
|
||||
#Defines
|
||||
###
|
||||
gd_add_extension_definitions(AnchorBehavior)
|
||||
|
||||
#The targets
|
||||
###
|
||||
include_directories(.)
|
||||
file(GLOB source_files *)
|
||||
|
||||
gd_add_extension_target(AnchorBehavior "${source_files}")
|
||||
gdcpp_add_runtime_extension_target(AnchorBehavior_Runtime "${source_files}")
|
||||
|
||||
#Linker files for the IDE extension
|
||||
###
|
||||
gd_extension_link_libraries(AnchorBehavior)
|
||||
|
||||
#Linker files for the GD C++ Runtime extension
|
||||
###
|
||||
gdcpp_runtime_extension_link_libraries(AnchorBehavior_Runtime)
|
68
Extensions/AnchorBehavior/Extension.cpp
Normal file
68
Extensions/AnchorBehavior/Extension.cpp
Normal file
@@ -0,0 +1,68 @@
|
||||
/**
|
||||
|
||||
GDevelop - Anchor Behavior Extension
|
||||
Copyright (c) 2016 Victor Levasseur (victorlevasseur52@gmail.com)
|
||||
This project is released under the MIT License.
|
||||
*/
|
||||
|
||||
#include "GDCpp/Extensions/ExtensionBase.h"
|
||||
#include "GDCpp/Runtime/Project/BehaviorsSharedData.h"
|
||||
#include "GDCore/Tools/Version.h"
|
||||
#include "AnchorBehavior.h"
|
||||
|
||||
|
||||
void DeclareAnchorBehaviorExtension(gd::PlatformExtension & extension)
|
||||
{
|
||||
extension.SetExtensionInformation("AnchorBehavior",
|
||||
_("Anchor"),
|
||||
_("Anchor objects to the window's bounds."),
|
||||
"Victor Levasseur",
|
||||
"Open source (MIT License)");
|
||||
|
||||
gd::BehaviorMetadata & aut = extension.AddBehavior("AnchorBehavior",
|
||||
_("Anchor"),
|
||||
"Anchor",
|
||||
_("Behavior that anchors objects to the window's bounds."),
|
||||
"",
|
||||
"CppPlatform/Extensions/AnchorIcon.png",
|
||||
"AnchorBehavior",
|
||||
std::shared_ptr<gd::Behavior>(new AnchorBehavior),
|
||||
std::shared_ptr<gd::BehaviorsSharedData>(new gd::BehaviorsSharedData));
|
||||
|
||||
#if defined(GD_IDE_ONLY)
|
||||
|
||||
aut.SetIncludeFile("AnchorBehavior/AnchorBehavior.h");
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief This class declares information about the extension.
|
||||
*/
|
||||
class AnchorBehaviorCppExtension : public ExtensionBase
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor of an extension declares everything the extension contains: objects, actions, conditions and expressions.
|
||||
*/
|
||||
AnchorBehaviorCppExtension()
|
||||
{
|
||||
DeclareAnchorBehaviorExtension(*this);
|
||||
GD_COMPLETE_EXTENSION_COMPILATION_INFORMATION();
|
||||
};
|
||||
};
|
||||
|
||||
#if defined(ANDROID)
|
||||
extern "C" ExtensionBase * CreateGDCppAnchorBehaviorExtension() {
|
||||
return new AnchorBehaviorCppExtension;
|
||||
}
|
||||
#elif !defined(EMSCRIPTEN)
|
||||
/**
|
||||
* Used by GDevelop to create the extension class
|
||||
* -- Do not need to be modified. --
|
||||
*/
|
||||
extern "C" ExtensionBase * GD_EXTENSION_API CreateGDExtension() {
|
||||
return new AnchorBehaviorCppExtension;
|
||||
}
|
||||
#endif
|
@@ -10,6 +10,7 @@ include(CMakeUtils.txt) #Functions to factor common tasks done in CMakeLists.txt
|
||||
#Add all the CMakeLists:
|
||||
ADD_SUBDIRECTORY(AdMobObject)
|
||||
IF (NOT EMSCRIPTEN) #Only add some extensions when compiling with emscripten.
|
||||
ADD_SUBDIRECTORY(AnchorBehavior)
|
||||
ADD_SUBDIRECTORY(AdvancedXML)
|
||||
ADD_SUBDIRECTORY(AES)
|
||||
ADD_SUBDIRECTORY(Box3DObject)
|
||||
|
@@ -139,7 +139,7 @@ gd::String CodeCompilerCall::GetFullCall() const
|
||||
}
|
||||
else //Generate argument for linking files
|
||||
{
|
||||
if(!compilationForRuntime)
|
||||
if(!compilationForRuntime)
|
||||
args.push_back("-Wl,-rpath," + baseDir);
|
||||
args.push_back("-shared");
|
||||
if ( !inputFile.empty() ) args.push_back("\""+inputFile+"\"");
|
||||
|
Reference in New Issue
Block a user