about summary refs log tree commit diff stats
path: root/src/subway_map.cpp
blob: 0aa7df3de9f79951982bf4d9992e3254a54a2391 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
#include "subway_map.h"

#include "game_data.h"
#include "global.h"
#include "tracker_state.h"

constexpr int AREA_ACTUAL_SIZE = 21;

enum class ItemDrawType {
  kNone,
  kBox,
  kOwl
};

SubwayMap::SubwayMap(wxWindow *parent) : wxPanel(parent, wxID_ANY) {
  map_image_ =
      wxImage(GetAbsolutePath("assets/subway.png").c_str(), wxBITMAP_TYPE_PNG);
  if (!map_image_.IsOk()) {
    return;
  }

  owl_image_ =
      wxImage(GetAbsolutePath("assets/owl.png").c_str(), wxBITMAP_TYPE_PNG);
  if (!owl_image_.IsOk()) {
    return;
  }

  Redraw();

  Bind(wxEVT_PAINT, &SubwayMap::OnPaint, this);
  Bind(wxEVT_MOTION, &SubwayMap::OnMouseMove, this);
}

void SubwayMap::UpdateIndicators() {
  Redraw();
}

void SubwayMap::OnPaint(wxPaintEvent &event) {
  if (GetSize() != rendered_.GetSize()) {
    Redraw();
  }

  wxPaintDC dc(this);
  dc.DrawBitmap(rendered_, 0, 0);

  event.Skip();
}

void SubwayMap::OnMouseMove(wxMouseEvent &event) {
  event.Skip();
}

void SubwayMap::Redraw() {
  wxSize panel_size = GetSize();
  wxSize image_size = map_image_.GetSize();

  render_x_ = 0;
  render_y_ = 0;
  render_width_ = panel_size.GetWidth();
  render_height_ = panel_size.GetHeight();

  if (image_size.GetWidth() * panel_size.GetHeight() >
      panel_size.GetWidth() * image_size.GetHeight()) {
    render_height_ = (panel_size.GetWidth() * image_size.GetHeight()) /
                     image_size.GetWidth();
    render_y_ = (panel_size.GetHeight() - render_height_) / 2;
  } else {
    render_width_ = (image_size.GetWidth() * panel_size.GetHeight()) /
                    image_size.GetHeight();
    render_x_ = (panel_size.GetWidth() - render_width_) / 2;
  }

  rendered_ = wxBitmap(
      map_image_
          .Scale(render_width_, render_height_, wxIMAGE_QUALITY_BILINEAR)
          .Size(panel_size, {render_x_, render_y_}, 0, 0, 0));

  wxMemoryDC dc;
  dc.SelectObject(rendered_);

  int real_area_size =
      render_width_ * AREA_ACTUAL_SIZE / image_size.GetWidth();
  if (real_area_size == 0) {
    real_area_size = 1;
  }
  wxBitmap owl_bitmap = wxBitmap(owl_image_.Scale(
      real_area_size * 1.25, real_area_size * 1.25, wxIMAGE_QUALITY_BILINEAR));

  for (const SubwayItem &subway_item : GD_GetSubwayItems()) {
    ItemDrawType draw_type = ItemDrawType::kNone;
    const wxBrush *brush_color = wxGREY_BRUSH;

    if (subway_item.door) {
      draw_type = ItemDrawType::kBox;

      if (IsDoorOpen(*subway_item.door)) {
        if (!subway_item.paintings.empty()) {
          draw_type = ItemDrawType::kOwl;
        } else {
          brush_color = wxGREEN_BRUSH;
        }
      } else {
        brush_color = wxRED_BRUSH;
      }
    } else if (!subway_item.paintings.empty()) {
      draw_type = ItemDrawType::kOwl;
    }

    int real_area_x =
        render_x_ + subway_item.x * render_width_ / image_size.GetWidth();
    int real_area_y =
        render_y_ + subway_item.y * render_width_ / image_size.GetWidth();

    if (draw_type == ItemDrawType::kBox) {
      dc.SetPen(*wxThePenList->FindOrCreatePen(*wxBLACK, 1));
      dc.SetBrush(*brush_color);
      dc.DrawRectangle({real_area_x, real_area_y},
                       {real_area_size, real_area_size});
    } else if (draw_type == ItemDrawType::kOwl) {
      dc.DrawBitmap(owl_bitmap, {real_area_x, real_area_y});
    }
  }
}