File indexing completed on 2025-02-02 04:11:25
0001 /* 0002 * SPDX-FileCopyrightText: 2019-2023 Mattia Basaglia <dev@dragon.best> 0003 * 0004 * SPDX-License-Identifier: GPL-3.0-or-later 0005 */ 0006 0007 #include "plugin_ui_dialog.hpp" 0008 0009 #include <QMetaObject> 0010 #include <QVBoxLayout> 0011 #include <QtUiTools/QUiLoader> 0012 #include <QDialogButtonBox> 0013 0014 #include "app/log/log.hpp" 0015 #include "app/application.hpp" 0016 0017 #include <QtColorWidgets/ColorSelector> 0018 #include <QtColorWidgets/color_2d_slider.hpp> 0019 #include <QtColorWidgets/ColorDialog> 0020 #include <QtColorWidgets/ColorListWidget> 0021 #include <QtColorWidgets/ColorPreview> 0022 #include <QtColorWidgets/ColorWheel> 0023 #include <QtColorWidgets/color_palette_widget.hpp> 0024 #include <QtColorWidgets/GradientEditor> 0025 #include <QtColorWidgets/GradientSlider> 0026 #include <QtColorWidgets/HueSlider> 0027 #include <QtColorWidgets/swatch.hpp> 0028 #include <QtColorWidgets/HarmonyColorWheel> 0029 0030 using namespace glaxnimate::gui; 0031 using namespace glaxnimate; 0032 0033 /** 0034 * On mac widgets created from the plugin don't work right, so we fake it... 0035 */ 0036 class ColoredUiLoader : public QUiLoader 0037 { 0038 public: 0039 using QUiLoader::QUiLoader; 0040 0041 QWidget* createWidget(const QString & className, QWidget * parent, const QString & name) override 0042 { 0043 if ( className.startsWith("color_widgets::") ) 0044 { 0045 auto it = ctors().find(className); 0046 if ( it != ctors().end() ) 0047 { 0048 QWidget* widget = it->second->create(parent); 0049 widget->setObjectName(name); 0050 return widget; 0051 0052 } 0053 } 0054 return QUiLoader::createWidget(className, parent, name); 0055 } 0056 0057 private: 0058 class CtorBase 0059 { 0060 public: 0061 virtual ~CtorBase() = default; 0062 virtual QWidget* create(QWidget* parent) const = 0; 0063 }; 0064 0065 template<class Wid> 0066 class Ctor : public CtorBase 0067 { 0068 public: 0069 QWidget* create(QWidget* parent) const override 0070 { 0071 return new Wid(parent); 0072 } 0073 0074 static std::pair<QString, std::unique_ptr<CtorBase>> pair() 0075 { 0076 return { 0077 Wid::staticMetaObject.className(), 0078 std::make_unique<Ctor>() 0079 }; 0080 } 0081 }; 0082 0083 static const std::map<QString, std::unique_ptr<CtorBase>>& ctors() 0084 { 0085 static std::map<QString, std::unique_ptr<CtorBase>> meta; 0086 if ( meta.empty() ) 0087 { 0088 meta.insert(Ctor<color_widgets::Color2DSlider>::pair()); 0089 meta.insert(Ctor<color_widgets::ColorSelector>::pair()); 0090 meta.insert(Ctor<color_widgets::ColorDialog>::pair()); 0091 meta.insert(Ctor<color_widgets::ColorListWidget>::pair()); 0092 meta.insert(Ctor<color_widgets::ColorPreview>::pair()); 0093 meta.insert(Ctor<color_widgets::ColorWheel>::pair()); 0094 meta.insert(Ctor<color_widgets::ColorPaletteWidget>::pair()); 0095 meta.insert(Ctor<color_widgets::GradientEditor>::pair()); 0096 meta.insert(Ctor<color_widgets::GradientSlider>::pair()); 0097 meta.insert(Ctor<color_widgets::HueSlider>::pair()); 0098 meta.insert(Ctor<color_widgets::Swatch>::pair()); 0099 meta.insert(Ctor<color_widgets::HarmonyColorWheel>::pair()); 0100 } 0101 0102 return meta; 0103 } 0104 }; 0105 0106 PluginUiDialog::PluginUiDialog(QIODevice& file, const plugin::Plugin& data, QWidget* parent) 0107 : QDialog(parent) 0108 { 0109 ColoredUiLoader loader; 0110 loader.setWorkingDirectory(data.data().dir); 0111 loader.setLanguageChangeEnabled(true); 0112 // for ( const auto& dir : app::Application::instance()->data_paths("lib") ) 0113 // loader.addPluginPath(dir); 0114 0115 QWidget* child = loader.load(&file, nullptr); 0116 if ( !child ) 0117 { 0118 data.logger().stream(app::log::Error) << "Could not load UI:" << loader.errorString(); 0119 return; 0120 } 0121 0122 if ( child->windowIcon().cacheKey() == qApp->windowIcon().cacheKey() ) 0123 setWindowIcon(data.icon()); 0124 else 0125 setWindowIcon(child->windowIcon()); 0126 0127 if ( child->windowTitle().isEmpty() ) 0128 setWindowTitle(data.data().name); 0129 else 0130 setWindowTitle(child->windowTitle()); 0131 0132 resize(child->size()); 0133 0134 setSizePolicy(child->sizePolicy()); 0135 0136 0137 if ( auto d = qobject_cast<QDialog*>(child) ) 0138 { 0139 child->setVisible(false); 0140 connect(this, &QObject::destroyed, child, &QObject::deleteLater); 0141 connect(d, &QDialog::accepted, this, &QDialog::accept); 0142 connect(d, &QDialog::rejected, this, &QDialog::reject); 0143 setLayout(child->layout()); 0144 } 0145 else 0146 { 0147 auto lay = new QVBoxLayout; 0148 setLayout(lay); 0149 lay->addWidget(child); 0150 auto box = new QDialogButtonBox(QDialogButtonBox::Ok|QDialogButtonBox::Cancel); 0151 lay->addWidget(box); 0152 connect(box, &QDialogButtonBox::accepted, this, &QDialog::accept); 0153 connect(box, &QDialogButtonBox::rejected, this, &QDialog::reject); 0154 } 0155 } 0156 0157 QVariant PluginUiDialog::get_value(const QString& widget, const QString& property) 0158 { 0159 QWidget* wid = findChild<QWidget*>(widget); 0160 if ( !wid ) 0161 return {}; 0162 0163 return wid->property(property.toStdString().c_str()); 0164 } 0165 0166 bool PluginUiDialog::set_value(const QString& widget, const QString& property, const QVariant& value) 0167 { 0168 QWidget* wid = findChild<QWidget*>(widget); 0169 if ( !wid ) 0170 return {}; 0171 0172 return wid->setProperty(property.toStdString().c_str(), value); 0173 }