Compare commits
	
		
			17 Commits
		
	
	
		
			84205879d4
			...
			d7f309750e
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| d7f309750e | |||
| eeb2a5a151 | |||
| 453f2750dd | |||
| 189ba4c545 | |||
| 057738088e | |||
| 272eabc732 | |||
| a02566697a | |||
| 6808adc8a1 | |||
| abc076d657 | |||
| 1b790a34c4 | |||
| 9220271630 | |||
| 7941a514ba | |||
| 0c09c5306e | |||
| 3ff91af86b | |||
| 79b42e1df7 | |||
| 5eec9085f8 | |||
| af7c89564c | 
| @@ -57,6 +57,7 @@ misc-*, | ||||
| readability-duplicate-include, | ||||
| -misc-non-private-member-variables-in-classes, | ||||
| -misc-no-recursion, | ||||
| -misc-include-cleaner, | ||||
| bugprone-*, | ||||
| clang-analyzer-*, | ||||
| modernize-*, | ||||
|   | ||||
							
								
								
									
										2
									
								
								deps/glutils/include/glutils/glutils.hpp
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								deps/glutils/include/glutils/glutils.hpp
									
									
									
									
										vendored
									
									
								
							| @@ -210,7 +210,7 @@ struct BufferSet { | ||||
| }; | ||||
|  | ||||
| void sendVbo(BufferSet const&bs) noexcept; | ||||
|                              | ||||
|  | ||||
| void sendEbo(BufferSet const&bs) noexcept; | ||||
|  | ||||
| void clearScreen() noexcept; | ||||
|   | ||||
							
								
								
									
										15
									
								
								deps/ox/src/ox/model/typenamecatcher.hpp
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										15
									
								
								deps/ox/src/ox/model/typenamecatcher.hpp
									
									
									
									
										vendored
									
									
								
							| @@ -147,4 +147,19 @@ constexpr auto ModelTypeName_v = getModelTypeName<T, Str>(); | ||||
| template<typename T, typename Str = const char*> | ||||
| constexpr auto ModelTypeVersion_v = requireModelTypeVersion<T>(); | ||||
|  | ||||
| template<typename T, typename Str = const char*> | ||||
| constexpr auto ModelTypeVersionStr_v = [] { | ||||
| 	constexpr auto version = ModelTypeVersion_v<T>; | ||||
| 	constexpr auto versionStr = ox::sfmt("{}", version); | ||||
| 	return ox::BString<versionStr.len()>{versionStr}; | ||||
| }; | ||||
|  | ||||
| template<typename T> | ||||
| constexpr auto ModelTypeId_v = [] { | ||||
| 	constexpr auto name = ModelTypeName_v<T, ox::StringView>; | ||||
| 	constexpr auto version = ModelTypeVersion_v<T>; | ||||
| 	constexpr auto versionStr = ox::sfmt<ox::BString<19>>("{}", version); | ||||
| 	return ox::sfmt<ox::BString<name.len() + versionStr.len() + 1>>("{};{}", name, versionStr); | ||||
| }(); | ||||
|  | ||||
| } | ||||
|   | ||||
							
								
								
									
										1
									
								
								deps/ox/src/ox/std/CMakeLists.txt
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								deps/ox/src/ox/std/CMakeLists.txt
									
									
									
									
										vendored
									
									
								
							| @@ -103,6 +103,7 @@ install( | ||||
| 		hardware.hpp | ||||
| 		hashmap.hpp | ||||
| 		heapmgr.hpp | ||||
| 		ignore.hpp | ||||
| 		iterator.hpp | ||||
| 		math.hpp | ||||
| 		maybeview.hpp | ||||
|   | ||||
							
								
								
									
										2
									
								
								deps/ox/src/ox/std/fmt.hpp
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								deps/ox/src/ox/std/fmt.hpp
									
									
									
									
										vendored
									
									
								
							| @@ -77,7 +77,7 @@ class FmtArg { | ||||
| 		char dataStr[10] = {}; | ||||
|  | ||||
| 		template<typename T> | ||||
| 		static StringView sv(const T &v, char *dataStr) noexcept { | ||||
| 		constexpr StringView sv(const T &v, char *dataStr) noexcept { | ||||
| 			if constexpr(is_bool_v<T>) { | ||||
| 				return v ? "true" : "false"; | ||||
| 			} else if constexpr(is_integer_v<T>) { | ||||
|   | ||||
							
								
								
									
										20
									
								
								deps/ox/src/ox/std/ignore.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								deps/ox/src/ox/std/ignore.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,20 @@ | ||||
| /* | ||||
|  * Copyright 2016 - 2024 Gary Talent (gary@drinkingtea.net). All rights reserved. | ||||
|  */ | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #if __has_include(<tuple>) | ||||
|  | ||||
| #include <tuple> | ||||
|  | ||||
| #else | ||||
|  | ||||
| namespace std { | ||||
|  | ||||
| inline constexpr struct { | ||||
| 	constexpr void operator=(auto&&) const noexcept {} | ||||
| } ignore; | ||||
|  | ||||
| } | ||||
| #endif | ||||
							
								
								
									
										2
									
								
								deps/ox/src/ox/std/realstd.hpp
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								deps/ox/src/ox/std/realstd.hpp
									
									
									
									
										vendored
									
									
								
							| @@ -11,5 +11,5 @@ | ||||
| #if __has_include(<cassert>) | ||||
| #include <cassert> | ||||
| #else | ||||
| #define	assert(e) while (1); | ||||
| #define	assert(e) while (!(e)); | ||||
| #endif | ||||
							
								
								
									
										1
									
								
								deps/ox/src/ox/std/std.hpp
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								deps/ox/src/ox/std/std.hpp
									
									
									
									
										vendored
									
									
								
							| @@ -26,6 +26,7 @@ | ||||
| #include "hardware.hpp" | ||||
| #include "hashmap.hpp" | ||||
| #include "heapmgr.hpp" | ||||
| #include "ignore.hpp" | ||||
| #include "iterator.hpp" | ||||
| #include "math.hpp" | ||||
| #include "maybeview.hpp" | ||||
|   | ||||
							
								
								
									
										4
									
								
								deps/ox/src/ox/std/strops.hpp
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								deps/ox/src/ox/std/strops.hpp
									
									
									
									
										vendored
									
									
								
							| @@ -80,6 +80,7 @@ constexpr bool endsWith(CRStringView base, CRStringView ending) noexcept { | ||||
| 	return base.len() >= endingLen && ox::strcmp(base.data() + (base.len() - endingLen), ending) == 0; | ||||
| } | ||||
|  | ||||
| [[nodiscard]] | ||||
| constexpr std::size_t find(CRStringView str, char search) noexcept { | ||||
| 	std::size_t i = 0; | ||||
| 	for (; i < str.len(); ++i) { | ||||
| @@ -90,6 +91,7 @@ constexpr std::size_t find(CRStringView str, char search) noexcept { | ||||
| 	return i; | ||||
| } | ||||
|  | ||||
| [[nodiscard]] | ||||
| constexpr std::size_t find(CRStringView str, CRStringView search) noexcept { | ||||
| 	std::size_t i = 0; | ||||
| 	for (; i < str.len(); ++i) { | ||||
| @@ -101,6 +103,7 @@ constexpr std::size_t find(CRStringView str, CRStringView search) noexcept { | ||||
| } | ||||
|  | ||||
| template<std::size_t smallSz = 0> | ||||
| [[nodiscard]] | ||||
| constexpr ox::Vector<ox::StringView, smallSz> split(CRStringView str, char del) noexcept { | ||||
| 	ox::Vector<ox::StringView, smallSz> out; | ||||
| 	constexpr auto nextSeg = [](CRStringView current, char del) { | ||||
| @@ -117,6 +120,7 @@ constexpr ox::Vector<ox::StringView, smallSz> split(CRStringView str, char del) | ||||
| } | ||||
|  | ||||
| template<std::size_t smallSz = 0> | ||||
| [[nodiscard]] | ||||
| constexpr ox::Vector<ox::StringView, smallSz> split(CRStringView str, CRStringView del) noexcept { | ||||
| 	ox::Vector<ox::StringView, smallSz> out; | ||||
| 	constexpr auto nextSeg = [](CRStringView current, CRStringView del) { | ||||
|   | ||||
							
								
								
									
										10
									
								
								deps/ox/src/ox/std/typetraits.hpp
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										10
									
								
								deps/ox/src/ox/std/typetraits.hpp
									
									
									
									
										vendored
									
									
								
							| @@ -143,7 +143,7 @@ template<typename T> | ||||
| constexpr bool memberable(...) { return false; } | ||||
|  | ||||
| template<typename T> | ||||
| struct is_class: integral_constant<bool, !is_union<T>::value && memberable<T>(0)> {}; | ||||
| struct is_class: integral_constant<bool, !is_union_v<T> && memberable<T>(nullptr)> {}; | ||||
|  | ||||
| namespace test { | ||||
| struct TestClass {int i;}; | ||||
| @@ -159,11 +159,11 @@ constexpr bool is_class_v = is_class<T>(); | ||||
| template<typename T> | ||||
| constexpr bool is_signed_v = integral_constant<bool, T(-1) < T(0)>::value; | ||||
|  | ||||
| template<typename T, std::size_t bits> | ||||
| concept Signed_c = is_signed_v<T> && sizeof(T) == 8 * bits; | ||||
| template<typename T, std::size_t bits = sizeof(T) * 8> | ||||
| concept Signed_c = is_signed_v<T> && sizeof(T) == bits / 8; | ||||
|  | ||||
| template<typename T, std::size_t bits> | ||||
| concept Unsigned_c = !is_signed_v<T> && sizeof(T) == 8 * bits; | ||||
| template<typename T, std::size_t bits = sizeof(T) * 8> | ||||
| concept Unsigned_c = !is_signed_v<T> && sizeof(T) == bits / 8; | ||||
|  | ||||
| template<typename T, typename U> | ||||
| struct is_same: false_type {}; | ||||
|   | ||||
							
								
								
									
										34
									
								
								deps/ox/src/ox/std/vector.hpp
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										34
									
								
								deps/ox/src/ox/std/vector.hpp
									
									
									
									
										vendored
									
									
								
							| @@ -52,13 +52,15 @@ struct VectorAllocator { | ||||
| 				const std::size_t cap) noexcept { | ||||
| 			// this totally idiotic redundant check (&& count <= Size) is required to address a bug in devkitARM, | ||||
| 			// try removing it later | ||||
| 			if (cap <= m_data.size() && count <= m_data.size()) { | ||||
| 				for (auto i = 0u; i < count; ++i) { | ||||
| 					const auto dstItem = reinterpret_cast<T*>(&m_data[i]); | ||||
| 					const auto srcItem = reinterpret_cast<T*>(&src->m_data[i]); | ||||
| 					std::construct_at<T>(dstItem, std::move(*srcItem)); | ||||
| 			if (!std::is_constant_evaluated()) { | ||||
| 				if (cap <= m_data.size() && count <= m_data.size()) { | ||||
| 					for (auto i = 0u; i < count; ++i) { | ||||
| 						const auto dstItem = reinterpret_cast<T *>(&m_data[i]); | ||||
| 						const auto srcItem = reinterpret_cast<T *>(&src->m_data[i]); | ||||
| 						std::construct_at<T>(dstItem, std::move(*srcItem)); | ||||
| 					} | ||||
| 					*items = reinterpret_cast<T*>(m_data.data()); | ||||
| 				} | ||||
| 				*items = reinterpret_cast<T*>(m_data.data()); | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| @@ -69,20 +71,24 @@ struct VectorAllocator { | ||||
| 				const std::size_t cap) noexcept { | ||||
| 			// this totally idiotic redundant check (&& count <= Size) is required to address a bug in devkitARM, | ||||
| 			// try removing it later | ||||
| 			if (cap <= m_data.size() && count <= m_data.size()) { | ||||
| 				for (std::size_t i = 0; i < count; ++i) { | ||||
| 					const auto dstItem = reinterpret_cast<T*>(&m_data[i]); | ||||
| 					const auto srcItem = reinterpret_cast<T*>(&src->m_data[i]); | ||||
| 					*dstItem = std::move(*srcItem); | ||||
| 			if (!std::is_constant_evaluated()) { | ||||
| 				if (cap <= m_data.size() && count <= m_data.size()) { | ||||
| 					for (std::size_t i = 0; i < count; ++i) { | ||||
| 						const auto dstItem = reinterpret_cast<T *>(&m_data[i]); | ||||
| 						const auto srcItem = reinterpret_cast<T *>(&src->m_data[i]); | ||||
| 						*dstItem = std::move(*srcItem); | ||||
| 					} | ||||
| 					*items = reinterpret_cast<T*>(m_data.data()); | ||||
| 				} | ||||
| 				*items = reinterpret_cast<T*>(m_data.data()); | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| 		constexpr void deallocate(T *items, std::size_t cap) noexcept { | ||||
| 			// small vector optimization cannot be done it constexpr, but it doesn't really matter in constexpr | ||||
| 			if (std::is_constant_evaluated() || (items && static_cast<void*>(items) != static_cast<void*>(m_data.data()))) { | ||||
| 				m_allocator.deallocate(items, cap); | ||||
| 			if (std::is_constant_evaluated()) { | ||||
| 				if (items && static_cast<void*>(items) != static_cast<void*>(m_data.data())) { | ||||
| 					m_allocator.deallocate(items, cap); | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
|   | ||||
| @@ -14,7 +14,7 @@ | ||||
|  | ||||
| namespace nostalgia::core { | ||||
|  | ||||
| class KeelModule: public keel::Module { | ||||
| static class: public keel::Module { | ||||
| 	private: | ||||
| 		NostalgiaPaletteToPaletteV1Converter m_nostalgiaPaletteToPaletteV1Converter; | ||||
| 		PaletteV1ToPaletteV2Converter m_paletteV1ToPaletteV2Converter; | ||||
| @@ -62,11 +62,11 @@ class KeelModule: public keel::Module { | ||||
| 					oxRequire(hdr, keel::readAssetHeader(buff)); | ||||
| 					auto const typeId = ox::buildTypeId( | ||||
| 							hdr.clawHdr.typeName, hdr.clawHdr.typeVersion, hdr.clawHdr.typeParams); | ||||
| 					if (typeId == ox::buildTypeId<TileSheetV1>() || | ||||
| 					    typeId == ox::buildTypeId<TileSheetV2>() || | ||||
| 					    typeId == ox::buildTypeId<TileSheetV3>() || | ||||
| 					    typeId == ox::buildTypeId<TileSheetV4>()) { | ||||
| 						oxReturnError(keel::convertBuffToBuff<core::CompactTileSheet>( | ||||
| 					if (typeId == ox::ModelTypeId_v<TileSheetV1> || | ||||
| 					    typeId == ox::ModelTypeId_v<TileSheetV2> || | ||||
| 					    typeId == ox::ModelTypeId_v<TileSheetV3> || | ||||
| 					    typeId == ox::ModelTypeId_v<TileSheetV4>) { | ||||
| 						oxReturnError(keel::convertBuffToBuff<CompactTileSheet>( | ||||
| 								ctx, buff, ox::ClawFormat::Metal).moveTo(buff)); | ||||
| 					} | ||||
| 					return {}; | ||||
| @@ -75,19 +75,18 @@ class KeelModule: public keel::Module { | ||||
| 					oxRequire(hdr, keel::readAssetHeader(buff)); | ||||
| 					auto const typeId = ox::buildTypeId( | ||||
| 							hdr.clawHdr.typeName, hdr.clawHdr.typeVersion, hdr.clawHdr.typeParams); | ||||
| 					if (typeId == ox::buildTypeId<NostalgiaPalette>() || | ||||
| 					    typeId == ox::buildTypeId<PaletteV1>()) { | ||||
| 						oxReturnError(keel::convertBuffToBuff<core::Palette>( | ||||
| 					if (typeId == ox::ModelTypeId_v<NostalgiaPalette> || | ||||
| 					    typeId == ox::ModelTypeId_v<PaletteV1>) { | ||||
| 						oxReturnError(keel::convertBuffToBuff<Palette>( | ||||
| 								ctx, buff, ox::ClawFormat::Metal).moveTo(buff)); | ||||
| 					} | ||||
| 					return {}; | ||||
| 				}, | ||||
| 			}; | ||||
| 		} | ||||
| }; | ||||
| } mod; | ||||
|  | ||||
| static const KeelModule mod; | ||||
| const keel::Module *keelModule() noexcept { | ||||
| keel::Module const*keelModule() noexcept { | ||||
| 	return &mod; | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -239,6 +239,7 @@ static void initSpritesBufferset(Context &ctx) noexcept { | ||||
| 	glEnableVertexAttribArray(texCoordAttr); | ||||
| 	glVertexAttribPointer(texCoordAttr, 2, GL_FLOAT, GL_FALSE, SpriteVertexVboRowLength * sizeof(float), | ||||
| 	                      std::bit_cast<void*>(uintptr_t{4 * sizeof(float)})); | ||||
| 	glBindVertexArray(0); | ||||
| } | ||||
|  | ||||
| static void initBackgroundBufferset( | ||||
| @@ -272,6 +273,7 @@ static void initBackgroundBufferset( | ||||
| 	glVertexAttribPointer( | ||||
| 			palBankAttr, 1, GL_FLOAT, GL_FALSE, BgVertexVboRowLength * sizeof(float), | ||||
| 			std::bit_cast<void*>(uintptr_t{6 * sizeof(float)})); | ||||
| 	glBindVertexArray(0); | ||||
| } | ||||
|  | ||||
| static glutils::GLTexture createTexture( | ||||
| @@ -301,6 +303,7 @@ static void drawBackground(CBB &cbb) noexcept { | ||||
| 	} | ||||
| 	glBindTexture(GL_TEXTURE_2D, cbb.tex); | ||||
| 	glDrawElements(GL_TRIANGLES, static_cast<GLsizei>(cbb.elements.size()), GL_UNSIGNED_INT, nullptr); | ||||
| 	glBindVertexArray(0); | ||||
| } | ||||
|  | ||||
| static void drawBackgrounds( | ||||
| @@ -354,6 +357,7 @@ static void drawSprites(Context &ctx, ox::Size const&renderSz) noexcept { | ||||
| 	// draw | ||||
| 	glBindTexture(GL_TEXTURE_2D, sb.tex); | ||||
| 	glDrawElements(GL_TRIANGLES, static_cast<GLsizei>(sb.elements.size()), GL_UNSIGNED_INT, nullptr); | ||||
| 	glBindVertexArray(0); | ||||
| } | ||||
|  | ||||
| static void loadPalette( | ||||
|   | ||||
| @@ -342,13 +342,14 @@ void TileSheetEditorImGui::drawTileSheet(ox::Vec2 const&fbSize) noexcept { | ||||
| 	} else if (m_view.updated()) { | ||||
| 		m_view.ackUpdate(); | ||||
| 	} | ||||
| 	glBindFramebuffer(GL_FRAMEBUFFER, m_framebuffer); | ||||
| 	// clear screen and draw | ||||
| 	glViewport(0, 0, fbSizei.width, fbSizei.height); | ||||
| 	m_view.draw(); | ||||
| 	glBindFramebuffer(GL_FRAMEBUFFER, 0); | ||||
| 	{ | ||||
| 		glutils::FrameBufferBind const frameBufferBind(m_framebuffer); | ||||
| 		// clear screen and draw | ||||
| 		glViewport(0, 0, fbSizei.width, fbSizei.height); | ||||
| 		m_view.draw(); | ||||
| 	} | ||||
| 	ImGui::Image( | ||||
| 		std::bit_cast<ImTextureID>(uintptr_t{m_framebuffer.color.id}), | ||||
| 		ig::toImTextureID(m_framebuffer.color.id), | ||||
| 		static_cast<ImVec2>(fbSize), | ||||
| 		ImVec2(0, 1), | ||||
| 		ImVec2(1, 0)); | ||||
|   | ||||
| @@ -14,6 +14,7 @@ namespace nostalgia::core { | ||||
| TileSheetEditorView::TileSheetEditorView(studio::StudioContext &sctx, ox::StringView path, studio::UndoStack &undoStack): | ||||
| 	m_model(sctx, path, undoStack), | ||||
| 	m_pixelsDrawer(m_model) { | ||||
| 	glBindVertexArray(0); | ||||
| 	// build shaders | ||||
| 	oxThrowError(m_pixelsDrawer.buildShader()); | ||||
| 	oxThrowError(m_pixelGridDrawer.buildShader()); | ||||
|   | ||||
| @@ -160,7 +160,7 @@ auto transformRule(keel::Context &ctx, ox::Buffer &buff) noexcept -> ox::Error { | ||||
| 	oxRequire(hdr, readAssetHeader(buff)); | ||||
| 	const auto typeId = ox::buildTypeId( | ||||
| 			hdr.clawHdr.typeName, hdr.clawHdr.typeVersion, hdr.clawHdr.typeParams); | ||||
| 	if (typeId == ox::buildTypeId<From>()) { | ||||
| 	if (typeId == ox::ModelTypeId_v<From>) { | ||||
| 		oxReturnError(keel::convertBuffToBuff<To>(ctx, buff, fmt).moveTo(buff)); | ||||
| 	} | ||||
| 	return {}; | ||||
|   | ||||
| @@ -56,7 +56,7 @@ static ox::Error runApp( | ||||
| 	return err; | ||||
| } | ||||
|  | ||||
| ox::Error run( | ||||
| static ox::Error run( | ||||
| 		ox::CRStringView appName, | ||||
| 		ox::CRStringView projectDataDir, | ||||
| 		int, | ||||
|   | ||||
| @@ -8,6 +8,8 @@ | ||||
|  | ||||
| #include <imgui.h> | ||||
|  | ||||
| #include <ox/std/bit.hpp> | ||||
|  | ||||
| #include <turbine/context.hpp> | ||||
| #include <studio/context.hpp> | ||||
|  | ||||
| @@ -15,6 +17,91 @@ namespace studio::ig { | ||||
|  | ||||
| inline constexpr auto BtnSz = ImVec2{52, 22}; | ||||
|  | ||||
|  | ||||
| constexpr ImTextureID toImTextureID(ox::Unsigned_c auto id) noexcept | ||||
| 	requires(sizeof(id) <= sizeof(ox::Uint<sizeof(ImTextureID)*8>)) { | ||||
| 	return std::bit_cast<ImTextureID>(ox::Uint<sizeof(ImTextureID)*8>{id}); | ||||
| } | ||||
|  | ||||
| template<typename T> | ||||
| ox::Result<T> getDragDropPayload(ox::CStringView name) noexcept { | ||||
| 	auto const payload = ImGui::AcceptDragDropPayload(name.c_str()); | ||||
| 	if (!payload) { | ||||
| 		return OxError(1, "No drag/drop payload"); | ||||
| 	} | ||||
| 	return ox::readClaw<T>( | ||||
| 			reinterpret_cast<char const*>(payload->Data), | ||||
| 			static_cast<size_t>(payload->DataSize)); | ||||
| } | ||||
|  | ||||
| ox::Error setDragDropPayload(ox::CStringView name, auto const &obj) noexcept { | ||||
| 	oxRequire(buff, ox::writeClaw(obj, ox::ClawFormat::Metal)); | ||||
| 	ImGui::SetDragDropPayload(name.c_str(), buff.data(), buff.size()); | ||||
| 	return {}; | ||||
| } | ||||
|  | ||||
|  | ||||
| class DragDropSource { | ||||
| 	private: | ||||
| 		bool const m_active{}; | ||||
| 	public: | ||||
| 		inline DragDropSource() noexcept: | ||||
| 			m_active(ImGui::BeginDragDropSource()) { | ||||
| 		} | ||||
| 		inline ~DragDropSource() noexcept { | ||||
| 			if (m_active) { | ||||
| 				ImGui::EndDragDropSource(); | ||||
| 			} | ||||
| 		} | ||||
| 		constexpr operator bool() const noexcept { | ||||
| 			return m_active; | ||||
| 		} | ||||
| }; | ||||
|  | ||||
| inline auto dragDropSource(auto const&cb) noexcept { | ||||
| 	if constexpr(ox::is_same_v<decltype(cb()), ox::Error>) { | ||||
| 		if (ig::DragDropSource const tgt; tgt) [[unlikely]] { | ||||
| 			return cb(); | ||||
| 		} | ||||
| 	} else { | ||||
| 		if (ig::DragDropSource const tgt; tgt) [[unlikely]] { | ||||
| 			cb(); | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
|  | ||||
| class DragDropTarget { | ||||
| 	private: | ||||
| 		bool const m_active{}; | ||||
| 	public: | ||||
| 		inline DragDropTarget() noexcept: | ||||
| 			m_active(ImGui::BeginDragDropTarget()) { | ||||
| 		} | ||||
| 		inline ~DragDropTarget() noexcept { | ||||
| 			if (m_active) { | ||||
| 				ImGui::EndDragDropTarget(); | ||||
| 			} | ||||
| 		} | ||||
| 		constexpr operator bool() const noexcept { | ||||
| 			return m_active; | ||||
| 		} | ||||
| }; | ||||
|  | ||||
| inline auto dragDropTarget(auto const&cb) noexcept { | ||||
| 	if constexpr(ox::is_same_v<decltype(cb()), ox::Error>) { | ||||
| 		if (ig::DragDropTarget const tgt; tgt) [[unlikely]] { | ||||
| 			return cb(); | ||||
| 		} | ||||
| 		return ox::Error{}; | ||||
| 	} else { | ||||
| 		if (ig::DragDropTarget const tgt; tgt) [[unlikely]] { | ||||
| 			cb(); | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
|  | ||||
| class ChildStackItem { | ||||
| 	public: | ||||
| 		explicit ChildStackItem(ox::CStringView id, ImVec2 const&sz = {}) noexcept; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user