yaze 0.3.2
Link to the Past ROM Editor
 
Loading...
Searching...
No Matches
minecart_track_editor_panel.h
Go to the documentation of this file.
1#ifndef YAZE_APP_EDITOR_DUNGEON_PANELS_MINECART_TRACK_EDITOR_PANEL_H
2#define YAZE_APP_EDITOR_DUNGEON_PANELS_MINECART_TRACK_EDITOR_PANEL_H
3
4#include <array>
5#include <cstdint>
6#include <filesystem>
7#include <functional>
8#include <optional>
9#include <string>
10#include <unordered_map>
11#include <utility>
12#include <vector>
13
14#include "absl/status/status.h"
15#include "absl/status/statusor.h"
20#include "app/gui/core/icons.h"
21#include "core/project.h"
22#include "zelda3/dungeon/room.h"
24
25namespace yaze::editor {
26
28 public:
30 std::function<absl::Status(const project::DungeonOverlaySettings&)>;
31 using ProjectDraftChangedCallback = std::function<absl::Status()>;
32 using ProjectSaveCallback = std::function<absl::Status()>;
33 using CollisionBatchApplyCallback = std::function<absl::Status(
34 const std::vector<zelda3::TrackCollisionResult>&,
36
38
39 // WindowContent overrides
40 std::string GetId() const override { return "dungeon.minecart_tracks"; }
41 std::string GetWorkflowGroup() const override { return "Editors"; }
42 std::string GetDisplayName() const override { return "Minecart Tracks"; }
43 std::string GetIcon() const override { return ICON_MD_TRAIN; }
44 std::string GetEditorCategory() const override { return "Dungeon"; }
45
46 void Draw(bool* p_open) override;
47
48 // Custom methods
50 if (rooms_ != rooms) {
51 collision_preview_.clear();
53 }
54 rooms_ = rooms;
55 audit_dirty_ = true;
57 }
58 absl::Status SetProject(project::YazeProject* project);
59 // Reapply project-backed panel state even when the stable session project
60 // pointer and descriptor path did not change.
61 absl::Status RebindProjectContext(project::YazeProject* project);
62 absl::Status SaveTracks();
63 absl::Status ReloadTracks();
64 absl::Status DiscardUnpublishedChanges();
65 bool HasUnpublishedChanges() const;
66 absl::StatusOr<std::filesystem::path> ResolveTrackSourcePath() const;
67 absl::Status UpdateTrack(size_t track_index, const MinecartTrack& track);
69 absl::Status PrepareProjectSave();
70
71 using TrackEditCallback = std::function<absl::Status(
72 const MinecartTrack&, const MinecartTrack&, bool)>;
74 track_edit_callback_ = std::move(callback);
75 }
76 absl::Status MoveCartStart(const MinecartTrack& before,
77 const MinecartTrack& after);
78 // Undo replay only; validates source generation and expected record first.
79 absl::Status RestoreTrackDraft(uint64_t generation,
80 const MinecartTrack& expected,
81 const MinecartTrack& replacement);
82 uint64_t track_generation() const { return track_generation_; }
83 // Reload cancels an unfinished gesture even when Undo's source is unchanged.
84 uint64_t canvas_revision() const { return canvas_revision_; }
87 bool canvas_editing() const { return canvas_editing_; }
88 void set_canvas_editing(bool enabled);
89 int selected_track() const { return selected_track_; }
90 void SelectTrack(int id) { selected_track_ = id; }
91 void SetActiveRoom(int room) { active_room_ = room; }
93
94 void SetRailPaletteCallback(std::function<bool()> draw) {
95 draw_rail_palette_ = std::move(draw);
96 }
104 void set_collision_stamping(bool enabled) {
105 collision_stamping_ = enabled;
106 if (enabled)
107 set_canvas_editing(false);
108 }
110 int collision_stamp_size() const { return collision_stamp_large_ ? 2 : 1; }
111 void DrawRailTools();
112
113 // Advanced Pick uses the same paired move operation as marker dragging.
114 bool IsPickingCoordinates() const { return picking_mode_; }
116 const std::vector<MinecartTrack>& GetTracks();
117
118 // Callback to navigate to a specific room for coordinate picking
119 using RoomNavigationCallback = std::function<void(int room_id)>;
121 room_navigation_callback_ = std::move(callback);
122 }
124 project_changed_callback_ = std::move(callback);
125 }
130 project_save_callback_ = std::move(callback);
131 }
157
158 private:
160
161 absl::Status LoadTracks();
162 absl::Status ValidateLoadedManifestIdentity() const;
163 absl::Status RefreshProjectBinding();
164 void ResetTrackSession();
165 void StartCoordinatePicking(int track_index);
167 void RebuildAuditCache(bool include_unmaterialized = false);
168 absl::Status BuildCollisionPreview(const std::vector<int>& room_ids);
170 absl::Status ApplyCollisionPreview();
172 absl::StatusOr<zelda3::GeneratorOptions> ResolveGeneratorOptions() const;
173 bool IsDefaultTrack(const MinecartTrack& track) const;
174 void DrawOverlaySettings();
176 void ClearOverlayInputs();
177
179 std::vector<uint16_t> project::DungeonOverlaySettings::*;
180 bool UpdateOverlayList(const char* label, std::string& input,
181 OverlayListMember member);
182 absl::StatusOr<bool> CommitOverlayList(std::string& input,
183 OverlayListMember member);
184 absl::StatusOr<bool> CommitOverlayInputsForSave();
185 absl::StatusOr<bool> ResetOverlaySettings();
186 absl::Status NotifyProjectChanged(
187 const project::DungeonOverlaySettings& overlay);
188 absl::Status NotifyProjectDraftChanged();
189 absl::Status SaveProjectSettings();
190
194 bool has_stop_tiles = false;
197 std::vector<int> track_subtypes;
198 std::vector<int> route_slots;
199 };
200
201 std::function<bool()> draw_rail_palette_;
207 uint64_t track_generation_ = 0;
208 uint64_t canvas_revision_ = 0;
210 int active_room_ = -1;
211 bool canvas_editing_ = false;
213 std::vector<MinecartTrack> tracks_;
214 std::vector<MinecartTrack> loaded_tracks_;
215 std::optional<MinecartTrackSourceDocument> source_document_;
216 std::optional<core::MinecartTrackLayout::Source> loaded_source_identity_;
217 std::filesystem::path loaded_source_path_;
220 std::optional<core::MinecartTrackLayout::Source> bound_source_identity_;
223 std::unordered_map<int, RoomTrackAudit> room_audit_;
224 std::unordered_map<int, std::vector<int>> route_usage_rooms_;
225 std::vector<bool> route_slot_used_;
226 std::vector<zelda3::TrackCollisionResult> collision_preview_;
228 bool audit_dirty_ = true;
230 bool load_attempted_ = false;
231 bool loaded_ = false;
232 std::string status_message_;
233 bool show_success_ = false;
234 float success_timer_ = 0.0f;
235
236 // Coordinate picking state
237 bool picking_mode_ = false;
239
245
246 // Overlay config input state
248 std::optional<project::DungeonOverlaySettings> overlay_inputs_model_;
254};
255
256} // namespace yaze::editor
257
258#endif
std::string GetWorkflowGroup() const override
Optional workflow group for hack-centric actions.
bool IsDefaultTrack(const MinecartTrack &track) const
absl::Status RestoreTrackDraft(uint64_t generation, const MinecartTrack &expected, const MinecartTrack &replacement)
std::string GetId() const override
Unique identifier for this panel.
std::string GetIcon() const override
Material Design icon for this panel.
absl::StatusOr< zelda3::GeneratorOptions > ResolveGeneratorOptions() const
std::string GetEditorCategory() const override
Editor category this panel belongs to.
std::optional< core::MinecartTrackLayout::Source > bound_source_identity_
const MinecartCollisionApply & collision_stamp_callback() const
void SetProjectChangedCallback(ProjectChangedCallback callback)
bool UpdateOverlayList(const char *label, std::string &input, OverlayListMember member)
void Draw(bool *p_open) override
Draw the panel content.
const std::vector< MinecartTrack > & GetTracks()
ProjectDraftChangedCallback project_draft_changed_callback_
std::vector< uint16_t > project::DungeonOverlaySettings::* OverlayListMember
std::unordered_map< int, RoomTrackAudit > room_audit_
std::function< void(int room_id)> RoomNavigationCallback
void SetRailPaletteCallback(std::function< bool()> draw)
std::function< absl::Status( const std::vector< zelda3::TrackCollisionResult > &, const zelda3::GeneratorOptions &)> CollisionBatchApplyCallback
CollisionBatchApplyCallback collision_batch_apply_callback_
void SetRoomNavigationCallback(RoomNavigationCallback callback)
absl::Status NotifyProjectChanged(const project::DungeonOverlaySettings &overlay)
std::vector< zelda3::TrackCollisionResult > collision_preview_
std::optional< MinecartTrackSourceDocument > source_document_
absl::StatusOr< bool > CommitOverlayList(std::string &input, OverlayListMember member)
absl::Status UpdateTrack(size_t track_index, const MinecartTrack &track)
absl::Status RebindProjectContext(project::YazeProject *project)
void SetTrackEditCallback(TrackEditCallback callback)
absl::StatusOr< std::filesystem::path > ResolveTrackSourcePath() const
absl::Status MoveCartStart(const MinecartTrack &before, const MinecartTrack &after)
absl::Status BuildCollisionPreview(const std::vector< int > &room_ids)
absl::Status SetProject(project::YazeProject *project)
std::optional< core::MinecartTrackLayout::Source > loaded_source_identity_
std::function< absl::Status(const project::DungeonOverlaySettings &)> ProjectChangedCallback
std::function< absl::Status()> ProjectSaveCallback
std::unordered_map< int, std::vector< int > > route_usage_rooms_
void SetCollisionBatchApplyCallback(CollisionBatchApplyCallback callback)
void RebuildAuditCache(bool include_unmaterialized=false)
void SetProjectDraftChangedCallback(ProjectDraftChangedCallback callback)
std::function< absl::Status()> ProjectDraftChangedCallback
void SetProjectSaveCallback(ProjectSaveCallback callback)
std::function< absl::Status( const MinecartTrack &, const MinecartTrack &, bool)> TrackEditCallback
std::string GetDisplayName() const override
Human-readable name shown in menus and title bars.
void SetCollisionStampCallback(MinecartCollisionApply apply)
std::optional< project::DungeonOverlaySettings > overlay_inputs_model_
Base interface for all logical window content components.
#define ICON_MD_TRAIN
Definition icons.h:2005
Editors are the view controllers for the application.
std::function< absl::Status( int, const zelda3::CustomCollisionMap &, const MinecartCollisionStamp &)> MinecartCollisionApply
Dungeon overlay configuration (per-project).
Definition project.h:94
Modern project structure with comprehensive settings consolidation.
Definition project.h:287