77#include < initializer_list>
88#include < string>
99#include < type_traits>
10+ #include < Geode/loader/Dispatch.hpp>
11+ #define MY_MOD_ID " geode.devtools"
1012
1113namespace devtools {
1214 template <typename T>
@@ -22,6 +24,9 @@ namespace devtools {
2224 std::is_same_v<T, cocos2d::CCSize> ||
2325 std::is_same_v<T, cocos2d::CCRect>;
2426
27+ template <typename T>
28+ concept UnderlyingIntegral = std::is_integral_v<T> || std::is_integral_v<std::underlying_type_t <T>>;
29+
2530 struct RegisterNodeEvent final : geode::Event {
2631 RegisterNodeEvent (std::function<void (cocos2d::CCNode*)>&& callback)
2732 : callback(std::move(callback)) {}
@@ -124,7 +129,7 @@ namespace devtools {
124129 // / @param items A list of pairs where each pair contains a value and its corresponding label.
125130 // / @return True if the value was changed, false otherwise.
126131 // / @warning This function should only ever be called from within a registered node callback.
127- template <typename T> requires std::is_integral_v<std:: underlying_type_t <T> >
132+ template <UnderlyingIntegral T >
128133 bool enumerable (const char * label, T& value, std::initializer_list<std::pair<T, const char *>> items) {
129134 using ValueType = std::underlying_type_t <T>;
130135 static auto fn = ([] {
@@ -165,4 +170,38 @@ namespace devtools {
165170 callback ();
166171 }
167172 }
168- }
173+
174+ inline void newLine () GEODE_EVENT_EXPORT_NORES(&newLine, ());
175+ inline void sameLine () GEODE_EVENT_EXPORT_NORES(&sameLine, ());
176+ inline void separator () GEODE_EVENT_EXPORT_NORES(&separator, ());
177+ inline void nextItemWidth (float width) GEODE_EVENT_EXPORT_NORES(&nextItemWidth, (width));
178+
179+ inline bool combo (
180+ char const * label,
181+ int & current,
182+ std::span<char const *> items,
183+ int maxHeight = -1
184+ ) GEODE_EVENT_EXPORT_NORES(&combo, (label, current, items, maxHeight));
185+
186+ template <UnderlyingIntegral T, typename R = std::initializer_list<char const *>>
187+ requires
188+ std::ranges::range<R> &&
189+ std::same_as<std::remove_pointer_t <decltype (&*std::declval<R>().begin())> const , char const * const >
190+ bool combo (char const * label, T& current, R&& range, int maxHeight = -1 ) {
191+ return combo (
192+ label,
193+ reinterpret_cast <int &>(current),
194+ std::span (const_cast <char const **>(&*range.begin ()), const_cast <char const **>(&*range.end ())),
195+ maxHeight
196+ );
197+ }
198+
199+ inline bool radio (char const * label, int & current, int num) GEODE_EVENT_EXPORT_NORES(&radio, (label, current, num));
200+
201+ template <UnderlyingIntegral T, UnderlyingIntegral U>
202+ bool radio (char const * label, T& current, U value) {
203+ return radio (label, reinterpret_cast <int &>(current), reinterpret_cast <int &>(value));
204+ }
205+
206+ inline void inputMultiline (char const * label, std::string& text) GEODE_EVENT_EXPORT_NORES(&inputMultiline, (label, text));
207+ }
0 commit comments