mirror of
https://github.com/ModOrganizer2/modorganizer-plugin_python.git
synced 2026-07-27 14:03:33 -07:00
Add bindings for TaskDialog.
This commit is contained in:
@@ -35,6 +35,7 @@ add_filter(NAME src/converters GROUPS
|
||||
add_filter(NAME src/runner GROUPS
|
||||
pythonrunner
|
||||
pylogger
|
||||
widgets
|
||||
)
|
||||
|
||||
add_filter(NAME src/utils GROUPS
|
||||
|
||||
@@ -66,6 +66,37 @@ namespace utils {
|
||||
|
||||
}
|
||||
|
||||
namespace Enum_converter {
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
template <typename Enum>
|
||||
struct Enum_to_int
|
||||
{
|
||||
static PyObject* convert(const Enum& flags) {
|
||||
return bpy::incref(bpy::object(static_cast<int>(flags)).ptr());
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Enum>
|
||||
struct Enum_from_python_obj
|
||||
{
|
||||
|
||||
static void* convertible(PyObject* objPtr) {
|
||||
return SIPLong_Check(objPtr) ? objPtr : nullptr;
|
||||
}
|
||||
|
||||
static void construct(PyObject* objPtr, bpy::converter::rvalue_from_python_stage1_data* data) {
|
||||
int intVersion = (int)SIPLong_AsLong(objPtr);
|
||||
void* storage = ((bpy::converter::rvalue_from_python_storage<Enum>*)data)->storage.bytes;
|
||||
new (storage) Enum(static_cast<Enum>(intVersion));
|
||||
data->convertible = storage;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
namespace QFlags_converter {
|
||||
|
||||
/**
|
||||
@@ -508,6 +539,16 @@ namespace utils {
|
||||
bpy::type_id<Flags>());
|
||||
}
|
||||
|
||||
template <class Enum>
|
||||
inline void register_enum_converter() {
|
||||
using namespace Enum_converter;
|
||||
bpy::to_python_converter<Enum, Enum_to_int<Enum>>();
|
||||
bpy::converter::registry::push_back(
|
||||
&Enum_from_python_obj<Enum>::convertible,
|
||||
&Enum_from_python_obj<Enum>::construct,
|
||||
bpy::type_id<Enum>());
|
||||
}
|
||||
|
||||
template <class QClass>
|
||||
inline void register_qclass_converter() {
|
||||
using Converter = QClass_converter::QClass_converters<QClass>;
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
#include <iplugintool.h>
|
||||
#include <iprofile.h>
|
||||
#include <log.h>
|
||||
#include <report.h>
|
||||
|
||||
#include "uibasewrappers.h"
|
||||
#include "proxypluginwrappers.h"
|
||||
@@ -41,6 +42,7 @@
|
||||
#include "converters.h"
|
||||
#include "shared_ptr_converter.h"
|
||||
#include "pylogger.h"
|
||||
#include "widgets.h"
|
||||
|
||||
using namespace MOBase;
|
||||
|
||||
@@ -86,6 +88,10 @@ BOOST_PYTHON_MODULE(mobase)
|
||||
utils::register_qflags_converter<IPluginGame::ProfileSettings>();
|
||||
utils::register_qflags_converter<IModList::ModStates>();
|
||||
|
||||
// Enums:
|
||||
utils::register_enum_converter<QMessageBox::StandardButton>();
|
||||
utils::register_enum_converter<QMessageBox::Icon>();
|
||||
|
||||
// Pointers:
|
||||
bpy::register_ptr_to_python<std::shared_ptr<FileTreeEntry>>();
|
||||
bpy::register_ptr_to_python<std::shared_ptr<const FileTreeEntry>>();
|
||||
@@ -116,6 +122,7 @@ BOOST_PYTHON_MODULE(mobase)
|
||||
utils::register_sequence_container<std::vector<std::shared_ptr<const IPluginRequirement>>>();
|
||||
utils::register_sequence_container<std::vector<ModDataContent::Content>>();
|
||||
utils::register_sequence_container<std::vector<Mapping>>();
|
||||
utils::register_sequence_container<std::vector<TaskDialogButton>>();
|
||||
|
||||
utils::register_set_container<std::set<QString>>();
|
||||
|
||||
@@ -132,6 +139,7 @@ BOOST_PYTHON_MODULE(mobase)
|
||||
bpy::register_tuple<std::tuple<bool, DWORD>>(); // IOrganizer::waitForApplication
|
||||
bpy::register_tuple<std::tuple<bool, bool>>(); // IProfile::invalidationActive
|
||||
bpy::register_tuple<std::tuple<IPluginInstaller::EInstallResult, std::shared_ptr<IFileTree>, QString, int>>();
|
||||
bpy::register_tuple<std::tuple<QString, QString>>();
|
||||
|
||||
// Variants:
|
||||
bpy::register_variant<std::variant<
|
||||
@@ -140,6 +148,7 @@ BOOST_PYTHON_MODULE(mobase)
|
||||
std::tuple<IPluginInstaller::EInstallResult, std::shared_ptr<IFileTree>, QString, int>>>();
|
||||
bpy::register_variant<std::variant<IFileTree::OverwritesType, std::size_t>>();
|
||||
bpy::register_variant<std::variant<QString, bool>>();
|
||||
bpy::register_variant<std::variant<QString, std::tuple<QString, QString>>>();
|
||||
|
||||
// Functions:
|
||||
utils::register_functor_converter<void()>(); // converter for the onRefreshed-callback
|
||||
@@ -1088,6 +1097,13 @@ BOOST_PYTHON_MODULE(mobase)
|
||||
bpy::def("getProductVersion", &MOBase::getProductVersion, bpy::arg("executable"));
|
||||
bpy::def("getIconForExecutable", &MOBase::iconForExecutable, bpy::arg("executable"));
|
||||
|
||||
bpy::object widgets(bpy::borrowed(PyImport_AddModule("mobase.widgets")));
|
||||
bpy::scope().attr("widgets") = widgets;
|
||||
{
|
||||
bpy::scope w_ = widgets;
|
||||
register_widgets();
|
||||
}
|
||||
|
||||
// Expose MoVariant: MoVariant is a fake object whose only purpose is to be used as a type-hint
|
||||
// on the python side (e.g., def foo(x: mobase.MoVariant)). The real MoVariant is defined in the
|
||||
// generated stubs, since it's only relevant when doing type-checking, but this needs to be defined,
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
#include "widgets.h"
|
||||
|
||||
#include <variant>
|
||||
|
||||
#include <boost/python.hpp>
|
||||
|
||||
#include "report.h"
|
||||
#include "variant_helper.h"
|
||||
|
||||
namespace bpy = boost::python;
|
||||
|
||||
using namespace MOBase;
|
||||
|
||||
void register_widgets() {
|
||||
|
||||
// TaskDialog is also in Windows System.
|
||||
using TaskDialog = MOBase::TaskDialog;
|
||||
|
||||
// TaskDialog
|
||||
bpy::class_<TaskDialogButton>("TaskDialogButton", bpy::no_init)
|
||||
.def(bpy::init<QString, QString, QMessageBox::StandardButton>((bpy::arg("text"), bpy::arg("description"), bpy::arg("button"))))
|
||||
.def(bpy::init<QString, QMessageBox::StandardButton>((bpy::arg("text"), bpy::arg("button"))));
|
||||
|
||||
bpy::class_<TaskDialog, TaskDialog*, boost::noncopyable>("TaskDialog", bpy::no_init)
|
||||
.def("__init__", bpy::make_constructor(+[](
|
||||
QWidget* parent, QString const& title, QString const& main,
|
||||
QString const& content, QString const& details, QMessageBox::Icon icon,
|
||||
std::vector<TaskDialogButton> const& buttons,
|
||||
std::variant<QString, std::tuple<QString, QString>> const& remember) {
|
||||
auto* dialog = new TaskDialog(parent, title);
|
||||
dialog->main(main).content(content).details(details).icon(icon);
|
||||
|
||||
for (auto& button : buttons) {
|
||||
dialog->button(button);
|
||||
}
|
||||
|
||||
std::visit([dialog](auto const& item) {
|
||||
QString action, file;
|
||||
if constexpr (std::is_same_v<std::decay_t<decltype(item)>, QString>) {
|
||||
action = item;
|
||||
}
|
||||
else {
|
||||
action = std::get<0>(item);
|
||||
file = std::get<1>(item);
|
||||
}
|
||||
dialog->remember(action, file);
|
||||
}, remember);
|
||||
|
||||
return dialog;
|
||||
}, bpy::default_call_policies(),
|
||||
(bpy::arg("parent") = (QWidget*)nullptr, bpy::arg("title") = "", bpy::arg("main") = "", bpy::arg("content") = "",
|
||||
bpy::arg("details") = "", bpy::arg("icon") = QMessageBox::NoIcon, bpy::arg("buttons") = std::vector<TaskDialogButton>{},
|
||||
bpy::arg("remember") = "")))
|
||||
.def("setTitle", &TaskDialog::title, bpy::return_self<>(), bpy::arg("title"))
|
||||
.def("setMain", &TaskDialog::main, bpy::return_self<>(), bpy::arg("main"))
|
||||
.def("setContent", &TaskDialog::content, bpy::return_self<>(), bpy::arg("content"))
|
||||
.def("setDetails", &TaskDialog::details, bpy::return_self<>(), bpy::arg("details"))
|
||||
.def("setIcon", &TaskDialog::icon, bpy::return_self<>(), bpy::arg("icon"))
|
||||
.def("addButton", &TaskDialog::button, bpy::return_self<>(), bpy::arg("button"))
|
||||
.def("setRemember", &TaskDialog::remember, bpy::return_self<>(), (bpy::arg("action"), bpy::arg("file") = ""))
|
||||
.def("setWidth", &TaskDialog::setWidth, bpy::arg("widget"))
|
||||
.def("addContent", &TaskDialog::addContent, bpy::arg("widget"))
|
||||
.def("exec", &TaskDialog::exec)
|
||||
;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
#ifndef PYTHON_WIDGETS_HPP
|
||||
#define PYTHON_WIDGETS_HPP
|
||||
|
||||
/**
|
||||
* @brief Register uibase widgets in the current scope.
|
||||
*/
|
||||
void register_widgets();
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user