basic property and property drawer

This commit is contained in:
2019-12-09 22:52:03 +07:00
parent 5d32e5be64
commit 09edf8c514
10 changed files with 819 additions and 0 deletions

View File

@@ -66,6 +66,7 @@
#include "node.hpp"
#include "node.inl"
#include "prefab.hpp"
#include "property.hpp"
#include "script.hpp"
#include "spine.hpp"
#include "sprite.hpp"

View File

@@ -97,6 +97,14 @@ namespace e2d
class gcomponent;
template < typename T >
class const_gcomponent;
template < typename T >
class property;
class text_property;
template < typename T >
class drag_property;
template < typename T >
class slider_property;
}
namespace sol

View File

@@ -0,0 +1,202 @@
/*******************************************************************************
* This file is part of the "Enduro2D"
* For conditions of distribution and use, see copyright notice in LICENSE.md
* Copyright (C) 2018-2019, by Matvey Cherevko (blackmatov@gmail.com)
******************************************************************************/
#pragma once
#include "_high.hpp"
namespace e2d
{
template < typename T >
struct property_traits {
using step_t = T;
using range_t = std::pair<T,T>;
};
template < typename T >
struct property_traits<vec2<T>> {
using step_t = T;
using range_t = std::pair<T,T>;
};
template < typename T >
struct property_traits<vec3<T>> {
using step_t = T;
using range_t = std::pair<T,T>;
};
template < typename T >
struct property_traits<vec4<T>> {
using step_t = T;
using range_t = std::pair<T,T>;
};
}
namespace e2d
{
template < typename T >
class property {
public:
property() = delete;
property(property&&) = default;
property& operator=(property&&) = default;
property(const property&) = default;
property& operator=(const property&) = default;
property(T value)
noexcept(std::is_nothrow_move_constructible_v<T>)
: value_(std::move(value)) {}
property& operator=(T value)
noexcept(std::is_nothrow_move_assignable_v<T>)
{
value_ = std::move(value);
return *this;
}
const T& operator*() const noexcept {
return value_;
}
const T* operator->() const noexcept {
return &value_;
}
private:
T value_{};
};
}
namespace e2d
{
class text_property {
public:
text_property() = delete;
text_property(text_property&&) = default;
text_property& operator=(text_property&&) = default;
text_property(const text_property&) = default;
text_property& operator=(const text_property&) = default;
text_property(str value) noexcept
: value_(std::move(value)) {}
text_property(str value, bool multiline) noexcept
: value_(std::move(value))
, multiline_(multiline) {}
property<str>& value() noexcept {
return value_;
}
const property<str>& value() const noexcept {
return value_;
}
bool multiline() const noexcept {
return multiline_;
}
private:
property<str> value_;
bool multiline_ = false;
};
}
namespace e2d
{
template < typename T >
class drag_property {
public:
using step_t = typename property_traits<T>::step_t;
using range_t = typename property_traits<T>::range_t;
public:
drag_property() = delete;
drag_property(drag_property&&) = default;
drag_property& operator=(drag_property&&) = default;
drag_property(const drag_property&) = default;
drag_property& operator=(const drag_property&) = default;
drag_property(T value)
noexcept(std::is_nothrow_move_constructible_v<T>)
: value_(std::move(value)) {}
drag_property(T value, step_t step)
noexcept(std::is_nothrow_move_constructible_v<T>
&& std::is_nothrow_move_constructible_v<step_t>)
: value_(std::move(value))
, step_(std::move(step)) {}
drag_property(T value, step_t step, range_t range)
noexcept(std::is_nothrow_move_constructible_v<T>
&& std::is_nothrow_move_constructible_v<step_t>
&& std::is_nothrow_move_constructible_v<range_t>)
: value_(std::move(value))
, step_(std::move(step))
, range_(std::move(range)) {}
property<T>& value() noexcept {
return value_;
}
const property<T>& value() const noexcept {
return value_;
}
const std::optional<step_t>& step() const noexcept {
return step_;
}
const std::optional<range_t>& range() const noexcept {
return range_;
}
private:
property<T> value_;
std::optional<step_t> step_;
std::optional<range_t> range_;
};
}
namespace e2d
{
template < typename T >
class slider_property {
public:
using range_t = typename property_traits<T>::range_t;
public:
slider_property() = delete;
slider_property(slider_property&&) = default;
slider_property& operator=(slider_property&&) = default;
slider_property(const slider_property&) = default;
slider_property& operator=(const slider_property&) = default;
slider_property(T value, range_t range)
noexcept(std::is_nothrow_move_constructible_v<T>
&& std::is_nothrow_move_constructible_v<range_t>)
: value_(std::move(value))
, range_(std::move(range)) {}
property<T>& value() noexcept {
return value_;
}
const property<T>& value() const noexcept {
return value_;
}
const range_t& range() const noexcept {
return range_;
}
private:
property<T> value_;
range_t range_{};
};
}

View File

@@ -27,6 +27,8 @@ cp -fv $MODULES_DIR/imgui/imgui_widgets.cpp $SOURCES_RDPARTY_DIR/imgui/imgui_wid
cp -fv $MODULES_DIR/imgui/imstb_rectpack.h $SOURCES_RDPARTY_DIR/imgui/imstb_rectpack.h
cp -fv $MODULES_DIR/imgui/imstb_textedit.h $SOURCES_RDPARTY_DIR/imgui/imstb_textedit.h
cp -fv $MODULES_DIR/imgui/imstb_truetype.h $SOURCES_RDPARTY_DIR/imgui/imstb_truetype.h
cp -fv $MODULES_DIR/imgui/misc/cpp/imgui_stdlib.h $SOURCES_RDPARTY_DIR/imgui/imgui_stdlib.h
cp -fv $MODULES_DIR/imgui/misc/cpp/imgui_stdlib.cpp $SOURCES_RDPARTY_DIR/imgui/imgui_stdlib.cpp
mkdir -p $HEADERS_RDPARTY_DIR/lua
cp -fv $MODULES_DIR/lua/lapi.c $HEADERS_RDPARTY_DIR/lua/lapi.c

77
sources/3rdparty/imgui/imgui_stdlib.cpp vendored Normal file
View File

@@ -0,0 +1,77 @@
// imgui_stdlib.cpp
// Wrappers for C++ standard library (STL) types (std::string, etc.)
// This is also an example of how you may wrap your own similar types.
// Compatibility:
// - std::string support is only guaranteed to work from C++11.
// If you try to use it pre-C++11, please share your findings (w/ info about compiler/architecture)
// Changelog:
// - v0.10: Initial version. Added InputText() / InputTextMultiline() calls with std::string
#include "imgui.h"
#include "imgui_stdlib.h"
struct InputTextCallback_UserData
{
std::string* Str;
ImGuiInputTextCallback ChainCallback;
void* ChainCallbackUserData;
};
static int InputTextCallback(ImGuiInputTextCallbackData* data)
{
InputTextCallback_UserData* user_data = (InputTextCallback_UserData*)data->UserData;
if (data->EventFlag == ImGuiInputTextFlags_CallbackResize)
{
// Resize string callback
// If for some reason we refuse the new length (BufTextLen) and/or capacity (BufSize) we need to set them back to what we want.
std::string* str = user_data->Str;
IM_ASSERT(data->Buf == str->c_str());
str->resize(data->BufTextLen);
data->Buf = (char*)str->c_str();
}
else if (user_data->ChainCallback)
{
// Forward to user callback, if any
data->UserData = user_data->ChainCallbackUserData;
return user_data->ChainCallback(data);
}
return 0;
}
bool ImGui::InputText(const char* label, std::string* str, ImGuiInputTextFlags flags, ImGuiInputTextCallback callback, void* user_data)
{
IM_ASSERT((flags & ImGuiInputTextFlags_CallbackResize) == 0);
flags |= ImGuiInputTextFlags_CallbackResize;
InputTextCallback_UserData cb_user_data;
cb_user_data.Str = str;
cb_user_data.ChainCallback = callback;
cb_user_data.ChainCallbackUserData = user_data;
return InputText(label, (char*)str->c_str(), str->capacity() + 1, flags, InputTextCallback, &cb_user_data);
}
bool ImGui::InputTextMultiline(const char* label, std::string* str, const ImVec2& size, ImGuiInputTextFlags flags, ImGuiInputTextCallback callback, void* user_data)
{
IM_ASSERT((flags & ImGuiInputTextFlags_CallbackResize) == 0);
flags |= ImGuiInputTextFlags_CallbackResize;
InputTextCallback_UserData cb_user_data;
cb_user_data.Str = str;
cb_user_data.ChainCallback = callback;
cb_user_data.ChainCallbackUserData = user_data;
return InputTextMultiline(label, (char*)str->c_str(), str->capacity() + 1, size, flags, InputTextCallback, &cb_user_data);
}
bool ImGui::InputTextWithHint(const char* label, const char* hint, std::string* str, ImGuiInputTextFlags flags, ImGuiInputTextCallback callback, void* user_data)
{
IM_ASSERT((flags & ImGuiInputTextFlags_CallbackResize) == 0);
flags |= ImGuiInputTextFlags_CallbackResize;
InputTextCallback_UserData cb_user_data;
cb_user_data.Str = str;
cb_user_data.ChainCallback = callback;
cb_user_data.ChainCallbackUserData = user_data;
return InputTextWithHint(label, hint, (char*)str->c_str(), str->capacity() + 1, flags, InputTextCallback, &cb_user_data);
}

23
sources/3rdparty/imgui/imgui_stdlib.h vendored Normal file
View File

@@ -0,0 +1,23 @@
// imgui_stdlib.h
// Wrappers for C++ standard library (STL) types (std::string, etc.)
// This is also an example of how you may wrap your own similar types.
// Compatibility:
// - std::string support is only guaranteed to work from C++11.
// If you try to use it pre-C++11, please share your findings (w/ info about compiler/architecture)
// Changelog:
// - v0.10: Initial version. Added InputText() / InputTextMultiline() calls with std::string
#pragma once
#include <string>
namespace ImGui
{
// ImGui::InputText() with std::string
// Because text input needs dynamic resizing, we need to setup a callback to grow the capacity
IMGUI_API bool InputText(const char* label, std::string* str, ImGuiInputTextFlags flags = 0, ImGuiInputTextCallback callback = NULL, void* user_data = NULL);
IMGUI_API bool InputTextMultiline(const char* label, std::string* str, const ImVec2& size = ImVec2(0, 0), ImGuiInputTextFlags flags = 0, ImGuiInputTextCallback callback = NULL, void* user_data = NULL);
IMGUI_API bool InputTextWithHint(const char* label, const char* hint, std::string* str, ImGuiInputTextFlags flags = 0, ImGuiInputTextCallback callback = NULL, void* user_data = NULL);
}

View File

@@ -137,4 +137,18 @@ namespace e2d::imgex
show_checkbox(label, &value);
}
bool show_input_text(str_view label, str* value) {
char* label_cstr = static_cast<char*>(E2D_CLEAR_ALLOCA(label.size() + 1));
std::memcpy(label_cstr, label.data(), label.size());
return ImGui::InputText(label_cstr, value);
}
bool show_input_text_multiline(str_view label, str* value) {
char* label_cstr = static_cast<char*>(E2D_CLEAR_ALLOCA(label.size() + 1));
std::memcpy(label_cstr, label.data(), label.size());
return ImGui::InputTextMultiline(label_cstr, value);
}
}

View File

@@ -15,6 +15,7 @@
#include <enduro2d/core/window.hpp>
#include <3rdparty/imgui/imgui.h>
#include <3rdparty/imgui/imgui_stdlib.h>
#include <3rdparty/imgui/imgui_internal.h>
namespace e2d::imgui
@@ -48,6 +49,9 @@ namespace e2d::imgex
bool show_checkbox(str_view label, bool* value);
void show_disabled_checkbox(str_view label, bool value);
bool show_input_text(str_view label, str* value);
bool show_input_text_multiline(str_view label, str* value);
template < typename... Args >
void show_text(str_view text, Args&&... args) {
if constexpr ( sizeof... (Args) ) {

View File

@@ -0,0 +1,429 @@
/*******************************************************************************
* This file is part of the "Enduro2D"
* For conditions of distribution and use, see copyright notice in LICENSE.md
* Copyright (C) 2018-2019, by Matvey Cherevko (blackmatov@gmail.com)
******************************************************************************/
#include "property_drawer.hpp"
#include <enduro2d/high/property.hpp>
namespace e2d::dbgui_widgets
{
//
// f32
//
bool property_drawer::operator()(str_view l, f32& p) const {
char* l_cstr = static_cast<char*>(E2D_CLEAR_ALLOCA(l.size() + 1));
std::memcpy(l_cstr, l.data(), l.size());
return ImGui::InputFloat(l_cstr, &p);
}
bool property_drawer::operator()(str_view l, property<f32>& p) const {
f32 v = *p;
if ( (*this)(l, v) ) {
p = v;
return true;
}
return false;
}
bool property_drawer::operator()(str_view l, drag_property<f32>& p) const {
char* l_cstr = static_cast<char*>(E2D_CLEAR_ALLOCA(l.size() + 1));
std::memcpy(l_cstr, l.data(), l.size());
f32 v = *p.value();
bool changed = false;
if ( p.step() && p.range() ) {
changed = ImGui::DragFloat(l_cstr, &v, *p.step(), p.range()->first, p.range()->second);
} else if ( p.step() ) {
changed = ImGui::DragFloat(l_cstr, &v, *p.step());
} else {
changed = ImGui::DragFloat(l_cstr, &v);
}
if ( changed ) {
p.value() = v;
}
return changed;
}
bool property_drawer::operator()(str_view l, slider_property<f32>& p) const {
char* l_cstr = static_cast<char*>(E2D_CLEAR_ALLOCA(l.size() + 1));
std::memcpy(l_cstr, l.data(), l.size());
f32 v = *p.value();
bool changed = false;
changed = ImGui::SliderFloat(l_cstr, &v, p.range().first, p.range().second);
if ( changed ) {
p.value() = v;
}
return changed;
}
//
// v2f
//
bool property_drawer::operator()(str_view l, v2f& p) const {
char* l_cstr = static_cast<char*>(E2D_CLEAR_ALLOCA(l.size() + 1));
std::memcpy(l_cstr, l.data(), l.size());
return ImGui::InputFloat2(l_cstr, p.data());
}
bool property_drawer::operator()(str_view l, property<v2f>& p) const {
v2f v = *p;
if ( (*this)(l, v) ) {
p = v;
return true;
}
return false;
}
bool property_drawer::operator()(str_view l, drag_property<v2f>& p) const {
char* l_cstr = static_cast<char*>(E2D_CLEAR_ALLOCA(l.size() + 1));
std::memcpy(l_cstr, l.data(), l.size());
v2f v = *p.value();
bool changed = false;
if ( p.step() && p.range() ) {
changed = ImGui::DragFloat2(l_cstr, v.data(), *p.step(), p.range()->first, p.range()->second);
} else if ( p.step() ) {
changed = ImGui::DragFloat2(l_cstr, v.data(), *p.step());
} else {
changed = ImGui::DragFloat2(l_cstr, v.data());
}
if ( changed ) {
p.value() = v;
}
return changed;
}
bool property_drawer::operator()(str_view l, slider_property<v2f>& p) const {
char* l_cstr = static_cast<char*>(E2D_CLEAR_ALLOCA(l.size() + 1));
std::memcpy(l_cstr, l.data(), l.size());
v2f v = *p.value();
bool changed = false;
changed = ImGui::SliderFloat2(l_cstr, v.data(), p.range().first, p.range().second);
if ( changed ) {
p.value() = v;
}
return changed;
}
//
// v3f
//
bool property_drawer::operator()(str_view l, v3f& p) const {
char* l_cstr = static_cast<char*>(E2D_CLEAR_ALLOCA(l.size() + 1));
std::memcpy(l_cstr, l.data(), l.size());
return ImGui::InputFloat3(l_cstr, p.data());
}
bool property_drawer::operator()(str_view l, property<v3f>& p) const {
v3f v = *p;
if ( (*this)(l, v) ) {
p = v;
return true;
}
return false;
}
bool property_drawer::operator()(str_view l, drag_property<v3f>& p) const {
char* l_cstr = static_cast<char*>(E2D_CLEAR_ALLOCA(l.size() + 1));
std::memcpy(l_cstr, l.data(), l.size());
v3f v = *p.value();
bool changed = false;
if ( p.step() && p.range() ) {
changed = ImGui::DragFloat3(l_cstr, v.data(), *p.step(), p.range()->first, p.range()->second);
} else if ( p.step() ) {
changed = ImGui::DragFloat3(l_cstr, v.data(), *p.step());
} else {
changed = ImGui::DragFloat3(l_cstr, v.data());
}
if ( changed ) {
p.value() = v;
}
return changed;
}
bool property_drawer::operator()(str_view l, slider_property<v3f>& p) const {
char* l_cstr = static_cast<char*>(E2D_CLEAR_ALLOCA(l.size() + 1));
std::memcpy(l_cstr, l.data(), l.size());
v3f v = *p.value();
bool changed = false;
changed = ImGui::SliderFloat3(l_cstr, v.data(), p.range().first, p.range().second);
if ( changed ) {
p.value() = v;
}
return changed;
}
//
// v4f
//
bool property_drawer::operator()(str_view l, v4f& p) const {
char* l_cstr = static_cast<char*>(E2D_CLEAR_ALLOCA(l.size() + 1));
std::memcpy(l_cstr, l.data(), l.size());
return ImGui::InputFloat4(l_cstr, p.data());
}
bool property_drawer::operator()(str_view l, property<v4f>& p) const {
v4f v = *p;
if ( (*this)(l, v) ) {
p = v;
return true;
}
return false;
}
bool property_drawer::operator()(str_view l, drag_property<v4f>& p) const {
char* l_cstr = static_cast<char*>(E2D_CLEAR_ALLOCA(l.size() + 1));
std::memcpy(l_cstr, l.data(), l.size());
v4f v = *p.value();
bool changed = false;
if ( p.step() && p.range() ) {
changed = ImGui::DragFloat4(l_cstr, v.data(), *p.step(), p.range()->first, p.range()->second);
} else if ( p.step() ) {
changed = ImGui::DragFloat4(l_cstr, v.data(), *p.step());
} else {
changed = ImGui::DragFloat4(l_cstr, v.data());
}
if ( changed ) {
p.value() = v;
}
return changed;
}
bool property_drawer::operator()(str_view l, slider_property<v4f>& p) const {
char* l_cstr = static_cast<char*>(E2D_CLEAR_ALLOCA(l.size() + 1));
std::memcpy(l_cstr, l.data(), l.size());
v4f v = *p.value();
bool changed = false;
changed = ImGui::SliderFloat4(l_cstr, v.data(), p.range().first, p.range().second);
if ( changed ) {
p.value() = v;
}
return changed;
}
//
// str
//
bool property_drawer::operator()(str_view l, str& p) const {
return imgex::show_input_text(l, &p);
}
bool property_drawer::operator()(str_view l, property<str>& p) const {
str v = *p;
if ( (*this)(l, v) ) {
p = std::move(v);
return true;
}
return false;
}
bool property_drawer::operator()(str_view l, text_property& p) const {
str v = *p.value();
bool changed = false;
if ( p.multiline() ) {
changed = imgex::show_input_text_multiline(l, &v);
} else {
changed = imgex::show_input_text(l, &v);
}
if ( changed ) {
p.value() = std::move(v);
}
return changed;
}
//
// degf
//
bool property_drawer::operator()(str_view l, degf& p) const {
char* l_cstr = static_cast<char*>(E2D_CLEAR_ALLOCA(l.size() + 1));
std::memcpy(l_cstr, l.data(), l.size());
return ImGui::InputFloat(l_cstr, &p.value);
}
bool property_drawer::operator()(str_view l, property<degf>& p) const {
degf v = *p;
if ( (*this)(l, v) ) {
p = v;
return true;
}
return false;
}
bool property_drawer::operator()(str_view l, drag_property<degf>& p) const {
char* l_cstr = static_cast<char*>(E2D_CLEAR_ALLOCA(l.size() + 1));
std::memcpy(l_cstr, l.data(), l.size());
f32 v = p.value()->value;
bool changed = false;
if ( p.step() && p.range() ) {
changed = ImGui::DragFloat(l_cstr, &v, p.step()->value, p.range()->first.value, p.range()->second.value);
} else if ( p.step() ) {
changed = ImGui::DragFloat(l_cstr, &v, p.step()->value);
} else {
changed = ImGui::DragFloat(l_cstr, &v);
}
if ( changed ) {
p.value() = make_deg(v);
}
return changed;
}
bool property_drawer::operator()(str_view l, slider_property<degf>& p) const {
char* l_cstr = static_cast<char*>(E2D_CLEAR_ALLOCA(l.size() + 1));
std::memcpy(l_cstr, l.data(), l.size());
f32 v = p.value()->value;
bool changed = false;
changed = ImGui::SliderFloat(l_cstr, &v, p.range().first.value, p.range().second.value);
if ( changed ) {
p.value() = make_deg(v);
}
return changed;
}
//
// radf
//
bool property_drawer::operator()(str_view l, radf& p) const {
char* l_cstr = static_cast<char*>(E2D_CLEAR_ALLOCA(l.size() + 1));
std::memcpy(l_cstr, l.data(), l.size());
return ImGui::InputFloat(l_cstr, &p.value);
}
bool property_drawer::operator()(str_view l, property<radf>& p) const {
radf v = *p;
if ( (*this)(l, v) ) {
p = v;
return true;
}
return false;
}
bool property_drawer::operator()(str_view l, drag_property<radf>& p) const {
char* l_cstr = static_cast<char*>(E2D_CLEAR_ALLOCA(l.size() + 1));
std::memcpy(l_cstr, l.data(), l.size());
f32 v = p.value()->value;
bool changed = false;
if ( p.step() && p.range() ) {
changed = ImGui::DragFloat(l_cstr, &v, p.step()->value, p.range()->first.value, p.range()->second.value);
} else if ( p.step() ) {
changed = ImGui::DragFloat(l_cstr, &v, p.step()->value);
} else {
changed = ImGui::DragFloat(l_cstr, &v);
}
if ( changed ) {
p.value() = make_rad(v);
}
return changed;
}
bool property_drawer::operator()(str_view l, slider_property<radf>& p) const {
char* l_cstr = static_cast<char*>(E2D_CLEAR_ALLOCA(l.size() + 1));
std::memcpy(l_cstr, l.data(), l.size());
f32 v = p.value()->value;
bool changed = false;
changed = ImGui::SliderFloat(l_cstr, &v, p.range().first.value, p.range().second.value);
if ( changed ) {
p.value() = make_rad(v);
}
return changed;
}
//
// color
//
bool property_drawer::operator()(str_view l, color& p) const {
char* l_cstr = static_cast<char*>(E2D_CLEAR_ALLOCA(l.size() + 1));
std::memcpy(l_cstr, l.data(), l.size());
return ImGui::ColorEdit4(l_cstr, p.data());
}
bool property_drawer::operator()(str_view l, property<color>& p) const {
color v = *p;
if ( (*this)(l, v) ) {
p = v;
return true;
}
return false;
}
//
// color32
//
bool property_drawer::operator()(str_view l, color32& p) const {
color v = color(p);
if ( (*this)(l, v) ) {
p = color32(v);
return true;
}
return false;
}
bool property_drawer::operator()(str_view l, property<color32>& p) const {
color v = color(*p);
if ( (*this)(l, v) ) {
p = color32(v);
return true;
}
return false;
}
}

View File

@@ -0,0 +1,59 @@
/*******************************************************************************
* This file is part of the "Enduro2D"
* For conditions of distribution and use, see copyright notice in LICENSE.md
* Copyright (C) 2018-2019, by Matvey Cherevko (blackmatov@gmail.com)
******************************************************************************/
#pragma once
#include <enduro2d/high/_high.hpp>
#include "../../core/dbgui_impl/dbgui.hpp"
namespace e2d::dbgui_widgets
{
class property_drawer {
public:
property_drawer() = default;
bool operator()(str_view l, f32& p) const;
bool operator()(str_view l, property<f32>& p) const;
bool operator()(str_view l, drag_property<f32>& p) const;
bool operator()(str_view l, slider_property<f32>& p) const;
bool operator()(str_view l, v2f& p) const;
bool operator()(str_view l, property<v2f>& p) const;
bool operator()(str_view l, drag_property<v2f>& p) const;
bool operator()(str_view l, slider_property<v2f>& p) const;
bool operator()(str_view l, v3f& p) const;
bool operator()(str_view l, property<v3f>& p) const;
bool operator()(str_view l, drag_property<v3f>& p) const;
bool operator()(str_view l, slider_property<v3f>& p) const;
bool operator()(str_view l, v4f& p) const;
bool operator()(str_view l, property<v4f>& p) const;
bool operator()(str_view l, drag_property<v4f>& p) const;
bool operator()(str_view l, slider_property<v4f>& p) const;
bool operator()(str_view l, str& p) const;
bool operator()(str_view l, property<str>& p) const;
bool operator()(str_view l, text_property& p) const;
bool operator()(str_view l, degf& p) const;
bool operator()(str_view l, property<degf>& p) const;
bool operator()(str_view l, drag_property<degf>& p) const;
bool operator()(str_view l, slider_property<degf>& p) const;
bool operator()(str_view l, radf& p) const;
bool operator()(str_view l, property<radf>& p) const;
bool operator()(str_view l, drag_property<radf>& p) const;
bool operator()(str_view l, slider_property<radf>& p) const;
bool operator()(str_view l, color& p) const;
bool operator()(str_view l, property<color>& p) const;
bool operator()(str_view l, color32& p) const;
bool operator()(str_view l, property<color32>& p) const;
};
}