mirror of
https://github.com/AvengeMedia/DankMaterialShell.git
synced 2026-01-24 21:42:51 -05:00
plugins: support for multiple widgets per-plugin (variants)
This commit is contained in:
@@ -87,8 +87,18 @@ Loader {
|
||||
}
|
||||
|
||||
if (item.pluginService !== undefined) {
|
||||
var parts = widgetId.split(":")
|
||||
var pluginId = parts[0]
|
||||
var variantId = parts.length > 1 ? parts[1] : null
|
||||
|
||||
if (item.pluginId !== undefined) {
|
||||
item.pluginId = widgetId
|
||||
item.pluginId = pluginId
|
||||
}
|
||||
if (item.variantId !== undefined) {
|
||||
item.variantId = variantId
|
||||
}
|
||||
if (item.variantData !== undefined && variantId) {
|
||||
item.variantData = PluginService.getPluginVariantData(pluginId, variantId)
|
||||
}
|
||||
item.pluginService = PluginService
|
||||
}
|
||||
@@ -134,8 +144,11 @@ Loader {
|
||||
return componentMap[widgetId]
|
||||
}
|
||||
|
||||
var parts = widgetId.split(":")
|
||||
var pluginId = parts[0]
|
||||
|
||||
let pluginMap = PluginService.getWidgetComponents()
|
||||
return pluginMap[widgetId] || null
|
||||
return pluginMap[pluginId] || null
|
||||
}
|
||||
|
||||
function getWidgetVisible(widgetId, dgopAvailable) {
|
||||
|
||||
@@ -34,6 +34,7 @@ Item {
|
||||
signal ccWidgetExpanded()
|
||||
|
||||
property var pluginData: ({})
|
||||
property var variants: []
|
||||
|
||||
readonly property bool isVertical: axis?.isVertical ?? false
|
||||
readonly property bool hasHorizontalPill: horizontalBarPill !== null
|
||||
@@ -64,9 +65,32 @@ Item {
|
||||
function loadPluginData() {
|
||||
if (!pluginService || !pluginId) {
|
||||
pluginData = {}
|
||||
variants = []
|
||||
return
|
||||
}
|
||||
pluginData = SettingsData.getPluginSettingsForPlugin(pluginId)
|
||||
variants = pluginService.getPluginVariants(pluginId)
|
||||
}
|
||||
|
||||
function createVariant(variantName, variantConfig) {
|
||||
if (!pluginService || !pluginId) {
|
||||
return null
|
||||
}
|
||||
return pluginService.createPluginVariant(pluginId, variantName, variantConfig)
|
||||
}
|
||||
|
||||
function removeVariant(variantId) {
|
||||
if (!pluginService || !pluginId) {
|
||||
return
|
||||
}
|
||||
pluginService.removePluginVariant(pluginId, variantId)
|
||||
}
|
||||
|
||||
function updateVariant(variantId, variantConfig) {
|
||||
if (!pluginService || !pluginId) {
|
||||
return
|
||||
}
|
||||
pluginService.updatePluginVariant(pluginId, variantId, variantConfig)
|
||||
}
|
||||
|
||||
width: isVertical ? (hasVerticalPill ? verticalPill.width : 0) : (hasHorizontalPill ? horizontalPill.width : 0)
|
||||
|
||||
@@ -12,13 +12,20 @@ Item {
|
||||
|
||||
signal settingChanged()
|
||||
|
||||
property var variants: []
|
||||
|
||||
implicitHeight: hasPermission ? settingsColumn.implicitHeight : errorText.implicitHeight
|
||||
height: implicitHeight
|
||||
|
||||
readonly property bool hasPermission: pluginService && pluginService.hasPermission ? pluginService.hasPermission(pluginId, "settings_write") : true
|
||||
|
||||
Component.onCompleted: {
|
||||
loadVariants()
|
||||
}
|
||||
|
||||
onPluginServiceChanged: {
|
||||
if (pluginService) {
|
||||
loadVariants()
|
||||
for (let i = 0; i < settingsColumn.children.length; i++) {
|
||||
const child = settingsColumn.children[i]
|
||||
if (child.loadValue) {
|
||||
@@ -28,6 +35,44 @@ Item {
|
||||
}
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: pluginService
|
||||
function onPluginDataChanged(changedPluginId) {
|
||||
if (changedPluginId === pluginId) {
|
||||
loadVariants()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function loadVariants() {
|
||||
if (!pluginService || !pluginId) {
|
||||
variants = []
|
||||
return
|
||||
}
|
||||
variants = pluginService.getPluginVariants(pluginId)
|
||||
}
|
||||
|
||||
function createVariant(variantName, variantConfig) {
|
||||
if (!pluginService || !pluginId) {
|
||||
return null
|
||||
}
|
||||
return pluginService.createPluginVariant(pluginId, variantName, variantConfig)
|
||||
}
|
||||
|
||||
function removeVariant(variantId) {
|
||||
if (!pluginService || !pluginId) {
|
||||
return
|
||||
}
|
||||
pluginService.removePluginVariant(pluginId, variantId)
|
||||
}
|
||||
|
||||
function updateVariant(variantId, variantConfig) {
|
||||
if (!pluginService || !pluginId) {
|
||||
return
|
||||
}
|
||||
pluginService.updatePluginVariant(pluginId, variantId, variantConfig)
|
||||
}
|
||||
|
||||
function saveValue(key, value) {
|
||||
if (!pluginService) {
|
||||
return
|
||||
|
||||
@@ -190,18 +190,16 @@ Item {
|
||||
"enabled": SystemUpdateService.distributionSupported
|
||||
}]
|
||||
|
||||
// Add all available plugins (loaded and unloaded)
|
||||
var allPlugins = PluginService.getAvailablePlugins()
|
||||
for (var i = 0; i < allPlugins.length; i++) {
|
||||
var plugin = allPlugins[i]
|
||||
var isLoaded = PluginService.isPluginLoaded(plugin.id)
|
||||
var allPluginVariants = PluginService.getAllPluginVariants()
|
||||
for (var i = 0; i < allPluginVariants.length; i++) {
|
||||
var variant = allPluginVariants[i]
|
||||
coreWidgets.push({
|
||||
"id": plugin.id,
|
||||
"text": plugin.name,
|
||||
"description": plugin.description || "Plugin widget",
|
||||
"icon": plugin.icon || "extension",
|
||||
"enabled": isLoaded,
|
||||
"warning": !isLoaded ? "Plugin is disabled - enable in Plugins settings to use" : undefined
|
||||
"id": variant.fullId,
|
||||
"text": variant.name,
|
||||
"description": variant.description,
|
||||
"icon": variant.icon,
|
||||
"enabled": variant.loaded,
|
||||
"warning": !variant.loaded ? "Plugin is disabled - enable in Plugins settings to use" : undefined
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -378,6 +378,7 @@ Item {
|
||||
anchors.margins: Theme.spacingL
|
||||
active: pluginDelegate.isExpanded && pluginDelegate.hasSettings && PluginService.isPluginLoaded(pluginDelegate.pluginId)
|
||||
asynchronous: false
|
||||
focus: true
|
||||
|
||||
source: {
|
||||
if (active && pluginDelegate.pluginSettingsPath) {
|
||||
@@ -394,9 +395,13 @@ Item {
|
||||
if (item && typeof PluginService !== "undefined") {
|
||||
item.pluginService = PluginService
|
||||
}
|
||||
if (item && typeof PopoutService !== "undefined") {
|
||||
if (item && typeof PopoutService !== "undefined" && "popoutService" in item) {
|
||||
item.popoutService = PopoutService
|
||||
}
|
||||
if (item) {
|
||||
item.focus = true
|
||||
item.forceActiveFocus()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
116
PLUGINS/ExampleWithVariants/README.md
Normal file
116
PLUGINS/ExampleWithVariants/README.md
Normal file
@@ -0,0 +1,116 @@
|
||||
# Example with Variants Plugin
|
||||
|
||||
This plugin demonstrates the dynamic variant system for DankMaterialShell plugins.
|
||||
|
||||
## What are Variants?
|
||||
|
||||
Variants allow a single plugin to create multiple widget instances with different configurations. Each variant appears as a separate widget option in the Bar Settings "Add Widget" menu.
|
||||
|
||||
## How It Works
|
||||
|
||||
### Plugin Architecture
|
||||
|
||||
1. **Single Component**: The plugin defines one widget component (`VariantWidget.qml`)
|
||||
2. **Variant Data**: Each variant stores its configuration in plugin settings
|
||||
3. **Dynamic Creation**: Variants are created through the plugin's settings UI
|
||||
4. **Widget ID Format**: Variants use the format `pluginId:variantId` (e.g., `exampleVariants:variant_1234567890`)
|
||||
|
||||
### Widget Properties
|
||||
|
||||
Each variant widget receives:
|
||||
- `pluginService`: Reference to PluginService
|
||||
- `pluginId`: The base plugin ID (e.g., "exampleVariants")
|
||||
- `variantId`: The specific variant ID (e.g., "variant_1234567890")
|
||||
- `variantData`: The variant's configuration object
|
||||
|
||||
### Variant Configuration
|
||||
|
||||
This example stores:
|
||||
```javascript
|
||||
{
|
||||
id: "variant_1234567890",
|
||||
name: "My Variant",
|
||||
text: "Display Text",
|
||||
icon: "star",
|
||||
color: "#FF5722"
|
||||
}
|
||||
```
|
||||
|
||||
## Creating Your Own Variant Plugin
|
||||
|
||||
### 1. Widget Component
|
||||
|
||||
Create a widget that accepts variant data:
|
||||
|
||||
```qml
|
||||
Rectangle {
|
||||
property var pluginService: null
|
||||
property string pluginId: ""
|
||||
property string variantId: ""
|
||||
property var variantData: null
|
||||
|
||||
// Use variantData for configuration
|
||||
property string displayText: variantData?.text || "Default"
|
||||
}
|
||||
```
|
||||
|
||||
### 2. Settings Component
|
||||
|
||||
Provide UI to manage variants:
|
||||
|
||||
```qml
|
||||
FocusScope {
|
||||
property var pluginService: null
|
||||
|
||||
// Create variant
|
||||
pluginService.createPluginVariant(pluginId, variantName, variantConfig)
|
||||
|
||||
// Remove variant
|
||||
pluginService.removePluginVariant(pluginId, variantId)
|
||||
|
||||
// Update variant
|
||||
pluginService.updatePluginVariant(pluginId, variantId, variantConfig)
|
||||
|
||||
// Get all variants
|
||||
var variants = pluginService.getPluginVariants(pluginId)
|
||||
}
|
||||
```
|
||||
|
||||
### 3. Plugin Manifest
|
||||
|
||||
Standard plugin manifest - no special configuration needed:
|
||||
|
||||
```json
|
||||
{
|
||||
"id": "yourPlugin",
|
||||
"name": "Your Plugin",
|
||||
"component": "./Widget.qml",
|
||||
"settings": "./Settings.qml"
|
||||
}
|
||||
```
|
||||
|
||||
## Use Cases
|
||||
|
||||
- **Script Runner**: Multiple variants running different scripts
|
||||
- **System Monitors**: Different monitoring targets (CPU, GPU, Network)
|
||||
- **Quick Launchers**: Different apps or commands per variant
|
||||
- **Custom Indicators**: Different data sources or APIs
|
||||
- **Time Zones**: Multiple clocks for different time zones
|
||||
|
||||
## API Reference
|
||||
|
||||
### PluginService Functions
|
||||
|
||||
- `getPluginVariants(pluginId)`: Get all variants for a plugin
|
||||
- `getAllPluginVariants()`: Get all variants across all plugins
|
||||
- `createPluginVariant(pluginId, name, config)`: Create new variant
|
||||
- `removePluginVariant(pluginId, variantId)`: Delete variant
|
||||
- `updatePluginVariant(pluginId, variantId, config)`: Update variant
|
||||
- `getPluginVariantData(pluginId, variantId)`: Get specific variant data
|
||||
|
||||
### Widget Properties
|
||||
|
||||
- `pluginId`: Base plugin identifier
|
||||
- `variantId`: Variant identifier (null if no variant)
|
||||
- `variantData`: Variant configuration object
|
||||
- `pluginService`: PluginService reference
|
||||
303
PLUGINS/ExampleWithVariants/VariantSettings.qml
Normal file
303
PLUGINS/ExampleWithVariants/VariantSettings.qml
Normal file
@@ -0,0 +1,303 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import qs.Common
|
||||
import qs.Services
|
||||
import qs.Widgets
|
||||
import qs.Modules.Plugins
|
||||
|
||||
PluginSettings {
|
||||
id: root
|
||||
pluginId: "exampleVariants"
|
||||
|
||||
onVariantsChanged: {
|
||||
variantsModel.clear()
|
||||
for (var i = 0; i < variants.length; i++) {
|
||||
variantsModel.append(variants[i])
|
||||
}
|
||||
}
|
||||
|
||||
StyledText {
|
||||
width: parent.width
|
||||
text: "Variant Manager"
|
||||
font.pixelSize: Theme.fontSizeLarge
|
||||
font.weight: Font.Bold
|
||||
color: Theme.surfaceText
|
||||
}
|
||||
|
||||
StyledText {
|
||||
width: parent.width
|
||||
text: "Create multiple widget variants with different text, icons, and colors"
|
||||
font.pixelSize: Theme.fontSizeSmall
|
||||
color: Theme.surfaceVariantText
|
||||
wrapMode: Text.WordWrap
|
||||
}
|
||||
|
||||
StyledRect {
|
||||
width: parent.width
|
||||
height: addVariantColumn.implicitHeight + Theme.spacingL * 2
|
||||
radius: Theme.cornerRadius
|
||||
color: Theme.surfaceContainerHigh
|
||||
|
||||
Column {
|
||||
id: addVariantColumn
|
||||
anchors.fill: parent
|
||||
anchors.margins: Theme.spacingL
|
||||
spacing: Theme.spacingM
|
||||
|
||||
StyledText {
|
||||
text: "Add New Variant"
|
||||
font.pixelSize: Theme.fontSizeMedium
|
||||
font.weight: Font.Medium
|
||||
color: Theme.surfaceText
|
||||
}
|
||||
|
||||
Row {
|
||||
width: parent.width
|
||||
spacing: Theme.spacingM
|
||||
|
||||
Column {
|
||||
width: (parent.width - Theme.spacingM * 2) / 3
|
||||
spacing: Theme.spacingXS
|
||||
|
||||
StyledText {
|
||||
text: "Name"
|
||||
font.pixelSize: Theme.fontSizeSmall
|
||||
color: Theme.surfaceVariantText
|
||||
}
|
||||
|
||||
DankTextField {
|
||||
id: nameField
|
||||
width: parent.width
|
||||
placeholderText: "Variant Name"
|
||||
}
|
||||
}
|
||||
|
||||
Column {
|
||||
width: (parent.width - Theme.spacingM * 2) / 3
|
||||
spacing: Theme.spacingXS
|
||||
|
||||
StyledText {
|
||||
text: "Icon"
|
||||
font.pixelSize: Theme.fontSizeSmall
|
||||
color: Theme.surfaceVariantText
|
||||
}
|
||||
|
||||
DankTextField {
|
||||
id: iconField
|
||||
width: parent.width
|
||||
placeholderText: "star"
|
||||
}
|
||||
}
|
||||
|
||||
Column {
|
||||
width: (parent.width - Theme.spacingM * 2) / 3
|
||||
spacing: Theme.spacingXS
|
||||
|
||||
StyledText {
|
||||
text: "Text"
|
||||
font.pixelSize: Theme.fontSizeSmall
|
||||
color: Theme.surfaceVariantText
|
||||
}
|
||||
|
||||
DankTextField {
|
||||
id: textField
|
||||
width: parent.width
|
||||
placeholderText: "Display Text"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DankButton {
|
||||
text: "Create Variant"
|
||||
iconName: "add"
|
||||
onClicked: {
|
||||
if (!nameField.text) {
|
||||
ToastService.showError("Please enter a variant name")
|
||||
return
|
||||
}
|
||||
|
||||
var variantConfig = {
|
||||
text: textField.text || nameField.text,
|
||||
icon: iconField.text || "widgets"
|
||||
}
|
||||
|
||||
createVariant(nameField.text, variantConfig)
|
||||
ToastService.showInfo("Variant created: " + nameField.text)
|
||||
|
||||
nameField.text = ""
|
||||
iconField.text = ""
|
||||
textField.text = ""
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
StyledRect {
|
||||
width: parent.width
|
||||
height: Math.max(200, variantsColumn.implicitHeight + Theme.spacingL * 2)
|
||||
radius: Theme.cornerRadius
|
||||
color: Theme.surfaceContainerHigh
|
||||
|
||||
Column {
|
||||
id: variantsColumn
|
||||
anchors.fill: parent
|
||||
anchors.margins: Theme.spacingL
|
||||
spacing: Theme.spacingM
|
||||
|
||||
StyledText {
|
||||
text: "Existing Variants"
|
||||
font.pixelSize: Theme.fontSizeMedium
|
||||
font.weight: Font.Medium
|
||||
color: Theme.surfaceText
|
||||
}
|
||||
|
||||
ListView {
|
||||
width: parent.width
|
||||
height: Math.max(100, contentHeight)
|
||||
clip: true
|
||||
spacing: Theme.spacingXS
|
||||
|
||||
model: ListModel {
|
||||
id: variantsModel
|
||||
}
|
||||
|
||||
delegate: StyledRect {
|
||||
required property var model
|
||||
width: ListView.view.width
|
||||
height: variantRow.implicitHeight + Theme.spacingM * 2
|
||||
radius: Theme.cornerRadius
|
||||
color: variantMouseArea.containsMouse ? Theme.surfaceContainerHighest : Theme.surfaceContainer
|
||||
|
||||
Row {
|
||||
id: variantRow
|
||||
anchors.fill: parent
|
||||
anchors.margins: Theme.spacingM
|
||||
spacing: Theme.spacingM
|
||||
|
||||
Item {
|
||||
width: Theme.iconSize
|
||||
height: Theme.iconSize
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
|
||||
DankIcon {
|
||||
anchors.centerIn: parent
|
||||
name: model.icon || "widgets"
|
||||
size: Theme.iconSize
|
||||
color: Theme.surfaceText
|
||||
width: Theme.iconSize
|
||||
height: Theme.iconSize
|
||||
clip: true
|
||||
}
|
||||
}
|
||||
|
||||
Column {
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
spacing: Theme.spacingXS
|
||||
width: parent.width - Theme.iconSize - deleteButton.width - Theme.spacingM * 4
|
||||
|
||||
StyledText {
|
||||
text: model.name || "Unnamed"
|
||||
font.pixelSize: Theme.fontSizeMedium
|
||||
color: Theme.surfaceText
|
||||
width: parent.width
|
||||
elide: Text.ElideRight
|
||||
}
|
||||
|
||||
StyledText {
|
||||
text: "Text: " + (model.text || "") + " | Icon: " + (model.icon || "")
|
||||
font.pixelSize: Theme.fontSizeSmall
|
||||
color: Theme.surfaceVariantText
|
||||
width: parent.width
|
||||
elide: Text.ElideRight
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: deleteButton
|
||||
width: 32
|
||||
height: 32
|
||||
radius: 16
|
||||
color: deleteArea.containsMouse ? Theme.error : "transparent"
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
|
||||
DankIcon {
|
||||
anchors.centerIn: parent
|
||||
name: "delete"
|
||||
size: 16
|
||||
color: deleteArea.containsMouse ? Theme.onError : Theme.surfaceVariantText
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
id: deleteArea
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
onClicked: {
|
||||
removeVariant(model.id)
|
||||
ToastService.showInfo("Variant removed: " + model.name)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
id: variantMouseArea
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
propagateComposedEvents: true
|
||||
}
|
||||
}
|
||||
|
||||
StyledText {
|
||||
anchors.centerIn: parent
|
||||
text: "No variants created yet"
|
||||
font.pixelSize: Theme.fontSizeSmall
|
||||
color: Theme.surfaceVariantText
|
||||
visible: variantsModel.count === 0
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
StyledRect {
|
||||
width: parent.width
|
||||
height: instructionsColumn.implicitHeight + Theme.spacingL * 2
|
||||
radius: Theme.cornerRadius
|
||||
color: Theme.surface
|
||||
|
||||
Column {
|
||||
id: instructionsColumn
|
||||
anchors.fill: parent
|
||||
anchors.margins: Theme.spacingL
|
||||
spacing: Theme.spacingM
|
||||
|
||||
Row {
|
||||
spacing: Theme.spacingM
|
||||
|
||||
DankIcon {
|
||||
name: "info"
|
||||
size: Theme.iconSize
|
||||
color: Theme.primary
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
}
|
||||
|
||||
StyledText {
|
||||
text: "How to Use Variants"
|
||||
font.pixelSize: Theme.fontSizeMedium
|
||||
font.weight: Font.Medium
|
||||
color: Theme.surfaceText
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
}
|
||||
}
|
||||
|
||||
StyledText {
|
||||
text: "1. Create variants with different names, icons, and text\n2. Go to Bar Settings and click 'Add Widget'\n3. Each variant will appear as a separate widget option\n4. Add variants to your bar just like any other widget"
|
||||
font.pixelSize: Theme.fontSizeSmall
|
||||
color: Theme.surfaceVariantText
|
||||
wrapMode: Text.WordWrap
|
||||
width: parent.width
|
||||
lineHeight: 1.4
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
57
PLUGINS/ExampleWithVariants/VariantWidget.qml
Normal file
57
PLUGINS/ExampleWithVariants/VariantWidget.qml
Normal file
@@ -0,0 +1,57 @@
|
||||
import QtQuick
|
||||
import qs.Common
|
||||
import qs.Services
|
||||
import qs.Widgets
|
||||
import qs.Modules.Plugins
|
||||
|
||||
PluginComponent {
|
||||
id: root
|
||||
|
||||
property string variantId: ""
|
||||
property var variantData: null
|
||||
|
||||
property string displayText: variantData?.text || "Default Text"
|
||||
property string displayIcon: variantData?.icon || "widgets"
|
||||
|
||||
horizontalBarPill: Component {
|
||||
Row {
|
||||
spacing: 3
|
||||
|
||||
DankIcon {
|
||||
name: root.displayIcon
|
||||
size: Theme.iconSize - 8
|
||||
color: Theme.surfaceText
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
}
|
||||
|
||||
StyledText {
|
||||
text: root.displayText
|
||||
font.pixelSize: Theme.fontSizeSmall
|
||||
font.weight: Font.Medium
|
||||
color: Theme.surfaceText
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
verticalBarPill: Component {
|
||||
Column {
|
||||
spacing: 1
|
||||
|
||||
DankIcon {
|
||||
name: root.displayIcon
|
||||
size: Theme.iconSize - 8
|
||||
color: Theme.surfaceText
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
}
|
||||
|
||||
StyledText {
|
||||
text: root.displayText
|
||||
font.pixelSize: Theme.fontSizeSmall
|
||||
font.weight: Font.Medium
|
||||
color: Theme.surfaceText
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
14
PLUGINS/ExampleWithVariants/plugin.json
Normal file
14
PLUGINS/ExampleWithVariants/plugin.json
Normal file
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"id": "exampleVariants",
|
||||
"name": "Example with Variants",
|
||||
"description": "Demonstrates dynamic variant creation for plugins",
|
||||
"version": "1.0.0",
|
||||
"author": "DMS",
|
||||
"icon": "widgets",
|
||||
"component": "./VariantWidget.qml",
|
||||
"settings": "./VariantSettings.qml",
|
||||
"permissions": [
|
||||
"settings_read",
|
||||
"settings_write"
|
||||
]
|
||||
}
|
||||
@@ -333,6 +333,93 @@ Singleton {
|
||||
return result
|
||||
}
|
||||
|
||||
function getPluginVariants(pluginId) {
|
||||
var plugin = availablePlugins[pluginId]
|
||||
if (!plugin) {
|
||||
return []
|
||||
}
|
||||
var variants = SettingsData.getPluginSetting(pluginId, "variants", [])
|
||||
return variants
|
||||
}
|
||||
|
||||
function getAllPluginVariants() {
|
||||
var result = []
|
||||
for (var pluginId in availablePlugins) {
|
||||
var plugin = availablePlugins[pluginId]
|
||||
if (plugin.type !== "widget") {
|
||||
continue
|
||||
}
|
||||
var variants = getPluginVariants(pluginId)
|
||||
if (variants.length === 0) {
|
||||
result.push({
|
||||
pluginId: pluginId,
|
||||
variantId: null,
|
||||
fullId: pluginId,
|
||||
name: plugin.name,
|
||||
icon: plugin.icon || "extension",
|
||||
description: plugin.description || "Plugin widget",
|
||||
loaded: plugin.loaded
|
||||
})
|
||||
} else {
|
||||
for (var i = 0; i < variants.length; i++) {
|
||||
var variant = variants[i]
|
||||
result.push({
|
||||
pluginId: pluginId,
|
||||
variantId: variant.id,
|
||||
fullId: pluginId + ":" + variant.id,
|
||||
name: plugin.name + " - " + variant.name,
|
||||
icon: variant.icon || plugin.icon || "extension",
|
||||
description: variant.description || plugin.description || "Plugin widget variant",
|
||||
loaded: plugin.loaded
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
function createPluginVariant(pluginId, variantName, variantConfig) {
|
||||
var variants = getPluginVariants(pluginId)
|
||||
var variantId = "variant_" + Date.now()
|
||||
var newVariant = Object.assign({}, variantConfig, {
|
||||
id: variantId,
|
||||
name: variantName
|
||||
})
|
||||
variants.push(newVariant)
|
||||
SettingsData.setPluginSetting(pluginId, "variants", variants)
|
||||
pluginDataChanged(pluginId)
|
||||
return variantId
|
||||
}
|
||||
|
||||
function removePluginVariant(pluginId, variantId) {
|
||||
var variants = getPluginVariants(pluginId)
|
||||
var newVariants = variants.filter(function(v) { return v.id !== variantId })
|
||||
SettingsData.setPluginSetting(pluginId, "variants", newVariants)
|
||||
pluginDataChanged(pluginId)
|
||||
}
|
||||
|
||||
function updatePluginVariant(pluginId, variantId, variantConfig) {
|
||||
var variants = getPluginVariants(pluginId)
|
||||
for (var i = 0; i < variants.length; i++) {
|
||||
if (variants[i].id === variantId) {
|
||||
variants[i] = Object.assign({}, variants[i], variantConfig)
|
||||
break
|
||||
}
|
||||
}
|
||||
SettingsData.setPluginSetting(pluginId, "variants", variants)
|
||||
pluginDataChanged(pluginId)
|
||||
}
|
||||
|
||||
function getPluginVariantData(pluginId, variantId) {
|
||||
var variants = getPluginVariants(pluginId)
|
||||
for (var i = 0; i < variants.length; i++) {
|
||||
if (variants[i].id === variantId) {
|
||||
return variants[i]
|
||||
}
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
function getLoadedPlugins() {
|
||||
var result = []
|
||||
for (var key in loadedPlugins) {
|
||||
|
||||
Reference in New Issue
Block a user