2022-07-15 15:37:19 +00:00
|
|
|
#include "Notebook.hpp"
|
|
|
|
|
|
|
|
//#ifdef _WIN32
|
|
|
|
|
|
|
|
#include "GUI_App.hpp"
|
|
|
|
#include "wxExtensions.hpp"
|
|
|
|
#include "Widgets/Button.hpp"
|
|
|
|
|
|
|
|
//BBS set font size
|
|
|
|
#include "Widgets/Label.hpp"
|
|
|
|
|
|
|
|
#include <wx/button.h>
|
|
|
|
#include <wx/sizer.h>
|
|
|
|
|
|
|
|
wxDEFINE_EVENT(wxCUSTOMEVT_NOTEBOOK_SEL_CHANGED, wxCommandEvent);
|
|
|
|
|
|
|
|
ButtonsListCtrl::ButtonsListCtrl(wxWindow *parent, wxBoxSizer* side_tools) :
|
|
|
|
wxControl(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxBORDER_NONE | wxTAB_TRAVERSAL)
|
|
|
|
{
|
|
|
|
#ifdef __WINDOWS__
|
|
|
|
SetDoubleBuffered(true);
|
|
|
|
#endif //__WINDOWS__
|
2022-12-10 07:15:56 +00:00
|
|
|
|
|
|
|
wxColour default_btn_bg;
|
|
|
|
#ifdef __APPLE__
|
|
|
|
default_btn_bg = wxColour("#3B4446"); // Gradient #414B4E
|
|
|
|
#else
|
|
|
|
default_btn_bg = wxColour("#2D2D30"); // Gradient #414B4E
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
2022-07-15 15:37:19 +00:00
|
|
|
SetBackgroundColour(default_btn_bg);
|
|
|
|
|
|
|
|
int em = em_unit(this);// Slic3r::GUI::wxGetApp().em_unit();
|
|
|
|
// BBS: no gap
|
|
|
|
m_btn_margin = 0; // std::lround(0.3 * em);
|
|
|
|
m_line_margin = std::lround(0.1 * em);
|
|
|
|
|
|
|
|
m_sizer = new wxBoxSizer(wxHORIZONTAL);
|
|
|
|
this->SetSizer(m_sizer);
|
|
|
|
|
|
|
|
m_buttons_sizer = new wxFlexGridSizer(1, m_btn_margin, m_btn_margin);
|
|
|
|
m_sizer->Add(m_buttons_sizer, 0, wxALIGN_CENTER_VERTICAL | wxLEFT | wxBOTTOM, m_btn_margin);
|
|
|
|
|
|
|
|
if (side_tools != NULL) {
|
|
|
|
m_sizer->AddStretchSpacer(1);
|
|
|
|
for (size_t idx = 0; idx < side_tools->GetItemCount(); idx++) {
|
|
|
|
wxSizerItem* item = side_tools->GetItem(idx);
|
|
|
|
wxWindow* item_win = item->GetWindow();
|
|
|
|
if (item_win) {
|
|
|
|
item_win->Reparent(this);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
m_sizer->Add(side_tools, 0, wxALIGN_CENTER_VERTICAL | wxRIGHT | wxBOTTOM, m_btn_margin);
|
|
|
|
}
|
|
|
|
|
|
|
|
// BBS: disable custom paint
|
|
|
|
//this->Bind(wxEVT_PAINT, &ButtonsListCtrl::OnPaint, this);
|
2022-11-04 03:28:05 +00:00
|
|
|
Bind(wxEVT_SYS_COLOUR_CHANGED, [this](auto& e){
|
|
|
|
});
|
2022-07-15 15:37:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void ButtonsListCtrl::OnPaint(wxPaintEvent&)
|
|
|
|
{
|
2022-12-08 07:57:13 +00:00
|
|
|
//Slic3r::GUI::wxGetApp().UpdateDarkUI(this);
|
2022-07-15 15:37:19 +00:00
|
|
|
const wxSize sz = GetSize();
|
|
|
|
wxPaintDC dc(this);
|
|
|
|
|
|
|
|
if (m_selection < 0 || m_selection >= (int)m_pageButtons.size())
|
|
|
|
return;
|
|
|
|
|
|
|
|
wxColour selected_btn_bg("#1F8EEA");
|
|
|
|
wxColour default_btn_bg("#3B4446"); // Gradient #414B4E
|
|
|
|
const wxColour& btn_marker_color = Slic3r::GUI::wxGetApp().get_color_hovered_btn_label();
|
|
|
|
|
|
|
|
// highlight selected notebook button
|
|
|
|
|
|
|
|
for (int idx = 0; idx < int(m_pageButtons.size()); idx++) {
|
|
|
|
Button* btn = m_pageButtons[idx];
|
|
|
|
|
|
|
|
btn->SetBackgroundColor(idx == m_selection ? selected_btn_bg : default_btn_bg);
|
|
|
|
|
|
|
|
wxPoint pos = btn->GetPosition();
|
|
|
|
wxSize size = btn->GetSize();
|
|
|
|
const wxColour& clr = idx == m_selection ? btn_marker_color : default_btn_bg;
|
|
|
|
dc.SetPen(clr);
|
|
|
|
dc.SetBrush(clr);
|
|
|
|
dc.DrawRectangle(pos.x, pos.y + size.y, size.x, sz.y - size.y);
|
|
|
|
}
|
|
|
|
|
|
|
|
#if 0
|
|
|
|
// highlight selected mode button
|
|
|
|
if (m_mode_sizer) {
|
|
|
|
const std::vector<ModeButton*>& mode_btns = m_mode_sizer->get_btns();
|
|
|
|
for (int idx = 0; idx < int(mode_btns.size()); idx++) {
|
|
|
|
ModeButton* btn = mode_btns[idx];
|
|
|
|
btn->SetBackgroundColor(btn->is_selected() ? selected_btn_bg : default_btn_bg);
|
|
|
|
|
|
|
|
//wxPoint pos = btn->GetPosition();
|
|
|
|
//wxSize size = btn->GetSize();
|
|
|
|
//const wxColour& clr = btn->is_selected() ? btn_marker_color : default_btn_bg;
|
|
|
|
//dc.SetPen(clr);
|
|
|
|
//dc.SetBrush(clr);
|
|
|
|
//dc.DrawRectangle(pos.x, pos.y + size.y, size.x, sz.y - size.y);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
// Draw orange bottom line
|
|
|
|
|
|
|
|
dc.SetPen(btn_marker_color);
|
|
|
|
dc.SetBrush(btn_marker_color);
|
|
|
|
dc.DrawRectangle(1, sz.y - m_line_margin, sz.x, m_line_margin);
|
|
|
|
}
|
|
|
|
|
|
|
|
void ButtonsListCtrl::UpdateMode()
|
|
|
|
{
|
|
|
|
//m_mode_sizer->SetMode(Slic3r::GUI::wxGetApp().get_mode());
|
|
|
|
}
|
|
|
|
|
|
|
|
void ButtonsListCtrl::Rescale()
|
|
|
|
{
|
|
|
|
//m_mode_sizer->msw_rescale();
|
|
|
|
int em = em_unit(this);
|
|
|
|
for (Button* btn : m_pageButtons) {
|
|
|
|
//BBS
|
|
|
|
btn->SetMinSize({(btn->GetLabel().empty() ? 40 : 132) * em / 10, 36 * em / 10});
|
|
|
|
btn->Rescale();
|
|
|
|
}
|
|
|
|
|
|
|
|
// BBS: no gap
|
|
|
|
//m_btn_margin = std::lround(0.3 * em);
|
|
|
|
//m_line_margin = std::lround(0.1 * em);
|
|
|
|
//m_buttons_sizer->SetVGap(m_btn_margin);
|
|
|
|
//m_buttons_sizer->SetHGap(m_btn_margin);
|
|
|
|
|
|
|
|
m_sizer->Layout();
|
|
|
|
}
|
|
|
|
|
|
|
|
void ButtonsListCtrl::SetSelection(int sel)
|
|
|
|
{
|
|
|
|
if (m_selection == sel)
|
|
|
|
return;
|
|
|
|
// BBS: change button color
|
|
|
|
wxColour selected_btn_bg("#00AE42"); // Gradient #00AE42
|
|
|
|
if (m_selection >= 0) {
|
|
|
|
StateColor bg_color = StateColor(
|
|
|
|
std::pair{wxColour(107, 107, 107), (int) StateColor::Hovered},
|
|
|
|
std::pair{wxColour(59, 68, 70), (int) StateColor::Normal});
|
|
|
|
m_pageButtons[m_selection]->SetBackgroundColor(bg_color);
|
|
|
|
StateColor text_color = StateColor(
|
2022-11-04 03:28:05 +00:00
|
|
|
std::pair{wxColour(254,254, 254), (int) StateColor::Normal}
|
2022-07-15 15:37:19 +00:00
|
|
|
);
|
|
|
|
m_pageButtons[m_selection]->SetSelected(false);
|
|
|
|
m_pageButtons[m_selection]->SetTextColor(text_color);
|
|
|
|
}
|
|
|
|
m_selection = sel;
|
|
|
|
|
|
|
|
StateColor bg_color = StateColor(
|
|
|
|
std::pair{wxColour(0, 174, 66), (int) StateColor::Hovered},
|
|
|
|
std::pair{wxColour(0,174, 66), (int) StateColor::Normal});
|
|
|
|
m_pageButtons[m_selection]->SetBackgroundColor(bg_color);
|
|
|
|
|
|
|
|
StateColor text_color = StateColor(
|
2022-11-04 03:28:05 +00:00
|
|
|
std::pair{wxColour(254, 254, 254), (int) StateColor::Normal}
|
2022-07-15 15:37:19 +00:00
|
|
|
);
|
|
|
|
m_pageButtons[m_selection]->SetSelected(true);
|
|
|
|
m_pageButtons[m_selection]->SetTextColor(text_color);
|
|
|
|
|
|
|
|
Refresh();
|
|
|
|
}
|
|
|
|
|
|
|
|
bool ButtonsListCtrl::InsertPage(size_t n, const wxString &text, bool bSelect /* = false*/, const std::string &bmp_name /* = ""*/, const std::string &inactive_bmp_name)
|
|
|
|
{
|
|
|
|
Button * btn = new Button(this, text.empty() ? text : " " + text, bmp_name, wxNO_BORDER);
|
|
|
|
btn->SetCornerRadius(0);
|
|
|
|
|
|
|
|
int em = em_unit(this);
|
|
|
|
//BBS set size for button
|
|
|
|
btn->SetMinSize({(text.empty() ? 40 : 136) * em / 10, 36 * em / 10});
|
|
|
|
|
|
|
|
StateColor bg_color = StateColor(
|
|
|
|
std::pair{wxColour(107, 107, 107), (int) StateColor::Hovered},
|
|
|
|
std::pair{wxColour(59, 68, 70), (int) StateColor::Normal});
|
|
|
|
|
|
|
|
btn->SetBackgroundColor(bg_color);
|
|
|
|
StateColor text_color = StateColor(
|
2022-11-04 03:28:05 +00:00
|
|
|
std::pair{wxColour(254,254, 254), (int) StateColor::Normal});
|
2022-07-15 15:37:19 +00:00
|
|
|
btn->SetTextColor(text_color);
|
|
|
|
btn->SetInactiveIcon(inactive_bmp_name);
|
|
|
|
btn->SetSelected(false);
|
|
|
|
btn->Bind(wxEVT_BUTTON, [this, btn](wxCommandEvent& event) {
|
|
|
|
if (auto it = std::find(m_pageButtons.begin(), m_pageButtons.end(), btn); it != m_pageButtons.end()) {
|
|
|
|
auto sel = it - m_pageButtons.begin();
|
2022-07-22 09:46:10 +00:00
|
|
|
//do it later
|
|
|
|
//SetSelection(sel);
|
2022-07-15 15:37:19 +00:00
|
|
|
|
|
|
|
wxCommandEvent evt = wxCommandEvent(wxCUSTOMEVT_NOTEBOOK_SEL_CHANGED);
|
|
|
|
evt.SetId(sel);
|
|
|
|
wxPostEvent(this->GetParent(), evt);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
Slic3r::GUI::wxGetApp().UpdateDarkUI(btn);
|
|
|
|
m_pageButtons.insert(m_pageButtons.begin() + n, btn);
|
|
|
|
m_buttons_sizer->Insert(n, new wxSizerItem(btn));
|
|
|
|
m_buttons_sizer->SetCols(m_buttons_sizer->GetCols() + 1);
|
|
|
|
m_sizer->Layout();
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
void ButtonsListCtrl::RemovePage(size_t n)
|
|
|
|
{
|
|
|
|
Button* btn = m_pageButtons[n];
|
|
|
|
m_pageButtons.erase(m_pageButtons.begin() + n);
|
|
|
|
m_buttons_sizer->Remove(n);
|
2022-07-22 09:46:10 +00:00
|
|
|
#if __WXOSX__
|
|
|
|
RemoveChild(btn);
|
|
|
|
#else
|
2022-07-15 15:37:19 +00:00
|
|
|
btn->Reparent(nullptr);
|
2022-07-22 09:46:10 +00:00
|
|
|
#endif
|
2022-07-15 15:37:19 +00:00
|
|
|
btn->Destroy();
|
|
|
|
m_sizer->Layout();
|
|
|
|
}
|
|
|
|
|
|
|
|
bool ButtonsListCtrl::SetPageImage(size_t n, const std::string& bmp_name) const
|
|
|
|
{
|
|
|
|
if (n >= m_pageButtons.size())
|
|
|
|
return false;
|
|
|
|
|
|
|
|
// BBS
|
|
|
|
//return m_pageButtons[n]->SetBitmap_(bmp_name);
|
|
|
|
ScalableBitmap bitmap(NULL, bmp_name);
|
|
|
|
//m_pageButtons[n]->SetBitmap_(bitmap);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
void ButtonsListCtrl::SetPageText(size_t n, const wxString& strText)
|
|
|
|
{
|
|
|
|
Button* btn = m_pageButtons[n];
|
|
|
|
btn->SetLabel(strText);
|
|
|
|
}
|
|
|
|
|
|
|
|
wxString ButtonsListCtrl::GetPageText(size_t n) const
|
|
|
|
{
|
|
|
|
Button* btn = m_pageButtons[n];
|
|
|
|
return btn->GetLabel();
|
|
|
|
}
|
|
|
|
|
|
|
|
//#endif // _WIN32
|
|
|
|
|
2022-12-08 07:57:13 +00:00
|
|
|
void Notebook::Init()
|
|
|
|
{
|
|
|
|
// We don't need any border as we don't have anything to separate the
|
|
|
|
// page contents from.
|
|
|
|
SetInternalBorder(0);
|
|
|
|
|
|
|
|
// No effects by default.
|
|
|
|
m_showEffect = m_hideEffect = wxSHOW_EFFECT_NONE;
|
2022-07-15 15:37:19 +00:00
|
|
|
|
2022-12-08 07:57:13 +00:00
|
|
|
m_showTimeout = m_hideTimeout = 0;
|
Add support for Bambu Lab X1 series live video stream on Linux.
wxWidgets on Linux uses GStreamer as its back-end for wxMediaCtrl, which
doesn't have a bambu: URI handler. On Windows, this is handled by a Windows
Media subsystem plugin, and on Mac, this is handled with a BambuPlayer
class. Luckily, the libBambuSource.so binary that is distributed with the
network plugin package already contains support for receiving h.264 data
from the network, and the API is the same as is used by the tiny
bambusource.exe binary on Windows; we glue this into a GStreamer source
plugin that registers a URI handler for bambu:.
To make this work, we make a few additional changes elsewhere. GStreamer
seems to have trouble rendering an Xv overlay onto a 32bpp X visual, but
Bambu Slicer seems to request a 32bpp visual for some background
transparency in the Notebook; it doesn't seem to use it in an interesting
way on Linux, though, so we remove that request for transparency to allow
Bambu Studio to render to a 24bpp visual. The media controller
infrastructure also makes a few assumptions about when sizing information
can be queried from a wxMediaCtrl backend that do not hold true on Linux; we
either fix those assumptions, or fake them out, as needed. We also make a
few changes needed to successfully compile C.
This has only been tested with the GStreamer backend for wxWidgets --
notably, not the GStreamer-play backend (these are, astonishingly, two
different things!). If you find that this seems not to work, consider
*un*installing the libgstreamer-plugins-bad1.0-dev package and then
rebuilding wxWidgets.
2023-01-10 09:40:39 +00:00
|
|
|
|
|
|
|
/* On Linux, Gstreamer wxMediaCtrl does not seem to get along well with
|
|
|
|
* 32-bit X11 visuals (the overlay does not work). Is this a wxWindows
|
|
|
|
* bug? Is this a Gstreamer bug? No idea, but it is our problem ...
|
|
|
|
* and anyway, this transparency thing just isn't all that interesting,
|
|
|
|
* so we just don't do it on Linux.
|
|
|
|
*/
|
|
|
|
#ifndef __WXGTK__
|
2022-12-08 07:57:13 +00:00
|
|
|
SetBackgroundStyle(wxBG_STYLE_TRANSPARENT);
|
Add support for Bambu Lab X1 series live video stream on Linux.
wxWidgets on Linux uses GStreamer as its back-end for wxMediaCtrl, which
doesn't have a bambu: URI handler. On Windows, this is handled by a Windows
Media subsystem plugin, and on Mac, this is handled with a BambuPlayer
class. Luckily, the libBambuSource.so binary that is distributed with the
network plugin package already contains support for receiving h.264 data
from the network, and the API is the same as is used by the tiny
bambusource.exe binary on Windows; we glue this into a GStreamer source
plugin that registers a URI handler for bambu:.
To make this work, we make a few additional changes elsewhere. GStreamer
seems to have trouble rendering an Xv overlay onto a 32bpp X visual, but
Bambu Slicer seems to request a 32bpp visual for some background
transparency in the Notebook; it doesn't seem to use it in an interesting
way on Linux, though, so we remove that request for transparency to allow
Bambu Studio to render to a 24bpp visual. The media controller
infrastructure also makes a few assumptions about when sizing information
can be queried from a wxMediaCtrl backend that do not hold true on Linux; we
either fix those assumptions, or fake them out, as needed. We also make a
few changes needed to successfully compile C.
This has only been tested with the GStreamer backend for wxWidgets --
notably, not the GStreamer-play backend (these are, astonishingly, two
different things!). If you find that this seems not to work, consider
*un*installing the libgstreamer-plugins-bad1.0-dev package and then
rebuilding wxWidgets.
2023-01-10 09:40:39 +00:00
|
|
|
#endif
|
2022-12-08 07:57:13 +00:00
|
|
|
}
|