11 if (!ImGui::BeginTabBar(
"##RailTools")) {
14 if (ImGui::BeginTabItem(
"Rails")) {
17 if (ImGui::IsItemHovered()) {
19 "Straight rails set collision with placement and Undo. "
20 "Corners and crossings need explicit behavior until their "
21 "collision patterns are verified. Existing collision is preserved.");
30 if (ImGui::BeginTabItem(
"Nodes")) {
34 if (!ImGui::BeginTabItem(
"Behavior")) {
40 if (ImGui::Checkbox(
"Stamp rail behavior", &stamping)) {
55 static constexpr Behavior kBehaviors[] = {
56 {0xB0,
"Straight: horizontal"},
57 {0xB1,
"Straight: vertical"},
58 {0xB2,
"Corner: right / down"},
59 {0xB3,
"Corner: right / up"},
60 {0xB4,
"Corner: left / down"},
61 {0xB5,
"Corner: left / up"},
63 {0xB7,
"Stop: depart south"},
64 {0xB8,
"Stop: depart north"},
65 {0xB9,
"Stop: depart east"},
66 {0xBA,
"Stop: depart west"},
67 {0xBB,
"Junction: south / east / west"},
68 {0xBC,
"Junction: north / east / west"},
69 {0xBD,
"Junction: north / south / west"},
70 {0xBE,
"Junction: north / south / east"},
71 {0xD0,
"Switch: right / down"},
72 {0xD1,
"Switch: right / up"},
73 {0xD2,
"Switch: left / down"},
74 {0xD3,
"Switch: left / up"},
75 {0x00,
"Erase rail behavior"}};
76 const char* selected = kBehaviors[1].label;
77 for (
const auto& behavior : kBehaviors) {
79 selected = behavior.label;
81 ImGui::SetNextItemWidth(-1);
82 const bool open = ImGui::BeginCombo(
"##RailBehavior", selected);
85 for (
const auto& behavior : kBehaviors) {
86 if (ImGui::Selectable(behavior.label,
95 ImGui::TextDisabled(
"Click to stamp. Drag a matching node to move it.");
101 ImGui::SetNextItemWidth(ImGui::CalcTextSize(
"00000").x +
102 2 * ImGui::GetStyle().FramePadding.x);
103 ImGui::InputInt(
"ID", &
node_id_, 0, 0);
106 if (ImGui::IsItemHovered()) {
108 "Cart: unused route 0-31. Switches: shared channel 0-31. "
109 "Move an existing cart using its room marker.");
111 ImGui::SetNextItemWidth(-1);
113 "Depart south\0Depart north\0Depart east\0Depart west\0");
115 ImGui::SetNextItemWidth(-1);
117 "Switch: right / down\0Switch: right / up\0"
118 "Switch: left / down\0Switch: left / up\0");
120 ImGui::SetNextItemWidth(-1);
122 "T: south / east / west\0T: north / east / west\0"
123 "T: north / south / west\0T: north / south / east\0");
125 auto row = [&](
const char* label,
const char* help,
129 if (ImGui::Selectable(label,
false, 0,
130 ImVec2(0, ImGui::GetFrameHeight()))) {
134 if (ImGui::BeginDragDropSource()) {
135 payload.owner =
this;
139 sizeof(payload), ImGuiCond_Once);
140 ImGui::TextUnformatted(label);
141 ImGui::EndDragDropSource();
143 if (ImGui::IsItemHovered()) {
144 ImGui::SetTooltip(
"%s\nDrag to the room, or click then place.", help);
146 ImGui::EndDisabled();
150 row(
"Cart spawn",
"Adds a cart, its route start and a stop.",
152 row(
"End stop",
"Sets the cart's departure direction.", {{},
true, stop, 1});
153 row(
"Switch",
"Links a lever to this channel.",
155 row(
"Switch track",
"Places a rotating track and its collision.",
157 row(
"T junction",
"Sets the three available exits. Artwork is separate.",