NEW: reimpl wxMediaCtrl from ffmpeg

Jira: none
Change-Id: I46a47118a7649b2a50fcce8911e2888342ef25de
(cherry picked from commit d6c7f08769c8cfdbbf0e80ad280c9b3408a3c27d)
This commit is contained in:
chunmao.guo 2024-06-26 19:51:59 +08:00 committed by Lane.Wei
parent 76ef39c588
commit 94d91be60b
15 changed files with 710 additions and 112 deletions

View File

@ -167,6 +167,7 @@ set(CMAKE_POSITION_INDEPENDENT_CODE ON)
# WIN10SDK_PATH is used to point CMake to the WIN10 SDK installation directory. # WIN10SDK_PATH is used to point CMake to the WIN10 SDK installation directory.
# We pick it from environment if it is not defined in another way # We pick it from environment if it is not defined in another way
if(WIN32) if(WIN32)
find_package(PkgConfig REQUIRED)
if(NOT DEFINED WIN10SDK_PATH) if(NOT DEFINED WIN10SDK_PATH)
if(DEFINED ENV{WIN10SDK_PATH}) if(DEFINED ENV{WIN10SDK_PATH})
set(WIN10SDK_PATH "$ENV{WIN10SDK_PATH}") set(WIN10SDK_PATH "$ENV{WIN10SDK_PATH}")
@ -362,7 +363,7 @@ endif()
function(slic3r_remap_configs targets from_Cfg to_Cfg) function(slic3r_remap_configs targets from_Cfg to_Cfg)
if(MSVC) if(MSVC)
string(TOUPPER ${from_Cfg} from_CFG) string(TOUPPER ${from_Cfg} from_CFG)
foreach(tgt ${targets}) foreach(tgt ${targets})
if(TARGET ${tgt}) if(TARGET ${tgt})
set_target_properties(${tgt} PROPERTIES MAP_IMPORTED_CONFIG_${from_CFG} ${to_Cfg}) set_target_properties(${tgt} PROPERTIES MAP_IMPORTED_CONFIG_${from_CFG} ${to_Cfg})
@ -503,7 +504,7 @@ add_custom_target(gettext_make_pot
COMMAND xgettext --keyword=L --keyword=_L --keyword=_u8L --keyword=L_CONTEXT:1,2c --keyword=_L_PLURAL:1,2 --add-comments=TRN --from-code=UTF-8 --no-location --debug --boost COMMAND xgettext --keyword=L --keyword=_L --keyword=_u8L --keyword=L_CONTEXT:1,2c --keyword=_L_PLURAL:1,2 --add-comments=TRN --from-code=UTF-8 --no-location --debug --boost
-f "${BBL_L18N_DIR}/list.txt" -f "${BBL_L18N_DIR}/list.txt"
-o "${BBL_L18N_DIR}/BambuStudio.pot" -o "${BBL_L18N_DIR}/BambuStudio.pot"
COMMAND hintsToPot ${SLIC3R_RESOURCES_DIR} ${BBL_L18N_DIR} COMMAND hintsToPot ${SLIC3R_RESOURCES_DIR} ${BBL_L18N_DIR}
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
COMMENT "Generate pot file from strings in the source tree" COMMENT "Generate pot file from strings in the source tree"
) )
@ -619,6 +620,10 @@ function(bambustudio_copy_dlls target config postfix output_dlls)
${CMAKE_PREFIX_PATH}/bin/occt/TKXDESTEP.dll ${CMAKE_PREFIX_PATH}/bin/occt/TKXDESTEP.dll
${CMAKE_PREFIX_PATH}/bin/occt/TKXSBase.dll ${CMAKE_PREFIX_PATH}/bin/occt/TKXSBase.dll
${CMAKE_PREFIX_PATH}/bin/freetype.dll ${CMAKE_PREFIX_PATH}/bin/freetype.dll
${CMAKE_PREFIX_PATH}/bin/avcodec-59.dll
${CMAKE_PREFIX_PATH}/bin/swresample-4.dll
${CMAKE_PREFIX_PATH}/bin/swscale-6.dll
${CMAKE_PREFIX_PATH}/bin/avutil-57.dll
DESTINATION ${_out_dir}) DESTINATION ${_out_dir})
set(${output_dlls} set(${output_dlls}
@ -654,11 +659,34 @@ function(bambustudio_copy_dlls target config postfix output_dlls)
${_out_dir}/TKXSBase.dll ${_out_dir}/TKXSBase.dll
${_out_dir}/freetype.dll ${_out_dir}/freetype.dll
${_out_dir}/avcodec-59.dll
${_out_dir}/swresample-4.dll
${_out_dir}/swscale-6.dll
${_out_dir}/avutil-57.dll
PARENT_SCOPE PARENT_SCOPE
) )
endfunction() endfunction()
function(bambustudio_copy_sos target config postfix output_sos)
set(_out_dir "${CMAKE_CURRENT_BINARY_DIR}")
message ("set out_dir to CMAKE_CURRENT_BINARY_DIR: ${_out_dir}")
file(COPY ${CMAKE_PREFIX_PATH}/lib/libavcodec.so
${CMAKE_PREFIX_PATH}/lib/libavutil.so
${CMAKE_PREFIX_PATH}/lib/libswscale.so
${CMAKE_PREFIX_PATH}/lib/libswresample.so
DESTINATION ${_out_dir})
set(${output_dlls}
${_out_dir}/libavcodec.so
${_out_dir}/libavutil.so
${_out_dir}/libswscale.so
${_out_dir}/libswresample.so
PARENT_SCOPE
)
endfunction()
# libslic3r, BambuStudio GUI and the BambuStudio executable. # libslic3r, BambuStudio GUI and the BambuStudio executable.
add_subdirectory(src) add_subdirectory(src)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 224 KiB

After

Width:  |  Height:  |  Size: 579 KiB

View File

@ -82,7 +82,7 @@ if (SLIC3R_GUI)
list(FILTER wxWidgets_LIBRARIES EXCLUDE REGEX expat) list(FILTER wxWidgets_LIBRARIES EXCLUDE REGEX expat)
list(APPEND wxWidgets_LIBRARIES ${EXPAT_LIBRARIES}) list(APPEND wxWidgets_LIBRARIES ${EXPAT_LIBRARIES})
endif () endif ()
# This is an issue in the new wxWidgets cmake build, doesn't deal with librt # This is an issue in the new wxWidgets cmake build, doesn't deal with librt
find_library(LIBRT rt) find_library(LIBRT rt)
if(LIBRT) if(LIBRT)
@ -218,6 +218,16 @@ if (WIN32)
else () else ()
if (NOT APPLE)
set(output_sos_Release "")
set(output_sos_Debug "")
add_custom_target(BambuStudioSosCopy ALL DEPENDS BambuStudio)
if ("${CMAKE_BUILD_TYPE}" STREQUAL "Debug")
bambustudio_copy_sos(BambuStudioSosCopy "Debug" "d" output_sos_Debug)
else()
bambustudio_copy_sos(BambuStudioSosCopy "Release" "" output_sos_Release)
endif()
endif()
if (APPLE AND NOT CMAKE_MACOSX_BUNDLE) if (APPLE AND NOT CMAKE_MACOSX_BUNDLE)
# On OSX, the name of the binary matches the name of the Application. # On OSX, the name of the binary matches the name of the Application.
add_custom_command(TARGET BambuStudio POST_BUILD add_custom_command(TARGET BambuStudio POST_BUILD
@ -275,5 +285,9 @@ if (WIN32)
endif () endif ()
install(FILES ${output_dlls_${build_type}} DESTINATION "${CMAKE_INSTALL_PREFIX}") install(FILES ${output_dlls_${build_type}} DESTINATION "${CMAKE_INSTALL_PREFIX}")
else () else ()
if (APPLE)
else()
install(FILES ${output_sos_${build_type}} DESTINATION "${CMAKE_INSTALL_PREFIX}")
endif()
install(TARGETS BambuStudio RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}" BUNDLE DESTINATION ${CMAKE_INSTALL_BINDIR}) install(TARGETS BambuStudio RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}" BUNDLE DESTINATION ${CMAKE_INSTALL_BINDIR})
endif () endif ()

View File

@ -546,12 +546,17 @@ if (APPLE)
GUI/InstanceCheckMac.h GUI/InstanceCheckMac.h
GUI/wxMediaCtrl2.mm GUI/wxMediaCtrl2.mm
GUI/wxMediaCtrl2.h GUI/wxMediaCtrl2.h
GUI/wxMediaCtrl3.h
) )
FIND_LIBRARY(DISKARBITRATION_LIBRARY DiskArbitration) FIND_LIBRARY(DISKARBITRATION_LIBRARY DiskArbitration)
else () else ()
list(APPEND SLIC3R_GUI_SOURCES list(APPEND SLIC3R_GUI_SOURCES
GUI/AVVideoDecoder.cpp
GUI/AVVideoDecoder.hpp
GUI/wxMediaCtrl2.cpp GUI/wxMediaCtrl2.cpp
GUI/wxMediaCtrl2.h GUI/wxMediaCtrl2.h
GUI/wxMediaCtrl3.cpp
GUI/wxMediaCtrl3.h
) )
endif () endif ()
@ -608,6 +613,15 @@ if (SLIC3R_PCH AND NOT SLIC3R_SYNTAXONLY)
add_precompiled_header(libslic3r_gui pchheader.hpp FORCEINCLUDE) add_precompiled_header(libslic3r_gui pchheader.hpp FORCEINCLUDE)
endif () endif ()
if (NOT APPLE)
pkg_check_modules(LIBAV REQUIRED IMPORTED_TARGET
libavcodec
libswscale
libavutil
)
target_link_libraries(libslic3r_gui PkgConfig::LIBAV)
endif()
# We need to implement some hacks for wxWidgets and touch the underlying GTK # We need to implement some hacks for wxWidgets and touch the underlying GTK
# layer and sub-libraries. This forces us to use the include locations and # layer and sub-libraries. This forces us to use the include locations and
# link these libraries. # link these libraries.

View File

@ -0,0 +1,126 @@
#include "AVVideoDecoder.hpp"
extern "C"
{
#include <libavutil/avutil.h>
#include <libavutil/imgutils.h>
}
AVVideoDecoder::AVVideoDecoder()
{
codec_ctx_ = avcodec_alloc_context3(nullptr);
}
AVVideoDecoder::~AVVideoDecoder()
{
if (sws_ctx_)
sws_freeContext(sws_ctx_);
if (frame_)
av_frame_free(&frame_);
if (codec_ctx_)
avcodec_free_context(&codec_ctx_);
}
int AVVideoDecoder::open(Bambu_StreamInfo const &info)
{
auto codec_id = info.sub_type == AVC1 ? AV_CODEC_ID_H264 : AV_CODEC_ID_MJPEG;
auto codec = avcodec_find_decoder(codec_id);
if (codec == nullptr) {
fprintf(stderr, "Unsupported codec!\n");
return -1; // Codec not found
}
/* open the coderc */
if (avcodec_open2(codec_ctx_, codec, nullptr) < 0) {
fprintf(stderr, "could not open codec\n");
return -1;
}
// Allocate an AVFrame structure
frame_ = av_frame_alloc();
if (frame_ == nullptr)
return -1;
return 0;
}
int AVVideoDecoder::decode(const Bambu_Sample &sample)
{
auto pkt = av_packet_alloc();
int ret = av_new_packet(pkt, sample.size);
if (ret == 0)
memcpy(pkt->data, sample.buffer, size_t(sample.size));
got_frame_ = avcodec_receive_frame(codec_ctx_, frame_) == 0;
ret = avcodec_send_packet(codec_ctx_, pkt);
return ret;
}
int AVVideoDecoder::flush()
{
int ret = avcodec_send_packet(codec_ctx_, nullptr);
got_frame_ = avcodec_receive_frame(codec_ctx_, frame_) == 0;
return ret;
}
void AVVideoDecoder::close()
{
}
bool AVVideoDecoder::toWxImage(wxImage &image, wxSize const &size2)
{
if (!got_frame_)
return false;
auto size = size2;
if (!size.IsFullySpecified())
size = {frame_->width, frame_->height };
if (size.GetWidth() & 0x0f)
size.SetWidth((size.GetWidth() & ~0x0f) + 0x10);
AVPixelFormat wxFmt = AV_PIX_FMT_RGB24;
sws_ctx_ = sws_getCachedContext(sws_ctx_,
frame_->width, frame_->height, AVPixelFormat(frame_->format),
size.GetWidth(), size.GetHeight(), wxFmt,
SWS_POINT, // SWS_FAST_BILINEAR //SWS_BICUBIC
nullptr, nullptr, nullptr);
uint8_t *data = (uint8_t*)malloc(size.GetWidth() * size.GetHeight() * 3);
if (data == nullptr)
return false;
uint8_t * datas[] = {data };
int strides[] = {size.GetWidth() * 3};
int result_h = sws_scale(sws_ctx_, frame_->data, frame_->linesize, 0, frame_->height, datas, strides);
if (result_h != size.GetHeight()) {
delete[] data;
return false;
}
image = wxImage(size.GetWidth(), size.GetHeight(), data);
return true;
}
bool AVVideoDecoder::toWxBitmap(wxBitmap &bitmap, wxSize const &size2)
{
if (!got_frame_)
return false;
auto size = size2;
if (!size.IsFullySpecified())
size = {frame_->width, frame_->height };
if (size.GetWidth() & 0x0f)
size.SetWidth((size.GetWidth() & ~0x0f) + 0x10);
AVPixelFormat wxFmt = AV_PIX_FMT_RGB32;
sws_ctx_ = sws_getCachedContext(sws_ctx_,
frame_->width, frame_->height, AVPixelFormat(frame_->format),
size.GetWidth(), size.GetHeight(), wxFmt,
SWS_POINT, // SWS_FAST_BILINEAR //SWS_BICUBIC
nullptr, nullptr, nullptr);
uint8_t *data = (uint8_t*)malloc(size.GetWidth() * size.GetHeight() * 4);
if (data == nullptr)
return false;
uint8_t *datas[] = {data};
int strides[] = {size.GetWidth() * 4};
int result_h = sws_scale(sws_ctx_, frame_->data, frame_->linesize, 0, frame_->height, datas, strides);
if (result_h != size.GetHeight()) {
delete[] data;
return false;
}
bitmap = wxBitmap((char *) data, size.GetWidth(), size.GetHeight(), 32);
return true;
}

View File

@ -0,0 +1,39 @@
#ifndef AVVIDEODECODER_HPP
#define AVVIDEODECODER_HPP
#include "BambuTunnel.h"
extern "C" {
#include <libavcodec/avcodec.h>
#include <libswscale/swscale.h>
}
class wxBitmap;
class AVVideoDecoder
{
public:
AVVideoDecoder();
~AVVideoDecoder();
public:
int open(Bambu_StreamInfo const &info);
int decode(Bambu_Sample const &sample);
int flush();
void close();
bool toWxImage(wxImage &image, wxSize const &size);
bool toWxBitmap(wxBitmap &bitmap, wxSize const & size);
private:
AVCodecContext *codec_ctx_ = nullptr;
AVFrame * frame_ = nullptr;
SwsContext * sws_ctx_ = nullptr;
bool got_frame_ = false;
};
#endif // AVVIDEODECODER_HPP

View File

@ -49,6 +49,7 @@ MediaPlayCtrl::MediaPlayCtrl(wxWindow *parent, wxMediaCtrl2 *media_ctrl, const w
SetLabel("MediaPlayCtrl"); SetLabel("MediaPlayCtrl");
SetBackgroundColour(*wxWHITE); SetBackgroundColour(*wxWHITE);
m_media_ctrl->Bind(wxEVT_MEDIA_STATECHANGED, &MediaPlayCtrl::onStateChanged, this); m_media_ctrl->Bind(wxEVT_MEDIA_STATECHANGED, &MediaPlayCtrl::onStateChanged, this);
m_media_ctrl->SetIdleImage(from_u8(resources_dir() + "/images/live_stream_default.png"));
m_button_play = new Button(this, "", "media_play", wxBORDER_NONE); m_button_play = new Button(this, "", "media_play", wxBORDER_NONE);
m_button_play->SetCanFocus(false); m_button_play->SetCanFocus(false);
@ -332,7 +333,7 @@ void MediaPlayCtrl::Play()
// !m_lan_mode && !m_remote_proto && m_lan_proto == LVL_None (x) // !m_lan_mode && !m_remote_proto && m_lan_proto == LVL_None (x)
if (m_lan_proto <= MachineObject::LVL_Disable && (m_lan_mode || !m_remote_proto)) { if (m_lan_proto <= MachineObject::LVL_Disable && (m_lan_mode || !m_remote_proto)) {
Stop(m_lan_proto == MachineObject::LVL_None Stop(m_lan_proto == MachineObject::LVL_None
? _L("Problem occured. Please update the printer firmware and try again.") ? _L("Problem occured. Please update the printer firmware and try again.")
: _L("LAN Only Liveview is off. Please turn on the liveview on printer screen.")); : _L("LAN Only Liveview is off. Please turn on the liveview on printer screen."));
return; return;
@ -366,7 +367,7 @@ void MediaPlayCtrl::Play()
url += "&cli_id=" + wxGetApp().app_config->get("slicer_uuid"); url += "&cli_id=" + wxGetApp().app_config->get("slicer_uuid");
url += "&cli_ver=" + std::string(SLIC3R_VERSION); url += "&cli_ver=" + std::string(SLIC3R_VERSION);
} }
BOOST_LOG_TRIVIAL(info) << "MediaPlayCtrl: " << hide_passwd(url, BOOST_LOG_TRIVIAL(info) << "MediaPlayCtrl: " << hide_passwd(url,
{"?uid=", "authkey=", "passwd=", "license=", "token="}); {"?uid=", "authkey=", "passwd=", "license=", "token="});
CallAfter([this, m, url] { CallAfter([this, m, url] {
if (m != m_machine) { if (m != m_machine) {
@ -436,7 +437,7 @@ void MediaPlayCtrl::Stop(wxString const &msg, wxString const &msg2)
auto tunnel = m_url.empty() ? "" : into_u8(wxURI(m_url).GetPath()).substr(1); auto tunnel = m_url.empty() ? "" : into_u8(wxURI(m_url).GetPath()).substr(1);
if (auto n = tunnel.find_first_of("/_"); n != std::string::npos) if (auto n = tunnel.find_first_of("/_"); n != std::string::npos)
tunnel = tunnel.substr(0, n); tunnel = tunnel.substr(0, n);
if (last_state != wxMEDIASTATE_PLAYING && m_failed_code != 0 if (last_state != wxMEDIASTATE_PLAYING && m_failed_code != 0
&& m_last_failed_codes.find(m_failed_code) == m_last_failed_codes.end() && m_last_failed_codes.find(m_failed_code) == m_last_failed_codes.end()
&& (m_user_triggered || m_failed_retry > 3)) { && (m_user_triggered || m_failed_retry > 3)) {
json j; json j;
@ -604,7 +605,7 @@ void MediaPlayCtrl::ToggleStream()
url += "&cli_id=" + wxGetApp().app_config->get("slicer_uuid"); url += "&cli_id=" + wxGetApp().app_config->get("slicer_uuid");
url += "&cli_ver=" + std::string(SLIC3R_VERSION); url += "&cli_ver=" + std::string(SLIC3R_VERSION);
} }
BOOST_LOG_TRIVIAL(info) << "MediaPlayCtrl::ToggleStream: " << hide_passwd(url, BOOST_LOG_TRIVIAL(info) << "MediaPlayCtrl::ToggleStream: " << hide_passwd(url,
{"?uid=", "authkey=", "passwd=", "license=", "token="}); {"?uid=", "authkey=", "passwd=", "license=", "token="});
CallAfter([this, m, url] { CallAfter([this, m, url] {
if (m != m_machine) return; if (m != m_machine) return;
@ -624,8 +625,8 @@ void MediaPlayCtrl::ToggleStream()
}); });
} }
void MediaPlayCtrl::msw_rescale() { void MediaPlayCtrl::msw_rescale() {
m_button_play->Rescale(); m_button_play->Rescale();
} }
void MediaPlayCtrl::jump_to_play() void MediaPlayCtrl::jump_to_play()
@ -841,15 +842,15 @@ bool MediaPlayCtrl::start_stream_service(bool *need_install)
if (!boost::filesystem::exists(file_dll) || boost::filesystem::last_write_time(file_dll) != boost::filesystem::last_write_time(file_dll2)) if (!boost::filesystem::exists(file_dll) || boost::filesystem::last_write_time(file_dll) != boost::filesystem::last_write_time(file_dll2))
boost::filesystem::copy_file(file_dll2, file_dll, boost::filesystem::copy_option::overwrite_if_exists); boost::filesystem::copy_file(file_dll2, file_dll, boost::filesystem::copy_option::overwrite_if_exists);
} }
boost::process::child process_source(file_source, file_url2.ToStdWstring(), boost::process::start_dir(tools_dir), boost::process::child process_source(file_source, file_url2.ToStdWstring(), boost::process::start_dir(tools_dir),
boost::process::windows::create_no_window, boost::process::windows::create_no_window,
boost::process::std_out > intermediate, boost::process::limit_handles); boost::process::std_out > intermediate, boost::process::limit_handles);
boost::process::child process_ffmpeg(file_ffmpeg, configss, boost::process::windows::create_no_window, boost::process::child process_ffmpeg(file_ffmpeg, configss, boost::process::windows::create_no_window,
boost::process::std_in < intermediate, boost::process::limit_handles); boost::process::std_in < intermediate, boost::process::limit_handles);
#else #else
boost::filesystem::permissions(file_source, boost::filesystem::owner_exe | boost::filesystem::add_perms); boost::filesystem::permissions(file_source, boost::filesystem::owner_exe | boost::filesystem::add_perms);
boost::filesystem::permissions(file_ffmpeg, boost::filesystem::owner_exe | boost::filesystem::add_perms); boost::filesystem::permissions(file_ffmpeg, boost::filesystem::owner_exe | boost::filesystem::add_perms);
boost::process::child process_source(file_source, file_url2.data().AsInternal(), boost::process::start_dir(start_dir), boost::process::child process_source(file_source, file_url2.data().AsInternal(), boost::process::start_dir(start_dir),
boost::process::std_out > intermediate, boost::process::limit_handles); boost::process::std_out > intermediate, boost::process::limit_handles);
boost::process::child process_ffmpeg(file_ffmpeg, configss, boost::process::std_in < intermediate, boost::process::limit_handles); boost::process::child process_ffmpeg(file_ffmpeg, configss, boost::process::std_in < intermediate, boost::process::limit_handles);
#endif #endif
@ -914,25 +915,19 @@ static int SecondsSinceLastInput()
}} }}
void wxMediaCtrl2::DoSetSize(int x, int y, int width, int height, int sizeFlags) void wxMediaCtrl_OnSize(wxWindow * ctrl, wxSize const & videoSize, int width, int height)
{ {
#ifdef __WXMAC__ wxSize size = videoSize;
wxWindow::DoSetSize(x, y, width, height, sizeFlags); if (!size.IsFullySpecified()) size = {16, 9};
#else
wxMediaCtrl::DoSetSize(x, y, width, height, sizeFlags);
#endif
if (sizeFlags & wxSIZE_USE_EXISTING) return;
wxSize size = m_video_size;
int maxHeight = (width * size.GetHeight() + size.GetHeight() - 1) / size.GetWidth(); int maxHeight = (width * size.GetHeight() + size.GetHeight() - 1) / size.GetWidth();
if (maxHeight != GetMaxHeight()) { if (maxHeight != ctrl->GetMaxHeight()) {
// BOOST_LOG_TRIVIAL(info) << "wxMediaCtrl2::DoSetSize: width: " << width << ", height: " << height << ", maxHeight: " << maxHeight; // BOOST_LOG_TRIVIAL(info) << "wxMediaCtrl_OnSize: width: " << width << ", height: " << height << ", maxHeight: " << maxHeight;
SetMaxSize({-1, maxHeight}); ctrl->SetMaxSize({-1, maxHeight});
CallAfter([this] { ctrl->CallAfter([ctrl] {
if (auto p = GetParent()) { if (auto p = ctrl->GetParent()) {
p->Layout(); p->Layout();
p->Refresh(); p->Refresh();
} }
}); });
} }
} }

View File

@ -8,7 +8,14 @@
#ifndef MediaPlayCtrl_h #ifndef MediaPlayCtrl_h
#define MediaPlayCtrl_h #define MediaPlayCtrl_h
#define USE_WX_MEDIA_CTRL_2 0
#if USE_WX_MEDIA_CTRL_2
#include "wxMediaCtrl2.h" #include "wxMediaCtrl2.h"
#define wxMediaCtrl3 wxMediaCtrl2
#else
#include "wxMediaCtrl3.h"
#endif
#include <wx/panel.h> #include <wx/panel.h>
@ -31,7 +38,7 @@ namespace GUI {
class MediaPlayCtrl : public wxPanel class MediaPlayCtrl : public wxPanel
{ {
public: public:
MediaPlayCtrl(wxWindow *parent, wxMediaCtrl2 *media_ctrl, const wxPoint &pos = wxDefaultPosition, const wxSize &size = wxDefaultSize); MediaPlayCtrl(wxWindow *parent, wxMediaCtrl3 *media_ctrl, const wxPoint &pos = wxDefaultPosition, const wxSize &size = wxDefaultSize);
~MediaPlayCtrl(); ~MediaPlayCtrl();
@ -73,7 +80,7 @@ private:
static constexpr wxMediaState MEDIASTATE_LOADING = (wxMediaState) 5; static constexpr wxMediaState MEDIASTATE_LOADING = (wxMediaState) 5;
static constexpr wxMediaState MEDIASTATE_BUFFERING = (wxMediaState) 6; static constexpr wxMediaState MEDIASTATE_BUFFERING = (wxMediaState) 6;
wxMediaCtrl2 * m_media_ctrl; wxMediaCtrl3 * m_media_ctrl;
wxMediaState m_last_state = MEDIASTATE_IDLE; wxMediaState m_last_state = MEDIASTATE_IDLE;
std::string m_machine; std::string m_machine;
int m_lan_proto = 0; int m_lan_proto = 0;
@ -88,7 +95,7 @@ private:
bool m_device_busy = false; bool m_device_busy = false;
bool m_disable_lan = false; bool m_disable_lan = false;
wxString m_url; wxString m_url;
std::deque<wxString> m_tasks; std::deque<wxString> m_tasks;
boost::mutex m_mutex; boost::mutex m_mutex;
boost::condition_variable m_cond; boost::condition_variable m_cond;

View File

@ -577,7 +577,7 @@ void PrintingTaskPanel::paint(wxPaintEvent&)
dc.SetTextForeground(*wxBLACK); dc.SetTextForeground(*wxBLACK);
dc.DrawBitmap(m_thumbnail_bmp_display, wxPoint(0, 0)); dc.DrawBitmap(m_thumbnail_bmp_display, wxPoint(0, 0));
dc.SetFont(Label::Body_12); dc.SetFont(Label::Body_12);
if (m_plate_index >= 0) { if (m_plate_index >= 0) {
wxString plate_id_str = wxString::Format("%d", m_plate_index); wxString plate_id_str = wxString::Format("%d", m_plate_index);
dc.DrawText(plate_id_str, wxPoint(4, 4)); dc.DrawText(plate_id_str, wxPoint(4, 4));
@ -795,7 +795,7 @@ void PrintingTaskPanel::set_plate_index(int plate_idx)
} }
void PrintingTaskPanel::market_scoring_show() void PrintingTaskPanel::market_scoring_show()
{ {
m_score_staticline->Show(); m_score_staticline->Show();
m_score_subtask_info->Show(); m_score_subtask_info->Show();
} }
@ -916,7 +916,7 @@ void StatusBasePanel::init_bitmaps()
m_bitmap_fan_off = ScalableBitmap(this, "monitor_fan_off", 22); m_bitmap_fan_off = ScalableBitmap(this, "monitor_fan_off", 22);
m_bitmap_speed = ScalableBitmap(this, "monitor_speed", 24); m_bitmap_speed = ScalableBitmap(this, "monitor_speed", 24);
m_bitmap_speed_active = ScalableBitmap(this, "monitor_speed_active", 24); m_bitmap_speed_active = ScalableBitmap(this, "monitor_speed_active", 24);
m_thumbnail_brokenimg = ScalableBitmap(this, "monitor_brokenimg", 120); m_thumbnail_brokenimg = ScalableBitmap(this, "monitor_brokenimg", 120);
m_thumbnail_sdcard = ScalableBitmap(this, "monitor_sdcard_thumbnail", 120); m_thumbnail_sdcard = ScalableBitmap(this, "monitor_sdcard_thumbnail", 120);
//m_bitmap_camera = create_scaled_bitmap("monitor_camera", nullptr, 18); //m_bitmap_camera = create_scaled_bitmap("monitor_camera", nullptr, 18);
@ -1012,7 +1012,7 @@ wxBoxSizer *StatusBasePanel::create_monitoring_page()
// media_ctrl_panel = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxDefaultSize); // media_ctrl_panel = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxDefaultSize);
// media_ctrl_panel->SetBackgroundColour(*wxBLACK); // media_ctrl_panel->SetBackgroundColour(*wxBLACK);
// wxBoxSizer *bSizer_monitoring = new wxBoxSizer(wxVERTICAL); // wxBoxSizer *bSizer_monitoring = new wxBoxSizer(wxVERTICAL);
m_media_ctrl = new wxMediaCtrl2(this); m_media_ctrl = new wxMediaCtrl3(this);
m_media_ctrl->SetMinSize(wxSize(PAGE_MIN_WIDTH, FromDIP(288))); m_media_ctrl->SetMinSize(wxSize(PAGE_MIN_WIDTH, FromDIP(288)));
m_media_play_ctrl = new MediaPlayCtrl(this, m_media_ctrl, wxDefaultPosition, wxSize(-1, FromDIP(40))); m_media_play_ctrl = new MediaPlayCtrl(this, m_media_ctrl, wxDefaultPosition, wxSize(-1, FromDIP(40)));
@ -1689,7 +1689,7 @@ StatusPanel::StatusPanel(wxWindow *parent, wxWindowID id, const wxPoint &pos, co
m_project_task_panel->get_pause_resume_button()->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(StatusPanel::on_subtask_pause_resume), NULL, this); m_project_task_panel->get_pause_resume_button()->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(StatusPanel::on_subtask_pause_resume), NULL, this);
m_project_task_panel->get_abort_button()->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(StatusPanel::on_subtask_abort), NULL, this); m_project_task_panel->get_abort_button()->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(StatusPanel::on_subtask_abort), NULL, this);
m_project_task_panel->get_market_scoring_button()->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(StatusPanel::on_market_scoring), NULL, this); m_project_task_panel->get_market_scoring_button()->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(StatusPanel::on_market_scoring), NULL, this);
m_project_task_panel->get_market_retry_buttom()->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(StatusPanel::on_market_retry), NULL, this); m_project_task_panel->get_market_retry_buttom()->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(StatusPanel::on_market_retry), NULL, this);
m_project_task_panel->get_clean_button()->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(StatusPanel::on_print_error_clean), NULL, this); m_project_task_panel->get_clean_button()->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(StatusPanel::on_print_error_clean), NULL, this);
m_setting_button->Connect(wxEVT_LEFT_DOWN, wxMouseEventHandler(StatusPanel::on_camera_enter), NULL, this); m_setting_button->Connect(wxEVT_LEFT_DOWN, wxMouseEventHandler(StatusPanel::on_camera_enter), NULL, this);
@ -1703,7 +1703,7 @@ StatusPanel::StatusPanel(wxWindow *parent, wxWindowID id, const wxPoint &pos, co
m_switch_lamp->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(StatusPanel::on_lamp_switch), NULL, this); m_switch_lamp->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(StatusPanel::on_lamp_switch), NULL, this);
m_switch_nozzle_fan->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(StatusPanel::on_nozzle_fan_switch), NULL, this); // TODO m_switch_nozzle_fan->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(StatusPanel::on_nozzle_fan_switch), NULL, this); // TODO
m_switch_printing_fan->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(StatusPanel::on_nozzle_fan_switch), NULL, this); m_switch_printing_fan->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(StatusPanel::on_nozzle_fan_switch), NULL, this);
m_switch_cham_fan->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(StatusPanel::on_nozzle_fan_switch), NULL, this); m_switch_cham_fan->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(StatusPanel::on_nozzle_fan_switch), NULL, this);
m_bpButton_xy->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(StatusPanel::on_axis_ctrl_xy), NULL, this); // TODO m_bpButton_xy->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(StatusPanel::on_axis_ctrl_xy), NULL, this); // TODO
m_bpButton_z_10->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(StatusPanel::on_axis_ctrl_z_up_10), NULL, this); m_bpButton_z_10->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(StatusPanel::on_axis_ctrl_z_up_10), NULL, this);
m_bpButton_z_1->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(StatusPanel::on_axis_ctrl_z_up_1), NULL, this); m_bpButton_z_1->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(StatusPanel::on_axis_ctrl_z_up_1), NULL, this);
@ -1748,7 +1748,7 @@ StatusPanel::~StatusPanel()
m_project_task_panel->get_pause_resume_button()->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(StatusPanel::on_subtask_pause_resume), NULL, this); m_project_task_panel->get_pause_resume_button()->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(StatusPanel::on_subtask_pause_resume), NULL, this);
m_project_task_panel->get_abort_button()->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(StatusPanel::on_subtask_abort), NULL, this); m_project_task_panel->get_abort_button()->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(StatusPanel::on_subtask_abort), NULL, this);
m_project_task_panel->get_market_scoring_button()->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(StatusPanel::on_market_scoring), NULL, this); m_project_task_panel->get_market_scoring_button()->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(StatusPanel::on_market_scoring), NULL, this);
m_project_task_panel->get_market_retry_buttom()->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(StatusPanel::on_market_retry), NULL, this); m_project_task_panel->get_market_retry_buttom()->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(StatusPanel::on_market_retry), NULL, this);
m_project_task_panel->get_clean_button()->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(StatusPanel::on_print_error_clean), NULL, this); m_project_task_panel->get_clean_button()->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(StatusPanel::on_print_error_clean), NULL, this);
m_setting_button->Disconnect(wxEVT_LEFT_DOWN, wxMouseEventHandler(StatusPanel::on_camera_enter), NULL, this); m_setting_button->Disconnect(wxEVT_LEFT_DOWN, wxMouseEventHandler(StatusPanel::on_camera_enter), NULL, this);
@ -1787,7 +1787,7 @@ StatusPanel::~StatusPanel()
if (sdcard_hint_dlg != nullptr) if (sdcard_hint_dlg != nullptr)
delete sdcard_hint_dlg; delete sdcard_hint_dlg;
if (m_score_data != nullptr) { if (m_score_data != nullptr) {
delete m_score_data; delete m_score_data;
} }
} }
@ -1811,7 +1811,7 @@ void StatusPanel::init_scaled_buttons()
m_bpButton_e_down_10->SetCornerRadius(FromDIP(12)); m_bpButton_e_down_10->SetCornerRadius(FromDIP(12));
} }
void StatusPanel::on_market_scoring(wxCommandEvent &event) { void StatusPanel::on_market_scoring(wxCommandEvent &event) {
if (obj && obj->is_makeworld_subtask() && obj->rating_info && obj->rating_info->request_successful) { // model is mall model and has rating_id if (obj && obj->is_makeworld_subtask() && obj->rating_info && obj->rating_info->request_successful) { // model is mall model and has rating_id
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ": on_market_scoring" ; BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ": on_market_scoring" ;
if (m_score_data && m_score_data->rating_id == obj->rating_info->rating_id) { // current score data for model is same as mall model if (m_score_data && m_score_data->rating_id == obj->rating_info->rating_id) { // current score data for model is same as mall model
@ -1820,7 +1820,7 @@ void StatusPanel::on_market_scoring(wxCommandEvent &event) {
int ret = m_score_dlg.ShowModal(); int ret = m_score_dlg.ShowModal();
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ": old data"; BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ": old data";
if (ret == wxID_OK) { if (ret == wxID_OK) {
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ": old data is upload"; BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ": old data is upload";
m_score_data->rating_id = -1; m_score_data->rating_id = -1;
m_project_task_panel->set_star_count_dirty(false); m_project_task_panel->set_star_count_dirty(false);
@ -1842,11 +1842,11 @@ void StatusPanel::on_market_scoring(wxCommandEvent &event) {
std::string comment = obj->rating_info->content; std::string comment = obj->rating_info->content;
if (!comment.empty()) { m_score_dlg.set_comment(comment); } if (!comment.empty()) { m_score_dlg.set_comment(comment); }
std::vector<std::string> images_json_array; std::vector<std::string> images_json_array;
images_json_array = obj->rating_info->image_url_paths; images_json_array = obj->rating_info->image_url_paths;
if (!images_json_array.empty()) m_score_dlg.set_cloud_bitmap(images_json_array); if (!images_json_array.empty()) m_score_dlg.set_cloud_bitmap(images_json_array);
int ret = m_score_dlg.ShowModal(); int ret = m_score_dlg.ShowModal();
if (ret == wxID_OK) { if (ret == wxID_OK) {
@ -1881,11 +1881,11 @@ void StatusPanel::on_subtask_pause_resume(wxCommandEvent &event)
if (obj->can_resume()) { if (obj->can_resume()) {
BOOST_LOG_TRIVIAL(info) << "monitor: resume current print task dev_id =" << obj->dev_id; BOOST_LOG_TRIVIAL(info) << "monitor: resume current print task dev_id =" << obj->dev_id;
obj->command_task_resume(); obj->command_task_resume();
} }
else { else {
BOOST_LOG_TRIVIAL(info) << "monitor: pause current print task dev_id =" << obj->dev_id; BOOST_LOG_TRIVIAL(info) << "monitor: pause current print task dev_id =" << obj->dev_id;
obj->command_task_pause(); obj->command_task_pause();
} }
if (m_print_error_dlg) { if (m_print_error_dlg) {
m_print_error_dlg->on_hide(); m_print_error_dlg->on_hide();
}if (m_print_error_dlg_no_action) { }if (m_print_error_dlg_no_action) {
@ -1902,7 +1902,7 @@ void StatusPanel::on_subtask_abort(wxCommandEvent &event)
abort_dlg->Bind(EVT_SECONDARY_CHECK_CONFIRM, [this](wxCommandEvent &e) { abort_dlg->Bind(EVT_SECONDARY_CHECK_CONFIRM, [this](wxCommandEvent &e) {
if (obj) { if (obj) {
BOOST_LOG_TRIVIAL(info) << "monitor: stop current print task dev_id =" << obj->dev_id; BOOST_LOG_TRIVIAL(info) << "monitor: stop current print task dev_id =" << obj->dev_id;
obj->command_task_abort(); obj->command_task_abort();
} }
}); });
} }
@ -2050,7 +2050,7 @@ void StatusPanel::update(MachineObject *obj)
calibration_dlg->update_machine_obj(obj); calibration_dlg->update_machine_obj(obj);
calibration_dlg->update_cali(obj); calibration_dlg->update_cali(obj);
} }
if (obj->is_support_first_layer_inspect if (obj->is_support_first_layer_inspect
@ -2576,10 +2576,15 @@ void StatusPanel::update_ams(MachineObject *obj)
m_ams_control->show_auto_refill(false); m_ams_control->show_auto_refill(false);
} }
else { else {
<<<<<<< HEAD (26a4fc ENH: refresh_agora_url callback)
=======
m_ams_control->SetAmsModel(ams_mode, ams_mode);
>>>>>>> CHANGE (d6c7f0 NEW: reimpl wxMediaCtrl from ffmpeg)
m_ams_control->SetAmsModel(ams_mode, ams_mode); m_ams_control->SetAmsModel(ams_mode, ams_mode);
show_ams_group(true); show_ams_group(true);
m_ams_control->show_auto_refill(true); m_ams_control->show_auto_refill(true);
} }
@ -2643,7 +2648,7 @@ void StatusPanel::update_ams(MachineObject *obj)
m_ams_control->SetExtruder(obj->is_filament_at_extruder(), true, obj->m_ams_id, obj->vt_tray.get_color()); m_ams_control->SetExtruder(obj->is_filament_at_extruder(), true, obj->m_ams_id, obj->vt_tray.get_color());
} else { } else {
m_ams_control->SetExtruder(obj->is_filament_at_extruder(), false, obj->m_ams_id, m_ams_control->GetCanColour(obj->m_ams_id, obj->m_tray_id)); m_ams_control->SetExtruder(obj->is_filament_at_extruder(), false, obj->m_ams_id, m_ams_control->GetCanColour(obj->m_ams_id, obj->m_tray_id));
} }
if (obj->ams_status_main == AMS_STATUS_MAIN_FILAMENT_CHANGE) { if (obj->ams_status_main == AMS_STATUS_MAIN_FILAMENT_CHANGE) {
@ -2696,7 +2701,7 @@ void StatusPanel::update_ams(MachineObject *obj)
}else{ }else{
m_ams_control->SetFilamentStep(FilamentStep::STEP_PUSH_NEW_FILAMENT, FilamentStepType::STEP_TYPE_LOAD); m_ams_control->SetFilamentStep(FilamentStep::STEP_PUSH_NEW_FILAMENT, FilamentStepType::STEP_TYPE_LOAD);
} }
} }
else { else {
m_ams_control->SetFilamentStep(FilamentStep::STEP_PUSH_NEW_FILAMENT, FilamentStepType::STEP_TYPE_UNLOAD); m_ams_control->SetFilamentStep(FilamentStep::STEP_PUSH_NEW_FILAMENT, FilamentStepType::STEP_TYPE_UNLOAD);
@ -2736,7 +2741,7 @@ void StatusPanel::update_ams(MachineObject *obj)
} else { } else {
m_ams_control->SetFilamentStep(FilamentStep::STEP_IDLE, FilamentStepType::STEP_TYPE_LOAD); m_ams_control->SetFilamentStep(FilamentStep::STEP_IDLE, FilamentStepType::STEP_TYPE_LOAD);
} }
for (auto ams_it = obj->amsList.begin(); ams_it != obj->amsList.end(); ams_it++) { for (auto ams_it = obj->amsList.begin(); ams_it != obj->amsList.end(); ams_it++) {
std::string ams_id = ams_it->first; std::string ams_id = ams_it->first;
@ -2783,7 +2788,7 @@ void StatusPanel::update_ams(MachineObject *obj)
}else { }else {
is_curr_tray_selected = true; is_curr_tray_selected = true;
} }
update_ams_control_state(is_curr_tray_selected); update_ams_control_state(is_curr_tray_selected);
} }
@ -2839,7 +2844,7 @@ void StatusPanel::update_ams_control_state(bool is_curr_tray_selected)
if (!obj->is_filament_at_extruder()) { if (!obj->is_filament_at_extruder()) {
enable[ACTION_BTN_UNLOAD] = false; enable[ACTION_BTN_UNLOAD] = false;
} }
if (obj->ams_exist_bits == 0) { if (obj->ams_exist_bits == 0) {
if (obj->is_in_printing()) { if (obj->is_in_printing()) {
if (!obj->can_resume()) { if (!obj->can_resume()) {
@ -2857,7 +2862,7 @@ void StatusPanel::update_ams_control_state(bool is_curr_tray_selected)
} }
} }
} }
} }
else { else {
if (obj->is_in_printing() /*&& obj->can_resume() && obj->m_tray_now != std::to_string(VIRTUAL_TRAY_ID) */) { if (obj->is_in_printing() /*&& obj->can_resume() && obj->m_tray_now != std::to_string(VIRTUAL_TRAY_ID) */) {
@ -2876,7 +2881,7 @@ void StatusPanel::update_ams_control_state(bool is_curr_tray_selected)
else if (!m_ams_control->GetCurrentCan(m_ams_control->GetCurentAms()).empty()) { else if (!m_ams_control->GetCurrentCan(m_ams_control->GetCurentAms()).empty()) {
enable[ACTION_BTN_LOAD] = false; enable[ACTION_BTN_LOAD] = false;
enable[ACTION_BTN_UNLOAD] = false; enable[ACTION_BTN_UNLOAD] = false;
} }
} }
else if (obj->m_tray_now == std::to_string(VIRTUAL_TRAY_ID)) { else if (obj->m_tray_now == std::to_string(VIRTUAL_TRAY_ID)) {
if (m_ams_control->GetCurentAms() == std::to_string(VIRTUAL_TRAY_ID)) { if (m_ams_control->GetCurentAms() == std::to_string(VIRTUAL_TRAY_ID)) {
@ -2892,7 +2897,7 @@ void StatusPanel::update_ams_control_state(bool is_curr_tray_selected)
enable[ACTION_BTN_LOAD] = false; enable[ACTION_BTN_LOAD] = false;
enable[ACTION_BTN_UNLOAD] = false; enable[ACTION_BTN_UNLOAD] = false;
} }
} }
} }
} }
@ -2952,14 +2957,14 @@ void StatusPanel::update_basic_print_data(bool def)
void StatusPanel::update_model_info() void StatusPanel::update_model_info()
{ {
auto get_subtask_fn = [this](BBLModelTask* subtask) { auto get_subtask_fn = [this](BBLModelTask* subtask) {
CallAfter([this, subtask]() { CallAfter([this, subtask]() {
if (obj && obj->subtask_id_ == subtask->task_id) { if (obj && obj->subtask_id_ == subtask->task_id) {
obj->set_modeltask(subtask); obj->set_modeltask(subtask);
} }
}); });
}; };
if (wxGetApp().getAgent() && obj) { if (wxGetApp().getAgent() && obj) {
BBLSubTask* curr_task = obj->get_subtask(); BBLSubTask* curr_task = obj->get_subtask();
if (curr_task) { if (curr_task) {
@ -3024,7 +3029,7 @@ void StatusPanel::update_subtask(MachineObject *obj)
if (calib_bitmap != nullptr) if (calib_bitmap != nullptr)
m_project_task_panel->set_thumbnail_img(*calib_bitmap); m_project_task_panel->set_thumbnail_img(*calib_bitmap);
} }
if (obj->is_support_layer_num) { if (obj->is_support_layer_num) {
m_project_task_panel->update_layers_num(true); m_project_task_panel->update_layers_num(true);
} }
@ -3127,7 +3132,7 @@ void StatusPanel::update_subtask(MachineObject *obj)
m_project_task_panel->get_request_failed_panel()->Hide(); m_project_task_panel->get_request_failed_panel()->Hide();
} }
// update printing stage // update printing stage
m_project_task_panel->update_left_time(obj->mc_left_time); m_project_task_panel->update_left_time(obj->mc_left_time);
if (obj->subtask_) { if (obj->subtask_) {
m_project_task_panel->update_stage_value(obj->get_curr_stage(), obj->subtask_->task_progress); m_project_task_panel->update_stage_value(obj->get_curr_stage(), obj->subtask_->task_progress);
@ -3243,7 +3248,7 @@ void StatusPanel::reset_printing_values()
m_project_task_panel->update_left_time(NA_STR); m_project_task_panel->update_left_time(NA_STR);
m_project_task_panel->update_layers_num(true, wxString::Format(_L("Layer: %s"), NA_STR)); m_project_task_panel->update_layers_num(true, wxString::Format(_L("Layer: %s"), NA_STR));
update_calib_bitmap(); update_calib_bitmap();
task_thumbnail_state = ThumbnailState::PLACE_HOLDER; task_thumbnail_state = ThumbnailState::PLACE_HOLDER;
m_start_loading_thumbnail = false; m_start_loading_thumbnail = false;
m_load_sdcard_thumbnail = false; m_load_sdcard_thumbnail = false;
@ -3313,7 +3318,7 @@ bool StatusPanel::check_axis_z_at_home(MachineObject* obj)
} }
void StatusPanel::on_axis_ctrl_z_up_10(wxCommandEvent &event) void StatusPanel::on_axis_ctrl_z_up_10(wxCommandEvent &event)
{ {
if (obj) { if (obj) {
obj->command_axis_control("Z", 1.0, -10.0f, 900); obj->command_axis_control("Z", 1.0, -10.0f, 900);
if (!check_axis_z_at_home(obj)) if (!check_axis_z_at_home(obj))
@ -3478,7 +3483,7 @@ void StatusPanel::on_ams_load_curr()
std::string curr_ams_id = m_ams_control->GetCurentAms(); std::string curr_ams_id = m_ams_control->GetCurentAms();
std::string curr_can_id = m_ams_control->GetCurrentCan(curr_ams_id); std::string curr_can_id = m_ams_control->GetCurrentCan(curr_ams_id);
update_filament_step(); update_filament_step();
//virtual tray //virtual tray
if (curr_ams_id.compare(std::to_string(VIRTUAL_TRAY_ID)) == 0) { if (curr_ams_id.compare(std::to_string(VIRTUAL_TRAY_ID)) == 0) {
@ -3853,7 +3858,7 @@ void StatusPanel::on_ams_guide(wxCommandEvent& event)
else { else {
ams_wiki_url = "https://wiki.bambulab.com/en/software/bambu-studio/use-ams-on-bambu-studio"; ams_wiki_url = "https://wiki.bambulab.com/en/software/bambu-studio/use-ams-on-bambu-studio";
} }
wxLaunchDefaultBrowser(ams_wiki_url); wxLaunchDefaultBrowser(ams_wiki_url);
} }
@ -3991,7 +3996,7 @@ void StatusPanel::on_switch_speed(wxCommandEvent &event)
speed_dismiss_time = boost::posix_time::microsec_clock::universal_time(); speed_dismiss_time = boost::posix_time::microsec_clock::universal_time();
} }
}); });
m_ams_control->Bind(EVT_CLEAR_SPEED_CONTROL, [this, popUp](auto& e) { m_ams_control->Bind(EVT_CLEAR_SPEED_CONTROL, [this, popUp](auto& e) {
if (m_showing_speed_popup) { if (m_showing_speed_popup) {
if (popUp && popUp->IsShown()) { if (popUp && popUp->IsShown()) {
@ -4378,8 +4383,8 @@ void StatusPanel::msw_rescale()
m_calibration_btn->Rescale(); m_calibration_btn->Rescale();
m_options_btn->SetMinSize(wxSize(-1, FromDIP(26))); m_options_btn->SetMinSize(wxSize(-1, FromDIP(26)));
m_options_btn->Rescale(); m_options_btn->Rescale();
m_parts_btn->SetMinSize(wxSize(-1, FromDIP(26))); m_parts_btn->SetMinSize(wxSize(-1, FromDIP(26)));
m_parts_btn->Rescale(); m_parts_btn->Rescale();
@ -4420,11 +4425,11 @@ ScoreDialog::ScoreDialog(wxWindow *parent, ScoreData *score_data)
, m_upload_status_code(StatusCode::CODE_NUMBER) , m_upload_status_code(StatusCode::CODE_NUMBER)
{ {
m_tocken.reset(new int(0)); m_tocken.reset(new int(0));
wxBoxSizer *m_main_sizer = get_main_sizer(score_data->local_to_url_image, score_data->comment_text); wxBoxSizer *m_main_sizer = get_main_sizer(score_data->local_to_url_image, score_data->comment_text);
m_image_url_paths = score_data->image_url_paths; m_image_url_paths = score_data->image_url_paths;
this->SetSizer(m_main_sizer); this->SetSizer(m_main_sizer);
Fit(); Fit();
@ -4440,16 +4445,16 @@ void ScoreDialog::on_dpi_changed(const wxRect &suggested_rect) {}
void ScoreDialog::OnBitmapClicked(wxMouseEvent &event) void ScoreDialog::OnBitmapClicked(wxMouseEvent &event)
{ {
wxStaticBitmap *clickedBitmap = dynamic_cast<wxStaticBitmap *>(event.GetEventObject()); wxStaticBitmap *clickedBitmap = dynamic_cast<wxStaticBitmap *>(event.GetEventObject());
if (m_image.find(clickedBitmap) != m_image.end()) { if (m_image.find(clickedBitmap) != m_image.end()) {
if (!m_image[clickedBitmap].is_selected) { if (!m_image[clickedBitmap].is_selected) {
for (auto panel : m_image[clickedBitmap].image_broad) { for (auto panel : m_image[clickedBitmap].image_broad) {
panel->Show(); panel->Show();
} }
m_image[clickedBitmap].is_selected = true; m_image[clickedBitmap].is_selected = true;
m_selected_image_list.insert(clickedBitmap); m_selected_image_list.insert(clickedBitmap);
} else { } else {
for (auto panel : m_image[clickedBitmap].image_broad) { for (auto panel : m_image[clickedBitmap].image_broad) {
panel->Hide(); panel->Hide();
} }
m_image[clickedBitmap].is_selected = false; m_image[clickedBitmap].is_selected = false;
m_selected_image_list.erase(clickedBitmap); m_selected_image_list.erase(clickedBitmap);
@ -4466,9 +4471,9 @@ void ScoreDialog::OnBitmapClicked(wxMouseEvent &event)
} }
std::set <std::pair<wxStaticBitmap * ,wxString>> ScoreDialog::add_need_upload_imgs() std::set <std::pair<wxStaticBitmap * ,wxString>> ScoreDialog::add_need_upload_imgs()
{ {
std::set<std::pair<wxStaticBitmap *, wxString>> need_upload_images; std::set<std::pair<wxStaticBitmap *, wxString>> need_upload_images;
for (auto bitmap : m_image) { for (auto bitmap : m_image) {
if (!bitmap.second.is_uploaded) { if (!bitmap.second.is_uploaded) {
wxString &local_image_path = bitmap.second.local_image_url; wxString &local_image_path = bitmap.second.local_image_url;
if (!local_image_path.empty()) { need_upload_images.insert(std::make_pair(bitmap.first, local_image_path)); } if (!local_image_path.empty()) { need_upload_images.insert(std::make_pair(bitmap.first, local_image_path)); }
@ -4488,7 +4493,7 @@ std::pair<wxStaticBitmap *, ScoreDialog::ImageMsg> ScoreDialog::create_local_thu
cur_image_msg.local_image_url = local_path; cur_image_msg.local_image_url = local_path;
cur_image_msg.img_url_paths = ""; cur_image_msg.img_url_paths = "";
cur_image_msg.is_uploaded = false; cur_image_msg.is_uploaded = false;
wxStaticBitmap *imageCtrl = new wxStaticBitmap(this, wxID_ANY, wxBitmap(wxImage(local_path, wxBITMAP_TYPE_ANY).Rescale(FromDIP(80), FromDIP(60))), wxDefaultPosition, wxStaticBitmap *imageCtrl = new wxStaticBitmap(this, wxID_ANY, wxBitmap(wxImage(local_path, wxBITMAP_TYPE_ANY).Rescale(FromDIP(80), FromDIP(60))), wxDefaultPosition,
wxDefaultSize, 0); wxDefaultSize, 0);
imageCtrl->Bind(wxEVT_LEFT_DOWN, &ScoreDialog::OnBitmapClicked, this); imageCtrl->Bind(wxEVT_LEFT_DOWN, &ScoreDialog::OnBitmapClicked, this);
@ -4553,7 +4558,7 @@ void ScoreDialog::update_static_bitmap(wxStaticBitmap* static_bitmap, wxImage im
} }
wxBoxSizer *ScoreDialog::create_broad_sizer(wxStaticBitmap *bitmap, ImageMsg& cur_image_msg) wxBoxSizer *ScoreDialog::create_broad_sizer(wxStaticBitmap *bitmap, ImageMsg& cur_image_msg)
{ {
// tb: top and bottom lr: left and right // tb: top and bottom lr: left and right
auto m_image_tb_broad = new wxBoxSizer(wxVERTICAL); auto m_image_tb_broad = new wxBoxSizer(wxVERTICAL);
auto line_top = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxSize(-1, 1), wxTAB_TRAVERSAL); auto line_top = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxSize(-1, 1), wxTAB_TRAVERSAL);
@ -4600,7 +4605,7 @@ void ScoreDialog::init() {
SetIcon(wxIcon(encode_path(icon_path.c_str()), wxBITMAP_TYPE_ICO)); SetIcon(wxIcon(encode_path(icon_path.c_str()), wxBITMAP_TYPE_ICO));
} }
wxBoxSizer *ScoreDialog::get_score_sizer() { wxBoxSizer *ScoreDialog::get_score_sizer() {
wxBoxSizer *score_sizer = new wxBoxSizer(wxHORIZONTAL); wxBoxSizer *score_sizer = new wxBoxSizer(wxHORIZONTAL);
wxStaticText *static_score_text = new wxStaticText(this, wxID_ANY, _L("Rate"), wxDefaultPosition, wxDefaultSize, 0); wxStaticText *static_score_text = new wxStaticText(this, wxID_ANY, _L("Rate"), wxDefaultPosition, wxDefaultSize, 0);
static_score_text->Wrap(-1); static_score_text->Wrap(-1);
@ -4720,18 +4725,18 @@ wxBoxSizer *ScoreDialog::get_photo_btn_sizer() {
for (int i = 0; i < filePaths.GetCount(); i++) { //It's ugly, but useful for (int i = 0; i < filePaths.GetCount(); i++) { //It's ugly, but useful
bool is_repeat = false; bool is_repeat = false;
for (auto image : m_image) { for (auto image : m_image) {
if (filePaths[i] == image.second.local_image_url) { if (filePaths[i] == image.second.local_image_url) {
is_repeat = true; is_repeat = true;
continue; continue;
} }
} }
if (!is_repeat) { if (!is_repeat) {
local_path.push_back(std::make_pair(filePaths[i], "")); local_path.push_back(std::make_pair(filePaths[i], ""));
if (local_path.size() + m_image.size() > m_photo_nums) { if (local_path.size() + m_image.size() > m_photo_nums) {
break; break;
} }
} }
} }
load_photo(local_path); load_photo(local_path);
@ -4858,7 +4863,7 @@ wxBoxSizer *ScoreDialog::get_button_sizer()
} }
} }
progress_dialog->Hide(); progress_dialog->Hide();
if (progress_dialog) { if (progress_dialog) {
delete progress_dialog; delete progress_dialog;
progress_dialog = nullptr; progress_dialog = nullptr;
} }
@ -4998,7 +5003,7 @@ wxBoxSizer *ScoreDialog::get_main_sizer(const std::vector<std::pair<wxString, st
m_main_sizer->Add(m_photo_sizer, 0, wxEXPAND | wxTOP, FromDIP(8)); m_main_sizer->Add(m_photo_sizer, 0, wxEXPAND | wxTOP, FromDIP(8));
m_image_sizer = new wxGridSizer(5, FromDIP(5), FromDIP(5)); m_image_sizer = new wxGridSizer(5, FromDIP(5), FromDIP(5));
if (!images.empty()) { if (!images.empty()) {
load_photo(images); load_photo(images);
} }
m_main_sizer->Add(m_image_sizer, 0, wxEXPAND | wxLEFT, FromDIP(24)); m_main_sizer->Add(m_image_sizer, 0, wxEXPAND | wxLEFT, FromDIP(24));
@ -5010,7 +5015,7 @@ wxBoxSizer *ScoreDialog::get_main_sizer(const std::vector<std::pair<wxString, st
return m_main_sizer; return m_main_sizer;
} }
ScoreData ScoreDialog::get_score_data() { ScoreData ScoreDialog::get_score_data() {
ScoreData score_data; ScoreData score_data;
score_data.rating_id = m_rating_id; score_data.rating_id = m_rating_id;
score_data.design_id = m_design_id; score_data.design_id = m_design_id;
@ -5021,20 +5026,20 @@ ScoreData ScoreDialog::get_score_data() {
score_data.comment_text = m_comment_text->GetValue(); score_data.comment_text = m_comment_text->GetValue();
score_data.image_url_paths = m_image_url_paths; score_data.image_url_paths = m_image_url_paths;
for (auto img : m_image) { score_data.local_to_url_image.push_back(std::make_pair(img.second.local_image_url, img.second.img_url_paths)); } for (auto img : m_image) { score_data.local_to_url_image.push_back(std::make_pair(img.second.local_image_url, img.second.img_url_paths)); }
return score_data; return score_data;
} }
void ScoreDialog::set_comment(std::string comment) void ScoreDialog::set_comment(std::string comment)
{ {
if (m_comment_text) { if (m_comment_text) {
m_comment_text->SetValue(wxString::FromUTF8(comment)); m_comment_text->SetValue(wxString::FromUTF8(comment));
} }
} }
void ScoreDialog::set_cloud_bitmap(std::vector<std::string> cloud_bitmaps) void ScoreDialog::set_cloud_bitmap(std::vector<std::string> cloud_bitmaps)
{ {
m_image_url_paths = cloud_bitmaps; m_image_url_paths = cloud_bitmaps;
for (std::string &url : cloud_bitmaps) { for (std::string &url : cloud_bitmaps) {
if (std::string::npos == url.find(m_model_id)) continue; if (std::string::npos == url.find(m_model_id)) continue;

View File

@ -13,7 +13,6 @@
#include <wx/sizer.h> #include <wx/sizer.h>
#include <wx/gbsizer.h> #include <wx/gbsizer.h>
#include <wx/webrequest.h> #include <wx/webrequest.h>
#include "wxMediaCtrl2.h"
#include "MediaPlayCtrl.h" #include "MediaPlayCtrl.h"
#include "AMSSetting.hpp" #include "AMSSetting.hpp"
#include "Calibration.hpp" #include "Calibration.hpp"
@ -91,11 +90,11 @@ public:
void set_cloud_bitmap(std::vector<std::string> cloud_bitmaps); void set_cloud_bitmap(std::vector<std::string> cloud_bitmaps);
protected: protected:
enum StatusCode { enum StatusCode {
UPLOAD_PROGRESS = 0, UPLOAD_PROGRESS = 0,
UPLOAD_EXIST_ISSUE, UPLOAD_EXIST_ISSUE,
UPLOAD_IMG_FAILED, UPLOAD_IMG_FAILED,
CODE_NUMBER CODE_NUMBER
}; };
std::shared_ptr<int> m_tocken; std::shared_ptr<int> m_tocken;
@ -113,7 +112,7 @@ protected:
{ {
wxString local_image_url; //local image path wxString local_image_url; //local image path
std::string img_url_paths; // oss url path std::string img_url_paths; // oss url path
vector<wxPanel *> image_broad; vector<wxPanel *> image_broad;
bool is_selected; bool is_selected;
bool is_uploaded; // load bool is_uploaded; // load
wxBoxSizer * image_tb_broad = nullptr; wxBoxSizer * image_tb_broad = nullptr;
@ -148,7 +147,7 @@ protected:
std::set<std::pair<wxStaticBitmap *, wxString>> add_need_upload_imgs(); std::set<std::pair<wxStaticBitmap *, wxString>> add_need_upload_imgs();
std::pair<wxStaticBitmap *, ImageMsg> create_local_thumbnail(wxString &local_path); std::pair<wxStaticBitmap *, ImageMsg> create_local_thumbnail(wxString &local_path);
std::pair<wxStaticBitmap *, ImageMsg> create_oss_thumbnail(std::string &oss_path); std::pair<wxStaticBitmap *, ImageMsg> create_oss_thumbnail(std::string &oss_path);
}; };
class PrintingTaskPanel : public wxPanel class PrintingTaskPanel : public wxPanel
@ -157,7 +156,7 @@ public:
PrintingTaskPanel(wxWindow* parent, PrintingTaskType type); PrintingTaskPanel(wxWindow* parent, PrintingTaskType type);
~PrintingTaskPanel(); ~PrintingTaskPanel();
void create_panel(wxWindow* parent); void create_panel(wxWindow* parent);
private: private:
MachineObject* m_obj; MachineObject* m_obj;
@ -232,7 +231,7 @@ public:
void set_plate_index(int plate_idx = -1); void set_plate_index(int plate_idx = -1);
void market_scoring_show(); void market_scoring_show();
void market_scoring_hide(); void market_scoring_hide();
public: public:
ScalableButton* get_abort_button() {return m_button_abort;}; ScalableButton* get_abort_button() {return m_button_abort;};
ScalableButton* get_pause_resume_button() {return m_button_pause_resume;}; ScalableButton* get_pause_resume_button() {return m_button_pause_resume;};
@ -313,7 +312,7 @@ protected:
wxStaticBitmap *m_bitmap_static_use_weight; wxStaticBitmap *m_bitmap_static_use_weight;
wxMediaCtrl2 * m_media_ctrl; wxMediaCtrl3 * m_media_ctrl;
MediaPlayCtrl * m_media_play_ctrl; MediaPlayCtrl * m_media_play_ctrl;
Label * m_staticText_printing; Label * m_staticText_printing;
@ -340,7 +339,7 @@ protected:
/* TempInput */ /* TempInput */
wxBoxSizer * m_misc_ctrl_sizer; wxBoxSizer * m_misc_ctrl_sizer;
StaticBox* m_fan_panel; StaticBox* m_fan_panel;
StaticLine * m_line_nozzle; StaticLine * m_line_nozzle;
TempInput* m_tempCtrl_nozzle; TempInput* m_tempCtrl_nozzle;
int m_temp_nozzle_timeout{ 0 }; int m_temp_nozzle_timeout{ 0 };
@ -406,7 +405,7 @@ protected:
virtual void on_bed_temp_kill_focus(wxFocusEvent &event) { event.Skip(); } virtual void on_bed_temp_kill_focus(wxFocusEvent &event) { event.Skip(); }
virtual void on_bed_temp_set_focus(wxFocusEvent &event) { event.Skip(); } virtual void on_bed_temp_set_focus(wxFocusEvent &event) { event.Skip(); }
virtual void on_nozzle_temp_kill_focus(wxFocusEvent &event) { event.Skip(); } virtual void on_nozzle_temp_kill_focus(wxFocusEvent &event) { event.Skip(); }
virtual void on_nozzle_temp_set_focus(wxFocusEvent &event) { event.Skip(); } virtual void on_nozzle_temp_set_focus(wxFocusEvent &event) { event.Skip(); }
virtual void on_nozzle_fan_switch(wxCommandEvent &event) { event.Skip(); } virtual void on_nozzle_fan_switch(wxCommandEvent &event) { event.Skip(); }
virtual void on_printing_fan_switch(wxCommandEvent &event) { event.Skip(); } virtual void on_printing_fan_switch(wxCommandEvent &event) { event.Skip(); }
virtual void on_axis_ctrl_z_up_10(wxCommandEvent &event) { event.Skip(); } virtual void on_axis_ctrl_z_up_10(wxCommandEvent &event) { event.Skip(); }

View File

@ -1,6 +1,6 @@
#include "wxMediaCtrl2.h" #include "wxMediaCtrl2.h"
#include "I18N.hpp" #include "I18N.hpp"
#include "GUI_App.hpp" #include "libslic3r/Utils.hpp"
#ifdef __WIN32__ #ifdef __WIN32__
#include <versionhelpers.h> #include <versionhelpers.h>
#include <wx/msw/registry.h> #include <wx/msw/registry.h>
@ -61,8 +61,8 @@ void wxMediaCtrl2::Load(wxURI url)
if (!notified) CallAfter([] { if (!notified) CallAfter([] {
auto res = wxMessageBox(_L("Windows Media Player is required for this task! Do you want to enable 'Windows Media Player' for your operation system?"), _L("Error"), wxOK | wxCANCEL); auto res = wxMessageBox(_L("Windows Media Player is required for this task! Do you want to enable 'Windows Media Player' for your operation system?"), _L("Error"), wxOK | wxCANCEL);
if (res == wxOK) { if (res == wxOK) {
wxString url = IsWindows10OrGreater() wxString url = IsWindows10OrGreater()
? "ms-settings:optionalfeatures?activationSource=SMC-Article-14209" ? "ms-settings:optionalfeatures?activationSource=SMC-Article-14209"
: "https://support.microsoft.com/en-au/windows/get-windows-media-player-81718e0d-cfce-25b1-aee3-94596b658287"; : "https://support.microsoft.com/en-au/windows/get-windows-media-player-81718e0d-cfce-25b1-aee3-94596b658287";
wxExecute("cmd /c start " + url, wxEXEC_HIDE_CONSOLE); wxExecute("cmd /c start " + url, wxEXEC_HIDE_CONSOLE);
} }
@ -77,7 +77,7 @@ void wxMediaCtrl2::Load(wxURI url)
{ {
wxRegKey key11(wxRegKey::HKCU, L"SOFTWARE\\Classes\\CLSID\\" CLSID_BAMBU_SOURCE L"\\InProcServer32"); wxRegKey key11(wxRegKey::HKCU, L"SOFTWARE\\Classes\\CLSID\\" CLSID_BAMBU_SOURCE L"\\InProcServer32");
wxRegKey key12(wxRegKey::HKCR, L"CLSID\\" CLSID_BAMBU_SOURCE L"\\InProcServer32"); wxRegKey key12(wxRegKey::HKCR, L"CLSID\\" CLSID_BAMBU_SOURCE L"\\InProcServer32");
wxString path = key11.Exists() ? key11.QueryDefaultValue() wxString path = key11.Exists() ? key11.QueryDefaultValue()
: key12.Exists() ? key12.QueryDefaultValue() : wxString{}; : key12.Exists() ? key12.QueryDefaultValue() : wxString{};
wxRegKey key2(wxRegKey::HKCR, "bambu"); wxRegKey key2(wxRegKey::HKCR, "bambu");
wxString clsid; wxString clsid;
@ -144,14 +144,14 @@ void wxMediaCtrl2::Load(wxURI url)
#ifdef __WXGTK3__ #ifdef __WXGTK3__
GstElementFactory *factory; GstElementFactory *factory;
int hasplugins = 1; int hasplugins = 1;
factory = gst_element_factory_find("h264parse"); factory = gst_element_factory_find("h264parse");
if (!factory) { if (!factory) {
hasplugins = 0; hasplugins = 0;
} else { } else {
gst_object_unref(factory); gst_object_unref(factory);
} }
factory = gst_element_factory_find("openh264dec"); factory = gst_element_factory_find("openh264dec");
if (!factory) { if (!factory) {
factory = gst_element_factory_find("avdec_h264"); factory = gst_element_factory_find("avdec_h264");
@ -164,7 +164,7 @@ void wxMediaCtrl2::Load(wxURI url)
} else { } else {
gst_object_unref(factory); gst_object_unref(factory);
} }
if (!hasplugins) { if (!hasplugins) {
CallAfter([] { CallAfter([] {
wxMessageBox(_L("Your system is missing H.264 codecs for GStreamer, which are required to play video. (Try installing the gstreamer1.0-plugins-bad or gstreamer1.0-libav packages, then restart Bambu Studio?)"), _L("Error"), wxOK); wxMessageBox(_L("Your system is missing H.264 codecs for GStreamer, which are required to play video. (Try installing the gstreamer1.0-plugins-bad or gstreamer1.0-libav packages, then restart Bambu Studio?)"), _L("Error"), wxOK);
@ -194,8 +194,9 @@ void wxMediaCtrl2::Play() { wxMediaCtrl::Play(); }
void wxMediaCtrl2::Stop() void wxMediaCtrl2::Stop()
{ {
wxMediaCtrl::Stop(); wxMediaCtrl::Stop(); }
}
void wxMediaCtrl2::SetIdleImage(wxString const &image) {}
#ifdef __LINUX__ #ifdef __LINUX__
extern "C" int gst_bambu_last_error; extern "C" int gst_bambu_last_error;
@ -230,6 +231,13 @@ wxSize wxMediaCtrl2::DoGetBestSize() const
return {-1, -1}; return {-1, -1};
} }
void wxMediaCtrl2::DoSetSize(int x, int y, int width, int height, int sizeFlags)
{
wxWindow::DoSetSize(x, y, width, height, sizeFlags);
if (sizeFlags & wxSIZE_USE_EXISTING) return;
wxMediaCtrl_OnSize(this, m_video_size, width, height);
}
#ifdef __WIN32__ #ifdef __WIN32__
WXLRESULT wxMediaCtrl2::MSWWindowProc(WXUINT nMsg, WXLRESULT wxMediaCtrl2::MSWWindowProc(WXUINT nMsg,

View File

@ -13,13 +13,15 @@
wxDECLARE_EVENT(EVT_MEDIA_CTRL_STAT, wxCommandEvent); wxDECLARE_EVENT(EVT_MEDIA_CTRL_STAT, wxCommandEvent);
void wxMediaCtrl_OnSize(wxWindow * ctrl, wxSize const & videoSize, int width, int height);
#ifdef __WXMAC__ #ifdef __WXMAC__
class wxMediaCtrl2 : public wxWindow class wxMediaCtrl2 : public wxWindow
{ {
public: public:
wxMediaCtrl2(wxWindow * parent); wxMediaCtrl2(wxWindow * parent);
~wxMediaCtrl2(); ~wxMediaCtrl2();
void Load(wxURI url); void Load(wxURI url);
@ -41,8 +43,8 @@ public:
protected: protected:
void DoSetSize(int x, int y, int width, int height, int sizeFlags) override; void DoSetSize(int x, int y, int width, int height, int sizeFlags) override;
static void bambu_log(void const * ctx, int level, char const * msg); static void bambu_log(void const *ctx, int level, char const *msg);
void NotifyStopped(); void NotifyStopped();
private: private:

View File

@ -140,6 +140,10 @@ void wxMediaCtrl2::Stop()
NotifyStopped(); NotifyStopped();
} }
void wxMediaCtrl2::SetIdleImage(wxString const &image)
{
}
void wxMediaCtrl2::NotifyStopped() void wxMediaCtrl2::NotifyStopped()
{ {
if (m_state != wxMEDIASTATE_STOPPED) { if (m_state != wxMEDIASTATE_STOPPED) {
@ -168,3 +172,10 @@ wxSize wxMediaCtrl2::GetVideoSize() const
return {0, 0}; return {0, 0};
} }
} }
void wxMediaCtrl2::DoSetSize(int x, int y, int width, int height, int sizeFlags)
{
wxWindow::DoSetSize(x, y, width, height, sizeFlags);
if (sizeFlags & wxSIZE_USE_EXISTING) return;
wxMediaCtrl_OnSize(this, m_video_size, width, height);
}

View File

@ -0,0 +1,267 @@
#include "wxMediaCtrl3.h"
#include "AVVideoDecoder.hpp"
#include "I18N.hpp"
#include "libslic3r/Utils.hpp"
#ifdef __WIN32__
#include <versionhelpers.h>
#include <wx/msw/registry.h>
#include <shellapi.h>
#endif
//wxDEFINE_EVENT(EVT_MEDIA_CTRL_STAT, wxCommandEvent);
BEGIN_EVENT_TABLE(wxMediaCtrl3, wxWindow)
// catch paint events
EVT_PAINT(wxMediaCtrl3::paintEvent)
END_EVENT_TABLE()
struct StaticBambuLib : BambuLib
{
static StaticBambuLib &get();
};
wxMediaCtrl3::wxMediaCtrl3(wxWindow *parent)
: wxWindow(parent, wxID_ANY)
, BambuLib(StaticBambuLib::get())
, m_thread([this] { PlayThread(); })
{
SetBackgroundColour(*wxBLACK);
}
wxMediaCtrl3::~wxMediaCtrl3()
{
{
std::unique_lock<std::mutex> lk(m_mutex);
m_url.reset(new wxURI);
m_frame = wxImage(m_idle_image);
m_cond.notify_all();
}
m_thread.join();
}
void wxMediaCtrl3::Load(wxURI url)
{
std::unique_lock<std::mutex> lk(m_mutex);
m_video_size = wxDefaultSize;
m_error = 0;
m_url.reset(new wxURI(url));
m_cond.notify_all();
}
void wxMediaCtrl3::Play()
{
std::unique_lock<std::mutex> lk(m_mutex);
if (m_state != wxMEDIASTATE_PLAYING) {
m_state = wxMEDIASTATE_PLAYING;
wxMediaEvent event(wxEVT_MEDIA_STATECHANGED);
event.SetId(GetId());
event.SetEventObject(this);
wxPostEvent(this, event);
}
}
void wxMediaCtrl3::Stop()
{
std::unique_lock<std::mutex> lk(m_mutex);
m_url.reset();
m_frame = wxImage(m_idle_image);
m_cond.notify_all();
Refresh();
}
void wxMediaCtrl3::SetIdleImage(wxString const &image)
{
if (m_idle_image == image)
return;
m_idle_image = image;
if (m_url == nullptr) {
std::unique_lock<std::mutex> lk(m_mutex);
m_frame = wxImage(m_idle_image);
assert(m_frame.IsOk());
Refresh();
}
}
wxMediaState wxMediaCtrl3::GetState()
{
std::unique_lock<std::mutex> lk(m_mutex);
return m_state;
}
int wxMediaCtrl3::GetLastError()
{
std::unique_lock<std::mutex> lk(m_mutex);
return m_error;
}
wxSize wxMediaCtrl3::GetVideoSize()
{
std::unique_lock<std::mutex> lk(m_mutex);
return m_video_size;
}
wxSize wxMediaCtrl3::DoGetBestSize() const
{
return {-1, -1};
}
static void adjust_frame_size(wxSize & frame, wxSize const & video, wxSize const & window)
{
if (video.x * window.y < video.y * window.x)
frame = { video.x * window.y / video.y, window.y };
else
frame = { window.x, video.y * window.x / video.x };
}
void wxMediaCtrl3::paintEvent(wxPaintEvent &evt)
{
wxPaintDC dc(this);
auto size = GetSize();
std::unique_lock<std::mutex> lk(m_mutex);
if (!m_frame.IsOk())
return;
auto size2 = m_frame.GetSize();
if (size2.x != m_frame_size.x && size2.y == m_frame_size.y)
size2.x = m_frame_size.x;
if (size2.x != size.x && size2.y != size.y) {
auto scale = std::min(double(size.x) / size2.x, double(size.y) / size2.y);
dc.SetUserScale(scale, scale);
adjust_frame_size(size2, size2, size);
}
size2 = (size - size2) / 2;
dc.DrawBitmap(m_frame, size2.x, size2.y);
}
void wxMediaCtrl3::DoSetSize(int x, int y, int width, int height, int sizeFlags)
{
wxWindow::DoSetSize(x, y, width, height, sizeFlags);
if (sizeFlags & wxSIZE_USE_EXISTING) return;
wxMediaCtrl_OnSize(this, m_video_size, width, height);
}
void wxMediaCtrl3::bambu_log(void *ctx, int level, tchar const *msg2)
{
#ifdef _WIN32
wxString msg(msg2);
#else
wxString msg = wxString::FromUTF8(msg2);
#endif
if (level == 1) {
if (msg.EndsWith("]")) {
int n = msg.find_last_of('[');
if (n != wxString::npos) {
long val = 0;
wxMediaCtrl3 *ctrl = (wxMediaCtrl3 *) ctx;
if (msg.SubString(n + 1, msg.Length() - 2).ToLong(&val)) {
std::unique_lock<std::mutex> lk(ctrl->m_mutex);
ctrl->m_error = (int) val;
}
}
} else if (msg.Contains("stat_log")) {
wxCommandEvent evt(EVT_MEDIA_CTRL_STAT);
wxMediaCtrl3 *ctrl = (wxMediaCtrl3 *) ctx;
evt.SetEventObject(ctrl);
evt.SetString(msg.Mid(msg.Find(' ') + 1));
wxPostEvent(ctrl, evt);
}
}
BOOST_LOG_TRIVIAL(info) << msg.ToUTF8().data();
}
void wxMediaCtrl3::PlayThread()
{
using namespace std::chrono_literals;
std::shared_ptr<wxURI> url;
std::unique_lock<std::mutex> lk(m_mutex);
while (true) {
m_cond.wait(lk, [this, &url] { return m_url != url; });
url = m_url;
if (url == nullptr)
continue;
if (!url->HasScheme())
break;
lk.unlock();
Bambu_Tunnel tunnel = nullptr;
int error = Bambu_Create(&tunnel, m_url->BuildURI().ToUTF8());
if (error == 0) {
Bambu_SetLogger(tunnel, &wxMediaCtrl3::bambu_log, this);
error = Bambu_Open(tunnel);
if (error == 0)
error = Bambu_would_block;
}
lk.lock();
while (error == int(Bambu_would_block)) {
m_cond.wait_for(lk, 100ms);
if (m_url != url) {
error = 1;
break;
}
lk.unlock();
error = Bambu_StartStream(tunnel, true);
lk.lock();
}
Bambu_StreamInfo info;
if (error == 0)
error = Bambu_GetStreamInfo(tunnel, 0, &info);
AVVideoDecoder decoder;
if (error == 0) {
decoder.open(info);
m_video_size = { info.format.video.width, info.format.video.height };
adjust_frame_size(m_frame_size, m_video_size, GetSize());
NotifyStopped();
}
Bambu_Sample sample;
while (error == 0) {
lk.unlock();
error = Bambu_ReadSample(tunnel, &sample);
lk.lock();
while (error == int(Bambu_would_block)) {
m_cond.wait_for(lk, 100ms);
if (m_url != url) {
error = 1;
break;
}
lk.unlock();
error = Bambu_ReadSample(tunnel, &sample);
lk.lock();
}
if (error == 0) {
if (m_url != url) {
error = 1;
break;
}
lk.unlock();
wxBitmap bm;
decoder.decode(sample);
decoder.toWxBitmap(bm, m_frame_size);
lk.lock();
if (bm.IsOk())
m_frame = bm;
CallAfter([this] { Refresh(); });
}
}
if (tunnel) {
lk.unlock();
Bambu_Close(tunnel);
Bambu_Destroy(tunnel);
tunnel = nullptr;
lk.lock();
}
if (m_url == url)
m_error = error;
m_video_size = wxDefaultSize;
NotifyStopped();
}
}
void wxMediaCtrl3::NotifyStopped()
{
m_state = wxMEDIASTATE_STOPPED;
wxMediaEvent event(wxEVT_MEDIA_STATECHANGED);
event.SetId(GetId());
event.SetEventObject(this);
wxPostEvent(this, event);
}

View File

@ -0,0 +1,83 @@
//
// wxMediaCtrl3.h
// libslic3r_gui
//
// Created by cmguo on 2024/6/22.
//
#ifndef wxMediaCtrl3_h
#define wxMediaCtrl3_h
#include "wx/uri.h"
#include "wx/mediactrl.h"
wxDECLARE_EVENT(EVT_MEDIA_CTRL_STAT, wxCommandEvent);
void wxMediaCtrl_OnSize(wxWindow * ctrl, wxSize const & videoSize, int width, int height);
#ifdef __WXMAC__
#include "wxMediaCtrl2.h"
#define wxMediaCtrl3 wxMediaCtrl2
#else
#define BAMBU_DYNAMIC
#include <BambuTunnel.h>
class AVVideoDecoder;
class wxMediaCtrl3 : public wxWindow, BambuLib
{
public:
wxMediaCtrl3(wxWindow *parent);
~wxMediaCtrl3();
void Load(wxURI url);
void Play();
void Stop();
void SetIdleImage(wxString const & image);
wxMediaState GetState();
int GetLastError();
wxSize GetVideoSize();
protected:
DECLARE_EVENT_TABLE()
void paintEvent(wxPaintEvent &evt);
wxSize DoGetBestSize() const override;
void DoSetSize(int x, int y, int width, int height, int sizeFlags) override;
static void bambu_log(void *ctx, int level, tchar const *msg);
void PlayThread();
void NotifyStopped();
private:
wxString m_idle_image;
wxMediaState m_state = wxMEDIASTATE_STOPPED;
int m_error = 0;
wxSize m_video_size = wxDefaultSize;
wxSize m_frame_size = wxDefaultSize;
wxBitmap m_frame;
wxImage m_frame2;
std::shared_ptr<wxURI> m_url;
std::mutex m_mutex;
std::condition_variable m_cond;
std::thread m_thread;
};
#endif
#endif /* wxMediaCtrl3_h */