mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-09-11 02:57:39 +00:00
Add a OrcaSlicer badge in the thumbnail preview for published 3MF projects. Add a visual indicator in the publish dialog to show that something in the section is toggled
This commit is contained in:
@@ -552,7 +552,8 @@ body
|
||||
background-color: #E4E4E4;
|
||||
border-radius: 8px;
|
||||
width: 184px;
|
||||
height: 184px;
|
||||
height: 184px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.FileItem img
|
||||
@@ -564,6 +565,19 @@ body
|
||||
object-fit: cover;
|
||||
}
|
||||
|
||||
.FileImg .FileLogoBadge
|
||||
{
|
||||
position: absolute;
|
||||
top: 8px;
|
||||
left: 8px;
|
||||
width: 26px;
|
||||
height: 26px;
|
||||
padding: 2px;
|
||||
box-sizing: border-box;
|
||||
background-color: rgba(255,255,255,0.85);
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
.FileName
|
||||
{
|
||||
white-space: nowrap;
|
||||
|
||||
@@ -226,10 +226,11 @@ function ShowRecentFileList( pList )
|
||||
//let sShortName=sPath.substring(index+1,sPath.length);
|
||||
|
||||
let sBadge=sPublished? '<span class="FilePublishedBadge">PUB</span>':'';
|
||||
let sLogoBadge=sPublished? '<img class="FileLogoBadge" src="../../images/OrcaSlicer_gradient_circle.svg" alt="" />':'';
|
||||
|
||||
let TmpHtml='<div class="FileItem" fpath="'+sPath+'" >'+
|
||||
'<a class="FileTip" title="'+sPath+'"></a>'+
|
||||
'<div class="FileImg" ><img src="'+sImg+'" onerror="this.onerror=null;this.src=\'img/d.png\';" alt="No Image" /></div>'+
|
||||
'<div class="FileImg" ><img src="'+sImg+'" onerror="this.onerror=null;this.src=\'img/d.png\';" alt="No Image" />'+sLogoBadge+'</div>'+
|
||||
'<div class="FileNamePack">'+sBadge+'<div class="FileName TextS1">'+sName+'</div></div>'+
|
||||
'<div class="FileDate">'+sTime+'</div>'+
|
||||
'</div>';
|
||||
|
||||
@@ -881,6 +881,7 @@ void PublishSettingsDialog::build_option_model()
|
||||
m_outer_tabs->SelectItem(0);
|
||||
show_outer_page(0);
|
||||
}
|
||||
refresh_tab_indicators();
|
||||
}
|
||||
|
||||
size_t PublishSettingsDialog::section_group_for(Section kind)
|
||||
@@ -1127,6 +1128,7 @@ void PublishSettingsDialog::add_row_ui(const std::string& key,
|
||||
Row& current = m_rows[row_index];
|
||||
current.check = new wxCheckBox(category.scroll, wxID_ANY, label);
|
||||
current.check->SetFont(Label::Body_13);
|
||||
current.check->Bind(wxEVT_CHECKBOX, [this](wxCommandEvent&) { refresh_tab_indicators(); });
|
||||
auto* row_sizer = new wxBoxSizer(wxHORIZONTAL);
|
||||
row_sizer->Add(current.check, 0, wxALIGN_CENTER_VERTICAL);
|
||||
// The value is read-only text (incl. the Type row: the published type is the slot's
|
||||
@@ -1161,6 +1163,7 @@ void PublishSettingsDialog::on_full_toggle(size_t category_index)
|
||||
const bool full = cat.full_check->GetValue();
|
||||
for (size_t r : cat.rows)
|
||||
m_rows[r].check->Enable(!full);
|
||||
refresh_tab_indicators();
|
||||
}
|
||||
|
||||
void PublishSettingsDialog::on_enable_toggle(size_t category_index)
|
||||
@@ -1195,6 +1198,7 @@ void PublishSettingsDialog::on_enable_toggle(size_t category_index)
|
||||
apply_visibility();
|
||||
if (cat.page != nullptr)
|
||||
cat.page->GetSizer()->Layout();
|
||||
refresh_tab_indicators();
|
||||
}
|
||||
|
||||
void PublishSettingsDialog::add_mixed_visual(size_t category_index, const MixedVisualSpec& spec)
|
||||
@@ -1606,6 +1610,7 @@ void PublishSettingsDialog::select_all(bool value)
|
||||
if (m_categories[c].section == Section::Material)
|
||||
on_enable_toggle(c);
|
||||
apply_visibility();
|
||||
refresh_tab_indicators();
|
||||
}
|
||||
|
||||
bool PublishSettingsDialog::row_is_visible(const Row& row) const
|
||||
@@ -1637,6 +1642,7 @@ void PublishSettingsDialog::select_visible(bool value)
|
||||
m_filter_ctrl->ChangeValue("");
|
||||
apply_filter(""); // resync visibility and the All/None bar
|
||||
}
|
||||
refresh_tab_indicators();
|
||||
}
|
||||
|
||||
void PublishSettingsDialog::show_menu(wxMouseEvent& evt)
|
||||
@@ -1778,6 +1784,7 @@ void PublishSettingsDialog::apply_selection(const std::vector<std::string>& publ
|
||||
}
|
||||
|
||||
apply_visibility();
|
||||
refresh_tab_indicators();
|
||||
}
|
||||
|
||||
std::vector<std::string> PublishSettingsDialog::GetPublishedKeys() const
|
||||
@@ -1932,6 +1939,38 @@ std::vector<Slic3r::PublishedMaterialEntry> PublishSettingsDialog::GetPublishedM
|
||||
return out;
|
||||
}
|
||||
|
||||
bool PublishSettingsDialog::category_has_selection(const Category& cat) const
|
||||
{
|
||||
// A material slot publishes (or not) as a whole, gated by "Enable".
|
||||
if (cat.section == Section::Material)
|
||||
return cat.enable_check != nullptr && cat.enable_check->GetValue();
|
||||
// Print/Printer categories have no gate: any checked row counts.
|
||||
for (const size_t r : cat.rows)
|
||||
if (m_rows[r].check->GetValue())
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
void PublishSettingsDialog::refresh_tab_indicators()
|
||||
{
|
||||
for (size_t s = 0; s < m_sections.size(); ++s) {
|
||||
SectionGroup& section = m_sections[s];
|
||||
bool any = false;
|
||||
for (size_t i = 0; i < section.categories.size(); ++i) {
|
||||
const bool on = category_has_selection(m_categories[section.categories[i]]);
|
||||
section.tabs->SetItemIndicator(static_cast<unsigned int>(i), on);
|
||||
any = any || on;
|
||||
}
|
||||
if (section.mixed_tabs != nullptr)
|
||||
for (size_t i = 0; i < section.mixed_categories.size(); ++i) {
|
||||
const bool on = category_has_selection(m_categories[section.mixed_categories[i]]);
|
||||
section.mixed_tabs->SetItemIndicator(static_cast<unsigned int>(i), on);
|
||||
any = any || on;
|
||||
}
|
||||
m_outer_tabs->SetItemIndicator(static_cast<unsigned int>(s), any);
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<std::string> PublishSettingsDialog::full_keys_for_slot() const
|
||||
{
|
||||
// The canonical filament preset keys minus the structural keys the published overlay must
|
||||
|
||||
@@ -213,6 +213,11 @@ private:
|
||||
// "Enable" toggled on a material slot: reveals/hides everything below the header and, for a
|
||||
// mixed slot, auto-selects its component filaments' "Enable" + "Full Publish" toggles.
|
||||
void on_enable_toggle(size_t category_index);
|
||||
// Whether a category currently publishes something, driving its tab's indicator dot.
|
||||
// Print/Printer: any row checked. Material: the slot's "Enable" is on.
|
||||
bool category_has_selection(const Category& cat) const;
|
||||
// Recompute the indicator dot on every outer/inner tab from the current selection state.
|
||||
void refresh_tab_indicators();
|
||||
// Unmet dependencies of enabled mixed-filament slots, one record per (mix, component) pair:
|
||||
// "Enable" not checked on the component, or enabled with neither "Full Publish" nor the
|
||||
// "Type" requirement row checked. Colour is deliberately ignored (the receiver renders the
|
||||
|
||||
@@ -162,6 +162,15 @@ void Button::SetCenter(bool isCenter)
|
||||
{
|
||||
this->isCenter = isCenter; }
|
||||
|
||||
void Button::SetIndicator(bool on)
|
||||
{
|
||||
if (m_show_indicator == on)
|
||||
return;
|
||||
m_show_indicator = on;
|
||||
messureSize();
|
||||
Refresh();
|
||||
}
|
||||
|
||||
void Button::SetVertical(bool vertical)
|
||||
{
|
||||
this->vertical = vertical;
|
||||
@@ -324,6 +333,13 @@ void Button::render(wxDC& dc)
|
||||
szContent.x -= d;
|
||||
}
|
||||
}
|
||||
if (m_show_indicator) {
|
||||
const int dot = FromDIP(6);
|
||||
if (vertical)
|
||||
szContent.y += dot + FromDIP(6);
|
||||
else
|
||||
szContent.x += dot + FromDIP(6);
|
||||
}
|
||||
// move to center
|
||||
wxRect rcContent = { {0, 0}, size };
|
||||
if (isCenter) {
|
||||
@@ -364,6 +380,17 @@ void Button::render(wxDC& dc)
|
||||
#endif
|
||||
dc.DrawText(text, pt);
|
||||
}
|
||||
if (m_show_indicator) {
|
||||
const int dot = FromDIP(6); // diameter
|
||||
wxPoint dot_pt;
|
||||
dot_pt.x = pt.x + (text.IsEmpty() ? 0 : textSize.x) + FromDIP(6) + dot / 2;
|
||||
// Centre on the content vertically; a bitmap-only (empty-label) tab has no text row.
|
||||
dot_pt.y = text.IsEmpty() ? rcContent.y + rcContent.height / 2 : pt.y + textSize.y / 2;
|
||||
const wxColour c = StateColor::darkModeColorFor(m_indicator_color);
|
||||
dc.SetBrush(wxBrush(c));
|
||||
dc.SetPen(wxPen(c));
|
||||
dc.DrawCircle(dot_pt, dot / 2);
|
||||
}
|
||||
}
|
||||
|
||||
void Button::messureSize()
|
||||
@@ -388,6 +415,14 @@ void Button::messureSize()
|
||||
if (szIcon.y > szContent.y) szContent.y = szIcon.y;
|
||||
}
|
||||
}
|
||||
if (m_show_indicator) {
|
||||
// Indicator dot sits to the right of the label: its diameter plus the gap from the text.
|
||||
const int dot = FromDIP(6);
|
||||
if (vertical)
|
||||
szContent.y += dot + FromDIP(6);
|
||||
else
|
||||
szContent.x += dot + FromDIP(6);
|
||||
}
|
||||
wxSize size = szContent + paddingSize * 2;
|
||||
if (minSize.GetHeight() > 0)
|
||||
size.SetHeight(minSize.GetHeight());
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include "../wxExtensions.hpp"
|
||||
#include "StaticBox.hpp"
|
||||
#include <wx/tipwin.h>
|
||||
#include <wx/colour.h>
|
||||
|
||||
class ButtonProps
|
||||
{
|
||||
@@ -44,6 +45,8 @@ class Button : public StaticBox
|
||||
bool canFocus = true;
|
||||
bool isCenter = true;
|
||||
bool vertical = false;
|
||||
bool m_show_indicator = false;
|
||||
wxColour m_indicator_color = wxColour("#009688");
|
||||
|
||||
static const int buttonWidth = 200;
|
||||
static const int buttonHeight = 50;
|
||||
@@ -75,6 +78,10 @@ public:
|
||||
|
||||
void SetSelected(bool selected = true) { m_selected = selected; }
|
||||
|
||||
// Show a small coloured dot to the right of the label (used by TabCtrl tabs to flag that
|
||||
// the tab's category has a selected/toggled setting).
|
||||
void SetIndicator(bool on);
|
||||
|
||||
// Only meant to be used by inspector, not public API
|
||||
ButtonStyle GetStyle() const { return m_style; }
|
||||
ButtonType GetType() const { return m_type; }
|
||||
|
||||
@@ -171,6 +171,14 @@ void TabCtrl::SetItemBitmap(unsigned int item, const wxBitmap& bitmap)
|
||||
relayout();
|
||||
}
|
||||
|
||||
void TabCtrl::SetItemIndicator(unsigned int item, bool on)
|
||||
{
|
||||
if (item >= btns.size())
|
||||
return;
|
||||
btns[item]->SetIndicator(on);
|
||||
relayout();
|
||||
}
|
||||
|
||||
bool TabCtrl::GetItemBold(unsigned int item) const
|
||||
{
|
||||
if (item >= btns.size())
|
||||
|
||||
@@ -46,6 +46,9 @@ public:
|
||||
void SetItemText(unsigned int item, wxString const& value);
|
||||
void SetItemBitmap(unsigned int item, const wxBitmap& bitmap);
|
||||
|
||||
// Show/hide the small "has selection" dot next to a tab's text.
|
||||
void SetItemIndicator(unsigned int item, bool on);
|
||||
|
||||
bool GetItemBold(unsigned int item) const;
|
||||
void SetItemBold(unsigned int item, bool bold);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user