Fix the new status area code
[lsnes.git] / src / platform / wxwidgets / status.cpp
blob2467a7decf4a8d0aaf97b8863e15537e0a880588
1 #include "core/window.hpp"
2 #include "platform/wxwidgets/platform.hpp"
3 #include "platform/wxwidgets/window_status.hpp"
4 #include "library/string.hpp"
5 #include "library/minmax.hpp"
6 #include <iostream>
8 #define STATWIDTH 40
9 #define MAXSTATUS 30
11 namespace
13 std::string string_pad(const std::string& x, size_t width)
15 if(x.length() >= width)
16 return x;
17 std::string y = x;
18 y.append(width - y.length(), ' ');
19 return y;
23 wxwin_status::panel::panel(wxWindow* _parent, wxWindow* focuswin, unsigned lines)
24 : wxPanel(_parent)
26 tfocuswin = focuswin;
27 parent = _parent;
28 dirty = false;
29 statusvars.set_size(STATWIDTH, lines ? lines : MAXSTATUS);
30 auto s = statusvars.get_pixels();
31 SetMinSize(wxSize(s.first, s.second));
32 this->Connect(wxEVT_PAINT, wxPaintEventHandler(wxwin_status::panel::on_paint), NULL, this);
33 this->Connect(wxEVT_SET_FOCUS, wxFocusEventHandler(wxwin_status::panel::on_focus), NULL, this);
36 bool wxwin_status::panel::AcceptsFocus () const
38 return false;
41 void wxwin_status::panel::on_focus(wxFocusEvent& e)
43 if(tfocuswin)
44 tfocuswin->SetFocus();
47 wxwin_status::wxwin_status()
48 : wxFrame(NULL, wxID_ANY, wxT("lsnes: Status"), wxDefaultPosition, wxSize(-1, -1),
49 wxMINIMIZE_BOX | wxSYSTEM_MENU | wxCAPTION | wxCLIP_CHILDREN)
51 wxFlexGridSizer* top_s = new wxFlexGridSizer(1, 1, 0, 0);
52 top_s->Add(spanel = new wxwin_status::panel(this, NULL, MAXSTATUS));
53 top_s->SetSizeHints(this);
54 SetSizer(top_s);
55 Fit();
58 wxwin_status::~wxwin_status()
62 void wxwin_status::panel::on_paint(wxPaintEvent& e)
64 //Quickly copy the status area.
65 auto& s = platform::get_emustatus();
66 std::map<std::string, std::string> newstatus;
67 emulator_status::iterator i = s.first();
68 while(s.next(i))
69 newstatus[i.key] = i.value;
71 memorywatches.clear();
72 statusvars.clear();
74 wxPaintDC dc(this);
75 dc.Clear();
76 int y = 0;
77 size_t mem_width = 0;
78 size_t oth_width = 0;
79 size_t mem_count = 0;
80 size_t oth_count = 0;
81 for(auto i : newstatus) {
82 bool x = regex_match("M\\[.*\\]", i.first);
83 if(x) {
84 mem_width = max(mem_width, text_framebuffer::text_width(i.first) - 3);
85 mem_count++;
86 } else {
87 oth_width = max(oth_width, text_framebuffer::text_width(i.first));
88 oth_count++;
91 regex_results r;
92 size_t p = 1;
93 if(mem_count) {
94 memorywatches.set_size(STATWIDTH, mem_count + 1);
95 memorywatches.write("Memory watches:", 0, 0, 0, 0, 0xFFFFFF);
96 for(auto i : newstatus) {
97 if(r = regex("M\\[(.*)\\]", i.first)) {
98 size_t n = memorywatches.write(r[1], mem_width + 1, 0, p, 0, 0xFFFFFF);
99 memorywatches.write(i.second, 0, n, p, 0, 0xFFFFFF);
100 p++;
104 statusvars.set_size(STATWIDTH, oth_count + 1);
105 if(mem_count)
106 statusvars.write("Status:", 0, 0, 0, 0, 0xFFFFFF);
107 p = mem_count ? 1 : 0;
108 for(auto i : newstatus) {
109 if(regex_match("M\\[.*\\]", i.first))
110 continue;
111 size_t n = statusvars.write(i.first, oth_width + 1, 0, p, 0, 0xFFFFFF);
112 statusvars.write(i.second, 0, n, p, 0, 0xFFFFFF);
113 p++;
116 auto ssize = statusvars.get_pixels();
117 auto msize = memorywatches.get_pixels();
118 std::vector<char> buffer1, buffer2;
119 buffer1.resize(msize.first * msize.second * 3);
120 buffer2.resize(ssize.first * ssize.second * 3);
121 memorywatches.render(&buffer1[0]);
122 statusvars.render(&buffer2[0]);
123 wxBitmap bmp2(wxImage(ssize.first, ssize.second, reinterpret_cast<unsigned char*>(&buffer2[0]), true));
124 if(mem_count) {
125 wxBitmap bmp1(wxImage(msize.first, msize.second, reinterpret_cast<unsigned char*>(&buffer1[0]), true));
126 dc.DrawBitmap(bmp1, 0, 0, false);
127 dc.SetPen(wxPen(wxColour(0, 0, 0)));
128 dc.DrawLine(0, msize.second + 1, msize.first, msize.second + 1);
130 dc.DrawBitmap(bmp2, 0, mem_count ? msize.second + 3 : 0, false);
132 dirty = false;
135 void wxwin_status::notify_update() throw()
137 if(spanel->dirty)
138 return;
139 spanel->dirty = true;
140 spanel->Refresh();
143 bool wxwin_status::ShouldPreventAppExit() const
145 return false;