Commit d39d90b8 authored by Jan Möbius's avatar Jan Möbius

Added public object picking and selection widgets

git-svn-id: http://www.openflipper.org/svnrepo/OpenFlipper/branches/Free@9247 383ad7c9-94d9-4d36-a494-682f7c89f535
parent 522a1366
......@@ -44,6 +44,7 @@ set (directories
../common/bsp
../INIFile
../widgets/glWidget
../publicWidgets/objectSelectionWidget
)
# generate dllexport macros on windows
......
//=============================================================================
//
// OpenFlipper
// Copyright (C) 2009 by Computer Graphics Group, RWTH Aachen
// www.openflipper.org
//
//-----------------------------------------------------------------------------
//
// License
//
// OpenFlipper is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// OpenFlipper 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 Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with OpenFlipper. If not, see <http://www.gnu.org/licenses/>.
//
//-----------------------------------------------------------------------------
//
// $Revision: $
// $Author: $
// $Date: $
//
//=============================================================================
#include <OpenFlipper/common/Types.hh>
#include <OpenFlipper/common/BaseObjectData.hh>
#include "SelectionObjectMarker.hh"
//******************************************************************************
const ACG::Vec4f disabled_color (0.4,0.4,0.4,1.0);
const ACG::Vec4f selected_color (0.0,1.0,0.0,0.5);
//******************************************************************************
bool SelectionObjectMarker::stencilRefForObject(BaseObjectData * _obj, GLuint & _reference)
{
if (_obj->flag("vsi_objectId_disabled"))
{
_reference = 1;
return true;
}
else if (_obj->flag("vsi_objectId_selected"))
{
_reference = 2;
return true;
}
return false;
}
bool SelectionObjectMarker::blendForStencilRefNumber(GLuint _reference, GLenum & _src, GLenum & _dst, ACG::Vec4f & _color)
{
switch (_reference)
{
case 1:
_src = GL_ZERO;
_dst = GL_SRC_COLOR;
_color = disabled_color;
return true;
case 2:
_src = GL_SRC_ALPHA;
_dst = GL_ONE_MINUS_SRC_ALPHA;
_color = selected_color;
return true;
default:
return false;
}
return false;
}
//=============================================================================
//
// OpenFlipper
// Copyright (C) 2009 by Computer Graphics Group, RWTH Aachen
// www.openflipper.org
//
//-----------------------------------------------------------------------------
//
// License
//
// OpenFlipper is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// OpenFlipper 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 Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with OpenFlipper. If not, see <http://www.gnu.org/licenses/>.
//
//-----------------------------------------------------------------------------
//
// $Revision: $
// $Author: $
// $Date: $
//
//=============================================================================
#ifndef SELECTIONOBJECTMARKER_HH
#define SELECTIONOBJECTMARKER_HH
#include <OpenFlipper/common/Types.hh>
#include <OpenFlipper/common/ViewObjectMarker.hh>
/** Object marker to visualize objectPickDialog selection
*/
class SelectionObjectMarker : public ViewObjectMarker
{
public:
bool stencilRefForObject (BaseObjectData *_obj, GLuint &_reference);
bool blendForStencilRefNumber (GLuint _reference, GLenum &_src, GLenum &_dst, ACG::Vec4f &_color);
};
#endif
#include "TreeItemObjectSelection.hh"
//--------------------------------------------------------------------------------
TreeItemObjectSelection::TreeItemObjectSelection(int _id, QString _name, DataType _type, TreeItemObjectSelection* _parent) :
id_(_id),
dataType_(_type),
name_(_name),
parentItem_(_parent)
{
}
// ===============================================================================
// Static Members
// ===============================================================================
int TreeItemObjectSelection::id() {
return id_;
}
//--------------------------------------------------------------------------------
bool TreeItemObjectSelection::dataType(DataType _type) {
if ( _type == DATA_ALL ) {
return true;
}
return ( dataType_ & _type);
}
//--------------------------------------------------------------------------------
DataType TreeItemObjectSelection::dataType() {
return dataType_;
}
//--------------------------------------------------------------------------------
int TreeItemObjectSelection::group() {
// Skip root node
if ( parent() == 0 )
return -1;
// Dont count root node as a group
if ( parent()->parent() == 0 )
return -1;
// Only consider groups
if ( !parent()->dataType(DATA_GROUP) )
return -1;
// Get the group id
return ( parent()->id() );
}
//--------------------------------------------------------------------------------
bool TreeItemObjectSelection::isGroup() {
return ( dataType(DATA_GROUP) );
}
// ===============================================================================
// Dynamic Members
// ===============================================================================
bool TreeItemObjectSelection::visible() {
return visible_;
}
//--------------------------------------------------------------------------------
void TreeItemObjectSelection::visible(bool _visible) {
visible_ = _visible;
}
//--------------------------------------------------------------------------------
QString TreeItemObjectSelection::name() {
return name_;
}
//--------------------------------------------------------------------------------
void TreeItemObjectSelection::name(QString _name ) {
name_ = _name;
}
// ===============================================================================
// Tree Structure
// ===============================================================================
TreeItemObjectSelection* TreeItemObjectSelection::next() {
// Visit child item of this node
if ( childItems_.size() > 0 ) {
return childItems_[0];
}
// No Child Item so visit the next child of the parentItem_
if ( parentItem_ ) {
TreeItemObjectSelection* parentPointer = parentItem_;
TreeItemObjectSelection* thisPointer = this;
// while we are not at the root node
while ( parentPointer ) {
// If there is an unvisited child of the parent, return this one
if ( parentPointer->childCount() > ( thisPointer->row() + 1) ) {
return parentPointer->childItems_[ thisPointer->row() + 1 ];
}
// Go to the next level
thisPointer = parentPointer;
parentPointer = parentPointer->parentItem_;
}
return thisPointer;
}
return this;
}
//--------------------------------------------------------------------------------
int TreeItemObjectSelection::level() {
int level = 0;
TreeItemObjectSelection* current = this;
// Go up and count the levels to the root node
while ( current->parent() != 0 ) {
level++;
current = current->parent();
}
return level;
}
//--------------------------------------------------------------------------------
int TreeItemObjectSelection::row() const
{
if (parentItem_)
return parentItem_->childItems_.indexOf(const_cast<TreeItemObjectSelection*>(this));
return 0;
}
//--------------------------------------------------------------------------------
TreeItemObjectSelection* TreeItemObjectSelection::parent()
{
return parentItem_;
}
//--------------------------------------------------------------------------------
void TreeItemObjectSelection::setParent(TreeItemObjectSelection* _parent) {
parentItem_ = _parent;
}
//--------------------------------------------------------------------------------
void TreeItemObjectSelection::appendChild(TreeItemObjectSelection *item)
{
childItems_.append(item);
}
//--------------------------------------------------------------------------------
TreeItemObjectSelection *TreeItemObjectSelection::child(int row)
{
return childItems_.value(row);
}
//--------------------------------------------------------------------------------
int TreeItemObjectSelection::childCount() const
{
return childItems_.count();
}
//--------------------------------------------------------------------------------
TreeItemObjectSelection* TreeItemObjectSelection::childExists(int _objectId) {
// Check if this object has the requested id
if ( id_ == _objectId )
return this;
// search in children
for ( int i = 0 ; i < childItems_.size(); ++i ) {
TreeItemObjectSelection* tmp = childItems_[i]->childExists(_objectId);
if ( tmp != 0)
return tmp;
}
return 0;
}
//--------------------------------------------------------------------------------
TreeItemObjectSelection* TreeItemObjectSelection::childExists(QString _name) {
// Check if this object has the requested id
if ( name() == _name )
return this;
// search in children
for ( int i = 0 ; i < childItems_.size(); ++i ) {
TreeItemObjectSelection* tmp = childItems_[i]->childExists(_name);
if ( tmp != 0)
return tmp;
}
return 0;
}
//--------------------------------------------------------------------------------
void TreeItemObjectSelection::removeChild( TreeItemObjectSelection* _item ) {
bool found = false;
QList<TreeItemObjectSelection*>::iterator i;
for (i = childItems_.begin(); i != childItems_.end(); ++i) {
if ( *i == _item ) {
found = true;
break;
}
}
if ( !found ) {
std::cerr << "TreeItemObjectSelection: Illegal remove request" << std::endl;
return;
}
childItems_.erase(i);
}
//--------------------------------------------------------------------------------
QList< TreeItemObjectSelection* > TreeItemObjectSelection::getLeafs() {
QList< TreeItemObjectSelection* > items;
for ( int i = 0 ; i < childItems_.size(); ++i ) {
items = items + childItems_[i]->getLeafs();
}
// If we are a leave...
if ( childCount() == 0 )
items.push_back(this);
return items;
}
//--------------------------------------------------------------------------------
void TreeItemObjectSelection::deleteSubtree() {
// call function for all children of this node
for ( int i = 0 ; i < childItems_.size(); ++i) {
// remove the subtree recursively
childItems_[i]->deleteSubtree();
// delete child
delete childItems_[i];
}
// clear the array
childItems_.clear();
}
//=============================================================================
#ifndef TREEITEM_HH
#define TREEITEM_HH
#include <QString>
#include <QList>
#include <vector>
#include <OpenFlipper/common/Types.hh>
class TreeItemObjectSelection {
public :
TreeItemObjectSelection(int _id, QString _name, DataType _type, TreeItemObjectSelection* _parent);
// static members
public:
/// id
int id();
/// dataType
DataType dataType();
bool dataType(DataType _type);
/// group
int group();
bool isGroup();
private:
int id_;
DataType dataType_;
// dynamic members
public:
/// visible
bool visible();
void visible(bool _visible);
/// name
QString name( );
void name( QString _name );
private:
bool visible_;
QString name_;
// tree traversal
public:
/** Get the next item of the tree (Preorder traversal of the tree)
*/
TreeItemObjectSelection* next();
/** level of the current object ( root node has level 0)
*/
int level();
private:
/// Parent item or 0 if rootnode
TreeItemObjectSelection *parentItem_;
/// Children of this node
QList<TreeItemObjectSelection*> childItems_;
public:
//===========================================================================
/** @name Tree : Parent nodes
* @{ */
//===========================================================================
/// get the row of this item from the parent
int row() const;
/// Get the parent item ( 0 if rootitem )
TreeItemObjectSelection *parent();
/// Set the parent pointer
void setParent(TreeItemObjectSelection* _parent);
/** @} */
//===========================================================================
/** @name Tree : Children
* @{ */
//===========================================================================
/// Check if the element exists in the subtree of this element
TreeItemObjectSelection* childExists(int _objectId);
/// Check if the element exists in the subtree of this element
TreeItemObjectSelection* childExists(QString _name);
/// add a child to this node
void appendChild(TreeItemObjectSelection *child);
/// return a child
TreeItemObjectSelection *child(int row);
/// get the number of children
int childCount() const;
/// Remove a child from this object
void removeChild( TreeItemObjectSelection* _item );
/// get all leafes of the tree below this object ( These will be all visible objects )
QList< TreeItemObjectSelection* > getLeafs();
/// delete the whole subtree below this item ( The item itself is not touched )
void deleteSubtree();
};
//=============================================================================
#endif // TREEITEM_HH defined
//=============================================================================
//=============================================================================
//
// OpenFlipper
// Copyright (C) 2009 by Computer Graphics Group, RWTH Aachen
// www.openflipper.org
//
//-----------------------------------------------------------------------------
//
// License
//
// OpenFlipper is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// OpenFlipper 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 Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with OpenFlipper. If not, see <http://www.gnu.org/licenses/>.
//
//-----------------------------------------------------------------------------
//
// $Revision: $
// $Author: $
// $Date: $
//
//=============================================================================
#ifndef TREEMODELOBJECTSELECTION_H
#define TREEMODELOBJECTSELECTION_H
#include <QAbstractItemModel>
#include <QModelIndex>
#include <QVariant>
#include "TreeItemObjectSelection.hh"
class TreeModelObjectSelection : public QAbstractItemModel
{
Q_OBJECT
signals:
// the connected TreeView changed data
void dataChangedInside(int _id, int _column, const QVariant& _value);
public:
/// Constructor
TreeModelObjectSelection(QObject *_parent = 0);
/// Destructor
~TreeModelObjectSelection();
//===========================================================================
/** @name inherited from QAbstractItemModel
* @{ */
//===========================================================================
public:
/// Get the data of the corresponding entry
QVariant data(const QModelIndex &index, int role) const;
/// return the types of the corresponding entry
Qt::ItemFlags flags(const QModelIndex &index) const;
/// return the header data of the model
QVariant headerData(int section,
Qt::Orientation orientation,
int role = Qt::DisplayRole) const;
/// Get the ModelIndex at given row,column
QModelIndex index(int row, int column,
const QModelIndex &parent = QModelIndex()) const;
/// Get the parent ModelIndex
QModelIndex parent(const QModelIndex &index) const;
/// get the number of rows
int rowCount(const QModelIndex &parent = QModelIndex()) const;
/// get the number of columns
int columnCount(const QModelIndex &parent = QModelIndex()) const;
/// Set the data at the given index
bool setData(const QModelIndex &index, const QVariant &value , int role);
/** @} */
//===========================================================================
/** @name Internal DataStructure (the TreeItemObjectSelection Tree)
* @{ */
//===========================================================================
public:
/// Return the ModelIndex corresponding to a given TreeItemObjectSelection and Column
QModelIndex getModelIndex(TreeItemObjectSelection* _object, int _column );
/// Return the ModelIndex corresponding to a given object id and Column
QModelIndex getModelIndex(int _id, int _column );
/// Check if the given item is the root item
bool isRoot(TreeItemObjectSelection* _item);
/// Get the name of a given object
bool getObjectName(TreeItemObjectSelection* _object , QString& _name);
/// Get the TreeItemObjectSelection corresponding to a given ModelIndex
TreeItemObjectSelection *getItem(const QModelIndex &index) const;
/// Get the name of a TreeItemObjectSelection corresponding to a given ModelIndex
QString itemName(const QModelIndex &index) const;
/// Get the id of a TreeItemObjectSelection corresponding to a given ModelIndex
int itemId(const QModelIndex &index) const;
/// The object with the given id has been changed. Check if model also has to be changed
void objectChanged(int id_);
/// The object with the given id has been added. add it to the internal tree
void objectAdded(BaseObject* _object);
/// The object with the given id has been added. add it to the internal tree
void objectAdded(BaseObject* _object, BaseObject* _parent);
/// The object with the given id has been deleted. delete it from the internal tree
void objectDeleted(int id_);
/// move the item to a new parent
void moveItem(TreeItemObjectSelection* _item, TreeItemObjectSelection* _parent );
private:
/// Rootitem of the tree
TreeItemObjectSelection* rootItem_;
void propagateUpwards(TreeItemObjectSelection* _obj, int _column, bool _value );
void propagateDownwards(TreeItemObjectSelection* _obj, int _column );
/** @} */
};
#endif
//=============================================================================
//
// OpenFlipper
// Copyright (C) 2009 by Computer Graphics Group, RWTH Aachen
// www.openflipper.org
//
//-----------------------------------------------------------------------------
//
// License
//
// OpenFlipper is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// OpenFlipper 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 Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with OpenFlipper. If not, see <http://www.gnu.org/licenses/>.
//
//-----------------------------------------------------------------------------