#include "report_popup.h"
#include <wx/dcbuffer.h>
#include <map>
#include <string>
#include "global.h"
#include "icons.h"
#include "tracker_state.h"
ReportPopup::ReportPopup(wxWindow* parent)
: wxScrolledCanvas(parent, wxID_ANY) {
SetBackgroundStyle(wxBG_STYLE_PAINT);
LoadIcons();
// TODO: This is slow on high-DPI screens.
SetScrollRate(5, 5);
SetBackgroundColour(*wxBLACK);
Hide();
Bind(wxEVT_PAINT, &ReportPopup::OnPaint, this);
Bind(wxEVT_DPI_CHANGED, &ReportPopup::OnDPIChanged, this);
}
void ReportPopup::SetDoorId(int door_id) {
door_id_ = door_id;
ResetIndicators();
}
void ReportPopup::Reset() {
door_id_ = -1;
}
void ReportPopup::ResetIndicators() {
if (door_id_ == -1) {
return;
}
wxFont the_font = GetFont().Scale(GetDPIScaleFactor());
const std::map<std::string, bool>& report = GetDoorRequirements(door_id_);
wxMemoryDC mem_dc;
mem_dc.SetFont(the_font);
int acc_height = FromDIP(10);
int col_width = 0;
for (const auto& [text, obtained] : report) {
wxSize item_extent = mem_dc.GetTextExtent(text);
int item_height =
std::max(FromDIP(32), item_extent.GetHeight()) + FromDIP(10);
acc_height += item_height;
if (item_extent.GetWidth() > col_width) {
col_width = item_extent.GetWidth();
}
}
int item_width = col_width + FromDIP(10 + 32);
full_width_ = item_width + FromDIP(20);
full_height_ = acc_height;
Fit();
SetVirtualSize(full_width_, full_height_);
UpdateIndicators();
}
void ReportPopup::UpdateIndicators() {
if (door_id_ == -1) {
return;
}
wxFont the_font = GetFont().Scale(GetDPIScaleFactor());
const std::map<std::string, bool>& report = GetDoorRequirements(door_id_);
rendered_ = wxBitmap(full_width_, full_height_);
wxMemoryDC mem_dc;
mem_dc.SelectObject(rendered_);
mem_dc.SetPen(*wxTRANSPARENT_PEN);
mem_dc.SetBrush(*wxBLACK_BRUSH);
mem_dc.DrawRectangle({0, 0}, {full_width_, full_height_});
mem_dc.SetFont(the_font);
int cur_height = FromDIP(10);
for (const auto& [text, obtained] : report) {
const wxBitmap* eye_ptr = obtained ? checked_eye_ : unchecked_eye_;
mem_dc.DrawBitmap(*eye_ptr, wxPoint{FromDIP(10), cur_height});
mem_dc.SetTextForeground(obtained ? *wxWHITE : *wxRED);
wxSize item_extent = mem_dc.GetTextExtent(text);
mem_dc.DrawText(
text, wxPoint{FromDIP(10 + 32 + 10),
cur_height +
(FromDIP(32) - mem_dc.GetFontMetrics().height) / 2});
cur_height += FromDIP(10 + 32);
}
}
void ReportPopup::OnPaint(wxPaintEvent& event) {
if (door_id_ != -1) {
wxBufferedPaintDC dc(this);
PrepareDC(dc);
dc.DrawBitmap(rendered_, 0, 0);
}
event.Skip();
}
void ReportPopup::OnDPIChanged(wxDPIChangedEvent& event) {
LoadIcons();
ResetIndicators();
event.Skip();
}
void ReportPopup::LoadIcons() {
unchecked_eye_ = GetTheIconCache().GetIcon("assets/unchecked.png",
FromDIP(wxSize{32, 32}));
checked_eye_ =
GetTheIconCache().GetIcon("assets/checked.png", FromDIP(wxSize{32, 32}));
}