Support android again (tested with NDK 12b)

0.8
Bruno Van de Velde 2017-09-07 15:38:35 +02:00
parent 7b22bb4de0
commit 5e48605e32
14 changed files with 404 additions and 91 deletions

View File

@ -16,6 +16,17 @@ macro(tgui_add_cxx_flag flag)
endif()
endmacro()
macro(tgui_remove_cxx_flag flagToRemove)
string(REPLACE " " ";" TGUI_CXX_FLAGS_LIST ${CMAKE_CXX_FLAGS})
set(TGUI_TEMP_CXX_FLAGS "")
foreach (flag ${TGUI_CXX_FLAGS_LIST})
if (NOT (${flag} STREQUAL "${flagToRemove}"))
set(TGUI_TEMP_CXX_FLAGS "${TGUI_TEMP_CXX_FLAGS} ${flag}")
endif()
endforeach(flag)
set(CMAKE_CXX_FLAGS "${TGUI_TEMP_CXX_FLAGS}")
endmacro()
# Set a default build type and module path if none was provided
tgui_set_option(CMAKE_BUILD_TYPE Release STRING "Choose the type of build (Debug or Release)")
tgui_set_option(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/Modules" STRING "The path to the cmake modules. This path must contain the FindSFML.cmake file.")
@ -76,27 +87,12 @@ tgui_set_option(TGUI_OPENGL_ES ${OPENGL_ES} BOOL "TRUE to use an OpenGL ES imple
# Set compile flags for gcc and clang
if (SFML_OS_ANDROID)
# Remove "-fno-exceptions" from the CMAKE_CXX_FLAGS
string(REPLACE " " ";" TGUI_CXX_FLAGS_LIST ${CMAKE_CXX_FLAGS})
set(TGUI_TEMP_CXX_FLAGS "")
foreach (flag ${TGUI_CXX_FLAGS_LIST})
if (NOT (${flag} STREQUAL "-fno-exceptions"))
set(TGUI_TEMP_CXX_FLAGS "${TGUI_TEMP_CXX_FLAGS} ${flag}")
endif()
endforeach(flag)
tgui_remove_cxx_flag(-fno-exceptions)
tgui_remove_cxx_flag(-fno-rtti)
# Remove "-fno-rtti" from the CMAKE_CXX_FLAGS
string(REPLACE " " ";" TGUI_CXX_FLAGS_LIST ${TGUI_TEMP_CXX_FLAGS})
set(TGUI_TEMP_CXX_FLAGS "")
foreach (flag ${TGUI_CXX_FLAGS_LIST})
if (NOT (${flag} STREQUAL "-fno-rtti"))
set(TGUI_TEMP_CXX_FLAGS "${TGUI_TEMP_CXX_FLAGS} ${flag}")
endif()
endforeach(flag)
# TGUI was only successfully tested on Android with NDK 12b, which did not work when -std=c++1y (or -std=c++14) is defined
tgui_add_cxx_flag(-std=c++11)
set(CMAKE_CXX_FLAGS "${TGUI_TEMP_CXX_FLAGS}")
tgui_add_cxx_flag(-std=c++1y)
tgui_add_cxx_flag(-fexceptions)
tgui_add_cxx_flag(-frtti)

View File

@ -1,4 +1,4 @@
NDK_TOOLCHAIN_VERSION := 4.8
NDK_TOOLCHAIN_VERSION := 4.9
APP_PLATFORM := android-9
APP_STL := c++_shared
APP_ABI := armeabi-v7a

View File

@ -70,6 +70,28 @@
#define TGUI_VERSION_MINOR 8
#define TGUI_VERSION_PATCH 0
// Disable c++14 code when using -std=c++11, which is needed for android when using NDK 12b.
// This technically results in undefined behavior because the std::function ambiguity was only fixed in c++14 (http://cplusplus.github.io/LWG/lwg-defects.html#2132).
// TGUI relies on a fix for LWG 2132 to be implemented, even when compiling with -std=c++11 (which is the case in supported gcc and clang compilers).
// The TGUI_NO_CPP14 macro thus does not provide support for all compilers with c++11 support, it just allows some compilers to work even with -std=c++11.
#ifndef _MSC_VER
#if __cplusplus <= 201103L
#define TGUI_NO_CPP14
#endif
#endif
// The signal system detects whether it can provide unbound parameters by checking the arguments of the function at runtime.
// This comparion is made by checking the typeid of the parameters with the typeid of the value which the widget can transmit.
// Although typeid returns a unique value and the operator== is guarenteed to only be true for the same type, it may not always work correctly.
// Dynamically linked libraries may have a different type_info internally than in the code using the library. In such case the comparison will always be false.
// This behavior has so far only been seen on android (using NDK 12b), so the alternative is currently only used when compiling on android.
// The alternative that is used on android is to compare the strings returned by type_info.name(). This is however considered undefined behavior since the compiler
// is not guarenteed to have unique names for different types. The names will however be the same inside and outside the library so this method solves the issue.
// I am also not aware of any supported compiler that does not create unique names.
#ifdef __ANDROID__
#define TGUI_UNSAFE_TYPE_INFO_COMPARISON
#endif
// Enable constexpr when using Clang or at least GCC 5 or MSVC++ 14.1 (VS2017)
#if _MSC_VER
#if _MSC_VER >= 1910

View File

@ -31,6 +31,22 @@
#include <TGUI/Exception.hpp>
#include <iostream>
#include <string>
#include <memory>
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#ifdef TGUI_NO_CPP14
namespace tgui
{
template<typename T, typename... Args>
std::unique_ptr<T> make_unique(Args&&... args)
{
return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
}
}
#else
using std::make_unique;
#endif
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

View File

@ -569,6 +569,111 @@ namespace tgui
namespace internal_signal
{
// make_integer_sequence implementation taken from https://gist.github.com/jappa/62f30b6da5adea60bad3
#ifdef TGUI_NO_CPP14
template <class Type, Type... Indices>
struct integer_sequence
{
typedef Type value_type;
static std::size_t size()
{
return sizeof...(Indices);
}
};
template<std::size_t... Ints>
using index_sequence = integer_sequence<std::size_t, Ints...>;
namespace integer_sequence_detail
{
template <typename T, std::size_t ..._Extra>
struct repeat;
template <typename T, T ...N, std::size_t ..._Extra>
struct repeat<integer_sequence<T, N...>, _Extra...>
{
typedef integer_sequence<T, N...,
1 * sizeof...(N) + N...,
2 * sizeof...(N) + N...,
3 * sizeof...(N) + N...,
4 * sizeof...(N) + N...,
5 * sizeof...(N) + N...,
6 * sizeof...(N) + N...,
7 * sizeof...(N) + N...,
_Extra...> type;
};
template <std::size_t N> struct parity;
template <std::size_t N> struct make:parity<N % 8>::template pmake<N> {};
template <> struct make<0> { typedef integer_sequence<std::size_t> type; };
template <> struct make<1> { typedef integer_sequence<std::size_t, 0> type; };
template <> struct make<2> { typedef integer_sequence<std::size_t, 0, 1> type; };
template <> struct make<3> { typedef integer_sequence<std::size_t, 0, 1, 2> type; };
template <> struct make<4> { typedef integer_sequence<std::size_t, 0, 1, 2, 3> type; };
template <> struct make<5> { typedef integer_sequence<std::size_t, 0, 1, 2, 3, 4> type; };
template <> struct make<6> { typedef integer_sequence<std::size_t, 0, 1, 2, 3, 4, 5> type; };
template <> struct make<7> { typedef integer_sequence<std::size_t, 0, 1, 2, 3, 4, 5, 6> type; };
template <> struct parity<0> { template <std::size_t N> struct pmake:repeat<typename make<N / 8>::type> {}; };
template <> struct parity<1> { template <std::size_t N> struct pmake:repeat<typename make<N / 8>::type, N - 1> {}; };
template <> struct parity<2> { template <std::size_t N> struct pmake:repeat<typename make<N / 8>::type, N - 2, N - 1> {}; };
template <> struct parity<3> { template <std::size_t N> struct pmake:repeat<typename make<N / 8>::type, N - 3, N - 2, N - 1> {}; };
template <> struct parity<4> { template <std::size_t N> struct pmake:repeat<typename make<N / 8>::type, N - 4, N - 3, N - 2, N - 1> {}; };
template <> struct parity<5> { template <std::size_t N> struct pmake:repeat<typename make<N / 8>::type, N - 5, N - 4, N - 3, N - 2, N - 1> {}; };
template <> struct parity<6> { template <std::size_t N> struct pmake:repeat<typename make<N / 8>::type, N - 6, N - 5, N - 4, N - 3, N - 2, N - 1> {}; };
template <> struct parity<7> { template <std::size_t N> struct pmake:repeat<typename make<N / 8>::type, N - 7, N - 6, N - 5, N - 4, N - 3, N - 2, N - 1> {}; };
template <typename T, typename U>
struct convert
{
template <typename>
struct result;
template <T ...N>
struct result<integer_sequence<T, N...> >
{
typedef integer_sequence<U, N...> type;
};
};
template <typename T>
struct convert<T, T>
{
template <typename U>
struct result
{
typedef U type;
};
};
template <typename T, T N>
using make_integer_sequence_unchecked = typename convert<std::size_t, T>::template result<typename make<N>::type>::type;
template <typename T, T N>
struct make_integer_sequence
{
static_assert(std::is_integral<T>::value,
"std::make_integer_sequence can only be instantiated with an integral type");
static_assert(0 <= N,"std::make_integer_sequence input shall not be negative");
typedef make_integer_sequence_unchecked<T, N> type;
};
}
template <typename T, T N>
using make_integer_sequence = typename integer_sequence_detail::make_integer_sequence<T, N>::type;
template<std::size_t N>
using make_index_sequence = make_integer_sequence<std::size_t, N>;
template<class... T>
using index_sequence_for = make_index_sequence<sizeof...(T)>;
#else
using std::index_sequence;
using std::index_sequence_for;
#endif
// void_t only exists in c++17 so we use our own implementation to support c++14 compilers
template<typename...>
using void_t = void;
@ -583,16 +688,24 @@ namespace tgui
// The dereference function turns the void* elements in the parameters list back into its original type right before calling the signal handler
template <typename Type, typename std::enable_if<std::is_same<Type, std::string>::value>::type* = nullptr>
#ifdef TGUI_NO_CPP14
std::string dereference(const void* obj)
#else
decltype(auto) dereference(const void* obj)
#endif
{
// Signal handlers are allowed to have std::string parameters while the signal sends sf::String
return static_cast<std::string>(*static_cast<const sf::String*>(obj));
}
template <typename Type, typename std::enable_if<!std::is_same<Type, std::string>::value>::type* = nullptr>
#ifdef TGUI_NO_CPP14
const Type& dereference(const void* obj)
#else
decltype(auto) dereference(const void* obj)
#endif
{
return *static_cast<const Type*>(obj);
return *static_cast<const typename std::decay<Type>::type*>(obj);
}
// std::invoke only exists in c++17 so we use our own implementation to support c++14 compilers
@ -623,18 +736,31 @@ namespace tgui
struct binder<TypeSet<std::shared_ptr<Widget>, std::string, UnboundArgs...>, TypeSet<>>
{
template <typename Func, typename... BoundArgs>
#ifdef TGUI_NO_CPP14
static std::function<void(const std::shared_ptr<Widget>& widget, const std::string& signalName)> bind(Signal& signal, Func&& func, BoundArgs&&... args)
#else
static decltype(auto) bind(Signal& signal, Func&& func, BoundArgs&&... args)
#endif
{
return bindImpl(std::index_sequence_for<UnboundArgs...>{}, signal, std::forward<Func>(func), std::forward<BoundArgs>(args)...);
return bindImpl(index_sequence_for<UnboundArgs...>{}, signal, std::forward<Func>(func), std::forward<BoundArgs>(args)...);
}
private:
template <typename Func, typename... BoundArgs, std::size_t... Indices>
static decltype(auto) bindImpl(std::index_sequence<Indices...>, Signal& signal, Func&& func, BoundArgs&&... args)
#ifdef TGUI_NO_CPP14
static std::function<void(const std::shared_ptr<Widget>& widget, const std::string& signalName)> bindImpl(index_sequence<Indices...>, Signal& signal, Func&& func, BoundArgs&&... args)
#else
static decltype(auto) bindImpl(index_sequence<Indices...>, Signal& signal, Func&& func, BoundArgs&&... args)
#endif
{
const std::size_t offset = (sizeof...(UnboundArgs) > 0) ? signal.validateTypes({typeid(UnboundArgs)...}) : 0;
#ifdef TGUI_NO_CPP14
return [=](const std::shared_ptr<Widget>& widget, const std::string& signalName) {
auto f = func;
#else
return [=, f=func](const std::shared_ptr<Widget>& widget, const std::string& signalName) { // f=func is needed to decay free functions
#endif
invokeFunc(f,
args...,
widget,
@ -648,18 +774,31 @@ namespace tgui
struct binder<TypeSet<UnboundArgs...>, TypeSet<>>
{
template <typename Func, typename... BoundArgs>
#ifdef TGUI_NO_CPP14
static std::function<void()> bind(Signal& signal, Func&& func, BoundArgs&&... args)
#else
static decltype(auto) bind(Signal& signal, Func&& func, BoundArgs&&... args)
#endif
{
return bindImpl(std::index_sequence_for<UnboundArgs...>{}, signal, std::forward<Func>(func), std::forward<BoundArgs>(args)...);
return bindImpl(index_sequence_for<UnboundArgs...>{}, signal, std::forward<Func>(func), std::forward<BoundArgs>(args)...);
}
private:
template <typename Func, typename... BoundArgs, std::size_t... Indices>
static decltype(auto) bindImpl(std::index_sequence<Indices...>, Signal& signal, Func&& func, BoundArgs&&... args)
#ifdef TGUI_NO_CPP14
static std::function<void()> bindImpl(index_sequence<Indices...>, Signal& signal, Func&& func, BoundArgs&&... args)
#else
static decltype(auto) bindImpl(index_sequence<Indices...>, Signal& signal, Func&& func, BoundArgs&&... args)
#endif
{
const std::size_t offset = (sizeof...(UnboundArgs) > 0) ? signal.validateTypes({typeid(UnboundArgs)...}) : 0;
#ifdef TGUI_NO_CPP14
return [=]() {
auto f = func;
#else
return [=, f=func]() { // f=func is needed to decay free functions
#endif
invokeFunc(f,
args...,
internal_signal::dereference<UnboundArgs>(internal_signal::parameters[offset + Indices])...);
@ -721,7 +860,11 @@ namespace tgui
template <typename Func, typename... Args, typename std::enable_if<std::is_convertible<Func, std::function<void(const Args&...)>>::value>::type* = nullptr>
unsigned int connect(std::string signalName, Func&& handler, const Args&... args)
{
#ifdef TGUI_NO_CPP14
const unsigned int id = getSignal(toLower(signalName)).connect([=](){ (std::function<void(const Args&...)>(handler))(args...); });
#else
const unsigned int id = getSignal(toLower(signalName)).connect([f=std::function<void(const Args&...)>(handler),args...](){ f(args...); });
#endif
m_connectedSignals[id] = toLower(signalName);
return id;
}
@ -740,11 +883,20 @@ namespace tgui
template <typename Func, typename... BoundArgs, typename std::enable_if<std::is_convertible<Func, std::function<void(const BoundArgs&..., std::shared_ptr<Widget>, const std::string&)>>::value>::type* = nullptr>
unsigned int connect(std::string signalName, Func&& handler, BoundArgs&&... args)
{
#ifdef TGUI_NO_CPP14
const unsigned int id = getSignal(toLower(signalName)).connect(
[=](const std::shared_ptr<Widget>& w, const std::string& s) {
(std::function<void(const BoundArgs&..., const std::shared_ptr<Widget>&, const std::string&)>(handler))(args..., w, s);
}
);
#else
const unsigned int id = getSignal(toLower(signalName)).connect(
[f=std::function<void(const BoundArgs&..., const std::shared_ptr<Widget>&, const std::string&)>(handler), args...]
(const std::shared_ptr<Widget>& w, const std::string& s)
{ f(args..., w, s); }
);
#endif
m_connectedSignals[id] = toLower(signalName);
return id;
}

View File

@ -53,8 +53,8 @@ namespace tgui
{
// We don't know if we have to bind the width or height, so bind "size" and let the connectWidget function figure it out later
*this = Layout{Layout::Operation::Multiplies,
std::make_unique<Layout>(tgui::stof(expression.substr(0, expression.length()-1)) / 100.f),
std::make_unique<Layout>("&.size")};
make_unique<Layout>(tgui::stof(expression.substr(0, expression.length()-1)) / 100.f),
make_unique<Layout>("&.size")};
}
else
{
@ -79,14 +79,14 @@ namespace tgui
else if (expression.size() >= 5 && expression.substr(expression.size()-5) == "right")
{
*this = Layout{Operation::Plus,
std::make_unique<Layout>(expression.substr(0, expression.size()-5) + "left"),
std::make_unique<Layout>(expression.substr(0, expression.size()-5) + "width")};
make_unique<Layout>(expression.substr(0, expression.size()-5) + "left"),
make_unique<Layout>(expression.substr(0, expression.size()-5) + "width")};
}
else if (expression.size() >= 6 && expression.substr(expression.size()-6) == "bottom")
{
*this = Layout{Operation::Plus,
std::make_unique<Layout>(expression.substr(0, expression.size()-6) + "top"),
std::make_unique<Layout>(expression.substr(0, expression.size()-6) + "height")};
make_unique<Layout>(expression.substr(0, expression.size()-6) + "top"),
make_unique<Layout>(expression.substr(0, expression.size()-6) + "height")};
}
else // Constant value
m_value = tgui::stof(expression);
@ -180,8 +180,8 @@ namespace tgui
std::advance(nextOperandIt, 1);
(*operandIt) = Layout{operators[i],
std::make_unique<Layout>(*operandIt),
std::make_unique<Layout>(*nextOperandIt)};
make_unique<Layout>(*operandIt),
make_unique<Layout>(*nextOperandIt)};
operands.erase(nextOperandIt);
}
@ -203,8 +203,8 @@ namespace tgui
assert(nextOperandIt != operands.end());
(*operandIt) = Layout{operators[i],
std::make_unique<Layout>(*operandIt),
std::make_unique<Layout>(*nextOperandIt)};
make_unique<Layout>(*operandIt),
make_unique<Layout>(*nextOperandIt)};
operands.erase(nextOperandIt);
}
@ -255,8 +255,8 @@ namespace tgui
m_value {other.m_value},
m_parent {other.m_parent},
m_operation {other.m_operation},
m_leftOperand {other.m_leftOperand ? std::make_unique<Layout>(*other.m_leftOperand) : nullptr},
m_rightOperand {other.m_rightOperand ? std::make_unique<Layout>(*other.m_rightOperand) : nullptr},
m_leftOperand {other.m_leftOperand ? make_unique<Layout>(*other.m_leftOperand) : nullptr},
m_rightOperand {other.m_rightOperand ? make_unique<Layout>(*other.m_rightOperand) : nullptr},
m_boundWidget {other.m_boundWidget},
m_boundString {other.m_boundString},
m_connectedWidget{nullptr}
@ -292,8 +292,8 @@ namespace tgui
m_value = other.m_value;
m_parent = other.m_parent;
m_operation = other.m_operation;
m_leftOperand = other.m_leftOperand ? std::make_unique<Layout>(*other.m_leftOperand) : nullptr;
m_rightOperand = other.m_rightOperand ? std::make_unique<Layout>(*other.m_rightOperand) : nullptr;
m_leftOperand = other.m_leftOperand ? make_unique<Layout>(*other.m_leftOperand) : nullptr;
m_rightOperand = other.m_rightOperand ? make_unique<Layout>(*other.m_rightOperand) : nullptr;
m_boundWidget = other.m_boundWidget;
m_boundString = other.m_boundString;
m_connectedWidget = nullptr;
@ -583,35 +583,35 @@ namespace tgui
Layout operator-(Layout right)
{
return Layout{Layout::Operation::Minus, std::make_unique<Layout>(), std::make_unique<Layout>(std::move(right))};
return Layout{Layout::Operation::Minus, make_unique<Layout>(), make_unique<Layout>(std::move(right))};
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Layout operator+(Layout left, Layout right)
{
return Layout{Layout::Operation::Plus, std::make_unique<Layout>(std::move(left)), std::make_unique<Layout>(std::move(right))};
return Layout{Layout::Operation::Plus, make_unique<Layout>(std::move(left)), make_unique<Layout>(std::move(right))};
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Layout operator-(Layout left, Layout right)
{
return Layout{Layout::Operation::Minus, std::make_unique<Layout>(std::move(left)), std::make_unique<Layout>(std::move(right))};
return Layout{Layout::Operation::Minus, make_unique<Layout>(std::move(left)), make_unique<Layout>(std::move(right))};
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Layout operator*(Layout left, Layout right)
{
return Layout{Layout::Operation::Multiplies, std::make_unique<Layout>(std::move(left)), std::make_unique<Layout>(std::move(right))};
return Layout{Layout::Operation::Multiplies, make_unique<Layout>(std::move(left)), make_unique<Layout>(std::move(right))};
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Layout operator/(Layout left, Layout right)
{
return Layout{Layout::Operation::Divides, std::make_unique<Layout>(std::move(left)), std::make_unique<Layout>(std::move(right))};
return Layout{Layout::Operation::Divides, make_unique<Layout>(std::move(left)), make_unique<Layout>(std::move(right))};
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@ -694,8 +694,8 @@ namespace tgui
Layout bindRight(Widget::Ptr widget)
{
return Layout{Layout::Operation::Plus,
std::make_unique<Layout>(Layout::Operation::BindingLeft, widget.get()),
std::make_unique<Layout>(Layout::Operation::BindingWidth, widget.get())};
make_unique<Layout>(Layout::Operation::BindingLeft, widget.get()),
make_unique<Layout>(Layout::Operation::BindingWidth, widget.get())};
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@ -703,8 +703,8 @@ namespace tgui
Layout bindBottom(Widget::Ptr widget)
{
return Layout{Layout::Operation::Plus,
std::make_unique<Layout>(Layout::Operation::BindingTop, widget.get()),
std::make_unique<Layout>(Layout::Operation::BindingHeight, widget.get())};
make_unique<Layout>(Layout::Operation::BindingTop, widget.get()),
make_unique<Layout>(Layout::Operation::BindingHeight, widget.get())};
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

View File

@ -287,7 +287,7 @@ namespace tgui
stream.read(&chr, 1);
// Create a value node to store the value
auto valueNode = std::make_unique<DataIO::ValueNode>();
auto valueNode = make_unique<DataIO::ValueNode>();
valueNode->value = line;
// It might be a list node
@ -367,7 +367,7 @@ namespace tgui
std::string parseSection(std::stringstream& stream, const std::unique_ptr<DataIO::Node>& node, const std::string& sectionName)
{
// Create a new node for this section
auto sectionNode = std::make_unique<DataIO::Node>();
auto sectionNode = make_unique<DataIO::Node>();
sectionNode->parent = node.get();
sectionNode->name = sectionName;
@ -487,7 +487,7 @@ namespace tgui
std::unique_ptr<DataIO::Node> DataIO::parse(std::stringstream& stream)
{
auto root = std::make_unique<Node>();
auto root = make_unique<Node>();
std::string error;
while (stream.peek() != EOF)

View File

@ -220,7 +220,7 @@ namespace tgui
std::string serializeRendererData(ObjectConverter&& value)
{
auto node = std::make_unique<DataIO::Node>();
auto node = make_unique<DataIO::Node>();
for (const auto& pair : value.getRenderer()->propertyValuePairs)
{
sf::String strValue;
@ -233,7 +233,7 @@ namespace tgui
else
{
strValue = ObjectConverter{pair.second}.getString();
node->propertyValuePairs[pair.first] = std::make_unique<DataIO::ValueNode>(strValue);
node->propertyValuePairs[pair.first] = make_unique<DataIO::ValueNode>(strValue);
}
}

View File

@ -57,7 +57,7 @@ namespace tgui
namespace
{
#define SET_PROPERTY(property, value) node->propertyValuePairs[property] = std::make_unique<DataIO::ValueNode>(value)
#define SET_PROPERTY(property, value) node->propertyValuePairs[property] = make_unique<DataIO::ValueNode>(value)
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@ -67,7 +67,7 @@ namespace tgui
if (widget->getParent())
widgetName = widget->getParent()->getWidgetName(widget);
auto node = std::make_unique<DataIO::Node>();
auto node = make_unique<DataIO::Node>();
if (widgetName.isEmpty())
node->name = widget->getWidgetType();
else
@ -86,12 +86,12 @@ namespace tgui
{
auto toolTipWidgetNode = WidgetSaver::getSaveFunction("widget")(widget->getToolTip());
auto toolTipNode = std::make_unique<DataIO::Node>();
auto toolTipNode = make_unique<DataIO::Node>();
toolTipNode->name = "ToolTip";
toolTipNode->children.emplace_back(std::move(toolTipWidgetNode));
toolTipNode->propertyValuePairs["TimeToDisplay"] = std::make_unique<DataIO::ValueNode>(to_string(ToolTip::getTimeToDisplay().asSeconds()));
toolTipNode->propertyValuePairs["DistanceToMouse"] = std::make_unique<DataIO::ValueNode>("(" + to_string(ToolTip::getDistanceToMouse().x) + "," + to_string(ToolTip::getDistanceToMouse().y) + ")");
toolTipNode->propertyValuePairs["TimeToDisplay"] = make_unique<DataIO::ValueNode>(to_string(ToolTip::getTimeToDisplay().asSeconds()));
toolTipNode->propertyValuePairs["DistanceToMouse"] = make_unique<DataIO::ValueNode>("(" + to_string(ToolTip::getDistanceToMouse().x) + "," + to_string(ToolTip::getDistanceToMouse().y) + ")");
node->children.emplace_back(std::move(toolTipNode));
}
@ -99,7 +99,7 @@ namespace tgui
/// TODO: Separate renderer section?
if (!widget->getRenderer()->getPropertyValuePairs().empty())
{
node->children.emplace_back(std::make_unique<DataIO::Node>());
node->children.emplace_back(make_unique<DataIO::Node>());
node->children.back()->name = "Renderer";
for (const auto& pair : widget->getRenderer()->getPropertyValuePairs())
{
@ -120,7 +120,7 @@ namespace tgui
node->children.back()->children.back()->name = pair.first;
}
else
node->children.back()->propertyValuePairs[pair.first] = std::make_unique<DataIO::ValueNode>(value);
node->children.back()->propertyValuePairs[pair.first] = make_unique<DataIO::ValueNode>(value);
}
}
@ -188,15 +188,15 @@ namespace tgui
unsigned int lineTextSize = chatBox->getLineTextSize(i);
sf::Color lineTextColor = chatBox->getLineColor(i);
auto lineNode = std::make_unique<DataIO::Node>();
auto lineNode = make_unique<DataIO::Node>();
lineNode->parent = node.get();
lineNode->name = "Line";
lineNode->propertyValuePairs["Text"] = std::make_unique<DataIO::ValueNode>(Serializer::serialize(chatBox->getLine(i)));
lineNode->propertyValuePairs["Text"] = make_unique<DataIO::ValueNode>(Serializer::serialize(chatBox->getLine(i)));
if (lineTextSize != chatBox->getTextSize())
lineNode->propertyValuePairs["TextSize"] = std::make_unique<DataIO::ValueNode>(to_string(lineTextSize));
lineNode->propertyValuePairs["TextSize"] = make_unique<DataIO::ValueNode>(to_string(lineTextSize));
if (lineTextColor != chatBox->getTextColor())
lineNode->propertyValuePairs["Color"] = std::make_unique<DataIO::ValueNode>(Serializer::serialize(lineTextColor));
lineNode->propertyValuePairs["Color"] = make_unique<DataIO::ValueNode>(Serializer::serialize(lineTextColor));
node->children.push_back(std::move(lineNode));
}
@ -362,7 +362,7 @@ namespace tgui
}
};
auto getWidgetsInGridString = [&](const auto& w) -> std::string {
auto getWidgetsInGridString = [&](const tgui::Widget::Ptr& w) -> std::string {
auto it = widgetsMap.find(w);
if (it != widgetsMap.end())
{
@ -491,11 +491,11 @@ namespace tgui
std::map<sf::String, std::vector<sf::String>> menus = menuBar->getMenus();
for (const auto& menu : menus)
{
auto menuNode = std::make_unique<DataIO::Node>();
auto menuNode = make_unique<DataIO::Node>();
menuNode->parent = node.get();
menuNode->name = "Menu";
menuNode->propertyValuePairs["Name"] = std::make_unique<DataIO::ValueNode>(Serializer::serialize(menu.first));
menuNode->propertyValuePairs["Name"] = make_unique<DataIO::ValueNode>(Serializer::serialize(menu.first));
const auto& items = menu.second;
if (!items.empty())
@ -505,7 +505,7 @@ namespace tgui
itemList += ", " + Serializer::serialize(items[i]);
itemList += "]";
menuNode->propertyValuePairs["Items"] = std::make_unique<DataIO::ValueNode>(itemList);
menuNode->propertyValuePairs["Items"] = make_unique<DataIO::ValueNode>(itemList);
}
node->children.push_back(std::move(menuNode));
@ -762,7 +762,7 @@ namespace tgui
void WidgetSaver::save(Container::ConstPtr widget, std::stringstream& stream)
{
auto node = std::make_unique<DataIO::Node>();
auto node = make_unique<DataIO::Node>();
for (const auto& child : widget->getWidgets())
{
auto& saveFunction = WidgetSaver::getSaveFunction(toLower(child->getWidgetType()));

View File

@ -84,7 +84,12 @@ namespace tgui
unsigned int Signal::connect(const DelegateEx& handler)
{
const auto id = generateUniqueId();
#ifdef TGUI_NO_CPP14
std::string name = m_name;
m_handlers[id] = [handler, name](){ handler(getWidget(), name); };
#else
m_handlers[id] = [handler, name=m_name](){ handler(getWidget(), name); };
#endif
return id;
}
@ -121,6 +126,23 @@ namespace tgui
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#ifdef TGUI_NO_CPP14
#define TGUI_SIGNAL_VALUE_CONNECT_DEFINITION(TypeName, Type) \
unsigned int Signal##TypeName::connect(const Delegate##TypeName& handler) \
{ \
const auto id = generateUniqueId(); \
m_handlers[id] = [handler](){ handler(internal_signal::dereference<Type>(internal_signal::parameters[1])); }; \
return id; \
} \
\
unsigned int Signal##TypeName::connect(const Delegate##TypeName##Ex& handler) \
{ \
const auto id = generateUniqueId(); \
std::string name = m_name; \
m_handlers[id] = [handler, name](){ handler(getWidget(), name, internal_signal::dereference<Type>(internal_signal::parameters[1])); }; \
return id; \
}
#else
#define TGUI_SIGNAL_VALUE_CONNECT_DEFINITION(TypeName, Type) \
unsigned int Signal##TypeName::connect(const Delegate##TypeName& handler) \
{ \
@ -134,45 +156,95 @@ namespace tgui
const auto id = generateUniqueId(); \
m_handlers[id] = [handler, name=m_name](){ handler(getWidget(), name, internal_signal::dereference<Type>(internal_signal::parameters[1])); }; \
return id; \
} \
\
unsigned int Signal##TypeName::validateTypes(std::initializer_list<std::type_index> unboundParameters) \
{ \
if ((unboundParameters.size() == 1) && (*unboundParameters.begin() == typeid(Type))) \
return 1; \
else \
return Signal::validateTypes(unboundParameters); \
}
#endif
TGUI_SIGNAL_VALUE_CONNECT_DEFINITION(Int, int)
TGUI_SIGNAL_VALUE_CONNECT_DEFINITION(UInt, unsigned int)
TGUI_SIGNAL_VALUE_CONNECT_DEFINITION(Bool, bool)
TGUI_SIGNAL_VALUE_CONNECT_DEFINITION(Float, float)
TGUI_SIGNAL_VALUE_CONNECT_DEFINITION(String, const sf::String&)
TGUI_SIGNAL_VALUE_CONNECT_DEFINITION(Vector2f, sf::Vector2f)
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
unsigned int SignalString::connect(const DelegateString& handler)
unsigned int SignalInt::validateTypes(std::initializer_list<std::type_index> unboundParameters)
{
const auto id = generateUniqueId();
m_handlers[id] = [handler](){ handler(internal_signal::dereference<sf::String>(internal_signal::parameters[1])); };
return id;
#ifdef TGUI_UNSAFE_TYPE_INFO_COMPARISON
if ((unboundParameters.size() == 1) && (strcmp(unboundParameters.begin()->name(), typeid(int).name()) == 0))
#else
if ((unboundParameters.size() == 1) && (*unboundParameters.begin() == typeid(int)))
#endif
return 1;
else
return Signal::validateTypes(unboundParameters);
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
unsigned int SignalString::connect(const DelegateStringEx& handler)
unsigned int SignalUInt::validateTypes(std::initializer_list<std::type_index> unboundParameters)
{
const auto id = generateUniqueId();
m_handlers[id] = [handler, name=m_name](){ handler(getWidget(), name, internal_signal::dereference<sf::String>(internal_signal::parameters[1])); };
return id;
#ifdef TGUI_UNSAFE_TYPE_INFO_COMPARISON
if ((unboundParameters.size() == 1) && (strcmp(unboundParameters.begin()->name(), typeid(unsigned int).name()) == 0))
#else
if ((unboundParameters.size() == 1) && (*unboundParameters.begin() == typeid(unsigned int)))
#endif
return 1;
else
return Signal::validateTypes(unboundParameters);
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
unsigned int SignalBool::validateTypes(std::initializer_list<std::type_index> unboundParameters)
{
#ifdef TGUI_UNSAFE_TYPE_INFO_COMPARISON
if ((unboundParameters.size() == 1) && (strcmp(unboundParameters.begin()->name(), typeid(bool).name()) == 0))
#else
if ((unboundParameters.size() == 1) && (*unboundParameters.begin() == typeid(bool)))
#endif
return 1;
else
return Signal::validateTypes(unboundParameters);
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
unsigned int SignalFloat::validateTypes(std::initializer_list<std::type_index> unboundParameters)
{
#ifdef TGUI_UNSAFE_TYPE_INFO_COMPARISON
if ((unboundParameters.size() == 1) && (strcmp(unboundParameters.begin()->name(), typeid(float).name()) == 0))
#else
if ((unboundParameters.size() == 1) && (*unboundParameters.begin() == typeid(float)))
#endif
return 1;
else
return Signal::validateTypes(unboundParameters);
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
unsigned int SignalString::validateTypes(std::initializer_list<std::type_index> unboundParameters)
{
#ifdef TGUI_UNSAFE_TYPE_INFO_COMPARISON
if ((unboundParameters.size() == 1) && ((strcmp(unboundParameters.begin()->name(), typeid(std::string).name()) == 0) || (strcmp(unboundParameters.begin()->name(), typeid(sf::String).name()) == 0)))
#else
if ((unboundParameters.size() == 1) && ((*unboundParameters.begin() == typeid(std::string)) || (*unboundParameters.begin() == typeid(sf::String))))
#endif
return 1;
else
return Signal::validateTypes(unboundParameters);
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
unsigned int SignalVector2f::validateTypes(std::initializer_list<std::type_index> unboundParameters)
{
#ifdef TGUI_UNSAFE_TYPE_INFO_COMPARISON
if ((unboundParameters.size() == 1) && (strcmp(unboundParameters.begin()->name(), typeid(sf::Vector2f).name()) == 0))
#else
if ((unboundParameters.size() == 1) && (*unboundParameters.begin() == typeid(sf::Vector2f)))
#endif
return 1;
else
return Signal::validateTypes(unboundParameters);
@ -192,7 +264,12 @@ namespace tgui
unsigned int SignalRange::connect(const DelegateRangeEx& handler)
{
const auto id = generateUniqueId();
#ifdef TGUI_NO_CPP14
std::string name = m_name;
m_handlers[id] = [handler, name](){ handler(getWidget(), name, internal_signal::dereference<int>(internal_signal::parameters[1]), internal_signal::dereference<int>(internal_signal::parameters[2])); };
#else
m_handlers[id] = [handler, name=m_name](){ handler(getWidget(), name, internal_signal::dereference<int>(internal_signal::parameters[1]), internal_signal::dereference<int>(internal_signal::parameters[2])); };
#endif
return id;
}
@ -212,7 +289,11 @@ namespace tgui
unsigned int SignalRange::validateTypes(std::initializer_list<std::type_index> unboundParameters)
{
#ifdef TGUI_UNSAFE_TYPE_INFO_COMPARISON
if ((unboundParameters.size() == 2) && (strcmp(unboundParameters.begin()->name(), typeid(int).name()) == 0) && (strcmp((unboundParameters.begin()+1)->name(), typeid(int).name()) == 0))
#else
if ((unboundParameters.size() == 2) && (*unboundParameters.begin() == typeid(int)) && (*(unboundParameters.begin()+1) == typeid(int)))
#endif
return 1;
else
return Signal::validateTypes(unboundParameters);
@ -232,7 +313,12 @@ namespace tgui
unsigned int SignalChildWindow::connect(const DelegateChildWindowEx& handler)
{
const auto id = generateUniqueId();
#ifdef TGUI_NO_CPP14
std::string name = m_name;
m_handlers[id] = [handler, name](){ handler(getWidget(), name, std::static_pointer_cast<ChildWindow>(internal_signal::dereference<ChildWindow*>(internal_signal::parameters[1])->shared_from_this())); };
#else
m_handlers[id] = [handler, name=m_name](){ handler(getWidget(), name, std::static_pointer_cast<ChildWindow>(internal_signal::dereference<ChildWindow*>(internal_signal::parameters[1])->shared_from_this())); };
#endif
return id;
}
@ -251,7 +337,11 @@ namespace tgui
unsigned int SignalChildWindow::validateTypes(std::initializer_list<std::type_index> unboundParameters)
{
if ((unboundParameters.size() == 1) && (*unboundParameters.begin() == typeid(tgui::ChildWindow::Ptr)))
#ifdef TGUI_UNSAFE_TYPE_INFO_COMPARISON
if ((unboundParameters.size() == 1) && (strcmp(unboundParameters.begin()->name(), typeid(ChildWindow::Ptr).name()) == 0))
#else
if ((unboundParameters.size() == 1) && (*unboundParameters.begin() == typeid(ChildWindow::Ptr)))
#endif
return 1;
else
return Signal::validateTypes(unboundParameters);
@ -271,7 +361,12 @@ namespace tgui
unsigned int SignalItem::connect(const DelegateItemEx& handler)
{
const auto id = generateUniqueId();
#ifdef TGUI_NO_CPP14
std::string name = m_name;
m_handlers[id] = [handler, name](){ handler(getWidget(), name, internal_signal::dereference<sf::String>(internal_signal::parameters[1])); };
#else
m_handlers[id] = [handler, name=m_name](){ handler(getWidget(), name, internal_signal::dereference<sf::String>(internal_signal::parameters[1])); };
#endif
return id;
}
@ -289,7 +384,12 @@ namespace tgui
unsigned int SignalItem::connect(const DelegateItemAndIdEx& handler)
{
const auto id = generateUniqueId();
#ifdef TGUI_NO_CPP14
std::string name = m_name;
m_handlers[id] = [handler, name](){ handler(getWidget(), name, internal_signal::dereference<sf::String>(internal_signal::parameters[1]), internal_signal::dereference<sf::String>(internal_signal::parameters[2])); };
#else
m_handlers[id] = [handler, name=m_name](){ handler(getWidget(), name, internal_signal::dereference<sf::String>(internal_signal::parameters[1]), internal_signal::dereference<sf::String>(internal_signal::parameters[2])); };
#endif
return id;
}
@ -297,11 +397,20 @@ namespace tgui
unsigned int SignalItem::validateTypes(std::initializer_list<std::type_index> unboundParameters)
{
#ifdef TGUI_UNSAFE_TYPE_INFO_COMPARISON
if ((unboundParameters.size() == 1) && ((strcmp(unboundParameters.begin()->name(), typeid(std::string).name()) == 0) || (strcmp(unboundParameters.begin()->name(), typeid(sf::String).name()) == 0)))
#else
if ((unboundParameters.size() == 1) && ((*unboundParameters.begin() == typeid(std::string)) || (*unboundParameters.begin() == typeid(sf::String))))
#endif
return 1;
else if ((unboundParameters.size() == 2)
#ifdef TGUI_UNSAFE_TYPE_INFO_COMPARISON
&& ((strcmp(unboundParameters.begin()->name(), typeid(std::string).name()) == 0) || (strcmp(unboundParameters.begin()->name(), typeid(sf::String).name()) == 0))
&& ((strcmp((unboundParameters.begin()+1)->name(), typeid(std::string).name()) == 0) || (strcmp((unboundParameters.begin()+1)->name(), typeid(sf::String).name()) == 0)))
#else
&& ((*unboundParameters.begin() == typeid(std::string)) || (*unboundParameters.begin() == typeid(sf::String)))
&& ((*(unboundParameters.begin()+1) == typeid(std::string)) || (*(unboundParameters.begin()+1) == typeid(sf::String))))
#endif
{
return 1;
}
@ -323,7 +432,12 @@ namespace tgui
unsigned int SignalMenuItem::connect(const DelegateMenuItemEx& handler)
{
const auto id = generateUniqueId();
#ifdef TGUI_NO_CPP14
std::string name = m_name;
m_handlers[id] = [handler, name](){ handler(getWidget(), name, internal_signal::dereference<sf::String>(internal_signal::parameters[1])); };
#else
m_handlers[id] = [handler, name=m_name](){ handler(getWidget(), name, internal_signal::dereference<sf::String>(internal_signal::parameters[1])); };
#endif
return id;
}
@ -341,7 +455,12 @@ namespace tgui
unsigned int SignalMenuItem::connect(const DelegateMenuItemFullEx& handler)
{
const auto id = generateUniqueId();
#ifdef TGUI_NO_CPP14
std::string name = m_name;
m_handlers[id] = [handler, name](){ handler(getWidget(), name, internal_signal::dereference<std::vector<sf::String>>(internal_signal::parameters[2])); };
#else
m_handlers[id] = [handler, name=m_name](){ handler(getWidget(), name, internal_signal::dereference<std::vector<sf::String>>(internal_signal::parameters[2])); };
#endif
return id;
}
@ -349,9 +468,17 @@ namespace tgui
unsigned int SignalMenuItem::validateTypes(std::initializer_list<std::type_index> unboundParameters)
{
#ifdef TGUI_UNSAFE_TYPE_INFO_COMPARISON
if ((unboundParameters.size() == 1) && ((strcmp(unboundParameters.begin()->name(), typeid(std::string).name()) == 0) || (strcmp(unboundParameters.begin()->name(), typeid(sf::String).name()) == 0)))
#else
if ((unboundParameters.size() == 1) && ((*unboundParameters.begin() == typeid(std::string)) || (*unboundParameters.begin() == typeid(sf::String))))
#endif
return 1;
#ifdef TGUI_UNSAFE_TYPE_INFO_COMPARISON
else if ((unboundParameters.size() == 1) && (strcmp(unboundParameters.begin()->name(), typeid(std::vector<sf::String>).name()) == 0))
#else
else if ((unboundParameters.size() == 1) && (*unboundParameters.begin() == typeid(std::vector<sf::String>)))
#endif
return 2;
else
return Signal::validateTypes(unboundParameters);

View File

@ -385,7 +385,7 @@ namespace tgui
// Apply clipping when needed
std::unique_ptr<Clipping> clipping;
if (m_visibleRect != sf::FloatRect{0, 0, 0, 0})
clipping = std::make_unique<Clipping>(target, states, sf::Vector2f{m_visibleRect.left, m_visibleRect.top}, sf::Vector2f{m_visibleRect.width, m_visibleRect.height});
clipping = make_unique<Clipping>(target, states, sf::Vector2f{m_visibleRect.left, m_visibleRect.top}, sf::Vector2f{m_visibleRect.width, m_visibleRect.height});
states.texture = &m_texture.getData()->texture;
target.draw(m_vertices.data(), m_vertices.size(), sf::PrimitiveType::TrianglesStrip, states);

View File

@ -37,7 +37,7 @@ namespace tgui
Texture::TextureLoaderFunc Texture::m_textureLoader = &TextureManager::getTexture;
Texture::ImageLoaderFunc Texture::m_imageLoader = [](const sf::String& filename) -> std::unique_ptr<sf::Image>
{
auto image = std::make_unique<sf::Image>();
auto image = make_unique<sf::Image>();
if (image->loadFromFile(filename))
return image;
else

View File

@ -453,7 +453,7 @@ namespace tgui
innerSize.x -= m_paddingCached.getLeft() + m_paddingCached.getRight();
innerSize.y -= m_paddingCached.getTop() + m_paddingCached.getBottom();
clipping = std::make_unique<Clipping>(target, states, sf::Vector2f{m_paddingCached.getLeft(), m_paddingCached.getTop()}, innerSize);
clipping = make_unique<Clipping>(target, states, sf::Vector2f{m_paddingCached.getLeft(), m_paddingCached.getTop()}, innerSize);
}
// Draw the text

View File

@ -643,7 +643,7 @@ namespace tgui
std::unique_ptr<Clipping> clipping;
const float usableWidth = m_tabWidth[i] - (2 * m_distanceToSideCached);
if (m_tabTexts[i].getSize().x > usableWidth)
clipping = std::make_unique<Clipping>(target, textStates, sf::Vector2f{m_distanceToSideCached, 0}, sf::Vector2f{usableWidth, usableHeight});
clipping = make_unique<Clipping>(target, textStates, sf::Vector2f{m_distanceToSideCached, 0}, sf::Vector2f{usableWidth, usableHeight});
// Draw the text
textStates.transform.translate({m_distanceToSideCached + ((usableWidth - m_tabTexts[i].getSize().x) / 2.f), ((usableHeight - m_tabTexts[i].getSize().y) / 2.f)});