Commit 43d2b988 authored by Jan Möbius's avatar Jan Möbius

Merge branch 'customizeableSidePaneArea' into 'master'

Introduce and Use Customizeable Side Pane Area

In order to use screen real estate more effectively, replace the stretch space between plugin titles and detach button with a widget that is customizeable by plugins. 

Also added a use case for this new feature to make the Datacontrol plugin interface sleeker.

# Screenshot
![Untitled](/uploads/8ff4eff44e0d95ffe1a124c318a0cfa1/Untitled.png)

See merge request !107
parents 2b0842f6 17bcbe86
Pipeline #2101 passed with stage
in 80 minutes and 57 seconds
......@@ -111,6 +111,18 @@ class ToolboxInterface {
* @param _icon Icon for the toolbox
*/
virtual void addToolbox( QString _name , QWidget* _widget, QIcon* _icon) {};
/** \brief Add a toolbox widget to the gui with the given name, icon and header area widget.
*
* This signal adds a toolbox widget to the toolbox area on the right. And sets an icon for it
*
* @param _name Visible name of the toolbox
* @param _widget Pointer to the toolbox widget
* @param _icon Icon for the toolbox
* @param _headerAreaWidget Widget displayed in the toolbox header between
* the title and the detach button.
*/
virtual void addToolbox( QString _name , QWidget* _widget, QIcon* _icon, QWidget* _headerAreaWidget) {};
};
......
......@@ -1022,6 +1022,10 @@ private slots:
/// Add a Toolbox from a plugin or from scripting (with icon)
void addToolbox(QString _name ,QWidget* _widget, QIcon* _icon);
/// Add a Toolbox from a plugin or from scripting (with icon)
void addToolbox(QString _name ,QWidget* _widget, QIcon* _icon,
QWidget* _headerAreaWidget);
/**
* Get a toolbox.
*
......
......@@ -93,6 +93,7 @@ class PluginInfo{
slotInfos.clear();
keys.clear();
toolboxWidgets.clear();
headerAreaWidgets.clear();
toolboxIcons.clear();
toolbars.clear();
contextMenus.clear();
......@@ -111,6 +112,7 @@ class PluginInfo{
slotInfos(_i.slotInfos),
keys(_i.keys),
toolboxWidgets(_i.toolboxWidgets),
headerAreaWidgets(_i.headerAreaWidgets),
toolboxIcons(_i.toolboxIcons),
toolbars(_i.toolbars),
contextMenus(_i.contextMenus),
......@@ -151,6 +153,9 @@ class PluginInfo{
/// Pointer to plugins toolbox widget (if available)
std::vector< std::pair< QString , QWidget* > > toolboxWidgets;
/// Pointer to plugins header area widgets (if available)
std::vector< std::pair< QString , QWidget* > > headerAreaWidgets;
/// Pointer to plugins toolbox widget icons (if available)
std::vector< QIcon* > toolboxIcons;
......
......@@ -1069,7 +1069,11 @@ void Core::loadPlugin(const QString& _filename,const bool _silent, QString& _lic
if ( checkSignal(plugin, "addToolbox(QString,QWidget*,QIcon*)"))
connect(plugin, SIGNAL( addToolbox(QString,QWidget*,QIcon*) ),
this, SLOT( addToolbox(QString,QWidget*,QIcon*) ),Qt::DirectConnection );
}
if ( checkSignal(plugin, "addToolbox(QString,QWidget*,QIcon*,QWidget*)"))
connect(plugin, SIGNAL( addToolbox(QString,QWidget*,QIcon*,QWidget*) ),
this, SLOT( addToolbox(QString,QWidget*,QIcon*,QWidget*) ),Qt::DirectConnection );
}
//Check if the plugin supports ViewMode-Interface
ViewModeInterface* viewModePlugin = qobject_cast< ViewModeInterface * >(plugin);
......
......@@ -254,48 +254,15 @@ void Core::activateToolbox(QString _pluginName, QString _toolboxName, bool activ
}
void Core::addToolbox(QString _name ,QWidget* _widget) {
int id = -1;
// Find the plugin which added this Toolbox
for ( uint i = 0 ; i < plugins_.size(); ++i ) {
if ( plugins_[i].plugin == sender() ) {
id = i;
break;
}
}
// Find the scripting plugin because we assign this toolBox to it as we did not find the original sender
if ( id == -1 ) {
for ( uint i = 0 ; i < plugins_.size(); ++i ) {
if ( plugins_[i].name == "Scripting" ) {
id = i;
break;
}
}
if ( id == -1 ) {
std::cerr << "Unknown sender plugin when adding Toolbox!" << std::endl;
return;
}
}
spinBoxEventFilter_.hookUpToWidgetTree(_widget);
plugins_[id].toolboxWidgets.push_back( std::pair< QString,QWidget* >( _name , _widget) );
plugins_[id].toolboxIcons.push_back( 0 );
// add widget name to viewMode 'all'
if ( !viewModes_[0]->visibleToolboxes.contains(_name) ){
viewModes_[0]->visibleToolboxes << _name;
viewModes_[0]->visibleToolboxes.sort();
}
setViewMode( OpenFlipper::Options::currentViewMode() );
addToolbox(_name, _widget, 0, 0);
}
//-----------------------------------------------------------------------------
void Core::addToolbox(QString _name ,QWidget* _widget, QIcon* _icon) {
addToolbox(_name, _widget, _icon, 0);
}
void Core::addToolbox(QString _name ,QWidget* _widget, QIcon* _icon,
QWidget *_headerAreaWidget) {
int id = -1;
// Find the plugin which added this Toolbox
......@@ -325,6 +292,7 @@ void Core::addToolbox(QString _name ,QWidget* _widget, QIcon* _icon) {
spinBoxEventFilter_.hookUpToWidgetTree(_widget);
plugins_[id].toolboxWidgets.push_back( std::pair< QString,QWidget* >( _name , _widget) );
plugins_[id].toolboxIcons.push_back( _icon );
plugins_[id].headerAreaWidgets.push_back( std::pair< QString,QWidget* >( _name , _headerAreaWidget) );
// add widget name to viewMode 'all'
if ( !viewModes_[0]->visibleToolboxes.contains(_name) ){
......
......@@ -75,20 +75,10 @@ SideArea::SideArea (QWidget *_parent) :
//-----------------------------------------------------------------------------
void SideArea::addItem (QObject const * const _plugin, QWidget *_w, QString _name, QIcon *_icon)
void SideArea::addItem (QObject const * const _plugin, QWidget *_w, QString _name,
QIcon *_icon, QWidget *_headerAreaWidget)
{
SideElement *e = new SideElement (this, _w, _name, _icon);
layout_->addWidget (e);
items_.push_back (e);
plugins_.push_back(_plugin);
itemNames_.push_back(_name);
}
//-----------------------------------------------------------------------------
void SideArea::addItem (QObject const * const _plugin, QWidget *_w, QString _name)
{
SideElement *e = new SideElement (this, _w, _name);
SideElement *e = new SideElement (this, _w, _name, _icon, _headerAreaWidget);
layout_->addWidget (e);
items_.push_back (e);
plugins_.push_back(_plugin);
......
......@@ -85,20 +85,15 @@ class SideArea : public QWidget {
*/
SideArea (QWidget *_parent = 0);
/** Adds a plugin tool widget
\param _plugin plugin corresponding to the widget
\param _w Plugin widget
\param _name Plugin name
*/
void addItem (QObject const * const _plugin, QWidget *_w, QString _name);
/** Adds a plugin tool widget
\param _plugin plugin corresponding to the widget
\param _w Plugin widget
\param _name Plugin name
\param _icon an icon
\param _headerAreaWidget
*/
void addItem (QObject const * const _plugin, QWidget *_w, QString _name, QIcon* _icon);
void addItem (QObject const * const _plugin, QWidget *_w, QString _name,
QIcon* _icon = 0, QWidget *_headerAreaWidget = 0);
/// clears the whole tool widget area
void clear ();
......
......@@ -64,9 +64,11 @@
//== IMPLEMENTATION ==========================================================
SideElement::SideElement (SideArea *_parent, QWidget *_w, QString _name, QIcon* _icon) :
SideElement::SideElement (SideArea *_parent, QWidget *_w, QString _name, QIcon* _icon,
QWidget *_headerAreaWidget) :
parent_ (_parent),
widget_ (_w),
headerAreaWidget_(_headerAreaWidget),
name_ (_name),
icon_ (_icon),
active_ (0),
......@@ -98,7 +100,12 @@ SideElement::SideElement (SideArea *_parent, QWidget *_w, QString _name, QIcon*
detachButton_->setAutoRaise(true);
hl->addWidget (iconHolder_);
hl->addWidget (label_);
hl->addStretch (1);
if (headerAreaWidget_) {
headerAreaWidget_->setVisible(false);
connect(this, SIGNAL(toggleActive(bool)), headerAreaWidget_, SLOT(setVisible(bool)));
hl->addWidget (headerAreaWidget_);
}
hl->addStretch(1);
hl->addWidget (detachButton_);
......@@ -139,6 +146,8 @@ SideElement::~SideElement ()
dialog_->close ();
}
widget_->setParent (0);
if (headerAreaWidget_)
headerAreaWidget_->setParent(0);
}
//-----------------------------------------------------------------------------
......@@ -161,6 +170,8 @@ void SideElement::labelPress ()
QFont font;
font.setBold (active_);
label_->setFont (font);
emit toggleActive(active_);
}
}
......@@ -175,6 +186,7 @@ void SideElement::setActive(bool _active)
}
else
{
const bool doEmit = (active_ != _active);
active_ = _active;
if (active_)
widget_->show ();
......@@ -184,6 +196,8 @@ void SideElement::setActive(bool _active)
QFont font;
font.setBold (active_);
label_->setFont (font);
if (doEmit) emit toggleActive(active_);
}
}
......@@ -261,7 +275,9 @@ void SideElement::restoreState (QSettings &_settings)
{
_settings.beginGroup (name_);
active_ = _settings.value ("Active", active_).toBool ();
bool active = _settings.value ("Active", active_).toBool ();
const bool doEmit = (active_ != active);
active_ = active;
if (active_)
widget_->show ();
......@@ -272,6 +288,8 @@ void SideElement::restoreState (QSettings &_settings)
font.setBold (active_);
label_->setFont (font);
if (doEmit) emit toggleActive(active_);
if (_settings.value ("Detached", false).toBool () && !dialog_)
detachPressed (true);
......
......@@ -94,7 +94,8 @@ class SideElement : public QWidget
@param _icon An icon that should be shown in the title bar of the side element
*/
SideElement (SideArea *_parent, QWidget *_w, QString _name, QIcon* _icon = 0);
SideElement (SideArea *_parent, QWidget *_w, QString _name, QIcon* _icon,
QWidget *_headerAreaWidget);
/// Destructor
~SideElement ();
......@@ -117,6 +118,9 @@ class SideElement : public QWidget
/// returns the pointer to the plugin tool widget
QWidget const * widget();
signals:
void toggleActive(bool);
private:
/// Clickable area inside of the side element.
......@@ -147,7 +151,7 @@ class SideElement : public QWidget
SideArea *parent_;
// plugin widget
QWidget *widget_;
QWidget *widget_, *headerAreaWidget_;
// plugin name
QString name_;
......
......@@ -378,7 +378,7 @@ void CoreWidget::slotChangeView(QString _mode, QStringList _toolboxWidgets, QStr
// only add items that have not been added yet
if (!skip) {
toolBox_->addItem (plugins_[p].plugin, plugins_[p].toolboxWidgets[j].second, plugins_[p].toolboxWidgets[j].first, plugins_[p].toolboxIcons[j] );
toolBox_->addItem (plugins_[p].plugin, plugins_[p].toolboxWidgets[j].second, plugins_[p].toolboxWidgets[j].first, plugins_[p].toolboxIcons[j], plugins_[p].headerAreaWidgets[j].second );
// move item to the correct position
if (i < toolBox_->lastPos_) {
......
......@@ -83,7 +83,8 @@ DataControlPlugin::DataControlPlugin() :
headerPopupType_(0),
targetAction_(0),
sourceAction_(0),
removeAction_(0)
removeAction_(0),
advancedSettingsBtn_(0)
{
}
......@@ -160,7 +161,7 @@ void DataControlPlugin::pluginsInitialized() {
PluginFunctions::setDefaultViewObjectMarker (&objectMarker);
PluginFunctions::setViewObjectMarker (&objectMarker);
connect(tool_->lightSources, SIGNAL(stateChanged(int)), this, SLOT(slotShowLightSources(int)));
connect(tool_->lightSources, SIGNAL(toggled(bool)), this, SLOT(slotShowLightSources(bool)));
//update light visibility, if layout was changed
connect(model_, SIGNAL(layoutChanged ()), this, SLOT(slotShowLightSources()) );
connect(model_, SIGNAL(rowsRemoved(const QModelIndex& , int , int )), this, SLOT(slotShowLightSources()));
......@@ -200,11 +201,11 @@ void DataControlPlugin::initializePlugin()
connect( view_,SIGNAL(customContextMenuRequested ( const QPoint & ) ),
this,SLOT(slotCustomContextMenuRequested ( const QPoint & ) ));
connect( tool_->notSelected, SIGNAL(stateChanged ( int ) ),
connect( tool_->notSelected, SIGNAL(toggled ( bool ) ),
this, SLOT (slotBoundingBoxChange ( ) ));
connect( tool_->sourceSelected, SIGNAL(stateChanged ( int ) ),
connect( tool_->sourceSelected, SIGNAL(toggled ( bool ) ),
this, SLOT (slotBoundingBoxChange ( ) ));
connect( tool_->targetSelected, SIGNAL(stateChanged ( int ) ),
connect( tool_->targetSelected, SIGNAL(toggled ( bool ) ),
this, SLOT (slotBoundingBoxChange ( ) ));
......@@ -217,16 +218,27 @@ void DataControlPlugin::initializePlugin()
toolIcon_ = new QIcon(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"datacontrol-toolbox.png");
emit addToolbox("Data Control", tool_, toolIcon_);
QIcon icon = QIcon(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"datacontrol-boundingBox.png");
tool_->boundingBoxBtn->setIcon( icon );
icon = QIcon(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"datacontrol-hide-object.png");
tool_->visibleDataBtn->setIcon( icon );
//hide additional boxes
tool_->visibleDataBtn->setChecked(false);
tool_->boundingBoxBtn->setChecked(false);
QWidget *headerAreaWidget = new QWidget();
advancedSettingsBtn_ = new QToolButton();
advancedSettingsBtn_->setAutoRaise(true);
advancedSettingsBtn_->setIcon(QIcon(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"preferences.png"));
advancedSettingsBtn_->setIconSize(QSize(16, 16));
advancedSettingsBtn_->setPopupMode(QToolButton::InstantPopup);
advancedSettingsBtn_->setToolTip(tr("Advanced Settings"));
QHBoxLayout *hl = new QHBoxLayout;
hl->addWidget(advancedSettingsBtn_);
hl->addStretch(1);
hl->setContentsMargins(8, 0, 0, 0);
headerAreaWidget->setLayout(hl);
QMenu *menu = new QMenu();
menu->addAction(tool_->lightSources);
menu->addAction(tool_->notSelected);
menu->addAction(tool_->sourceSelected);
menu->addAction(tool_->targetSelected);
advancedSettingsBtn_->setMenu(menu);
emit addToolbox("Data Control", tool_, toolIcon_, headerAreaWidget);
}
......@@ -395,7 +407,7 @@ void DataControlPlugin::fileOpened(int _id){
// Only if the added object was a light source, we will traverse the objects!
if ( obj->dataType() == DATA_LIGHT)
slotShowLightSources(tool_->lightSources->checkState());
slotShowLightSources(tool_->lightSources->isChecked());
view_->resizeColumnToContents(0);
}
......@@ -535,14 +547,14 @@ void DataControlPlugin::slotMoveBaseObject(int _id, int _newParentId){
//******************************************************************************
void DataControlPlugin::slotShowLightSources( int _state ) {
void DataControlPlugin::slotShowLightSources( bool _state ) {
int rows = model_->rowCount();
for(int i = 0; i < rows; ++i) {
TreeItem* item = model_->getItem(model_->index(i,0));
if(item->dataType() == DATA_LIGHT) {
view_->setRowHidden(i, model_->parent(model_->index(i,0)), !(_state == Qt::Checked));
view_->setRowHidden(i, model_->parent(model_->index(i,0)), !_state);
}else{
//always show, if it is not a light
view_->setRowHidden(i, model_->parent(model_->index(i,0)), false);
......@@ -553,7 +565,7 @@ void DataControlPlugin::slotShowLightSources( int _state ) {
void DataControlPlugin::slotShowLightSources()
{
slotShowLightSources( tool_->lightSources->checkState() );
slotShowLightSources( tool_->lightSources->isChecked() );
}
//******************************************************************************
......@@ -885,11 +897,8 @@ void DataControlPlugin::saveOnExit(INIFile& _ini){
}
void DataControlPlugin::showReducedUi(bool reduced) {
tool_->boundingBoxWidget->setVisible(!reduced);
tool_->boundingBoxBtn->setVisible(!reduced);
tool_->line_2->setVisible(!reduced);
tool_->visibleDataWidget->setVisible(!reduced);
tool_->visibleDataBtn->setVisible(!reduced);
if (advancedSettingsBtn_)
advancedSettingsBtn_->setVisible(reduced);
}
void DataControlPlugin::slotObjectUpdated( int _identifier, const UpdateType& _type )
......
......@@ -110,7 +110,7 @@ class DataControlPlugin : public QObject, BaseInterface, ToolboxInterface, KeyIn
void copyObject( int _oldId, int& _newId);
// ToolboxInterface
void addToolbox( QString _name , QWidget* _widget, QIcon* _icon );
void addToolbox( QString _name , QWidget* _widget, QIcon* _icon, QWidget *_headerAreaWidget);
private slots :
// BaseInterface
......@@ -255,7 +255,7 @@ class DataControlPlugin : public QObject, BaseInterface, ToolboxInterface, KeyIn
void slotNodeChanged( ACG::SceneGraph::BaseNode* _node );
/// Hide/Show all light sources if checkbox has been checked
void slotShowLightSources( int _state );
void slotShowLightSources( bool _state );
void slotShowLightSources();
private :
......@@ -300,6 +300,8 @@ class DataControlPlugin : public QObject, BaseInterface, ToolboxInterface, KeyIn
QAction* sourceAction_;
QAction* removeAction_;
QToolButton *advancedSettingsBtn_;
/** @} */
//===========================================================================
......
......@@ -6,8 +6,17 @@
<string>Form</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_3">
<property name="margin">
<number>2</number>
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="DataControlTreeView" name="treeView">
......@@ -31,86 +40,39 @@
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="visibleDataBtn">
<property name="text">
<string>Object Visibility</string>
</property>
<property name="checkable">
<bool>true</bool>
</property>
<property name="checked">
<bool>true</bool>
</property>
<property name="flat">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QWidget" name="visibleDataWidget" native="true">
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QCheckBox" name="lightSources">
<property name="text">
<string>Show Light Sources</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="Line" name="line_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="boundingBoxBtn">
<property name="text">
<string>Object Bounding Box</string>
</property>
<property name="checkable">
<bool>true</bool>
</property>
<property name="checked">
<bool>true</bool>
</property>
<property name="flat">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QWidget" name="boundingBoxWidget" native="true">
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QCheckBox" name="notSelected">
<property name="text">
<string>Show always</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="sourceSelected">
<property name="text">
<string>Show on source objects</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="targetSelected">
<property name="text">
<string>Show on target objects</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
<action name="lightSources">
<property name="checkable">
<bool>true</bool>
</property>
<property name="text">
<string>Show &amp;Light Sources</string>
</property>
</action>
<action name="notSelected">
<property name="checkable">
<bool>true</bool>
</property>
<property name="text">
<string>Show &amp;All Bounding Boxes</string>
</property>
</action>
<action name="sourceSelected">
<property name="checkable">
<bool>true</bool>
</property>
<property name="text">
<string>Show Bounding Boxes of &amp;Source Objects</string>
</property>
</action>
<action name="targetSelected">
<property name="checkable">
<bool>true</bool>
</property>
<property name="text">
<string>Show Bounding Boxes of &amp;Targeted Objects</string>
</property>
</action>
</widget>
<customwidgets>
<customwidget>
......@@ -120,38 +82,5 @@
</customwidget>
</customwidgets>
<resources/>
<connections>
<connection>
<sender>visibleDataBtn</sender>
<signal>toggled(bool)</signal>
<receiver>visibleDataWidget</receiver>
<slot>setVisible(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>161</x>
<y>276</y>
</hint>
<hint type="destinationlabel">
<x>160</x>
<y>302</y>
</hint>
</hints>
</connection>
<connection>
<sender>boundingBoxBtn</sender>
<signal>toggled(bool)</signal>
<receiver>boundingBoxWidget</receiver>
<slot>setVisible(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>138</x>
<y>345</y>
</hint>
<hint type="destinationlabel">
<x>133</x>
<y>373</y>
</hint>
</hints>
</connection>
</connections>
<connections/>
</ui>
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment