#include "entities/ScutcheonComponent.h" #include Scutcheon::Scutcheon() { } Scutcheon::Scutcheon(const QString& titleText, osg::ref_ptr targetObj) : osgWidget::Box("Scutcheon", osgWidget::Box::VERTICAL), mTargetObj(targetObj), mIndex(0), mIsVisible(true), mIsItemVisible(true), mIsMouseDrag(false), mIsMousePush(false) { getBackground()->setColor(1.0, 1.0, 1.0, 0.5); setEventMask(osgWidget::EVENT_ALL); attachMoveCallback(); mTitleText = titleText; addLabelTitle(titleText); } Scutcheon::~Scutcheon() { } void Scutcheon::addLabelTitle(const QString& titleText) { osg::ref_ptr labelTitle = new osgWidget::Label("labelTitle"); labelTitle->setFont(FONT_TEXT); labelTitle->setFontSize(14); labelTitle->setFontColor(1.0f, 1.0f, 0.0f, 1.0f); labelTitle->setColor(1.0f, 1.0f, 1.0f, 0.3f); labelTitle->addSize(128.0f, 32.0f); //labelTitle->setEventMask(osgWidget::EVENT_MOUSE_DRAG); //labelTitle->addCallback(new osgWidget::Callback(&osgScutcheon::callbackMousePush, this, osgWidget::EVENT_MOUSE_DRAG)); //labelTitle->setShadow(0.08f); labelTitle->setCanFill(true); labelTitle->setImage(TITLE_IMAGE); labelTitle->setTexCoord(0.0f, 0.0f, osgWidget::Widget::LOWER_LEFT); labelTitle->setTexCoord(1.0f, 0.0f, osgWidget::Widget::LOWER_RIGHT); labelTitle->setTexCoord(1.0f, 1.0f, osgWidget::Widget::UPPER_RIGHT); labelTitle->setTexCoord(0.0f, 1.0f, osgWidget::Widget::UPPER_LEFT); osgText::String labelString = TextCodecUtils::QStringToOsgTextString(titleText); labelTitle->setLabel(labelString); addWidget(labelTitle); } void Scutcheon::addLabelItem(const QString& labelText) { ++mIndex; ScutcheonMenu* labelItem = new ScutcheonMenu(labelText, this); labelItem->setIndex(mIndex); mLabelItemManager.push_back(labelItem); addWidget(labelItem); } void Scutcheon::addLabelItem(ScutcheonMenu& labelItem) { ++mIndex; labelItem.setIndex(mIndex); mLabelItemManager.push_back(&labelItem); if (mIsItemVisible) { addWidget(&labelItem); } } void Scutcheon::moveLabelItem() { int x = this->getX(); int y = this->getY(); for (int i = 0; i < mLabelItemManager.size(); ++i) { ScutcheonMenu* labelItem = mLabelItemManager.at(i); labelItem->moveTo(x, y); } } bool Scutcheon::callbackMouseDrag(osgWidget::Event& ev) { return true; } bool Scutcheon::mouseDrag(double, double, const osgWidget::WindowManager*) { qDebug() << "osgScutcheon mouseDrag called"; mIsMouseDrag = true; return true; } bool Scutcheon::mousePush(double, double, const osgWidget::WindowManager*) { mIsMousePush = true; qDebug() << "osgScutcheon mousePush called" << mIsMousePush << ":" << mTitleText; return true; } bool Scutcheon::mouseRelease(double, double, const osgWidget::WindowManager*) { qDebug() << "osgScutcheon mouseRelease called" << mIsMouseDrag << ":" << mTitleText; if (!mIsMouseDrag) { if (mIsMousePush && mIsItemVisible) { std::vector >::const_iterator it; for (it = mLabelItemManager.begin(); it != mLabelItemManager.end(); ++it) { (*it)->getChildMenu()->hide(); this->removeWidget((*it)); qDebug() << "item removed!" << (*it)->getIndex(); } } else { if (this->getNumChildren() <= mLabelItemManager.size()) { std::vector >::const_iterator it; for (it = mLabelItemManager.begin(); it != mLabelItemManager.end(); ++it) { this->addWidget((*it)); qDebug() << "item added!" << (*it)->getIndex(); } } } mIsItemVisible = !mIsItemVisible; } mIsMousePush = false; mIsMouseDrag = false; return true; } std::vector > Scutcheon::getLabelItemManager() const { return mLabelItemManager; } void Scutcheon::onMouseEvent(const osgGA::GUIEventAdapter& ea, osgViewer::Viewer* viewer) { int etype = ea.getEventType(); if (etype == ea.FRAME) { if (mTargetObj) { osg::Vec3 position = mTargetObj->getMatrix().getTrans() + osg::Vec3d(0, 0, 0); osgViewer::Renderer* renderer = dynamic_cast(viewer->getCamera()->getRenderer()); osg::Vec3 renderPos; renderer->getSceneView(0)->projectObjectIntoWindow(position, renderPos); float x = this->getX(); float y = this->getY(); float w = this->getWidth(); float h = this->getHeight(); float offset = 0.0; osg::Vec3 stPt(x + 0.5 * w, y + 0.5 * h, 0); if (stPt.y()- renderPos.y()>0.5*h) { stPt[1] = stPt.y()-0.5*h+offset; } else if (stPt.y()- renderPos.y()<-0.5*h) { stPt[1] = stPt.y()+0.5*h+offset; } if (stPt.x()- renderPos.x()>0.5*w) { stPt[0] = stPt.x()-0.5*w-offset; } else if (stPt.x()- renderPos.x()<-0.5*w) { stPt[0] = stPt.x()+0.5*w-offset; } setPos(renderPos + osg::Vec3d(50, 50, 50)); createLine(stPt, renderPos); } } if ((etype == ea.PUSH) && ea.getButtonMask() == ea.LEFT_MOUSE_BUTTON) { if (mIsMousePush) { //qDebug() << "mousePush called" ; m_LBDownPt.set(ea.getX(), ea.getY(), 0); m_LastPt = m_LBDownPt; } } if ((etype == ea.DRAG)) { //qDebug() << "mouseDrag called" ; if (mIsMouseDrag) { osg::Vec3 pt(ea.getX() - m_LastPt[0], ea.getY() - m_LastPt[1], 0); setOffset(m_offset + pt); m_LastPt.set(ea.getX(), ea.getY(), 0); ea.setHandled(true); } } if ((etype == ea.RELEASE)) { //qDebug() << "mouseDrag release" ; } } void Scutcheon::setPos(osg::Vec3 pos) { m_pos = pos; pos = m_pos + m_offset; this->setOrigin(pos.x(), pos.y()); this->update(); moveLabelItem(); } void Scutcheon::setOffset(osg::Vec3 offset) { m_offset = offset; offset = m_pos + m_offset; this->setOrigin(offset.x(), offset.y()); this->update(); moveLabelItem(); } osg::ref_ptr Scutcheon::getTargetObject() { return mTargetObj; } int Scutcheon::getItemCount() { return mLabelItemManager.size(); } void Scutcheon::setVisibility(bool b) { mIsVisible = b; if (mIsVisible) { this->show(); m_line->setNodeMask(1); } else { this->hide(); m_line->setNodeMask(0); for (int i = 0; i < mLabelItemManager.size(); i++) { mLabelItemManager.at(i)->getChildMenu()->hide(); } } } void Scutcheon::createLine(const osg::Vec3& startPt, const osg::Vec3& endPt) { if (NULL == m_line) { m_line = new osg::Geometry; osg::Vec3Array* vertices = new osg::Vec3Array; vertices->push_back(startPt); vertices->push_back(endPt); m_line->setVertexArray(vertices); osg::Vec3Array* normals = new osg::Vec3Array; normals->push_back(osg::Vec3(0.0f, 0.0f, 1.0f)); m_line->setNormalArray(normals); m_line->setNormalBinding(osg::Geometry::BIND_OVERALL); osg::Vec4Array* colors = new osg::Vec4Array; colors->push_back(osg::Vec4(1.0, 1.0, 0.0, 1.0)); m_line->setColorArray(colors); m_line->setColorBinding(osg::Geometry::BIND_OVERALL); m_line->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::LINE_STRIP, 0, 2)); m_line->getOrCreateStateSet()->setMode(GL_BLEND, osg::StateAttribute::ON); //m_line->getOrCreateStateSet()->setAttributeAndModes(new osg::LineWidth(1.0f),osg::StateAttribute::ON); m_line->getOrCreateStateSet()->setRenderingHint(osg::StateSet::TRANSPARENT_BIN); osg::Geode* geode = new osg::Geode(); geode->getOrCreateStateSet()->setMode(GL_LIGHTING, osg::StateAttribute::OFF); geode->addDrawable(m_line); //this->addChild(geode); this->getWindowManager()->addChild(geode); } else { osg::Vec3Array* vertices = dynamic_cast(m_line->getVertexArray()); (*vertices)[0].set(startPt.x(), startPt.y(), 0.0); (*vertices)[1].set(endPt.x(), endPt.y(), 0.0); vertices->dirty(); m_line->setVertexArray(vertices); m_line->dirtyDisplayList(); } } /////////////////////////////////////////////////////////////// /// \brief osgScutcheonManager::osgScutcheonManager /// 标牌管理器 /// /////////////////////////////////////////////////////////// ScutcheonManager* ScutcheonManager::m_pInstance = NULL; ScutcheonManager::ScutcheonManager(osgViewer::Viewer* pViewer, osg::Group* pScreneRoot) { m_bVisible = true; mWindowManager = new osgWidget::WindowManager(pViewer, 50.0f, 50.0f, 1, /*0xF0000000*/ osgWidget::WindowManager::WM_PICK_DEBUG); osg::Camera* camera = mWindowManager->createParentOrthoCamera(); pScreneRoot->addChild(camera); /*pViewer->addEventHandler(new osgWidget::MouseHandler(mWindowManager)); pViewer->addEventHandler(new osgWidget::KeyboardHandler(mWindowManager)); pViewer->addEventHandler(new osgWidget::ResizeHandler(mWindowManager, camera)); pViewer->addEventHandler(new osgWidget::CameraSwitchHandler(mWindowManager, camera));*/ } ScutcheonManager::~ScutcheonManager() { m_bGUIStoped = true; clear(); } ScutcheonManager* ScutcheonManager::instance() { if (NULL == m_pInstance) { //osgViewer::Viewer* getOSGViewer(){ return m_pViewer; } //osg::Group* getRoot(){ return m_pRoot.get(); } /* m_pInstance = new osgScutcheonManager(GraphicsView::instance()->getOSGViewer(), GraphicsView::instance()->getRoot()); GraphicsView::instance()->getOSGViewer()->addEventHandler(m_pInstance);*/ } return m_pInstance; } void ScutcheonManager::destroy() { if (NULL != m_pInstance) { delete m_pInstance; m_pInstance = NULL; } } bool ScutcheonManager::handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa) { if (m_bStopGUI) { m_bGUIStoped = true; } else { osgViewer::Viewer* viewer = dynamic_cast(&aa); int nCount = m_LabelList.size(); for (int i = 0; i < nCount; i++) { m_LabelList[i]->onMouseEvent(ea, viewer); } } return false; } int ScutcheonManager::addLabel(Scutcheon* label) { m_bVisible = true; if (label == NULL) { return 0; } lock(true); // while (!m_bStopGUI) QThread::sleep(100); int nCount = m_LabelList.size(); for (int i = 0; i < nCount; i++) { if (m_LabelList[i] == label) { lock(false); return 0; } } mWindowManager->addChild(label); mWindowManager->resizeAllWindows(); m_LabelList.push_back(label); lock(false); return m_LabelList.size(); } int ScutcheonManager::delLabel(Scutcheon*& label) { lock(true); while (!m_bStopGUI) QThread::sleep(100); for (std::vector::iterator vit = m_LabelList.begin(); vit != m_LabelList.end(); vit++) { if ((*vit) == label) { m_LabelList.erase(vit); //label->setVisibility(false); delete label; label = NULL; lock(false); return m_LabelList.size(); } } lock(false); return 0; } int ScutcheonManager::delLabel(osg::MatrixTransform* tethernode) { return 0; } void ScutcheonManager::clear() { lock(true); //while (!m_bGUIStoped) Sleep(200); while (m_LabelList.size() > 0) { Scutcheon* back = m_LabelList.back(); delLabel(back); } lock(false); } void ScutcheonManager::lock(bool b) { if (b) { m_bStopGUI = true; m_bGUIStoped = false; } else { m_bStopGUI = false; m_bGUIStoped = true; } } osg::ref_ptr ScutcheonManager::getWindowManager() const { return mWindowManager; } ScutcheonMenu::ScutcheonMenu(const QString& label, osg::ref_ptr parentMenu) : osgWidget::Label("menu1"), mChildMenu(NULL), mParentMenu(parentMenu), mHasChildMenu(false), mIndex(0), mMenuItemCount(0) { initLabel(label); } void ScutcheonMenu::addChildMenu(const QString& menuText) { ImageLabel* childMenuContent = new ImageLabel(menuText); if (mChildMenu == NULL) { mChildMenu = new osgWidget::Box("childMenu", osgWidget::Box::VERTICAL, true); mChildMenu->addWidget(childMenuContent); mMenuItemManager.push_back(childMenuContent); mChildMenu->getBackground()->setColor(1.0f, 1.0f, 1.0f, 0.6f); mChildMenu->resize(); mChildMenu->hide(); mHasChildMenu = true; //mParentMenu->addChild(mChildMenu); mParentMenu->getWindowManager()->addChild(mChildMenu.get()); } else { mChildMenu->addWidget(childMenuContent); mMenuItemManager.push_back(childMenuContent); } ++mMenuItemCount; } void ScutcheonMenu::updateChildMenuText(int index, QString labelText) { if (index >= 0 && index < getMenuItemCount()) { //mMenuItemManager.at(index)->setLabelText(labelText); } } void ScutcheonMenu::initLabel(const QString& labelText) { setFont(FONT_TEXT); setFontSize(15); setFontColor(0.0f, 0.0f, 1.0f, 1.0f); addSize(128.0f, 32.0f); setColor(1.0f, 1.0f, 0.0f, 0.6f); //setShadow(0.08f); setCanFill(true); setEventMask(osgWidget::EVENT_ALL); setImage(ITEM_IAMGE); setTexCoord(0.0f, 0.0f, osgWidget::Widget::LOWER_LEFT); setTexCoord(1.0f, 0.0f, osgWidget::Widget::LOWER_RIGHT); setTexCoord(1.0f, 1.0f, osgWidget::Widget::UPPER_RIGHT); setTexCoord(0.0f, 1.0f, osgWidget::Widget::UPPER_LEFT); osgText::String labelString = TextCodecUtils::QStringToOsgTextString(labelText); setLabel(labelString); } void ScutcheonMenu::hideOtherChildMenu() { for (int i = 0; i < mParentMenu->getLabelItemManager().size(); i++) { osg::ref_ptr childItem = mParentMenu->getLabelItemManager().at(i); if (childItem->getChildMenu() != mChildMenu) { childItem->getChildMenu()->hide(); } qDebug() << "hideOtherChildMenu"; } } void ScutcheonMenu::hideAllChildMenu(osgWidget::WindowManager* wm) { osgWidget::Window* tmp = 0; unsigned int count = wm->getNumChildren(); for (unsigned int i = 0; i < count; ++i) { tmp = dynamic_cast(wm->getChild(i)); if (tmp) { QString name = QString::fromStdString(tmp->getName()); if (tmp != mChildMenu.get() && name == "childMenu") { if (tmp->isVisible()) { tmp->hide(); } } } } } bool ScutcheonMenu::mousePush(double, double, const osgWidget::WindowManager* wm) { hideOtherChildMenu(); //hideAllChildMenu(mParentMenu->getWindowManager()); if (!mChildMenu->isVisible()) { mChildMenu->show(); qDebug() << "hideOtherChildMenu show"; } else { mChildMenu->hide(); qDebug() << "hideOtherChildMenu hide"; } return true; } ImageLabel::ImageLabel(const QString& labelText) : osgWidget::Label("menu1") { setFont(FONT_TEXT); setFontSize(13); setFontColor(0.0f, 0.2f, 1.0f, 1.0f); addSize(128.0f, 32.0f); setColor(1.0f, 1.0f, 1.0f, 0.6f); //setPadding(1.0f); //setShadow(0.08f); setCanFill(true); setEventMask(osgWidget::EVENT_ALL); setImage(ITEM_IAMGE); setLabelText(labelText); } void ImageLabel::setLabelText(QString labelText) { setAlignHorizontal(osgWidget::Widget::HA_LEFT); setTexCoord(0.0f, 0.0f, osgWidget::Widget::LOWER_LEFT); setTexCoord(1.0f, 0.0f, osgWidget::Widget::LOWER_RIGHT); setTexCoord(1.0f, 1.0f, osgWidget::Widget::UPPER_RIGHT); setTexCoord(0.0f, 1.0f, osgWidget::Widget::UPPER_LEFT); osgText::String labelString = TextCodecUtils::QStringToOsgTextString(labelText); setLabel(labelString); }