Refactoring; Started GUI for interior layout graph

This commit is contained in:
2024-10-25 22:16:35 +03:00
parent 2cc591706f
commit 3b4006e02d
19 changed files with 1713 additions and 1148 deletions

View File

@@ -993,42 +993,6 @@
"lanes": -1,
"pattern": 1,
"buildings": [
{
"building_key": "",
"line_offset": 0,
"normal_offset": 0,
"y_rotation": 0
},
{
"building_key": "",
"line_offset": 0,
"normal_offset": 0,
"y_rotation": 0
},
{
"building_key": "",
"line_offset": 0,
"normal_offset": 0,
"y_rotation": 0
},
{
"building_key": "Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 192.51, 0.0385437, -75 )",
"line_offset": 17.490011,
"normal_offset": -0,
"y_rotation": 0
},
{
"building_key": "Transform( 1, 0, 9.53674e-07, 0, 1, 0, -9.53674e-07, 0, 1, 147.621, 0.0346222, -75 )",
"line_offset": 62.379005,
"normal_offset": -0,
"y_rotation": 0.000001
},
{
"building_key": "Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 112.609, 0.0179977, -75 )",
"line_offset": 97.391006,
"normal_offset": -0,
"y_rotation": 0
}
]
},
"buildings9_buildings": {
@@ -1046,46 +1010,53 @@
"pattern": 1,
"buildings": [
{
"building_key": "Transform( 0.252425, 0, 0.967616, 0, 1, 0, -0.967616, 0, 0.252425, 325.572, 0.0140915, -373.025 )",
"line_offset": 17.543036,
"normal_offset": -0,
"y_rotation": 1.315611
},
{
"building_key": "Transform( 0.252425, 0, 0.967616, 0, 1, 0, -0.967616, 0, 0.252425, 314.233, 0.0113754, -329.558 )",
"line_offset": 62.464645,
"normal_offset": -0,
"y_rotation": 1.315611
},
{
"building_key": "Transform( 0.252422, 0, 0.967617, 0, 1, 0, -0.967617, 0, 0.252422, 305.37, 0.0140915, -295.584 )",
"line_offset": 97.575691,
"normal_offset": -0,
"y_rotation": 1.315614
},
{
"building_key": "Transform( -0.826927, 0, -0.56231, 0, 1, 0, 0.56231, 0, -0.826927, 386.071, 0.0181885, -285.928 )",
"line_offset": 208.283112,
"building_key": "",
"line_offset": 0,
"normal_offset": 0,
"y_rotation": -2.544416
"y_rotation": 0,
"y_offset": 0
},
{
"building_key": "Transform( -0.826926, 0, -0.562311, 0, 1, 0, 0.562311, 0, -0.826926, 414.911, 0.0102997, -305.54 )",
"line_offset": 243.159698,
"building_key": "",
"line_offset": 0,
"normal_offset": 0,
"y_rotation": -2.544415
"y_rotation": 0,
"y_offset": 0
},
{
"building_key": "Transform( -0.826925, 0, -0.562312, 0, 1, 0, 0.562312, 0, -0.826925, 456, -0.00187683, -333.48 )",
"line_offset": 292.848206,
"building_key": "",
"line_offset": 0,
"normal_offset": 0,
"y_rotation": -2.544414
"y_rotation": 0,
"y_offset": 0
},
{
"building_key": "Transform( -1, 0, 0, 0, 1, 0, 0, 0, -1, 512.826, -0.00187683, -360 )",
"line_offset": 357.836792,
"building_key": "",
"line_offset": 0,
"normal_offset": 0,
"y_rotation": 3.141593
"y_rotation": 0,
"y_offset": 0
},
{
"building_key": "",
"line_offset": 0,
"normal_offset": 0,
"y_rotation": 0,
"y_offset": 0
},
{
"building_key": "",
"line_offset": 0,
"normal_offset": 0,
"y_rotation": 0,
"y_offset": 0
},
{
"building_key": "",
"line_offset": 0,
"normal_offset": 0,
"y_rotation": 0,
"y_offset": 0
}
]
},
@@ -1117,130 +1088,151 @@
"pattern": 2,
"buildings": [
{
"building_key": "Transform( -0.999911, 0, 0.0133308, 0, 1, 0, -0.0133308, 0, -0.999911, -132.505, 3.8147e-05, -279.767 )",
"line_offset": 17.496548,
"building_key": "",
"line_offset": 0,
"normal_offset": 0,
"y_rotation": 3.128262
"y_rotation": 0,
"y_offset": 0
},
{
"building_key": "Transform( -0.999911, 0, 0.0133325, 0, 1, 0, -0.0133325, 0, -0.999911, -87.5817, -0.00187683, -279.168 )",
"line_offset": 62.423843,
"building_key": "",
"line_offset": 0,
"normal_offset": 0,
"y_rotation": 3.12826
"y_rotation": 0,
"y_offset": 0
},
{
"building_key": "Transform( -0.999911, 0, 0.0133314, 0, 1, 0, -0.0133314, 0, -0.999911, -52.2412, 0.0127792, -278.697 )",
"line_offset": 97.767479,
"building_key": "",
"line_offset": 0,
"normal_offset": 0,
"y_rotation": 3.128261
"y_rotation": 0,
"y_offset": 0
},
{
"building_key": "Transform( -0.999911, 0, 0.0133351, 0, 1, 0, -0.0133351, 0, -0.999911, -1.69597, 0.0169067, -278.023 )",
"line_offset": 148.3172,
"building_key": "",
"line_offset": 0,
"normal_offset": 0,
"y_rotation": 3.128257
"y_rotation": 0,
"y_offset": 0
},
{
"building_key": "Transform( -0.999911, 0, 0.0133326, 0, 1, 0, -0.0133326, 0, -0.999911, 31.9662, 0.0140915, -277.574 )",
"line_offset": 181.982361,
"building_key": "",
"line_offset": 0,
"normal_offset": 0,
"y_rotation": 3.12826
"y_rotation": 0,
"y_offset": 0
},
{
"building_key": "Transform( -0.999911, 0, 0.0133316, 0, 1, 0, -0.0133316, 0, -0.999911, 80.3236, 0.019165, -276.929 )",
"line_offset": 230.34407,
"building_key": "",
"line_offset": 0,
"normal_offset": 0,
"y_rotation": 3.128261
"y_rotation": 0,
"y_offset": 0
},
{
"building_key": "Transform( -0.999911, 0, 0.0133311, 0, 1, 0, -0.0133311, 0, -0.999911, 115.211, 0.0228729, -276.464 )",
"line_offset": 265.234558,
"building_key": "",
"line_offset": 0,
"normal_offset": 0,
"y_rotation": 3.128261
"y_rotation": 0,
"y_offset": 0
},
{
"building_key": "Transform( -0.999911, 0, 0.0133318, 0, 1, 0, -0.0133318, 0, -0.999911, 164.491, 0.0140915, -275.807 )",
"line_offset": 314.518951,
"building_key": "",
"line_offset": 0,
"normal_offset": 0,
"y_rotation": 3.12826
"y_rotation": 0,
"y_offset": 0
},
{
"building_key": "Transform( -0.999911, 0, 0.0133307, 0, 1, 0, -0.0133307, 0, -0.999911, 199.246, -0.0331802, -275.343 )",
"line_offset": 349.277008,
"building_key": "",
"line_offset": 0,
"normal_offset": 0,
"y_rotation": 3.128262
"y_rotation": 0,
"y_offset": 0
},
{
"building_key": "Transform( -0.211332, 0, -0.977414, 0, 1, 0, 0.977414, 0, -0.211332, 236.48, -0.00166321, -328.096 )",
"line_offset": 429.356293,
"normal_offset": -0,
"y_rotation": -1.783734
"building_key": "",
"line_offset": 0,
"normal_offset": 0,
"y_rotation": 0,
"y_offset": 0
},
{
"building_key": "Transform( -0.211333, 0, -0.977414, 0, 1, 0, 0.977414, 0, -0.211333, 247.081, -0.001297, -377.125 )",
"line_offset": 479.51825,
"normal_offset": -0,
"y_rotation": -1.783735
"building_key": "",
"line_offset": 0,
"normal_offset": 0,
"y_rotation": 0,
"y_offset": 0
},
{
"building_key": "Transform( -0.211331, 0, -0.977414, 0, 1, 0, 0.977415, 0, -0.211331, 254.523, 0.0189209, -411.545 )",
"line_offset": 514.733582,
"normal_offset": -0,
"y_rotation": -1.783733
"building_key": "",
"line_offset": 0,
"normal_offset": 0,
"y_rotation": 0,
"y_offset": 0
},
{
"building_key": "Transform( 0.999924, 0, -0.0123398, 0, 1, 0, 0.0123398, 0, 0.999924, 239.47, -0.000640869, -460.315 )",
"line_offset": 589.84021,
"normal_offset": -0,
"y_rotation": -0.01234
"building_key": "",
"line_offset": 0,
"normal_offset": 0,
"y_rotation": 0,
"y_offset": 0
},
{
"building_key": "Transform( 0.999924, 0, -0.0123484, 0, 1, 0, 0.0123484, 0, 0.999924, 204.291, -0.00187683, -460.75 )",
"line_offset": 625.021912,
"normal_offset": -0,
"y_rotation": -0.012349
"building_key": "",
"line_offset": 0,
"normal_offset": 0,
"y_rotation": 0,
"y_offset": 0
},
{
"building_key": "Transform( 0.999924, 0, -0.0123436, 0, 1, 0, 0.0123436, 0, 0.999924, 154.158, 0.0606918, -461.368 )",
"line_offset": 675.158752,
"normal_offset": -0,
"y_rotation": -0.012344
"building_key": "",
"line_offset": 0,
"normal_offset": 0,
"y_rotation": 0,
"y_offset": 0
},
{
"building_key": "Transform( 0.999924, 0, -0.0123399, 0, 1, 0, 0.0123399, 0, 0.999924, 119.883, 0.0995483, -461.792 )",
"line_offset": 709.436401,
"normal_offset": -0,
"y_rotation": -0.01234
"building_key": "",
"line_offset": 0,
"normal_offset": 0,
"y_rotation": 0,
"y_offset": 0
},
{
"building_key": "Transform( 0.999924, 0, -0.0123464, 0, 1, 0, 0.0123464, 0, 0.999924, 70.166, 0.114784, -462.405 )",
"line_offset": 759.157104,
"normal_offset": -0,
"y_rotation": -0.012347
"building_key": "",
"line_offset": 0,
"normal_offset": 0,
"y_rotation": 0,
"y_offset": 0
},
{
"building_key": "Transform( 0.999924, 0, -0.0123453, 0, 1, 0, 0.0123453, 0, 0.999924, 34.9446, 0.165733, -462.84 )",
"line_offset": 794.381226,
"normal_offset": -0,
"y_rotation": -0.012346
"building_key": "",
"line_offset": 0,
"normal_offset": 0,
"y_rotation": 0,
"y_offset": 0
},
{
"building_key": "Transform( 0.999924, 0, -0.0123454, 0, 1, 0, 0.0123454, 0, 0.999924, -14.3668, 0.0253067, -463.449 )",
"line_offset": 843.696411,
"normal_offset": -0,
"y_rotation": -0.012346
"building_key": "",
"line_offset": 0,
"normal_offset": 0,
"y_rotation": 0,
"y_offset": 0
},
{
"building_key": "Transform( 0.999924, 0, -0.0123453, 0, 1, 0, 0.0123453, 0, 0.999924, -49.1236, 0.0152969, -463.878 )",
"line_offset": 878.455811,
"normal_offset": -0,
"y_rotation": -0.012346
"building_key": "",
"line_offset": 0,
"normal_offset": 0,
"y_rotation": 0,
"y_offset": 0
},
{
"building_key": "Transform( 0.999924, 0, -0.012343, 0, 1, 0, 0.012343, 0, 0.999924, -99.1523, 0.0240707, -464.496 )",
"line_offset": 928.488342,
"normal_offset": -0,
"y_rotation": -0.012343
"building_key": "",
"line_offset": 0,
"normal_offset": 0,
"y_rotation": 0,
"y_offset": 0
}
]
},
@@ -1280,337 +1272,393 @@
"building_key": "",
"line_offset": 0,
"normal_offset": 0,
"y_rotation": 0
"y_rotation": 0,
"y_offset": 0
},
{
"building_key": "",
"line_offset": 0,
"normal_offset": 0,
"y_rotation": 0
"y_rotation": 0,
"y_offset": 0
},
{
"building_key": "",
"line_offset": 0,
"normal_offset": 0,
"y_rotation": 0
"y_rotation": 0,
"y_offset": 0
},
{
"building_key": "",
"line_offset": 0,
"normal_offset": 0,
"y_rotation": 0
"y_rotation": 0,
"y_offset": 0
},
{
"building_key": "",
"line_offset": 0,
"normal_offset": 0,
"y_rotation": 0
"y_rotation": 0,
"y_offset": 0
},
{
"building_key": "",
"line_offset": 0,
"normal_offset": 0,
"y_rotation": 0
"y_rotation": 0,
"y_offset": 0
},
{
"building_key": "",
"line_offset": 0,
"normal_offset": 0,
"y_rotation": 0
"y_rotation": 0,
"y_offset": 0
},
{
"building_key": "",
"line_offset": 0,
"normal_offset": 0,
"y_rotation": 0
"y_rotation": 0,
"y_offset": 0
},
{
"building_key": "",
"line_offset": 0,
"normal_offset": 0,
"y_rotation": 0
"y_rotation": 0,
"y_offset": 0
},
{
"building_key": "",
"line_offset": 0,
"normal_offset": 0,
"y_rotation": 0
"y_rotation": 0,
"y_offset": 0
},
{
"building_key": "",
"line_offset": 0,
"normal_offset": 0,
"y_rotation": 0
"y_rotation": 0,
"y_offset": 0
},
{
"building_key": "",
"line_offset": 0,
"normal_offset": 0,
"y_rotation": 0
"y_rotation": 0,
"y_offset": 0
},
{
"building_key": "",
"line_offset": 0,
"normal_offset": 0,
"y_rotation": 0
"y_rotation": 0,
"y_offset": 0
},
{
"building_key": "",
"line_offset": 0,
"normal_offset": 0,
"y_rotation": 0
"y_rotation": 0,
"y_offset": 0
},
{
"building_key": "",
"line_offset": 0,
"normal_offset": 0,
"y_rotation": 0
"y_rotation": 0,
"y_offset": 0
},
{
"building_key": "",
"line_offset": 0,
"normal_offset": 0,
"y_rotation": 0
"y_rotation": 0,
"y_offset": 0
},
{
"building_key": "",
"line_offset": 0,
"normal_offset": 0,
"y_rotation": 0
"y_rotation": 0,
"y_offset": 0
},
{
"building_key": "",
"line_offset": 0,
"normal_offset": 0,
"y_rotation": 0
"y_rotation": 0,
"y_offset": 0
},
{
"building_key": "",
"line_offset": 0,
"normal_offset": 0,
"y_rotation": 0
"y_rotation": 0,
"y_offset": 0
},
{
"building_key": "",
"line_offset": 0,
"normal_offset": 0,
"y_rotation": 0
"y_rotation": 0,
"y_offset": 0
},
{
"building_key": "",
"line_offset": 0,
"normal_offset": 0,
"y_rotation": 0
"y_rotation": 0,
"y_offset": 0
},
{
"building_key": "",
"line_offset": 0,
"normal_offset": 0,
"y_rotation": 0
"y_rotation": 0,
"y_offset": 0
},
{
"building_key": "",
"line_offset": 0,
"normal_offset": 0,
"y_rotation": 0
"y_rotation": 0,
"y_offset": 0
},
{
"building_key": "",
"line_offset": 0,
"normal_offset": 0,
"y_rotation": 0
"y_rotation": 0,
"y_offset": 0
},
{
"building_key": "",
"line_offset": 0,
"normal_offset": 0,
"y_rotation": 0
"y_rotation": 0,
"y_offset": 0
},
{
"building_key": "",
"line_offset": 0,
"normal_offset": 0,
"y_rotation": 0
"y_rotation": 0,
"y_offset": 0
},
{
"building_key": "",
"line_offset": 0,
"normal_offset": 0,
"y_rotation": 0
"y_rotation": 0,
"y_offset": 0
},
{
"building_key": "",
"line_offset": 0,
"normal_offset": 0,
"y_rotation": 0
"y_rotation": 0,
"y_offset": 0
},
{
"building_key": "",
"line_offset": 0,
"normal_offset": 0,
"y_rotation": 0
"y_rotation": 0,
"y_offset": 0
},
{
"building_key": "",
"line_offset": 0,
"normal_offset": 0,
"y_rotation": 0
"y_rotation": 0,
"y_offset": 0
},
{
"building_key": "",
"line_offset": 0,
"normal_offset": 0,
"y_rotation": 0
"y_rotation": 0,
"y_offset": 0
},
{
"building_key": "",
"line_offset": 0,
"normal_offset": 0,
"y_rotation": 0
"y_rotation": 0,
"y_offset": 0
},
{
"building_key": "",
"line_offset": 0,
"normal_offset": 0,
"y_rotation": 0
"y_rotation": 0,
"y_offset": 0
},
{
"building_key": "",
"line_offset": 0,
"normal_offset": 0,
"y_rotation": 0
"y_rotation": 0,
"y_offset": 0
},
{
"building_key": "",
"line_offset": 0,
"normal_offset": 0,
"y_rotation": 0
"y_rotation": 0,
"y_offset": 0
},
{
"building_key": "",
"line_offset": 0,
"normal_offset": 0,
"y_rotation": 0
"y_rotation": 0,
"y_offset": 0
},
{
"building_key": "",
"line_offset": 0,
"normal_offset": 0,
"y_rotation": 0
"y_rotation": 0,
"y_offset": 0
},
{
"building_key": "",
"line_offset": 0,
"normal_offset": 0,
"y_rotation": 0
"y_rotation": 0,
"y_offset": 0
},
{
"building_key": "",
"line_offset": 0,
"normal_offset": 0,
"y_rotation": 0
"y_rotation": 0,
"y_offset": 0
},
{
"building_key": "",
"line_offset": 0,
"normal_offset": 0,
"y_rotation": 0
"y_rotation": 0,
"y_offset": 0
},
{
"building_key": "",
"line_offset": 0,
"normal_offset": 0,
"y_rotation": 0
"y_rotation": 0,
"y_offset": 0
},
{
"building_key": "",
"line_offset": 0,
"normal_offset": 0,
"y_rotation": 0
"y_rotation": 0,
"y_offset": 0
},
{
"building_key": "Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, -807.503, 0.0140915, -375 )",
"line_offset": 17.502991,
"normal_offset": -0,
"y_rotation": 0
},
{
"building_key": "Transform( 1, 0, 1.52588e-06, 0, 1, 0, -1.52588e-06, 0, 1, -852.561, 0.0140915, -375 )",
"line_offset": 62.560974,
"normal_offset": -0,
"y_rotation": 0.000002
},
{
"building_key": "Transform( 0.982871, 0, 0.184293, 0, 1, 0, -0.184293, 0, 0.982871, -917.236, 0.0146027, -370.831 )",
"line_offset": 127.623474,
"normal_offset": -0,
"y_rotation": 0.185353
},
{
"building_key": "Transform( 1, 0, 1.52588e-06, 0, 1, 0, -1.52588e-06, 0, 1, -996.222, 0.0140915, -360 )",
"line_offset": 207.616089,
"normal_offset": -0,
"y_rotation": 0.000002
},
{
"building_key": "Transform( 1, 0, 1.52588e-06, 0, 1, 0, -1.52588e-06, 0, 1, -1031.17, 0.0140915, -360 )",
"line_offset": 242.564148,
"normal_offset": -0,
"y_rotation": 0.000002
},
{
"building_key": "Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, -1080.97, 0.0144806, -360 )",
"line_offset": 292.364075,
"normal_offset": -0,
"y_rotation": 0
},
{
"building_key": "Transform( 0.371391, 0, 0.928477, 0, 1, 0, -0.928477, 0, 0.371391, -1129.74, 0.0215302, -335.643 )",
"line_offset": 357.626343,
"building_key": "",
"line_offset": 0,
"normal_offset": 0,
"y_rotation": 1.19029
"y_rotation": 0,
"y_offset": 0
},
{
"building_key": "Transform( -1, 0, 1.52588e-06, 0, 1, 0, -1.52588e-06, 0, -1, -1078.2, 0.0140915, -280 )",
"line_offset": 467.89624,
"building_key": "",
"line_offset": 0,
"normal_offset": 0,
"y_rotation": 3.141591
"y_rotation": 0,
"y_offset": 0
},
{
"building_key": "Transform( -1, 0, -3.05176e-06, 0, 1, 0, 3.05176e-06, 0, -1, -1043.2, 0.0140915, -280 )",
"line_offset": 502.89624,
"building_key": "",
"line_offset": 0,
"normal_offset": 0,
"y_rotation": -3.14159
"y_rotation": 0,
"y_offset": 0
},
{
"building_key": "Transform( -1, 0, -3.8147e-06, 0, 1, 0, 3.8147e-06, 0, -1, -993.383, 0.0270004, -280 )",
"line_offset": 552.713196,
"building_key": "",
"line_offset": 0,
"normal_offset": 0,
"y_rotation": -3.141589
"y_rotation": 0,
"y_offset": 0
},
{
"building_key": "Transform( -1, 0, -1.52588e-06, 0, 1, 0, 1.52588e-06, 0, -1, -943.889, 0.0416718, -280 )",
"line_offset": 602.207214,
"building_key": "",
"line_offset": 0,
"normal_offset": 0,
"y_rotation": -3.141591
"y_rotation": 0,
"y_offset": 0
},
{
"building_key": "Transform( -1, 0, 0, 0, 1, 0, 0, 0, -1, -909.404, 0.0602722, -280 )",
"line_offset": 636.6922,
"building_key": "",
"line_offset": 0,
"normal_offset": 0,
"y_rotation": 3.141593
"y_rotation": 0,
"y_offset": 0
},
{
"building_key": "Transform( -1, 0, 0, 0, 1, 0, 0, 0, -1, -864.082, 0.0658722, -280 )",
"line_offset": 682.014221,
"building_key": "",
"line_offset": 0,
"normal_offset": 0,
"y_rotation": 3.141593
"y_rotation": 0,
"y_offset": 0
},
{
"building_key": "Transform( -1, 0, 0, 0, 1, 0, 0, 0, -1, -829.033, 0.0537186, -280 )",
"line_offset": 717.063171,
"building_key": "",
"line_offset": 0,
"normal_offset": 0,
"y_rotation": 3.141593
"y_rotation": 0,
"y_offset": 0
},
{
"building_key": "",
"line_offset": 0,
"normal_offset": 0,
"y_rotation": 0,
"y_offset": 0
},
{
"building_key": "",
"line_offset": 0,
"normal_offset": 0,
"y_rotation": 0,
"y_offset": 0
},
{
"building_key": "",
"line_offset": 0,
"normal_offset": 0,
"y_rotation": 0,
"y_offset": 0
},
{
"building_key": "",
"line_offset": 0,
"normal_offset": 0,
"y_rotation": 0,
"y_offset": 0
},
{
"building_key": "",
"line_offset": 0,
"normal_offset": 0,
"y_rotation": 0,
"y_offset": 0
},
{
"building_key": "",
"line_offset": 0,
"normal_offset": 0,
"y_rotation": 0,
"y_offset": 0
}
]
},
@@ -1629,4 +1677,4 @@
]
}
}
}

View File

@@ -67,13 +67,13 @@ focus_mode = 2
unique_name_in_owner = true
margin_top = 52.0
margin_right = 248.0
margin_bottom = 500.0
margin_bottom = 524.0
[node name="v_buildings" type="VBoxContainer" parent="VBoxContainer"]
unique_name_in_owner = true
margin_top = 504.0
margin_top = 528.0
margin_right = 248.0
margin_bottom = 504.0
margin_bottom = 528.0
[node name="v_navigation" type="VBoxContainer" parent="VBoxContainer"]
unique_name_in_owner = true
@@ -116,10 +116,6 @@ margin_top = 246.0
margin_right = 248.0
margin_bottom = 1205.0
[node name="HSeparator" type="HSeparator" parent="VBoxContainer/v_road_lines"]
margin_right = 248.0
margin_bottom = 4.0
[node name="road_lines_base" type="PanelContainer" parent="VBoxContainer/v_road_lines"]
unique_name_in_owner = true
margin_top = 8.0
@@ -134,69 +130,6 @@ margin_bottom = 301.0
size_flags_horizontal = 3
size_flags_vertical = 3
[node name="road_lines_menu_block" type="HBoxContainer" parent="VBoxContainer/v_road_lines/road_lines_base/VBoxContainer"]
unique_name_in_owner = true
margin_right = 234.0
margin_bottom = 20.0
[node name="road_lines_file_menu" type="MenuButton" parent="VBoxContainer/v_road_lines/road_lines_base/VBoxContainer/road_lines_menu_block"]
unique_name_in_owner = true
margin_right = 35.0
margin_bottom = 20.0
focus_mode = 2
text = "File"
items = [ "Save Lines", null, 0, false, false, 101, 0, null, "", false ]
switch_on_hover = true
[node name="road_lines_edit_menu" type="MenuButton" parent="VBoxContainer/v_road_lines/road_lines_base/VBoxContainer/road_lines_menu_block"]
unique_name_in_owner = true
margin_left = 39.0
margin_right = 75.0
margin_bottom = 20.0
focus_mode = 2
text = "Edit"
items = [ "Undo", null, 0, false, false, 201, 0, null, "", false ]
switch_on_hover = true
[node name="road_lines_point_menu" type="MenuButton" parent="VBoxContainer/v_road_lines/road_lines_base/VBoxContainer/road_lines_menu_block"]
unique_name_in_owner = true
margin_left = 79.0
margin_right = 124.0
margin_bottom = 20.0
text = "Point"
items = [ "", null, 0, false, false, 0, 0, null, "", true, "Create", null, 0, false, false, 11, 0, null, "", false, "Remove", null, 0, false, false, 12, 0, null, "", false, "", null, 0, false, false, 3, 0, null, "", true, "Point To Cursor", null, 0, false, false, 51, 0, null, "", false, "Cursor To Point", null, 0, false, false, 52, 0, null, "", false, "Cursor to closest building", null, 0, false, false, 53, 0, null, "", false, "Item 7", null, 0, false, true, 7, 0, null, "", false ]
switch_on_hover = true
[node name="road_lines_line_menu" type="MenuButton" parent="VBoxContainer/v_road_lines/road_lines_base/VBoxContainer/road_lines_menu_block"]
unique_name_in_owner = true
margin_left = 128.0
margin_right = 167.0
margin_bottom = 20.0
focus_mode = 2
text = "Line"
items = [ "Create", null, 0, false, false, 21, 0, null, "", false, "Delete", null, 0, false, false, 22, 0, null, "", false, "", null, 0, false, false, -1, 0, null, "", true, "Remove Generated", null, 0, false, false, 30, 0, null, "", false, "Place Generated Objects", null, 0, false, false, 31, 0, null, "", false, "Edit Line Metadata", null, 0, false, false, 23, 0, null, "", false, "Rebuild roads", null, 0, false, false, 32, 0, null, "", false, "Remove road meshes", null, 0, false, false, 33, 0, null, "", false, "Assign close (generated) buildings", null, 0, false, false, 34, 0, null, "", false, "Create new building at cursor", null, 0, false, false, 35, 0, null, "", false, "View Buildings", null, 0, false, false, 36, 0, null, "", false ]
switch_on_hover = true
[node name="road_lines_options_menu" type="MenuButton" parent="VBoxContainer/v_road_lines/road_lines_base/VBoxContainer/road_lines_menu_block"]
unique_name_in_owner = true
margin_left = 171.0
margin_right = 234.0
margin_bottom = 20.0
text = "Options"
items = [ "Update roads", null, 1, false, false, 201, 0, null, "", false, "", null, 0, false, false, 1, 0, null, "", true, "Debug Road Nodes", null, 1, false, false, 210, 0, null, "", false, "Debug Road Edges", null, 1, false, false, 211, 0, null, "", false, "Debug Road Wedges", null, 1, false, false, 212, 0, null, "", false ]
switch_on_hover = true
[node name="HSeparator3" type="HSeparator" parent="VBoxContainer/v_road_lines/road_lines_base/VBoxContainer"]
margin_top = 24.0
margin_right = 234.0
margin_bottom = 28.0
[node name="Label" type="Label" parent="VBoxContainer/v_road_lines/road_lines_base/VBoxContainer"]
margin_top = 32.0
margin_right = 234.0
margin_bottom = 46.0
text = "Road Lines mode"
[node name="HBoxContainer" type="HBoxContainer" parent="VBoxContainer/v_road_lines/road_lines_base/VBoxContainer"]
margin_top = 50.0
margin_right = 234.0

View File

@@ -1,3 +1,5 @@
#ifndef BASE_DATA_H
#define BASE_DATA_H
#include "flecs/flecs.h"
class BaseData {
flecs::world ecs;
@@ -11,3 +13,4 @@ public:
static BaseData *get_singleton();
void cleanup();
};
#endif

View File

@@ -234,6 +234,7 @@ static LinesAccessor lines;
ImmediateGeometry *RoadLinesData::debug_im = nullptr;
static Ref<Material> debug_material;
RoadLinesData::RoadLinesData()
: initialized(false)
{
load_data();
}
@@ -286,6 +287,7 @@ RoadLinesData *RoadLinesData::get_singleton()
{
if (!singleton)
singleton = memnew(RoadLinesData);
assert(singleton->initialized);
return singleton;
}
RoadLinesData::~RoadLinesData()
@@ -321,7 +323,9 @@ void RoadLinesData::get_road_lines_key_list(List<String> *keys)
}
void RoadLinesData::get_lines_key_list(List<String> *keys)
{
assert(initialized);
::lines.get_key_list(keys);
assert(!keys->empty());
}
const String &RoadLinesData::get_next_line(const String &key)
{
@@ -337,6 +341,7 @@ void RoadLinesData::load_data()
ConfigFile config;
Error result = config.load("res://config/stream.conf");
ERR_FAIL_COND_MSG(result != OK, "Failed to load config");
assert(result == OK);
road_lines_path = config.get_value("lines", "road_lines_path");
String road_lines_path = config.get_value("lines", "road_lines_path");
String road_lines_json =
@@ -345,7 +350,8 @@ void RoadLinesData::load_data()
String es;
int eline;
Error status = JSON::parse(road_lines_json, json_v, es, eline);
ERR_FAIL_COND_MSG(status != OK, "Can't parse json: " + es +
ERR_FAIL_COND_MSG(status != OK, "Can't parse json: " + road_lines_path +
": " + es +
" at line: " + itos(eline));
Dictionary json = json_v;
@@ -384,6 +390,12 @@ void RoadLinesData::load_data()
set_line(key, rline);
e = e->next();
}
{
List<String> tkeys;
::lines.get_key_list(&tkeys);
assert(!tkeys.empty());
}
initialized = true;
}
void RoadLinesData::save_data()
{

View File

@@ -7,6 +7,7 @@ class RoadLinesData {
String road_lines_path;
uint32_t road_lines_hash(const Vector3 &v);
static ImmediateGeometry *debug_im;
bool initialized;
protected:
RoadLinesData();

View File

@@ -219,19 +219,6 @@ public:
, editor(editor)
{
int i;
Node *menu_block =
editor->get_as_node<Node>("%road_lines_menu_block");
for (i = 0; i < menu_block->get_child_count(); i++) {
Node *menu_button_node = menu_block->get_child(i);
MenuButton *menu_button =
Object::cast_to<MenuButton>(menu_button_node);
if (!menu_button)
continue;
PopupMenu *popup = menu_button->get_popup();
popup->connect("id_pressed", this, "main_handler");
// popup->connect("mouse_exited", popup, "hide");
popup->connect("focus_exited", popup, "hide");
}
Button *cancel_button = editor->get_as_node<Button>(
"%road_lines_create_new_cancel");
LineEdit *line_name = editor->get_as_node<LineEdit>(
@@ -282,17 +269,6 @@ public:
line_name->disconnect("text_changed", this, "changed_handler");
line_name->disconnect("text_entered", this, "entered_handler");
cancel_button->disconnect("pressed", this, "cancel_handler");
Node *menu_block =
editor->get_as_node<Node>("%road_lines_menu_block");
for (i = 0; i < menu_block->get_child_count(); i++) {
Node *menu_button_node = menu_block->get_child(i);
MenuButton *menu_button =
Object::cast_to<MenuButton>(menu_button_node);
if (!menu_button)
continue;
PopupMenu *popup = menu_button->get_popup();
popup->disconnect("id_pressed", this, "main_handler");
}
}
protected:
@@ -324,129 +300,6 @@ protected:
items->add_item(key);
}
}
void main_handler(int id)
{
switch (id) {
case 11:
editor->line_create_point();
break;
case 12:
editor->line_delete_point();
break;
case 21:
/* Create line */
editor->get_as_node<Control>("%road_lines_base")->hide();
editor->get_as_node<Control>(
"%road_lines_create_new_line_dlg")
->show();
break;
case 22:
/* delete line */
editor->delete_current_line();
break;
case 23:
/* edit line metadata */
if (current_line == "") {
print_error("No current line set");
return;
}
editor->get_as_node<Control>("%road_lines_base")->hide();
editor->get_as_node<Control>(
"%road_lines_edit_metadata_dlg")
->show();
update_metadata_editor();
break;
case 30:
editor->remove_generated_stuff();
break;
case 31:
editor->place_generated_objects();
break;
case 32:
editor->rebuild_roads();
break;
case 33:
editor->remove_road_meshes();
break;
case 34: {
RoadLinesData::get_singleton()->assign_close_buildings(
current_line);
editor->update_line_geometry();
} break;
case 36:
editor->get_as_node<Control>("%road_lines_base")->hide();
editor->get_as_node<Control>("%road_lines_buildings")
->show();
update_line_buildings_editor();
break;
case 51:
editor->set_point_to_cursor();
break;
case 52:
editor->move_cursor_to_point();
break;
case 53:
editor->move_cursor_to_closest_building();
case 101:
editor->save_data();
break;
case 201:
case 210:
case 211:
case 212: {
print_line("selected item 201");
int i, j;
Node *menu_block = editor->get_as_node<Node>(
"%road_lines_menu_block");
for (i = 0; i < menu_block->get_child_count(); i++) {
Node *menu_button_node =
menu_block->get_child(i);
MenuButton *menu_button =
Object::cast_to<MenuButton>(
menu_button_node);
if (!menu_button)
continue;
PopupMenu *popup = menu_button->get_popup();
for (j = 0; j < popup->get_item_count(); j++) {
int nid = popup->get_item_id(j);
if (nid == id) {
bool checked =
popup->is_item_checked(
j);
if (checked)
print_line("checked");
else
print_line("unchecked");
checked = !checked;
popup->set_item_checked(
j, checked);
switch (id) {
case 201:
editor->set_update_roads(
checked);
break;
case 210:
editor->set_debug_road_nodes(
checked);
break;
case 211:
editor->set_debug_road_edges(
checked);
break;
case 212:
editor->set_debug_road_wedges(
checked);
break;
}
}
}
}
} break;
default:
print_line("menu option pressed: " + itos(id));
assert(false);
}
}
void cancel_handler()
{
LineEdit *line_name = editor->get_as_node<LineEdit>(
@@ -553,8 +406,6 @@ protected:
}
static void _bind_methods()
{
ClassDB::bind_method(D_METHOD("main_handler", "id"),
&HandleCreateNewLine::main_handler);
ClassDB::bind_method(D_METHOD("cancel_handler"),
&HandleCreateNewLine::cancel_handler);
ClassDB::bind_method(D_METHOD("entered_handler", "new_text"),
@@ -1127,6 +978,38 @@ void RoadLinesEditor::set_debug_road_wedges(bool checked)
{
debug_road_wedges = checked;
}
const String &RoadLinesEditor::get_current_line() const
{
return current_line;
}
const String &RoadLinesEditor::get_filter_text() const
{
return filter_text;
}
void RoadLinesEditor::get_matching_lines(List<String> *lines)
{
if (!re.is_valid())
re.instance();
re->compile(filter_text);
if (filter_text.length() > 0 && !re->is_valid())
return;
List<String> line_keys;
RoadLinesData *rld = RoadLinesData::get_singleton();
rld->get_lines_key_list(&line_keys);
assert(!line_keys.empty());
lines->clear();
List<String>::Element *e = line_keys.front();
while (e) {
Array matches = re->search_all(e->get());
if (filter_text.length() > 0 && matches.size() == 0) {
e = e->next();
continue;
}
lines->push_back(e->get());
e = e->next();
}
assert(!lines->empty());
}
void RoadLinesEditor::place_zebras()
{
editor->editor_command("remove_buildings_by_prefix", varray("zebra"));

View File

@@ -59,6 +59,9 @@ public:
void set_debug_road_nodes(bool checked);
void set_debug_road_edges(bool checked);
void set_debug_road_wedges(bool checked);
const String &get_current_line() const;
const String &get_filter_text() const;
void get_matching_lines(List<String> *lines);
protected:
void activate();

View File

@@ -0,0 +1,107 @@
#ifndef BUILDING_LAYOUT_GRAPH_UI_H
#define BUILDING_LAYOUT_GRAPH_UI_H
#include <cassert>
#include <vector>
#include <core/object.h>
#include <core/variant.h>
#include <core/engine.h>
#include <scene/gui/dialogs.h>
#include <scene/gui/menu_button.h>
#include <scene/gui/color_rect.h>
#include "ui_field_builder.h"
class BuildingLayoutGraphUI : public Object {
GDCLASS(BuildingLayoutGraphUI, Object)
WindowDialog *dlg;
Control *canvas_item;
public:
BuildingLayoutGraphUI(WindowDialog *dlg)
: Object()
, dlg(dlg)
{
dlg->connect("tree_entered", this, "tree_entered");
}
void tree_entered()
{
if (!Engine::get_singleton()->is_editor_hint()) {
/* move this elsewhere */
std::vector<Variant> args_data2 = {
/* clang-format off */
MARGIN_RIGHT, 1.0f, MARGIN_BOTTOM, 1.0f,
// Control::SIZE_EXPAND_FILL, Control::SIZE_EXPAND_FILL,
// MARGIN_RIGHT, 1.0f, MARGIN_BOTTOM, 1.0f,
// Control::SIZE_EXPAND_FILL, Control::SIZE_EXPAND_FILL,
"Layout Graph",
MARGIN_RIGHT, 1.0f, MARGIN_BOTTOM, 1.0f,
"buildings_layout_graph",
MARGIN_RIGHT, 1.0f, MARGIN_BOTTOM, 1.0f,
"Interior",
"Exterior",
/* clang-format on */
};
ui_field::ui_field_builder(
dlg, dlg,
// "p+={t+={v#{s#!+={}}v#{}v#{}}}",
"t**{v#{s**{p#!**}}v#{}v#{}}",
args_data2.data(), args_data2.size());
dlg->update();
update_graph();
}
}
void update_graph()
{
int i;
assert(dlg->get_node(NodePath("%buildings_layout_graph")));
Control *base = Object::cast_to<Control>(
dlg->get_node(NodePath("%buildings_layout_graph")));
ScrollContainer *p =
Object::cast_to<ScrollContainer>(base->get_parent());
p->set_v_size_flags(Control::SIZE_EXPAND_FILL);
p->set_h_size_flags(Control::SIZE_EXPAND_FILL);
p->set_anchor(MARGIN_RIGHT, 1.0f);
p->set_anchor(MARGIN_BOTTOM, 1.0f);
base->set_custom_minimum_size(Vector2(2048, 1600));
LocalVector<Node *> data;
for (i = 0; i < base->get_child_count(); i++)
data.push_back(base->get_child(i));
for (i = 0; i < (int)data.size(); i++) {
base->remove_child(data[i]);
data[i]->queue_delete();
}
data.clear();
ColorRect *canvas = memnew(ColorRect);
base->add_child(canvas);
canvas->set_frame_color(Color(0.2, 0.2, 0.25, 1.0));
canvas_item = canvas;
canvas->connect("draw", this, "draw_graph");
MenuButton *button = memnew(MenuButton);
button->set_text("Entry");
canvas->add_child(button);
button->set_size(Vector2(80, 40));
button->set_position(Vector2(40, 45));
button->get_popup()->add_item("Create block unit", 100);
button->get_popup()->add_item("Create private zone", 101);
button->get_popup()->add_item("Create public zone", 102);
button->get_popup()->add_item("Create hallway", 103);
}
void draw_graph()
{
canvas_item->draw_rect(Rect2(Vector2(),
canvas_item->get_size()),
Color(0.2, 0.2, 0.25, 1.0));
canvas_item->draw_circle(Vector2(40, 45) + Vector2(40, 20),
40.0f, Color(0.4, 0.4, 0.55, 1.0));
}
static void _bind_methods()
{
ClassDB::bind_method(D_METHOD("tree_entered"),
&BuildingLayoutGraphUI::tree_entered);
ClassDB::bind_method(D_METHOD("draw_graph"),
&BuildingLayoutGraphUI::draw_graph);
}
};
#endif

View File

@@ -0,0 +1,66 @@
#ifndef HANDLE_BUILDING_TYPE_H
#define HANDLE_BUILDING_TYPE_H
#include <core/object.h>
#include <scene/gui/option_button.h>
#include "buildings_editor.h"
#include "base_data.h"
#include "world_editor.h"
class HandleBuildingType : public Object {
GDCLASS(HandleBuildingType, Object)
OptionButton *ob;
BuildingsEditor *editor;
void change_building_type(int index)
{
assert(editor->scene());
const String &item = ob->get_item_text(index);
int bmode = editor->get_buildings_editor_mode();
if (bmode == 0 || bmode == 1 ||
bmode == 2) /* select, move, rotate */
editor->change_building_type(item);
/* do not change building types in create mode (3) */
flecs::world ecs = BaseData::get_singleton()->get();
flecs::entity e = ecs.lookup("world_editor");
assert(e.is_valid());
e.get_mut<WorldEditor::components::buildings_editor_mode>()
->current_type = item;
}
public:
HandleBuildingType(OptionButton *ob, BuildingsEditor *editor)
: Object()
, ob(ob)
, editor(editor)
{
ConfigFile config;
Error result = config.load("res://config/stream.conf");
ERR_FAIL_COND_MSG(result != OK, "Failed to load config");
Dictionary buildings_data =
config.get_value("buildings", "building_data");
ob->clear();
List<Variant> keys;
buildings_data.get_key_list(&keys);
List<Variant>::Element *e = keys.front();
while (e) {
const String &key = e->get();
print_line("EE::" + key);
ob->add_item(key);
e = e->next();
}
ob->connect("item_selected", this, "change_building_type");
}
virtual ~HandleBuildingType()
{
if (ob->is_connected("item_selected", this,
"change_building_type"))
ob->disconnect("item_selected", this,
"change_building_type");
}
static void _bind_methods()
{
ClassDB::bind_method(D_METHOD("change_building_type", "index"),
&HandleBuildingType::change_building_type);
}
};
#endif

View File

@@ -0,0 +1,42 @@
#ifndef HANDLE_BUILDINGS_EDITOR_MODE
#define HANDLE_BUILDINGS_EDITOR_MODE
#include <core/object.h>
#include <scene/gui/option_button.h>
#include "buildings_editor.h"
#include "base_data.h"
#include "world_editor.h"
class HandleBuildingsEditorMode : public Object {
GDCLASS(HandleBuildingsEditorMode, Object)
OptionButton *ob;
BuildingsEditor *editor;
void update_editor_mode(int index)
{
flecs::world ecs = BaseData::get_singleton()->get();
flecs::entity e = ecs.lookup("world_editor");
assert(e.is_valid());
e.set<WorldEditor::components::buildings_editor_mode>(
{ index });
}
public:
HandleBuildingsEditorMode(OptionButton *ob, BuildingsEditor *editor)
: Object()
, ob(ob)
, editor(editor)
{
ob->connect("item_selected", this, "update_editor_mode");
}
~HandleBuildingsEditorMode()
{
ob->disconnect("item_selected", this, "update_editor_mode");
}
protected:
static void _bind_methods()
{
ClassDB::bind_method(
D_METHOD("update_editor_mode", "index"),
&HandleBuildingsEditorMode::update_editor_mode);
}
};
#endif

View File

@@ -0,0 +1,62 @@
#ifndef HANDLE_CMD_BUTTON_H
#define HANDLE_CMD_BUTTON_H
#include <core/object.h>
#include <core/engine.h>
#include <scene/gui/option_button.h>
#include <scene/gui/item_list.h>
#include <scene/gui/line_edit.h>
#include "buildings_editor.h"
#include "base_data.h"
#include "world_editor.h"
#include "main_tabs.h"
#include "road_lines_data.h"
#include "road_lines_editor.h"
#include "editor_event.h"
class HandleCmdButton : public Object {
GDCLASS(HandleCmdButton, Object)
Button *button;
WorldEditor *editor;
String command;
Vector<Variant> args;
void button_handler()
{
assert(command.length() > 0);
editor->editor_command(command, args);
}
public:
HandleCmdButton(Button *button, WorldEditor *editor,
const String &command,
const Vector<Variant> &args = varray())
: Object()
, button(button)
, editor(editor)
, command(command)
, args(args)
{
assert(button);
assert(this->command.length() > 0);
if (!button->is_connected("pressed", this, "button_handler")) {
button->connect("pressed", this, "button_handler");
assert(button->is_connected("pressed", this,
"button_handler"));
}
}
virtual ~HandleCmdButton()
{
assert(button);
assert(button->is_connected("pressed", this, "button_handler"));
if (button->is_connected("pressed", this, "button_handler"))
button->disconnect("pressed", this, "button_handler");
}
protected:
static void _bind_methods()
{
ClassDB::bind_method(D_METHOD("button_handler"),
&HandleCmdButton::button_handler);
}
};
#endif

View File

@@ -0,0 +1,62 @@
#ifndef HANDLE_EVENT_BUTTON_H
#define HANDLE_EVENT_BUTTON_H
#include <core/object.h>
#include <core/engine.h>
#include <scene/gui/option_button.h>
#include <scene/gui/item_list.h>
#include <scene/gui/line_edit.h>
#include "buildings_editor.h"
#include "base_data.h"
#include "world_editor.h"
#include "main_tabs.h"
#include "road_lines_data.h"
#include "road_lines_editor.h"
#include "editor_event.h"
class HandleEventButton : public Object {
GDCLASS(HandleEventButton, Object)
Button *button;
BuildingsEditor *editor;
String event_string;
Vector<Variant> event_args;
void button_handler()
{
assert(event_string.length() > 0);
editor->emit("button:" + event_string, event_args);
}
public:
HandleEventButton(Button *button, BuildingsEditor *editor,
const String &event_string,
const Vector<Variant> &event_args = varray())
: Object()
, button(button)
, editor(editor)
, event_string(event_string)
, event_args(event_args)
{
assert(button);
assert(this->event_string.length() > 0);
if (!button->is_connected("pressed", this, "button_handler")) {
button->connect("pressed", this, "button_handler");
assert(button->is_connected("pressed", this,
"button_handler"));
}
}
virtual ~HandleEventButton()
{
assert(button);
assert(button->is_connected("pressed", this, "button_handler"));
if (button->is_connected("pressed", this, "button_handler"))
button->disconnect("pressed", this, "button_handler");
}
protected:
static void _bind_methods()
{
ClassDB::bind_method(D_METHOD("button_handler"),
&HandleEventButton::button_handler);
}
};
#endif

View File

@@ -0,0 +1,226 @@
#ifndef HANDLE_FULL_POSITION_SETTING_H
#define HANDLE_FULL_POSITION_SETTING_H
#include <core/object.h>
#include <core/engine.h>
#include <scene/gui/option_button.h>
#include <scene/gui/item_list.h>
#include <scene/gui/line_edit.h>
#include "buildings_editor.h"
#include "base_data.h"
#include "world_editor.h"
#include "main_tabs.h"
#include "road_lines_data.h"
#include "road_lines_editor.h"
#include "editor_event.h"
class HandleFullPositionSetting : public Object {
GDCLASS(HandleFullPositionSetting, Object)
BuildingsEditor *editor;
MainTabs *gui;
int old_mode;
public:
HandleFullPositionSetting(BuildingsEditor *editor, MainTabs *gui)
: Object()
, editor(editor)
, gui(gui)
, old_mode(-1)
{
SceneTree::get_singleton()->connect("idle_frame", this,
"handle_update");
Button *set_cursor_position = gui->get_as_node<Button>(
"%buildings_set_cursor_position");
set_cursor_position->connect("pressed", this,
"handle_set_cursor");
Button *set_building_position = gui->get_as_node<Button>(
"%buildings_set_building_position");
set_building_position->connect("pressed", this,
"handle_set_building");
EditorEvent::get_singleton()->event.add_listener(
this, &HandleFullPositionSetting::handle_event);
#if 0
String building = editor->get_selected_building();
if (building.length() > 0) {
Vector3 building_pos =
editor->get_selected_building_xform().origin;
}
#endif
assert(set_cursor_position);
assert(set_building_position);
}
virtual ~HandleFullPositionSetting()
{
EditorEvent::get_singleton()->event.remove_listener(
this, &HandleFullPositionSetting::handle_event);
Button *set_building_position = gui->get_as_node<Button>(
"%buildings_set_building_position");
set_building_position->disconnect("pressed", this,
"handle_set_building");
Button *set_cursor_position = gui->get_as_node<Button>(
"%buildings_set_cursor_position");
set_cursor_position->disconnect("pressed", this,
"handle_set_cursor");
SceneTree::get_singleton()->disconnect("idle_frame", this,
"handle_update");
}
protected:
static void _bind_methods()
{
ClassDB::bind_method(D_METHOD("handle_update"),
&HandleFullPositionSetting::handle_update);
ClassDB::bind_method(
D_METHOD("handle_set_cursor"),
&HandleFullPositionSetting::handle_set_cursor);
ClassDB::bind_method(
D_METHOD("handle_set_building"),
&HandleFullPositionSetting::handle_set_building);
}
private:
void handle_event(const String &event, const Vector<Variant> &args)
{
if (event == "buildings_building_cursor_moved") {
Vector3 position = args[0];
LineEdit *cursor_x = gui->get_as_node<LineEdit>(
"%building_cursor_x");
LineEdit *cursor_y = gui->get_as_node<LineEdit>(
"%building_cursor_y");
LineEdit *cursor_z = gui->get_as_node<LineEdit>(
"%building_cursor_z");
cursor_x->set_text(String::num(position.x));
cursor_y->set_text(String::num(position.y));
cursor_z->set_text(String::num(position.z));
} else if (event == "buildings_building_selected" ||
event == "buildings_building_moved" ||
event == "buildings_building_rotated") {
LineEdit *position_x = gui->get_as_node<LineEdit>(
"%building_position_x");
LineEdit *position_y = gui->get_as_node<LineEdit>(
"%building_position_y");
LineEdit *position_z = gui->get_as_node<LineEdit>(
"%building_position_z");
LineEdit *position_rot = gui->get_as_node<LineEdit>(
"%building_rotation_y");
Transform xform = editor->get_selected_building_xform();
position_x->set_text(String::num(xform.origin.x));
position_y->set_text(String::num(xform.origin.y));
position_z->set_text(String::num(xform.origin.z));
Vector3 reference(0, 0, -1);
Vector3 rotated =
xform.basis.xform(reference).normalized();
float angle = reference.signed_angle_to(
rotated, Vector3(0, 1, 0));
position_rot->set_text(
String::num(angle * 180.0f / Math_PI));
}
}
void handle_set_cursor()
{
LineEdit *cursor_x =
gui->get_as_node<LineEdit>("%building_cursor_x");
LineEdit *cursor_y =
gui->get_as_node<LineEdit>("%building_cursor_y");
LineEdit *cursor_z =
gui->get_as_node<LineEdit>("%building_cursor_z");
Vector3 position;
position.x = cursor_x->get_text().to_float();
position.y = cursor_y->get_text().to_float();
position.z = cursor_z->get_text().to_float();
editor->set_cursor_position(position);
}
void handle_set_building()
{
LineEdit *position_x =
gui->get_as_node<LineEdit>("%building_position_x");
LineEdit *position_y =
gui->get_as_node<LineEdit>("%building_position_y");
LineEdit *position_z =
gui->get_as_node<LineEdit>("%building_position_z");
LineEdit *position_rot =
gui->get_as_node<LineEdit>("%building_rotation_y");
Transform xform = editor->get_selected_building_xform();
xform.basis = Basis().rotated(
Vector3(0, 1, 0),
position_rot->get_text().to_float() * Math_PI / 180.0f);
xform.origin.x = position_x->get_text().to_float();
xform.origin.y = position_y->get_text().to_float();
xform.origin.z = position_z->get_text().to_float();
String key = editor->get_selected_building();
int mode = editor->get_buildings_editor_mode();
if (mode == 1 || mode == 2)
editor->set_cursor_position(xform.origin);
editor->emit("run_update_building_transform",
varray(key, xform));
}
void handle_update()
{
if (Engine::get_singleton()->is_editor_hint())
return;
// TODO: handle selection
int i;
int mode = editor->get_buildings_editor_mode();
LineEdit *cursor_x =
gui->get_as_node<LineEdit>("%building_cursor_x");
LineEdit *cursor_y =
gui->get_as_node<LineEdit>("%building_cursor_y");
LineEdit *cursor_z =
gui->get_as_node<LineEdit>("%building_cursor_z");
LineEdit *cursor_le[] = { cursor_x, cursor_y, cursor_z };
Button *set_cursor_position = gui->get_as_node<Button>(
"%buildings_set_cursor_position");
LineEdit *position_x =
gui->get_as_node<LineEdit>("%building_position_x");
LineEdit *position_y =
gui->get_as_node<LineEdit>("%building_position_y");
LineEdit *position_z =
gui->get_as_node<LineEdit>("%building_position_z");
LineEdit *position_rot =
gui->get_as_node<LineEdit>("%building_rotation_y");
LineEdit *position_le[] = { position_x, position_y, position_z,
position_rot };
Button *set_building_position = gui->get_as_node<Button>(
"%buildings_set_building_position");
int sz_cursor = (int)(sizeof(cursor_le) / sizeof(cursor_le[0]));
int sz_position =
(int)(sizeof(position_le) / sizeof(position_le[0]));
if (mode != old_mode) {
switch (mode) {
case 0: // select
for (i = 0; i < sz_cursor; i++)
cursor_le[i]->set_editable(false);
set_cursor_position->set_disabled(true);
for (i = 0; i < sz_position; i++)
position_le[i]->set_editable(false);
set_building_position->set_disabled(true);
break;
case 1: // move
for (i = 0; i < sz_cursor; i++)
cursor_le[i]->set_editable(false);
set_cursor_position->set_disabled(true);
for (i = 0; i < sz_position; i++)
position_le[i]->set_editable(true);
set_building_position->set_disabled(false);
break;
case 2: // rotate
for (i = 0; i < sz_cursor; i++)
cursor_le[i]->set_editable(false);
set_cursor_position->set_disabled(true);
for (i = 0; i < sz_position; i++)
position_le[i]->set_editable(true);
set_building_position->set_disabled(false);
break;
case 3: // create
for (i = 0; i < sz_cursor; i++)
cursor_le[i]->set_editable(true);
set_cursor_position->set_disabled(false);
for (i = 0; i < sz_position; i++)
position_le[i]->set_editable(true);
set_building_position->set_disabled(false);
break;
}
old_mode = mode;
}
}
};
#endif

View File

@@ -0,0 +1,85 @@
#ifndef HANDLE_LINES_LIST_H
#define HANDLE_LINES_LIST_H
#include <core/object.h>
#include <scene/gui/option_button.h>
#include <scene/gui/item_list.h>
#include "buildings_editor.h"
#include "base_data.h"
#include "world_editor.h"
#include "main_tabs.h"
#include "road_lines_data.h"
#include "road_lines_editor.h"
#include "editor_event.h"
class HandleLinesList : public Object {
GDCLASS(HandleLinesList, Object)
public:
RoadLinesEditor *editor;
MainTabs *gui;
void handler(int index)
{
if (index < 0)
return;
ItemList *lines_list =
gui->get_as_node<ItemList>("%lines_list");
editor->select_line(lines_list->get_item_text(index));
}
void update_ui()
{
RoadLinesData *rld = RoadLinesData::get_singleton();
ItemList *lines_list =
gui->get_as_node<ItemList>("%lines_list");
assert(lines_list);
List<String> line_keys;
editor->get_matching_lines(&line_keys);
assert(!line_keys.empty());
List<String>::Element *e = line_keys.front();
lines_list->clear();
int selected_index = -1;
int index = 0;
while (e) {
String key = e->get();
if (key == editor->get_current_line())
selected_index = index;
lines_list->add_item(key);
e = e->next();
index++;
}
if (selected_index >= 0)
lines_list->set_current(selected_index);
else
lines_list->set_current(0);
}
HandleLinesList(RoadLinesEditor *editor, MainTabs *gui)
: Object()
, editor(editor)
, gui(gui)
{
ItemList *lines_list =
gui->get_as_node<ItemList>("%lines_list");
update_ui();
EditorEvent::get_singleton()->event.add_listener(
this, &HandleLinesList::event_handler);
lines_list->connect("item_selected", this, "handler");
}
virtual ~HandleLinesList()
{
ItemList *lines_list =
gui->get_as_node<ItemList>("%lines_list");
lines_list->disconnect("item_selected", this, "handler");
assert(lines_list);
}
void event_handler(const String &event, const Vector<Variant> &args)
{
if (event == "lines_select_line")
update_ui();
}
protected:
static void _bind_methods()
{
ClassDB::bind_method(D_METHOD("handler", "index"),
&HandleLinesList::handler);
}
};
#endif

View File

@@ -7,607 +7,30 @@
#include <scene/gui/panel_container.h>
#include <scene/gui/button.h>
#include <scene/gui/option_button.h>
#include <scene/gui/menu_button.h>
#include <scene/gui/line_edit.h>
#include <scene/gui/item_list.h>
#include <scene/gui/spin_box.h>
#include <scene/gui/text_edit.h>
#include <scene/gui/dialogs.h>
#include <scene/gui/color_rect.h>
#include "world_editor.h"
#include "buildings_editor.h"
#include "base_data.h"
#include "editor_event.h"
#include "road_lines_editor.h"
#include "road_lines_data.h"
#include "handle_buildings_editor_mode.h"
#include "handle_building_type.h"
#include "handle_lines_list.h"
#include "handle_cmd_button.h"
#include "handle_event_button.h"
#include "handle_full_position_setting.h"
#include "menu_handler.h"
#include "ui_field_builder.h"
#include "building_layout_graph_ui.h"
#include "main_tabs.h"
class HandleBuildingsEditorMode : public Object {
GDCLASS(HandleBuildingsEditorMode, Object)
OptionButton *ob;
BuildingsEditor *editor;
void update_editor_mode(int index)
{
flecs::world ecs = BaseData::get_singleton()->get();
flecs::entity e = ecs.lookup("world_editor");
assert(e.is_valid());
e.set<WorldEditor::components::buildings_editor_mode>(
{ index });
}
public:
HandleBuildingsEditorMode(OptionButton *ob, BuildingsEditor *editor)
: Object()
, ob(ob)
, editor(editor)
{
ob->connect("item_selected", this, "update_editor_mode");
}
~HandleBuildingsEditorMode()
{
ob->disconnect("item_selected", this, "update_editor_mode");
}
protected:
static void _bind_methods()
{
ClassDB::bind_method(
D_METHOD("update_editor_mode", "index"),
&HandleBuildingsEditorMode::update_editor_mode);
}
};
class HandleBuildingType : public Object {
GDCLASS(HandleBuildingType, Object)
OptionButton *ob;
BuildingsEditor *editor;
void change_building_type(int index)
{
assert(editor->scene());
const String &item = ob->get_item_text(index);
int bmode = editor->get_buildings_editor_mode();
if (bmode == 0 || bmode == 1 ||
bmode == 2) /* select, move, rotate */
editor->change_building_type(item);
/* do not change building types in create mode (3) */
flecs::world ecs = BaseData::get_singleton()->get();
flecs::entity e = ecs.lookup("world_editor");
assert(e.is_valid());
e.get_mut<WorldEditor::components::buildings_editor_mode>()
->current_type = item;
}
public:
HandleBuildingType(OptionButton *ob, BuildingsEditor *editor)
: Object()
, ob(ob)
, editor(editor)
{
ConfigFile config;
Error result = config.load("res://config/stream.conf");
ERR_FAIL_COND_MSG(result != OK, "Failed to load config");
Dictionary buildings_data =
config.get_value("buildings", "building_data");
ob->clear();
List<Variant> keys;
buildings_data.get_key_list(&keys);
List<Variant>::Element *e = keys.front();
while (e) {
const String &key = e->get();
print_line("EE::" + key);
ob->add_item(key);
e = e->next();
}
ob->connect("item_selected", this, "change_building_type");
}
virtual ~HandleBuildingType()
{
if (ob->is_connected("item_selected", this,
"change_building_type"))
ob->disconnect("item_selected", this,
"change_building_type");
}
static void _bind_methods()
{
ClassDB::bind_method(D_METHOD("change_building_type", "index"),
&HandleBuildingType::change_building_type);
}
};
class HandleFullPositionSetting : public Object {
GDCLASS(HandleFullPositionSetting, Object)
BuildingsEditor *editor;
MainTabs *gui;
int old_mode;
public:
HandleFullPositionSetting(BuildingsEditor *editor, MainTabs *gui)
: Object()
, editor(editor)
, gui(gui)
, old_mode(-1)
{
SceneTree::get_singleton()->connect("idle_frame", this,
"handle_update");
Button *set_cursor_position = gui->get_as_node<Button>(
"%buildings_set_cursor_position");
set_cursor_position->connect("pressed", this,
"handle_set_cursor");
Button *set_building_position = gui->get_as_node<Button>(
"%buildings_set_building_position");
set_building_position->connect("pressed", this,
"handle_set_building");
EditorEvent::get_singleton()->event.add_listener(
this, &HandleFullPositionSetting::handle_event);
#if 0
String building = editor->get_selected_building();
if (building.length() > 0) {
Vector3 building_pos =
editor->get_selected_building_xform().origin;
}
#endif
assert(set_cursor_position);
assert(set_building_position);
}
virtual ~HandleFullPositionSetting()
{
EditorEvent::get_singleton()->event.remove_listener(
this, &HandleFullPositionSetting::handle_event);
Button *set_building_position = gui->get_as_node<Button>(
"%buildings_set_building_position");
set_building_position->disconnect("pressed", this,
"handle_set_building");
Button *set_cursor_position = gui->get_as_node<Button>(
"%buildings_set_cursor_position");
set_cursor_position->disconnect("pressed", this,
"handle_set_cursor");
SceneTree::get_singleton()->disconnect("idle_frame", this,
"handle_update");
}
protected:
static void _bind_methods()
{
ClassDB::bind_method(D_METHOD("handle_update"),
&HandleFullPositionSetting::handle_update);
ClassDB::bind_method(
D_METHOD("handle_set_cursor"),
&HandleFullPositionSetting::handle_set_cursor);
ClassDB::bind_method(
D_METHOD("handle_set_building"),
&HandleFullPositionSetting::handle_set_building);
}
private:
void handle_event(const String &event, const Vector<Variant> &args)
{
if (event == "buildings_building_cursor_moved") {
Vector3 position = args[0];
LineEdit *cursor_x = gui->get_as_node<LineEdit>(
"%building_cursor_x");
LineEdit *cursor_y = gui->get_as_node<LineEdit>(
"%building_cursor_y");
LineEdit *cursor_z = gui->get_as_node<LineEdit>(
"%building_cursor_z");
cursor_x->set_text(String::num(position.x));
cursor_y->set_text(String::num(position.y));
cursor_z->set_text(String::num(position.z));
} else if (event == "buildings_building_selected" ||
event == "buildings_building_moved" ||
event == "buildings_building_rotated") {
LineEdit *position_x = gui->get_as_node<LineEdit>(
"%building_position_x");
LineEdit *position_y = gui->get_as_node<LineEdit>(
"%building_position_y");
LineEdit *position_z = gui->get_as_node<LineEdit>(
"%building_position_z");
LineEdit *position_rot = gui->get_as_node<LineEdit>(
"%building_rotation_y");
Transform xform = editor->get_selected_building_xform();
position_x->set_text(String::num(xform.origin.x));
position_y->set_text(String::num(xform.origin.y));
position_z->set_text(String::num(xform.origin.z));
Vector3 reference(0, 0, -1);
Vector3 rotated =
xform.basis.xform(reference).normalized();
float angle = reference.signed_angle_to(
rotated, Vector3(0, 1, 0));
position_rot->set_text(
String::num(angle * 180.0f / Math_PI));
}
}
void handle_set_cursor()
{
LineEdit *cursor_x =
gui->get_as_node<LineEdit>("%building_cursor_x");
LineEdit *cursor_y =
gui->get_as_node<LineEdit>("%building_cursor_y");
LineEdit *cursor_z =
gui->get_as_node<LineEdit>("%building_cursor_z");
Vector3 position;
position.x = cursor_x->get_text().to_float();
position.y = cursor_y->get_text().to_float();
position.z = cursor_z->get_text().to_float();
editor->set_cursor_position(position);
}
void handle_set_building()
{
LineEdit *position_x =
gui->get_as_node<LineEdit>("%building_position_x");
LineEdit *position_y =
gui->get_as_node<LineEdit>("%building_position_y");
LineEdit *position_z =
gui->get_as_node<LineEdit>("%building_position_z");
LineEdit *position_rot =
gui->get_as_node<LineEdit>("%building_rotation_y");
Transform xform = editor->get_selected_building_xform();
xform.basis = Basis().rotated(
Vector3(0, 1, 0),
position_rot->get_text().to_float() * Math_PI / 180.0f);
xform.origin.x = position_x->get_text().to_float();
xform.origin.y = position_y->get_text().to_float();
xform.origin.z = position_z->get_text().to_float();
String key = editor->get_selected_building();
int mode = editor->get_buildings_editor_mode();
if (mode == 1 || mode == 2)
editor->set_cursor_position(xform.origin);
editor->emit("run_update_building_transform",
varray(key, xform));
}
void handle_update()
{
if (Engine::get_singleton()->is_editor_hint())
return;
// TODO: handle selection
int i;
int mode = editor->get_buildings_editor_mode();
LineEdit *cursor_x =
gui->get_as_node<LineEdit>("%building_cursor_x");
LineEdit *cursor_y =
gui->get_as_node<LineEdit>("%building_cursor_y");
LineEdit *cursor_z =
gui->get_as_node<LineEdit>("%building_cursor_z");
LineEdit *cursor_le[] = { cursor_x, cursor_y, cursor_z };
Button *set_cursor_position = gui->get_as_node<Button>(
"%buildings_set_cursor_position");
LineEdit *position_x =
gui->get_as_node<LineEdit>("%building_position_x");
LineEdit *position_y =
gui->get_as_node<LineEdit>("%building_position_y");
LineEdit *position_z =
gui->get_as_node<LineEdit>("%building_position_z");
LineEdit *position_rot =
gui->get_as_node<LineEdit>("%building_rotation_y");
LineEdit *position_le[] = { position_x, position_y, position_z,
position_rot };
Button *set_building_position = gui->get_as_node<Button>(
"%buildings_set_building_position");
int sz_cursor = (int)(sizeof(cursor_le) / sizeof(cursor_le[0]));
int sz_position =
(int)(sizeof(position_le) / sizeof(position_le[0]));
if (mode != old_mode) {
switch (mode) {
case 0: // select
for (i = 0; i < sz_cursor; i++)
cursor_le[i]->set_editable(false);
set_cursor_position->set_disabled(true);
for (i = 0; i < sz_position; i++)
position_le[i]->set_editable(false);
set_building_position->set_disabled(true);
break;
case 1: // move
for (i = 0; i < sz_cursor; i++)
cursor_le[i]->set_editable(false);
set_cursor_position->set_disabled(true);
for (i = 0; i < sz_position; i++)
position_le[i]->set_editable(true);
set_building_position->set_disabled(false);
break;
case 2: // rotate
for (i = 0; i < sz_cursor; i++)
cursor_le[i]->set_editable(false);
set_cursor_position->set_disabled(true);
for (i = 0; i < sz_position; i++)
position_le[i]->set_editable(true);
set_building_position->set_disabled(false);
break;
case 3: // create
for (i = 0; i < sz_cursor; i++)
cursor_le[i]->set_editable(true);
set_cursor_position->set_disabled(false);
for (i = 0; i < sz_position; i++)
position_le[i]->set_editable(true);
set_building_position->set_disabled(false);
break;
}
old_mode = mode;
}
}
};
class HandleCmdButton : public Object {
GDCLASS(HandleCmdButton, Object)
Button *button;
WorldEditor *editor;
String command;
Vector<Variant> args;
void button_handler()
{
assert(command.length() > 0);
editor->editor_command(command, args);
}
public:
HandleCmdButton(Button *button, WorldEditor *editor,
const String &command,
const Vector<Variant> &args = varray())
: Object()
, button(button)
, editor(editor)
, command(command)
, args(args)
{
assert(button);
assert(this->command.length() > 0);
if (!button->is_connected("pressed", this, "button_handler")) {
button->connect("pressed", this, "button_handler");
assert(button->is_connected("pressed", this,
"button_handler"));
}
}
virtual ~HandleCmdButton()
{
assert(button);
assert(button->is_connected("pressed", this, "button_handler"));
if (button->is_connected("pressed", this, "button_handler"))
button->disconnect("pressed", this, "button_handler");
}
protected:
static void _bind_methods()
{
ClassDB::bind_method(D_METHOD("button_handler"),
&HandleCmdButton::button_handler);
}
};
class HandleEventButton : public Object {
GDCLASS(HandleEventButton, Object)
Button *button;
BuildingsEditor *editor;
String event_string;
Vector<Variant> event_args;
void button_handler()
{
assert(event_string.length() > 0);
editor->emit("button:" + event_string, event_args);
}
public:
HandleEventButton(Button *button, BuildingsEditor *editor,
const String &event_string,
const Vector<Variant> &event_args = varray())
: Object()
, button(button)
, editor(editor)
, event_string(event_string)
, event_args(event_args)
{
assert(button);
assert(this->event_string.length() > 0);
if (!button->is_connected("pressed", this, "button_handler")) {
button->connect("pressed", this, "button_handler");
assert(button->is_connected("pressed", this,
"button_handler"));
}
}
virtual ~HandleEventButton()
{
assert(button);
assert(button->is_connected("pressed", this, "button_handler"));
if (button->is_connected("pressed", this, "button_handler"))
button->disconnect("pressed", this, "button_handler");
}
protected:
static void _bind_methods()
{
ClassDB::bind_method(D_METHOD("button_handler"),
&HandleEventButton::button_handler);
}
};
static Vector<Object *> c_handlers;
static void ui_field_builder(Node *owner, Node *parent, const String format,
const Vector<Variant> args)
{
int argp = 0, i;
List<Node *> stack;
int fmt_size = (int)format.length();
int args_size = (int)args.size();
Control *last_created = nullptr;
flecs::world ecs = BaseData::get_singleton()->get();
flecs::entity world_editor_e = ecs.lookup("world_editor");
WorldEditor *we =
world_editor_e
.get<WorldEditor::components::world_editor_node>()
->node;
BuildingsEditor *be =
world_editor_e
.get<WorldEditor::components::buildings_editor_node>()
->node;
for (i = 0; i < format.length(); i++) {
const char *fmt = format.ascii().ptr();
int c = fmt[i];
printf("character: %c : argp: %d\n", (char)c, argp);
switch (c) {
case '{':
stack.push_front(parent);
parent = last_created;
break;
case '}':
parent = stack.front()->get();
stack.pop_front();
break;
case '#': {
assert(argp < args_size);
String name = args[argp++];
assert(name.length() > 0);
last_created->set_name(name);
printf("set name: %s\n", name.ascii().ptr());
} break;
case '.':
assert(argp < args_size);
last_created->set_custom_minimum_size(args[argp++]);
break;
case '!':
last_created->set_unique_name_in_owner(true);
break;
case '+':
assert(argp < args_size);
last_created->set_h_size_flags(args[argp++]);
break;
case 'v':
case 'V':
case 'h':
case 'H':
if (c == 'v' || c == 'V') {
VBoxContainer *vb = memnew(VBoxContainer);
parent->add_child(vb);
vb->set_owner(owner);
last_created = vb;
} else {
HBoxContainer *hb = memnew(HBoxContainer);
parent->add_child(hb);
hb->set_owner(owner);
last_created = hb;
}
break;
case 'l':
case 'L':
assert(i < fmt_size - 1);
assert(argp < args_size);
{
Label *l = memnew(Label);
l->set_text(args[argp++]);
parent->add_child(l);
l->set_owner(owner);
last_created = l;
}
break;
case 'e':
case 'E':
assert(i < fmt_size);
assert(argp < args_size);
{
LineEdit *l = memnew(LineEdit);
assert(argp < args_size);
l->set_text(args[argp++]);
parent->add_child(l);
l->set_owner(owner);
last_created = l;
}
break;
case 'b':
case 'B':
assert(argp < args_size);
{
Button *b = memnew(Button);
assert(argp < args_size);
b->set_text(args[argp++]);
parent->add_child(b);
b->set_owner(owner);
last_created = b;
}
break;
case 'o':
assert(argp < args_size);
{
int j, count;
OptionButton *b = memnew(OptionButton);
assert(argp < args_size);
b->set_text(args[argp++]);
parent->add_child(b);
b->set_owner(owner);
assert(argp < args_size);
count = args[argp++];
for (j = 0; j < count; j++) {
assert(argp < args_size);
int id = args[argp++];
assert(argp < args_size);
String text = args[argp++];
b->add_item(text, id);
}
last_created = b;
}
break;
case 'i':
assert(argp < args_size);
{
int j, count;
ItemList *l = memnew(ItemList);
assert(argp < args_size);
parent->add_child(l);
l->set_owner(owner);
assert(argp < args_size);
count = args[argp++];
for (j = 0; j < count; j++) {
assert(argp < args_size);
String text = args[argp++];
l->add_item(text);
}
last_created = l;
}
break;
case '_': {
HSeparator *hs = memnew(HSeparator);
parent->add_child(hs);
hs->set_owner(owner);
last_created = hs;
} break;
case '|': {
VSeparator *vs = memnew(VSeparator);
parent->add_child(vs);
vs->set_owner(owner);
last_created = vs;
} break;
case 'q': {
assert(argp + 1 < args_size);
Button *b = Object::cast_to<Button>(last_created);
assert(b);
HandleCmdButton *cmd = memnew(HandleCmdButton(
b, we, args[argp++], args[argp++]));
c_handlers.push_back(cmd);
} break;
case 'Q': {
assert(argp + 1 < args_size);
Button *b = Object::cast_to<Button>(last_created);
assert(b);
HandleEventButton *cmd = memnew(HandleEventButton(
b, be, args[argp++], args[argp++]));
c_handlers.push_back(cmd);
} break;
case 'T': {
assert(argp < args_size);
OptionButton *b =
Object::cast_to<OptionButton>(last_created);
assert(b);
HandleBuildingType *cmd =
memnew(HandleBuildingType(b, be));
c_handlers.push_back(cmd);
} break;
case 'M': {
assert(argp < args_size);
OptionButton *b =
Object::cast_to<OptionButton>(last_created);
assert(b);
HandleBuildingsEditorMode *cmd =
memnew(HandleBuildingsEditorMode(b, be));
c_handlers.push_back(cmd);
} break;
default:
printf("bad character %c\n", (char)c);
assert(false);
}
}
}
template <class T>
inline void MainTabs::mode_visibility(int mode, const String &path)
{
@@ -677,12 +100,18 @@ void MainTabs::_notification(int which)
{ "POI", "select_poi", "POI mode" },
{ "Lines", "select_road_lines", "Lines mode" },
{ "NPC", "select_npc", "NPC mode" },
{ "Building layouts", "select_building_layouts",
"Building layouts" },
};
flecs::world ecs = BaseData::get_singleton()->get();
flecs::entity world_editor_e = ecs.lookup("world_editor");
assert(world_editor_e.is_valid());
assert(world_editor_e.has<
WorldEditor::components::world_editor_node>());
assert(world_editor_e.has<
WorldEditor::components::buildings_editor_node>());
assert(world_editor_e.has<
WorldEditor::components::road_lines_editor_node>());
WorldEditor *we =
world_editor_e
.get<WorldEditor::components::world_editor_node>()
@@ -692,23 +121,52 @@ void MainTabs::_notification(int which)
.get<WorldEditor::components::
buildings_editor_node>()
->node;
RoadLinesEditor *rleditor =
world_editor_e
.get<WorldEditor::components::
road_lines_editor_node>()
->node;
int i;
if (!Engine::get_singleton()->is_editor_hint()) {
npc_editor = memnew(WindowDialog);
SceneTree::get_singleton()
->get_current_scene()
->call_deferred("add_child", npc_editor);
npc_editor->set_anchor(MARGIN_TOP, 0.0316667f);
npc_editor->set_anchor(MARGIN_RIGHT, 0.746094f);
npc_editor->set_anchor(MARGIN_BOTTOM, 1.0f);
npc_editor->set_name("npc_editor");
npc_editor->set_unique_name_in_owner(true);
npc_editor->set_exclusive(false);
npc_editor->call_deferred(
"set_owner",
SceneTree::get_singleton()->get_current_scene());
building_layouts_editor = memnew(WindowDialog);
SceneTree::get_singleton()
->get_current_scene()
->call_deferred("add_child",
building_layouts_editor);
building_layouts_editor->set_anchor(MARGIN_TOP,
0.0316667f);
building_layouts_editor->set_anchor(MARGIN_RIGHT,
0.746094f);
building_layouts_editor->set_anchor(MARGIN_BOTTOM,
1.0f);
building_layouts_editor->set_name(
"building_layouts_editor");
building_layouts_editor->set_unique_name_in_owner(true);
building_layouts_editor->set_exclusive(false);
building_layouts_editor->call_deferred(
"set_owner",
SceneTree::get_singleton()->get_current_scene());
} else
building_layouts_editor = nullptr;
for (i = 0; i < (int)(sizeof(items) / sizeof(items[0])); i++) {
VBoxContainer *tab = memnew(VBoxContainer);
tab->set_name(items[i].title);
tab->set_meta("command", items[i].command);
tab->set_owner(this);
add_child(tab);
Label *header = memnew(Label);
header->set_text(items[i].header);
tab->add_child(header);
header->set_owner(this);
HSeparator *sep = memnew(HSeparator);
tab->add_child(sep);
sep->set_owner(this);
PanelContainer *panel = memnew(PanelContainer);
tab->add_child(panel);
panel->set_owner(this);
switch (i) {
case 0: {
// VBoxContainer *v = memnew(VBoxContainer);
@@ -728,6 +186,7 @@ void MainTabs::_notification(int which)
"building_position";
/* clang-format off */
std::vector<Variant> args_data = {
items[i].header,
/* 0 */
"Cursor position",
@@ -766,91 +225,131 @@ void MainTabs::_notification(int which)
/* 60 */
};
/* clang-format on */
Vector<Variant> args;
args.resize(args_data.size());
{
Variant *pw = args.ptrw();
for (j = 0; j < args.size();
j++)
pw[j] = args_data.data()
[j];
}
#if 0
/* clang-format off */
/* 0 */
args.push_back("Cursor position");
/* 1 */
args.push_back(""); args.push_back(cursor_prefix + "_x"); args.push_back(Control::SIZE_EXPAND_FILL);
/* 4 */
args.push_back(""); args.push_back(cursor_prefix + "_y"); args.push_back(Control::SIZE_EXPAND_FILL);
/* 7 */
args.push_back(""); args.push_back(cursor_prefix + "_z"); args.push_back(Control::SIZE_EXPAND_FILL);
/* 10 */
args.push_back("Set"); args.push_back("building_set_cursor_position");
/* 12 */
args.push_back("Selected building position");
/* 13 */
args.push_back(""); args.push_back(building_prefix + "_x"); args.push_back(Control::SIZE_EXPAND_FILL);
/* 16 */
args.push_back(""); args.push_back(building_prefix + "_y"); args.push_back(Control::SIZE_EXPAND_FILL);
/* 19 */
args.push_back(""); args.push_back(building_prefix + "_z"); args.push_back(Control::SIZE_EXPAND_FILL);
/* 22 */
args.push_back("rot");
/* 23 */
args.push_back(""); args.push_back("building_rotation_y");
/* 25 */
args.push_back("Set"); args.push_back("buildings_set_building_position");
args.push_back("Mode");
/* 28 */
args.push_back("Select");
args.push_back(4);
args.push_back(0); args.push_back("Select");
args.push_back(1); args.push_back("Move");
args.push_back(2); args.push_back("Rotate");
args.push_back(3); args.push_back("Create");
args.push_back("buildings_edit_mode");
/* 39 */
args.push_back("Building type");
/* 40 */
args.push_back("Building Type"); args.push_back(0); args.push_back("building_type");
/* 43 */
args.push_back("Delete Building");
args.push_back("buildings_delete_building");
args.push_back("delete_building");
args.push_back(varray());
/* 47 */
args.push_back("Create Building");
args.push_back("buildings_create_building");
args.push_back("create_building");
args.push_back(varray());
/* 51 */
args.push_back("Save Buildings");
args.push_back("buildings_save");
args.push_back("buildings_save");
args.push_back(varray());
/* 55 */
args.push_back(0); args.push_back(Vector2(0, 80)); args.push_back("lines_list_building");
/* 58 */
args.push_back("Assign To Line"); args.push_back("buildings_assign_to_line");
/* 60 */
/* clang-format on */
print_line(itos(args_data.size()) +
" " + itos(args.size()));
assert((int)args_data.size() ==
(int)args.size());
#endif
ui_field_builder(
this, panel,
"v{lh{e#!+e#!+e#!+b#!}lh{e#!+e#!+e#!+}h{le#!b#!}_lo#!Mlo#!T_b#!Qb#!QB#!qi.#!b#!}",
args);
ui_field::ui_field_builder(
this, tab,
"l_p{v{lh{e#!+e#!+e#!+b#!}lh{e#!+e#!+e#!+}h{le#!b#!}_lo#!Mlo#!T_b#!Qb#!QB#!qi.#!b#!}}",
args_data.data(),
args_data.size());
}
} break;
case 1: {
std::vector<Variant> args_data = {
items[i].header
};
ui_field::ui_field_builder(this, tab,
"l_p{v{}}",
args_data.data(),
args_data.size());
} break;
case 2: {
std::vector<Variant> args_data = {
items[i].header
};
ui_field::ui_field_builder(this, tab,
"l_p{v{}}",
args_data.data(),
args_data.size());
} break;
case 3: {
std::vector<Variant> args_data = {
/* clang-format off */
"road_lines_base",
items[i].header,
"road_lines_menu_block",
"File", 1,
101, "Save Lines", false,
"road_lines_file_menu",
"Edit", 1,
201, "Undo", false,
"road_lines_edit_menu",
"Point", 5,
11, "Create", false,
12, "Remove", false,
51, "Point To Cursor", false,
52, "Cursor To Point", false,
53, "Cursor to closest building", false,
"road_lines_point_menu",
"Line", 11,
21, "Create", false,
22, "Delete", false,
-1, "", false,
30, "Remove Generated", false,
31, "Place Generated Objects", false,
23, "Edit Line Metadata", false,
32, "Rebuild roads", false,
33, "Remove Road Meshes", false,
34, "Assign close (generated) buildings", false,
35, "Create new building at cursor", false,
36, "View Buildings", false,
"road_lines_line_menu",
"Options", 5,
201, "Update roads", true,
-1, "", false,
210, "Debug Road Nodes", true,
211, "Debug Road Edges", true,
212, "Debug Road Wedges", true,
"road_lines_options_menu",
"Road Lines mode",
"Filter: ",
"", "road_lines_filter",
0, Vector2(0, 80), "lines_list",
"line_index",
"Cursor position",
"road_lines_cursor_position",
"", "cursor_x",
"", "cursor_y",
"", "cursor_z",
"Set", "road_lines_set_cursor_position",
"Point position",
"road_lines_point_position",
"", "point_x",
"", "point_y",
"", "point_z",
"Set", "road_lines_set_point_position",
/* clang-format on */
};
ui_field::ui_field_builder(
this, tab,
"v{p#!{v{lh#!{m#!m#!m#!m#!m#!}_lh{le#!}i.#!x#!_lv#!{h{e#!e#!e#!b#!}}_lv#!{h{e#!e#!e#!b#!}}}}}",
// "p{v{lh#!{m#!m#!m#!m#!m#!}_lh{le#!}i.#!x#!_lv#!{h{e#!e#!e#!b#!}}_lv#!{h{e#!e#!e#!b#!}}}}",
args_data.data(), args_data.size());
} break;
case 4: {
std::vector<Variant> args_data = {
items[i].header
};
ui_field::ui_field_builder(this, tab,
"l_p{v{}}",
args_data.data(),
args_data.size());
} break;
case 5: {
std::vector<Variant> args_data = {
/* clang-format off */
items[i].header,
"Layouts:",
0, Vector2(0, 80), "building_layout_list",
"Create new layout",
"", "building_layouts_create_text", Control::SIZE_EXPAND_FILL,
"Create", "building_layouts_create_button",
/* clang-format on */
};
ui_field::ui_field_builder(
this, tab, "l_p{v{li.#!lh{e#+!b#!}}}",
args_data.data(), args_data.size());
} break;
}
}
handlers.push_back(
memnew(HandleFullPositionSetting(editor, this)));
set_process(true);
if (!Engine::get_singleton()->is_editor_hint()) {
handlers.push_back(memnew(
HandleFullPositionSetting(editor, this)));
handlers.push_back(memnew(MenuHandler(rleditor, this)));
handlers.push_back(
memnew(HandleLinesList(rleditor, this)));
handlers.push_back(memnew(BuildingLayoutGraphUI(
building_layouts_editor)));
set_process(true);
}
} break;
case NOTIFICATION_PROCESS: {
mode_visibility<Button>(0, "%buildings_delete_building");
@@ -879,6 +378,16 @@ void MainTabs::tab_changed(int tab)
return;
String command = get_tab_control(tab)->get_meta("command");
EditorEvent::get_singleton()->event.emit(command, varray());
if (tab == 4) {
npc_editor->set_exclusive(true);
npc_editor->show();
} else
npc_editor->hide();
if (tab == 5) {
building_layouts_editor->set_exclusive(true);
building_layouts_editor->show();
} else
building_layouts_editor->hide();
}
void MainTabs::hide_control(const String &path)

View File

@@ -1,8 +1,13 @@
#ifndef MAIN_TABS_H
#define MAIN_TABS_H
#include <scene/gui/tab_container.h>
class WindowDialog;
class MainTabs : public TabContainer {
GDCLASS(MainTabs, TabContainer)
Vector<Object *> handlers;
WindowDialog *npc_editor;
WindowDialog *building_layouts_editor;
template <class T>
inline void mode_visibility(int mode, const String &path);
void handle_event(const String &event, const Vector<Variant> &args);
@@ -20,3 +25,4 @@ public:
void hide_control(const String &path);
void show_control(const String &path);
};
#endif

View File

@@ -0,0 +1,219 @@
#ifndef MENU_HANDLER_H
#define MENU_HANDLER_H
#include <core/object.h>
#include <core/engine.h>
#include <scene/gui/option_button.h>
#include <scene/gui/item_list.h>
#include <scene/gui/line_edit.h>
#include <scene/gui/menu_button.h>
#include <scene/gui/text_edit.h>
#include "buildings_editor.h"
#include "base_data.h"
#include "world_editor.h"
#include "main_tabs.h"
#include "road_lines_data.h"
#include "road_lines_editor.h"
#include "editor_event.h"
class MenuHandler : public Object {
GDCLASS(MenuHandler, Object)
RoadLinesEditor *editor;
MainTabs *gui;
public:
MenuHandler(RoadLinesEditor *editor, MainTabs *gui)
: Object()
, editor(editor)
, gui(gui)
{
int i;
Node *menu_block =
gui->get_as_node<Node>("%road_lines_menu_block");
for (i = 0; i < menu_block->get_child_count(); i++) {
Node *menu_button_node = menu_block->get_child(i);
MenuButton *menu_button =
Object::cast_to<MenuButton>(menu_button_node);
if (!menu_button)
continue;
PopupMenu *popup = menu_button->get_popup();
popup->connect("id_pressed", this, "main_handler");
// popup->connect("mouse_exited", popup, "hide");
popup->connect("focus_exited", popup, "hide");
}
}
virtual ~MenuHandler()
{
int i;
Node *menu_block =
gui->get_as_node<Node>("%road_lines_menu_block");
for (i = 0; i < menu_block->get_child_count(); i++) {
Node *menu_button_node = menu_block->get_child(i);
MenuButton *menu_button =
Object::cast_to<MenuButton>(menu_button_node);
if (!menu_button)
continue;
PopupMenu *popup = menu_button->get_popup();
popup->disconnect("id_pressed", this, "main_handler");
}
}
/* FIXME: handle elsewhere */
void update_metadata_editor()
{
if (editor->get_current_line() == "")
return;
TextEdit *metadata_edit = editor->get_as_node<TextEdit>(
"%road_lines_metadata_edit");
String text = editor->get_current_line_metadata();
metadata_edit->set_text(text);
}
void update_line_buildings_editor()
{
int i;
if (editor->get_current_line() == "")
return;
ItemList *items =
gui->get_as_node<ItemList>("%line_buildings_list");
items->clear();
for (i = 0; i < (int)RoadLinesData::get_singleton()
->lines(editor->get_current_line())
.buildings.size();
i++) {
const String &key =
RoadLinesData::get_singleton()
->lines(editor->get_current_line())
.buildings[i]
.building_key;
items->add_item(key);
}
}
void main_handler(int id)
{
switch (id) {
case 11:
editor->line_create_point();
break;
case 12:
editor->line_delete_point();
break;
case 21:
/* Create line */
editor->get_as_node<Control>("%road_lines_base")->hide();
editor->get_as_node<Control>(
"%road_lines_create_new_line_dlg")
->show();
break;
case 22:
/* delete line */
editor->delete_current_line();
break;
case 23:
/* edit line metadata */
if (editor->get_current_line() == "") {
print_error("No current line set");
return;
}
editor->get_as_node<Control>("%road_lines_base")->hide();
editor->get_as_node<Control>(
"%road_lines_edit_metadata_dlg")
->show();
update_metadata_editor();
break;
case 30:
editor->remove_generated_stuff();
break;
case 31:
editor->place_generated_objects();
break;
case 32:
editor->rebuild_roads();
break;
case 33:
editor->remove_road_meshes();
break;
case 34: {
RoadLinesData::get_singleton()->assign_close_buildings(
editor->get_current_line());
editor->update_line_geometry();
} break;
case 36:
editor->get_as_node<Control>("%road_lines_base")->hide();
editor->get_as_node<Control>("%road_lines_buildings")
->show();
update_line_buildings_editor();
break;
case 51:
editor->set_point_to_cursor();
break;
case 52:
editor->move_cursor_to_point();
break;
case 53:
editor->move_cursor_to_closest_building();
case 101:
editor->save_data();
break;
case 201:
case 210:
case 211:
case 212: {
print_line("selected item 201");
int i, j;
Node *menu_block = gui->get_as_node<Node>(
"%road_lines_menu_block");
for (i = 0; i < menu_block->get_child_count(); i++) {
Node *menu_button_node =
menu_block->get_child(i);
MenuButton *menu_button =
Object::cast_to<MenuButton>(
menu_button_node);
if (!menu_button)
continue;
PopupMenu *popup = menu_button->get_popup();
for (j = 0; j < popup->get_item_count(); j++) {
int nid = popup->get_item_id(j);
if (nid == id) {
bool checked =
popup->is_item_checked(
j);
if (checked)
print_line("checked");
else
print_line("unchecked");
checked = !checked;
popup->set_item_checked(
j, checked);
switch (id) {
case 201:
editor->set_update_roads(
checked);
break;
case 210:
editor->set_debug_road_nodes(
checked);
break;
case 211:
editor->set_debug_road_edges(
checked);
break;
case 212:
editor->set_debug_road_wedges(
checked);
break;
}
}
}
}
} break;
default:
print_line("menu option pressed: " + itos(id));
assert(false);
}
}
static void _bind_methods()
{
ClassDB::bind_method(D_METHOD("main_handler", "id"),
&MenuHandler::main_handler);
}
};
#endif

View File

@@ -0,0 +1,285 @@
#include <scene/gui/control.h>
#include <scene/gui/box_container.h>
#include <scene/gui/panel_container.h>
#include <scene/gui/tab_container.h>
#include <scene/gui/scroll_container.h>
#include <scene/gui/label.h>
#include <scene/gui/line_edit.h>
#include <scene/gui/button.h>
#include <scene/gui/option_button.h>
#include <scene/gui/item_list.h>
#include <scene/gui/menu_button.h>
#include <scene/gui/spin_box.h>
#include <scene/gui/separator.h>
#include "base_data.h"
#include "world_editor.h"
#include "handle_cmd_button.h"
#include "handle_event_button.h"
#include "handle_building_type.h"
#include "handle_buildings_editor_mode.h"
#include "ui_field_builder.h"
Vector<Object *> ui_field::c_handlers;
void ui_field::ui_field_builder(Node *owner, Node *parent, const String format,
const Variant *args, int args_size)
{
int argp = 0, i;
List<Node *> stack;
int fmt_size = (int)format.length();
Control *last_created = nullptr;
flecs::world ecs = BaseData::get_singleton()->get();
flecs::entity world_editor_e = ecs.lookup("world_editor");
WorldEditor *we =
world_editor_e
.get<WorldEditor::components::world_editor_node>()
->node;
BuildingsEditor *be =
world_editor_e
.get<WorldEditor::components::buildings_editor_node>()
->node;
assert(owner->is_inside_tree());
for (i = 0; i < format.length(); i++) {
const char *fmt = format.ascii().ptr();
int c = fmt[i];
printf("character: %c : argp: %d\n", (char)c, argp);
switch (c) {
case '{':
stack.push_front(parent);
parent = last_created;
break;
case '}':
parent = stack.front()->get();
stack.pop_front();
break;
case '#': {
assert(argp < args_size);
String name = args[argp++];
assert(name.length() > 0);
last_created->set_name(name);
printf("set name: %s\n", name.ascii().ptr());
} break;
case '.':
assert(argp < args_size);
last_created->set_custom_minimum_size(args[argp++]);
break;
case '!':
last_created->set_unique_name_in_owner(true);
break;
case '+':
assert(argp < args_size);
last_created->set_h_size_flags(args[argp++]);
break;
case '=':
assert(argp < args_size);
last_created->set_v_size_flags(args[argp++]);
break;
case '*': {
assert(argp + 1 < args_size);
assert(args[argp].get_type() == Variant::INT);
assert(args[argp + 1].get_type() == Variant::REAL);
Margin m = args[argp++];
float value = args[argp++];
last_created->set_anchor(m, value);
} break;
case 'v':
case 'h':
if (c == 'v') {
VBoxContainer *vb = memnew(VBoxContainer);
parent->add_child(vb);
vb->set_owner(owner);
last_created = vb;
} else {
HBoxContainer *hb = memnew(HBoxContainer);
parent->add_child(hb);
hb->set_owner(owner);
last_created = hb;
}
break;
case 'p': {
PanelContainer *p = memnew(PanelContainer);
parent->add_child(p);
p->set_owner(owner);
last_created = p;
} break;
case 't': {
TabContainer *t = memnew(TabContainer);
parent->add_child(t);
t->set_owner(owner);
last_created = t;
} break;
case 's': {
ScrollContainer *sc = memnew(ScrollContainer);
parent->add_child(sc);
sc->set_owner(owner);
last_created = sc;
} break;
case 'l':
case 'L':
assert(i < fmt_size - 1);
assert(argp < args_size);
{
Label *l = memnew(Label);
l->set_text(args[argp++]);
parent->add_child(l);
l->set_owner(owner);
last_created = l;
}
break;
case 'e':
case 'E':
assert(i < fmt_size);
assert(argp < args_size);
{
LineEdit *l = memnew(LineEdit);
assert(argp < args_size);
l->set_text(args[argp++]);
parent->add_child(l);
l->set_owner(owner);
last_created = l;
}
break;
case 'b':
case 'B':
assert(argp < args_size);
{
Button *b = memnew(Button);
assert(argp < args_size);
b->set_text(args[argp++]);
parent->add_child(b);
b->set_owner(owner);
last_created = b;
}
break;
case 'o':
assert(argp < args_size);
{
int j, count;
OptionButton *b = memnew(OptionButton);
assert(argp < args_size);
b->set_text(args[argp++]);
parent->add_child(b);
b->set_owner(owner);
assert(argp < args_size);
count = args[argp++];
for (j = 0; j < count; j++) {
assert(argp < args_size);
int id = args[argp++];
assert(argp < args_size);
String text = args[argp++];
b->add_item(text, id);
}
last_created = b;
}
break;
case 'i':
assert(argp < args_size);
{
int j, count;
ItemList *l = memnew(ItemList);
assert(argp < args_size);
parent->add_child(l);
l->set_owner(owner);
assert(argp < args_size);
count = args[argp++];
for (j = 0; j < count; j++) {
assert(argp < args_size);
String text = args[argp++];
l->add_item(text);
}
last_created = l;
}
break;
case 'm':
assert(argp < args_size);
{
int j, count;
MenuButton *b = memnew(MenuButton);
assert(argp < args_size);
b->set_text(args[argp++]);
parent->add_child(b);
b->set_owner(owner);
assert(argp < args_size);
count = args[argp++];
for (j = 0; j < count; j++) {
assert(argp < args_size);
int id = args[argp++];
assert(argp < args_size);
String text = args[argp++];
assert(argp < args_size);
bool checkable = args[argp++];
if (id == -1)
b->get_popup()->add_separator(
text, id);
else {
if (checkable)
b->get_popup()
->add_check_item(
text,
id);
else
b->get_popup()->add_item(
text, id);
}
}
b->set_switch_on_hover(true);
last_created = b;
}
break;
case 'x': {
SpinBox *sp = memnew(SpinBox);
parent->add_child(sp);
sp->set_owner(owner);
last_created = sp;
} break;
case '_': {
HSeparator *hs = memnew(HSeparator);
parent->add_child(hs);
hs->set_owner(owner);
last_created = hs;
} break;
case '|': {
VSeparator *vs = memnew(VSeparator);
parent->add_child(vs);
vs->set_owner(owner);
last_created = vs;
} break;
case 'q': {
assert(argp + 1 < args_size);
Button *b = Object::cast_to<Button>(last_created);
assert(b);
HandleCmdButton *cmd = memnew(HandleCmdButton(
b, we, args[argp++], args[argp++]));
c_handlers.push_back(cmd);
} break;
case 'Q': {
assert(argp + 1 < args_size);
Button *b = Object::cast_to<Button>(last_created);
assert(b);
HandleEventButton *cmd = memnew(HandleEventButton(
b, be, args[argp++], args[argp++]));
c_handlers.push_back(cmd);
} break;
case 'T': {
assert(argp < args_size);
OptionButton *b =
Object::cast_to<OptionButton>(last_created);
assert(b);
HandleBuildingType *cmd =
memnew(HandleBuildingType(b, be));
c_handlers.push_back(cmd);
} break;
case 'M': {
assert(argp < args_size);
OptionButton *b =
Object::cast_to<OptionButton>(last_created);
assert(b);
HandleBuildingsEditorMode *cmd =
memnew(HandleBuildingsEditorMode(b, be));
c_handlers.push_back(cmd);
} break;
default:
printf("bad character %c\n", (char)c);
assert(false);
}
}
}

View File

@@ -0,0 +1,13 @@
#ifndef UI_FIELD_BUILDER_H
#define UI_FIELD_BUILDER_H
#include <scene/main/node.h>
#include <core/object.h>
class ui_field {
public:
static Vector<Object *> c_handlers;
static void ui_field_builder(Node *owner, Node *parent,
const String format, const Variant *args,
int args_size);
};
#endif