Working on splash rendering

This commit is contained in:
Brad Davis 2018-04-04 13:33:37 -07:00
parent a0e1d2e54e
commit d478204722
8 changed files with 302 additions and 186 deletions

View file

@ -1266,9 +1266,32 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo
// Make sure the window is set to the correct size by processing the pending events
QCoreApplication::processEvents();
_glWidget->createContext();
_glWidget->makeCurrent();
// Create the main thread context, the GPU backend, and the display plugins
initializeGL();
qCDebug(interfaceapp, "Initialized Display.");
// Create the rendering engine. This can be slow on some machines due to lots of
// GPU pipeline creation.
initializeRenderEngine();
qCDebug(interfaceapp, "Initialized Render Engine.");
// Initialize the user interface and menu system
// Needs to happen AFTER the render engine initialization to access its configuration
initializeUi();
init();
qCDebug(interfaceapp, "init() complete.");
// create thread for parsing of octree data independent of the main network and rendering threads
_octreeProcessor.initialize(_enableProcessOctreeThread);
connect(&_octreeProcessor, &OctreePacketProcessor::packetVersionMismatch, this, &Application::notifyPacketVersionMismatch);
_entityEditSender.initialize(_enableProcessOctreeThread);
_idleLoopStdev.reset();
// update before the first render
update(0);
// Make sure we don't time out during slow operations at startup
updateHeartbeat();
@ -2430,48 +2453,47 @@ void Application::initializeGL() {
_isGLInitialized = true;
}
// Build a shared canvas / context for the Chromium processes
_glWidget->makeCurrent();
glClearColor(0.2f, 0.2f, 0.2f, 1);
glClear(GL_COLOR_BUFFER_BIT);
_glWidget->swapBuffers();
#if !defined(DISABLE_QML)
// Chromium rendering uses some GL functions that prevent nSight from capturing
// frames, so we only create the shared context if nsight is NOT active.
if (!nsightActive()) {
_chromiumShareContext = new OffscreenGLCanvas();
_chromiumShareContext->setObjectName("ChromiumShareContext");
_chromiumShareContext->create(_glWidget->qglContext());
_chromiumShareContext->makeCurrent();
if (!_chromiumShareContext->makeCurrent()) {
qCWarning(interfaceapp, "Unable to make chromium shared context current");
}
qt_gl_set_global_share_context(_chromiumShareContext->getContext());
} else {
qCWarning(interfaceapp) << "nSIGHT detected, disabling chrome rendering";
// Build an offscreen GL context for the main thread.
_offscreenContext = new OffscreenGLCanvas();
_offscreenContext->setObjectName("MainThreadContext");
_offscreenContext->create(_glWidget->qglContext());
if (!_offscreenContext->makeCurrent()) {
qFatal("Unable to make offscreen context current");
}
#endif
_offscreenContext->doneCurrent();
_offscreenContext->setThreadContext();
// Build a shared canvas / context for the QML rendering
_glWidget->makeCurrent();
_qmlShareContext = new OffscreenGLCanvas();
_qmlShareContext->setObjectName("QmlShareContext");
_qmlShareContext->create(_glWidget->qglContext());
if (!_qmlShareContext->makeCurrent()) {
qCWarning(interfaceapp, "Unable to make QML shared context current");
// Move the GL widget context to the render event handler thread
_renderEventHandler = new RenderEventHandler(_glWidget->qglContext());
if (!_offscreenContext->makeCurrent()) {
qFatal("Unable to make offscreen context current");
}
OffscreenQmlSurface::setSharedContext(_qmlShareContext->getContext());
_qmlShareContext->doneCurrent();
// Create the GPU backend
// Requires the window context, because that's what's used in the actual rendering
// and the GPU backend will make things like the VAO which cannot be shared across
// contexts
_glWidget->makeCurrent();
gpu::Context::init<gpu::gl::GLBackend>();
qApp->setProperty(hifi::properties::gl::MAKE_PROGRAM_CALLBACK,
QVariant::fromValue((void*)(&gpu::gl::GLBackend::makeProgram)));
_gpuContext = std::make_shared<gpu::Context>();
// The gpu context can make child contexts for transfers, so
// we need to restore primary rendering context
_glWidget->makeCurrent();
_gpuContext = std::make_shared<gpu::Context>();
initDisplay();
qCDebug(interfaceapp, "Initialized Display.");
// Restore the default main thread context
_offscreenContext->makeCurrent();
updateDisplayMode();
}
void Application::initializeRenderEngine() {
_offscreenContext->makeCurrent();
// FIXME: on low end systems os the shaders take up to 1 minute to compile, so we pause the deadlock watchdog thread.
DeadlockWatchdogThread::withPause([&] {
@ -2488,66 +2510,44 @@ void Application::initializeGL() {
// Now that OpenGL is initialized, we are sure we have a valid context and can create the various pipeline shaders with success.
DependencyManager::get<GeometryCache>()->initializeShapePipelines();
});
_offscreenContext = new OffscreenGLCanvas();
_offscreenContext->setObjectName("MainThreadContext");
_offscreenContext->create(_glWidget->qglContext());
if (!_offscreenContext->makeCurrent()) {
qFatal("Unable to make offscreen context current");
}
_offscreenContext->doneCurrent();
_offscreenContext->setThreadContext();
_renderEventHandler = new RenderEventHandler(_glWidget->qglContext());
// The UI can't be created until the primary OpenGL
// context is created, because it needs to share
// texture resources
// Needs to happen AFTER the render engine initialization to access its configuration
if (!_offscreenContext->makeCurrent()) {
qFatal("Unable to make offscreen context current");
}
initializeUi();
qCDebug(interfaceapp, "Initialized Offscreen UI.");
if (!_offscreenContext->makeCurrent()) {
qFatal("Unable to make offscreen context current");
}
init();
qCDebug(interfaceapp, "init() complete.");
// create thread for parsing of octree data independent of the main network and rendering threads
_octreeProcessor.initialize(_enableProcessOctreeThread);
connect(&_octreeProcessor, &OctreePacketProcessor::packetVersionMismatch, this, &Application::notifyPacketVersionMismatch);
_entityEditSender.initialize(_enableProcessOctreeThread);
_idleLoopStdev.reset();
// Restore the primary GL content for the main thread
if (!_offscreenContext->makeCurrent()) {
qFatal("Unable to make offscreen context current");
}
// update before the first render
update(0);
}
extern void setupPreferences();
void Application::initializeUi() {
// Build a shared canvas / context for the Chromium processes
#if !defined(DISABLE_QML)
// Chromium rendering uses some GL functions that prevent nSight from capturing
// frames, so we only create the shared context if nsight is NOT active.
if (!nsightActive()) {
_chromiumShareContext = new OffscreenGLCanvas();
_chromiumShareContext->setObjectName("ChromiumShareContext");
_chromiumShareContext->create(_offscreenContext->getContext());
if (!_chromiumShareContext->makeCurrent()) {
qCWarning(interfaceapp, "Unable to make chromium shared context current");
}
qt_gl_set_global_share_context(_chromiumShareContext->getContext());
_chromiumShareContext->doneCurrent();
// Restore the GL widget context
_offscreenContext->makeCurrent();
} else {
qCWarning(interfaceapp) << "nSIGHT detected, disabling chrome rendering";
}
#endif
// Build a shared canvas / context for the QML rendering
_qmlShareContext = new OffscreenGLCanvas();
_qmlShareContext->setObjectName("QmlShareContext");
_qmlShareContext->create(_offscreenContext->getContext());
if (!_qmlShareContext->makeCurrent()) {
qCWarning(interfaceapp, "Unable to make QML shared context current");
}
OffscreenQmlSurface::setSharedContext(_qmlShareContext->getContext());
_qmlShareContext->doneCurrent();
// Restore the GL widget context
_offscreenContext->makeCurrent();
// Make sure all QML surfaces share the main thread GL context
OffscreenQmlSurface::setSharedContext(_offscreenContext->getContext());
OffscreenQmlSurface::addWhitelistContextHandler(QUrl{ "OverlayWindowTest.qml" },
[](QQmlContext* context) {
qDebug() << "Whitelist OverlayWindow worked";
context->setContextProperty("OverlayWindowTestString", "TestWorked");
});
OffscreenQmlSurface::addWhitelistContextHandler(QUrl{ "hifi/audio/Audio.qml" },
[](QQmlContext* context) {
qDebug() << "QQQ" << __FUNCTION__ << "Whitelist Audio worked";
});
AddressBarDialog::registerType();
ErrorDialog::registerType();
@ -2650,6 +2650,10 @@ void Application::initializeUi() {
auto offscreenSurfaceCache = DependencyManager::get<OffscreenQmlSurfaceCache>();
offscreenSurfaceCache->reserve(TabletScriptingInterface::QML, 1);
offscreenSurfaceCache->reserve(Web3DOverlay::QML, 2);
// Now that the menu is instantiated, ensure the display plugin menu is properly updated
updateDisplayMode();
flushMenuUpdates();
}
@ -4607,11 +4611,8 @@ QVector<EntityItemID> Application::pasteEntities(float x, float y, float z) {
return _entityClipboard->sendEntities(&_entityEditSender, getEntities()->getTree(), x, y, z);
}
void Application::initDisplay() {
}
void Application::init() {
_offscreenContext->makeCurrent();
// Make sure Login state is up to date
DependencyManager::get<DialogsManager>()->toggleLoginDialog();
if (!DISABLE_DEFERRED) {
@ -7500,21 +7501,34 @@ void Application::updateDisplayMode() {
qFatal("Attempted to switch display plugins from a non-main thread");
}
auto menu = Menu::getInstance();
auto displayPlugins = PluginManager::getInstance()->getDisplayPlugins();
// Once time initialization code
static std::once_flag once;
std::call_once(once, [&] {
bool first = true;
// first sort the plugins into groupings: standard, advanced, developer
DisplayPluginList standard;
DisplayPluginList advanced;
DisplayPluginList developer;
foreach(auto displayPlugin, displayPlugins) {
displayPlugin->setContext(_gpuContext);
auto grouping = displayPlugin->getGrouping();
switch (grouping) {
QObject::connect(displayPlugin.get(), &DisplayPlugin::recommendedFramebufferSizeChanged,
[this](const QSize& size) { resizeGL(); });
QObject::connect(displayPlugin.get(), &DisplayPlugin::resetSensorsRequested, this, &Application::requestReset);
}
});
// Once time initialization code that depends on the UI being available
auto menu = Menu::getInstance();
if (menu) {
static std::once_flag onceUi;
std::call_once(onceUi, [&] {
bool first = true;
// first sort the plugins into groupings: standard, advanced, developer
DisplayPluginList standard;
DisplayPluginList advanced;
DisplayPluginList developer;
foreach(auto displayPlugin, displayPlugins) {
displayPlugin->setContext(_gpuContext);
auto grouping = displayPlugin->getGrouping();
switch (grouping) {
case Plugin::ADVANCED:
advanced.push_back(displayPlugin);
break;
@ -7524,42 +7538,40 @@ void Application::updateDisplayMode() {
default:
standard.push_back(displayPlugin);
break;
}
}
}
// concatenate the groupings into a single list in the order: standard, advanced, developer
standard.insert(std::end(standard), std::begin(advanced), std::end(advanced));
standard.insert(std::end(standard), std::begin(developer), std::end(developer));
// concatenate the groupings into a single list in the order: standard, advanced, developer
standard.insert(std::end(standard), std::begin(advanced), std::end(advanced));
standard.insert(std::end(standard), std::begin(developer), std::end(developer));
foreach(auto displayPlugin, standard) {
addDisplayPluginToMenu(displayPlugin, first);
auto displayPluginName = displayPlugin->getName();
QObject::connect(displayPlugin.get(), &DisplayPlugin::recommendedFramebufferSizeChanged, [this](const QSize & size) {
resizeGL();
});
QObject::connect(displayPlugin.get(), &DisplayPlugin::resetSensorsRequested, this, &Application::requestReset);
first = false;
}
foreach(auto displayPlugin, standard) {
addDisplayPluginToMenu(displayPlugin, first);
first = false;
}
// after all plugins have been added to the menu, add a separator to the menu
auto menu = Menu::getInstance();
auto parent = menu->getMenu(MenuOption::OutputMenu);
parent->addSeparator();
});
// after all plugins have been added to the menu, add a separator to the menu
auto parent = menu->getMenu(MenuOption::OutputMenu);
parent->addSeparator();
});
}
// Default to the first item on the list, in case none of the menu items match
DisplayPluginPointer newDisplayPlugin = displayPlugins.at(0);
foreach(DisplayPluginPointer displayPlugin, PluginManager::getInstance()->getDisplayPlugins()) {
QString name = displayPlugin->getName();
QAction* action = menu->getActionForOption(name);
// Menu might have been removed if the display plugin lost
if (!action) {
continue;
}
if (action->isChecked()) {
newDisplayPlugin = displayPlugin;
break;
if (menu) {
foreach(DisplayPluginPointer displayPlugin, PluginManager::getInstance()->getDisplayPlugins()) {
QString name = displayPlugin->getName();
QAction* action = menu->getActionForOption(name);
// Menu might have been removed if the display plugin lost
if (!action) {
continue;
}
if (action->isChecked()) {
newDisplayPlugin = displayPlugin;
break;
}
}
}
@ -7567,8 +7579,13 @@ void Application::updateDisplayMode() {
return;
}
setDisplayPlugin(newDisplayPlugin);
}
void Application::setDisplayPlugin(DisplayPluginPointer newDisplayPlugin) {
auto offscreenUi = DependencyManager::get<OffscreenUi>();
auto desktop = offscreenUi->getDesktop();
auto menu = Menu::getInstance();
// Make the switch atomic from the perspective of other threads
{
@ -7589,6 +7606,8 @@ void Application::updateDisplayMode() {
bool active = newDisplayPlugin->activate();
if (!active) {
auto displayPlugins = PluginManager::getInstance()->getDisplayPlugins();
// If the new plugin fails to activate, fallback to last display
qWarning() << "Failed to activate display: " << newDisplayPlugin->getName();
newDisplayPlugin = oldDisplayPlugin;
@ -7609,13 +7628,6 @@ void Application::updateDisplayMode() {
if (!active) {
qFatal("Failed to activate fallback plugin");
}
// We've changed the selection - it should be reflected in the menu
QAction* action = menu->getActionForOption(newDisplayPlugin->getName());
if (!action) {
qFatal("Failed to find activated plugin");
}
action->setChecked(true);
}
offscreenUi->resize(fromGlm(newDisplayPlugin->getRecommendedUiSize()));
@ -7642,14 +7654,21 @@ void Application::updateDisplayMode() {
getMyAvatar()->reset(false);
// switch to first person if entering hmd and setting is checked
if (isHmd && menu->isOptionChecked(MenuOption::FirstPersonHMD)) {
menu->setIsOptionChecked(MenuOption::FirstPerson, true);
cameraMenuChanged();
}
if (menu) {
QAction* action = menu->getActionForOption(newDisplayPlugin->getName());
if (action) {
action->setChecked(true);
}
// Remove the mirror camera option from menu if in HMD mode
auto mirrorAction = menu->getActionForOption(MenuOption::FullscreenMirror);
mirrorAction->setVisible(!isHmd);
if (isHmd && menu->isOptionChecked(MenuOption::FirstPersonHMD)) {
menu->setIsOptionChecked(MenuOption::FirstPerson, true);
cameraMenuChanged();
}
// Remove the mirror camera option from menu if in HMD mode
auto mirrorAction = menu->getActionForOption(MenuOption::FullscreenMirror);
mirrorAction->setVisible(!isHmd);
}
Q_ASSERT_X(_displayPlugin, "Application::updateDisplayMode", "could not find an activated display plugin");
}
@ -7725,15 +7744,18 @@ void Application::unresponsiveApplication() {
}
void Application::setActiveDisplayPlugin(const QString& pluginName) {
auto menu = Menu::getInstance();
foreach(DisplayPluginPointer displayPlugin, PluginManager::getInstance()->getDisplayPlugins()) {
DisplayPluginPointer newDisplayPlugin;
for (DisplayPluginPointer displayPlugin : PluginManager::getInstance()->getDisplayPlugins()) {
QString name = displayPlugin->getName();
QAction* action = menu->getActionForOption(name);
if (pluginName == name) {
action->setChecked(true);
newDisplayPlugin = displayPlugin;
break;
}
}
updateDisplayMode();
if (newDisplayPlugin) {
setDisplayPlugin(newDisplayPlugin);
}
}
void Application::handleLocalServerConnection() const {

View file

@ -145,6 +145,7 @@ public:
Q_INVOKABLE QString getUserAgent();
void initializeGL();
void initializeRenderEngine();
void initializeUi();
void updateCamera(RenderArgs& renderArgs, float deltaTime);
@ -437,6 +438,7 @@ private slots:
static void packetSent(quint64 length);
static void addingEntityWithCertificate(const QString& certificateID, const QString& placeName);
void updateDisplayMode();
void setDisplayPlugin(DisplayPluginPointer newPlugin);
void domainConnectionRefused(const QString& reasonMessage, int reason, const QString& extraInfo);
void addAssetToWorldCheckModelSize();
@ -449,7 +451,6 @@ private slots:
void switchDisplayMode();
private:
static void initDisplay();
void init();
bool handleKeyEventForFocusedEntityOrOverlay(QEvent* event);
bool handleFileOpenEvent(QFileOpenEvent* event);

View file

@ -56,10 +56,8 @@ glm::mat4 StereoDisplayPlugin::getEyeProjection(Eye eye, const glm::mat4& basePr
static const QString FRAMERATE = DisplayPlugin::MENU_PATH() + ">Framerate";
std::vector<QAction*> _screenActions;
bool StereoDisplayPlugin::internalActivate() {
auto screens = qApp->screens();
_screenActions.resize(screens.size());
for (int i = 0; i < screens.size(); ++i) {
auto screen = screens.at(i);
QString name = QString("Screen %1: %2").arg(i + 1).arg(screen->name());
@ -67,9 +65,9 @@ bool StereoDisplayPlugin::internalActivate() {
if (screen == qApp->primaryScreen()) {
checked = true;
}
auto action = _container->addMenuItem(PluginType::DISPLAY_PLUGIN, MENU_PATH(), name,
[this](bool clicked) { updateScreen(); }, true, checked, "Screens");
_screenActions[i] = action;
const uint32_t screenIndex = i;
_container->addMenuItem(PluginType::DISPLAY_PLUGIN, MENU_PATH(), name,
[=](bool clicked) { updateScreen(screenIndex); }, true, checked, "Screens");
}
_container->removeMenu(FRAMERATE);
@ -80,18 +78,12 @@ bool StereoDisplayPlugin::internalActivate() {
return Parent::internalActivate();
}
void StereoDisplayPlugin::updateScreen() {
for (uint32_t i = 0; i < _screenActions.size(); ++i) {
if (_screenActions[i]->isChecked()) {
_screen = qApp->screens().at(i);
_container->setFullscreen(_screen);
break;
}
}
void StereoDisplayPlugin::updateScreen(uint32_t i) {
_screen = qApp->screens().at(i);
_container->setFullscreen(_screen);
}
void StereoDisplayPlugin::internalDeactivate() {
_screenActions.clear();
_container->unsetFullscreen();
Parent::internalDeactivate();
}

View file

@ -31,7 +31,7 @@ public:
protected:
virtual bool internalActivate() override;
virtual void internalDeactivate() override;
void updateScreen();
void updateScreen(uint32_t i);
float _ipd{ 0.064f };
QScreen* _screen;

View file

@ -72,6 +72,10 @@ void GLWidget::createContext() {
_context->doneCurrent();
}
void GLWidget::swapBuffers() {
_context->swapBuffers();
}
bool GLWidget::makeCurrent() {
gl::Context::makeCurrent(_context->qglContext(), windowHandle());
return _context->makeCurrent();

View file

@ -32,6 +32,7 @@ public:
void createContext();
bool makeCurrent();
void doneCurrent();
void swapBuffers();
gl::Context* context() { return _context; }
QOpenGLContext* qglContext();

View file

@ -34,48 +34,140 @@ PluginContainer::~PluginContainer() {
INSTANCE = nullptr;
};
struct MenuCache {
QSet<QString> menus;
struct Item {
QString path;
std::function<void(bool)> onClicked;
bool checkable;
bool checked;
QString groupName;
};
QHash<QString, Item> items;
std::map<QString, QActionGroup*> _exclusiveGroups;
void addMenu(ui::Menu* menu, const QString& menuName) {
if (!menu) {
menus.insert(menuName);
return;
}
flushCache(menu);
menu->addMenu(menuName);
}
void removeMenu(ui::Menu* menu, const QString& menuName) {
if (!menu) {
menus.remove(menuName);
return;
}
flushCache(menu);
menu->removeMenu(menuName);
}
void addMenuItem(ui::Menu* menu, const QString& path, const QString& name, std::function<void(bool)> onClicked, bool checkable, bool checked, const QString& groupName) {
if (!menu) {
items[name] = Item{ path, onClicked, checkable, checked, groupName };
return;
}
flushCache(menu);
MenuWrapper* parentItem = menu->getMenu(path);
QAction* action = menu->addActionToQMenuAndActionHash(parentItem, name);
if (!groupName.isEmpty()) {
QActionGroup* group{ nullptr };
if (!_exclusiveGroups.count(groupName)) {
group = _exclusiveGroups[groupName] = new QActionGroup(menu);
group->setExclusive(true);
} else {
group = _exclusiveGroups[groupName];
}
group->addAction(action);
}
QObject::connect(action, &QAction::triggered, [=] {
onClicked(action->isChecked());
});
action->setCheckable(checkable);
action->setChecked(checked);
}
void removeMenuItem(ui::Menu* menu, const QString& menuName, const QString& menuItemName) {
if (!menu) {
items.remove(menuItemName);
return;
}
flushCache(menu);
menu->removeMenuItem(menuName, menuItemName);
}
bool isOptionChecked(ui::Menu* menu, const QString& name) {
if (!menu) {
return items.contains(name) && items[name].checked;
}
flushCache(menu);
return menu->isOptionChecked(name);
}
void setIsOptionChecked(ui::Menu* menu, const QString& name, bool checked) {
if (!menu) {
if (items.contains(name)) {
items[name].checked = checked;
}
return;
}
flushCache(menu);
}
void flushCache(ui::Menu* menu) {
if (!menu) {
return;
}
static bool flushed = false;
if (flushed) {
return;
}
flushed = true;
for (const auto& menuName : menus) {
addMenu(menu, menuName);
}
menus.clear();
for (const auto& menuItemName : items.keys()) {
const auto menuItem = items[menuItemName];
addMenuItem(menu, menuItem.path, menuItemName, menuItem.onClicked, menuItem.checkable, menuItem.checked, menuItem.groupName);
}
items.clear();
}
};
static MenuCache& getMenuCache() {
static MenuCache cache;
return cache;
}
void PluginContainer::addMenu(const QString& menuName) {
getPrimaryMenu()->addMenu(menuName);
getMenuCache().addMenu(getPrimaryMenu(), menuName);
}
void PluginContainer::removeMenu(const QString& menuName) {
getPrimaryMenu()->removeMenu(menuName);
getMenuCache().removeMenu(getPrimaryMenu(), menuName);
}
QAction* PluginContainer::addMenuItem(PluginType type, const QString& path, const QString& name, std::function<void(bool)> onClicked, bool checkable, bool checked, const QString& groupName) {
auto menu = getPrimaryMenu();
MenuWrapper* parentItem = menu->getMenu(path);
QAction* action = menu->addActionToQMenuAndActionHash(parentItem, name);
if (!groupName.isEmpty()) {
QActionGroup* group { nullptr };
if (!_exclusiveGroups.count(groupName)) {
group = _exclusiveGroups[groupName] = new QActionGroup(menu);
group->setExclusive(true);
} else {
group = _exclusiveGroups[groupName];
}
group->addAction(action);
}
QObject::connect(action, &QAction::triggered, [=] {
onClicked(action->isChecked());
});
action->setCheckable(checkable);
action->setChecked(checked);
void PluginContainer::addMenuItem(PluginType type, const QString& path, const QString& name, std::function<void(bool)> onClicked, bool checkable, bool checked, const QString& groupName) {
getMenuCache().addMenuItem(getPrimaryMenu(), path, name, onClicked, checkable, checked, groupName);
if (type == PluginType::DISPLAY_PLUGIN) {
_currentDisplayPluginActions.push_back({ path, name });
} else {
_currentInputPluginActions.push_back({ path, name });
}
return action;
}
void PluginContainer::removeMenuItem(const QString& menuName, const QString& menuItem) {
getPrimaryMenu()->removeMenuItem(menuName, menuItem);
getMenuCache().removeMenuItem(getPrimaryMenu(), menuName, menuItem);
}
bool PluginContainer::isOptionChecked(const QString& name) {
return getPrimaryMenu()->isOptionChecked(name);
return getMenuCache().isOptionChecked(getPrimaryMenu(), name);
}
void PluginContainer::setIsOptionChecked(const QString& path, bool checked) {
@ -161,3 +253,7 @@ void PluginContainer::setBoolSetting(const QString& settingName, bool value) {
Setting::Handle<bool> settingValue(settingName, value);
return settingValue.set(value);
}
void PluginContainer::flushMenuUpdates() {
getMenuCache().flushCache(getPrimaryMenu());
}

View file

@ -46,7 +46,7 @@ public:
void addMenu(const QString& menuName);
void removeMenu(const QString& menuName);
QAction* addMenuItem(PluginType pluginType, const QString& path, const QString& name, std::function<void(bool)> onClicked, bool checkable = false, bool checked = false, const QString& groupName = "");
void addMenuItem(PluginType pluginType, const QString& path, const QString& name, std::function<void(bool)> onClicked, bool checkable = false, bool checked = false, const QString& groupName = "");
void removeMenuItem(const QString& menuName, const QString& menuItem);
bool isOptionChecked(const QString& name);
void setIsOptionChecked(const QString& path, bool checked);
@ -77,9 +77,9 @@ public:
}
protected:
void flushMenuUpdates();
QVector<QPair<QString, QString>> _currentDisplayPluginActions;
QVector<QPair<QString, QString>> _currentInputPluginActions;
std::map<QString, QActionGroup*> _exclusiveGroups;
QRect _savedGeometry { 10, 120, 800, 600 };
};