diff options
-rw-r--r-- | src/subway_map.cpp | 99 | ||||
-rw-r--r-- | src/subway_map.h | 3 |
2 files changed, 50 insertions, 52 deletions
diff --git a/src/subway_map.cpp b/src/subway_map.cpp index 2e7b36f..5a4be4b 100644 --- a/src/subway_map.cpp +++ b/src/subway_map.cpp | |||
@@ -143,23 +143,20 @@ void SubwayMap::OnPaint(wxPaintEvent &event) { | |||
143 | int item_width = col_width + 10 + 32; | 143 | int item_width = col_width + 10 + 32; |
144 | int full_width = item_width + 20; | 144 | int full_width = item_width + 20; |
145 | 145 | ||
146 | int popup_x = (subway_item.x + AREA_ACTUAL_SIZE / 2) * render_width_ / | 146 | wxPoint popup_pos = |
147 | map_image_.GetWidth() + | 147 | MapPosToRenderPos({subway_item.x + AREA_ACTUAL_SIZE / 2, |
148 | render_x_; | 148 | subway_item.y + AREA_ACTUAL_SIZE / 2}); |
149 | int popup_y = (subway_item.y + AREA_ACTUAL_SIZE / 2) * render_width_ / | 149 | |
150 | map_image_.GetWidth() + | 150 | if (popup_pos.x + full_width > GetSize().GetWidth()) { |
151 | render_y_; | 151 | popup_pos.x = GetSize().GetWidth() - full_width; |
152 | |||
153 | if (popup_x + full_width > GetSize().GetWidth()) { | ||
154 | popup_x = GetSize().GetWidth() - full_width; | ||
155 | } | 152 | } |
156 | if (popup_y + acc_height > GetSize().GetHeight()) { | 153 | if (popup_pos.y + acc_height > GetSize().GetHeight()) { |
157 | popup_y = GetSize().GetHeight() - acc_height; | 154 | popup_pos.y = GetSize().GetHeight() - acc_height; |
158 | } | 155 | } |
159 | 156 | ||
160 | dc.SetPen(*wxTRANSPARENT_PEN); | 157 | dc.SetPen(*wxTRANSPARENT_PEN); |
161 | dc.SetBrush(*wxBLACK_BRUSH); | 158 | dc.SetBrush(*wxBLACK_BRUSH); |
162 | dc.DrawRectangle({popup_x, popup_y}, {full_width, acc_height}); | 159 | dc.DrawRectangle(popup_pos, {full_width, acc_height}); |
163 | 160 | ||
164 | dc.SetFont(GetFont()); | 161 | dc.SetFont(GetFont()); |
165 | 162 | ||
@@ -168,14 +165,15 @@ void SubwayMap::OnPaint(wxPaintEvent &event) { | |||
168 | for (const auto& [text, obtained] : report) { | 165 | for (const auto& [text, obtained] : report) { |
169 | wxBitmap *eye_ptr = obtained ? &unchecked_eye_ : &checked_eye_; | 166 | wxBitmap *eye_ptr = obtained ? &unchecked_eye_ : &checked_eye_; |
170 | 167 | ||
171 | dc.DrawBitmap(*eye_ptr, {popup_x + 10, popup_y + cur_height}); | 168 | dc.DrawBitmap(*eye_ptr, popup_pos + wxPoint{10, cur_height}); |
172 | 169 | ||
173 | dc.SetTextForeground(obtained ? *wxWHITE : *wxRED); | 170 | dc.SetTextForeground(obtained ? *wxWHITE : *wxRED); |
174 | wxSize item_extent = dc.GetTextExtent(text); | 171 | wxSize item_extent = dc.GetTextExtent(text); |
175 | dc.DrawText( | 172 | dc.DrawText( |
176 | text, | 173 | text, |
177 | {popup_x + 10 + 32 + 10, | 174 | popup_pos + |
178 | popup_y + cur_height + (32 - dc.GetFontMetrics().height) / 2}); | 175 | wxPoint{10 + 32 + 10, |
176 | cur_height + (32 - dc.GetFontMetrics().height) / 2}); | ||
179 | 177 | ||
180 | cur_height += 10 + 32; | 178 | cur_height += 10 + 32; |
181 | } | 179 | } |
@@ -189,43 +187,34 @@ void SubwayMap::OnPaint(wxPaintEvent &event) { | |||
189 | const SubwayItem &item1 = GD_GetSubwayItem(item_id1); | 187 | const SubwayItem &item1 = GD_GetSubwayItem(item_id1); |
190 | const SubwayItem &item2 = GD_GetSubwayItem(item_id2); | 188 | const SubwayItem &item2 = GD_GetSubwayItem(item_id2); |
191 | 189 | ||
192 | int item1_x = (item1.x + AREA_ACTUAL_SIZE / 2) * render_width_ / | 190 | wxPoint item1_pos = MapPosToRenderPos( |
193 | map_image_.GetWidth() + | 191 | {item1.x + AREA_ACTUAL_SIZE / 2, item1.y + AREA_ACTUAL_SIZE / 2}); |
194 | render_x_; | 192 | wxPoint item2_pos = MapPosToRenderPos( |
195 | int item1_y = (item1.y + AREA_ACTUAL_SIZE / 2) * render_width_ / | 193 | {item2.x + AREA_ACTUAL_SIZE / 2, item2.y + AREA_ACTUAL_SIZE / 2}); |
196 | map_image_.GetWidth() + | 194 | |
197 | render_y_; | 195 | int left = std::min(item1_pos.x, item2_pos.x); |
198 | 196 | int top = std::min(item1_pos.y, item2_pos.y); | |
199 | int item2_x = (item2.x + AREA_ACTUAL_SIZE / 2) * render_width_ / | 197 | int right = std::max(item1_pos.x, item2_pos.x); |
200 | map_image_.GetWidth() + | 198 | int bottom = std::max(item1_pos.y, item2_pos.y); |
201 | render_x_; | ||
202 | int item2_y = (item2.y + AREA_ACTUAL_SIZE / 2) * render_width_ / | ||
203 | map_image_.GetWidth() + | ||
204 | render_y_; | ||
205 | |||
206 | int left = std::min(item1_x, item2_x); | ||
207 | int top = std::min(item1_y, item2_y); | ||
208 | int right = std::max(item1_x, item2_x); | ||
209 | int bottom = std::max(item1_y, item2_y); | ||
210 | 199 | ||
211 | int halfwidth = right - left; | 200 | int halfwidth = right - left; |
212 | int halfheight = bottom - top; | 201 | int halfheight = bottom - top; |
213 | 202 | ||
214 | if (halfwidth < 4 || halfheight < 4) { | 203 | if (halfwidth < 4 || halfheight < 4) { |
215 | dc.SetPen(*wxThePenList->FindOrCreatePen(*wxBLACK, 4)); | 204 | dc.SetPen(*wxThePenList->FindOrCreatePen(*wxBLACK, 4)); |
216 | dc.DrawLine(item1_x, item1_y, item2_x, item2_y); | 205 | dc.DrawLine(item1_pos, item2_pos); |
217 | dc.SetPen(*wxThePenList->FindOrCreatePen(*wxCYAN, 2)); | 206 | dc.SetPen(*wxThePenList->FindOrCreatePen(*wxCYAN, 2)); |
218 | dc.DrawLine(item1_x, item1_y, item2_x, item2_y); | 207 | dc.DrawLine(item1_pos, item2_pos); |
219 | } else { | 208 | } else { |
220 | int ellipse_x; | 209 | int ellipse_x; |
221 | int ellipse_y; | 210 | int ellipse_y; |
222 | double start; | 211 | double start; |
223 | double end; | 212 | double end; |
224 | 213 | ||
225 | if (item1_x > item2_x) { | 214 | if (item1_pos.x > item2_pos.x) { |
226 | ellipse_y = top; | 215 | ellipse_y = top; |
227 | 216 | ||
228 | if (item1_y > item2_y) { | 217 | if (item1_pos.y > item2_pos.y) { |
229 | ellipse_x = left - halfwidth; | 218 | ellipse_x = left - halfwidth; |
230 | 219 | ||
231 | start = 0; | 220 | start = 0; |
@@ -239,7 +228,7 @@ void SubwayMap::OnPaint(wxPaintEvent &event) { | |||
239 | } else { | 228 | } else { |
240 | ellipse_y = top - halfheight; | 229 | ellipse_y = top - halfheight; |
241 | 230 | ||
242 | if (item1_y > item2_y) { | 231 | if (item1_pos.y > item2_pos.y) { |
243 | ellipse_x = left - halfwidth; | 232 | ellipse_x = left - halfwidth; |
244 | 233 | ||
245 | start = 270; | 234 | start = 270; |
@@ -267,15 +256,10 @@ void SubwayMap::OnPaint(wxPaintEvent &event) { | |||
267 | } | 256 | } |
268 | 257 | ||
269 | void SubwayMap::OnMouseMove(wxMouseEvent &event) { | 258 | void SubwayMap::OnMouseMove(wxMouseEvent &event) { |
270 | int mouse_x = std::clamp( | 259 | wxPoint mouse_pos = RenderPosToMapPos(event.GetPosition()); |
271 | (event.GetX() - render_x_) * map_image_.GetWidth() / render_width_, | 260 | |
272 | 0, map_image_.GetWidth() - 1); | ||
273 | int mouse_y = std::clamp( | ||
274 | (event.GetY() - render_y_) * map_image_.GetWidth() / render_width_, | ||
275 | 0, map_image_.GetHeight() - 1); | ||
276 | |||
277 | std::vector<int> hovered = tree_->query( | 261 | std::vector<int> hovered = tree_->query( |
278 | {static_cast<float>(mouse_x), static_cast<float>(mouse_y), 2, 2}); | 262 | {static_cast<float>(mouse_pos.x), static_cast<float>(mouse_pos.y), 2, 2}); |
279 | std::optional<int> new_hovered_item; | 263 | std::optional<int> new_hovered_item; |
280 | if (!hovered.empty()) { | 264 | if (!hovered.empty()) { |
281 | new_hovered_item = hovered[0]; | 265 | new_hovered_item = hovered[0]; |
@@ -369,10 +353,7 @@ void SubwayMap::Redraw() { | |||
369 | } | 353 | } |
370 | } | 354 | } |
371 | 355 | ||
372 | int real_area_x = | 356 | wxPoint real_area_pos = MapPosToRenderPos({subway_item.x, subway_item.y}); |
373 | render_x_ + subway_item.x * render_width_ / image_size.GetWidth(); | ||
374 | int real_area_y = | ||
375 | render_y_ + subway_item.y * render_width_ / image_size.GetWidth(); | ||
376 | 357 | ||
377 | int real_area_size = | 358 | int real_area_size = |
378 | render_width_ * | 359 | render_width_ * |
@@ -385,17 +366,31 @@ void SubwayMap::Redraw() { | |||
385 | if (draw_type == ItemDrawType::kBox) { | 366 | if (draw_type == ItemDrawType::kBox) { |
386 | dc.SetPen(*wxThePenList->FindOrCreatePen(*wxBLACK, 1)); | 367 | dc.SetPen(*wxThePenList->FindOrCreatePen(*wxBLACK, 1)); |
387 | dc.SetBrush(*brush_color); | 368 | dc.SetBrush(*brush_color); |
388 | dc.DrawRectangle({real_area_x, real_area_y}, | 369 | dc.DrawRectangle(real_area_pos, |
389 | {real_area_size, real_area_size}); | 370 | {real_area_size, real_area_size}); |
390 | } else if (draw_type == ItemDrawType::kOwl) { | 371 | } else if (draw_type == ItemDrawType::kOwl) { |
391 | wxBitmap owl_bitmap = wxBitmap( | 372 | wxBitmap owl_bitmap = wxBitmap( |
392 | owl_image_.Scale(real_area_size, real_area_size, | 373 | owl_image_.Scale(real_area_size, real_area_size, |
393 | wxIMAGE_QUALITY_BILINEAR)); | 374 | wxIMAGE_QUALITY_BILINEAR)); |
394 | dc.DrawBitmap(owl_bitmap, {real_area_x, real_area_y}); | 375 | dc.DrawBitmap(owl_bitmap, real_area_pos); |
395 | } | 376 | } |
396 | } | 377 | } |
397 | } | 378 | } |
398 | 379 | ||
380 | |||
381 | wxPoint SubwayMap::MapPosToRenderPos(wxPoint pos) const { | ||
382 | return {pos.x * render_width_ / map_image_.GetSize().GetWidth() + render_x_, | ||
383 | pos.y * render_width_ / map_image_.GetSize().GetWidth() + render_y_}; | ||
384 | } | ||
385 | |||
386 | wxPoint SubwayMap::RenderPosToMapPos(wxPoint pos) const { | ||
387 | return { | ||
388 | std::clamp((pos.x - render_x_) * map_image_.GetWidth() / render_width_, 0, | ||
389 | map_image_.GetWidth() - 1), | ||
390 | std::clamp((pos.y - render_y_) * map_image_.GetWidth() / render_width_, 0, | ||
391 | map_image_.GetHeight() - 1)}; | ||
392 | } | ||
393 | |||
399 | quadtree::Box<float> SubwayMap::GetItemBox::operator()(const int& id) const { | 394 | quadtree::Box<float> SubwayMap::GetItemBox::operator()(const int& id) const { |
400 | const SubwayItem &subway_item = GD_GetSubwayItem(id); | 395 | const SubwayItem &subway_item = GD_GetSubwayItem(id); |
401 | return {static_cast<float>(subway_item.x), static_cast<float>(subway_item.y), | 396 | return {static_cast<float>(subway_item.x), static_cast<float>(subway_item.y), |
diff --git a/src/subway_map.h b/src/subway_map.h index 52d07b8..0d26d0b 100644 --- a/src/subway_map.h +++ b/src/subway_map.h | |||
@@ -32,6 +32,9 @@ class SubwayMap : public wxPanel { | |||
32 | 32 | ||
33 | void Redraw(); | 33 | void Redraw(); |
34 | 34 | ||
35 | wxPoint MapPosToRenderPos(wxPoint pos) const; | ||
36 | wxPoint RenderPosToMapPos(wxPoint pos) const; | ||
37 | |||
35 | wxImage map_image_; | 38 | wxImage map_image_; |
36 | wxImage owl_image_; | 39 | wxImage owl_image_; |
37 | wxBitmap unchecked_eye_; | 40 | wxBitmap unchecked_eye_; |