3 #include <wx/control.h>
4 #include <wx/combobox.h>
5 #include <wx/statline.h>
7 #include "core/emustatus.hpp"
8 #include "core/instance.hpp"
9 #include "core/window.hpp"
10 #include "platform/wxwidgets/platform.hpp"
11 #include "platform/wxwidgets/window_status.hpp"
12 #include "platform/wxwidgets/window_mainwindow.hpp"
13 #include "library/string.hpp"
14 #include "library/minmax.hpp"
20 wxwin_status::panel::panel(wxWindow
* _parent
, emulator_instance
& _inst
, wxWindow
* focuswin
, unsigned lines
)
21 : text_framebuffer_panel(_parent
, STATWIDTH
, lines
? lines
: MAXSTATUS
, wxID_ANY
, focuswin
), inst(_inst
)
26 wxwin_status::wxwin_status(int flag
, emulator_instance
& _inst
, const std::string
& title
)
27 : wxFrame(NULL
, wxID_ANY
, towxstring(title
), wxDefaultPosition
, wxSize(-1, -1),
28 wxMINIMIZE_BOX
| wxRESIZE_BORDER
| wxSYSTEM_MENU
| wxCAPTION
| wxCLIP_CHILDREN
), inst(_inst
)
31 wxBoxSizer
* top_s
= new wxBoxSizer(wxVERTICAL
);
32 top_s
->Add(spanel
= new wxwin_status::panel(this, inst
, NULL
, MAXSTATUS
), 1, wxGROW
);
33 spanel
->set_watch_flag(flag
);
34 top_s
->SetSizeHints(this);
39 wxwin_status::~wxwin_status()
45 void register_entry(size_t& count
, size_t& width
, const std::string
& text
)
47 width
= max(width
, text_framebuffer::text_width(text
));
51 void show_entry(text_framebuffer_panel
& tp
, bool& sofar
, size_t& line
, size_t width
, const std::string
& name
,
52 const std::u32string
& text
)
54 size_t n
= tp
.write(name
, width
+ 1, 0, line
, 0, 0xFFFFFF);
55 tp
.write(text
, 0, n
, line
++, 0, 0xFFFFFF);
59 void draw_split(text_framebuffer_panel
& tp
, size_t& line
)
61 auto s
= tp
.get_characters();
62 for(unsigned i
= 0; i
< s
.first
; i
++)
63 tp
.write(U
"\u2500", 0, i
, line
, 0, 0xFFFFFF);
67 int num_nonzeroes() { return 0; }
68 template<typename T
, typename
... U
> int num_nonzeroes(T hd
, U
... tl
) {
69 return (hd
? 1 : 0) + num_nonzeroes(tl
...);
71 template<typename
... T
> bool one_nonzero(T
... args
) { return (num_nonzeroes(args
...) == 1); }
74 void wxwin_status::panel::prepare_paint()
79 auto& newstatus
= inst
.status
->get_read();
81 bool entry_so_far
= false;
89 for(auto& i
: newstatus
.mvars
) register_entry(mem_count
, mem_width
, i
.first
);
90 if(newstatus
.rtc_valid
) register_entry(oth_count
, oth_width
, "RTC");
91 for(size_t j
= 0; j
< newstatus
.inputs
.size(); j
++)
92 register_entry(oth_count
, oth_width
, (stringfmt() << "P" << (j
+ 1)).str());
93 for(auto& i
: newstatus
.lvars
) register_entry(lua_count
, lua_width
, i
.first
);
101 single
= one_nonzero(mem_count
, oth_count
, lua_count
);
106 if(entry_so_far
) draw_split(*this, p
);
107 if(!single
) write("Memory watches:", 0, 0, p
++, 0, 0xFFFFFF);
108 for(auto i
: newstatus
.mvars
) show_entry(*this, entry_so_far
, p
, mem_width
, i
.first
,
113 if(entry_so_far
) draw_split(*this, p
);
114 if(!single
) write("Status:", 0, 0, p
++, 0, 0xFFFFFF);
115 if(newstatus
.rtc_valid
) show_entry(*this, entry_so_far
, p
, oth_width
, "RTC", newstatus
.rtc
);
116 for(size_t j
= 0; j
< newstatus
.inputs
.size(); j
++)
117 show_entry(*this, entry_so_far
, p
, oth_width
, (stringfmt() << "P" << (j
+ 1)).str(),
118 newstatus
.inputs
[j
]);
122 if(entry_so_far
) draw_split(*this, p
);
123 if(!single
) write("From Lua:", 0, 0, p
++, 0, 0xFFFFFF);
124 for(auto i
: newstatus
.lvars
) show_entry(*this, entry_so_far
, p
, lua_width
, i
.first
,
129 inst
.status
->put_read();
132 void wxwin_status::notify_update() throw()
135 spanel
->request_paint();
138 bool wxwin_status::ShouldPreventAppExit() const