diff --git a/OpenRGBPluginInterface.h b/OpenRGBPluginInterface.h index d0a23b0f..271277e3 100644 --- a/OpenRGBPluginInterface.h +++ b/OpenRGBPluginInterface.h @@ -14,16 +14,22 @@ #include #include -#define OpenRGBPluginInterface_IID "com.OpenRGBPluginInterface" +#define OpenRGBPluginInterface_IID "com.OpenRGBPluginInterface" + +#define OPENRGB_PLUGIN_API_VERSION 1 struct OpenRGBPluginInfo { - std::string PluginName; - std::string PluginDescription; - std::string PluginLocation; + std::string Name; + std::string Description; + std::string Version; + std::string Commit; + std::string URL; - bool HasCustom; - QLabel *PluginLabel; + std::string Location; + std::string Label; + + QImage Icon; }; class OpenRGBPluginInterface @@ -31,11 +37,18 @@ class OpenRGBPluginInterface public: virtual ~OpenRGBPluginInterface() {} - virtual OpenRGBPluginInfo Initialize(bool dark_theme, ResourceManager* resource_manager_ptr) = 0; + /*-------------------------------------------------------------------------------------------------*\ + | Plugin Information | + \*-------------------------------------------------------------------------------------------------*/ + virtual OpenRGBPluginInfo GetPluginInfo() = 0; + virtual unsigned int GetPluginAPIVersion() = 0; + /*-------------------------------------------------------------------------------------------------*\ + | Plugin Functionality | + \*-------------------------------------------------------------------------------------------------*/ + virtual void Initialize(bool dark_theme, ResourceManager* resource_manager_ptr) = 0; virtual QWidget *CreateGUI(QWidget* parent) = 0; - - OpenRGBPluginInfo info; + virtual void Unload() = 0; }; Q_DECLARE_INTERFACE(OpenRGBPluginInterface, OpenRGBPluginInterface_IID) diff --git a/PluginManager.cpp b/PluginManager.cpp index b8150fc0..b8a4c9e7 100644 --- a/PluginManager.cpp +++ b/PluginManager.cpp @@ -16,18 +16,27 @@ void PluginManager::ScanAndLoadPlugins() { LOG_INFO("Loading plugins"); + /*---------------------------------------------------------*\ + | Get the plugins directory | + | | + | The plugins directory is a directory named "plugins" in | + | the configuration directory | + \*---------------------------------------------------------*/ const QDir plugins_dir = QString().fromStdString(ResourceManager::get()->GetConfigurationDirectory()) + "plugins/"; + /*---------------------------------------------------------*\ + | Get a list of all files in the plugins directory | + \*---------------------------------------------------------*/ std::vector FileList; for(int i = 0; i < QDir(plugins_dir).entryList(QDir::Files).size(); i++) { - /*--------------------------------------*\ - | Add all of the Plugin Files to a list | - \*--------------------------------------*/ FileList.push_back(QDir(plugins_dir).entryList(QDir::Files)[i].toStdString()); } + /*---------------------------------------------------------*\ + | Attempt to load each file in the plugins directory | + \*---------------------------------------------------------*/ for(const std::string &plugin_name : FileList) { const std::string plugin_path = plugins_dir.absoluteFilePath(QString().fromStdString(plugin_name)).toStdString(); @@ -38,92 +47,127 @@ void PluginManager::ScanAndLoadPlugins() void PluginManager::LoadPlugin(std::string path) { - OpenRGBPluginInterface *OpenRGBPlugin = nullptr; + OpenRGBPluginInterface* plugin = nullptr; LOG_VERBOSE("Attempting to load: %s", path.c_str()); - QPluginLoader loader(QString().fromStdString(path)); + /*-----------------------------------------------------------------*\ + | Create a QPluginLoader and load the plugin | + \*-----------------------------------------------------------------*/ + QPluginLoader loader(QString().fromStdString(path)); + QObject* instance = loader.instance(); - if (QObject *instance = loader.instance()) + /*-----------------------------------------------------------------*\ + | Check that the plugin is valid, then check the API version | + \*-----------------------------------------------------------------*/ + if(instance) { - if ((OpenRGBPlugin = qobject_cast(instance))) + plugin = qobject_cast(instance); + + if(plugin) { - /*-----------------------------------------------------*\ - | Initialize the plugin | - \*-----------------------------------------------------*/ - OpenRGBPlugin->info = OpenRGBPlugin->Initialize(dark_theme, ResourceManager::get()); - - /*-----------------------------------------------------*\ - | Search the settings to see if it is enabled | - \*-----------------------------------------------------*/ - std::string name = ""; - std::string description = ""; - bool enabled = true; - bool found = false; - unsigned int plugin_ct = 0; - - /*-------------------------------------------------*\ - | Open device disable list and read in disabled | - | device strings | - \*-------------------------------------------------*/ - json plugin_settings = ResourceManager::get()->GetSettingsManager()->GetSettings("Plugins"); - - if(plugin_settings.contains("plugins")) + if(plugin->GetPluginAPIVersion() == OPENRGB_PLUGIN_API_VERSION) { - plugin_ct = plugin_settings["plugins"].size(); + /*-----------------------------------------------------*\ + | Get the plugin information | + \*-----------------------------------------------------*/ + OpenRGBPluginInfo info = plugin->GetPluginInfo(); - for(unsigned int plugin_idx = 0; plugin_idx < plugin_settings["plugins"].size(); plugin_idx++) + /*-----------------------------------------------------*\ + | Search the settings to see if it is enabled | + \*-----------------------------------------------------*/ + std::string name = ""; + std::string description = ""; + bool enabled = true; + bool found = false; + unsigned int plugin_ct = 0; + + /*-----------------------------------------------------*\ + | Open plugin list and check if plugin is in the list | + \*-----------------------------------------------------*/ + json plugin_settings = ResourceManager::get()->GetSettingsManager()->GetSettings("Plugins"); + + if(plugin_settings.contains("plugins")) { - if(plugin_settings["plugins"][plugin_idx].contains("name")) - { - name = plugin_settings["plugins"][plugin_idx]["name"]; - } + plugin_ct = plugin_settings["plugins"].size(); - if(plugin_settings["plugins"][plugin_idx].contains("description")) + for(unsigned int plugin_idx = 0; plugin_idx < plugin_settings["plugins"].size(); plugin_idx++) { - description = plugin_settings["plugins"][plugin_idx]["description"]; - } + if(plugin_settings["plugins"][plugin_idx].contains("name")) + { + name = plugin_settings["plugins"][plugin_idx]["name"]; + } - if(plugin_settings["plugins"][plugin_idx].contains("enabled")) - { - enabled = plugin_settings["plugins"][plugin_idx]["enabled"]; - } + if(plugin_settings["plugins"][plugin_idx].contains("description")) + { + description = plugin_settings["plugins"][plugin_idx]["description"]; + } - if((OpenRGBPlugin->info.PluginName == name) - &&(OpenRGBPlugin->info.PluginDescription == description)) - { - found = true; - break; + if(plugin_settings["plugins"][plugin_idx].contains("enabled")) + { + enabled = plugin_settings["plugins"][plugin_idx]["enabled"]; + } + + if((info.Name == name) + &&(info.Description == description)) + { + found = true; + break; + } } } - } - if(!found) - { - plugin_settings["plugins"][plugin_ct]["name"] = OpenRGBPlugin->info.PluginName; - plugin_settings["plugins"][plugin_ct]["description"] = OpenRGBPlugin->info.PluginDescription; - plugin_settings["plugins"][plugin_ct]["enabled"] = enabled; + /*-----------------------------------------------------*\ + | If the plugin was not in the list, add it to the list | + | and default it to enabled, then save the settings | + \*-----------------------------------------------------*/ + if(!found) + { + plugin_settings["plugins"][plugin_ct]["name"] = info.Name; + plugin_settings["plugins"][plugin_ct]["description"] = info.Description; + plugin_settings["plugins"][plugin_ct]["enabled"] = enabled; - ResourceManager::get()->GetSettingsManager()->SetSettings("Plugins", plugin_settings); - ResourceManager::get()->GetSettingsManager()->SaveSettings(); - } + ResourceManager::get()->GetSettingsManager()->SetSettings("Plugins", plugin_settings); + ResourceManager::get()->GetSettingsManager()->SaveSettings(); + } - LOG_VERBOSE("Loaded plugin %s", OpenRGBPlugin->info.PluginName.c_str()); + LOG_VERBOSE("Loaded plugin %s", info.Name.c_str()); - OpenRGBPluginEntry entry; + /*-----------------------------------------------------*\ + | Add the plugin to the PluginManager active plugins | + \*-----------------------------------------------------*/ + OpenRGBPluginEntry entry; - entry.plugin = OpenRGBPlugin; - entry.path = path; - entry.enabled = enabled; + entry.info = info; + entry.plugin = plugin; + entry.path = path; + entry.enabled = enabled; - PluginManager::ActivePlugins.push_back(entry); + PluginManager::ActivePlugins.push_back(entry); - /*-------------------------------------------------*\ - | Call the callbacks | - \*-------------------------------------------------*/ - for(unsigned int callback_idx = 0; callback_idx < AddPluginTabCallbacks.size(); callback_idx++) - { - AddPluginTabCallbacks[callback_idx](AddPluginTabCallbackArgs[callback_idx], OpenRGBPlugin); + /*-----------------------------------------------------*\ + | If the plugin is enabled, load it | + \*-----------------------------------------------------*/ + if(enabled) + { + /*-------------------------------------------------*\ + | Initialize the plugin | + \*-------------------------------------------------*/ + plugin->Initialize(dark_theme, ResourceManager::get()); + + /*-------------------------------------------------*\ + | Call the callbacks | + \*-------------------------------------------------*/ + for(unsigned int callback_idx = 0; callback_idx < AddPluginTabCallbacks.size(); callback_idx++) + { + AddPluginTabCallbacks[callback_idx](AddPluginTabCallbackArgs[callback_idx], entry); + } + } + else + { + delete instance; + loader.unload(); + } } } } diff --git a/PluginManager.h b/PluginManager.h index 27d64a6b..239f7976 100644 --- a/PluginManager.h +++ b/PluginManager.h @@ -13,12 +13,13 @@ typedef struct { + OpenRGBPluginInfo info; OpenRGBPluginInterface* plugin; std::string path; bool enabled; } OpenRGBPluginEntry; -typedef void (*AddPluginTabCallback)(void *, OpenRGBPluginInterface* plugin); +typedef void (*AddPluginTabCallback)(void *, OpenRGBPluginEntry plugin); class PluginManager { diff --git a/qt/OpenRGBDialog2.cpp b/qt/OpenRGBDialog2.cpp index 02dd7200..5745a26d 100644 --- a/qt/OpenRGBDialog2.cpp +++ b/qt/OpenRGBDialog2.cpp @@ -96,7 +96,7 @@ static void UpdateDetectionProgressCallback(void * this_ptr) QMetaObject::invokeMethod(this_obj, "onDetectionProgressUpdated", Qt::QueuedConnection); } -static void CreatePluginTabCallback(void * this_ptr, OpenRGBPluginInterface * plugin) +static void CreatePluginTabCallback(void * this_ptr, OpenRGBPluginEntry plugin) { OpenRGBDialog2 * this_obj = (OpenRGBDialog2 *)this_ptr; @@ -690,7 +690,7 @@ void OpenRGBDialog2::AddSerialSettingsPage() ui->SettingsTabBar->tabBar()->setTabButton(ui->SettingsTabBar->tabBar()->count() - 1, QTabBar::LeftSide, SettingsTabLabel); } -void OpenRGBDialog2::AddPluginTab(OpenRGBPluginInterface* plugin) +void OpenRGBDialog2::AddPluginTab(OpenRGBPluginEntry plugin) { /*-----------------------------------------------------*\ | Create Label for the Tab | @@ -701,41 +701,28 @@ void OpenRGBDialog2::AddPluginTab(OpenRGBPluginInterface* plugin) | If the plugin has custom information, use it, | | otherwise generate it | \*-----------------------------------------------------*/ - if(plugin->info.HasCustom) + QString PluginLabelString; + + if(IsDarkTheme()) { - PluginTabLabel = plugin->info.PluginLabel; + PluginLabelString = "plugin_dark.png"; } else { - QLabel *TabLabelText = plugin->info.PluginLabel; - QString PluginLabelString; - - if(IsDarkTheme()) - { - PluginLabelString = "plugin_dark.png"; - } - else - { - PluginLabelString = "plugin.png"; - } - - /*-----------------------------------------------------*\ - | Create the tab label | - \*-----------------------------------------------------*/ - PluginTabLabel = (QLabel*)new TabLabel(PluginLabelString, TabLabelText->text()); + PluginLabelString = "plugin.png"; } /*-----------------------------------------------------*\ - | Determine plugin location | + | Create the tab label | \*-----------------------------------------------------*/ - std::string Location = plugin->info.PluginLocation; + PluginTabLabel = (QLabel*)new TabLabel(PluginLabelString, QString::fromStdString(plugin.info.Label)); /*-----------------------------------------------------*\ | InformationTab - Place plugin in the Information tab | \*-----------------------------------------------------*/ - if(Location == "InformationTab") + if(plugin.info.Location == "InformationTab") { - QWidget* NewPluginTab = plugin->CreateGUI(this); + QWidget* NewPluginTab = plugin.plugin->CreateGUI(this); OpenRGBPluginContainer* NewPluginContainer = new OpenRGBPluginContainer(NewPluginTab); @@ -746,9 +733,9 @@ void OpenRGBDialog2::AddPluginTab(OpenRGBPluginInterface* plugin) /*-----------------------------------------------------*\ | DevicesTab - Place plugin in the Devices tab | \*-----------------------------------------------------*/ - else if(Location == "DevicesTab") + else if(plugin.info.Location == "DevicesTab") { - QWidget* NewPluginTab = plugin->CreateGUI(this); + QWidget* NewPluginTab = plugin.plugin->CreateGUI(this); OpenRGBPluginContainer* NewPluginContainer = new OpenRGBPluginContainer(NewPluginTab); @@ -759,20 +746,20 @@ void OpenRGBDialog2::AddPluginTab(OpenRGBPluginInterface* plugin) /*-----------------------------------------------------*\ | TopTabBar - Place plugin as its own top level tab | \*-----------------------------------------------------*/ - else if(Location == "TopTabBar") + else if(plugin.info.Location == "TopTabBar") { - QWidget* NewPluginTab = plugin->CreateGUI(this); + QWidget* NewPluginTab = plugin.plugin->CreateGUI(this); OpenRGBPluginContainer* NewPluginContainer = new OpenRGBPluginContainer(NewPluginTab); - ui->MainTabBar->addTab(NewPluginContainer,QString().fromStdString(plugin->info.PluginName)); + ui->MainTabBar->addTab(NewPluginContainer,QString().fromStdString(plugin.info.Label)); } /*-----------------------------------------------------*\ | SettingsTabBar - Place plugin in the Settings tab | \*-----------------------------------------------------*/ - else if(Location == "SettingsTabBar") + else if(plugin.info.Location == "SettingsTabBar") { - QWidget* NewPluginTab = plugin->CreateGUI(this); + QWidget* NewPluginTab = plugin.plugin->CreateGUI(this); OpenRGBPluginContainer* NewPluginContainer = new OpenRGBPluginContainer(NewPluginTab); @@ -786,7 +773,7 @@ void OpenRGBDialog2::AddPluginTab(OpenRGBPluginInterface* plugin) \*-----------------------------------------------------*/ else { - std::cout << ("Cannot load plugin '" + plugin->info.PluginName + "' as it does not specify a valid location: " + Location + "\n"); + std::cout << ("Cannot load plugin '" + plugin.info.Name + "' as it does not specify a valid location: " + plugin.info.Location + "\n"); } } diff --git a/qt/OpenRGBDialog2.h b/qt/OpenRGBDialog2.h index f434bf42..6880434f 100644 --- a/qt/OpenRGBDialog2.h +++ b/qt/OpenRGBDialog2.h @@ -45,7 +45,7 @@ public: void AddI2CToolsPage(); void AddServerTab(); - void AddPluginTab(OpenRGBPluginInterface* plugin); + void AddPluginTab(OpenRGBPluginEntry plugin); void setMode(unsigned char mode_val); diff --git a/qt/OpenRGBPluginsPage/OpenRGBPluginsEntry.ui b/qt/OpenRGBPluginsPage/OpenRGBPluginsEntry.ui index 4cce4923..18df12aa 100644 --- a/qt/OpenRGBPluginsPage/OpenRGBPluginsEntry.ui +++ b/qt/OpenRGBPluginsPage/OpenRGBPluginsEntry.ui @@ -6,8 +6,8 @@ 0 0 - 195 - 109 + 478 + 238 @@ -20,7 +20,28 @@ - + + + + Version: + + + + + + + + + + + + + + Path Value + + + + @@ -33,40 +54,7 @@ - - - - Enabled - - - - - - - 0 - 0 - - - - Name Value - - - - - - - - 0 - 0 - - - - Description - - - - @@ -79,24 +67,109 @@ - - + + + + + 0 + 0 + + - + Description: - - + + - Path + URL: + + + + + + + + 0 + 0 + + + + Name Value + + + + + + + Version Value + + + + + + + Commit Value - + - Path Value + Path: + + + + + + + Enabled + + + + + + + Commit: + + + + + + + URL Value + + + true + + + + + + + + 0 + 0 + + + + + 64 + 64 + + + + + 64 + 64 + + + + Icon + + + Qt::AlignCenter diff --git a/qt/OpenRGBPluginsPage/OpenRGBPluginsPage.cpp b/qt/OpenRGBPluginsPage/OpenRGBPluginsPage.cpp index e6e3657b..16d7e68e 100644 --- a/qt/OpenRGBPluginsPage/OpenRGBPluginsPage.cpp +++ b/qt/OpenRGBPluginsPage/OpenRGBPluginsPage.cpp @@ -1,5 +1,7 @@ #include #include +#include +#include #include "filesystem.h" #include "OpenRGBPluginsPage.h" @@ -29,22 +31,43 @@ void Ui::OpenRGBPluginsPage::RefreshList() { OpenRGBPluginsEntry* entry = new OpenRGBPluginsEntry(); - entry->ui->NameValue->setText(QString::fromStdString(plugin_manager->ActivePlugins[plugin_idx].plugin->info.PluginName)); - entry->ui->DescriptionValue->setText(QString::fromStdString(plugin_manager->ActivePlugins[plugin_idx].plugin->info.PluginDescription)); + /*---------------------------------------------------------*\ + | Fill in plugin information fields | + \*---------------------------------------------------------*/ + entry->ui->NameValue->setText(QString::fromStdString(plugin_manager->ActivePlugins[plugin_idx].info.Name)); + entry->ui->DescriptionValue->setText(QString::fromStdString(plugin_manager->ActivePlugins[plugin_idx].info.Description)); + entry->ui->VersionValue->setText(QString::fromStdString(plugin_manager->ActivePlugins[plugin_idx].info.Version)); + entry->ui->CommitValue->setText(QString::fromStdString(plugin_manager->ActivePlugins[plugin_idx].info.Commit)); + entry->ui->URLValue->setText(QString::fromStdString(plugin_manager->ActivePlugins[plugin_idx].info.URL)); + + /*---------------------------------------------------------*\ + | Fill in plugin icon | + \*---------------------------------------------------------*/ + QPixmap pixmap(QPixmap::fromImage(plugin_manager->ActivePlugins[plugin_idx].info.Icon)); + + entry->ui->IconView->setPixmap(pixmap); + entry->ui->IconView->setScaledContents(true); + + /*---------------------------------------------------------*\ + | Fill in plugin path | + \*---------------------------------------------------------*/ entry->ui->PathValue->setText(QString::fromStdString(plugin_manager->ActivePlugins[plugin_idx].path)); + + /*---------------------------------------------------------*\ + | Fill in plugin enabled status | + \*---------------------------------------------------------*/ entry->ui->EnabledCheckBox->setChecked((plugin_manager->ActivePlugins[plugin_idx].enabled)); - //TODO: Get plugin enable/disable working - // Until then, hide the enable checkbox - entry->ui->EnabledLabel->setVisible(false); - entry->ui->EnabledCheckBox->setVisible(false); - + /*---------------------------------------------------------*\ + | Add the entry to the plugin list | + \*---------------------------------------------------------*/ QListWidgetItem* item = new QListWidgetItem; item->setSizeHint(entry->sizeHint()); ui->PluginsList->addItem(item); ui->PluginsList->setItemWidget(item, entry); + entries.push_back(entry); } }