1#include "main.h"
2#include "borderize_window.h"
3#include <wx/gauge.h>
4#include <wx/stattext.h>
5#include <wx/button.h>
6#include <wx/spinctrl.h>
7#include "gui.h"
8
9BEGIN_EVENT_TABLE(BorderizeWindow, wxDialog)
10 EVT_BUTTON(wxID_ANY, BorderizeWindow::OnClickNext)
11
12 EVT_SPINCTRL(wxID_ANY, BorderizeWindow::OnChunkSizeChange)
13END_EVENT_TABLE()
14
15BorderizeWindow::BorderizeWindow(wxWindow* parent, Editor& editor) :
16 wxDialog(parent, wxID_ANY, "Borderize Progress", wxDefaultPosition, wxDefaultSize),
17 editor(editor),
18 current_chunk(0),
19 total_chunks(0),
20 processing_whole_map(false)
21{
22 wxBoxSizer* sizer = new wxBoxSizer(wxVERTICAL);
23
24 // Add chunk size control
25 wxBoxSizer* chunk_sizer = new wxBoxSizer(wxHORIZONTAL);
26 chunk_sizer->Add(new wxStaticText(this, wxID_ANY, "Tiles per chunk:"), 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
27 chunk_size_spin = new wxSpinCtrl(this, wxID_ANY, "500", wxDefaultPosition, wxDefaultSize,
28 wxSP_ARROW_KEYS, 100, 10000, 500);
29 chunk_sizer->Add(chunk_size_spin, 0, wxALL, 5);
30 sizer->Add(chunk_sizer);
31
32 status_text = new wxStaticText(this, wxID_ANY, "Preparing to borderize...");
33 sizer->Add(status_text, 0, wxALL, 5);
34
35 progress = new wxGauge(this, wxID_ANY, 100, wxDefaultPosition, wxSize(300, 20));
36 sizer->Add(progress, 0, wxEXPAND | wxALL, 5);
37
38 wxBoxSizer* button_sizer = new wxBoxSizer(wxHORIZONTAL);
39 next_button = new wxButton(this, wxID_ANY, "Process Next Chunk");
40
41
42 button_sizer->Add(next_button, 1, wxALL, 5);
43 button_sizer->Add(cancel_button, 1, wxALL, 5);
44 sizer->Add(button_sizer, 0, wxEXPAND | wxALL, 5);
45
46 SetSizer(sizer);
47 Fit();
48 Centre();
49
50 Bind(wxEVT_CLOSE_WINDOW, [this](wxCloseEvent& event) {
51 // Clear remaining tiles and close without processing
52 remaining_tiles.clear();
53 EndModal(0);
54 });
55}
56
57BorderizeWindow::~BorderizeWindow() {}
58
59void BorderizeWindow::Start() {
60 // Initialize the tile list based on whether we're processing selection or whole map
61 if (editor.selection.size() > 0) {
62 processing_whole_map = false;
63 for (Tile* tile : editor.selection) {
64 remaining_tiles.push_back(tile);
65 }
66 } else {
67 processing_whole_map = true;
68 for (TileLocation* tileLocation : editor.map) {
69 if (Tile* tile = tileLocation->get()) {
70 remaining_tiles.push_back(tile);
71 }
72 }
73 }
74
75 total_chunks = (remaining_tiles.size() + 499) / 500; // Process 500 tiles per chunk
76 UpdateProgress(0, total_chunks);
77 ShowModal();
78}
79
80void BorderizeWindow::UpdateProgress(int current, int total) {
81 progress->SetValue((current * 100) / total);
82 status_text->SetLabel(wxString::Format("Processing chunk %d of %d (%d tiles remaining)",
83 current + 1, total, (int)remaining_tiles.size()));
84}
85
86void BorderizeWindow::OnChunkSizeChange(wxSpinEvent& event) {
87 // Recalculate total chunks based on new chunk size
88 if (!remaining_tiles.empty()) {
89 total_chunks = (remaining_tiles.size() + chunk_size_spin->GetValue() - 1) / chunk_size_spin->GetValue();
90 UpdateProgress(current_chunk, total_chunks);
91 }
92}
93
94void BorderizeWindow::OnClickNext(wxCommandEvent& WXUNUSED(event)) {
95 if (remaining_tiles.empty()) {
96 EndModal(1);
97 return;
98 }
99
100 // Process next chunk of tiles using the user-defined chunk size
101 Action* action = editor.actionQueue->createAction(ACTION_BORDERIZE);
102
103 size_t chunk_size = chunk_size_spin->GetValue();
104 size_t tiles_to_process = std::min<size_t>(chunk_size, remaining_tiles.size());
105
106 for (size_t i = 0; i < tiles_to_process; ++i) {
107 Tile* tile = remaining_tiles.front();
108 remaining_tiles.pop_front();
109
110 Tile* newTile = tile->deepCopy(editor.map);
111 newTile->borderize(&editor.map);
112 if (!processing_whole_map) {
113 newTile->select();
114 }
115 action->addChange(newd Change(newTile));
116 }
117
118 editor.addAction(action);
119 current_chunk++;
120 UpdateProgress(current_chunk, total_chunks);
121
122 if (remaining_tiles.empty()) {
123 next_button->SetLabel("Finish");
124 }
125
126 editor.map.doChange();
127 // Refresh the view after each chunk
128 g_gui.RefreshView();
129}
130