Onionskin, input rebinding, alt icons, settings refactor
This commit is contained in:
BIN
assets/atlas.png
BIN
assets/atlas.png
Binary file not shown.
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
30
src/COMMON.h
30
src/COMMON.h
@@ -10,6 +10,7 @@
|
|||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
|
#include <climits>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
@@ -342,8 +343,6 @@ static inline void map_insert_shift(std::map<int, T>& map, s32 index, const T& v
|
|||||||
map[insertIndex] = value;
|
map[insertIndex] = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#define DEFINE_ENUM_TO_STRING_FUNCTION(function, array, count) \
|
#define DEFINE_ENUM_TO_STRING_FUNCTION(function, array, count) \
|
||||||
static inline std::string function(s32 index) \
|
static inline std::string function(s32 index) \
|
||||||
{ \
|
{ \
|
||||||
@@ -356,19 +355,30 @@ static inline void map_insert_shift(std::map<int, T>& map, s32 index, const T& v
|
|||||||
return static_cast<enumType>(string_to_enum(string, stringArray, count)); \
|
return static_cast<enumType>(string_to_enum(string, stringArray, count)); \
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define DATATYPE_LIST \
|
||||||
|
X(TYPE_INT, s32) \
|
||||||
|
X(TYPE_BOOL, bool) \
|
||||||
|
X(TYPE_FLOAT, f32) \
|
||||||
|
X(TYPE_STRING, std::string) \
|
||||||
|
X(TYPE_IVEC2, ivec2) \
|
||||||
|
X(TYPE_IVEC2_WH, ivec2) \
|
||||||
|
X(TYPE_VEC2, vec2) \
|
||||||
|
X(TYPE_VEC2_WH, vec2) \
|
||||||
|
X(TYPE_VEC3, vec3) \
|
||||||
|
X(TYPE_VEC4, vec4)
|
||||||
|
|
||||||
enum DataType
|
enum DataType
|
||||||
{
|
{
|
||||||
TYPE_INT,
|
#define X(symbol, ctype) symbol,
|
||||||
TYPE_BOOL,
|
DATATYPE_LIST
|
||||||
TYPE_FLOAT,
|
#undef X
|
||||||
TYPE_STRING,
|
|
||||||
TYPE_IVEC2,
|
|
||||||
TYPE_VEC2,
|
|
||||||
TYPE_VEC3,
|
|
||||||
TYPE_VEC4
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define DATATYPE_TO_CTYPE(dt) DATATYPE_CTYPE_##dt
|
||||||
|
#define X(symbol, ctype) typedef ctype DATATYPE_CTYPE_##symbol;
|
||||||
|
DATATYPE_LIST
|
||||||
|
#undef X
|
||||||
|
|
||||||
enum OriginType
|
enum OriginType
|
||||||
{
|
{
|
||||||
ORIGIN_TOP_LEFT,
|
ORIGIN_TOP_LEFT,
|
||||||
|
198
src/PACKED.h
198
src/PACKED.h
@@ -7,104 +7,106 @@
|
|||||||
const u8 TEXTURE_ATLAS[] =
|
const u8 TEXTURE_ATLAS[] =
|
||||||
{
|
{
|
||||||
0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d,
|
0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d,
|
||||||
0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x78,
|
0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0xa0,
|
||||||
0x04, 0x03, 0x00, 0x00, 0x00, 0xff, 0x33, 0xea, 0xfd, 0x00, 0x00, 0x00,
|
0x02, 0x03, 0x00, 0x00, 0x00, 0x8e, 0x1e, 0x81, 0x1f, 0x00, 0x00, 0x00,
|
||||||
0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x0b, 0x12, 0x00, 0x00, 0x0b,
|
0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x0b, 0x12, 0x00, 0x00, 0x0b,
|
||||||
0x12, 0x01, 0xd2, 0xdd, 0x7e, 0xfc, 0x00, 0x00, 0x00, 0x0f, 0x50, 0x4c,
|
0x12, 0x01, 0xd2, 0xdd, 0x7e, 0xfc, 0x00, 0x00, 0x00, 0x0c, 0x50, 0x4c,
|
||||||
0x54, 0x45, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x60, 0x60, 0x60, 0xff,
|
0x54, 0x45, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x60,
|
||||||
0xff, 0xff, 0x60, 0x60, 0x60, 0x15, 0x68, 0x14, 0xc2, 0x00, 0x00, 0x00,
|
0x60, 0x60, 0x58, 0xe6, 0xdc, 0x65, 0x00, 0x00, 0x00, 0x02, 0x74, 0x52,
|
||||||
0x03, 0x74, 0x52, 0x4e, 0x53, 0x00, 0x00, 0x00, 0xfa, 0x76, 0xc4, 0xde,
|
0x4e, 0x53, 0x00, 0x00, 0x76, 0x93, 0xcd, 0x38, 0x00, 0x00, 0x04, 0x15,
|
||||||
0x00, 0x00, 0x03, 0xf4, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0xed, 0x98,
|
0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0xe5, 0xd3, 0xb1, 0x6a, 0x1c, 0x47,
|
||||||
0x6d, 0x6e, 0xde, 0x38, 0x0c, 0x84, 0x27, 0x20, 0x0f, 0xb0, 0xc1, 0x5e,
|
0x1c, 0xc7, 0xf1, 0x2f, 0xb3, 0xc4, 0x2c, 0xe3, 0x63, 0xaf, 0x4b, 0x91,
|
||||||
0x60, 0x81, 0x5c, 0x80, 0x9b, 0xe1, 0x01, 0x08, 0x88, 0xf7, 0x3f, 0xd3,
|
0x6a, 0x49, 0xb5, 0xcc, 0x1d, 0xf6, 0x81, 0x1b, 0xb1, 0x36, 0x56, 0x1e,
|
||||||
0x42, 0x94, 0x04, 0xa9, 0xad, 0x83, 0xd8, 0x0b, 0x34, 0xed, 0x8f, 0x4e,
|
0x21, 0x75, 0xde, 0xc0, 0x79, 0x8a, 0xc1, 0x95, 0x48, 0x61, 0x5c, 0x24,
|
||||||
0x90, 0xc8, 0xb4, 0xf9, 0x84, 0x5f, 0xd2, 0xeb, 0x20, 0xf8, 0x3f, 0x22,
|
0xfd, 0x20, 0x1c, 0x98, 0xfc, 0x77, 0xd1, 0x2d, 0x49, 0x63, 0x14, 0x81,
|
||||||
0x71, 0x29, 0x31, 0x94, 0x9a, 0x97, 0xd7, 0xe1, 0x4f, 0xd6, 0x12, 0x42,
|
0xb6, 0x34, 0x41, 0xe4, 0x19, 0x5c, 0x8a, 0xb3, 0x09, 0x02, 0x37, 0xe1,
|
||||||
0xc6, 0xe1, 0x4f, 0xda, 0xf1, 0x0b, 0x99, 0x0e, 0x68, 0xdd, 0x07, 0x68,
|
0x72, 0xf8, 0x92, 0x19, 0x5d, 0xb4, 0x91, 0x6e, 0x94, 0x20, 0xab, 0x48,
|
||||||
0x90, 0x22, 0x87, 0x4b, 0x23, 0x09, 0x29, 0x73, 0x03, 0x29, 0x04, 0x64,
|
0xe1, 0x1f, 0x0c, 0x03, 0xf7, 0xe1, 0xfe, 0x33, 0xf3, 0xdf, 0x19, 0xae,
|
||||||
0x86, 0x22, 0xeb, 0x72, 0x7b, 0x90, 0xc2, 0x92, 0xed, 0x94, 0x84, 0xae,
|
0x8f, 0x76, 0x5c, 0x44, 0x59, 0x28, 0x3a, 0x34, 0x00, 0x22, 0xe8, 0xd6,
|
||||||
0x1c, 0x80, 0x90, 0x38, 0x1c, 0xd4, 0x80, 0xd3, 0x16, 0x9b, 0x00, 0xc9,
|
0xb4, 0x00, 0x18, 0x0f, 0xda, 0xa1, 0xff, 0x60, 0x86, 0x72, 0xda, 0x96,
|
||||||
0x61, 0xd1, 0xc4, 0xa4, 0xb2, 0xd7, 0xed, 0x30, 0x53, 0xba, 0x02, 0x84,
|
0x5a, 0x3c, 0x2c, 0x44, 0x89, 0xd8, 0x00, 0x63, 0x43, 0x89, 0x46, 0xbb,
|
||||||
0x10, 0x13, 0x94, 0xac, 0xdb, 0x15, 0x26, 0x1b, 0xe9, 0x19, 0xdf, 0x02,
|
0x92, 0x00, 0x22, 0x46, 0xc4, 0xc7, 0x52, 0xe6, 0x27, 0x87, 0xc6, 0xb8,
|
||||||
0x5e, 0x16, 0xed, 0x04, 0x1c, 0x2d, 0x0a, 0xc8, 0xe6, 0xd9, 0x01, 0x1d,
|
0xf8, 0x43, 0x66, 0x89, 0xb3, 0xb2, 0x68, 0x23, 0x8e, 0x0a, 0x5f, 0x4d,
|
||||||
0xbd, 0x63, 0x0b, 0xd2, 0x3a, 0x20, 0xc4, 0x01, 0x28, 0x41, 0x60, 0x10,
|
0x61, 0x07, 0x65, 0x09, 0xa5, 0x06, 0x50, 0xae, 0x2a, 0x21, 0xaf, 0x94,
|
||||||
0xe5, 0x8f, 0x66, 0xe2, 0x1d, 0x58, 0xd5, 0x17, 0x46, 0x2c, 0x00, 0x0b,
|
0x65, 0x77, 0xd1, 0xac, 0x36, 0xd0, 0x51, 0x69, 0x1b, 0x61, 0x52, 0xf4,
|
||||||
0x88, 0xee, 0x1f, 0xa1, 0x64, 0xcd, 0x08, 0x3c, 0xe7, 0x7c, 0x02, 0x8d,
|
0xec, 0xbe, 0x3f, 0x5e, 0x51, 0xb7, 0xe8, 0xb7, 0x62, 0xa9, 0x0c, 0x11,
|
||||||
0x5e, 0x01, 0x54, 0x35, 0x55, 0x21, 0x95, 0x06, 0x6d, 0x02, 0x7b, 0x70,
|
0x6a, 0x0d, 0xd9, 0x7a, 0xdd, 0x73, 0x3a, 0x41, 0xf3, 0x06, 0xb4, 0xc7,
|
||||||
0xab, 0x4b, 0xf5, 0xb0, 0x14, 0x5d, 0x17, 0xc0, 0xdc, 0x1a, 0xca, 0x52,
|
0x05, 0xd0, 0x1a, 0x46, 0xeb, 0xd5, 0x49, 0xed, 0x74, 0xab, 0x37, 0x07,
|
||||||
0xa0, 0x9e, 0xcc, 0x18, 0x00, 0x94, 0x31, 0x7e, 0xf0, 0xf3, 0xcd, 0x87,
|
0x8f, 0x50, 0x34, 0xf0, 0xe0, 0xc1, 0xbb, 0x99, 0xb1, 0xca, 0x07, 0x88,
|
||||||
0xc0, 0x2f, 0x96, 0x92, 0x71, 0x65, 0x8b, 0x61, 0xd9, 0xd8, 0xda, 0xe7,
|
0x07, 0x0c, 0xbb, 0x52, 0x1e, 0x38, 0x39, 0xe9, 0x2f, 0x00, 0x11, 0x6a,
|
||||||
0xa2, 0x71, 0x6c, 0x81, 0xec, 0x6b, 0x1e, 0x00, 0xb9, 0x89, 0xa3, 0xbd,
|
0x91, 0x16, 0x07, 0x3c, 0x98, 0x51, 0xf7, 0x59, 0xab, 0xb7, 0x9a, 0x48,
|
||||||
0x70, 0x74, 0xaa, 0x83, 0x40, 0x07, 0x85, 0x7c, 0x07, 0x80, 0x37, 0x66,
|
0xcf, 0x6d, 0x53, 0xb7, 0xc3, 0x7c, 0x29, 0x22, 0x14, 0x22, 0xdd, 0x58,
|
||||||
0xd0, 0x8e, 0xd0, 0xcc, 0x4c, 0x12, 0xb0, 0xa2, 0x01, 0xc6, 0xe8, 0x9f,
|
0xe4, 0x0c, 0x86, 0xc4, 0x2d, 0xdf, 0x85, 0xd7, 0x85, 0xd3, 0xdd, 0xa5,
|
||||||
0x8b, 0xb5, 0x0a, 0xa0, 0x91, 0xe4, 0xf0, 0xef, 0x84, 0x32, 0xb3, 0x91,
|
0x32, 0x7a, 0xbd, 0x74, 0x39, 0x94, 0xba, 0x1f, 0xb6, 0x48, 0x26, 0xd2,
|
||||||
0xb1, 0x00, 0x25, 0x20, 0x65, 0x8b, 0xc9, 0x04, 0xa4, 0x00, 0xf1, 0xcc,
|
0xd7, 0xeb, 0x45, 0x1b, 0xa0, 0xc6, 0xb4, 0x43, 0x99, 0xe3, 0xf7, 0x76,
|
||||||
0x66, 0xb5, 0xd0, 0x9b, 0x2d, 0x60, 0x9d, 0x13, 0x96, 0x80, 0x56, 0xcf,
|
0xb2, 0x6e, 0x4e, 0x03, 0x84, 0x6f, 0x73, 0x01, 0x0f, 0x7f, 0xfb, 0xf9,
|
||||||
0xc5, 0xa0, 0xde, 0x9a, 0x7b, 0x0b, 0xf1, 0x6c, 0xcc, 0x13, 0x80, 0x10,
|
0xed, 0xe4, 0xfd, 0xfc, 0x34, 0x57, 0xb6, 0xac, 0x94, 0x1b, 0xa0, 0xfd,
|
||||||
0x07, 0x50, 0xcf, 0xc5, 0xc0, 0x10, 0x31, 0x53, 0x36, 0x4b, 0x7a, 0x8a,
|
0x7c, 0xaf, 0x3e, 0x5d, 0x1e, 0x4f, 0xfe, 0x82, 0x59, 0xa5, 0xed, 0x00,
|
||||||
0x0f, 0x40, 0xb1, 0xce, 0xc9, 0x4a, 0x49, 0x4c, 0xe9, 0xdd, 0x56, 0x93,
|
0x3b, 0xd3, 0x9d, 0xe9, 0xc4, 0x10, 0x4a, 0x51, 0x19, 0x06, 0x50, 0xda,
|
||||||
0xe8, 0xdf, 0xe2, 0x42, 0x60, 0x45, 0xd8, 0xe7, 0x64, 0x15, 0xdd, 0x9f,
|
0xd9, 0xba, 0x59, 0xb7, 0x39, 0xda, 0xd5, 0x7e, 0x3c, 0x2c, 0x9e, 0x75,
|
||||||
0x67, 0xb7, 0x21, 0x20, 0x61, 0x50, 0xd2, 0x33, 0x67, 0xd1, 0x64, 0xb7,
|
0x45, 0xaf, 0xe7, 0x6b, 0x97, 0x73, 0xef, 0xa5, 0x76, 0xbb, 0x03, 0xb0,
|
||||||
0x0d, 0xc9, 0xa8, 0xb6, 0x92, 0x00, 0xe9, 0x91, 0xd5, 0x25, 0x47, 0x1d,
|
0x68, 0x50, 0xf3, 0xa5, 0xbd, 0xcb, 0x8f, 0xcf, 0x0a, 0xb7, 0x3c, 0xde,
|
||||||
0x4a, 0x56, 0x5f, 0xd1, 0x01, 0x69, 0x6e, 0x05, 0x75, 0x00, 0x62, 0xd3,
|
0x6e, 0x49, 0x3b, 0xdd, 0x19, 0x8b, 0x8c, 0x12, 0x4d, 0xd4, 0x8e, 0x7a,
|
||||||
0x8e, 0xb2, 0x6b, 0xb4, 0x5e, 0x83, 0xcb, 0x9c, 0x83, 0xab, 0x2c, 0x1a,
|
0x7e, 0xc6, 0x7f, 0x47, 0xd9, 0x30, 0x92, 0xef, 0x23, 0x8c, 0x58, 0x4e,
|
||||||
0x91, 0xf4, 0xec, 0x40, 0xd9, 0xc2, 0x08, 0xba, 0x5e, 0x6d, 0x8d, 0xe8,
|
0x7d, 0x53, 0xb9, 0x30, 0x80, 0x15, 0x18, 0x4f, 0x1c, 0x22, 0x94, 0x10,
|
||||||
0x55, 0x21, 0xcb, 0x0e, 0xe0, 0xf5, 0x9f, 0xb2, 0x31, 0xec, 0xeb, 0xcd,
|
0x07, 0x64, 0x2b, 0x62, 0x36, 0x17, 0xba, 0x54, 0xb2, 0x57, 0x42, 0x0e,
|
||||||
0xb7, 0x26, 0x9a, 0x79, 0xd8, 0x58, 0xf6, 0x73, 0x89, 0xed, 0xf5, 0x96,
|
0xd3, 0x55, 0x28, 0x11, 0x41, 0xb7, 0xb5, 0x03, 0xd9, 0x23, 0xc2, 0xe1,
|
||||||
0xc8, 0xbd, 0xee, 0xd4, 0xc4, 0x28, 0xc6, 0xbd, 0x96, 0x32, 0xf6, 0x7b,
|
0x8c, 0xfc, 0xed, 0xc3, 0x32, 0x74, 0x36, 0x5c, 0xb4, 0x92, 0x85, 0x2d,
|
||||||
0xa0, 0xd6, 0x5d, 0xbc, 0xac, 0xf0, 0x38, 0xa4, 0x05, 0x9c, 0xa9, 0xfd,
|
0x01, 0xd4, 0xa2, 0xa7, 0xea, 0x8a, 0xaa, 0x2a, 0xba, 0xca, 0xf4, 0xf8,
|
||||||
0x05, 0xfc, 0x4d, 0x76, 0x52, 0xc6, 0x6f, 0xb0, 0x09, 0x18, 0x5e, 0x01,
|
0x92, 0x4d, 0xa9, 0xbb, 0x8d, 0xc5, 0x3f, 0x7d, 0x6a, 0x44, 0x44, 0x0c,
|
||||||
0x89, 0x8c, 0xb3, 0x3b, 0x52, 0x77, 0xc9, 0x58, 0x87, 0xb1, 0x03, 0x98,
|
0x78, 0xd4, 0x41, 0x2c, 0xc5, 0xbd, 0x03, 0x18, 0xc0, 0xfa, 0x52, 0xdb,
|
||||||
0xc0, 0xcb, 0x2b, 0xe0, 0x54, 0x00, 0xd6, 0x42, 0x5d, 0x00, 0xeb, 0x80,
|
0x58, 0x8a, 0xc3, 0x97, 0x30, 0x94, 0xda, 0xf7, 0x46, 0xc8, 0x4b, 0xd4,
|
||||||
0x60, 0x7d, 0x70, 0x49, 0x8d, 0xc4, 0xce, 0x94, 0xa4, 0x8d, 0xc1, 0x3b,
|
0x1e, 0x8b, 0xd7, 0x5c, 0x2c, 0x5e, 0x5b, 0x69, 0x8d, 0x27, 0x07, 0x65,
|
||||||
0xd0, 0xc4, 0xc4, 0xd0, 0x1c, 0x62, 0x52, 0xe1, 0x06, 0x50, 0x29, 0xed,
|
0xd5, 0xc4, 0x32, 0x6c, 0xd7, 0x8b, 0x33, 0x1e, 0x4a, 0x8c, 0xd7, 0xcf,
|
||||||
0x08, 0x4e, 0x37, 0xa0, 0xdf, 0x33, 0x11, 0x2e, 0x09, 0x51, 0x40, 0x75,
|
0x60, 0x38, 0xa0, 0x17, 0x1b, 0xfe, 0x11, 0xc1, 0xc1, 0xd0, 0x92, 0xf0,
|
||||||
0xa1, 0xed, 0x94, 0xf0, 0x2a, 0x8d, 0x0d, 0xd7, 0x80, 0x81, 0x26, 0x45,
|
0x8f, 0x4d, 0xa9, 0xc7, 0x16, 0x86, 0x26, 0x22, 0xde, 0xf8, 0x7d, 0xab,
|
||||||
0x9d, 0x29, 0x55, 0x80, 0xeb, 0x94, 0x28, 0x34, 0x61, 0x55, 0x6e, 0x05,
|
0xab, 0x7d, 0xfb, 0x28, 0xd1, 0xf6, 0x9b, 0xc4, 0x02, 0x28, 0x20, 0x73,
|
||||||
0x88, 0x19, 0x50, 0x01, 0x7e, 0x2c, 0x5a, 0x69, 0x20, 0x19, 0x73, 0x2a,
|
0xc0, 0x08, 0x78, 0x04, 0xea, 0xd7, 0x4e, 0x9d, 0x83, 0x85, 0x79, 0x80,
|
||||||
0xb6, 0xfa, 0x07, 0x91, 0x0a, 0x70, 0xd5, 0x56, 0x23, 0xb9, 0xc7, 0xb9,
|
0x57, 0xc0, 0x12, 0xb2, 0x43, 0xa7, 0xcf, 0xc1, 0x31, 0x69, 0xa1, 0xee,
|
||||||
0x46, 0x4a, 0xab, 0x00, 0x57, 0x83, 0x33, 0xd2, 0x16, 0x60, 0x1b, 0x20,
|
0x3c, 0x64, 0x0b, 0x0b, 0x0b, 0x67, 0x44, 0xfa, 0x4c, 0xc4, 0xeb, 0x37,
|
||||||
0x4a, 0x17, 0x5b, 0x63, 0x47, 0x38, 0x52, 0xd2, 0x66, 0x57, 0x9b, 0x6f,
|
0x90, 0xf9, 0xa9, 0x87, 0xb1, 0x74, 0x28, 0xdd, 0x89, 0x88, 0xd3, 0x22,
|
||||||
0x5d, 0xd0, 0x3a, 0x40, 0x31, 0x80, 0x52, 0xab, 0xc6, 0xe5, 0xf6, 0xfe,
|
0xa2, 0x7b, 0x28, 0x7e, 0xbf, 0xdf, 0xc2, 0x63, 0x39, 0x23, 0x57, 0xbd,
|
||||||
0x1a, 0xd9, 0x11, 0x1b, 0x43, 0x4a, 0x4c, 0xc5, 0xb0, 0xc7, 0x22, 0xd1,
|
0x39, 0x07, 0x3f, 0x9e, 0xcf, 0x5d, 0xbd, 0x9c, 0xf7, 0xf0, 0x4b, 0xd3,
|
||||||
0x7c, 0x27, 0x76, 0x24, 0xc9, 0x5c, 0x40, 0x58, 0x2d, 0xd3, 0x56, 0x27,
|
0x53, 0x66, 0x9d, 0xb6, 0x9c, 0x4e, 0x50, 0x2e, 0x80, 0x91, 0x03, 0x4b,
|
||||||
0x01, 0x9e, 0x00, 0x01, 0x88, 0x33, 0x46, 0x18, 0x9f, 0x0f, 0xb5, 0x4d,
|
0xb6, 0x3f, 0x07, 0xfb, 0xea, 0xb5, 0xb2, 0x54, 0x15, 0xca, 0x8e, 0x60,
|
||||||
0xa7, 0x56, 0xed, 0xec, 0x8a, 0xf5, 0x1e, 0x36, 0xb0, 0xf9, 0x4c, 0xeb,
|
0x56, 0xca, 0x01, 0x14, 0xfe, 0x08, 0x45, 0x09, 0xe7, 0xc0, 0x78, 0xbd,
|
||||||
0xfd, 0x2d, 0x86, 0x63, 0x92, 0x3e, 0x32, 0xa6, 0x83, 0x43, 0xc0, 0xba,
|
0x3e, 0x2b, 0xe5, 0x10, 0x6a, 0x99, 0x91, 0x8f, 0x2c, 0x10, 0x00, 0x46,
|
||||||
0x60, 0xa0, 0xd4, 0xf2, 0xfd, 0x2d, 0x19, 0x23, 0x00, 0x73, 0x54, 0x2b,
|
0xcc, 0x66, 0x66, 0x7e, 0x08, 0x5a, 0x7a, 0x72, 0x05, 0x10, 0xd6, 0x20,
|
||||||
0x01, 0xf9, 0x16, 0x30, 0x24, 0xfb, 0x17, 0x94, 0x49, 0x66, 0xc1, 0x41,
|
0x42, 0x75, 0xff, 0x25, 0x28, 0x81, 0x3c, 0x07, 0x54, 0xd8, 0x95, 0x8d,
|
||||||
0x7a, 0x54, 0x00, 0xa8, 0x03, 0xb4, 0xfd, 0x17, 0x8c, 0x10, 0x03, 0x98,
|
0x80, 0x39, 0x05, 0x9a, 0x77, 0xa3, 0xc2, 0x0d, 0x10, 0xd6, 0xa0, 0x0e,
|
||||||
0xa9, 0xd6, 0xb4, 0x95, 0xb2, 0x02, 0x84, 0xb5, 0xd9, 0x19, 0xb1, 0xb9,
|
0xb0, 0x7b, 0xd2, 0x43, 0x80, 0x70, 0x72, 0xcb, 0x87, 0x45, 0x59, 0x00,
|
||||||
0xcc, 0x46, 0x2a, 0x04, 0x1d, 0x18, 0x95, 0xda, 0x0a, 0x20, 0xe8, 0x3a,
|
0x76, 0x12, 0x10, 0xa9, 0x45, 0x5b, 0x50, 0xad, 0xe9, 0xd1, 0x1d, 0x03,
|
||||||
0x01, 0x00, 0x59, 0x2a, 0xc0, 0xd7, 0x3b, 0x51, 0x57, 0x00, 0x94, 0x26,
|
0x28, 0x87, 0xf6, 0x57, 0xc1, 0x78, 0xd0, 0x16, 0x2d, 0x36, 0x01, 0x06,
|
||||||
0xb0, 0x47, 0xa5, 0x50, 0x08, 0x99, 0x05, 0x60, 0x34, 0x11, 0xc7, 0x69,
|
0xb4, 0xf8, 0x01, 0x36, 0x04, 0x4d, 0x8f, 0x16, 0xb1, 0x01, 0xb4, 0x48,
|
||||||
0xdc, 0x35, 0x9c, 0x80, 0x49, 0xfa, 0xda, 0xd5, 0x18, 0x80, 0x61, 0x48,
|
0x17, 0x46, 0x5c, 0x23, 0x13, 0x09, 0xd0, 0x5e, 0x06, 0x40, 0x49, 0x13,
|
||||||
0x56, 0x97, 0x6c, 0x03, 0x75, 0xbb, 0x0d, 0x0f, 0x7a, 0x2a, 0x02, 0x8d,
|
0xe0, 0xe8, 0x9f, 0x40, 0xcc, 0xd8, 0xa3, 0xa5, 0xe9, 0x03, 0x8c, 0x97,
|
||||||
0xb8, 0x04, 0xb2, 0x04, 0x40, 0x17, 0xa0, 0x19, 0x11, 0x38, 0x24, 0x6b,
|
0xc7, 0x67, 0xa1, 0x57, 0xf1, 0x5a, 0xc7, 0xed, 0xca, 0xd1, 0xa5, 0xc5,
|
||||||
0xd2, 0x86, 0x2f, 0x95, 0x1c, 0xf1, 0xd4, 0x6e, 0x01, 0x1b, 0x62, 0x00,
|
0x8d, 0xff, 0x7b, 0xbb, 0x4d, 0x9f, 0x80, 0x1a, 0xf4, 0x11, 0x09, 0x98,
|
||||||
0x2f, 0x9c, 0x86, 0x30, 0x84, 0x31, 0xba, 0xf1, 0x01, 0x20, 0x44, 0x07,
|
0xc2, 0xb8, 0x87, 0x6c, 0xb5, 0xdb, 0x33, 0x3e, 0x1b, 0x20, 0x95, 0xb8,
|
||||||
0x68, 0x9f, 0x01, 0xfb, 0x73, 0x65, 0x00, 0xb4, 0x7b, 0x80, 0x10, 0x13,
|
0xf8, 0xb5, 0x59, 0x6f, 0xd2, 0x43, 0x8c, 0x72, 0x0c, 0x10, 0x96, 0xd8,
|
||||||
0xa0, 0x5d, 0x03, 0x27, 0x54, 0xf7, 0x63, 0x01, 0xb4, 0x0d, 0x94, 0xed,
|
0x82, 0x85, 0x48, 0xf3, 0x61, 0xc0, 0xc7, 0x02, 0x46, 0xd2, 0xa0, 0x44,
|
||||||
0x6b, 0x3d, 0x6a, 0x50, 0x92, 0x5c, 0x00, 0xe3, 0x63, 0xe0, 0xdc, 0x39,
|
0x5c, 0x12, 0xf4, 0x53, 0xe7, 0xd3, 0xa0, 0x5c, 0x95, 0x84, 0x4a, 0x39,
|
||||||
0xbe, 0x00, 0xff, 0x10, 0x38, 0x95, 0xb4, 0x09, 0x78, 0xec, 0x94, 0x32,
|
0x7d, 0x03, 0x90, 0x8b, 0xdc, 0x1c, 0x6e, 0xb3, 0x78, 0xfa, 0x1c, 0xe9,
|
||||||
0xe9, 0x99, 0x40, 0x96, 0xf6, 0x07, 0xf2, 0x6e, 0x6b, 0xf9, 0x7f, 0x54,
|
0x93, 0xa7, 0x7b, 0x95, 0xee, 0xee, 0xff, 0xff, 0xcd, 0x6b, 0x91, 0x36,
|
||||||
0x74, 0x01, 0x67, 0x5b, 0x81, 0xf2, 0xbf, 0x05, 0x28, 0xb1, 0x9a, 0x75,
|
0x09, 0x85, 0x48, 0x97, 0x84, 0x4c, 0xa4, 0x4f, 0xbe, 0x0f, 0x16, 0x0d,
|
||||||
0x0f, 0x90, 0xe1, 0x98, 0x81, 0xb5, 0xdb, 0x75, 0x5c, 0x67, 0x5e, 0x01,
|
0x69, 0xa8, 0x5b, 0xd2, 0x50, 0x74, 0x49, 0x88, 0x3f, 0x6d, 0x3d, 0xe7,
|
||||||
0x37, 0xb5, 0x8b, 0x7e, 0xac, 0xfc, 0x4e, 0x81, 0xef, 0x44, 0xbb, 0x06,
|
0x54, 0x44, 0x48, 0xc6, 0x88, 0xfc, 0x40, 0x22, 0x9f, 0x0a, 0x88, 0x4d,
|
||||||
0x56, 0x05, 0x9f, 0x02, 0x8d, 0x25, 0xff, 0x3a, 0x00, 0x7f, 0x80, 0xdf,
|
0xc0, 0xd7, 0x16, 0x94, 0x67, 0x2b, 0x9f, 0xc4, 0x32, 0x26, 0x51, 0xe9,
|
||||||
0x12, 0x20, 0x69, 0x4f, 0x00, 0x76, 0xd9, 0x7d, 0x40, 0x08, 0x9a, 0xf0,
|
0x3b, 0x80, 0x3b, 0xcf, 0xb7, 0xe0, 0xab, 0x2f, 0x01, 0x78, 0xb1, 0x05,
|
||||||
0x01, 0x60, 0xa0, 0xbd, 0x3c, 0x00, 0x58, 0x45, 0x8b, 0xfd, 0x0c, 0x80,
|
0x4f, 0xbe, 0x00, 0xa0, 0xda, 0x82, 0xef, 0x89, 0xd1, 0x5c, 0xc9, 0x9d,
|
||||||
0x3f, 0xea, 0xdf, 0x2f, 0x05, 0xbe, 0xbe, 0xe8, 0xe7, 0x73, 0x78, 0x3e,
|
0x6f, 0x37, 0xb3, 0xbd, 0x0a, 0x9b, 0x55, 0xd5, 0x55, 0xf8, 0x8c, 0x4d,
|
||||||
0xe9, 0xe7, 0x7b, 0x69, 0x13, 0xf6, 0xe7, 0x4c, 0x3f, 0x06, 0x94, 0xa5,
|
0x5c, 0x02, 0x92, 0xdb, 0x7a, 0xc2, 0x26, 0xd5, 0x6d, 0x61, 0x28, 0xad,
|
||||||
0xb8, 0x05, 0xec, 0x10, 0x8e, 0xfb, 0x80, 0x56, 0x00, 0xdc, 0x7e, 0x3f,
|
0x6f, 0x0d, 0x0e, 0x50, 0xf6, 0xa6, 0x00, 0xb7, 0x82, 0xad, 0x73, 0x55,
|
||||||
0x54, 0x08, 0xc7, 0x13, 0x40, 0xc9, 0x78, 0x04, 0xa0, 0x39, 0x9e, 0x01,
|
0xb7, 0x85, 0xeb, 0xdb, 0xae, 0xaf, 0xfb, 0x50, 0xca, 0x0e, 0xf3, 0x65,
|
||||||
0xe5, 0x94, 0x53, 0x9f, 0xfd, 0x33, 0xf0, 0x3f, 0x53, 0x26, 0x87, 0x23,
|
0x78, 0x4e, 0xfa, 0x32, 0xe0, 0xd2, 0xc7, 0x80, 0x6a, 0x98, 0x92, 0xdb,
|
||||||
0x59, 0xac, 0x2b, 0x06, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44,
|
0x7a, 0x01, 0x89, 0x8b, 0x95, 0xbc, 0xd4, 0x78, 0xd2, 0xcf, 0x00, 0x93,
|
||||||
0xae, 0x42, 0x60, 0x82
|
0x7e, 0x38, 0xa0, 0x86, 0xa7, 0x96, 0x78, 0x9c, 0xff, 0xfe, 0x9c, 0xff,
|
||||||
|
0x04, 0xe2, 0xd8, 0x90, 0xc1, 0x18, 0xe1, 0xf4, 0x9b, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
|
||||||
};
|
};
|
||||||
|
|
||||||
const u32 TEXTURE_ATLAS_LENGTH = (u32)std::size(TEXTURE_ATLAS);
|
const u32 TEXTURE_ATLAS_LENGTH = (u32)std::size(TEXTURE_ATLAS);
|
||||||
const vec2 TEXTURE_ATLAS_SIZE = {96, 120};
|
const vec2 TEXTURE_ATLAS_SIZE = {96, 160};
|
||||||
|
|
||||||
enum AtlasType
|
enum AtlasType
|
||||||
{
|
{
|
||||||
@@ -118,8 +120,8 @@ enum AtlasType
|
|||||||
ATLAS_INVISIBLE,
|
ATLAS_INVISIBLE,
|
||||||
ATLAS_SHOW_RECT,
|
ATLAS_SHOW_RECT,
|
||||||
ATLAS_HIDE_RECT,
|
ATLAS_HIDE_RECT,
|
||||||
ATLAS_SHOW_TARGETS,
|
ATLAS_PLACEHOLDER,
|
||||||
ATLAS_HIDE_TARGETS,
|
ATLAS_PLACEHOLDER2,
|
||||||
ATLAS_PAN,
|
ATLAS_PAN,
|
||||||
ATLAS_MOVE,
|
ATLAS_MOVE,
|
||||||
ATLAS_ROTATE,
|
ATLAS_ROTATE,
|
||||||
@@ -145,6 +147,7 @@ enum AtlasType
|
|||||||
ATLAS_FRAME,
|
ATLAS_FRAME,
|
||||||
ATLAS_FRAME_ALT,
|
ATLAS_FRAME_ALT,
|
||||||
ATLAS_TARGET,
|
ATLAS_TARGET,
|
||||||
|
ATLAS_TARGET_ALT,
|
||||||
ATLAS_COUNT
|
ATLAS_COUNT
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -197,7 +200,8 @@ const inline AtlasEntry ATLAS_ENTRIES[ATLAS_COUNT] =
|
|||||||
{{ 0, 80}, ATLAS_SIZE_OBLONG},
|
{{ 0, 80}, ATLAS_SIZE_OBLONG},
|
||||||
{{16, 80}, ATLAS_SIZE_OBLONG},
|
{{16, 80}, ATLAS_SIZE_OBLONG},
|
||||||
{{32, 80}, ATLAS_SIZE_OBLONG},
|
{{32, 80}, ATLAS_SIZE_OBLONG},
|
||||||
{{48, 80}, ATLAS_SIZE_BIG}
|
{{48, 80}, ATLAS_SIZE_BIG},
|
||||||
|
{{48, 120}, ATLAS_SIZE_BIG}
|
||||||
};
|
};
|
||||||
|
|
||||||
#define ATLAS_POSITION(type) ATLAS_ENTRIES[type].position
|
#define ATLAS_POSITION(type) ATLAS_ENTRIES[type].position
|
||||||
|
12
src/anm2.cpp
12
src/anm2.cpp
@@ -54,8 +54,6 @@ bool anm2_serialize(Anm2* self, const std::string& path)
|
|||||||
|
|
||||||
for (auto& [id, spritesheet] : self->spritesheets)
|
for (auto& [id, spritesheet] : self->spritesheets)
|
||||||
{
|
{
|
||||||
if (id == ID_NONE) continue;
|
|
||||||
|
|
||||||
XMLElement* spritesheetElement;
|
XMLElement* spritesheetElement;
|
||||||
|
|
||||||
// Spritesheet
|
// Spritesheet
|
||||||
@@ -72,8 +70,6 @@ bool anm2_serialize(Anm2* self, const std::string& path)
|
|||||||
|
|
||||||
for (auto& [id, layer] : self->layers)
|
for (auto& [id, layer] : self->layers)
|
||||||
{
|
{
|
||||||
if (id == ID_NONE) continue;
|
|
||||||
|
|
||||||
XMLElement* layerElement;
|
XMLElement* layerElement;
|
||||||
|
|
||||||
// Layer
|
// Layer
|
||||||
@@ -92,8 +88,6 @@ bool anm2_serialize(Anm2* self, const std::string& path)
|
|||||||
|
|
||||||
for (auto& [id, null] : self->nulls)
|
for (auto& [id, null] : self->nulls)
|
||||||
{
|
{
|
||||||
if (id == ID_NONE) continue;
|
|
||||||
|
|
||||||
XMLElement* nullElement;
|
XMLElement* nullElement;
|
||||||
|
|
||||||
// Null
|
// Null
|
||||||
@@ -101,9 +95,9 @@ bool anm2_serialize(Anm2* self, const std::string& path)
|
|||||||
nullElement->SetAttribute(ANM2_ATTRIBUTE_STRINGS[ANM2_ATTRIBUTE_NAME], null.name.c_str()); // Name
|
nullElement->SetAttribute(ANM2_ATTRIBUTE_STRINGS[ANM2_ATTRIBUTE_NAME], null.name.c_str()); // Name
|
||||||
nullElement->SetAttribute(ANM2_ATTRIBUTE_STRINGS[ANM2_ATTRIBUTE_ID], id); // ID
|
nullElement->SetAttribute(ANM2_ATTRIBUTE_STRINGS[ANM2_ATTRIBUTE_ID], id); // ID
|
||||||
|
|
||||||
// special case; only serialize if this is true
|
|
||||||
if (null.isShowRect)
|
if (null.isShowRect)
|
||||||
nullElement->SetAttribute(ANM2_ATTRIBUTE_STRINGS[ANM2_ATTRIBUTE_SHOW_RECT], null.isShowRect); // ShowRect
|
nullElement->SetAttribute(ANM2_ATTRIBUTE_STRINGS[ANM2_ATTRIBUTE_SHOW_RECT], null.isShowRect); // ShowRect
|
||||||
|
|
||||||
nullsElement->InsertEndChild(nullElement);
|
nullsElement->InsertEndChild(nullElement);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -114,8 +108,6 @@ bool anm2_serialize(Anm2* self, const std::string& path)
|
|||||||
|
|
||||||
for (auto& [id, event] : self->events)
|
for (auto& [id, event] : self->events)
|
||||||
{
|
{
|
||||||
if (id == ID_NONE) continue;
|
|
||||||
|
|
||||||
XMLElement* eventElement;
|
XMLElement* eventElement;
|
||||||
|
|
||||||
// Event
|
// Event
|
||||||
@@ -137,8 +129,6 @@ bool anm2_serialize(Anm2* self, const std::string& path)
|
|||||||
|
|
||||||
for (auto& [id, animation] : self->animations)
|
for (auto& [id, animation] : self->animations)
|
||||||
{
|
{
|
||||||
if (id == ID_NONE) continue;
|
|
||||||
|
|
||||||
XMLElement* animationElement;
|
XMLElement* animationElement;
|
||||||
XMLElement* rootAnimationElement;
|
XMLElement* rootAnimationElement;
|
||||||
XMLElement* layerAnimationsElement;
|
XMLElement* layerAnimationsElement;
|
||||||
|
12
src/anm2.h
12
src/anm2.h
@@ -45,14 +45,16 @@
|
|||||||
X(TRIGGERS, "Triggers") \
|
X(TRIGGERS, "Triggers") \
|
||||||
X(TRIGGER, "Trigger")
|
X(TRIGGER, "Trigger")
|
||||||
|
|
||||||
typedef enum {
|
typedef enum
|
||||||
|
{
|
||||||
#define X(name, str) ANM2_ELEMENT_##name,
|
#define X(name, str) ANM2_ELEMENT_##name,
|
||||||
ANM2_ELEMENT_LIST
|
ANM2_ELEMENT_LIST
|
||||||
#undef X
|
#undef X
|
||||||
ANM2_ELEMENT_COUNT
|
ANM2_ELEMENT_COUNT
|
||||||
} Anm2Element;
|
} Anm2Element;
|
||||||
|
|
||||||
static const char* ANM2_ELEMENT_STRINGS[] = {
|
const inline char* ANM2_ELEMENT_STRINGS[] =
|
||||||
|
{
|
||||||
#define X(name, str) str,
|
#define X(name, str) str,
|
||||||
ANM2_ELEMENT_LIST
|
ANM2_ELEMENT_LIST
|
||||||
#undef X
|
#undef X
|
||||||
@@ -259,6 +261,12 @@ enum Anm2ChangeType
|
|||||||
ANM2_CHANGE_SET
|
ANM2_CHANGE_SET
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum OnionskinDrawOrder
|
||||||
|
{
|
||||||
|
ONIONSKIN_BELOW,
|
||||||
|
ONIONSKIN_ABOVE
|
||||||
|
};
|
||||||
|
|
||||||
void anm2_layer_add(Anm2* self);
|
void anm2_layer_add(Anm2* self);
|
||||||
void anm2_layer_remove(Anm2* self, s32 id);
|
void anm2_layer_remove(Anm2* self, s32 id);
|
||||||
void anm2_null_add(Anm2* self);
|
void anm2_null_add(Anm2* self);
|
||||||
|
@@ -5,13 +5,12 @@
|
|||||||
#define CANVAS_ZOOM_MIN 1.0f
|
#define CANVAS_ZOOM_MIN 1.0f
|
||||||
#define CANVAS_ZOOM_MAX 2000.0f
|
#define CANVAS_ZOOM_MAX 2000.0f
|
||||||
#define CANVAS_ZOOM_DEFAULT 100.0f
|
#define CANVAS_ZOOM_DEFAULT 100.0f
|
||||||
#define CANVAS_ZOOM_STEP 10.0f
|
#define CANVAS_ZOOM_STEP 100.0f
|
||||||
#define CANVAS_ZOOM_MOD 10.0f
|
|
||||||
#define CANVAS_GRID_MIN 1
|
#define CANVAS_GRID_MIN 1
|
||||||
#define CANVAS_GRID_MAX 1000
|
#define CANVAS_GRID_MAX 1000
|
||||||
#define CANVAS_GRID_DEFAULT 32
|
#define CANVAS_GRID_DEFAULT 32
|
||||||
|
|
||||||
const inline vec2 CANVAS_PIVOT_SIZE = {8, 8};
|
const inline vec2 CANVAS_PIVOT_SIZE = {4, 4};
|
||||||
const inline vec2 CANVAS_SCALE_DEFAULT = {1.0f, 1.0f};
|
const inline vec2 CANVAS_SCALE_DEFAULT = {1.0f, 1.0f};
|
||||||
|
|
||||||
const inline f32 CANVAS_AXIS_VERTICES[] = {-1.0f, 1.0f};
|
const inline f32 CANVAS_AXIS_VERTICES[] = {-1.0f, 1.0f};
|
||||||
|
@@ -7,7 +7,6 @@ static void _clipboard_item_remove(ClipboardItem* self, Anm2* anm2)
|
|||||||
case CLIPBOARD_FRAME:
|
case CLIPBOARD_FRAME:
|
||||||
{
|
{
|
||||||
Anm2FrameWithReference* frameWithReference = std::get_if<Anm2FrameWithReference>(&self->data);
|
Anm2FrameWithReference* frameWithReference = std::get_if<Anm2FrameWithReference>(&self->data);
|
||||||
|
|
||||||
if (!frameWithReference) break;
|
if (!frameWithReference) break;
|
||||||
|
|
||||||
anm2_frame_erase(anm2, &frameWithReference->reference);
|
anm2_frame_erase(anm2, &frameWithReference->reference);
|
||||||
@@ -16,7 +15,6 @@ static void _clipboard_item_remove(ClipboardItem* self, Anm2* anm2)
|
|||||||
case CLIPBOARD_ANIMATION:
|
case CLIPBOARD_ANIMATION:
|
||||||
{
|
{
|
||||||
Anm2AnimationWithID* animationWithID = std::get_if<Anm2AnimationWithID>(&self->data);
|
Anm2AnimationWithID* animationWithID = std::get_if<Anm2AnimationWithID>(&self->data);
|
||||||
|
|
||||||
if (!animationWithID) break;
|
if (!animationWithID) break;
|
||||||
|
|
||||||
for (auto & [id, animation] : anm2->animations)
|
for (auto & [id, animation] : anm2->animations)
|
||||||
@@ -58,7 +56,6 @@ static void _clipboard_item_paste(ClipboardItem* self, ClipboardLocation* locati
|
|||||||
case CLIPBOARD_ANIMATION:
|
case CLIPBOARD_ANIMATION:
|
||||||
{
|
{
|
||||||
Anm2AnimationWithID* animationWithID = std::get_if<Anm2AnimationWithID>(&self->data);
|
Anm2AnimationWithID* animationWithID = std::get_if<Anm2AnimationWithID>(&self->data);
|
||||||
|
|
||||||
if (!animationWithID) break;
|
if (!animationWithID) break;
|
||||||
|
|
||||||
s32 index = 0;
|
s32 index = 0;
|
||||||
|
206
src/imgui.cpp
206
src/imgui.cpp
@@ -1,5 +1,15 @@
|
|||||||
#include "imgui.h"
|
#include "imgui.h"
|
||||||
|
|
||||||
|
static bool _imgui_chord_pressed(ImGuiKeyChord chord)
|
||||||
|
{
|
||||||
|
if (chord == IMGUI_CHORD_NONE) return false;
|
||||||
|
ImGuiKey key = (ImGuiKey)(chord & ~ImGuiMod_Mask_);
|
||||||
|
if (key == ImGuiKey_None) return false;
|
||||||
|
if (key < ImGuiKey_NamedKey_BEGIN || key >= ImGuiKey_NamedKey_END) return false;
|
||||||
|
|
||||||
|
return ImGui::IsKeyChordPressed(chord);
|
||||||
|
}
|
||||||
|
|
||||||
static const char* _imgui_f32_format_get(const ImguiItem& item, f32& value)
|
static const char* _imgui_f32_format_get(const ImguiItem& item, f32& value)
|
||||||
{
|
{
|
||||||
if (item.isEmptyFormat) return "";
|
if (item.isEmptyFormat) return "";
|
||||||
@@ -38,7 +48,6 @@ static void _imgui_anm2_open(Imgui* self, const std::string& path)
|
|||||||
if (anm2_deserialize(self->anm2, path))
|
if (anm2_deserialize(self->anm2, path))
|
||||||
{
|
{
|
||||||
window_title_from_path_set(self->window, path);
|
window_title_from_path_set(self->window, path);
|
||||||
snapshots_reset(self->snapshots);
|
|
||||||
imgui_log_push(self, std::format(IMGUI_LOG_FILE_OPEN_FORMAT, path));
|
imgui_log_push(self, std::format(IMGUI_LOG_FILE_OPEN_FORMAT, path));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -152,6 +161,7 @@ static void _imgui_item_pre(const ImguiItem& self, ImguiItemType type)
|
|||||||
break;
|
break;
|
||||||
case IMGUI_INPUT_INT:
|
case IMGUI_INPUT_INT:
|
||||||
case IMGUI_INPUT_TEXT:
|
case IMGUI_INPUT_TEXT:
|
||||||
|
case IMGUI_INPUT_FLOAT:
|
||||||
case IMGUI_DRAG_FLOAT:
|
case IMGUI_DRAG_FLOAT:
|
||||||
case IMGUI_SLIDER_FLOAT:
|
case IMGUI_SLIDER_FLOAT:
|
||||||
case IMGUI_COLOR_EDIT:
|
case IMGUI_COLOR_EDIT:
|
||||||
@@ -178,6 +188,16 @@ static void _imgui_item_pre(const ImguiItem& self, ImguiItemType type)
|
|||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
if (self.is_hotkey())
|
||||||
|
{
|
||||||
|
std::string chordString = imgui_string_from_chord_get(imgui->hotkeys[self.hotkey]);
|
||||||
|
if (isShortcutInLabel)
|
||||||
|
label += std::format(IMGUI_LABEL_SHORTCUT_FORMAT, chordString);
|
||||||
|
tooltip += std::format(IMGUI_TOOLTIP_SHORTCUT_FORMAT, chordString);
|
||||||
|
}
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _imgui_item_post(const ImguiItem& self, Imgui* imgui, ImguiItemType type, bool& isActivated)
|
static void _imgui_item_post(const ImguiItem& self, Imgui* imgui, ImguiItemType type, bool& isActivated)
|
||||||
@@ -201,7 +221,7 @@ static void _imgui_item_post(const ImguiItem& self, Imgui* imgui, ImguiItemType
|
|||||||
ImU32 color = ImGui::GetColorU32(ImGuiCol_Text);
|
ImU32 color = ImGui::GetColorU32(ImGuiCol_Text);
|
||||||
ImGui::GetWindowDrawList()->AddLine(lineStart, lineEnd, color, 1.0f);
|
ImGui::GetWindowDrawList()->AddLine(lineStart, lineEnd, color, 1.0f);
|
||||||
|
|
||||||
if (ImGui::IsKeyChordPressed(ImGuiMod_Alt | self.mnemonicKey))
|
if (_imgui_chord_pressed(ImGuiMod_Alt | self.mnemonicKey))
|
||||||
{
|
{
|
||||||
if (!self.isDisabled) isActivated = true;
|
if (!self.isDisabled) isActivated = true;
|
||||||
imgui_close_current_popup(imgui);
|
imgui_close_current_popup(imgui);
|
||||||
@@ -210,20 +230,20 @@ static void _imgui_item_post(const ImguiItem& self, Imgui* imgui, ImguiItemType
|
|||||||
|
|
||||||
if (self.isUseItemActivated && !self.isDisabled) isActivated = ImGui::IsItemActivated();
|
if (self.isUseItemActivated && !self.isDisabled) isActivated = ImGui::IsItemActivated();
|
||||||
|
|
||||||
if (imgui->isContextualActionsEnabled && (self.is_chord() && ImGui::IsKeyChordPressed(self.chord)))
|
if
|
||||||
if (self.is_focus_window() && (imgui_window_get() == self.focusWindow))
|
(
|
||||||
if (!self.isDisabled) isActivated = true;
|
imgui->isContextualActionsEnabled && _imgui_chord_pressed(self.chord_get()) &&
|
||||||
|
self.is_focus_window() && (imgui_window_get() == self.focusWindow)
|
||||||
|
)
|
||||||
|
if (!self.isDisabled) isActivated = true;
|
||||||
|
|
||||||
if (self.is_tooltip() && ImGui::IsItemHovered(ImGuiHoveredFlags_DelayNormal))
|
if (self.is_tooltip() && ImGui::IsItemHovered(ImGuiHoveredFlags_DelayNormal))
|
||||||
ImGui::SetTooltip(self.tooltip.c_str());
|
ImGui::SetTooltip(self.tooltip.c_str());
|
||||||
|
|
||||||
if (isActivated)
|
if (isActivated)
|
||||||
{
|
{
|
||||||
if (self.is_undoable())
|
if (self.is_undoable()) imgui_snapshot(imgui, self.snapshotAction);
|
||||||
imgui_snapshot(imgui, self.snapshotAction);
|
if (self.is_function()) self.function(imgui);
|
||||||
|
|
||||||
if (self.function)
|
|
||||||
self.function(imgui);
|
|
||||||
|
|
||||||
if (self.is_popup())
|
if (self.is_popup())
|
||||||
{
|
{
|
||||||
@@ -372,6 +392,8 @@ static bool NAME(const ImguiItem& self, Imgui* imgui, bool& boolValue)
|
|||||||
ImguiItem checkboxItem = self.copy \
|
ImguiItem checkboxItem = self.copy \
|
||||||
({.label = std::format(IMGUI_INVISIBLE_FORMAT, self.label), .isMnemonicDisabled = true}); \
|
({.label = std::format(IMGUI_INVISIBLE_FORMAT, self.label), .isMnemonicDisabled = true}); \
|
||||||
checkboxItem.isDisabled = false; \
|
checkboxItem.isDisabled = false; \
|
||||||
|
checkboxItem.isSeparator = false; \
|
||||||
|
checkboxItem.value = 0; \
|
||||||
bool isCheckboxActivated = _imgui_checkbox(checkboxItem, imgui, boolValue); \
|
bool isCheckboxActivated = _imgui_checkbox(checkboxItem, imgui, boolValue); \
|
||||||
ImGui::SameLine(); \
|
ImGui::SameLine(); \
|
||||||
bool isActivated = ([&] { return FUNCTION; })(); \
|
bool isActivated = ([&] { return FUNCTION; })(); \
|
||||||
@@ -386,6 +408,18 @@ static bool NAME(const ImguiItem& self, Imgui* imgui, VALUE& value, bool& boolVa
|
|||||||
ImguiItem checkboxItem = self.copy \
|
ImguiItem checkboxItem = self.copy \
|
||||||
({.label = std::format(IMGUI_INVISIBLE_FORMAT, self.label), .isMnemonicDisabled = true}); \
|
({.label = std::format(IMGUI_INVISIBLE_FORMAT, self.label), .isMnemonicDisabled = true}); \
|
||||||
checkboxItem.isDisabled = false; \
|
checkboxItem.isDisabled = false; \
|
||||||
|
checkboxItem.isSeparator = false; \
|
||||||
|
checkboxItem.value = 0; \
|
||||||
|
bool isCheckboxActivated = _imgui_checkbox(checkboxItem, imgui, boolValue); \
|
||||||
|
ImGui::SameLine(); \
|
||||||
|
bool isActivated = ([&](VALUE& value) { return FUNCTION; })(value); \
|
||||||
|
if (isCheckboxActivated) isActivated = true; \
|
||||||
|
return isActivated; \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define IMGUI_ITEM_AND_CHECKBOX_FUNCTION(NAME, VALUE, FUNCTION) \
|
||||||
|
static bool NAME(const ImguiItem& self, const ImguiItem& checkboxItem, Imgui* imgui, VALUE& value, bool& boolValue) \
|
||||||
|
{ \
|
||||||
bool isCheckboxActivated = _imgui_checkbox(checkboxItem, imgui, boolValue); \
|
bool isCheckboxActivated = _imgui_checkbox(checkboxItem, imgui, boolValue); \
|
||||||
ImGui::SameLine(); \
|
ImGui::SameLine(); \
|
||||||
bool isActivated = ([&](VALUE& value) { return FUNCTION; })(value); \
|
bool isActivated = ([&](VALUE& value) { return FUNCTION; })(value); \
|
||||||
@@ -403,6 +437,12 @@ IMGUI_ITEM_FUNCTION(_imgui_begin_child, IMGUI_CHILD, ImGui::BeginChild(self.labe
|
|||||||
static void _imgui_end_child(void) {ImGui::EndChild(); }
|
static void _imgui_end_child(void) {ImGui::EndChild(); }
|
||||||
IMGUI_ITEM_VOID_FUNCTION(_imgui_text, IMGUI_TEXT, ImGui::Text(self.label_get()));
|
IMGUI_ITEM_VOID_FUNCTION(_imgui_text, IMGUI_TEXT, ImGui::Text(self.label_get()));
|
||||||
IMGUI_ITEM_FUNCTION(_imgui_button, IMGUI_BUTTON, ImGui::Button(self.label_get(), _imgui_item_size_get(self, type)));
|
IMGUI_ITEM_FUNCTION(_imgui_button, IMGUI_BUTTON, ImGui::Button(self.label_get(), _imgui_item_size_get(self, type)));
|
||||||
|
IMGUI_ITEM_FUNCTION(_imgui_begin_table, IMGUI_TABLE, ImGui::BeginTable(self.label_get(), self.value, self.flags));
|
||||||
|
static void _imgui_end_table(void) {ImGui::EndTable(); }
|
||||||
|
static void _imgui_table_setup_column(const char* text) {ImGui::TableSetupColumn(text); }
|
||||||
|
static void _imgui_table_headers_row(void) {ImGui::TableHeadersRow(); }
|
||||||
|
static void _imgui_table_next_row(void) {ImGui::TableNextRow(); }
|
||||||
|
static void _imgui_table_set_column_index(s32 index) {ImGui::TableSetColumnIndex(index); }
|
||||||
IMGUI_ITEM_FUNCTION(_imgui_selectable, IMGUI_SELECTABLE, ImGui::Selectable(self.label_get(), self.isSelected, self.flags, _imgui_item_size_get(self, type)));
|
IMGUI_ITEM_FUNCTION(_imgui_selectable, IMGUI_SELECTABLE, ImGui::Selectable(self.label_get(), self.isSelected, self.flags, _imgui_item_size_get(self, type)));
|
||||||
IMGUI_ITEM_VALUE_FUNCTION(_imgui_radio_button, IMGUI_RADIO_BUTTON, s32, ImGui::RadioButton(self.label_get(), &value, self.value));
|
IMGUI_ITEM_VALUE_FUNCTION(_imgui_radio_button, IMGUI_RADIO_BUTTON, s32, ImGui::RadioButton(self.label_get(), &value, self.value));
|
||||||
IMGUI_ITEM_VALUE_FUNCTION(_imgui_color_button, IMGUI_COLOR_BUTTON, vec4, ImGui::ColorButton(self.label_get(), ImVec4(value), self.flags));
|
IMGUI_ITEM_VALUE_FUNCTION(_imgui_color_button, IMGUI_COLOR_BUTTON, vec4, ImGui::ColorButton(self.label_get(), ImVec4(value), self.flags));
|
||||||
@@ -1264,6 +1304,40 @@ static void _imgui_timeline(Imgui* self)
|
|||||||
_imgui_end(); // IMGUI_TIMELINE
|
_imgui_end(); // IMGUI_TIMELINE
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void _imgui_onionskin(Imgui* self)
|
||||||
|
{
|
||||||
|
IMGUI_BEGIN_OR_RETURN(IMGUI_ONIONSKIN, self);
|
||||||
|
|
||||||
|
static auto& isEnabled = self->settings->onionskinIsEnabled;
|
||||||
|
static auto& beforeCount = self->settings->onionskinBeforeCount;
|
||||||
|
static auto& afterCount = self->settings->onionskinAfterCount;
|
||||||
|
static auto& beforeColorOffset = self->settings->onionskinBeforeColorOffset;
|
||||||
|
static auto& afterColorOffset = self->settings->onionskinAfterColorOffset;
|
||||||
|
static auto& drawOrder = self->settings->onionskinDrawOrder;
|
||||||
|
|
||||||
|
_imgui_checkbox(IMGUI_ONIONSKIN_ENABLED, self, isEnabled);
|
||||||
|
|
||||||
|
auto onionskin_section = [&](auto& text, auto& count, auto& colorOffset)
|
||||||
|
{
|
||||||
|
ImGui::PushID(text.label.c_str());
|
||||||
|
_imgui_text(text, self);
|
||||||
|
_imgui_input_int(IMGUI_ONIONSKIN_COUNT.copy({!isEnabled}), self, count);
|
||||||
|
_imgui_color_edit3(IMGUI_ONIONSKIN_COLOR_OFFSET.copy({!isEnabled}), self, colorOffset);
|
||||||
|
ImGui::PopID();
|
||||||
|
};
|
||||||
|
|
||||||
|
onionskin_section(IMGUI_ONIONSKIN_BEFORE, beforeCount, beforeColorOffset);
|
||||||
|
onionskin_section(IMGUI_ONIONSKIN_AFTER, afterCount, afterColorOffset);
|
||||||
|
|
||||||
|
ImGui::Separator();
|
||||||
|
|
||||||
|
_imgui_text(IMGUI_ONIONSKIN_DRAW_ORDER, self);
|
||||||
|
_imgui_radio_button(IMGUI_ONIONSKIN_BELOW.copy({!isEnabled}), self, drawOrder);
|
||||||
|
_imgui_radio_button(IMGUI_ONIONSKIN_ABOVE.copy({!isEnabled}), self, drawOrder);
|
||||||
|
|
||||||
|
_imgui_end(); // IMGUI_ONIONSKIN
|
||||||
|
}
|
||||||
|
|
||||||
static void _imgui_taskbar(Imgui* self)
|
static void _imgui_taskbar(Imgui* self)
|
||||||
{
|
{
|
||||||
static ImguiPopupState exitConfirmState = IMGUI_POPUP_STATE_CLOSED;
|
static ImguiPopupState exitConfirmState = IMGUI_POPUP_STATE_CLOSED;
|
||||||
@@ -1277,15 +1351,15 @@ static void _imgui_taskbar(Imgui* self)
|
|||||||
Anm2Animation* animation = anm2_animation_from_reference(self->anm2, self->reference);
|
Anm2Animation* animation = anm2_animation_from_reference(self->anm2, self->reference);
|
||||||
Anm2Item* item = anm2_item_from_reference(self->anm2, self->reference);
|
Anm2Item* item = anm2_item_from_reference(self->anm2, self->reference);
|
||||||
|
|
||||||
_imgui_selectable(IMGUI_FILE.copy({}), self);
|
_imgui_selectable(IMGUI_FILE, self);
|
||||||
|
|
||||||
if (imgui_begin_popup(IMGUI_FILE.popup, self))
|
if (imgui_begin_popup(IMGUI_FILE.popup, self))
|
||||||
{
|
{
|
||||||
_imgui_selectable(IMGUI_NEW, self);
|
_imgui_selectable(IMGUI_NEW.copy({self->anm2->path.empty()}), self);
|
||||||
_imgui_selectable(IMGUI_OPEN, self);
|
_imgui_selectable(IMGUI_OPEN, self);
|
||||||
_imgui_selectable(IMGUI_SAVE, self);
|
_imgui_selectable(IMGUI_SAVE.copy({self->anm2->path.empty()}), self);
|
||||||
_imgui_selectable(IMGUI_SAVE_AS, self);
|
_imgui_selectable(IMGUI_SAVE_AS.copy({self->anm2->path.empty()}), self);
|
||||||
_imgui_selectable(IMGUI_EXPLORE_ANM2_LOCATION, self);
|
_imgui_selectable(IMGUI_EXPLORE_ANM2_LOCATION.copy({self->anm2->path.empty()}), self);
|
||||||
_imgui_selectable(IMGUI_EXIT, self);
|
_imgui_selectable(IMGUI_EXIT, self);
|
||||||
imgui_end_popup(self);
|
imgui_end_popup(self);
|
||||||
}
|
}
|
||||||
@@ -1440,6 +1514,7 @@ static void _imgui_taskbar(Imgui* self)
|
|||||||
_imgui_checkbox_color_edit4(IMGUI_FRAME_PROPERTIES_TINT.copy({!isTint}), self, tint, isTint);
|
_imgui_checkbox_color_edit4(IMGUI_FRAME_PROPERTIES_TINT.copy({!isTint}), self, tint, isTint);
|
||||||
_imgui_checkbox_color_edit3(IMGUI_FRAME_PROPERTIES_COLOR_OFFSET.copy({!isColorOffset}), self, colorOffset, isColorOffset);
|
_imgui_checkbox_color_edit3(IMGUI_FRAME_PROPERTIES_COLOR_OFFSET.copy({!isColorOffset}), self, colorOffset, isColorOffset);
|
||||||
_imgui_checkbox_checkbox(IMGUI_FRAME_PROPERTIES_VISIBLE.copy({!isVisibleSet}), self, isVisible, isVisibleSet);
|
_imgui_checkbox_checkbox(IMGUI_FRAME_PROPERTIES_VISIBLE.copy({!isVisibleSet}), self, isVisible, isVisibleSet);
|
||||||
|
ImGui::NewLine();
|
||||||
_imgui_checkbox_checkbox(IMGUI_FRAME_PROPERTIES_INTERPOLATED.copy({!isInterpolatedSet}), self, isInterpolated, isInterpolatedSet);
|
_imgui_checkbox_checkbox(IMGUI_FRAME_PROPERTIES_INTERPOLATED.copy({!isInterpolatedSet}), self, isInterpolated, isInterpolatedSet);
|
||||||
_imgui_end_child(); // IMGUI_FOOTER_CHILD
|
_imgui_end_child(); // IMGUI_FOOTER_CHILD
|
||||||
|
|
||||||
@@ -1658,10 +1733,76 @@ static void _imgui_taskbar(Imgui* self)
|
|||||||
if (imgui_begin_popup(IMGUI_SETTINGS.popup, self, IMGUI_SETTINGS.popupSize))
|
if (imgui_begin_popup(IMGUI_SETTINGS.popup, self, IMGUI_SETTINGS.popupSize))
|
||||||
{
|
{
|
||||||
if (_imgui_checkbox_selectable(IMGUI_VSYNC, self, self->settings->isVsync)) window_vsync_set(self->settings->isVsync);
|
if (_imgui_checkbox_selectable(IMGUI_VSYNC, self, self->settings->isVsync)) window_vsync_set(self->settings->isVsync);
|
||||||
|
_imgui_selectable(IMGUI_HOTKEYS, self);
|
||||||
if (_imgui_selectable(IMGUI_DEFAULT_SETTINGS, self)) *self->settings = Settings();
|
if (_imgui_selectable(IMGUI_DEFAULT_SETTINGS, self)) *self->settings = Settings();
|
||||||
imgui_end_popup(self);
|
imgui_end_popup(self);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (imgui_begin_popup_modal(IMGUI_HOTKEYS.popup, self, IMGUI_HOTKEYS.popupSize))
|
||||||
|
{
|
||||||
|
_imgui_begin_child(IMGUI_HOTKEYS_CHILD, self);
|
||||||
|
|
||||||
|
if (_imgui_begin_table(IMGUI_HOTKEYS_TABLE, self))
|
||||||
|
{
|
||||||
|
static s32 selectedIndex = INDEX_NONE;
|
||||||
|
|
||||||
|
_imgui_table_setup_column(IMGUI_HOTKEYS_FUNCTION);
|
||||||
|
_imgui_table_setup_column(IMGUI_HOTKEYS_HOTKEY);
|
||||||
|
_imgui_table_headers_row();
|
||||||
|
|
||||||
|
for (s32 i = 0; i < HOTKEY_COUNT; i++)
|
||||||
|
{
|
||||||
|
if (!SETTINGS_HOTKEY_MEMBERS[i]) continue;
|
||||||
|
|
||||||
|
bool isSelected = selectedIndex == i;
|
||||||
|
const char* string = HOTKEY_STRINGS[i];
|
||||||
|
std::string* settingString = &(self->settings->*SETTINGS_HOTKEY_MEMBERS[i]);
|
||||||
|
std::string chordString = isSelected ? IMGUI_HOTKEY_CHANGE : *settingString;
|
||||||
|
|
||||||
|
ImGui::PushID(i);
|
||||||
|
_imgui_table_next_row();
|
||||||
|
_imgui_table_set_column_index(0);
|
||||||
|
ImGui::TextUnformatted(string);
|
||||||
|
_imgui_table_set_column_index(1);
|
||||||
|
|
||||||
|
if (ImGui::Selectable(chordString.c_str(), isSelected)) selectedIndex = i;
|
||||||
|
ImGui::PopID();
|
||||||
|
|
||||||
|
if (isSelected)
|
||||||
|
{
|
||||||
|
ImGuiKeyChord chord = IMGUI_CHORD_NONE;
|
||||||
|
|
||||||
|
if (ImGui::IsKeyDown(ImGuiMod_Ctrl)) chord |= ImGuiMod_Ctrl;
|
||||||
|
if (ImGui::IsKeyDown(ImGuiMod_Shift)) chord |= ImGuiMod_Shift;
|
||||||
|
if (ImGui::IsKeyDown(ImGuiMod_Alt)) chord |= ImGuiMod_Alt;
|
||||||
|
if (ImGui::IsKeyDown(ImGuiMod_Super)) chord |= ImGuiMod_Super;
|
||||||
|
|
||||||
|
for (auto& [_, key] : IMGUI_KEY_MAP)
|
||||||
|
{
|
||||||
|
if (ImGui::IsKeyPressed(key))
|
||||||
|
{
|
||||||
|
chord |= key;
|
||||||
|
imgui_hotkey_chord_registry()[i] = chord;
|
||||||
|
*settingString = imgui_string_from_chord_get(chord);
|
||||||
|
selectedIndex = INDEX_NONE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_imgui_end_table();
|
||||||
|
}
|
||||||
|
|
||||||
|
_imgui_end_child(); // IMGUI_HOTKEYS_CHILD;
|
||||||
|
|
||||||
|
_imgui_begin_child(IMGUI_HOTKEYS_OPTIONS_CHILD, self);
|
||||||
|
if (_imgui_button(IMGUI_HOTKEYS_CONFIRM, self)) imgui_close_current_popup(self);
|
||||||
|
_imgui_end_child(); // IMGUI_HOTKEYS_OPTIONS_CHILD
|
||||||
|
|
||||||
|
imgui_end_popup(self);
|
||||||
|
}
|
||||||
|
|
||||||
_imgui_end();
|
_imgui_end();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2156,7 +2297,7 @@ static void _imgui_animation_preview(Imgui* self)
|
|||||||
|
|
||||||
_imgui_begin_child(IMGUI_CANVAS_VIEW_CHILD, self);
|
_imgui_begin_child(IMGUI_CANVAS_VIEW_CHILD, self);
|
||||||
_imgui_drag_float(IMGUI_CANVAS_ZOOM, self, zoom);
|
_imgui_drag_float(IMGUI_CANVAS_ZOOM, self, zoom);
|
||||||
if (_imgui_button(IMGUI_CANVAS_CENTER_VIEW.copy({pan == vec2()}), self)) pan = vec2();
|
if (_imgui_button(IMGUI_ANIMATION_PREVIEW_CENTER_VIEW.copy({pan == vec2()}), self)) pan = vec2();
|
||||||
ImGui::Text(mousePositionString.c_str());
|
ImGui::Text(mousePositionString.c_str());
|
||||||
_imgui_end_child(); //IMGUI_CANVAS_VIEW_CHILD
|
_imgui_end_child(); //IMGUI_CANVAS_VIEW_CHILD
|
||||||
|
|
||||||
@@ -2194,6 +2335,8 @@ static void _imgui_animation_preview(Imgui* self)
|
|||||||
_imgui_checkbox(IMGUI_CANVAS_AXES, self, self->settings->previewIsAxes);
|
_imgui_checkbox(IMGUI_CANVAS_AXES, self, self->settings->previewIsAxes);
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
_imgui_color_edit4(IMGUI_CANVAS_AXES_COLOR, self, self->settings->previewAxesColor);
|
_imgui_color_edit4(IMGUI_CANVAS_AXES_COLOR, self, self->settings->previewAxesColor);
|
||||||
|
ImGui::SameLine();
|
||||||
|
_imgui_checkbox(IMGUI_CANVAS_ALT_ICONS, self, self->settings->previewIsAltIcons);
|
||||||
_imgui_checkbox(IMGUI_CANVAS_ROOT_TRANSFORM, self, self->settings->previewIsRootTransform);
|
_imgui_checkbox(IMGUI_CANVAS_ROOT_TRANSFORM, self, self->settings->previewIsRootTransform);
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
_imgui_checkbox(IMGUI_CANVAS_TRIGGERS, self, self->settings->previewIsTriggers);
|
_imgui_checkbox(IMGUI_CANVAS_TRIGGERS, self, self->settings->previewIsTriggers);
|
||||||
@@ -2241,8 +2384,8 @@ static void _imgui_animation_preview(Imgui* self)
|
|||||||
const bool isUp = ImGui::IsKeyPressed(IMGUI_INPUT_UP);
|
const bool isUp = ImGui::IsKeyPressed(IMGUI_INPUT_UP);
|
||||||
const bool isDown = ImGui::IsKeyPressed(IMGUI_INPUT_DOWN);
|
const bool isDown = ImGui::IsKeyPressed(IMGUI_INPUT_DOWN);
|
||||||
const bool isMod = ImGui::IsKeyDown(IMGUI_INPUT_SHIFT);
|
const bool isMod = ImGui::IsKeyDown(IMGUI_INPUT_SHIFT);
|
||||||
const bool isZoomIn = ImGui::IsKeyPressed(IMGUI_INPUT_ZOOM_IN);
|
const bool isZoomIn = _imgui_chord_pressed(imgui_hotkey_chord_registry()[HOTKEY_ZOOM_IN]);
|
||||||
const bool isZoomOut = ImGui::IsKeyPressed(IMGUI_INPUT_ZOOM_OUT);
|
const bool isZoomOut = _imgui_chord_pressed(imgui_hotkey_chord_registry()[HOTKEY_ZOOM_OUT]);
|
||||||
const bool isMouseClick = ImGui::IsMouseClicked(ImGuiMouseButton_Left);
|
const bool isMouseClick = ImGui::IsMouseClicked(ImGuiMouseButton_Left);
|
||||||
const bool isMouseDown = ImGui::IsMouseDown(ImGuiMouseButton_Left);
|
const bool isMouseDown = ImGui::IsMouseDown(ImGuiMouseButton_Left);
|
||||||
const bool isMouseMiddleDown = ImGui::IsMouseDown(ImGuiMouseButton_Middle);
|
const bool isMouseMiddleDown = ImGui::IsMouseDown(ImGuiMouseButton_Middle);
|
||||||
@@ -2306,7 +2449,6 @@ static void _imgui_animation_preview(Imgui* self)
|
|||||||
if (mouseWheel != 0 || isZoomIn || isZoomOut)
|
if (mouseWheel != 0 || isZoomIn || isZoomOut)
|
||||||
{
|
{
|
||||||
f32 delta = (mouseWheel > 0 || isZoomIn) ? CANVAS_ZOOM_STEP : -CANVAS_ZOOM_STEP;
|
f32 delta = (mouseWheel > 0 || isZoomIn) ? CANVAS_ZOOM_STEP : -CANVAS_ZOOM_STEP;
|
||||||
delta = isMod ? delta * CANVAS_ZOOM_MOD : delta;
|
|
||||||
zoom = std::clamp(ROUND_NEAREST_MULTIPLE(zoom + delta, CANVAS_ZOOM_STEP), CANVAS_ZOOM_MIN, CANVAS_ZOOM_MAX);
|
zoom = std::clamp(ROUND_NEAREST_MULTIPLE(zoom + delta, CANVAS_ZOOM_STEP), CANVAS_ZOOM_MIN, CANVAS_ZOOM_MAX);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2340,7 +2482,7 @@ static void _imgui_spritesheet_editor(Imgui* self)
|
|||||||
|
|
||||||
_imgui_begin_child(IMGUI_CANVAS_VIEW_CHILD, self);
|
_imgui_begin_child(IMGUI_CANVAS_VIEW_CHILD, self);
|
||||||
_imgui_drag_float(IMGUI_CANVAS_ZOOM, self, zoom);
|
_imgui_drag_float(IMGUI_CANVAS_ZOOM, self, zoom);
|
||||||
if (_imgui_button(IMGUI_CANVAS_CENTER_VIEW.copy({pan == vec2()}), self)) pan = vec2();
|
if (_imgui_button(IMGUI_SPRITESHEET_EDITOR_CENTER_VIEW.copy({pan == vec2()}), self)) pan = vec2();
|
||||||
ImGui::Text(mousePositionString.c_str());
|
ImGui::Text(mousePositionString.c_str());
|
||||||
_imgui_end_child(); // IMGUI_CANVAS_VIEW_CHILD
|
_imgui_end_child(); // IMGUI_CANVAS_VIEW_CHILD
|
||||||
|
|
||||||
@@ -2371,9 +2513,8 @@ static void _imgui_spritesheet_editor(Imgui* self)
|
|||||||
const bool isMouseClick = ImGui::IsMouseClicked(ImGuiMouseButton_Left);
|
const bool isMouseClick = ImGui::IsMouseClicked(ImGuiMouseButton_Left);
|
||||||
const bool isMouseDown = ImGui::IsMouseDown(ImGuiMouseButton_Left);
|
const bool isMouseDown = ImGui::IsMouseDown(ImGuiMouseButton_Left);
|
||||||
const bool isMouseMiddleDown = ImGui::IsMouseDown(ImGuiMouseButton_Middle);
|
const bool isMouseMiddleDown = ImGui::IsMouseDown(ImGuiMouseButton_Middle);
|
||||||
const bool isZoomIn = ImGui::IsKeyPressed(IMGUI_INPUT_ZOOM_IN);
|
const bool isZoomIn = _imgui_chord_pressed(imgui_hotkey_chord_registry()[HOTKEY_ZOOM_IN]);
|
||||||
const bool isZoomOut = ImGui::IsKeyPressed(IMGUI_INPUT_ZOOM_OUT);
|
const bool isZoomOut = _imgui_chord_pressed(imgui_hotkey_chord_registry()[HOTKEY_ZOOM_OUT]);
|
||||||
const bool isMod = ImGui::IsKeyDown(IMGUI_INPUT_SHIFT);
|
|
||||||
const f32 mouseWheel = ImGui::GetIO().MouseWheel;
|
const f32 mouseWheel = ImGui::GetIO().MouseWheel;
|
||||||
const ImVec2 mouseDelta = ImGui::GetIO().MouseDelta;
|
const ImVec2 mouseDelta = ImGui::GetIO().MouseDelta;
|
||||||
|
|
||||||
@@ -2442,7 +2583,6 @@ static void _imgui_spritesheet_editor(Imgui* self)
|
|||||||
if (mouseWheel != 0 || isZoomIn || isZoomOut)
|
if (mouseWheel != 0 || isZoomIn || isZoomOut)
|
||||||
{
|
{
|
||||||
f32 delta = (mouseWheel > 0 || isZoomIn) ? CANVAS_ZOOM_STEP : -CANVAS_ZOOM_STEP;
|
f32 delta = (mouseWheel > 0 || isZoomIn) ? CANVAS_ZOOM_STEP : -CANVAS_ZOOM_STEP;
|
||||||
delta = isMod ? delta * CANVAS_ZOOM_MOD : delta;
|
|
||||||
zoom = std::clamp(ROUND_NEAREST_MULTIPLE(zoom + delta, CANVAS_ZOOM_STEP), CANVAS_ZOOM_MIN, CANVAS_ZOOM_MAX);
|
zoom = std::clamp(ROUND_NEAREST_MULTIPLE(zoom + delta, CANVAS_ZOOM_STEP), CANVAS_ZOOM_MIN, CANVAS_ZOOM_MAX);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2538,7 +2678,6 @@ static void _imgui_log(Imgui* self)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void _imgui_dock(Imgui* self)
|
static void _imgui_dock(Imgui* self)
|
||||||
{
|
{
|
||||||
ImguiItem window = IMGUI_WINDOW_MAIN;
|
ImguiItem window = IMGUI_WINDOW_MAIN;
|
||||||
@@ -2558,6 +2697,7 @@ static void _imgui_dock(Imgui* self)
|
|||||||
_imgui_animation_preview(self);
|
_imgui_animation_preview(self);
|
||||||
_imgui_spritesheet_editor(self);
|
_imgui_spritesheet_editor(self);
|
||||||
_imgui_timeline(self);
|
_imgui_timeline(self);
|
||||||
|
_imgui_onionskin(self);
|
||||||
_imgui_frame_properties(self);
|
_imgui_frame_properties(self);
|
||||||
|
|
||||||
_imgui_end(); // IMGUI_WINDOW_MAIN
|
_imgui_end(); // IMGUI_WINDOW_MAIN
|
||||||
@@ -2608,6 +2748,12 @@ void imgui_init
|
|||||||
io.ConfigWindowsMoveFromTitleBarOnly = true;
|
io.ConfigWindowsMoveFromTitleBarOnly = true;
|
||||||
|
|
||||||
ImGui::LoadIniSettingsFromDisk(settings_path_get().c_str());
|
ImGui::LoadIniSettingsFromDisk(settings_path_get().c_str());
|
||||||
|
|
||||||
|
for (s32 i = 0; i < HOTKEY_COUNT; i++)
|
||||||
|
{
|
||||||
|
if (!SETTINGS_HOTKEY_MEMBERS[i]) continue;
|
||||||
|
imgui_hotkey_chord_registry()[i] = imgui_chord_from_string_get(*&(self->settings->*SETTINGS_HOTKEY_MEMBERS[i]));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void imgui_update(Imgui* self)
|
void imgui_update(Imgui* self)
|
||||||
@@ -2622,13 +2768,13 @@ void imgui_update(Imgui* self)
|
|||||||
|
|
||||||
if (self->isContextualActionsEnabled)
|
if (self->isContextualActionsEnabled)
|
||||||
{
|
{
|
||||||
for (const auto& hotkey : imgui_hotkey_registry())
|
for (const auto& item : imgui_item_registry())
|
||||||
{
|
{
|
||||||
if (ImGui::IsKeyChordPressed(hotkey.chord))
|
if (item->is_chord() && _imgui_chord_pressed(item->chord_get()))
|
||||||
{
|
{
|
||||||
if (hotkey.is_undoable()) imgui_snapshot(self, hotkey.snapshotAction);
|
if (item->is_undoable()) imgui_snapshot(self, item->snapshotAction);
|
||||||
if (hotkey.is_focus_window()) continue;
|
if (item->is_focus_window()) continue;
|
||||||
hotkey.function(self);
|
if (item->is_function()) item->function(self);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
434
src/imgui.h
434
src/imgui.h
@@ -52,14 +52,15 @@
|
|||||||
#define IMGUI_FRAME_BORDER 2.0f
|
#define IMGUI_FRAME_BORDER 2.0f
|
||||||
#define IMGUI_LOG_DURATION 3.0f
|
#define IMGUI_LOG_DURATION 3.0f
|
||||||
#define IMGUI_LOG_PADDING 10.0f
|
#define IMGUI_LOG_PADDING 10.0f
|
||||||
#define IMGUI_PLAYHEAD_LINE_COLOR IM_COL32(255, 255, 255, 255)
|
#define IMGUI_PLAYHEAD_LINE_COLOR IM_COL32(UCHAR_MAX, UCHAR_MAX, UCHAR_MAX, UCHAR_MAX)
|
||||||
#define IMGUI_TRIGGERS_EVENT_COLOR IM_COL32(255, 255, 255, 128)
|
#define IMGUI_TRIGGERS_EVENT_COLOR IM_COL32(UCHAR_MAX, UCHAR_MAX, UCHAR_MAX, 128)
|
||||||
#define IMGUI_PLAYHEAD_LINE_WIDTH 2.0f
|
#define IMGUI_PLAYHEAD_LINE_WIDTH 2.0f
|
||||||
#define IMGUI_SPRITESHEETS_FOOTER_HEIGHT 65
|
#define IMGUI_SPRITESHEETS_FOOTER_HEIGHT 65
|
||||||
#define IMGUI_TIMELINE_FRAME_MULTIPLE 5
|
#define IMGUI_TIMELINE_FRAME_MULTIPLE 5
|
||||||
#define IMGUI_TIMELINE_MERGE
|
#define IMGUI_TIMELINE_MERGE
|
||||||
#define IMGUI_TOOL_COLOR_PICKER_DURATION 0.25f
|
#define IMGUI_TOOL_COLOR_PICKER_DURATION 0.25f
|
||||||
#define IMGUI_OPTION_POPUP_ROW_COUNT 2
|
#define IMGUI_OPTION_POPUP_ROW_COUNT 2
|
||||||
|
#define IMGUI_CHORD_REPEAT_TIME 0.25f
|
||||||
|
|
||||||
#define IMGUI_ACTION_FRAME_CROP "Frame Crop"
|
#define IMGUI_ACTION_FRAME_CROP "Frame Crop"
|
||||||
#define IMGUI_ACTION_FRAME_SWAP "Frame Swap"
|
#define IMGUI_ACTION_FRAME_SWAP "Frame Swap"
|
||||||
@@ -72,6 +73,7 @@
|
|||||||
#define IMGUI_ACTION_ERASE "Erase"
|
#define IMGUI_ACTION_ERASE "Erase"
|
||||||
#define IMGUI_ACTION_RELOAD_SPRITESHEET "Reload Spritesheet(s)"
|
#define IMGUI_ACTION_RELOAD_SPRITESHEET "Reload Spritesheet(s)"
|
||||||
#define IMGUI_ACTION_REPLACE_SPRITESHEET "Replace Spritesheet"
|
#define IMGUI_ACTION_REPLACE_SPRITESHEET "Replace Spritesheet"
|
||||||
|
#define IMGUI_ACTION_OPEN_FILE "Open File"
|
||||||
|
|
||||||
#define IMGUI_POPUP_FLAGS ImGuiWindowFlags_NoMove
|
#define IMGUI_POPUP_FLAGS ImGuiWindowFlags_NoMove
|
||||||
#define IMGUI_POPUP_MODAL_FLAGS ImGuiWindowFlags_NoMove | ImGuiWindowFlags_AlwaysAutoResize
|
#define IMGUI_POPUP_MODAL_FLAGS ImGuiWindowFlags_NoMove | ImGuiWindowFlags_AlwaysAutoResize
|
||||||
@@ -93,7 +95,7 @@
|
|||||||
|
|
||||||
#define IMGUI_NONE "None"
|
#define IMGUI_NONE "None"
|
||||||
#define IMGUI_ANIMATION_DEFAULT_FORMAT "(*) {}"
|
#define IMGUI_ANIMATION_DEFAULT_FORMAT "(*) {}"
|
||||||
#define IMGUI_BUFFER_MAX 255
|
#define IMGUI_BUFFER_MAX UCHAR_MAX
|
||||||
#define IMGUI_INVISIBLE_LABEL_MARKER "##"
|
#define IMGUI_INVISIBLE_LABEL_MARKER "##"
|
||||||
#define IMGUI_ITEM_SELECTABLE_EDITABLE_LABEL "## Editing"
|
#define IMGUI_ITEM_SELECTABLE_EDITABLE_LABEL "## Editing"
|
||||||
#define IMGUI_LOG_FORMAT "## Log {}"
|
#define IMGUI_LOG_FORMAT "## Log {}"
|
||||||
@@ -107,7 +109,7 @@
|
|||||||
#define IMGUI_TIMELINE_FRAME_LABEL_FORMAT "## {}"
|
#define IMGUI_TIMELINE_FRAME_LABEL_FORMAT "## {}"
|
||||||
#define IMGUI_SELECTABLE_INPUT_INT_FORMAT "#{}"
|
#define IMGUI_SELECTABLE_INPUT_INT_FORMAT "#{}"
|
||||||
#define IMGUI_TIMELINE_ANIMATION_NONE "Select an animation to show timeline..."
|
#define IMGUI_TIMELINE_ANIMATION_NONE "Select an animation to show timeline..."
|
||||||
|
#define IMGUI_HOTKEY_CHANGE "Input new hotkey..."
|
||||||
#define IMGUI_LABEL_SHORTCUT_FORMAT "({})"
|
#define IMGUI_LABEL_SHORTCUT_FORMAT "({})"
|
||||||
#define IMGUI_TOOLTIP_SHORTCUT_FORMAT "\n(Shortcut: {})"
|
#define IMGUI_TOOLTIP_SHORTCUT_FORMAT "\n(Shortcut: {})"
|
||||||
#define IMGUI_INVISIBLE_FORMAT "## {}"
|
#define IMGUI_INVISIBLE_FORMAT "## {}"
|
||||||
@@ -206,18 +208,13 @@ struct Imgui
|
|||||||
bool isTryQuit = false;
|
bool isTryQuit = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef void(*ImguiFunction)(Imgui*);
|
|
||||||
|
|
||||||
struct ImguiHotkey
|
static inline void imgui_snapshot(Imgui* self, const std::string& action = SNAPSHOT_ACTION)
|
||||||
{
|
{
|
||||||
ImGuiKeyChord chord;
|
self->snapshots->action = action;
|
||||||
ImguiFunction function;
|
Snapshot snapshot = snapshot_get(self->snapshots);
|
||||||
std::string focusWindow{};
|
snapshots_undo_push(self->snapshots, &snapshot);
|
||||||
std::string snapshotAction{};
|
}
|
||||||
|
|
||||||
bool is_focus_window() const { return !focusWindow.empty(); }
|
|
||||||
bool is_undoable() const { return !snapshotAction.empty(); }
|
|
||||||
};
|
|
||||||
|
|
||||||
static void imgui_log_push(Imgui* self, const std::string& text)
|
static void imgui_log_push(Imgui* self, const std::string& text)
|
||||||
{
|
{
|
||||||
@@ -225,12 +222,6 @@ static void imgui_log_push(Imgui* self, const std::string& text)
|
|||||||
log_imgui(text);
|
log_imgui(text);
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::vector<ImguiHotkey>& imgui_hotkey_registry()
|
|
||||||
{
|
|
||||||
static std::vector<ImguiHotkey> registry;
|
|
||||||
return registry;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void imgui_file_new(Imgui* self)
|
static inline void imgui_file_new(Imgui* self)
|
||||||
{
|
{
|
||||||
anm2_reference_clear(self->reference);
|
anm2_reference_clear(self->reference);
|
||||||
@@ -274,13 +265,6 @@ static inline void imgui_explore(Imgui* self)
|
|||||||
dialog_explorer_open(parentPath.string());
|
dialog_explorer_open(parentPath.string());
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void imgui_snapshot(Imgui* self, const std::string& action = SNAPSHOT_ACTION)
|
|
||||||
{
|
|
||||||
self->snapshots->action = action;
|
|
||||||
Snapshot snapshot = snapshot_get(self->snapshots);
|
|
||||||
snapshots_undo_push(self->snapshots, &snapshot);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void imgui_tool_pan_set(Imgui* self)
|
static inline void imgui_tool_pan_set(Imgui* self)
|
||||||
{
|
{
|
||||||
self->settings->tool = TOOL_PAN;
|
self->settings->tool = TOOL_PAN;
|
||||||
@@ -353,6 +337,125 @@ static inline void imgui_paste(Imgui* self)
|
|||||||
clipboard_paste(self->clipboard);
|
clipboard_paste(self->clipboard);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline void imgui_onionskin_toggle(Imgui* self)
|
||||||
|
{
|
||||||
|
self->settings->onionskinIsEnabled = !self->settings->onionskinIsEnabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const std::unordered_map<std::string, ImGuiKey> IMGUI_KEY_MAP =
|
||||||
|
{
|
||||||
|
{ "A", ImGuiKey_A },
|
||||||
|
{ "B", ImGuiKey_B },
|
||||||
|
{ "C", ImGuiKey_C },
|
||||||
|
{ "D", ImGuiKey_D },
|
||||||
|
{ "E", ImGuiKey_E },
|
||||||
|
{ "F", ImGuiKey_F },
|
||||||
|
{ "G", ImGuiKey_G },
|
||||||
|
{ "H", ImGuiKey_H },
|
||||||
|
{ "I", ImGuiKey_I },
|
||||||
|
{ "J", ImGuiKey_J },
|
||||||
|
{ "K", ImGuiKey_K },
|
||||||
|
{ "L", ImGuiKey_L },
|
||||||
|
{ "M", ImGuiKey_M },
|
||||||
|
{ "N", ImGuiKey_N },
|
||||||
|
{ "O", ImGuiKey_O },
|
||||||
|
{ "P", ImGuiKey_P },
|
||||||
|
{ "Q", ImGuiKey_Q },
|
||||||
|
{ "R", ImGuiKey_R },
|
||||||
|
{ "S", ImGuiKey_S },
|
||||||
|
{ "T", ImGuiKey_T },
|
||||||
|
{ "U", ImGuiKey_U },
|
||||||
|
{ "V", ImGuiKey_V },
|
||||||
|
{ "W", ImGuiKey_W },
|
||||||
|
{ "X", ImGuiKey_X },
|
||||||
|
{ "Y", ImGuiKey_Y },
|
||||||
|
{ "Z", ImGuiKey_Z },
|
||||||
|
|
||||||
|
{ "0", ImGuiKey_0 },
|
||||||
|
{ "1", ImGuiKey_1 },
|
||||||
|
{ "2", ImGuiKey_2 },
|
||||||
|
{ "3", ImGuiKey_3 },
|
||||||
|
{ "4", ImGuiKey_4 },
|
||||||
|
{ "5", ImGuiKey_5 },
|
||||||
|
{ "6", ImGuiKey_6 },
|
||||||
|
{ "7", ImGuiKey_7 },
|
||||||
|
{ "8", ImGuiKey_8 },
|
||||||
|
{ "9", ImGuiKey_9 },
|
||||||
|
|
||||||
|
{ "Num0", ImGuiKey_Keypad0 },
|
||||||
|
{ "Num1", ImGuiKey_Keypad1 },
|
||||||
|
{ "Num2", ImGuiKey_Keypad2 },
|
||||||
|
{ "Num3", ImGuiKey_Keypad3 },
|
||||||
|
{ "Num4", ImGuiKey_Keypad4 },
|
||||||
|
{ "Num5", ImGuiKey_Keypad5 },
|
||||||
|
{ "Num6", ImGuiKey_Keypad6 },
|
||||||
|
{ "Num7", ImGuiKey_Keypad7 },
|
||||||
|
{ "Num8", ImGuiKey_Keypad8 },
|
||||||
|
{ "Num9", ImGuiKey_Keypad9 },
|
||||||
|
{ "NumAdd", ImGuiKey_KeypadAdd },
|
||||||
|
{ "NumSubtract", ImGuiKey_KeypadSubtract },
|
||||||
|
{ "NumMultiply", ImGuiKey_KeypadMultiply },
|
||||||
|
{ "NumDivide", ImGuiKey_KeypadDivide },
|
||||||
|
{ "NumEnter", ImGuiKey_KeypadEnter },
|
||||||
|
{ "NumDecimal", ImGuiKey_KeypadDecimal },
|
||||||
|
|
||||||
|
{ "F1", ImGuiKey_F1 },
|
||||||
|
{ "F2", ImGuiKey_F2 },
|
||||||
|
{ "F3", ImGuiKey_F3 },
|
||||||
|
{ "F4", ImGuiKey_F4 },
|
||||||
|
{ "F5", ImGuiKey_F5 },
|
||||||
|
{ "F6", ImGuiKey_F6 },
|
||||||
|
{ "F7", ImGuiKey_F7 },
|
||||||
|
{ "F8", ImGuiKey_F8 },
|
||||||
|
{ "F9", ImGuiKey_F9 },
|
||||||
|
{ "F10", ImGuiKey_F10 },
|
||||||
|
{ "F11", ImGuiKey_F11 },
|
||||||
|
{ "F12", ImGuiKey_F12 },
|
||||||
|
|
||||||
|
{ "Up", ImGuiKey_UpArrow },
|
||||||
|
{ "Down", ImGuiKey_DownArrow },
|
||||||
|
{ "Left", ImGuiKey_LeftArrow },
|
||||||
|
{ "Right", ImGuiKey_RightArrow },
|
||||||
|
|
||||||
|
{ "Space", ImGuiKey_Space },
|
||||||
|
{ "Enter", ImGuiKey_Enter },
|
||||||
|
{ "Escape", ImGuiKey_Escape },
|
||||||
|
{ "Tab", ImGuiKey_Tab },
|
||||||
|
{ "Backspace", ImGuiKey_Backspace },
|
||||||
|
{ "Delete", ImGuiKey_Delete },
|
||||||
|
{ "Insert", ImGuiKey_Insert },
|
||||||
|
{ "Home", ImGuiKey_Home },
|
||||||
|
{ "End", ImGuiKey_End },
|
||||||
|
{ "PageUp", ImGuiKey_PageUp },
|
||||||
|
{ "PageDown", ImGuiKey_PageDown },
|
||||||
|
|
||||||
|
{ "Minus", ImGuiKey_Minus },
|
||||||
|
{ "Equal", ImGuiKey_Equal },
|
||||||
|
{ "LeftBracket", ImGuiKey_LeftBracket },
|
||||||
|
{ "RightBracket", ImGuiKey_RightBracket },
|
||||||
|
{ "Semicolon", ImGuiKey_Semicolon },
|
||||||
|
{ "Apostrophe", ImGuiKey_Apostrophe },
|
||||||
|
{ "Comma", ImGuiKey_Comma },
|
||||||
|
{ "Period", ImGuiKey_Period },
|
||||||
|
{ "Slash", ImGuiKey_Slash },
|
||||||
|
{ "Backslash", ImGuiKey_Backslash },
|
||||||
|
{ "GraveAccent", ImGuiKey_GraveAccent },
|
||||||
|
|
||||||
|
{ "MouseLeft", ImGuiKey_MouseLeft },
|
||||||
|
{ "MouseRight", ImGuiKey_MouseRight },
|
||||||
|
{ "MouseMiddle", ImGuiKey_MouseMiddle },
|
||||||
|
{ "MouseX1", ImGuiKey_MouseX1 },
|
||||||
|
{ "MouseX2", ImGuiKey_MouseX2 }
|
||||||
|
};
|
||||||
|
|
||||||
|
static std::unordered_map<std::string, ImGuiKey> IMGUI_MOD_MAP =
|
||||||
|
{
|
||||||
|
{ "Ctrl", ImGuiMod_Ctrl },
|
||||||
|
{ "Shift", ImGuiMod_Shift },
|
||||||
|
{ "Alt", ImGuiMod_Alt },
|
||||||
|
{ "Super", ImGuiMod_Super },
|
||||||
|
};
|
||||||
|
|
||||||
static inline ImGuiKey imgui_key_from_char_get(char c)
|
static inline ImGuiKey imgui_key_from_char_get(char c)
|
||||||
{
|
{
|
||||||
if (c >= 'a' && c <= 'z') c -= 'a' - 'A';
|
if (c >= 'a' && c <= 'z') c -= 'a' - 'A';
|
||||||
@@ -367,16 +470,12 @@ static inline std::string imgui_string_from_chord_get(ImGuiKeyChord chord)
|
|||||||
if (chord & ImGuiMod_Ctrl) result += "Ctrl+";
|
if (chord & ImGuiMod_Ctrl) result += "Ctrl+";
|
||||||
if (chord & ImGuiMod_Shift) result += "Shift+";
|
if (chord & ImGuiMod_Shift) result += "Shift+";
|
||||||
if (chord & ImGuiMod_Alt) result += "Alt+";
|
if (chord & ImGuiMod_Alt) result += "Alt+";
|
||||||
|
if (chord & ImGuiMod_Super) result += "Super+";
|
||||||
|
|
||||||
ImGuiKey key = (ImGuiKey)(chord & ~ImGuiMod_Mask_);
|
ImGuiKey key = (ImGuiKey)(chord & ~ImGuiMod_Mask_);
|
||||||
|
|
||||||
if (key >= ImGuiKey_A && key <= ImGuiKey_Z)
|
if (key != ImGuiKey_None)
|
||||||
result.push_back('A' + (key - ImGuiKey_A));
|
|
||||||
else if (key >= ImGuiKey_0 && key <= ImGuiKey_9)
|
|
||||||
result.push_back('0' + (key - ImGuiKey_0));
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
// Fallback to ImGui's built-in name for non-alphanumerics
|
|
||||||
const char* name = ImGui::GetKeyName(key);
|
const char* name = ImGui::GetKeyName(key);
|
||||||
if (name && *name)
|
if (name && *name)
|
||||||
result += name;
|
result += name;
|
||||||
@@ -384,9 +483,44 @@ static inline std::string imgui_string_from_chord_get(ImGuiKeyChord chord)
|
|||||||
result += "Unknown";
|
result += "Unknown";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!result.empty() && result.back() == '+')
|
||||||
|
result.pop_back();
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline ImGuiKeyChord imgui_chord_from_string_get(const std::string& str)
|
||||||
|
{
|
||||||
|
ImGuiKeyChord chord = 0;
|
||||||
|
ImGuiKey baseKey = ImGuiKey_None;
|
||||||
|
|
||||||
|
std::stringstream ss(str);
|
||||||
|
std::string token;
|
||||||
|
while (std::getline(ss, token, '+'))
|
||||||
|
{
|
||||||
|
// trim
|
||||||
|
token.erase(0, token.find_first_not_of(" \t\r\n"));
|
||||||
|
token.erase(token.find_last_not_of(" \t\r\n") + 1);
|
||||||
|
|
||||||
|
if (token.empty())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (auto it = IMGUI_MOD_MAP.find(token); it != IMGUI_MOD_MAP.end()) {
|
||||||
|
chord |= it->second;
|
||||||
|
}
|
||||||
|
else if (baseKey == ImGuiKey_None) {
|
||||||
|
if (auto it2 = IMGUI_KEY_MAP.find(token); it2 != IMGUI_KEY_MAP.end())
|
||||||
|
baseKey = it2->second;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (baseKey != ImGuiKey_None)
|
||||||
|
chord |= baseKey;
|
||||||
|
|
||||||
|
return chord;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void imgui_contextual_actions_enable(Imgui* self) { self->isContextualActionsEnabled = true; }
|
static void imgui_contextual_actions_enable(Imgui* self) { self->isContextualActionsEnabled = true; }
|
||||||
static void imgui_contextual_actions_disable(Imgui* self){ self->isContextualActionsEnabled = false; }
|
static void imgui_contextual_actions_disable(Imgui* self){ self->isContextualActionsEnabled = false; }
|
||||||
static inline bool imgui_is_popup_open(const std::string& label) { return ImGui::IsPopupOpen(label.c_str()); }
|
static inline bool imgui_is_popup_open(const std::string& label) { return ImGui::IsPopupOpen(label.c_str()); }
|
||||||
@@ -449,6 +583,7 @@ enum ImguiItemType
|
|||||||
IMGUI_WINDOW,
|
IMGUI_WINDOW,
|
||||||
IMGUI_DOCKSPACE,
|
IMGUI_DOCKSPACE,
|
||||||
IMGUI_CHILD,
|
IMGUI_CHILD,
|
||||||
|
IMGUI_TABLE,
|
||||||
IMGUI_OPTION_POPUP,
|
IMGUI_OPTION_POPUP,
|
||||||
IMGUI_SELECTABLE,
|
IMGUI_SELECTABLE,
|
||||||
IMGUI_BUTTON,
|
IMGUI_BUTTON,
|
||||||
@@ -478,6 +613,22 @@ struct ImguiItemOverride
|
|||||||
s32 value{};
|
s32 value{};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct ImguiItem;
|
||||||
|
|
||||||
|
static std::vector<ImguiItem*>& imgui_item_registry(void)
|
||||||
|
{
|
||||||
|
static std::vector<ImguiItem*> registry;
|
||||||
|
return registry;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ImGuiKeyChord* imgui_hotkey_chord_registry(void)
|
||||||
|
{
|
||||||
|
static ImGuiKeyChord registry[HOTKEY_COUNT];
|
||||||
|
return registry;
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef void(*ImguiFunction)(Imgui*);
|
||||||
|
|
||||||
// Item
|
// Item
|
||||||
struct ImguiItem
|
struct ImguiItem
|
||||||
{
|
{
|
||||||
@@ -491,6 +642,7 @@ struct ImguiItem
|
|||||||
std::vector<std::string> items{};
|
std::vector<std::string> items{};
|
||||||
AtlasType atlas = ATLAS_NONE;
|
AtlasType atlas = ATLAS_NONE;
|
||||||
ImGuiKeyChord chord = IMGUI_CHORD_NONE;
|
ImGuiKeyChord chord = IMGUI_CHORD_NONE;
|
||||||
|
HotkeyType hotkey = HOTKEY_NONE;
|
||||||
ImGuiKey mnemonicKey = ImGuiKey_None;
|
ImGuiKey mnemonicKey = ImGuiKey_None;
|
||||||
s32 mnemonicIndex = INDEX_NONE;
|
s32 mnemonicIndex = INDEX_NONE;
|
||||||
ImVec2 size{};
|
ImVec2 size{};
|
||||||
@@ -526,15 +678,7 @@ struct ImguiItem
|
|||||||
static s32 idNew = 0;
|
static s32 idNew = 0;
|
||||||
id = idNew++;
|
id = idNew++;
|
||||||
|
|
||||||
if (is_chord())
|
imgui_item_registry().push_back(this);
|
||||||
{
|
|
||||||
std::string chordString = imgui_string_from_chord_get(chord);
|
|
||||||
if (isShortcutInLabel)
|
|
||||||
label += std::format(IMGUI_LABEL_SHORTCUT_FORMAT, chordString);
|
|
||||||
tooltip += std::format(IMGUI_TOOLTIP_SHORTCUT_FORMAT, chordString);
|
|
||||||
if (function)
|
|
||||||
imgui_hotkey_registry().push_back({chord, function, focusWindow, snapshotAction});
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string labelNew{};
|
std::string labelNew{};
|
||||||
|
|
||||||
@@ -578,12 +722,20 @@ struct ImguiItem
|
|||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ImGuiKeyChord chord_get() const
|
||||||
|
{
|
||||||
|
if (is_hotkey()) return imgui_hotkey_chord_registry()[hotkey];
|
||||||
|
return chord;
|
||||||
|
}
|
||||||
|
|
||||||
bool is_border() const { return border != 0; }
|
bool is_border() const { return border != 0; }
|
||||||
bool is_row() const { return rowCount != 0; }
|
bool is_row() const { return rowCount != 0; }
|
||||||
bool is_chord() const { return chord != IMGUI_CHORD_NONE; }
|
bool is_hotkey() const { return hotkey != HOTKEY_NONE; }
|
||||||
|
bool is_chord() const { return chord != IMGUI_CHORD_NONE || is_hotkey(); }
|
||||||
bool is_drag_drop() const { return !dragDrop.empty(); }
|
bool is_drag_drop() const { return !dragDrop.empty(); }
|
||||||
bool is_focus_window() const { return !focusWindow.empty(); }
|
bool is_focus_window() const { return !focusWindow.empty(); }
|
||||||
bool is_popup() const { return !popup.empty(); }
|
bool is_popup() const { return !popup.empty(); }
|
||||||
|
bool is_function() const { return function; }
|
||||||
bool is_size() const { return size != ImVec2(); }
|
bool is_size() const { return size != ImVec2(); }
|
||||||
bool is_popup_size() const { return popupSize != ImVec2(); }
|
bool is_popup_size() const { return popupSize != ImVec2(); }
|
||||||
bool is_tooltip() const { return !tooltip.empty(); }
|
bool is_tooltip() const { return !tooltip.empty(); }
|
||||||
@@ -643,7 +795,7 @@ IMGUI_ITEM(IMGUI_NEW,
|
|||||||
self.label = "&New ",
|
self.label = "&New ",
|
||||||
self.tooltip = "Load a blank .anm2 file to edit.",
|
self.tooltip = "Load a blank .anm2 file to edit.",
|
||||||
self.function = imgui_file_new,
|
self.function = imgui_file_new,
|
||||||
self.chord = ImGuiMod_Ctrl | ImGuiKey_N,
|
self.hotkey = HOTKEY_NEW,
|
||||||
self.isSizeToText = true,
|
self.isSizeToText = true,
|
||||||
self.isShortcutInLabel = true
|
self.isShortcutInLabel = true
|
||||||
);
|
);
|
||||||
@@ -652,7 +804,7 @@ IMGUI_ITEM(IMGUI_OPEN,
|
|||||||
self.label = "&Open ",
|
self.label = "&Open ",
|
||||||
self.tooltip = "Open an existing .anm2 file to edit.",
|
self.tooltip = "Open an existing .anm2 file to edit.",
|
||||||
self.function = imgui_file_open,
|
self.function = imgui_file_open,
|
||||||
self.chord = ImGuiMod_Ctrl | ImGuiKey_O,
|
self.hotkey = HOTKEY_OPEN,
|
||||||
self.isSizeToText = true,
|
self.isSizeToText = true,
|
||||||
self.isShortcutInLabel = true
|
self.isShortcutInLabel = true
|
||||||
);
|
);
|
||||||
@@ -661,7 +813,7 @@ IMGUI_ITEM(IMGUI_SAVE,
|
|||||||
self.label = "&Save ",
|
self.label = "&Save ",
|
||||||
self.tooltip = "Saves the current .anm2 file to its path.\nIf no path exists, one can be chosen.",
|
self.tooltip = "Saves the current .anm2 file to its path.\nIf no path exists, one can be chosen.",
|
||||||
self.function = imgui_file_save,
|
self.function = imgui_file_save,
|
||||||
self.chord = ImGuiMod_Ctrl | ImGuiKey_S,
|
self.hotkey = HOTKEY_SAVE,
|
||||||
self.isSizeToText = true,
|
self.isSizeToText = true,
|
||||||
self.isShortcutInLabel = true
|
self.isShortcutInLabel = true
|
||||||
);
|
);
|
||||||
@@ -670,7 +822,7 @@ IMGUI_ITEM(IMGUI_SAVE_AS,
|
|||||||
self.label = "S&ave As ",
|
self.label = "S&ave As ",
|
||||||
self.tooltip = "Saves the current .anm2 file to a chosen path.",
|
self.tooltip = "Saves the current .anm2 file to a chosen path.",
|
||||||
self.function = imgui_file_save_as,
|
self.function = imgui_file_save_as,
|
||||||
self.chord = ImGuiMod_Ctrl | ImGuiMod_Shift | ImGuiKey_S,
|
self.hotkey = HOTKEY_SAVE_AS,
|
||||||
self.isSizeToText = true,
|
self.isSizeToText = true,
|
||||||
self.isShortcutInLabel = true
|
self.isShortcutInLabel = true
|
||||||
);
|
);
|
||||||
@@ -687,7 +839,7 @@ IMGUI_ITEM(IMGUI_EXIT,
|
|||||||
self.label = "&Exit ",
|
self.label = "&Exit ",
|
||||||
self.tooltip = "Exits the program.",
|
self.tooltip = "Exits the program.",
|
||||||
self.function = imgui_quit,
|
self.function = imgui_quit,
|
||||||
self.chord = ImGuiMod_Alt | ImGuiKey_F4,
|
self.hotkey = HOTKEY_EXIT,
|
||||||
self.isSizeToText = true,
|
self.isSizeToText = true,
|
||||||
self.isShortcutInLabel = true
|
self.isShortcutInLabel = true
|
||||||
);
|
);
|
||||||
@@ -697,6 +849,11 @@ IMGUI_ITEM(IMGUI_EXIT_CONFIRMATION,
|
|||||||
self.text = "Unsaved changes will be lost!\nAre you sure you want to exit?"
|
self.text = "Unsaved changes will be lost!\nAre you sure you want to exit?"
|
||||||
);
|
);
|
||||||
|
|
||||||
|
IMGUI_ITEM(IMGUI_OPEN_CONFIRMATION,
|
||||||
|
self.label = "Open Confirmation",
|
||||||
|
self.text = "Unsaved changes will be lost!\nAre you sure you open a new file?"
|
||||||
|
);
|
||||||
|
|
||||||
IMGUI_ITEM(IMGUI_WIZARD,
|
IMGUI_ITEM(IMGUI_WIZARD,
|
||||||
self.label = "&Wizard",
|
self.label = "&Wizard",
|
||||||
self.tooltip = "Opens the wizard menu, for neat functions related to the .anm2.",
|
self.tooltip = "Opens the wizard menu, for neat functions related to the .anm2.",
|
||||||
@@ -747,12 +904,14 @@ IMGUI_ITEM(IMGUI_GENERATE_ANIMATION_FROM_GRID_PIVOT,
|
|||||||
IMGUI_ITEM(IMGUI_GENERATE_ANIMATION_FROM_GRID_ROWS,
|
IMGUI_ITEM(IMGUI_GENERATE_ANIMATION_FROM_GRID_ROWS,
|
||||||
self.label = "Rows",
|
self.label = "Rows",
|
||||||
self.tooltip = "Set how many rows will be used in the generated animation.",
|
self.tooltip = "Set how many rows will be used in the generated animation.",
|
||||||
|
self.min = 1,
|
||||||
self.max = 1000
|
self.max = 1000
|
||||||
);
|
);
|
||||||
|
|
||||||
IMGUI_ITEM(IMGUI_GENERATE_ANIMATION_FROM_GRID_COLUMNS,
|
IMGUI_ITEM(IMGUI_GENERATE_ANIMATION_FROM_GRID_COLUMNS,
|
||||||
self.label = "Columns",
|
self.label = "Columns",
|
||||||
self.tooltip = "Set how many columns will be used in the generated animation.",
|
self.tooltip = "Set how many columns will be used in the generated animation.",
|
||||||
|
self.min = 1,
|
||||||
self.max = 1000
|
self.max = 1000
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -812,7 +971,7 @@ IMGUI_ITEM(IMGUI_CHANGE_ALL_FRAME_PROPERTIES,
|
|||||||
self.tooltip = "Change all frame properties in the selected animation item (or selected frame).",
|
self.tooltip = "Change all frame properties in the selected animation item (or selected frame).",
|
||||||
self.popup = "Change All Frame Properties",
|
self.popup = "Change All Frame Properties",
|
||||||
self.popupType = IMGUI_POPUP_CENTER_WINDOW,
|
self.popupType = IMGUI_POPUP_CENTER_WINDOW,
|
||||||
self.popupSize = {500, 380}
|
self.popupSize = {500, 405}
|
||||||
);
|
);
|
||||||
|
|
||||||
IMGUI_ITEM(IMGUI_CHANGE_ALL_FRAME_PROPERTIES_CHILD,
|
IMGUI_ITEM(IMGUI_CHANGE_ALL_FRAME_PROPERTIES_CHILD,
|
||||||
@@ -820,7 +979,7 @@ IMGUI_ITEM(IMGUI_CHANGE_ALL_FRAME_PROPERTIES_CHILD,
|
|||||||
self.size =
|
self.size =
|
||||||
{
|
{
|
||||||
IMGUI_CHANGE_ALL_FRAME_PROPERTIES.popupSize.x,
|
IMGUI_CHANGE_ALL_FRAME_PROPERTIES.popupSize.x,
|
||||||
250
|
275
|
||||||
},
|
},
|
||||||
self.flags = true
|
self.flags = true
|
||||||
);
|
);
|
||||||
@@ -862,7 +1021,7 @@ IMGUI_ITEM(IMGUI_CHANGE_ALL_FRAME_PROPERTIES_ADD,
|
|||||||
|
|
||||||
IMGUI_ITEM(IMGUI_CHANGE_ALL_FRAME_PROPERTIES_SUBTRACT,
|
IMGUI_ITEM(IMGUI_CHANGE_ALL_FRAME_PROPERTIES_SUBTRACT,
|
||||||
self.label = "Subtract",
|
self.label = "Subtract",
|
||||||
self.tooltip = "The specified values will be added to all selected frames.",
|
self.tooltip = "The specified values will be subtracted from all selected frames.",
|
||||||
self.snapshotAction = "Subtract Frame Properties",
|
self.snapshotAction = "Subtract Frame Properties",
|
||||||
self.rowCount = IMGUI_CHANGE_ALL_FRAME_PROPERTIES_OPTIONS_ROW_COUNT,
|
self.rowCount = IMGUI_CHANGE_ALL_FRAME_PROPERTIES_OPTIONS_ROW_COUNT,
|
||||||
self.isSameLine = true
|
self.isSameLine = true
|
||||||
@@ -887,7 +1046,7 @@ IMGUI_ITEM(IMGUI_SCALE_ANM2,
|
|||||||
self.tooltip = "Scale up all size and position-related frame properties in the anm2.",
|
self.tooltip = "Scale up all size and position-related frame properties in the anm2.",
|
||||||
self.popup = "Scale Anm2",
|
self.popup = "Scale Anm2",
|
||||||
self.popupType = IMGUI_POPUP_CENTER_WINDOW,
|
self.popupType = IMGUI_POPUP_CENTER_WINDOW,
|
||||||
self.popupSize = {260, 72},
|
self.popupSize = {260, 75},
|
||||||
self.isSizeToText = true,
|
self.isSizeToText = true,
|
||||||
self.isSeparator = true
|
self.isSeparator = true
|
||||||
);
|
);
|
||||||
@@ -963,7 +1122,7 @@ IMGUI_ITEM(IMGUI_RENDER_ANIMATION_OUTPUT,
|
|||||||
IMGUI_ITEM(IMGUI_RENDER_ANIMATION_FORMAT,
|
IMGUI_ITEM(IMGUI_RENDER_ANIMATION_FORMAT,
|
||||||
self.label = "Format",
|
self.label = "Format",
|
||||||
self.tooltip = "(PNG images only).\nSet the format of each output frame; i.e., its filename.\nThe format will only take one argument; that being the frame's index.\nFor example, a format like \"{}.png\" will export a frame of index 0 as \"0.png\".",
|
self.tooltip = "(PNG images only).\nSet the format of each output frame; i.e., its filename.\nThe format will only take one argument; that being the frame's index.\nFor example, a format like \"{}.png\" will export a frame of index 0 as \"0.png\".",
|
||||||
self.max = 255
|
self.max = UCHAR_MAX
|
||||||
);
|
);
|
||||||
|
|
||||||
IMGUI_ITEM(IMGUI_RENDER_ANIMATION_CONFIRM,
|
IMGUI_ITEM(IMGUI_RENDER_ANIMATION_CONFIRM,
|
||||||
@@ -1014,7 +1173,43 @@ IMGUI_ITEM(IMGUI_SETTINGS,
|
|||||||
IMGUI_ITEM(IMGUI_VSYNC,
|
IMGUI_ITEM(IMGUI_VSYNC,
|
||||||
self.label = "&Vsync",
|
self.label = "&Vsync",
|
||||||
self.tooltip = "Toggle vertical sync; synchronizes program framerate with your monitor's refresh rate.",
|
self.tooltip = "Toggle vertical sync; synchronizes program framerate with your monitor's refresh rate.",
|
||||||
self.isSizeToText = true
|
self.isSizeToText = true,
|
||||||
|
self.isSeparator = true
|
||||||
|
);
|
||||||
|
|
||||||
|
IMGUI_ITEM(IMGUI_HOTKEYS,
|
||||||
|
self.label = "&Hotkeys",
|
||||||
|
self.tooltip = "Change the program's hotkeys.",
|
||||||
|
self.popup = "Hotkeys",
|
||||||
|
self.popupSize = {500, 405},
|
||||||
|
self.isSizeToText = true,
|
||||||
|
self.isSeparator = true
|
||||||
|
);
|
||||||
|
|
||||||
|
IMGUI_ITEM(IMGUI_HOTKEYS_CHILD,
|
||||||
|
self.label = "## Hotkeys Child",
|
||||||
|
self.size = {IMGUI_HOTKEYS.popupSize.x, IMGUI_HOTKEYS.popupSize.y - 35},
|
||||||
|
self.flags = true
|
||||||
|
);
|
||||||
|
|
||||||
|
#define IMGUI_HOTKEYS_FUNCTION "Function"
|
||||||
|
#define IMGUI_HOTKEYS_HOTKEY "Hotkey"
|
||||||
|
IMGUI_ITEM(IMGUI_HOTKEYS_TABLE,
|
||||||
|
self.label = "## Hotkeys Table",
|
||||||
|
self.value = 2,
|
||||||
|
self.flags = ImGuiTableFlags_Borders
|
||||||
|
);
|
||||||
|
|
||||||
|
IMGUI_ITEM(IMGUI_HOTKEYS_OPTIONS_CHILD,
|
||||||
|
self.label = "## Merge Options Child",
|
||||||
|
self.size = {IMGUI_HOTKEYS.popupSize.x, 35},
|
||||||
|
self.flags = true
|
||||||
|
);
|
||||||
|
|
||||||
|
IMGUI_ITEM(IMGUI_HOTKEYS_CONFIRM,
|
||||||
|
self.label = "Confirm",
|
||||||
|
self.tooltip = "Use these hotkeys.",
|
||||||
|
self.rowCount = 1
|
||||||
);
|
);
|
||||||
|
|
||||||
IMGUI_ITEM(IMGUI_DEFAULT_SETTINGS,
|
IMGUI_ITEM(IMGUI_DEFAULT_SETTINGS,
|
||||||
@@ -1298,14 +1493,11 @@ IMGUI_ITEM(IMGUI_CANVAS_ZOOM,
|
|||||||
self.tooltip = "Change the zoom of the canvas.",
|
self.tooltip = "Change the zoom of the canvas.",
|
||||||
self.min = CANVAS_ZOOM_MIN,
|
self.min = CANVAS_ZOOM_MIN,
|
||||||
self.max = CANVAS_ZOOM_MAX,
|
self.max = CANVAS_ZOOM_MAX,
|
||||||
|
self.speed = 1.0f,
|
||||||
self.value = CANVAS_ZOOM_DEFAULT
|
self.value = CANVAS_ZOOM_DEFAULT
|
||||||
);
|
);
|
||||||
|
|
||||||
IMGUI_ITEM(IMGUI_CANVAS_CENTER_VIEW,
|
|
||||||
self.label = "Center View",
|
|
||||||
self.tooltip = "Centers the current view on the canvas.",
|
|
||||||
self.size = {-FLT_MIN, 0}
|
|
||||||
);
|
|
||||||
|
|
||||||
IMGUI_ITEM(IMGUI_CANVAS_VISUAL_CHILD,
|
IMGUI_ITEM(IMGUI_CANVAS_VISUAL_CHILD,
|
||||||
self.label = "## Animation Preview Visual Child",
|
self.label = "## Animation Preview Visual Child",
|
||||||
@@ -1327,8 +1519,8 @@ IMGUI_ITEM(IMGUI_CANVAS_ANIMATION_OVERLAY,
|
|||||||
IMGUI_ITEM(IMGUI_CANVAS_ANIMATION_OVERLAY_TRANSPARENCY,
|
IMGUI_ITEM(IMGUI_CANVAS_ANIMATION_OVERLAY_TRANSPARENCY,
|
||||||
self.label = "Alpha",
|
self.label = "Alpha",
|
||||||
self.tooltip = "Set the transparency of the animation overlay.",
|
self.tooltip = "Set the transparency of the animation overlay.",
|
||||||
self.value = 255,
|
self.value = SETTINGS_PREVIEW_OVERLAY_TRANSPARENCY_DEFAULT,
|
||||||
self.max = 255
|
self.max = UCHAR_MAX
|
||||||
);
|
);
|
||||||
|
|
||||||
IMGUI_ITEM(IMGUI_CANVAS_HELPER_CHILD,
|
IMGUI_ITEM(IMGUI_CANVAS_HELPER_CHILD,
|
||||||
@@ -1351,28 +1543,37 @@ IMGUI_ITEM(IMGUI_CANVAS_AXES_COLOR,
|
|||||||
IMGUI_ITEM(IMGUI_CANVAS_ROOT_TRANSFORM,
|
IMGUI_ITEM(IMGUI_CANVAS_ROOT_TRANSFORM,
|
||||||
self.label = "Root Transform",
|
self.label = "Root Transform",
|
||||||
self.tooltip = "Toggles the root frames's attributes transforming the other items in an animation.",
|
self.tooltip = "Toggles the root frames's attributes transforming the other items in an animation.",
|
||||||
self.value = true
|
self.value = SETTINGS_PREVIEW_IS_ROOT_TRANSFORM_DEFAULT
|
||||||
);
|
);
|
||||||
|
|
||||||
IMGUI_ITEM(IMGUI_CANVAS_TRIGGERS,
|
IMGUI_ITEM(IMGUI_CANVAS_TRIGGERS,
|
||||||
self.label = "Triggers",
|
self.label = "Triggers",
|
||||||
self.tooltip = "Toggles activated triggers drawing their event name.",
|
self.tooltip = "Toggles activated triggers drawing their event name.",
|
||||||
self.value = true
|
self.value = SETTINGS_PREVIEW_IS_TRIGGERS_DEFAULT
|
||||||
);
|
);
|
||||||
|
|
||||||
IMGUI_ITEM(IMGUI_CANVAS_PIVOTS,
|
IMGUI_ITEM(IMGUI_CANVAS_PIVOTS,
|
||||||
self.label = "Pivots",
|
self.label = "Pivots",
|
||||||
self.tooltip = "Toggles drawing each layer's pivot."
|
self.tooltip = "Toggles drawing each layer's pivot.",
|
||||||
|
self.value = SETTINGS_PREVIEW_IS_PIVOTS_DEFAULT
|
||||||
);
|
);
|
||||||
|
|
||||||
IMGUI_ITEM(IMGUI_CANVAS_TARGETS,
|
IMGUI_ITEM(IMGUI_CANVAS_TARGETS,
|
||||||
self.label = "Targets",
|
self.label = "Targets",
|
||||||
self.tooltip = "Toggles drawing the targets (i.e., the colored root/null icons)."
|
self.tooltip = "Toggles drawing the targets (the colored root/null icons).",
|
||||||
|
self.value = SETTINGS_PREVIEW_IS_TARGETS_DEFAULT
|
||||||
|
);
|
||||||
|
|
||||||
|
IMGUI_ITEM(IMGUI_CANVAS_ALT_ICONS,
|
||||||
|
self.label = "Alt Icons",
|
||||||
|
self.tooltip = "Toggles the use of alternate icons for the targets (the colored root/null icons).",
|
||||||
|
self.value = SETTINGS_PREVIEW_IS_ALT_ICONS_DEFAULT
|
||||||
);
|
);
|
||||||
|
|
||||||
IMGUI_ITEM(IMGUI_CANVAS_BORDER,
|
IMGUI_ITEM(IMGUI_CANVAS_BORDER,
|
||||||
self.label = "Border",
|
self.label = "Border",
|
||||||
self.tooltip = "Toggles the appearance of a border around the items."
|
self.tooltip = "Toggles the appearance of a border around the items.",
|
||||||
|
self.value = SETTINGS_PREVIEW_IS_BORDER_DEFAULT
|
||||||
);
|
);
|
||||||
|
|
||||||
IMGUI_ITEM(IMGUI_ANIMATION_PREVIEW,
|
IMGUI_ITEM(IMGUI_ANIMATION_PREVIEW,
|
||||||
@@ -1380,11 +1581,27 @@ IMGUI_ITEM(IMGUI_ANIMATION_PREVIEW,
|
|||||||
self.flags = ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoScrollWithMouse
|
self.flags = ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoScrollWithMouse
|
||||||
);
|
);
|
||||||
|
|
||||||
|
IMGUI_ITEM(IMGUI_ANIMATION_PREVIEW_CENTER_VIEW,
|
||||||
|
self.label = "Center View",
|
||||||
|
self.tooltip = "Centers the current view on the animation preview.",
|
||||||
|
self.hotkey = HOTKEY_CENTER_VIEW,
|
||||||
|
self.focusWindow = IMGUI_ANIMATION_PREVIEW.label,
|
||||||
|
self.size = {-FLT_MIN, 0}
|
||||||
|
);
|
||||||
|
|
||||||
IMGUI_ITEM(IMGUI_SPRITESHEET_EDITOR,
|
IMGUI_ITEM(IMGUI_SPRITESHEET_EDITOR,
|
||||||
self.label = "Spritesheet Editor",
|
self.label = "Spritesheet Editor",
|
||||||
self.flags = ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoScrollWithMouse
|
self.flags = ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoScrollWithMouse
|
||||||
);
|
);
|
||||||
|
|
||||||
|
IMGUI_ITEM(IMGUI_SPRITESHEET_EDITOR_CENTER_VIEW,
|
||||||
|
self.label = "Center View",
|
||||||
|
self.tooltip = "Centers the current view on the spritesheet editor.",
|
||||||
|
self.hotkey = HOTKEY_CENTER_VIEW,
|
||||||
|
self.focusWindow = IMGUI_SPRITESHEET_EDITOR.label,
|
||||||
|
self.size = {-FLT_MIN, 0}
|
||||||
|
);
|
||||||
|
|
||||||
IMGUI_ITEM(IMGUI_FRAME_PROPERTIES, self.label = "Frame Properties");
|
IMGUI_ITEM(IMGUI_FRAME_PROPERTIES, self.label = "Frame Properties");
|
||||||
|
|
||||||
IMGUI_ITEM(IMGUI_FRAME_PROPERTIES_POSITION,
|
IMGUI_ITEM(IMGUI_FRAME_PROPERTIES_POSITION,
|
||||||
@@ -1419,8 +1636,7 @@ IMGUI_ITEM(IMGUI_FRAME_PROPERTIES_SCALE,
|
|||||||
self.label = "Scale",
|
self.label = "Scale",
|
||||||
self.tooltip = "Change the scale of the selected frame.",
|
self.tooltip = "Change the scale of the selected frame.",
|
||||||
self.snapshotAction = "Frame Scale",
|
self.snapshotAction = "Frame Scale",
|
||||||
self.isUseItemActivated = true,
|
self.isUseItemActivated = true
|
||||||
self.value = 100
|
|
||||||
);
|
);
|
||||||
|
|
||||||
IMGUI_ITEM(IMGUI_FRAME_PROPERTIES_ROTATION,
|
IMGUI_ITEM(IMGUI_FRAME_PROPERTIES_ROTATION,
|
||||||
@@ -1505,7 +1721,7 @@ IMGUI_ITEM(IMGUI_TOOL_PAN,
|
|||||||
self.label = "## Pan",
|
self.label = "## Pan",
|
||||||
self.tooltip = "Use the pan tool.\nWill shift the view as the cursor is dragged.\nYou can also use the middle mouse button to pan at any time.",
|
self.tooltip = "Use the pan tool.\nWill shift the view as the cursor is dragged.\nYou can also use the middle mouse button to pan at any time.",
|
||||||
self.function = imgui_tool_pan_set,
|
self.function = imgui_tool_pan_set,
|
||||||
self.chord = ImGuiKey_P,
|
self.hotkey = HOTKEY_PAN,
|
||||||
self.atlas = ATLAS_PAN
|
self.atlas = ATLAS_PAN
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -1513,7 +1729,7 @@ IMGUI_ITEM(IMGUI_TOOL_MOVE,
|
|||||||
self.label = "## Move",
|
self.label = "## Move",
|
||||||
self.tooltip = "Use the move tool.\nWill move the selected item as the cursor is dragged, or directional keys are pressed.\n(Animation Preview only.)",
|
self.tooltip = "Use the move tool.\nWill move the selected item as the cursor is dragged, or directional keys are pressed.\n(Animation Preview only.)",
|
||||||
self.function = imgui_tool_move_set,
|
self.function = imgui_tool_move_set,
|
||||||
self.chord = ImGuiKey_M,
|
self.hotkey = HOTKEY_MOVE,
|
||||||
self.atlas = ATLAS_MOVE
|
self.atlas = ATLAS_MOVE
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -1521,7 +1737,7 @@ IMGUI_ITEM(IMGUI_TOOL_ROTATE,
|
|||||||
self.label = "## Rotate",
|
self.label = "## Rotate",
|
||||||
self.tooltip = "Use the rotate tool.\nWill rotate the selected item as the cursor is dragged, or directional keys are pressed.\n(Animation Preview only.)",
|
self.tooltip = "Use the rotate tool.\nWill rotate the selected item as the cursor is dragged, or directional keys are pressed.\n(Animation Preview only.)",
|
||||||
self.function = imgui_tool_rotate_set,
|
self.function = imgui_tool_rotate_set,
|
||||||
self.chord = ImGuiKey_R,
|
self.hotkey = HOTKEY_ROTATE,
|
||||||
self.atlas = ATLAS_ROTATE
|
self.atlas = ATLAS_ROTATE
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -1529,7 +1745,7 @@ IMGUI_ITEM(IMGUI_TOOL_SCALE,
|
|||||||
self.label = "## Scale",
|
self.label = "## Scale",
|
||||||
self.tooltip = "Use the scale tool.\nWill scale the selected item as the cursor is dragged, or directional keys are pressed.\n(Animation Preview only.)",
|
self.tooltip = "Use the scale tool.\nWill scale the selected item as the cursor is dragged, or directional keys are pressed.\n(Animation Preview only.)",
|
||||||
self.function = imgui_tool_scale_set,
|
self.function = imgui_tool_scale_set,
|
||||||
self.chord = ImGuiKey_S,
|
self.hotkey = HOTKEY_SCALE,
|
||||||
self.atlas = ATLAS_SCALE
|
self.atlas = ATLAS_SCALE
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -1537,7 +1753,7 @@ IMGUI_ITEM(IMGUI_TOOL_CROP,
|
|||||||
self.label = "## Crop",
|
self.label = "## Crop",
|
||||||
self.tooltip = "Use the crop tool.\nWill produce a crop rectangle based on how the cursor is dragged.\n(Spritesheet Editor only.)",
|
self.tooltip = "Use the crop tool.\nWill produce a crop rectangle based on how the cursor is dragged.\n(Spritesheet Editor only.)",
|
||||||
self.function = imgui_tool_crop_set,
|
self.function = imgui_tool_crop_set,
|
||||||
self.chord = ImGuiKey_C,
|
self.hotkey = HOTKEY_CROP,
|
||||||
self.atlas = ATLAS_CROP
|
self.atlas = ATLAS_CROP
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -1545,7 +1761,7 @@ IMGUI_ITEM(IMGUI_TOOL_DRAW,
|
|||||||
self.label = "## Draw",
|
self.label = "## Draw",
|
||||||
self.tooltip = "Draws pixels onto the selected spritesheet, with the current color.\n(Spritesheet Editor only.)",
|
self.tooltip = "Draws pixels onto the selected spritesheet, with the current color.\n(Spritesheet Editor only.)",
|
||||||
self.function = imgui_tool_draw_set,
|
self.function = imgui_tool_draw_set,
|
||||||
self.chord = ImGuiKey_B,
|
self.hotkey = HOTKEY_DRAW,
|
||||||
self.atlas = ATLAS_DRAW
|
self.atlas = ATLAS_DRAW
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -1553,7 +1769,7 @@ IMGUI_ITEM(IMGUI_TOOL_ERASE,
|
|||||||
self.label = "## Erase",
|
self.label = "## Erase",
|
||||||
self.tooltip = "Erases pixels from the selected spritesheet.\n(Spritesheet Editor only.)",
|
self.tooltip = "Erases pixels from the selected spritesheet.\n(Spritesheet Editor only.)",
|
||||||
self.function = imgui_tool_erase_set,
|
self.function = imgui_tool_erase_set,
|
||||||
self.chord = ImGuiKey_E,
|
self.hotkey = HOTKEY_ERASE,
|
||||||
self.atlas = ATLAS_ERASE
|
self.atlas = ATLAS_ERASE
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -1561,7 +1777,7 @@ IMGUI_ITEM(IMGUI_TOOL_COLOR_PICKER,
|
|||||||
self.label = "## Color Picker",
|
self.label = "## Color Picker",
|
||||||
self.tooltip = "Selects a color from the canvas, to be used for drawing.\n(Spritesheet Editor only).",
|
self.tooltip = "Selects a color from the canvas, to be used for drawing.\n(Spritesheet Editor only).",
|
||||||
self.function = imgui_tool_color_picker_set,
|
self.function = imgui_tool_color_picker_set,
|
||||||
self.chord = ImGuiKey_W,
|
self.hotkey = HOTKEY_COLOR_PICKER,
|
||||||
self.atlas = ATLAS_COLOR_PICKER
|
self.atlas = ATLAS_COLOR_PICKER
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -1569,7 +1785,7 @@ IMGUI_ITEM(IMGUI_TOOL_UNDO,
|
|||||||
self.label = "## Undo",
|
self.label = "## Undo",
|
||||||
self.tooltip = "Undo the last action.",
|
self.tooltip = "Undo the last action.",
|
||||||
self.function = imgui_undo,
|
self.function = imgui_undo,
|
||||||
self.chord = ImGuiMod_Ctrl | ImGuiKey_Z,
|
self.hotkey = HOTKEY_UNDO,
|
||||||
self.atlas = ATLAS_UNDO
|
self.atlas = ATLAS_UNDO
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -1577,7 +1793,7 @@ IMGUI_ITEM(IMGUI_TOOL_REDO,
|
|||||||
self.label = "## Redo",
|
self.label = "## Redo",
|
||||||
self.tooltip = "Redo the last action.",
|
self.tooltip = "Redo the last action.",
|
||||||
self.function = imgui_redo,
|
self.function = imgui_redo,
|
||||||
self.chord = ImGuiMod_Ctrl | ImGuiKey_Y,
|
self.hotkey = HOTKEY_REDO,
|
||||||
self.atlas = ATLAS_REDO
|
self.atlas = ATLAS_REDO
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -1875,7 +2091,7 @@ IMGUI_ITEM(IMGUI_PLAY,
|
|||||||
self.label = "|> Play",
|
self.label = "|> Play",
|
||||||
self.tooltip = "Play the current animation, if paused.",
|
self.tooltip = "Play the current animation, if paused.",
|
||||||
self.focusWindow = IMGUI_TIMELINE.label,
|
self.focusWindow = IMGUI_TIMELINE.label,
|
||||||
self.chord = ImGuiKey_Space,
|
self.hotkey = HOTKEY_PLAY_PAUSE,
|
||||||
self.rowCount = IMGUI_TIMELINE_OPTIONS_ROW_COUNT,
|
self.rowCount = IMGUI_TIMELINE_OPTIONS_ROW_COUNT,
|
||||||
self.isSameLine = true
|
self.isSameLine = true
|
||||||
);
|
);
|
||||||
@@ -1884,7 +2100,7 @@ IMGUI_ITEM(IMGUI_PAUSE,
|
|||||||
self.label = "|| Pause",
|
self.label = "|| Pause",
|
||||||
self.tooltip = "Pause the current animation, if playing.",
|
self.tooltip = "Pause the current animation, if playing.",
|
||||||
self.focusWindow = IMGUI_TIMELINE.label,
|
self.focusWindow = IMGUI_TIMELINE.label,
|
||||||
self.chord = ImGuiKey_Space,
|
self.hotkey = HOTKEY_PLAY_PAUSE,
|
||||||
self.rowCount = IMGUI_TIMELINE_OPTIONS_ROW_COUNT,
|
self.rowCount = IMGUI_TIMELINE_OPTIONS_ROW_COUNT,
|
||||||
self.isSameLine = true
|
self.isSameLine = true
|
||||||
);
|
);
|
||||||
@@ -1992,7 +2208,55 @@ IMGUI_ITEM(IMGUI_CREATED_BY,
|
|||||||
self.label = "Author",
|
self.label = "Author",
|
||||||
self.tooltip = "Sets the author of the animation.",
|
self.tooltip = "Sets the author of the animation.",
|
||||||
self.rowCount = IMGUI_TIMELINE_OPTIONS_ROW_COUNT,
|
self.rowCount = IMGUI_TIMELINE_OPTIONS_ROW_COUNT,
|
||||||
self.max = 255
|
self.max = UCHAR_MAX
|
||||||
|
);
|
||||||
|
|
||||||
|
#define IMGUI_ONIONSKIN_ROW_COUNT 3
|
||||||
|
IMGUI_ITEM(IMGUI_ONIONSKIN, self.label = "Onionskin");
|
||||||
|
IMGUI_ITEM(IMGUI_ONIONSKIN_ENABLED,
|
||||||
|
self.label = "Enabled",
|
||||||
|
self.tooltip = "Toggle onionskin (previews of frames before/after the current one.)",
|
||||||
|
self.function = imgui_onionskin_toggle,
|
||||||
|
self.hotkey = HOTKEY_ONIONSKIN,
|
||||||
|
self.isSeparator = true
|
||||||
|
);
|
||||||
|
|
||||||
|
IMGUI_ITEM(IMGUI_ONIONSKIN_BEFORE, self.label = "-- Before-- ");
|
||||||
|
IMGUI_ITEM(IMGUI_ONIONSKIN_AFTER, self.label = "-- After -- ");
|
||||||
|
|
||||||
|
IMGUI_ITEM(IMGUI_ONIONSKIN_COUNT,
|
||||||
|
self.label = "Count",
|
||||||
|
self.tooltip = "Set the number of previewed frames appearing.",
|
||||||
|
self.min = 1,
|
||||||
|
self.max = 100,
|
||||||
|
self.value = SETTINGS_ONIONSKIN_BEFORE_COUNT_DEFAULT,
|
||||||
|
self.rowCount = IMGUI_ONIONSKIN_ROW_COUNT,
|
||||||
|
self.isSameLine = true
|
||||||
|
);
|
||||||
|
|
||||||
|
IMGUI_ITEM(IMGUI_ONIONSKIN_COLOR_OFFSET,
|
||||||
|
self.label = "Color Offset",
|
||||||
|
self.tooltip = "Set the color offset of the previewed frames.",
|
||||||
|
self.flags = ImGuiColorEditFlags_NoInputs,
|
||||||
|
self.rowCount = IMGUI_ONIONSKIN_ROW_COUNT
|
||||||
|
);
|
||||||
|
|
||||||
|
IMGUI_ITEM(IMGUI_ONIONSKIN_DRAW_ORDER,
|
||||||
|
self.label = "Draw Order",
|
||||||
|
self.isSameLine = true
|
||||||
|
);
|
||||||
|
|
||||||
|
IMGUI_ITEM(IMGUI_ONIONSKIN_BELOW,
|
||||||
|
self.label = "Below",
|
||||||
|
self.tooltip = "The onionskin frames will draw below the base frame.",
|
||||||
|
self.value = ONIONSKIN_BELOW,
|
||||||
|
self.isSameLine = true
|
||||||
|
);
|
||||||
|
|
||||||
|
IMGUI_ITEM(IMGUI_ONIONSKIN_ABOVE,
|
||||||
|
self.label = "Above",
|
||||||
|
self.tooltip = "The onionskin frames will draw above the base frame.",
|
||||||
|
self.value = ONIONSKIN_ABOVE
|
||||||
);
|
);
|
||||||
|
|
||||||
IMGUI_ITEM(IMGUI_CONTEXT_MENU, self.label = "## Context Menu");
|
IMGUI_ITEM(IMGUI_CONTEXT_MENU, self.label = "## Context Menu");
|
||||||
@@ -2002,7 +2266,7 @@ IMGUI_ITEM(IMGUI_CUT,
|
|||||||
self.tooltip = "Cuts the currently selected contextual element; removing it and putting it to the clipboard.",
|
self.tooltip = "Cuts the currently selected contextual element; removing it and putting it to the clipboard.",
|
||||||
self.snapshotAction = "Cut",
|
self.snapshotAction = "Cut",
|
||||||
self.function = imgui_cut,
|
self.function = imgui_cut,
|
||||||
self.chord = ImGuiMod_Ctrl | ImGuiKey_X,
|
self.hotkey = HOTKEY_CUT,
|
||||||
self.isSizeToText = true
|
self.isSizeToText = true
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -2011,7 +2275,7 @@ IMGUI_ITEM(IMGUI_COPY,
|
|||||||
self.tooltip = "Copies the currently selected contextual element to the clipboard.",
|
self.tooltip = "Copies the currently selected contextual element to the clipboard.",
|
||||||
self.snapshotAction = "Copy",
|
self.snapshotAction = "Copy",
|
||||||
self.function = imgui_copy,
|
self.function = imgui_copy,
|
||||||
self.chord = ImGuiMod_Ctrl | ImGuiKey_C,
|
self.hotkey = HOTKEY_COPY,
|
||||||
self.isSizeToText = true
|
self.isSizeToText = true
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -2020,7 +2284,7 @@ IMGUI_ITEM(IMGUI_PASTE,
|
|||||||
self.tooltip = "Pastes the currently selection contextual element from the clipboard.",
|
self.tooltip = "Pastes the currently selection contextual element from the clipboard.",
|
||||||
self.snapshotAction = "Paste",
|
self.snapshotAction = "Paste",
|
||||||
self.function = imgui_paste,
|
self.function = imgui_paste,
|
||||||
self.chord = ImGuiMod_Ctrl | ImGuiKey_V,
|
self.hotkey = HOTKEY_PASTE,
|
||||||
self.isSizeToText = true
|
self.isSizeToText = true
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -2029,7 +2293,7 @@ IMGUI_ITEM(IMGUI_CHANGE_INPUT_TEXT,
|
|||||||
self.tooltip = "Rename the selected item.",
|
self.tooltip = "Rename the selected item.",
|
||||||
self.snapshotAction = "Rename Item",
|
self.snapshotAction = "Rename Item",
|
||||||
self.flags = ImGuiInputTextFlags_AutoSelectAll | ImGuiInputTextFlags_EnterReturnsTrue,
|
self.flags = ImGuiInputTextFlags_AutoSelectAll | ImGuiInputTextFlags_EnterReturnsTrue,
|
||||||
self.max = 255
|
self.max = UCHAR_MAX
|
||||||
);
|
);
|
||||||
|
|
||||||
IMGUI_ITEM(IMGUI_CHANGE_INPUT_INT,
|
IMGUI_ITEM(IMGUI_CHANGE_INPUT_INT,
|
||||||
|
236
src/preview.cpp
236
src/preview.cpp
@@ -98,155 +98,139 @@ void preview_draw(Preview* self)
|
|||||||
if (self->settings->previewIsAxes)
|
if (self->settings->previewIsAxes)
|
||||||
canvas_axes_draw(&self->canvas, shaderAxis, transform, self->settings->previewAxesColor);
|
canvas_axes_draw(&self->canvas, shaderAxis, transform, self->settings->previewAxesColor);
|
||||||
|
|
||||||
Anm2Animation* animation = anm2_animation_from_reference(self->anm2, self->reference);
|
auto animation_draw = [&](s32 animationID)
|
||||||
s32& animationID = self->reference->animationID;
|
|
||||||
|
|
||||||
if (animation)
|
|
||||||
{
|
{
|
||||||
Anm2Frame root;
|
Anm2Animation* animation = map_find(self->anm2->animations, animationID);
|
||||||
mat4 rootModel = mat4(1.0f);
|
if (!animation) return;
|
||||||
|
|
||||||
anm2_frame_from_time(self->anm2, &root, Anm2Reference{animationID, ANM2_ROOT}, self->time);
|
auto root_draw = [&](Anm2Frame root, vec3 colorOffset = {}, f32 alphaOffset = {}, bool isOnionskin = {})
|
||||||
|
|
||||||
if (self->settings->previewIsRootTransform)
|
|
||||||
rootModel = canvas_parent_model_get(root.position, {}, PERCENT_TO_UNIT(root.scale), root.rotation);
|
|
||||||
|
|
||||||
// Root
|
|
||||||
if (self->settings->previewIsTargets && animation->rootAnimation.isVisible && root.isVisible)
|
|
||||||
{
|
{
|
||||||
mat4 model = canvas_model_get(PREVIEW_TARGET_SIZE, root.position, PREVIEW_TARGET_SIZE * 0.5f, PERCENT_TO_UNIT(root.scale), root.rotation);
|
mat4 model = canvas_model_get(PREVIEW_TARGET_SIZE, root.position, PREVIEW_TARGET_SIZE * 0.5f, PERCENT_TO_UNIT(root.scale), root.rotation);
|
||||||
mat4 rootTransform = transform * model;
|
mat4 rootTransform = transform * model;
|
||||||
f32 vertices[] = ATLAS_UV_VERTICES(ATLAS_TARGET);
|
vec4 color = isOnionskin ? vec4(colorOffset, 1.0f - alphaOffset) : PREVIEW_ROOT_COLOR;
|
||||||
canvas_texture_draw(&self->canvas, shaderTexture, self->resources->atlas.id, rootTransform, vertices, PREVIEW_ROOT_COLOR);
|
AtlasType atlas = self->settings->previewIsAltIcons ? ATLAS_TARGET_ALT : ATLAS_TARGET;
|
||||||
}
|
f32 vertices[] = ATLAS_UV_VERTICES(atlas);
|
||||||
|
canvas_texture_draw(&self->canvas, shaderTexture, self->resources->atlas.id, rootTransform, vertices, color);
|
||||||
|
};
|
||||||
|
|
||||||
// Layers
|
auto layer_draw = [&](mat4 rootModel, s32 id, f32 time, vec3 colorOffset = {}, f32 alphaOffset = {}, bool isOnionskin = {})
|
||||||
for (auto [i, id] : self->anm2->layerMap)
|
|
||||||
{
|
{
|
||||||
Anm2Frame frame;
|
|
||||||
Anm2Item& layerAnimation = animation->layerAnimations[id];
|
Anm2Item& layerAnimation = animation->layerAnimations[id];
|
||||||
|
if (!layerAnimation.isVisible || layerAnimation.frames.size() <= 0) return;
|
||||||
|
|
||||||
if (!layerAnimation.isVisible || layerAnimation.frames.size() <= 0)
|
Anm2Frame frame;
|
||||||
continue;
|
anm2_frame_from_time(self->anm2, &frame, Anm2Reference{animationID, ANM2_LAYER, id}, time);
|
||||||
|
if (!frame.isVisible) return;
|
||||||
anm2_frame_from_time(self->anm2, &frame, Anm2Reference{animationID, ANM2_LAYER, id}, self->time);
|
|
||||||
|
|
||||||
if (!frame.isVisible)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
mat4 model = canvas_model_get(frame.size, frame.position, frame.pivot, PERCENT_TO_UNIT(frame.scale), frame.rotation);
|
mat4 model = canvas_model_get(frame.size, frame.position, frame.pivot, PERCENT_TO_UNIT(frame.scale), frame.rotation);
|
||||||
mat4 layerTransform = transform * (rootModel * model);
|
mat4 layerTransform = transform * (rootModel * model);
|
||||||
|
vec3 frameColorOffset = frame.offsetRGB + colorOffset;
|
||||||
|
vec4 frameTint = frame.tintRGBA;
|
||||||
|
frameTint.a = std::max(0.0f, frameTint.a - alphaOffset);
|
||||||
|
|
||||||
Anm2Spritesheet* spritesheet = map_find(self->anm2->spritesheets, self->anm2->layers[id].spritesheetID);
|
Anm2Spritesheet* spritesheet = map_find(self->anm2->spritesheets, self->anm2->layers[id].spritesheetID);
|
||||||
|
if (!spritesheet) return;
|
||||||
if (!spritesheet) continue;
|
|
||||||
|
|
||||||
Texture& texture = spritesheet->texture;
|
Texture& texture = spritesheet->texture;
|
||||||
|
if (texture.isInvalid) return;
|
||||||
if (!texture.isInvalid)
|
|
||||||
{
|
|
||||||
vec2 uvMin = frame.crop / vec2(texture.size);
|
|
||||||
vec2 uvMax = (frame.crop + frame.size) / vec2(texture.size);
|
|
||||||
f32 vertices[] = UV_VERTICES(uvMin, uvMax);
|
|
||||||
|
|
||||||
canvas_texture_draw(&self->canvas, shaderTexture, texture.id, layerTransform, vertices, frame.tintRGBA, frame.offsetRGB);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (self->settings->previewIsBorder)
|
|
||||||
canvas_rect_draw(&self->canvas, shaderLine, layerTransform, PREVIEW_BORDER_COLOR);
|
|
||||||
|
|
||||||
if (self->settings->previewIsPivots)
|
|
||||||
{
|
|
||||||
f32 vertices[] = ATLAS_UV_VERTICES(ATLAS_PIVOT);
|
|
||||||
mat4 pivotModel = canvas_model_get(CANVAS_PIVOT_SIZE, frame.position, CANVAS_PIVOT_SIZE * 0.5f, PERCENT_TO_UNIT(frame.scale), frame.rotation);
|
|
||||||
mat4 pivotTransform = transform * (rootModel * pivotModel);
|
|
||||||
canvas_texture_draw(&self->canvas, shaderTexture, self->resources->atlas.id, pivotTransform, vertices, PREVIEW_PIVOT_COLOR);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Nulls
|
|
||||||
if (self->settings->previewIsTargets)
|
|
||||||
{
|
|
||||||
for (auto& [id, nullAnimation] : animation->nullAnimations)
|
|
||||||
{
|
|
||||||
if (!nullAnimation.isVisible || nullAnimation.frames.size() <= 0)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
Anm2Frame frame;
|
|
||||||
anm2_frame_from_time(self->anm2, &frame, Anm2Reference{animationID, ANM2_NULL, id}, self->time);
|
|
||||||
|
|
||||||
if (!frame.isVisible)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
Anm2Null null = self->anm2->nulls[id];
|
|
||||||
|
|
||||||
vec4 color = (self->reference->itemType == ANM2_NULL && self->reference->itemID == id) ?
|
|
||||||
PREVIEW_NULL_SELECTED_COLOR :
|
|
||||||
PREVIEW_NULL_COLOR;
|
|
||||||
|
|
||||||
vec2 size = null.isShowRect ? CANVAS_PIVOT_SIZE : PREVIEW_TARGET_SIZE;
|
|
||||||
AtlasType atlas = null.isShowRect ? ATLAS_SQUARE : ATLAS_TARGET;
|
|
||||||
|
|
||||||
mat4 model = canvas_model_get(size, frame.position, size * 0.5f, PERCENT_TO_UNIT(frame.scale), frame.rotation);
|
|
||||||
mat4 nullTransform = transform * (rootModel * model);
|
|
||||||
|
|
||||||
f32 vertices[] = ATLAS_UV_VERTICES(atlas);
|
|
||||||
|
|
||||||
canvas_texture_draw(&self->canvas, shaderTexture, self->resources->atlas.id, nullTransform, vertices, color);
|
|
||||||
|
|
||||||
if (null.isShowRect)
|
|
||||||
{
|
|
||||||
mat4 rectModel = canvas_model_get(PREVIEW_NULL_RECT_SIZE, frame.position, PREVIEW_NULL_RECT_SIZE * 0.5f, PERCENT_TO_UNIT(frame.scale), frame.rotation);
|
|
||||||
mat4 rectTransform = transform * (rootModel * rectModel);
|
|
||||||
canvas_rect_draw(&self->canvas, shaderLine, rectTransform, color);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
s32& animationOverlayID = self->animationOverlayID;
|
|
||||||
Anm2Animation* animationOverlay = map_find(self->anm2->animations, animationOverlayID);
|
|
||||||
|
|
||||||
if (animationOverlay)
|
|
||||||
{
|
|
||||||
Anm2Frame root;
|
|
||||||
mat4 rootModel = mat4(1.0f);
|
|
||||||
|
|
||||||
anm2_frame_from_time(self->anm2, &root, Anm2Reference{animationOverlayID, ANM2_ROOT}, self->time);
|
|
||||||
|
|
||||||
if (self->settings->previewIsRootTransform)
|
|
||||||
rootModel = canvas_parent_model_get(root.position, {}, PERCENT_TO_UNIT(root.scale));
|
|
||||||
|
|
||||||
for (auto [i, id] : self->anm2->layerMap)
|
|
||||||
{
|
|
||||||
Anm2Frame frame;
|
|
||||||
Anm2Item& layerAnimation = animationOverlay->layerAnimations[id];
|
|
||||||
|
|
||||||
if (!layerAnimation.isVisible || layerAnimation.frames.size() <= 0)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
anm2_frame_from_time(self->anm2, &frame, Anm2Reference{animationOverlayID, ANM2_LAYER, id}, self->time);
|
|
||||||
|
|
||||||
if (!frame.isVisible)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
Texture& texture = self->anm2->spritesheets[self->anm2->layers[id].spritesheetID].texture;
|
|
||||||
|
|
||||||
if (texture.isInvalid) continue;
|
|
||||||
|
|
||||||
vec2 uvMin = frame.crop / vec2(texture.size);
|
vec2 uvMin = frame.crop / vec2(texture.size);
|
||||||
vec2 uvMax = (frame.crop + frame.size) / vec2(texture.size);
|
vec2 uvMax = (frame.crop + frame.size) / vec2(texture.size);
|
||||||
f32 vertices[] = UV_VERTICES(uvMin, uvMax);
|
f32 vertices[] = UV_VERTICES(uvMin, uvMax);
|
||||||
|
canvas_texture_draw(&self->canvas, shaderTexture, texture.id, layerTransform, vertices, frameTint, frameColorOffset);
|
||||||
|
|
||||||
mat4 model = canvas_model_get(frame.size, frame.position, frame.pivot, PERCENT_TO_UNIT(frame.scale), frame.rotation);
|
if (self->settings->previewIsBorder)
|
||||||
mat4 layerTransform = transform * (rootModel * model);
|
{
|
||||||
|
vec4 borderColor = isOnionskin ? vec4(colorOffset, 1.0f - alphaOffset) : PREVIEW_BORDER_COLOR;
|
||||||
|
canvas_rect_draw(&self->canvas, shaderLine, layerTransform, borderColor);
|
||||||
|
}
|
||||||
|
|
||||||
vec4 tint = frame.tintRGBA;
|
if (self->settings->previewIsPivots)
|
||||||
tint.a *= U8_TO_FLOAT(self->settings->previewOverlayTransparency);
|
{
|
||||||
|
vec4 pivotColor = isOnionskin ? vec4(colorOffset, 1.0f - alphaOffset) : PREVIEW_PIVOT_COLOR;
|
||||||
|
f32 vertices[] = ATLAS_UV_VERTICES(ATLAS_PIVOT);
|
||||||
|
mat4 pivotModel = canvas_model_get(CANVAS_PIVOT_SIZE, frame.position, CANVAS_PIVOT_SIZE * 0.5f, PERCENT_TO_UNIT(frame.scale), frame.rotation);
|
||||||
|
mat4 pivotTransform = transform * (rootModel * pivotModel);
|
||||||
|
canvas_texture_draw(&self->canvas, shaderTexture, self->resources->atlas.id, pivotTransform, vertices, pivotColor);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
canvas_texture_draw(&self->canvas, shaderTexture, texture.id, layerTransform, vertices, tint, frame.offsetRGB);
|
auto null_draw = [&](mat4 rootModel, s32 id, f32 time, vec3 colorOffset = {}, f32 alphaOffset = {}, bool isOnionskin = {})
|
||||||
}
|
{
|
||||||
}
|
Anm2Item& nullAnimation = animation->nullAnimations[id];
|
||||||
|
if (!nullAnimation.isVisible || nullAnimation.frames.size() <= 0) return;
|
||||||
|
|
||||||
|
Anm2Frame frame;
|
||||||
|
anm2_frame_from_time(self->anm2, &frame, Anm2Reference{animationID, ANM2_NULL, id}, time);
|
||||||
|
if (!frame.isVisible) return;
|
||||||
|
|
||||||
|
Anm2Null null = self->anm2->nulls[id];
|
||||||
|
|
||||||
|
vec4 color = isOnionskin ? vec4(colorOffset, 1.0f - alphaOffset) :
|
||||||
|
(self->reference->itemType == ANM2_NULL && self->reference->itemID == id) ?
|
||||||
|
PREVIEW_NULL_SELECTED_COLOR : PREVIEW_NULL_COLOR;
|
||||||
|
|
||||||
|
vec2 size = null.isShowRect ? CANVAS_PIVOT_SIZE : PREVIEW_TARGET_SIZE;
|
||||||
|
AtlasType atlas = null.isShowRect ? ATLAS_SQUARE : self->settings->previewIsAltIcons ? ATLAS_TARGET_ALT : ATLAS_TARGET;
|
||||||
|
|
||||||
|
mat4 model = canvas_model_get(size, frame.position, size * 0.5f, PERCENT_TO_UNIT(frame.scale), frame.rotation);
|
||||||
|
mat4 nullTransform = transform * (rootModel * model);
|
||||||
|
|
||||||
|
f32 vertices[] = ATLAS_UV_VERTICES(atlas);
|
||||||
|
|
||||||
|
canvas_texture_draw(&self->canvas, shaderTexture, self->resources->atlas.id, nullTransform, vertices, color);
|
||||||
|
|
||||||
|
if (null.isShowRect)
|
||||||
|
{
|
||||||
|
mat4 rectModel = canvas_model_get(PREVIEW_NULL_RECT_SIZE, frame.position, PREVIEW_NULL_RECT_SIZE * 0.5f, PERCENT_TO_UNIT(frame.scale), frame.rotation);
|
||||||
|
mat4 rectTransform = transform * (rootModel * rectModel);
|
||||||
|
canvas_rect_draw(&self->canvas, shaderLine, rectTransform, color);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
auto base_draw = [&](f32 time, vec3 colorOffset = {}, f32 alphaOffset = {}, bool isOnionskin = {})
|
||||||
|
{
|
||||||
|
Anm2Frame root;
|
||||||
|
anm2_frame_from_time(self->anm2, &root, Anm2Reference{animationID, ANM2_ROOT}, time);
|
||||||
|
|
||||||
|
mat4 rootModel = self->settings->previewIsRootTransform ?
|
||||||
|
canvas_parent_model_get(root.position, {}, PERCENT_TO_UNIT(root.scale), root.rotation) : mat4(1.0f);
|
||||||
|
|
||||||
|
if (self->settings->previewIsTargets && animation->rootAnimation.isVisible && root.isVisible)
|
||||||
|
root_draw(root, colorOffset, alphaOffset, isOnionskin);
|
||||||
|
|
||||||
|
for (auto [i, id] : self->anm2->layerMap)
|
||||||
|
layer_draw(rootModel, id, time, colorOffset, alphaOffset, isOnionskin);
|
||||||
|
|
||||||
|
if (self->settings->previewIsTargets)
|
||||||
|
for (auto& [id, _] : animation->nullAnimations)
|
||||||
|
null_draw(rootModel, id, time, colorOffset, alphaOffset, isOnionskin);
|
||||||
|
};
|
||||||
|
|
||||||
|
auto onionskin_draw = [&](s32 count, s32 direction, vec3 colorOffset)
|
||||||
|
{
|
||||||
|
for (s32 i = 1; i <= count; i++)
|
||||||
|
{
|
||||||
|
f32 time = self->time + (f32)(direction * i);
|
||||||
|
f32 alphaOffset = (1.0f / (count + 1)) * i;
|
||||||
|
base_draw(time, colorOffset, alphaOffset, true);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
auto onionskins_draw = [&]()
|
||||||
|
{
|
||||||
|
if (!self->settings->onionskinIsEnabled) return;
|
||||||
|
onionskin_draw(self->settings->onionskinBeforeCount, -1, self->settings->onionskinBeforeColorOffset);
|
||||||
|
onionskin_draw(self->settings->onionskinAfterCount, 1, self->settings->onionskinAfterColorOffset);
|
||||||
|
};
|
||||||
|
|
||||||
|
if (self->settings->onionskinDrawOrder == ONIONSKIN_BELOW) onionskins_draw();
|
||||||
|
base_draw(self->time);
|
||||||
|
if (self->settings->onionskinDrawOrder == ONIONSKIN_ABOVE) onionskins_draw();
|
||||||
|
};
|
||||||
|
|
||||||
|
animation_draw(self->reference->animationID);
|
||||||
|
animation_draw(self->animationOverlayID);
|
||||||
|
|
||||||
canvas_unbind();
|
canvas_unbind();
|
||||||
}
|
}
|
||||||
|
@@ -42,6 +42,8 @@ struct Preview
|
|||||||
f32 time{};
|
f32 time{};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void preview_init(Preview* self, Anm2* anm2, Anm2Reference* reference, Resources* resources, Settings* settings);
|
void preview_init(Preview* self, Anm2* anm2, Anm2Reference* reference, Resources* resources, Settings* settings);
|
||||||
void preview_draw(Preview* self);
|
void preview_draw(Preview* self);
|
||||||
void preview_tick(Preview* self);
|
void preview_tick(Preview* self);
|
||||||
|
@@ -7,17 +7,16 @@ enum RenderType
|
|||||||
RENDER_PNG,
|
RENDER_PNG,
|
||||||
RENDER_GIF,
|
RENDER_GIF,
|
||||||
RENDER_WEBM,
|
RENDER_WEBM,
|
||||||
RENDER_MP4
|
RENDER_MP4,
|
||||||
|
RENDER_COUNT
|
||||||
};
|
};
|
||||||
|
|
||||||
constexpr inline s32 RENDER_COUNT = RENDER_MP4 + 1;
|
|
||||||
|
|
||||||
const inline std::string RENDER_TYPE_STRINGS[] =
|
const inline std::string RENDER_TYPE_STRINGS[] =
|
||||||
{
|
{
|
||||||
"PNG Images",
|
"PNG Images",
|
||||||
"GIF image",
|
"GIF image",
|
||||||
"WebM video",
|
"WebM video",
|
||||||
"MP4 video"
|
"MP4 video",
|
||||||
};
|
};
|
||||||
|
|
||||||
const inline std::string RENDER_EXTENSIONS[RENDER_COUNT] =
|
const inline std::string RENDER_EXTENSIONS[RENDER_COUNT] =
|
||||||
@@ -25,5 +24,5 @@ const inline std::string RENDER_EXTENSIONS[RENDER_COUNT] =
|
|||||||
".png",
|
".png",
|
||||||
".gif",
|
".gif",
|
||||||
".webm",
|
".webm",
|
||||||
".mp4"
|
".mp4",
|
||||||
};
|
};
|
166
src/settings.cpp
166
src/settings.cpp
@@ -6,70 +6,87 @@ static void _settings_setting_load(Settings* self, const std::string& line)
|
|||||||
{
|
{
|
||||||
const auto& entry = SETTINGS_ENTRIES[i];
|
const auto& entry = SETTINGS_ENTRIES[i];
|
||||||
const std::string& key = entry.key;
|
const std::string& key = entry.key;
|
||||||
|
|
||||||
void* target = (u8*)self + entry.offset;
|
void* target = (u8*)self + entry.offset;
|
||||||
|
|
||||||
auto match_key = [&](const std::string& full) -> const char*
|
auto match_key = [&](const std::string& full) -> const char*
|
||||||
{
|
{
|
||||||
if (!line.starts_with(full))
|
if (!line.starts_with(full))
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
size_t p = full.size();
|
size_t p = full.size();
|
||||||
while (p < line.size() && std::isspace((u8)line[p])) ++p;
|
while (p < line.size() && std::isspace((u8)line[p])) ++p;
|
||||||
if (p < line.size() && line[p] == '=') return line.c_str() + p + 1;
|
if (p < line.size() && line[p] == '=')
|
||||||
|
return line.c_str() + p + 1;
|
||||||
return nullptr;
|
return nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
auto* value = match_key(key);
|
const char* value = nullptr;
|
||||||
|
|
||||||
if (value)
|
switch (entry.type)
|
||||||
{
|
{
|
||||||
switch (entry.type)
|
case TYPE_INT:
|
||||||
|
if ((value = match_key(key))) { *(s32*)target = std::atoi(value); return; }
|
||||||
|
break;
|
||||||
|
case TYPE_BOOL:
|
||||||
|
if ((value = match_key(key))) { *(bool*)target = string_to_bool(value); return; }
|
||||||
|
break;
|
||||||
|
case TYPE_FLOAT:
|
||||||
|
if ((value = match_key(key))) { *(f32*)target = std::atof(value); return; }
|
||||||
|
break;
|
||||||
|
case TYPE_STRING:
|
||||||
|
if ((value = match_key(key))) { *(std::string*)target = value; return; }
|
||||||
|
break;
|
||||||
|
case TYPE_IVEC2:
|
||||||
{
|
{
|
||||||
case TYPE_INT:
|
ivec2* v = (ivec2*)target;
|
||||||
*(s32*)target = std::atoi(value);
|
if ((value = match_key(key + "X"))) { v->x = std::atoi(value); return; }
|
||||||
return;
|
if ((value = match_key(key + "Y"))) { v->y = std::atoi(value); return; }
|
||||||
case TYPE_BOOL:
|
break;
|
||||||
*(bool*)target = string_to_bool(value);
|
|
||||||
return;
|
|
||||||
case TYPE_FLOAT:
|
|
||||||
*(f32*)target = std::atof(value);
|
|
||||||
return;
|
|
||||||
case TYPE_STRING:
|
|
||||||
*(std::string*)target = value;
|
|
||||||
return;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
case TYPE_IVEC2_WH:
|
||||||
|
{
|
||||||
if (entry.type == TYPE_VEC2)
|
ivec2* v = (ivec2*)target;
|
||||||
{
|
if ((value = match_key(key + "W"))) { v->x = std::atoi(value); return; }
|
||||||
vec2* v = (vec2*)target;
|
if ((value = match_key(key + "H"))) { v->y = std::atoi(value); return; }
|
||||||
if ((value = match_key(key + (entry.isWidthHeight ? "W" : "X")))) { v->x = std::atof(value); return; }
|
break;
|
||||||
if ((value = match_key(key + (entry.isWidthHeight ? "H" : "Y")))) { v->y = std::atof(value); return; }
|
};
|
||||||
}
|
case TYPE_VEC2:
|
||||||
else if (entry.type == TYPE_IVEC2)
|
{
|
||||||
{
|
vec2* v = (vec2*)target;
|
||||||
ivec2* v = (ivec2*)target;
|
if ((value = match_key(key + "X"))) { v->x = std::atof(value); return; }
|
||||||
if ((value = match_key(key + (entry.isWidthHeight ? "W" : "X")))) { v->x = std::atoi(value); return; }
|
if ((value = match_key(key + "Y"))) { v->y = std::atof(value); return; }
|
||||||
if ((value = match_key(key + (entry.isWidthHeight ? "H" : "Y")))) { v->y = std::atoi(value); return; }
|
break;
|
||||||
}
|
}
|
||||||
else if (entry.type == TYPE_VEC3)
|
case TYPE_VEC2_WH:
|
||||||
{
|
{
|
||||||
vec3* v = (vec3*)target;
|
vec2* v = (vec2*)target;
|
||||||
if ((value = match_key(key + "R"))) { v->x = std::atof(value); return; }
|
if ((value = match_key(key + "W"))) { v->x = std::atof(value); return; }
|
||||||
if ((value = match_key(key + "G"))) { v->y = std::atof(value); return; }
|
if ((value = match_key(key + "H"))) { v->y = std::atof(value); return; }
|
||||||
if ((value = match_key(key + "B"))) { v->z = std::atof(value); return; }
|
break;
|
||||||
}
|
};
|
||||||
else if (entry.type == TYPE_VEC4)
|
case TYPE_VEC3:
|
||||||
{
|
{
|
||||||
vec4* v = (vec4*)target;
|
vec3* v = (vec3*)target;
|
||||||
if ((value = match_key(key + "R"))) { v->x = std::atof(value); return; }
|
if ((value = match_key(key + "R"))) { v->x = std::atof(value); return; }
|
||||||
if ((value = match_key(key + "G"))) { v->y = std::atof(value); return; }
|
if ((value = match_key(key + "G"))) { v->y = std::atof(value); return; }
|
||||||
if ((value = match_key(key + "B"))) { v->z = std::atof(value); return; }
|
if ((value = match_key(key + "B"))) { v->z = std::atof(value); return; }
|
||||||
if ((value = match_key(key + "A"))) { v->w = std::atof(value); return; }
|
break;
|
||||||
|
}
|
||||||
|
case TYPE_VEC4:
|
||||||
|
{
|
||||||
|
vec4* v = (vec4*)target;
|
||||||
|
if ((value = match_key(key + "R"))) { v->x = std::atof(value); return; }
|
||||||
|
if ((value = match_key(key + "G"))) { v->y = std::atof(value); return; }
|
||||||
|
if ((value = match_key(key + "B"))) { v->z = std::atof(value); return; }
|
||||||
|
if ((value = match_key(key + "A"))) { v->w = std::atof(value); return; }
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
log_warning(std::format(SETTINGS_VALUE_INIT_WARNING, line));
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string settings_path_get(void)
|
std::string settings_path_get(void)
|
||||||
@@ -107,15 +124,29 @@ static void _settings_setting_write(Settings* self, std::ostream& out, SettingsE
|
|||||||
case TYPE_IVEC2:
|
case TYPE_IVEC2:
|
||||||
{
|
{
|
||||||
ivec2* data = (ivec2*)(selfPointer + entry.offset);
|
ivec2* data = (ivec2*)(selfPointer + entry.offset);
|
||||||
out << entry.key << (entry.isWidthHeight ? "W=" : "X=") << data->x << "\n";
|
out << entry.key << "X=" << data->x << "\n";
|
||||||
out << entry.key << (entry.isWidthHeight ? "H=" : "Y=") << data->y << "\n";
|
out << entry.key << "Y=" << data->y << "\n";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case TYPE_IVEC2_WH:
|
||||||
|
{
|
||||||
|
ivec2* data = (ivec2*)(selfPointer + entry.offset);
|
||||||
|
out << entry.key << "W=" << data->x << "\n";
|
||||||
|
out << entry.key << "H=" << data->y << "\n";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case TYPE_VEC2:
|
case TYPE_VEC2:
|
||||||
{
|
{
|
||||||
vec2* data = (vec2*)(selfPointer + entry.offset);
|
vec2* data = (vec2*)(selfPointer + entry.offset);
|
||||||
out << entry.key << (entry.isWidthHeight ? "W=" : "X=") << std::format(SETTINGS_FLOAT_FORMAT, data->x) << "\n";
|
out << entry.key << "X=" << std::format(SETTINGS_FLOAT_FORMAT, data->x) << "\n";
|
||||||
out << entry.key << (entry.isWidthHeight ? "H=" : "Y=") << std::format(SETTINGS_FLOAT_FORMAT, data->y) << "\n";
|
out << entry.key << "Y=" << std::format(SETTINGS_FLOAT_FORMAT, data->y) << "\n";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case TYPE_VEC2_WH:
|
||||||
|
{
|
||||||
|
vec2* data = (vec2*)(selfPointer + entry.offset);
|
||||||
|
out << entry.key << "W=" << std::format(SETTINGS_FLOAT_FORMAT, data->x) << "\n";
|
||||||
|
out << entry.key << "H=" << std::format(SETTINGS_FLOAT_FORMAT, data->y) << "\n";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case TYPE_VEC3:
|
case TYPE_VEC3:
|
||||||
@@ -214,47 +245,32 @@ void settings_init(Settings* self)
|
|||||||
{
|
{
|
||||||
const std::string path = settings_path_get();
|
const std::string path = settings_path_get();
|
||||||
std::ifstream file(path, std::ios::binary);
|
std::ifstream file(path, std::ios::binary);
|
||||||
std::istream* in = nullptr;
|
|
||||||
std::istringstream defaultSettings;
|
|
||||||
|
|
||||||
if (file)
|
if (file)
|
||||||
{
|
|
||||||
log_info(std::format(SETTINGS_INIT_INFO, path));
|
log_info(std::format(SETTINGS_INIT_INFO, path));
|
||||||
in = &file;
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
log_error(std::format(SETTINGS_INIT_ERROR, path));
|
log_warning(std::format(SETTINGS_INIT_WARNING, path));
|
||||||
log_info(SETTINGS_DEFAULT_INFO);
|
settings_save(self);
|
||||||
defaultSettings.str(SETTINGS_DEFAULT);
|
std::ofstream out(path, std::ios::binary | std::ios::app);
|
||||||
in = &defaultSettings;
|
out << SETTINGS_IMGUI_DEFAULT;
|
||||||
|
out.flush();
|
||||||
|
out.close();
|
||||||
|
file.open(path, std::ios::binary);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string line;
|
std::string line;
|
||||||
bool inSettingsSection = false;
|
bool inSettingsSection = false;
|
||||||
|
|
||||||
while (std::getline(*in, line))
|
while (std::getline(file, line))
|
||||||
{
|
{
|
||||||
if (line == SETTINGS_SECTION)
|
if (line == SETTINGS_SECTION)
|
||||||
{
|
{
|
||||||
inSettingsSection = true;
|
inSettingsSection = true;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
if (line.empty()) continue;
|
||||||
if (line == SETTINGS_SECTION_IMGUI) break;
|
if (line == SETTINGS_SECTION_IMGUI) break;
|
||||||
if (inSettingsSection) _settings_setting_load(self, line);
|
if (inSettingsSection) _settings_setting_load(self, line);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Save default settings
|
|
||||||
if (!file)
|
|
||||||
{
|
|
||||||
std::ofstream out(path, std::ios::binary | std::ios::trunc);
|
|
||||||
if (out)
|
|
||||||
{
|
|
||||||
out << SETTINGS_DEFAULT;
|
|
||||||
out.flush();
|
|
||||||
log_info(std::format(SETTINGS_SAVE_INFO, path));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
log_error(std::format(SETTINGS_DEFAULT_ERROR, path));
|
|
||||||
}
|
|
||||||
}
|
}
|
471
src/settings.h
471
src/settings.h
@@ -4,17 +4,15 @@
|
|||||||
#include "render.h"
|
#include "render.h"
|
||||||
#include "tool.h"
|
#include "tool.h"
|
||||||
|
|
||||||
#define SETTINGS_BUFFER 0xFFFF
|
|
||||||
#define SETTINGS_BUFFER_ITEM 0xFF
|
|
||||||
#define SETTINGS_SECTION "[Settings]"
|
#define SETTINGS_SECTION "[Settings]"
|
||||||
#define SETTINGS_SECTION_IMGUI "# Dear ImGui"
|
#define SETTINGS_SECTION_IMGUI "# Dear ImGui"
|
||||||
#define SETTINGS_INIT_ERROR "Failed to read settings file: {}"
|
#define SETTINGS_INIT_WARNING "Unable to read settings file: {}; using default settings"
|
||||||
#define SETTINGS_DEFAULT_ERROR "Failed to write default settings file: {}"
|
#define SETTINGS_INIT_ERROR "Unable to read settings file: {}"
|
||||||
#define SETTINGS_SAVE_ERROR "Failed to write settings file: {}"
|
#define SETTINGS_SAVE_ERROR "Failed to write settings file: {}"
|
||||||
#define SETTINGS_SAVE_FINALIZE_ERROR "Failed to write settings file: {} ({})"
|
#define SETTINGS_SAVE_FINALIZE_ERROR "Failed to write settings file: {} ({})"
|
||||||
|
#define SETTINGS_VALUE_INIT_WARNING "Unknown setting: {}"
|
||||||
#define SETTINGS_FLOAT_FORMAT "{:.3f}"
|
#define SETTINGS_FLOAT_FORMAT "{:.3f}"
|
||||||
#define SETTINGS_INIT_INFO "Initialized settings from: {}"
|
#define SETTINGS_INIT_INFO "Initialized settings from: {}"
|
||||||
#define SETTINGS_DEFAULT_INFO "Using default settings"
|
|
||||||
#define SETTINGS_DIRECTORY_ERROR "Failed to create settings directory: {} ({})"
|
#define SETTINGS_DIRECTORY_ERROR "Failed to create settings directory: {} ({})"
|
||||||
#define SETTINGS_SAVE_INFO "Saved settings to: {}"
|
#define SETTINGS_SAVE_INFO "Saved settings to: {}"
|
||||||
|
|
||||||
@@ -22,277 +20,224 @@
|
|||||||
#define SETTINGS_PATH "settings.ini"
|
#define SETTINGS_PATH "settings.ini"
|
||||||
#define SETTINGS_TEMPORARY_EXTENSION ".tmp"
|
#define SETTINGS_TEMPORARY_EXTENSION ".tmp"
|
||||||
|
|
||||||
|
#define SETTINGS_LIST \
|
||||||
|
/* name, symbol, type, defaultValue */ \
|
||||||
|
X(windowSize, WINDOW_SIZE, TYPE_IVEC2_WH, {1280, 720}) \
|
||||||
|
X(isVsync, IS_VSYNC, TYPE_BOOL, true) \
|
||||||
|
\
|
||||||
|
X(hotkeyCenterView, HOTKEY_CENTER_VIEW, TYPE_STRING, "Home") \
|
||||||
|
X(hotkeyZoomIn, HOTKEY_ZOOM_IN, TYPE_STRING, "Ctrl++") \
|
||||||
|
X(hotkeyZoomOut, HOTKEY_ZOOM_OUT, TYPE_STRING, "Ctrl+-") \
|
||||||
|
X(hotkeyPlayPause, HOTKEY_PLAY_PAUSE, TYPE_STRING, "Space") \
|
||||||
|
X(hotkeyOnionskin, HOTKEY_ONIONSKIN, TYPE_STRING, "O") \
|
||||||
|
X(hotkeyNew, HOTKEY_NEW, TYPE_STRING, "Ctrl+N") \
|
||||||
|
X(hotkeyOpen, HOTKEY_OPEN, TYPE_STRING, "Ctrl+O") \
|
||||||
|
X(hotkeySave, HOTKEY_SAVE, TYPE_STRING, "Ctrl+S") \
|
||||||
|
X(hotkeySaveAs, HOTKEY_SAVE_AS, TYPE_STRING, "Ctrl+Shift+S") \
|
||||||
|
X(hotkeyExit, HOTKEY_EXIT, TYPE_STRING, "Alt+F4") \
|
||||||
|
X(hotkeyPan, HOTKEY_PAN, TYPE_STRING, "P") \
|
||||||
|
X(hotkeyMove, HOTKEY_MOVE, TYPE_STRING, "V") \
|
||||||
|
X(hotkeyRotate, HOTKEY_ROTATE, TYPE_STRING, "R") \
|
||||||
|
X(hotkeyScale, HOTKEY_SCALE, TYPE_STRING, "S") \
|
||||||
|
X(hotkeyCrop, HOTKEY_CROP, TYPE_STRING, "C") \
|
||||||
|
X(hotkeyDraw, HOTKEY_DRAW, TYPE_STRING, "B") \
|
||||||
|
X(hotkeyErase, HOTKEY_ERASE, TYPE_STRING, "E") \
|
||||||
|
X(hotkeyColorPicker, HOTKEY_COLOR_PICKER, TYPE_STRING, "I") \
|
||||||
|
X(hotkeyUndo, HOTKEY_UNDO, TYPE_STRING, "Ctrl+Z") \
|
||||||
|
X(hotkeyRedo, HOTKEY_REDO, TYPE_STRING, "Ctrl+Shift+Z") \
|
||||||
|
X(hotkeyCopy, HOTKEY_COPY, TYPE_STRING, "Ctrl+C") \
|
||||||
|
X(hotkeyCut, HOTKEY_CUT, TYPE_STRING, "Ctrl+X") \
|
||||||
|
X(hotkeyPaste, HOTKEY_PASTE, TYPE_STRING, "Ctrl+V") \
|
||||||
|
\
|
||||||
|
X(playbackIsLoop, PLAYBACK_IS_LOOP, TYPE_BOOL, true) \
|
||||||
|
X(playbackIsClampPlayhead,PLAYBACK_IS_CLAMP_PLAYHEAD, TYPE_BOOL, true) \
|
||||||
|
\
|
||||||
|
X(changeIsCrop, CHANGE_IS_CROP, TYPE_BOOL, false) \
|
||||||
|
X(changeIsSize, CHANGE_IS_SIZE, TYPE_BOOL, false) \
|
||||||
|
X(changeIsPosition, CHANGE_IS_POSITION, TYPE_BOOL, false) \
|
||||||
|
X(changeIsPivot, CHANGE_IS_PIVOT, TYPE_BOOL, false) \
|
||||||
|
X(changeIsScale, CHANGE_IS_SCALE, TYPE_BOOL, false) \
|
||||||
|
X(changeIsRotation, CHANGE_IS_ROTATION, TYPE_BOOL, false) \
|
||||||
|
X(changeIsDelay, CHANGE_IS_DELAY, TYPE_BOOL, false) \
|
||||||
|
X(changeIsTint, CHANGE_IS_TINT, TYPE_BOOL, false) \
|
||||||
|
X(changeIsColorOffset, CHANGE_IS_COLOR_OFFSET, TYPE_BOOL, false) \
|
||||||
|
X(changeIsVisibleSet, CHANGE_IS_VISIBLE_SET, TYPE_BOOL, false) \
|
||||||
|
X(changeIsInterpolatedSet,CHANGE_IS_INTERPOLATED_SET, TYPE_BOOL, false) \
|
||||||
|
X(changeIsFromSelectedFrame,CHANGE_IS_FROM_SELECTED_FRAME,TYPE_BOOL, false) \
|
||||||
|
X(changeCrop, CHANGE_CROP, TYPE_VEC2, {}) \
|
||||||
|
X(changeSize, CHANGE_SIZE, TYPE_VEC2, {}) \
|
||||||
|
X(changePosition, CHANGE_POSITION, TYPE_VEC2, {}) \
|
||||||
|
X(changePivot, CHANGE_PIVOT, TYPE_VEC2, {}) \
|
||||||
|
X(changeScale, CHANGE_SCALE, TYPE_VEC2, {}) \
|
||||||
|
X(changeRotation, CHANGE_ROTATION, TYPE_FLOAT, 0.0f) \
|
||||||
|
X(changeDelay, CHANGE_DELAY, TYPE_INT, 0) \
|
||||||
|
X(changeTint, CHANGE_TINT, TYPE_VEC4, {}) \
|
||||||
|
X(changeColorOffset, CHANGE_COLOR_OFFSET, TYPE_VEC3, {}) \
|
||||||
|
X(changeIsVisible, CHANGE_IS_VISIBLE, TYPE_BOOL, false) \
|
||||||
|
X(changeIsInterpolated, CHANGE_IS_INTERPOLATED, TYPE_BOOL, false) \
|
||||||
|
X(changeNumberFrames, CHANGE_NUMBER_FRAMES, TYPE_INT, 1) \
|
||||||
|
\
|
||||||
|
X(scaleValue, SCALE_VALUE, TYPE_FLOAT, 1.0f) \
|
||||||
|
\
|
||||||
|
X(previewIsAxes, PREVIEW_IS_AXES, TYPE_BOOL, true) \
|
||||||
|
X(previewIsGrid, PREVIEW_IS_GRID, TYPE_BOOL, true) \
|
||||||
|
X(previewIsRootTransform, PREVIEW_IS_ROOT_TRANSFORM, TYPE_BOOL, false) \
|
||||||
|
X(previewIsTriggers, PREVIEW_IS_TRIGGERS, TYPE_BOOL, true) \
|
||||||
|
X(previewIsPivots, PREVIEW_IS_PIVOTS, TYPE_BOOL, false) \
|
||||||
|
X(previewIsTargets, PREVIEW_IS_TARGETS, TYPE_BOOL, true) \
|
||||||
|
X(previewIsBorder, PREVIEW_IS_BORDER, TYPE_BOOL, false) \
|
||||||
|
X(previewIsAltIcons, PREVIEW_IS_ALT_ICONS, TYPE_BOOL, false) \
|
||||||
|
X(previewOverlayTransparency,PREVIEW_OVERLAY_TRANSPARENCY,TYPE_FLOAT, 255.0f) \
|
||||||
|
X(previewZoom, PREVIEW_ZOOM, TYPE_FLOAT, 200.0f) \
|
||||||
|
X(previewPan, PREVIEW_PAN, TYPE_VEC2, {}) \
|
||||||
|
X(previewGridSize, PREVIEW_GRID_SIZE, TYPE_IVEC2, {32,32}) \
|
||||||
|
X(previewGridOffset, PREVIEW_GRID_OFFSET, TYPE_IVEC2, {}) \
|
||||||
|
X(previewGridColor, PREVIEW_GRID_COLOR, TYPE_VEC4, {1.0,1.0,1.0,0.125}) \
|
||||||
|
X(previewAxesColor, PREVIEW_AXES_COLOR, TYPE_VEC4, {1.0,1.0,1.0,0.125}) \
|
||||||
|
X(previewBackgroundColor, PREVIEW_BACKGROUND_COLOR, TYPE_VEC4, {0.113,0.184,0.286,1.0}) \
|
||||||
|
\
|
||||||
|
X(generateStartPosition, GENERATE_START_POSITION, TYPE_IVEC2, {}) \
|
||||||
|
X(generateSize, GENERATE_SIZE, TYPE_IVEC2, {64,64}) \
|
||||||
|
X(generatePivot, GENERATE_PIVOT, TYPE_IVEC2, {32,32}) \
|
||||||
|
X(generateRows, GENERATE_ROWS, TYPE_INT, 4) \
|
||||||
|
X(generateColumns, GENERATE_COLUMNS, TYPE_INT, 4) \
|
||||||
|
X(generateCount, GENERATE_COUNT, TYPE_INT, 16) \
|
||||||
|
X(generateDelay, GENERATE_DELAY, TYPE_INT, 1) \
|
||||||
|
\
|
||||||
|
X(editorIsGrid, EDITOR_IS_GRID, TYPE_BOOL, true) \
|
||||||
|
X(editorIsGridSnap, EDITOR_IS_GRID_SNAP, TYPE_BOOL, true) \
|
||||||
|
X(editorIsBorder, EDITOR_IS_BORDER, TYPE_BOOL, true) \
|
||||||
|
X(editorZoom, EDITOR_ZOOM, TYPE_FLOAT, 200.0f) \
|
||||||
|
X(editorPan, EDITOR_PAN, TYPE_VEC2, {0.0,0.0}) \
|
||||||
|
X(editorGridSize, EDITOR_GRID_SIZE, TYPE_IVEC2, {32,32}) \
|
||||||
|
X(editorGridOffset, EDITOR_GRID_OFFSET, TYPE_IVEC2, {32,32}) \
|
||||||
|
X(editorGridColor, EDITOR_GRID_COLOR, TYPE_VEC4, {1.0,1.0,1.0,0.125}) \
|
||||||
|
X(editorBackgroundColor, EDITOR_BACKGROUND_COLOR, TYPE_VEC4, {0.113,0.184,0.286,1.0}) \
|
||||||
|
\
|
||||||
|
X(mergeType, MERGE_TYPE, TYPE_INT, ANM2_MERGE_APPEND_FRAMES) \
|
||||||
|
X(mergeIsDeleteAnimationsAfter,MERGE_IS_DELETE_ANIMATIONS_AFTER,TYPE_BOOL, false) \
|
||||||
|
\
|
||||||
|
X(bakeInterval, BAKE_INTERVAL, TYPE_INT, 1) \
|
||||||
|
X(bakeIsRoundScale, BAKE_IS_ROUND_SCALE, TYPE_BOOL, true) \
|
||||||
|
X(bakeIsRoundRotation, BAKE_IS_ROUND_ROTATION, TYPE_BOOL, true) \
|
||||||
|
\
|
||||||
|
X(onionskinIsEnabled, ONIONSKIN_IS_ENABLED, TYPE_BOOL, false) \
|
||||||
|
X(onionskinDrawOrder, ONIONSKIN_DRAW_ORDER, TYPE_INT, ONIONSKIN_BELOW) \
|
||||||
|
X(onionskinBeforeCount, ONIONSKIN_BEFORE_COUNT, TYPE_INT, 1) \
|
||||||
|
X(onionskinAfterCount, ONIONSKIN_AFTER_COUNT, TYPE_INT, 1) \
|
||||||
|
X(onionskinBeforeColorOffset,ONIONSKIN_BEFORE_COLOR_OFFSET,TYPE_VEC3, COLOR_RED) \
|
||||||
|
X(onionskinAfterColorOffset, ONIONSKIN_AFTER_COLOR_OFFSET,TYPE_VEC3, COLOR_BLUE) \
|
||||||
|
\
|
||||||
|
X(tool, TOOL, TYPE_INT, TOOL_PAN) \
|
||||||
|
X(toolColor, TOOL_COLOR, TYPE_VEC4, {1.0,1.0,1.0,1.0}) \
|
||||||
|
\
|
||||||
|
X(renderType, RENDER_TYPE, TYPE_INT, RENDER_PNG) \
|
||||||
|
X(renderPath, RENDER_PATH, TYPE_STRING, ".") \
|
||||||
|
X(renderFormat, RENDER_FORMAT, TYPE_STRING, "{}.png") \
|
||||||
|
X(ffmpegPath, FFMPEG_PATH, TYPE_STRING, "")
|
||||||
|
|
||||||
|
#define X(name, symbol, type, ...) \
|
||||||
|
const inline DATATYPE_TO_CTYPE(type) SETTINGS_##symbol##_DEFAULT = __VA_ARGS__;
|
||||||
|
SETTINGS_LIST
|
||||||
|
#undef X
|
||||||
|
|
||||||
|
struct Settings
|
||||||
|
{
|
||||||
|
#define X(name, symbol, type, ...) \
|
||||||
|
DATATYPE_TO_CTYPE(type) name = SETTINGS_##symbol##_DEFAULT;
|
||||||
|
SETTINGS_LIST
|
||||||
|
#undef X
|
||||||
|
};
|
||||||
|
|
||||||
struct SettingsEntry
|
struct SettingsEntry
|
||||||
{
|
{
|
||||||
std::string key;
|
std::string key;
|
||||||
DataType type;
|
DataType type;
|
||||||
s32 offset;
|
s32 offset;
|
||||||
bool isWidthHeight = false;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Settings
|
const inline SettingsEntry SETTINGS_ENTRIES[] =
|
||||||
{
|
{
|
||||||
ivec2 windowSize = {1600, 900};
|
#define X(name, symbol, type, ...) \
|
||||||
bool isVsync = true;
|
{ #name, type, offsetof(Settings, name) },
|
||||||
bool playbackIsLoop = true;
|
SETTINGS_LIST
|
||||||
bool playbackIsClampPlayhead = true;
|
#undef X
|
||||||
bool changeIsCrop = false;
|
|
||||||
bool changeIsSize = false;
|
|
||||||
bool changeIsPosition = false;
|
|
||||||
bool changeIsPivot = false;
|
|
||||||
bool changeIsScale = false;
|
|
||||||
bool changeIsRotation = false;
|
|
||||||
bool changeIsDelay = false;
|
|
||||||
bool changeIsTint = false;
|
|
||||||
bool changeIsColorOffset = false;
|
|
||||||
bool changeIsVisibleSet = false;
|
|
||||||
bool changeIsInterpolatedSet = false;
|
|
||||||
bool changeIsFromSelectedFrame = false;
|
|
||||||
vec2 changeCrop{};
|
|
||||||
vec2 changeSize{};
|
|
||||||
vec2 changePosition{};
|
|
||||||
vec2 changePivot{};
|
|
||||||
vec2 changeScale{};
|
|
||||||
f32 changeRotation{};
|
|
||||||
s32 changeDelay{};
|
|
||||||
vec4 changeTint{};
|
|
||||||
vec3 changeColorOffset{};
|
|
||||||
bool changeIsVisible{};
|
|
||||||
bool changeIsInterpolated{};
|
|
||||||
s32 changeNumberFrames = 1;
|
|
||||||
f32 scaleValue = 1.0f;
|
|
||||||
bool previewIsAxes = true;
|
|
||||||
bool previewIsGrid = true;
|
|
||||||
bool previewIsRootTransform = false;
|
|
||||||
bool previewIsTriggers = true;
|
|
||||||
bool previewIsPivots = false;
|
|
||||||
bool previewIsTargets = true;
|
|
||||||
bool previewIsBorder = false;
|
|
||||||
f32 previewOverlayTransparency = 255.0f;
|
|
||||||
f32 previewZoom = 200.0;
|
|
||||||
vec2 previewPan = {0.0, 0.0};
|
|
||||||
ivec2 previewGridSize = {32, 32};
|
|
||||||
ivec2 previewGridOffset{};
|
|
||||||
vec4 previewGridColor = {1.0, 1.0, 1.0, 0.125};
|
|
||||||
vec4 previewAxesColor = {1.0, 1.0, 1.0, 0.125};
|
|
||||||
vec4 previewBackgroundColor = {0.113, 0.184, 0.286, 1.0};
|
|
||||||
ivec2 generateStartPosition = {0, 0};
|
|
||||||
ivec2 generateSize = {64, 64};
|
|
||||||
ivec2 generatePivot = {32, 32};
|
|
||||||
s32 generateRows = 4;
|
|
||||||
s32 generateColumns = 4;
|
|
||||||
s32 generateCount = 16;
|
|
||||||
s32 generateDelay = 1;
|
|
||||||
bool editorIsGrid = true;
|
|
||||||
bool editorIsGridSnap = true;
|
|
||||||
bool editorIsBorder = true;
|
|
||||||
f32 editorZoom = 200.0;
|
|
||||||
vec2 editorPan = {0.0, 0.0};
|
|
||||||
ivec2 editorGridSize = {32, 32};
|
|
||||||
ivec2 editorGridOffset = {32, 32};
|
|
||||||
vec4 editorGridColor = {1.0, 1.0, 1.0, 0.125};
|
|
||||||
vec4 editorBackgroundColor = {0.113, 0.184, 0.286, 1.0};
|
|
||||||
s32 mergeType = ANM2_MERGE_APPEND_FRAMES;
|
|
||||||
bool mergeIsDeleteAnimationsAfter = false;
|
|
||||||
s32 bakeInterval = 1;
|
|
||||||
bool bakeIsRoundScale = true;
|
|
||||||
bool bakeIsRoundRotation = true;
|
|
||||||
s32 tool = TOOL_PAN;
|
|
||||||
vec4 toolColor = {1.0, 1.0, 1.0, 1.0};
|
|
||||||
s32 renderType = RENDER_PNG;
|
|
||||||
std::string renderPath = ".";
|
|
||||||
std::string renderFormat = "{}.png";
|
|
||||||
std::string ffmpegPath{};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const SettingsEntry SETTINGS_ENTRIES[] =
|
|
||||||
{
|
|
||||||
{"window", TYPE_IVEC2, offsetof(Settings, windowSize), true},
|
|
||||||
{"isVsync", TYPE_BOOL, offsetof(Settings, isVsync)},
|
|
||||||
{"playbackIsLoop", TYPE_BOOL, offsetof(Settings, playbackIsLoop)},
|
|
||||||
{"playbackIsClampPlayhead", TYPE_BOOL, offsetof(Settings, playbackIsClampPlayhead)},
|
|
||||||
{"changeIsCrop", TYPE_BOOL, offsetof(Settings, changeIsCrop)},
|
|
||||||
{"changeIsSize", TYPE_BOOL, offsetof(Settings, changeIsSize)},
|
|
||||||
{"changeIsPosition", TYPE_BOOL, offsetof(Settings, changeIsPosition)},
|
|
||||||
{"changeIsPivot", TYPE_BOOL, offsetof(Settings, changeIsPivot)},
|
|
||||||
{"changeIsScale", TYPE_BOOL, offsetof(Settings, changeIsScale)},
|
|
||||||
{"changeIsRotation", TYPE_BOOL, offsetof(Settings, changeIsRotation)},
|
|
||||||
{"changeIsDelay", TYPE_BOOL, offsetof(Settings, changeIsDelay)},
|
|
||||||
{"changeIsTint", TYPE_BOOL, offsetof(Settings, changeIsTint)},
|
|
||||||
{"changeIsColorOffset", TYPE_BOOL, offsetof(Settings, changeIsColorOffset)},
|
|
||||||
{"changeIsVisibleSet", TYPE_BOOL, offsetof(Settings, changeIsVisibleSet)},
|
|
||||||
{"changeIsInterpolatedSet", TYPE_BOOL, offsetof(Settings, changeIsInterpolatedSet)},
|
|
||||||
{"changeIsFromSelectedFrame", TYPE_BOOL, offsetof(Settings, changeIsFromSelectedFrame)},
|
|
||||||
{"changeCrop", TYPE_VEC2, offsetof(Settings, changeCrop)},
|
|
||||||
{"changeSize", TYPE_VEC2, offsetof(Settings, changeSize)},
|
|
||||||
{"changePosition", TYPE_VEC2, offsetof(Settings, changePosition)},
|
|
||||||
{"changePivot", TYPE_VEC2, offsetof(Settings, changePivot)},
|
|
||||||
{"changeScale", TYPE_VEC2, offsetof(Settings, changeScale)},
|
|
||||||
{"changeRotation", TYPE_FLOAT, offsetof(Settings, changeRotation)},
|
|
||||||
{"changeDelay", TYPE_INT, offsetof(Settings, changeDelay)},
|
|
||||||
{"changeTint", TYPE_VEC4, offsetof(Settings, changeTint)},
|
|
||||||
{"changeColorOffset", TYPE_VEC3, offsetof(Settings, changeColorOffset)},
|
|
||||||
{"changeIsVisible", TYPE_BOOL, offsetof(Settings, changeIsVisibleSet)},
|
|
||||||
{"changeIsInterpolated", TYPE_BOOL, offsetof(Settings, changeIsInterpolatedSet)},
|
|
||||||
{"changeNumberFrames", TYPE_INT, offsetof(Settings, changeNumberFrames)},
|
|
||||||
{"scaleValue", TYPE_FLOAT, offsetof(Settings, scaleValue)},
|
|
||||||
{"previewIsAxes", TYPE_BOOL, offsetof(Settings, previewIsAxes)},
|
|
||||||
{"previewIsGrid", TYPE_BOOL, offsetof(Settings, previewIsGrid)},
|
|
||||||
{"previewIsRootTransform", TYPE_BOOL, offsetof(Settings, previewIsRootTransform)},
|
|
||||||
{"previewIsTriggers", TYPE_BOOL, offsetof(Settings, previewIsTriggers)},
|
|
||||||
{"previewIsPivots", TYPE_BOOL, offsetof(Settings, previewIsPivots)},
|
|
||||||
{"previewIsTargets", TYPE_BOOL, offsetof(Settings, previewIsTargets)},
|
|
||||||
{"previewIsBorder", TYPE_BOOL, offsetof(Settings, previewIsBorder)},
|
|
||||||
{"previewOverlayTransparency", TYPE_FLOAT, offsetof(Settings, previewOverlayTransparency)},
|
|
||||||
{"previewZoom", TYPE_FLOAT, offsetof(Settings, previewZoom)},
|
|
||||||
{"previewPan", TYPE_VEC2, offsetof(Settings, previewPan)},
|
|
||||||
{"previewGridSize", TYPE_IVEC2, offsetof(Settings, previewGridSize)},
|
|
||||||
{"previewGridOffset", TYPE_IVEC2, offsetof(Settings, previewGridOffset)},
|
|
||||||
{"previewGridColor", TYPE_VEC4, offsetof(Settings, previewGridColor)},
|
|
||||||
{"previewAxesColor", TYPE_VEC4, offsetof(Settings, previewAxesColor)},
|
|
||||||
{"previewBackgroundColor", TYPE_VEC4, offsetof(Settings, previewBackgroundColor)},
|
|
||||||
{"generateStartPosition", TYPE_IVEC2, offsetof(Settings, generateStartPosition)},
|
|
||||||
{"generateSize", TYPE_IVEC2, offsetof(Settings, generateSize)},
|
|
||||||
{"generatePivot", TYPE_IVEC2, offsetof(Settings, generatePivot)},
|
|
||||||
{"generateRows", TYPE_INT, offsetof(Settings, generateRows)},
|
|
||||||
{"generateColumns", TYPE_INT, offsetof(Settings, generateColumns)},
|
|
||||||
{"generateCount", TYPE_INT, offsetof(Settings, generateCount)},
|
|
||||||
{"generateDelay", TYPE_INT, offsetof(Settings, generateDelay)},
|
|
||||||
{"editorIsGrid", TYPE_BOOL, offsetof(Settings, editorIsGrid)},
|
|
||||||
{"editorIsGridSnap", TYPE_BOOL, offsetof(Settings, editorIsGridSnap)},
|
|
||||||
{"editorIsBorder", TYPE_BOOL, offsetof(Settings, editorIsBorder)},
|
|
||||||
{"editorZoom", TYPE_FLOAT, offsetof(Settings, editorZoom)},
|
|
||||||
{"editorPan", TYPE_VEC2, offsetof(Settings, editorPan)},
|
|
||||||
{"editorGridSize", TYPE_IVEC2, offsetof(Settings, editorGridSize)},
|
|
||||||
{"editorGridOffset", TYPE_IVEC2, offsetof(Settings, editorGridOffset)},
|
|
||||||
{"editorGridColor", TYPE_VEC4, offsetof(Settings, editorGridColor)},
|
|
||||||
{"editorBackgroundColor", TYPE_VEC4, offsetof(Settings, editorBackgroundColor)},
|
|
||||||
{"mergeType", TYPE_INT, offsetof(Settings, mergeType)},
|
|
||||||
{"mergeIsDeleteAnimationsAfter", TYPE_BOOL, offsetof(Settings, mergeIsDeleteAnimationsAfter)},
|
|
||||||
{"bakeInterval", TYPE_INT, offsetof(Settings, bakeInterval)},
|
|
||||||
{"bakeRoundScale", TYPE_BOOL, offsetof(Settings, bakeIsRoundScale)},
|
|
||||||
{"bakeRoundRotation", TYPE_BOOL, offsetof(Settings, bakeIsRoundRotation)},
|
|
||||||
{"tool", TYPE_INT, offsetof(Settings, tool)},
|
|
||||||
{"toolColor", TYPE_VEC4, offsetof(Settings, toolColor)},
|
|
||||||
{"renderType", TYPE_INT, offsetof(Settings, renderType)},
|
|
||||||
{"renderPath", TYPE_STRING, offsetof(Settings, renderPath)},
|
|
||||||
{"renderFormat", TYPE_STRING, offsetof(Settings, renderFormat)},
|
|
||||||
{"ffmpegPath", TYPE_STRING, offsetof(Settings, ffmpegPath)}
|
|
||||||
};
|
|
||||||
constexpr s32 SETTINGS_COUNT = (s32)std::size(SETTINGS_ENTRIES);
|
constexpr s32 SETTINGS_COUNT = (s32)std::size(SETTINGS_ENTRIES);
|
||||||
|
|
||||||
const std::string SETTINGS_DEFAULT = R"(
|
#define HOTKEY_LIST \
|
||||||
[Settings]
|
X(NONE, "None") \
|
||||||
windowW=1600
|
X(CENTER_VIEW, "Center View") \
|
||||||
windowH=900
|
X(ZOOM_IN, "Zoom In") \
|
||||||
isVsync=true
|
X(ZOOM_OUT, "Zoom Out") \
|
||||||
playbackIsLoop=true
|
X(PLAY_PAUSE, "Play/Pause") \
|
||||||
playbackIsClampPlayhead=false
|
X(ONIONSKIN, "Onionskin") \
|
||||||
changeIsCrop=false
|
X(NEW, "New") \
|
||||||
changeIsSize=false
|
X(OPEN, "Open") \
|
||||||
changeIsPosition=false
|
X(SAVE, "Save") \
|
||||||
changeIsPivot=false
|
X(SAVE_AS, "Save As") \
|
||||||
changeIsScale=false
|
X(EXIT, "Exit") \
|
||||||
changeIsRotation=false
|
X(PAN, "Pan") \
|
||||||
changeIsDelay=false
|
X(MOVE, "Move") \
|
||||||
changeIsTint=false
|
X(ROTATE, "Rotate") \
|
||||||
changeIsColorOffset=false
|
X(SCALE, "Scale") \
|
||||||
changeIsVisibleSet=false
|
X(CROP, "Crop") \
|
||||||
changeIsInterpolatedSet=false
|
X(DRAW, "Draw") \
|
||||||
changeIsFromSelectedFrame=false
|
X(ERASE, "Erase") \
|
||||||
changeCropX=0.000
|
X(COLOR_PICKER, "Color Picker") \
|
||||||
changeCropY=0.000
|
X(UNDO, "Undo") \
|
||||||
changeSizeX=0.000
|
X(REDO, "Redo") \
|
||||||
changeSizeY=0.000
|
X(COPY, "Copy") \
|
||||||
changePositionX=0.000
|
X(CUT, "Cut") \
|
||||||
changePositionY=0.000
|
X(PASTE, "Paste") \
|
||||||
changePivotX=0.000
|
|
||||||
changePivotY=0.000
|
|
||||||
changeScaleX=0.000
|
|
||||||
changeScaleY=0.000
|
|
||||||
changeRotation=0.000
|
|
||||||
changeDelay=1
|
|
||||||
changeTintR=0.000
|
|
||||||
changeTintG=0.000
|
|
||||||
changeTintB=0.000
|
|
||||||
changeTintA=0.000
|
|
||||||
changeColorOffsetR=0.000
|
|
||||||
changeColorOffsetG=0.000
|
|
||||||
changeColorOffsetB=0.000
|
|
||||||
changeIsVisible=false
|
|
||||||
changeIsInterpolated=false
|
|
||||||
changeNumberFrames=1
|
|
||||||
scaleValue=1.000
|
|
||||||
previewIsAxes=true
|
|
||||||
previewIsGrid=false
|
|
||||||
previewIsRootTransform=true
|
|
||||||
previewIsTriggers=false
|
|
||||||
previewIsPivots=false
|
|
||||||
previewIsTargets=true
|
|
||||||
previewIsBorder=false
|
|
||||||
previewOverlayTransparency=255.000
|
|
||||||
previewZoom=400.000
|
|
||||||
previewPanX=0.000
|
|
||||||
previewPanY=0.000
|
|
||||||
previewGridSizeX=32
|
|
||||||
previewGridSizeY=32
|
|
||||||
previewGridOffsetX=16
|
|
||||||
previewGridOffsetY=16
|
|
||||||
previewGridColorR=1.000
|
|
||||||
previewGridColorG=1.000
|
|
||||||
previewGridColorB=1.000
|
|
||||||
previewGridColorA=0.125
|
|
||||||
previewAxesColorR=1.000
|
|
||||||
previewAxesColorG=1.000
|
|
||||||
previewAxesColorB=1.000
|
|
||||||
previewAxesColorA=0.125
|
|
||||||
previewBackgroundColorR=0.114
|
|
||||||
previewBackgroundColorG=0.184
|
|
||||||
previewBackgroundColorB=0.286
|
|
||||||
previewBackgroundColorA=1.000
|
|
||||||
generateStartPositionX=0
|
|
||||||
generateStartPositionY=0
|
|
||||||
generateSizeX=0
|
|
||||||
generateSizeY=0
|
|
||||||
generatePivotX=0
|
|
||||||
generatePivotY=0
|
|
||||||
generateRows=4
|
|
||||||
generateColumns=4
|
|
||||||
generateCount=16
|
|
||||||
generateDelay=1
|
|
||||||
editorIsGrid=true
|
|
||||||
editorIsGridSnap=true
|
|
||||||
editorIsBorder=true
|
|
||||||
editorZoom=400.000
|
|
||||||
editorPanX=0.000
|
|
||||||
editorPanY=0.000
|
|
||||||
editorGridSizeX=32
|
|
||||||
editorGridSizeY=32
|
|
||||||
editorGridOffsetX=16
|
|
||||||
editorGridOffsetY=16
|
|
||||||
editorGridColorR=1.000
|
|
||||||
editorGridColorG=1.000
|
|
||||||
editorGridColorB=1.000
|
|
||||||
editorGridColorA=0.125
|
|
||||||
editorBackgroundColorR=0.113
|
|
||||||
editorBackgroundColorG=0.183
|
|
||||||
editorBackgroundColorB=0.286
|
|
||||||
editorBackgroundColorA=1.000
|
|
||||||
mergeType=1
|
|
||||||
mergeIsDeleteAnimationsAfter=false
|
|
||||||
bakeInterval=1
|
|
||||||
bakeRoundScale=true
|
|
||||||
bakeRoundRotation=true
|
|
||||||
tool=0
|
|
||||||
toolColorR=0.000
|
|
||||||
toolColorG=0.000
|
|
||||||
toolColorB=0.000
|
|
||||||
toolColorA=1.000
|
|
||||||
renderType=0
|
|
||||||
renderPath=.
|
|
||||||
renderFormat={}.png
|
|
||||||
ffmpegPath=
|
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
#define X(name, str) HOTKEY_##name,
|
||||||
|
HOTKEY_LIST
|
||||||
|
#undef X
|
||||||
|
HOTKEY_COUNT
|
||||||
|
} HotkeyType;
|
||||||
|
|
||||||
|
const inline char* HOTKEY_STRINGS[] =
|
||||||
|
{
|
||||||
|
#define X(name, str) str,
|
||||||
|
HOTKEY_LIST
|
||||||
|
#undef X
|
||||||
|
};
|
||||||
|
|
||||||
|
using HotkeyMember = std::string Settings::*;
|
||||||
|
|
||||||
|
const inline HotkeyMember SETTINGS_HOTKEY_MEMBERS[HOTKEY_COUNT] =
|
||||||
|
{
|
||||||
|
nullptr,
|
||||||
|
&Settings::hotkeyCenterView,
|
||||||
|
&Settings::hotkeyZoomIn,
|
||||||
|
&Settings::hotkeyZoomOut,
|
||||||
|
&Settings::hotkeyPlayPause,
|
||||||
|
&Settings::hotkeyOnionskin,
|
||||||
|
&Settings::hotkeyNew,
|
||||||
|
&Settings::hotkeyOpen,
|
||||||
|
&Settings::hotkeySave,
|
||||||
|
&Settings::hotkeySaveAs,
|
||||||
|
&Settings::hotkeyExit,
|
||||||
|
&Settings::hotkeyPan,
|
||||||
|
&Settings::hotkeyMove,
|
||||||
|
&Settings::hotkeyRotate,
|
||||||
|
&Settings::hotkeyScale,
|
||||||
|
&Settings::hotkeyCrop,
|
||||||
|
&Settings::hotkeyDraw,
|
||||||
|
&Settings::hotkeyErase,
|
||||||
|
&Settings::hotkeyColorPicker,
|
||||||
|
&Settings::hotkeyUndo,
|
||||||
|
&Settings::hotkeyRedo,
|
||||||
|
&Settings::hotkeyCopy,
|
||||||
|
&Settings::hotkeyCut,
|
||||||
|
&Settings::hotkeyPaste
|
||||||
|
};
|
||||||
|
|
||||||
|
const std::string SETTINGS_IMGUI_DEFAULT = R"(
|
||||||
# Dear ImGui
|
# Dear ImGui
|
||||||
[Window][## Window]
|
[Window][## Window]
|
||||||
Pos=0,32
|
Pos=0,32
|
||||||
|
Reference in New Issue
Block a user