feat: UI for mixed capability state

This commit is contained in:
Ian Chua
2026-07-03 14:48:49 +08:00
parent ba41b54c4b
commit e3c6ec309d
4 changed files with 42 additions and 4 deletions

View File

@@ -385,6 +385,21 @@ function IsPluginChecked(plugin) {
return GetStatus(plugin) === "Activated"; return GetStatus(plugin) === "Activated";
} }
function HasMixedCapabilityState(plugin) {
if (!IsPluginChecked(plugin))
return false;
const toggleableCapabilities = GetCapabilities(plugin).filter((capability) =>
capability?.can_toggle !== false &&
String(capability?.name || "") &&
String(capability?.type_key || "")
);
const hasEnabled = toggleableCapabilities.some((capability) => capability?.enabled === true);
const hasDisabled = toggleableCapabilities.some((capability) => capability?.enabled !== true);
return hasEnabled && hasDisabled;
}
function IsPluginLoading(plugin) { function IsPluginLoading(plugin) {
return GetStatus(plugin) === "Loading"; return GetStatus(plugin) === "Loading";
} }
@@ -420,12 +435,20 @@ function CheckCell(row, plugin) {
checkboxLabel.classList.add("loading"); checkboxLabel.classList.add("loading");
if (!plugin.can_toggle) if (!plugin.can_toggle)
checkboxLabel.classList.add("disabled"); checkboxLabel.classList.add("disabled");
const hasMixedCapabilityState = HasMixedCapabilityState(plugin);
if (hasMixedCapabilityState)
checkboxLabel.classList.add("mixed");
const checkbox = document.createElement("input"); const checkbox = document.createElement("input");
checkbox.type = "checkbox"; checkbox.type = "checkbox";
checkbox.className = "plugin-checkbox-input"; checkbox.className = "plugin-checkbox-input";
checkbox.checked = IsPluginChecked(plugin); checkbox.checked = IsPluginChecked(plugin);
checkbox.indeterminate = hasMixedCapabilityState;
checkbox.disabled = isLoading || !plugin.can_toggle; checkbox.disabled = isLoading || !plugin.can_toggle;
checkbox.dataset.pluginKey = row.dataset.pluginKey; checkbox.dataset.pluginKey = row.dataset.pluginKey;
if (checkbox.indeterminate) {
checkbox.setAttribute("aria-checked", "mixed");
checkbox.setAttribute("aria-label", "Some plugin capabilities are enabled");
}
const checkboxMark = document.createElement("span"); const checkboxMark = document.createElement("span");
checkboxMark.className = "plugin-checkbox-mark"; checkboxMark.className = "plugin-checkbox-mark";
checkboxLabel.appendChild(checkbox); checkboxLabel.appendChild(checkbox);

View File

@@ -878,6 +878,25 @@ body {
transform: rotate(45deg); transform: rotate(45deg);
} }
.plugin-checkbox-input:indeterminate + .plugin-checkbox-mark,
.plugin-checkbox.mixed .plugin-checkbox-mark {
border-color: #009688;
background: #009688;
}
.plugin-checkbox-input:indeterminate + .plugin-checkbox-mark::after,
.plugin-checkbox.mixed .plugin-checkbox-mark::after {
content: "";
position: absolute;
left: 2px;
top: 5px;
width: 6px;
height: 0;
border: solid #fff;
border-width: 1.5px 0 0 0;
transform: none;
}
.plugin-checkbox-input:disabled + .plugin-checkbox-mark { .plugin-checkbox-input:disabled + .plugin-checkbox-mark {
opacity: 0.6; opacity: 0.6;
} }

View File

@@ -33,7 +33,6 @@
#include "Widgets/TextCtrl.h" #include "Widgets/TextCtrl.h"
#include "../Utils/ColorSpaceConvert.hpp" #include "../Utils/ColorSpaceConvert.hpp"
#include "slic3r/plugin/PluginManager.hpp"
#ifdef __WXOSX__ #ifdef __WXOSX__
#define wxOSX true #define wxOSX true
#else #else

View File

@@ -2,10 +2,8 @@
#include "slic3r/GUI/GUI_App.hpp" #include "slic3r/GUI/GUI_App.hpp"
#include <pybind11/embed.h> #include <pybind11/embed.h>
namespace py = pybind11;
#include "PythonPluginBridge.hpp" #include "PythonPluginBridge.hpp"
#include "PythonPluginInterface.hpp"
#include "PluginFsUtils.hpp" #include "PluginFsUtils.hpp"
#include "PythonFileUtils.hpp" #include "PythonFileUtils.hpp"
@@ -13,7 +11,6 @@ namespace py = pybind11;
#include <boost/filesystem.hpp> #include <boost/filesystem.hpp>
#include <mutex> #include <mutex>
#include <algorithm> #include <algorithm>
#include <memory>
#include <chrono> #include <chrono>
#include <slic3r/GUI/NotificationManager.hpp> #include <slic3r/GUI/NotificationManager.hpp>
#include <slic3r/plugin/PluginDescriptor.hpp> #include <slic3r/plugin/PluginDescriptor.hpp>