548 lines
18 KiB
C++
548 lines
18 KiB
C++
#include "CameraPopup.hpp"
|
|
|
|
#include "I18N.hpp"
|
|
#include "Widgets/Label.hpp"
|
|
#include "libslic3r/Utils.hpp"
|
|
#include "BitmapCache.hpp"
|
|
#include <wx/progdlg.h>
|
|
#include <wx/clipbrd.h>
|
|
#include <wx/dcgraph.h>
|
|
#include "GUI_App.hpp"
|
|
#include <slic3r/GUI/StatusPanel.hpp>
|
|
|
|
namespace Slic3r {
|
|
namespace GUI {
|
|
|
|
wxIMPLEMENT_CLASS(CameraPopup, PopupWindow);
|
|
|
|
wxBEGIN_EVENT_TABLE(CameraPopup, PopupWindow)
|
|
EVT_MOUSE_EVENTS(CameraPopup::OnMouse )
|
|
EVT_SIZE(CameraPopup::OnSize)
|
|
EVT_SET_FOCUS(CameraPopup::OnSetFocus )
|
|
EVT_KILL_FOCUS(CameraPopup::OnKillFocus )
|
|
wxEND_EVENT_TABLE()
|
|
|
|
wxDEFINE_EVENT(EVT_VCAMERA_SWITCH, wxMouseEvent);
|
|
wxDEFINE_EVENT(EVT_SDCARD_ABSENT_HINT, wxCommandEvent);
|
|
|
|
#define CAMERAPOPUP_CLICK_INTERVAL 20
|
|
|
|
const wxColour TEXT_COL = wxColour(43, 52, 54);
|
|
|
|
CameraPopup::CameraPopup(wxWindow *parent)
|
|
: PopupWindow(parent, wxBORDER_NONE | wxPU_CONTAINS_CONTROLS)
|
|
{
|
|
#ifdef __WINDOWS__
|
|
SetDoubleBuffered(true);
|
|
#endif
|
|
m_panel = new wxScrolledWindow(this, wxID_ANY);
|
|
m_panel->SetBackgroundColour(*wxWHITE);
|
|
m_panel->SetMinSize(wxSize(FromDIP(180),-1));
|
|
m_panel->Bind(wxEVT_MOTION, &CameraPopup::OnMouse, this);
|
|
|
|
main_sizer = new wxBoxSizer(wxVERTICAL);
|
|
wxFlexGridSizer* top_sizer = new wxFlexGridSizer(0, 2, 0, FromDIP(50));
|
|
top_sizer->AddGrowableCol(0);
|
|
top_sizer->SetFlexibleDirection(wxBOTH);
|
|
top_sizer->SetNonFlexibleGrowMode(wxFLEX_GROWMODE_SPECIFIED);
|
|
|
|
//recording
|
|
m_text_recording = new wxStaticText(m_panel, wxID_ANY, _L("Auto-record Monitoring"));
|
|
m_text_recording->Wrap(-1);
|
|
m_text_recording->SetFont(Label::Head_14);
|
|
m_text_recording->SetForegroundColour(TEXT_COL);
|
|
m_switch_recording = new SwitchButton(m_panel);
|
|
|
|
//vcamera
|
|
m_text_vcamera = new wxStaticText(m_panel, wxID_ANY, _L("Go Live"));
|
|
m_text_vcamera->Wrap(-1);
|
|
m_text_vcamera->SetFont(Label::Head_14);
|
|
m_text_vcamera->SetForegroundColour(TEXT_COL);
|
|
m_switch_vcamera = new SwitchButton(m_panel);
|
|
|
|
top_sizer->Add(m_text_recording, 0, wxALIGN_CENTER_VERTICAL | wxALIGN_LEFT | wxALL, FromDIP(5));
|
|
top_sizer->Add(m_switch_recording, 0, wxALIGN_CENTER_VERTICAL | wxALIGN_RIGHT | wxALL, FromDIP(5));
|
|
top_sizer->Add(m_text_vcamera, 0, wxALIGN_CENTER_VERTICAL | wxALIGN_LEFT | wxALL, FromDIP(5));
|
|
top_sizer->Add(m_switch_vcamera, 0, wxALIGN_CENTER_VERTICAL | wxALIGN_RIGHT | wxALL, FromDIP(5));
|
|
|
|
#if !BBL_RELEASE_TO_PUBLIC
|
|
m_text_liveview_retry = new wxStaticText(m_panel, wxID_ANY, _L("Liveview Retry"));
|
|
m_text_liveview_retry->Wrap(-1);
|
|
m_text_liveview_retry->SetFont(Label::Head_14);
|
|
m_text_liveview_retry->SetForegroundColour(TEXT_COL);
|
|
m_switch_liveview_retry = new SwitchButton(m_panel);
|
|
bool auto_retry = wxGetApp().app_config->get("liveview", "auto_retry") != "false";
|
|
m_switch_liveview_retry->SetValue(auto_retry);
|
|
|
|
top_sizer->Add(m_text_liveview_retry, 0, wxALIGN_CENTER_VERTICAL | wxALIGN_LEFT | wxALL, FromDIP(5));
|
|
top_sizer->Add(m_switch_liveview_retry, 0, wxALIGN_CENTER_VERTICAL | wxALIGN_RIGHT | wxALL, FromDIP(5));
|
|
|
|
m_switch_liveview_retry->Bind(wxEVT_TOGGLEBUTTON, [this](wxCommandEvent &e) {
|
|
wxGetApp().app_config->set("liveview", "auto_retry", e.IsChecked());
|
|
e.Skip();
|
|
});
|
|
#endif
|
|
|
|
//resolution
|
|
m_text_resolution = new wxStaticText(m_panel, wxID_ANY, _L("Resolution"));
|
|
m_text_resolution->Wrap(-1);
|
|
m_text_resolution->SetFont(Label::Head_14);
|
|
m_text_resolution->SetForegroundColour(TEXT_COL);
|
|
top_sizer->Add(m_text_resolution, 0, wxALIGN_CENTER_VERTICAL | wxALIGN_LEFT | wxALL, FromDIP(5));
|
|
top_sizer->Add(0, 0, wxALL, 0);
|
|
for (int i = 0; i < (int)RESOLUTION_OPTIONS_NUM; ++i)
|
|
{
|
|
m_resolution_options[i] = create_item_radiobox(to_resolution_label_string(CameraResolution(i)), m_panel, wxEmptyString, FromDIP(10));
|
|
top_sizer->Add(m_resolution_options[i], 0, wxALIGN_CENTER_VERTICAL | wxALIGN_LEFT | wxALL, FromDIP(5));
|
|
top_sizer->Add(0, 0, wxALL, 0);
|
|
}
|
|
|
|
main_sizer->Add(top_sizer, 0, wxALL, FromDIP(10));
|
|
|
|
auto url = wxString::Format(L"https://wiki.bambulab.com/%s/software/bambu-studio/virtual-camera", L"en");
|
|
auto text = _L("Show \"Live Video\" guide page.");
|
|
|
|
wxBoxSizer* link_sizer = new wxBoxSizer(wxVERTICAL);
|
|
vcamera_guide_link = new Label(m_panel, text);
|
|
vcamera_guide_link->Wrap(-1);
|
|
vcamera_guide_link->SetForegroundColour(wxColour(0x1F, 0x8E, 0xEA));
|
|
auto text_size = vcamera_guide_link->GetTextExtent(text);
|
|
vcamera_guide_link->Bind(wxEVT_LEFT_DOWN, [this, url](wxMouseEvent& e) {wxLaunchDefaultBrowser(url); });
|
|
|
|
link_underline = new wxPanel(m_panel, wxID_ANY, wxDefaultPosition, wxSize(-1, 1), wxTAB_TRAVERSAL);
|
|
link_underline->SetBackgroundColour(wxColour(0x1F, 0x8E, 0xEA));
|
|
link_underline->SetSize(wxSize(text_size.x, 1));
|
|
link_underline->SetMinSize(wxSize(text_size.x, 1));
|
|
|
|
vcamera_guide_link->Hide();
|
|
link_underline->Hide();
|
|
link_sizer->Add(vcamera_guide_link, 0, wxALL, 0);
|
|
link_sizer->Add(link_underline, 0, wxALL, 0);
|
|
|
|
main_sizer->Add(link_sizer, 0, wxALL, FromDIP(15));
|
|
|
|
m_panel->SetSizer(main_sizer);
|
|
m_panel->Layout();
|
|
|
|
main_sizer->Fit(m_panel);
|
|
|
|
SetClientSize(m_panel->GetSize());
|
|
m_switch_recording->Connect(wxEVT_LEFT_DOWN, wxCommandEventHandler(CameraPopup::on_switch_recording), NULL, this);
|
|
m_switch_vcamera->Bind(wxEVT_LEFT_DOWN, [this](wxMouseEvent &e) {
|
|
wxMouseEvent evt(EVT_VCAMERA_SWITCH);
|
|
evt.SetEventObject(this);
|
|
GetEventHandler()->ProcessEvent(evt);
|
|
});
|
|
#ifdef __APPLE__
|
|
m_panel->Bind(wxEVT_LEFT_UP, &CameraPopup::OnLeftUp, this);
|
|
#endif //APPLE
|
|
|
|
this->Bind(wxEVT_TIMER, &CameraPopup::stop_interval, this);
|
|
m_interval_timer = new wxTimer();
|
|
m_interval_timer->SetOwner(this);
|
|
|
|
wxGetApp().UpdateDarkUIWin(this);
|
|
}
|
|
|
|
void CameraPopup::sdcard_absent_hint()
|
|
{
|
|
wxCommandEvent evt(EVT_SDCARD_ABSENT_HINT);
|
|
evt.SetEventObject(this);
|
|
GetEventHandler()->ProcessEvent(evt);
|
|
}
|
|
|
|
void CameraPopup::on_switch_recording(wxCommandEvent& event)
|
|
{
|
|
if (!m_obj) return;
|
|
if (m_obj->sdcard_state != MachineObject::SdcardState::HAS_SDCARD_NORMAL) {
|
|
sdcard_absent_hint();
|
|
return;
|
|
}
|
|
bool value = m_switch_recording->GetValue();
|
|
m_switch_recording->SetValue(!value);
|
|
m_obj->command_ipcam_record(!value);
|
|
}
|
|
|
|
void CameraPopup::on_set_resolution()
|
|
{
|
|
if (!m_obj) return;
|
|
|
|
m_obj->command_ipcam_resolution_set(to_resolution_msg_string(curr_sel_resolution));
|
|
}
|
|
|
|
void CameraPopup::Popup(wxWindow *WXUNUSED(focus))
|
|
{
|
|
wxPoint curr_position = this->GetPosition();
|
|
wxSize win_size = this->GetSize();
|
|
curr_position.x -= win_size.x;
|
|
this->SetPosition(curr_position);
|
|
|
|
if (!m_is_in_interval)
|
|
PopupWindow::Popup();
|
|
}
|
|
|
|
wxWindow* CameraPopup::create_item_radiobox(wxString title, wxWindow* parent, wxString tooltip, int padding_left)
|
|
{
|
|
wxWindow *item = new wxWindow(parent, wxID_ANY, wxDefaultPosition, wxSize(-1, FromDIP(20)));
|
|
item->SetBackgroundColour(*wxWHITE);
|
|
|
|
RadioBox *radiobox = new RadioBox(item);
|
|
radiobox->SetPosition(wxPoint(padding_left, (item->GetSize().GetHeight() - radiobox->GetSize().GetHeight()) / 2));
|
|
resolution_rbtns.push_back(radiobox);
|
|
int btn_idx = resolution_rbtns.size() - 1;
|
|
radiobox->Bind(wxEVT_LEFT_DOWN, [this, btn_idx](wxMouseEvent &e) {
|
|
if (m_obj && allow_alter_resolution) {
|
|
select_curr_radiobox(btn_idx);
|
|
on_set_resolution();
|
|
}
|
|
});
|
|
|
|
wxStaticText *text = new wxStaticText(item, wxID_ANY, title, wxDefaultPosition, wxDefaultSize);
|
|
text->SetForegroundColour(*wxBLACK);
|
|
resolution_texts.push_back(text);
|
|
text->SetPosition(wxPoint(padding_left + radiobox->GetSize().GetWidth() + 10, (item->GetSize().GetHeight() - text->GetSize().GetHeight()) / 2));
|
|
text->SetFont(Label::Body_13);
|
|
text->SetForegroundColour(0x6B6B6B);
|
|
text->Bind(wxEVT_LEFT_DOWN, [this, btn_idx](wxMouseEvent &e) {
|
|
if (m_obj && allow_alter_resolution) {
|
|
select_curr_radiobox(btn_idx);
|
|
on_set_resolution();
|
|
}
|
|
});
|
|
|
|
radiobox->SetToolTip(tooltip);
|
|
text->SetToolTip(tooltip);
|
|
return item;
|
|
}
|
|
|
|
void CameraPopup::select_curr_radiobox(int btn_idx)
|
|
{
|
|
if (!m_obj) return;
|
|
|
|
int len = resolution_rbtns.size();
|
|
for (int i = 0; i < len; ++i) {
|
|
if (i == btn_idx) {
|
|
curr_sel_resolution = CameraResolution(i);
|
|
resolution_rbtns[i]->SetValue(true);
|
|
}
|
|
else {
|
|
resolution_rbtns[i]->SetValue(false);
|
|
}
|
|
}
|
|
}
|
|
|
|
void CameraPopup::sync_resolution_setting(std::string resolution)
|
|
{
|
|
if (resolution == "") {
|
|
reset_resolution_setting();
|
|
return;
|
|
}
|
|
int res = 0;
|
|
for (CameraResolution i = RESOLUTION_720P; i < RESOLUTION_OPTIONS_NUM; i = CameraResolution(i+1)){
|
|
if (resolution == to_resolution_msg_string(i)) {
|
|
res = int(i);
|
|
break;
|
|
}
|
|
}
|
|
select_curr_radiobox(res);
|
|
}
|
|
|
|
void CameraPopup::reset_resolution_setting()
|
|
{
|
|
int len = resolution_rbtns.size();
|
|
for (int i = 0; i < len; ++i) {
|
|
resolution_rbtns[i]->SetValue(false);
|
|
}
|
|
curr_sel_resolution = RESOLUTION_OPTIONS_NUM;
|
|
}
|
|
|
|
void CameraPopup::sync_vcamera_state(bool show_vcamera)
|
|
{
|
|
is_vcamera_show = show_vcamera;
|
|
if (is_vcamera_show) {
|
|
m_switch_vcamera->SetValue(true);
|
|
vcamera_guide_link->Show();
|
|
link_underline->Show();
|
|
}
|
|
else {
|
|
m_switch_vcamera->SetValue(false);
|
|
vcamera_guide_link->Hide();
|
|
link_underline->Hide();
|
|
}
|
|
|
|
rescale();
|
|
}
|
|
|
|
void CameraPopup::check_func_supported(MachineObject *obj2)
|
|
{
|
|
m_obj = obj2;
|
|
if (m_obj == nullptr)
|
|
return;
|
|
// function supported
|
|
if (m_obj->has_ipcam) {
|
|
m_text_recording->Show();
|
|
m_switch_recording->Show();
|
|
} else {
|
|
m_text_recording->Hide();
|
|
m_switch_recording->Hide();
|
|
}
|
|
|
|
if (m_obj->virtual_camera && m_obj->has_ipcam) {
|
|
m_text_vcamera->Show();
|
|
m_switch_vcamera->Show();
|
|
if (is_vcamera_show) {
|
|
vcamera_guide_link->Show();
|
|
link_underline->Show();
|
|
}
|
|
} else {
|
|
m_text_vcamera->Hide();
|
|
m_switch_vcamera->Hide();
|
|
vcamera_guide_link->Hide();
|
|
link_underline->Hide();
|
|
}
|
|
|
|
allow_alter_resolution = ( (m_obj->camera_resolution_supported.size() > 1?true:false) && m_obj->has_ipcam);
|
|
|
|
//check u2 version
|
|
DeviceManager* dev = Slic3r::GUI::wxGetApp().getDeviceManager();
|
|
if (!dev) return;
|
|
MachineObject* obj = dev->get_selected_machine();
|
|
if (!obj) return;
|
|
|
|
//resolution supported
|
|
std::vector<std::string> resolution_supported = m_obj->get_resolution_supported();
|
|
auto support_count = resolution_supported.size();
|
|
for (int i = 0; i < (int)RESOLUTION_OPTIONS_NUM; ++i){
|
|
auto curr_res = to_resolution_msg_string(CameraResolution(i));
|
|
std::vector <std::string> ::iterator it = std::find(resolution_supported.begin(), resolution_supported.end(), curr_res);
|
|
if ((it == resolution_supported.end())||(support_count <= 1) || !obj->is_support_1080dpi)
|
|
m_resolution_options[i]->Hide();
|
|
else {
|
|
m_resolution_options[i]->Show();
|
|
if (m_obj->camera_resolution == curr_res) {
|
|
resolution_rbtns[i]->SetValue(true);
|
|
}
|
|
}
|
|
}
|
|
//hide resolution if there is only one choice
|
|
if (support_count <= 1 || !obj->is_support_1080dpi) {
|
|
m_text_resolution->Hide();
|
|
}
|
|
else {
|
|
m_text_resolution->Show();
|
|
}
|
|
}
|
|
|
|
void CameraPopup::update(bool vcamera_streaming)
|
|
{
|
|
if (!m_obj) return;
|
|
m_switch_recording->SetValue(m_obj->camera_recording_when_printing);
|
|
sync_resolution_setting(m_obj->camera_resolution);
|
|
sync_vcamera_state(vcamera_streaming);
|
|
|
|
rescale();
|
|
}
|
|
|
|
wxString CameraPopup::to_resolution_label_string(CameraResolution resolution) {
|
|
switch (resolution) {
|
|
case RESOLUTION_720P:
|
|
return "720p";
|
|
case RESOLUTION_1080P:
|
|
return "1080p";
|
|
default:
|
|
return "";
|
|
}
|
|
return "";
|
|
}
|
|
|
|
std::string CameraPopup::to_resolution_msg_string(CameraResolution resolution) {
|
|
switch (resolution) {
|
|
case RESOLUTION_720P:
|
|
return std::string("720p");
|
|
case RESOLUTION_1080P:
|
|
return std::string("1080p");
|
|
default:
|
|
return "";
|
|
}
|
|
return "";
|
|
}
|
|
|
|
void CameraPopup::rescale()
|
|
{
|
|
m_panel->Layout();
|
|
main_sizer->Fit(m_panel);
|
|
SetClientSize(m_panel->GetSize());
|
|
PopupWindow::Update();
|
|
}
|
|
|
|
void CameraPopup::OnLeftUp(wxMouseEvent &event)
|
|
{
|
|
auto mouse_pos = ClientToScreen(event.GetPosition());
|
|
auto wxscroll_win_pos = m_panel->ClientToScreen(wxPoint(0, 0));
|
|
|
|
if (mouse_pos.x > wxscroll_win_pos.x && mouse_pos.y > wxscroll_win_pos.y && mouse_pos.x < (wxscroll_win_pos.x + m_panel->GetSize().x) && mouse_pos.y < (wxscroll_win_pos.y + m_panel->GetSize().y)) {
|
|
//recording
|
|
auto recording_rect = m_switch_recording->ClientToScreen(wxPoint(0, 0));
|
|
if (mouse_pos.x > recording_rect.x && mouse_pos.y > recording_rect.y && mouse_pos.x < (recording_rect.x + m_switch_recording->GetSize().x) && mouse_pos.y < (recording_rect.y + m_switch_recording->GetSize().y)) {
|
|
wxMouseEvent recording_evt(wxEVT_LEFT_DOWN);
|
|
m_switch_recording->GetEventHandler()->ProcessEvent(recording_evt);
|
|
return;
|
|
}
|
|
//vcamera
|
|
auto vcamera_rect = m_switch_vcamera->ClientToScreen(wxPoint(0, 0));
|
|
if (mouse_pos.x > vcamera_rect.x && mouse_pos.y > vcamera_rect.y && mouse_pos.x < (vcamera_rect.x + m_switch_vcamera->GetSize().x) && mouse_pos.y < (vcamera_rect.y + m_switch_vcamera->GetSize().y)) {
|
|
wxMouseEvent vcamera_evt(wxEVT_LEFT_DOWN);
|
|
m_switch_vcamera->GetEventHandler()->ProcessEvent(vcamera_evt);
|
|
return;
|
|
}
|
|
//resolution
|
|
for (int i = 0; i < (int)RESOLUTION_OPTIONS_NUM; ++i){
|
|
auto resolution_rbtn = resolution_rbtns[i];
|
|
auto rbtn_rect = resolution_rbtn->ClientToScreen(wxPoint(0, 0));
|
|
if (mouse_pos.x > rbtn_rect.x && mouse_pos.y > rbtn_rect.y && mouse_pos.x < (rbtn_rect.x + resolution_rbtn->GetSize().x) && mouse_pos.y < (rbtn_rect.y + resolution_rbtn->GetSize().y)) {
|
|
wxMouseEvent resolution_evt(wxEVT_LEFT_DOWN);
|
|
resolution_rbtn->GetEventHandler()->ProcessEvent(resolution_evt);
|
|
return;
|
|
}
|
|
auto resolution_txt = resolution_texts[i];
|
|
auto txt_rect = resolution_txt->ClientToScreen(wxPoint(0, 0));
|
|
if (mouse_pos.x > txt_rect.x && mouse_pos.y > txt_rect.y && mouse_pos.x < (txt_rect.x + resolution_txt->GetSize().x) && mouse_pos.y < (txt_rect.y + resolution_txt->GetSize().y)) {
|
|
wxMouseEvent resolution_evt(wxEVT_LEFT_DOWN);
|
|
resolution_txt->GetEventHandler()->ProcessEvent(resolution_evt);
|
|
return;
|
|
}
|
|
}
|
|
//hyper link
|
|
auto h_rect = vcamera_guide_link->ClientToScreen(wxPoint(0, 0));
|
|
if (mouse_pos.x > h_rect.x && mouse_pos.y > h_rect.y && mouse_pos.x < (h_rect.x + vcamera_guide_link->GetSize().x) && mouse_pos.y < (h_rect.y + vcamera_guide_link->GetSize().y)) {
|
|
auto url = wxString::Format(L"https://wiki.bambulab.com/%s/software/bambu-studio/virtual-camera", L"en");
|
|
wxLaunchDefaultBrowser(url);
|
|
}
|
|
}
|
|
}
|
|
|
|
void CameraPopup::start_interval()
|
|
{
|
|
m_interval_timer->Start(CAMERAPOPUP_CLICK_INTERVAL);
|
|
m_is_in_interval = true;
|
|
}
|
|
|
|
void CameraPopup::stop_interval(wxTimerEvent& event)
|
|
{
|
|
m_is_in_interval = false;
|
|
m_interval_timer->Stop();
|
|
}
|
|
|
|
void CameraPopup::OnDismiss() {
|
|
PopupWindow::OnDismiss();
|
|
this->start_interval();
|
|
}
|
|
|
|
bool CameraPopup::ProcessLeftDown(wxMouseEvent &event)
|
|
{
|
|
return PopupWindow::ProcessLeftDown(event);
|
|
}
|
|
|
|
bool CameraPopup::Show(bool show)
|
|
{
|
|
return PopupWindow::Show(show);
|
|
}
|
|
|
|
void CameraPopup::OnSize(wxSizeEvent &event)
|
|
{
|
|
event.Skip();
|
|
}
|
|
|
|
void CameraPopup::OnSetFocus(wxFocusEvent &event)
|
|
{
|
|
event.Skip();
|
|
}
|
|
|
|
void CameraPopup::OnKillFocus(wxFocusEvent &event)
|
|
{
|
|
event.Skip();
|
|
}
|
|
|
|
void CameraPopup::OnMouse(wxMouseEvent &event)
|
|
{
|
|
event.Skip();
|
|
}
|
|
|
|
CameraItem::CameraItem(wxWindow *parent, std::string normal, std::string hover)
|
|
: wxPanel(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize)
|
|
{
|
|
#ifdef __WINDOWS__
|
|
SetDoubleBuffered(true);
|
|
#endif //__WINDOWS__
|
|
|
|
m_bitmap_normal = ScalableBitmap(this, normal, 20);
|
|
m_bitmap_hover = ScalableBitmap(this, hover, 20);
|
|
|
|
SetSize(wxSize(FromDIP(20), FromDIP(20)));
|
|
SetMinSize(wxSize(FromDIP(20), FromDIP(20)));
|
|
SetMaxSize(wxSize(FromDIP(20), FromDIP(20)));
|
|
Bind(wxEVT_PAINT, &CameraItem::paintEvent, this);
|
|
Bind(wxEVT_ENTER_WINDOW, &CameraItem::on_enter_win, this);
|
|
Bind(wxEVT_LEAVE_WINDOW, &CameraItem::on_level_win, this);
|
|
}
|
|
|
|
CameraItem::~CameraItem() {}
|
|
|
|
void CameraItem::msw_rescale() {
|
|
m_bitmap_normal.msw_rescale();
|
|
m_bitmap_hover.msw_rescale();
|
|
}
|
|
|
|
void CameraItem::on_enter_win(wxMouseEvent &evt)
|
|
{
|
|
m_hover = true;
|
|
Refresh();
|
|
}
|
|
|
|
void CameraItem::on_level_win(wxMouseEvent &evt)
|
|
{
|
|
m_hover = false;
|
|
Refresh();
|
|
}
|
|
|
|
void CameraItem::paintEvent(wxPaintEvent &evt)
|
|
{
|
|
wxPaintDC dc(this);
|
|
render(dc);
|
|
|
|
// PrepareDC(buffdc);
|
|
// PrepareDC(dc);
|
|
}
|
|
|
|
void CameraItem::render(wxDC &dc)
|
|
{
|
|
#ifdef __WXMSW__
|
|
wxSize size = GetSize();
|
|
wxMemoryDC memdc;
|
|
wxBitmap bmp(size.x, size.y);
|
|
memdc.SelectObject(bmp);
|
|
memdc.Blit({0, 0}, size, &dc, {0, 0});
|
|
|
|
{
|
|
wxGCDC dc2(memdc);
|
|
doRender(dc2);
|
|
}
|
|
|
|
memdc.SelectObject(wxNullBitmap);
|
|
dc.DrawBitmap(bmp, 0, 0);
|
|
#else
|
|
doRender(dc);
|
|
#endif
|
|
}
|
|
|
|
void CameraItem::doRender(wxDC &dc)
|
|
{
|
|
if (m_hover) {
|
|
dc.DrawBitmap(m_bitmap_hover.bmp(), wxPoint((GetSize().x - m_bitmap_hover.GetBmpSize().x) / 2, (GetSize().y - m_bitmap_hover.GetBmpSize().y) / 2));
|
|
} else {
|
|
dc.DrawBitmap(m_bitmap_normal.bmp(), wxPoint((GetSize().x - m_bitmap_normal.GetBmpSize().x) / 2, (GetSize().y - m_bitmap_normal.GetBmpSize().y) / 2));
|
|
}
|
|
}
|
|
|
|
}
|
|
} |