From 46cb88cbb4e1baf2123c8bafe1c9449c6c2742ed Mon Sep 17 00:00:00 2001 From: Sascha Cunz Date: Sun, 13 Oct 2013 14:46:08 +0100 Subject: [PATCH] Initial version of Views-Menu --- src/libHeaven/CMakeLists.txt | 4 + src/libHeaven/CentralUI/Views/View.cpp | 3 + .../CentralUI/Views/ViewDescriptor.cpp | 89 +++++++++++-- .../CentralUI/Views/ViewDescriptor.hpp | 26 +++- .../Views/ViewDescriptorRegistrar.cpp | 120 ++++++++++++++++++ .../Views/ViewDescriptorRegistrar.hpp | 63 +++++++++ .../CentralUI/Views/ViewIdentifier.cpp | 46 +++++++ .../CentralUI/Views/ViewIdentifier.hpp | 10 +- .../CentralUI/Views/ViewsMergerActions.hid | 30 +++++ 9 files changed, 374 insertions(+), 17 deletions(-) create mode 100644 src/libHeaven/CentralUI/Views/ViewDescriptorRegistrar.cpp create mode 100644 src/libHeaven/CentralUI/Views/ViewDescriptorRegistrar.hpp create mode 100644 src/libHeaven/CentralUI/Views/ViewsMergerActions.hid diff --git a/src/libHeaven/CMakeLists.txt b/src/libHeaven/CMakeLists.txt index 2a80e63..6765728 100644 --- a/src/libHeaven/CMakeLists.txt +++ b/src/libHeaven/CMakeLists.txt @@ -67,6 +67,7 @@ SET( SRC_FILES CentralUI/Views/View.cpp CentralUI/Views/AbstractViewWidget.cpp CentralUI/Views/ViewDescriptor.cpp + CentralUI/Views/ViewDescriptorRegistrar.cpp CentralUI/Views/ViewIdentifier.cpp CentralUI/Contexts/ContextKeys.cpp @@ -202,6 +203,8 @@ SET( PRI_HDR_FILES CentralUI/States/WindowStateView.hpp CentralUI/States/WindowStateWindow.hpp + CentralUI/Views/ViewDescriptorRegistrar.hpp + Widgets/FooterWidget.hpp Widgets/ModeSwitchCombo.hpp Widgets/TabWidget.hpp @@ -217,6 +220,7 @@ SET( RCC_FILES ) SET( HID_FILES + CentralUI/Views/ViewsMergerActions.hid CentralUI/ContainerWidgets/MultiBarContainerWidgetActions.hid MultiBar/MultiBarViewWidgetActions.hid ) diff --git a/src/libHeaven/CentralUI/Views/View.cpp b/src/libHeaven/CentralUI/Views/View.cpp index b263f45..fa90571 100644 --- a/src/libHeaven/CentralUI/Views/View.cpp +++ b/src/libHeaven/CentralUI/Views/View.cpp @@ -18,6 +18,7 @@ #include #include "libHeaven/CentralUI/Views/View.hpp" +#include "libHeaven/CentralUI/Views/ViewDescriptorRegistrar.hpp" #include "libHeaven/CentralUI/Contexts/ViewContextManager.hpp" namespace Heaven @@ -152,6 +153,8 @@ namespace Heaven */ void View::closeView() { + ViewDescriptor::Registrar::self().viewClosed(this); + parentContainer()->take( this ); deleteLater(); diff --git a/src/libHeaven/CentralUI/Views/ViewDescriptor.cpp b/src/libHeaven/CentralUI/Views/ViewDescriptor.cpp index b671b9f..cf603fc 100644 --- a/src/libHeaven/CentralUI/Views/ViewDescriptor.cpp +++ b/src/libHeaven/CentralUI/Views/ViewDescriptor.cpp @@ -3,6 +3,7 @@ * Copyright (C) 2012-2013 The MacGitver-Developers * * (C) Sascha Cunz + * (C) Cunz RaD Ltd * * This program is free software; you can redistribute it and/or modify it under the terms of the * GNU General Public License (Version 2) as published by the Free Software Foundation. @@ -16,7 +17,12 @@ * */ +#include +#include + +#include "libHeaven/CentralUI/Views/View.hpp" #include "libHeaven/CentralUI/Views/ViewDescriptor.hpp" +#include "libHeaven/CentralUI/Views/ViewDescriptorRegistrar.hpp" namespace Heaven { @@ -26,7 +32,7 @@ namespace Heaven * @ingroup CentralUI * @brief A descriptor for available views * - * This class stores meta data about the available views. It alos acts as a factory to create + * This class stores meta data about the available views. It also acts as a factory to create * real View objects, when required. * * Each instance of this class represents one View. @@ -51,14 +57,19 @@ namespace Heaven */ ViewDescriptor::ViewDescriptor( const ViewIdentifier& id, const QString& displayName, ViewDescriptor::CreatorFunc creator ) - : mIdentifier( id ) - , mDisplayName( displayName ) - , mCreatorFunc( creator ) + : mIdentifier(id) + , mDisplayName(displayName) + , mCreatorFunc(creator) + , mCreatedView(NULL) + , mActivatorAction(NULL) { - mDescriptors.insert( id, this ); + Registrar::self().insert( id, this ); } - QHash< ViewIdentifier, ViewDescriptor* > ViewDescriptor::mDescriptors; + ViewDescriptor::~ViewDescriptor() + { + delete mActivatorAction; + } /** * @brief Get the display name for this descriptor @@ -99,7 +110,7 @@ namespace Heaven */ void ViewDescriptor::unregister() { - mDescriptors.remove( mIdentifier ); + Registrar::self().remove(mIdentifier); delete this; } @@ -113,7 +124,7 @@ namespace Heaven */ ViewDescriptor* ViewDescriptor::get( const ViewIdentifier& id ) { - return mDescriptors.value( id, NULL ); + return Registrar::self().get(id); } /** @@ -126,8 +137,68 @@ namespace Heaven */ View* ViewDescriptor::createView() const { - return mCreatorFunc(); + View* view = mCreatorFunc(); + if (!view) { + return NULL; + } + + mCreatedView = view; + + Registrar::self().viewOpened(view); + + return view; } + /** + * @brief Get the activator action of this view + * + * @return A QAction that can be used to open/close this view + */ + QAction* ViewDescriptor::activatorAction() + { + if (!mActivatorAction) { + createActivatorAction(); + } + + return mActivatorAction; + } + + DynamicActionMerger* ViewDescriptor::actionMerger() + { + return Registrar::self().actionMerger(); + } + + void ViewDescriptor::createActivatorAction() + { + if (mActivatorAction) { + return; + } + + mActivatorAction = new QAction(mDisplayName, &Registrar::self()); + mActivatorAction->setCheckable(true); + + connect(mActivatorAction, SIGNAL(triggered(bool)), + this, SLOT(onActivatorAction(bool))); + } + + void ViewDescriptor::mergeViewsMenu(const QByteArray& mergePlace) + { + ViewDescriptor::Registrar::self().acViewsMergerAC->mergeInto(mergePlace); + } + + void ViewDescriptor::onActivatorAction(bool triggered) + { + if (triggered && !mCreatedView) { + qDebug() << "Should open:" << mIdentifier; + } + else if (!triggered && mCreatedView) { + mCreatedView->closeView(); + } + } + + void ViewDescriptor::setViewClosed() + { + mCreatedView = NULL; + } } diff --git a/src/libHeaven/CentralUI/Views/ViewDescriptor.hpp b/src/libHeaven/CentralUI/Views/ViewDescriptor.hpp index 815d1a5..5b40901 100644 --- a/src/libHeaven/CentralUI/Views/ViewDescriptor.hpp +++ b/src/libHeaven/CentralUI/Views/ViewDescriptor.hpp @@ -19,24 +19,34 @@ #ifndef HEAVEN_VIEW_DESCRIPTOR_HPP #define HEAVEN_VIEW_DESCRIPTOR_HPP +#include + #include "libHeaven/HeavenApi.hpp" #include "libHeaven/CentralUI/Views/ViewIdentifier.hpp" +class QAction; + namespace Heaven { + class DynamicActionMerger; class View; - class HEAVEN_API ViewDescriptor + class HEAVEN_API ViewDescriptor : public QObject { + Q_OBJECT public: + class Registrar; + friend class Registrar; typedef View* (*CreatorFunc)( ); public: - ViewDescriptor( const ViewIdentifier& id, const QString& displayName, CreatorFunc creator ); + ViewDescriptor(const ViewIdentifier& id, const QString& displayName, CreatorFunc creator); + ~ViewDescriptor(); public: + QAction* activatorAction(); QString displayName() const; ViewIdentifier identifier() const; ViewDescriptor::CreatorFunc creatorFunc() const; @@ -45,13 +55,23 @@ namespace Heaven View* createView() const; public: + static DynamicActionMerger* actionMerger(); + static void mergeViewsMenu(const QByteArray& mergePlace); static ViewDescriptor* get( const ViewIdentifier& id ); + private: + void setViewClosed(); + void createActivatorAction(); + + private slots: + void onActivatorAction(bool triggered); + private: const ViewIdentifier mIdentifier; const QString mDisplayName; const CreatorFunc mCreatorFunc; - static QHash< ViewIdentifier, ViewDescriptor* > mDescriptors; + mutable View* mCreatedView; + QAction* mActivatorAction; }; } diff --git a/src/libHeaven/CentralUI/Views/ViewDescriptorRegistrar.cpp b/src/libHeaven/CentralUI/Views/ViewDescriptorRegistrar.cpp new file mode 100644 index 0000000..4a64e45 --- /dev/null +++ b/src/libHeaven/CentralUI/Views/ViewDescriptorRegistrar.cpp @@ -0,0 +1,120 @@ +/* + * libHeaven - A Qt-based ui framework for strongly modularized applications + * Copyright (C) 2012-2013 The MacGitver-Developers + * + * (C) Sascha Cunz + * (C) Cunz RaD Ltd. + * + * This program is free software; you can redistribute it and/or modify it under the terms of the + * GNU General Public License (Version 2) as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without + * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with this program; if + * not, see . + * + */ + +#include + +#include "libHeaven/Actions/DynamicActionMerger.hpp" + +#include "View.hpp" +#include "ViewDescriptorRegistrar.hpp" + +namespace Heaven +{ + + /** + * @internal + * @class ViewDescriptor::Registrar + * + * @brief Internal class to manage registered ViewDescriptors and the Views-Menu + * + */ + + ViewDescriptor::Registrar::Registrar() + { + setupActions(this); + damViewsMerger->setMode(DAMergerAdvancedList); + sSelf = this; + } + + ViewDescriptor::Registrar& ViewDescriptor::Registrar::self() + { + if (sSelf == NULL) { + new Registrar(); + } + return *sSelf; + } + + ViewDescriptor::Registrar* ViewDescriptor::Registrar::sSelf = NULL; + + void ViewDescriptor::Registrar::insert(const ViewIdentifier& id, ViewDescriptor* vd) + { + mDescriptors.insert(id, vd); + rebuildMerger(); + } + + void ViewDescriptor::Registrar::remove(const ViewIdentifier& id) + { + mDescriptors.remove(id); + rebuildMerger(); + } + + ViewDescriptor* ViewDescriptor::Registrar::get(const ViewIdentifier& id) const + { + return mDescriptors.value(id, NULL); + } + + void ViewDescriptor::Registrar::viewClosed(View* view) + { + ViewIdentifier id = view->identifier(); + ViewDescriptor* vd = get(id); + + if (vd) { + QAction* aa = vd->activatorAction(); + aa->setChecked(false); + + vd->setViewClosed(); + } + } + + void ViewDescriptor::Registrar::viewOpened(View* view) + { + ViewIdentifier id = view->identifier(); + ViewDescriptor* vd = get(id); + + if (vd) { + QAction* aa = vd->activatorAction(); + aa->setChecked(true); + } + } + + DynamicActionMerger* ViewDescriptor::Registrar::actionMerger() + { + return damViewsMerger; + } + + void ViewDescriptor::Registrar::rebuildMerger() + { + Q_ASSERT(damViewsMerger); + damViewsMerger->clear(); + + QMap descriptors; + + foreach (ViewIdentifier id, mDescriptors.keys()) { + descriptors.insert(id, mDescriptors[id]); + } + + foreach (ViewIdentifier id, descriptors.keys()) { + ViewDescriptor* vd = get(id); + if (vd) { + damViewsMerger->addAction(vd->activatorAction()); + } + } + } + +} diff --git a/src/libHeaven/CentralUI/Views/ViewDescriptorRegistrar.hpp b/src/libHeaven/CentralUI/Views/ViewDescriptorRegistrar.hpp new file mode 100644 index 0000000..58b355d --- /dev/null +++ b/src/libHeaven/CentralUI/Views/ViewDescriptorRegistrar.hpp @@ -0,0 +1,63 @@ +/* + * libHeaven - A Qt-based ui framework for strongly modularized applications + * Copyright (C) 2012-2013 The MacGitver-Developers + * + * (C) Sascha Cunz + * (C) Cunz RaD Ltd. + * + * This program is free software; you can redistribute it and/or modify it under the terms of the + * GNU General Public License (Version 2) as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without + * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with this program; if + * not, see . + * + */ + +#ifndef HEAVEN_VIEW_DESCRIPTOR_REGISTRAR_HPP +#define HEAVEN_VIEW_DESCRIPTOR_REGISTRAR_HPP + +#include +#include + +#include "ViewIdentifier.hpp" +#include "ViewDescriptor.hpp" + +#include "hic_ViewsMergerActions.h" + +namespace Heaven +{ + + class ViewDescriptor::Registrar : public QObject, public ViewsMergerActions + { + Q_OBJECT + private: + Registrar(); + static Registrar* sSelf; + + public: + static Registrar& self(); + + public: + void remove(const ViewIdentifier& id); + void insert(const ViewIdentifier& id, ViewDescriptor* vd); + ViewDescriptor* get(const ViewIdentifier& id) const; + + void viewClosed(View* view); + void viewOpened(View* view); + + DynamicActionMerger* actionMerger(); + + private: + void rebuildMerger(); + + private: + QHash< ViewIdentifier, ViewDescriptor* > mDescriptors; + }; + +} + +#endif diff --git a/src/libHeaven/CentralUI/Views/ViewIdentifier.cpp b/src/libHeaven/CentralUI/Views/ViewIdentifier.cpp index 913036e..859d9c0 100644 --- a/src/libHeaven/CentralUI/Views/ViewIdentifier.cpp +++ b/src/libHeaven/CentralUI/Views/ViewIdentifier.cpp @@ -16,6 +16,9 @@ * */ +#include +#include + #include "libHeaven/CentralUI/Views/ViewIdentifier.hpp" namespace Heaven @@ -220,4 +223,47 @@ namespace Heaven return !mName.isEmpty(); } + /** + * @brief Hashing function for ViewIdentifiers + * + * @param[in] id The identifier to hash + * + * @return a hash suitable for QHash template + * + */ + uint qHash(const ViewIdentifier& id) + { + return qHash(id.toString()); + } + + /** + * @brief Compare two ViewIdentifiers (less than) + * + * @param[in] lhs Left hand side to compare + * @param[in] rhs Right hand side to compare + * + * @return `true` if left is smaller than right + * + */ + bool operator<(const ViewIdentifier& lhs, const ViewIdentifier& rhs) + { + return lhs.toString() < rhs.toString(); + } + +} + +/** + * @brief QDebug Shift operator for ViewIdentifier + * + * @param[in] stream The debug stream to shift into + * + * @param[in] id The ViewIdentifier to output + * + * @return A reference to @a stream. + * + */ +QDebug& operator<<(QDebug& stream, const Heaven::ViewIdentifier& id) +{ + QString s = QLatin1Literal("(VId:") % id.toString() % QChar(L')'); + return stream << qPrintable(s); } diff --git a/src/libHeaven/CentralUI/Views/ViewIdentifier.hpp b/src/libHeaven/CentralUI/Views/ViewIdentifier.hpp index 45d39ba..305a915 100644 --- a/src/libHeaven/CentralUI/Views/ViewIdentifier.hpp +++ b/src/libHeaven/CentralUI/Views/ViewIdentifier.hpp @@ -20,7 +20,6 @@ #define HEAVEN_VIEW_IDENTIFIER_HPP #include -#include #include "libHeaven/HeavenApi.hpp" @@ -53,11 +52,12 @@ namespace Heaven QString mName; }; - inline uint qHash( const ViewIdentifier& id ) - { - return qHash( id.toString() ); - } + HEAVEN_API uint qHash( const ViewIdentifier& id ); + + HEAVEN_API bool operator<(const ViewIdentifier& lhs, const ViewIdentifier& rhs); } +HEAVEN_API QDebug& operator<<(QDebug& stream, const Heaven::ViewIdentifier& id); + #endif diff --git a/src/libHeaven/CentralUI/Views/ViewsMergerActions.hid b/src/libHeaven/CentralUI/Views/ViewsMergerActions.hid new file mode 100644 index 0000000..fdd8e25 --- /dev/null +++ b/src/libHeaven/CentralUI/Views/ViewsMergerActions.hid @@ -0,0 +1,30 @@ +/* + * libHeaven - A Qt-based ui framework for strongly modularized applications + * Copyright (C) 2012-2013 The MacGitver-Developers + * + * (C) Sascha Cunz + * (C) Cunz RaD Ltd. + * + * This program is free software; you can redistribute it and/or modify it under the terms of the + * GNU General Public License (Version 2) as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without + * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with this program; if + * not, see . + * + */ + +Ui ViewsMergerActions { + + Container ViewsMergerAC { + + DynamicActionMerger ViewsMerger { + + }; + + }; + +};