From a7d968f88e44c9de044163b99f85e3e545f96fc2 Mon Sep 17 00:00:00 2001 From: Guillaume Damiand Date: Fri, 31 Oct 2014 19:31:37 +0100 Subject: [PATCH] Add missing impl files. --- .../include/CGAL/Qt/DemosMainWindow_impl.h | 436 ++++++++++++++++++ .../CGAL/Qt/GraphicsViewNavigation_impl.h | 351 ++++++++++++++ .../CGAL/Qt/GraphicsViewPolylineInput_impl.h | 208 +++++++++ GraphicsView/include/CGAL/Qt/debug_impl.h | 60 +++ GraphicsView/include/CGAL/Qt/resources_impl.h | 37 ++ GraphicsView/include/CGAL/Qt/utility_impl.h | 62 +++ 6 files changed, 1154 insertions(+) create mode 100644 GraphicsView/include/CGAL/Qt/DemosMainWindow_impl.h create mode 100644 GraphicsView/include/CGAL/Qt/GraphicsViewNavigation_impl.h create mode 100644 GraphicsView/include/CGAL/Qt/GraphicsViewPolylineInput_impl.h create mode 100644 GraphicsView/include/CGAL/Qt/debug_impl.h create mode 100644 GraphicsView/include/CGAL/Qt/resources_impl.h create mode 100644 GraphicsView/include/CGAL/Qt/utility_impl.h diff --git a/GraphicsView/include/CGAL/Qt/DemosMainWindow_impl.h b/GraphicsView/include/CGAL/Qt/DemosMainWindow_impl.h new file mode 100644 index 00000000000..5f4fee7b156 --- /dev/null +++ b/GraphicsView/include/CGAL/Qt/DemosMainWindow_impl.h @@ -0,0 +1,436 @@ +// Copyright (c) 2008 GeometryFactory Sarl (France). +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org). +// You can redistribute it and/or modify it under the terms of the GNU +// General Public License as published by the Free Software Foundation, +// either version 3 of the License, or (at your option) any later version. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// +// +// Author(s) : Andreas Fabri +// Laurent Rineau + +#ifdef CGAL_HEADER_ONLY +#define CGAL_INLINE_FUNCTION inline +#else +#define CGAL_INLINE_FUNCTION +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include // needed to get CGAL_VERSION_STR +#include +#include + +namespace CGAL { +namespace Qt { + +CGAL_INLINE_FUNCTION +DemosMainWindow::DemosMainWindow(QWidget * parent, ::Qt::WindowFlags flags) + : QMainWindow(parent, flags), + maxNumRecentFiles(10), + recentFileActs(maxNumRecentFiles) +{ + // prepare the QLabel xycoord for inclusion in the statusBar() + xycoord = new QLabel(" -0.00000 , -0.00000 ", this); + xycoord->setAlignment(::Qt::AlignHCenter); + xycoord->setMinimumSize(xycoord->sizeHint()); + xycoord->clear(); + + actionUse_OpenGL = new QAction(this); + actionUse_OpenGL->setObjectName("actionUse_OpenGL"); + actionUse_OpenGL->setCheckable(true); + actionUse_OpenGL->setText(tr("Use &OpenGL")); + actionUse_OpenGL->setStatusTip(tr("Make Qt use OpenGL to display the graphical items, instead of its native painting system.")); + actionUse_OpenGL->setShortcut(tr("Ctrl+G")); + + actionUse_Antialiasing = new QAction(this); + actionUse_Antialiasing->setObjectName("actionUse_Antialiasing"); + actionUse_Antialiasing->setCheckable(true); + actionUse_Antialiasing->setText(tr("Use &anti-aliasing")); + actionUse_Antialiasing->setStatusTip(tr("Make Qt use anti-aliasing when displaying the graphical items.")); + actionUse_Antialiasing->setShortcut(tr("Ctrl+A")); + + actionAboutCGAL = new QAction(this); + actionAboutCGAL->setObjectName("actionAboutCGAL"); + actionAboutCGAL->setText(tr("About &CGAL...")); + + actionAbout = new QAction(this); + actionAbout->setObjectName("actionAbout"); + actionAbout->setText(tr("&About...")); + + setAcceptDrops(true); +} + + +CGAL_INLINE_FUNCTION +void +DemosMainWindow::dragEnterEvent(QDragEnterEvent *event) +{ + if (event->mimeData()->hasFormat("text/uri-list")) + event->acceptProposedAction(); +} + +CGAL_INLINE_FUNCTION +void +DemosMainWindow::dropEvent(QDropEvent *event) +{ + Q_FOREACH(QUrl url, event->mimeData()->urls()) { + QString filename = url.toLocalFile(); + this->open(filename); + } + event->acceptProposedAction(); +} + +CGAL_INLINE_FUNCTION +void +DemosMainWindow::addNavigation(QGraphicsView* graphicsView) +{ + navigation = new CGAL::Qt::GraphicsViewNavigation(); + graphicsView->viewport()->installEventFilter(navigation); + graphicsView->installEventFilter(navigation); + QObject::connect(navigation, SIGNAL(mouseCoordinates(QString)), + xycoord, SLOT(setText(QString))); + view = graphicsView; +} + +CGAL_INLINE_FUNCTION +void +DemosMainWindow::setupStatusBar() +{ + this->statusBar()->addWidget(new QLabel(this), 1); + this->statusBar()->addWidget(xycoord, 0); +} + +CGAL_INLINE_FUNCTION +void +DemosMainWindow::setupOptionsMenu(QMenu* menuOptions) +{ + // search for the Options menu + if(!menuOptions) { + menuOptions = getMenu("menuOptions", tr("&Options")); + } + + // if not found, then create it + if(!menuOptions) { + menuOptions = new QMenu(this->menuBar()); + menuOptions->setTitle(tr("&Options")); + this->menuBar()->addAction(menuOptions->menuAction()); + menuOptions->setObjectName("menuOptions"); + } + + if(!menuOptions->isEmpty()) { + menuOptions->addSeparator(); + } + menuOptions->addAction(actionUse_OpenGL); + menuOptions->addAction(actionUse_Antialiasing); + connect(actionUse_Antialiasing, SIGNAL(toggled(bool)), + this, SLOT(setUseAntialiasing(bool))); + connect(actionUse_OpenGL, SIGNAL(toggled(bool)), + this, SLOT(setUseOpenGL(bool))); + actionUse_Antialiasing->setChecked(true); +} + +CGAL_INLINE_FUNCTION +void +DemosMainWindow::setUseAntialiasing(bool checked) +{ + view->setRenderHint(QPainter::Antialiasing, checked); +#if QT_VERSION >= 0x040300 + view->setRenderHint(QPainter::HighQualityAntialiasing, checked); +#endif + statusBar()->showMessage(tr("Antialiasing %1activated").arg(checked?"":"de-"), + 1000); +} + +CGAL_INLINE_FUNCTION +void +DemosMainWindow::setUseOpenGL(bool checked) +{ + if(checked) { + QGLWidget* new_viewport = new QGLWidget; + + // Setup the format to allow antialiasing with OpenGL: + // one need to activate the SampleBuffers, if the graphic driver allows + // this. + QGLFormat glformat = new_viewport->format(); + glformat.setOption(QGL::SampleBuffers); + new_viewport->setFormat(glformat); + + view->setViewport(new_viewport); + } + else { + view->setViewport(new QWidget); + } + statusBar()->showMessage(tr("OpenGL %1activated").arg(checked?"":"de-"), + 1000); + view->viewport()->installEventFilter(navigation); + view->setFocus(); +} + +CGAL_INLINE_FUNCTION +QMenu* +DemosMainWindow::getMenu(QString objectName, QString title) +{ + QMenu* menu = NULL; + + QString title2 = title; + title2.remove('&'); + // search if a menu has objectName()==objectName + menu = this->findChild(objectName); + + // then search if a menu has title()==title + if(menu) { + return menu; + } else { + Q_FOREACH(menu, this->findChildren()) { + if(menu->title() == title || + menu->title() == title2) { + return menu; + } + } + } + return NULL; +} + +CGAL_INLINE_FUNCTION +void +DemosMainWindow::popupAboutBox(QString title, QString html_resource_name) +{ + QFile about_CGAL(html_resource_name); + about_CGAL.open(QIODevice::ReadOnly); + QString about_CGAL_txt = QTextStream(&about_CGAL).readAll(); +#ifdef CGAL_VERSION_STR + QString cgal_version(CGAL_VERSION_STR); +# ifdef CGAL_FAKE_PUBLIC_RELEASE + cgal_version.replace(QRegExp("-Ic?.*"), ""); +# endif + about_CGAL_txt.replace("", + QString(" (version %1)") + .arg(cgal_version)); +#endif + QMessageBox mb(QMessageBox::NoIcon, + title, + about_CGAL_txt, + QMessageBox::Ok, + this); + + QLabel* mb_label = mb.findChild("qt_msgbox_label"); + if(mb_label) { + mb_label->setTextInteractionFlags(mb_label->textInteractionFlags() | + ::Qt::LinksAccessibleByMouse | + ::Qt::LinksAccessibleByKeyboard); + } + else { + std::cerr << "Cannot find child \"qt_msgbox_label\" in QMessageBox\n" + << " with Qt version " << QT_VERSION_STR << "!\n"; + } + mb.exec(); +} + +CGAL_INLINE_FUNCTION +QMenu* DemosMainWindow::getHelpMenu() +{ + QMenu* menuHelp = getMenu("menuHelp", tr("&Help")); + if(!menuHelp) { + menuHelp = new QMenu(this->menuBar()); + menuHelp->setTitle(tr("&Help")); + this->menuBar()->addAction(menuHelp->menuAction()); + menuHelp->setObjectName("menuHelp"); + } + return menuHelp; +} + +CGAL_INLINE_FUNCTION +void +DemosMainWindow::addAboutCGAL(QMenu* menuHelp) +{ + if(!menuHelp) { + menuHelp = getHelpMenu(); + } + menuHelp->addAction(actionAboutCGAL); + + connect(actionAboutCGAL, SIGNAL(triggered()), + this, SLOT(popupAboutCGAL())); +} + +CGAL_INLINE_FUNCTION +void +DemosMainWindow::addAboutDemo(QString htmlResourceName, QMenu* menuHelp) +{ + if(!menuHelp) { + menuHelp = getHelpMenu(); + } + menuHelp->addAction(actionAbout); + aboutHtmlResource = htmlResourceName; + + connect(actionAbout, SIGNAL(triggered()), + this, SLOT(popupAboutDemo())); +} + +CGAL_INLINE_FUNCTION +void +DemosMainWindow::popupAboutCGAL() +{ + popupAboutBox(tr("About CGAL..."), + ":/cgal/help/about_CGAL.html"); +} + +CGAL_INLINE_FUNCTION +void +DemosMainWindow::popupAboutDemo() +{ + popupAboutBox(tr("About the demo..."), + aboutHtmlResource); +} + +CGAL_INLINE_FUNCTION +void +DemosMainWindow::setMaxNumberOfRecentFiles(const unsigned int i) +{ + maxNumRecentFiles = i; + recentFileActs.resize(maxNumRecentFiles); +} + +CGAL_INLINE_FUNCTION +unsigned int +DemosMainWindow::maxNumberOfRecentFiles() const +{ + return maxNumRecentFiles; +} + +CGAL_INLINE_FUNCTION +void +DemosMainWindow::openRecentFile_aux() +{ + QAction *action = qobject_cast(sender()); + if (action) + emit openRecentFile(action->data().toString()); +} + +CGAL_INLINE_FUNCTION +void +DemosMainWindow::addToRecentFiles(QString fileName) +{ + QSettings settings; + QStringList files = settings.value("recentFileList").toStringList(); + files.removeAll(fileName); + files.prepend(fileName); + while (files.size() > (int)maxNumberOfRecentFiles()) + files.removeLast(); + + settings.setValue("recentFileList", files); + + updateRecentFileActions(); +} + +CGAL_INLINE_FUNCTION +void +DemosMainWindow::addRecentFiles(QMenu* menu, QAction* insertBeforeAction) +{ + if(!insertBeforeAction) { + recentFilesSeparator = menu->addSeparator(); + } + + for (unsigned int i = 0; i < maxNumberOfRecentFiles(); ++i) { + recentFileActs[i] = new QAction(this); + recentFileActs[i]->setVisible(false); + connect(recentFileActs[i], SIGNAL(triggered()), + this, SLOT(openRecentFile_aux())); + if(insertBeforeAction) + menu->insertAction(insertBeforeAction, recentFileActs[i]); + else + menu->addAction(recentFileActs[i]); + } + + if(insertBeforeAction) { + recentFilesSeparator = menu->insertSeparator(insertBeforeAction); + } + + recentFilesSeparator->setVisible(false); + + updateRecentFileActions(); +} + +CGAL_INLINE_FUNCTION +void +DemosMainWindow::updateRecentFileActions() +{ + QSettings settings; + QStringList files = settings.value("recentFileList").toStringList(); + + int numRecentFiles = qMin(files.size(), (int)this->maxNumberOfRecentFiles()); + + for (int i = 0; i < numRecentFiles; ++i) { + QString strippedName = QFileInfo(files[i]).fileName(); + QString text = tr("&%1 %2").arg(i).arg(strippedName); + recentFileActs[i]->setText(text); + recentFileActs[i]->setData(files[i]); + recentFileActs[i]->setVisible(true); + } + for (unsigned int j = numRecentFiles; j < maxNumberOfRecentFiles(); ++j) + recentFileActs[j]->setVisible(false); + + recentFilesSeparator->setVisible(numRecentFiles > 0); +} + +CGAL_INLINE_FUNCTION +void DemosMainWindow::writeState(QString groupname) +{ + QSettings settings; + + settings.beginGroup(groupname); + settings.setValue("size", size()); + settings.setValue("pos", pos()); + settings.setValue("state", saveState()); + settings.endGroup(); +} + +CGAL_INLINE_FUNCTION +void DemosMainWindow::readState(QString groupname, Options /*what_to_save*/) +{ + QSettings settings; + + settings.beginGroup(groupname); + resize(settings.value("size", this->size()).toSize()); + + QDesktopWidget* desktop = qApp->desktop(); + QPoint pos = settings.value("pos", this->pos()).toPoint(); + if(desktop->availableGeometry(pos).contains(pos)) { + move(pos); + } + QByteArray mainWindowState = settings.value("state").toByteArray(); + if(!mainWindowState.isNull()) { + this->restoreState(mainWindowState); + } + settings.endGroup(); +} + + +} // namespace Qt +} // namespace CGAL diff --git a/GraphicsView/include/CGAL/Qt/GraphicsViewNavigation_impl.h b/GraphicsView/include/CGAL/Qt/GraphicsViewNavigation_impl.h new file mode 100644 index 00000000000..0570920869f --- /dev/null +++ b/GraphicsView/include/CGAL/Qt/GraphicsViewNavigation_impl.h @@ -0,0 +1,351 @@ +// Copyright (c) 2008 GeometryFactory Sarl (France). +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org). +// You can redistribute it and/or modify it under the terms of the GNU +// General Public License as published by the Free Software Foundation, +// either version 3 of the License, or (at your option) any later version. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// +// +// Author(s) : Andreas Fabri +// Laurent Rineau + +#ifdef CGAL_HEADER_ONLY +#define CGAL_INLINE_FUNCTION inline +#else +#define CGAL_INLINE_FUNCTION +#endif + +#include +#include // for mapToScene(QGraphicsView*, QRect) +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace CGAL { +namespace Qt { + + CGAL_INLINE_FUNCTION + GraphicsViewNavigation::GraphicsViewNavigation() + : rectItem(new QGraphicsRectItem), + dragging(false) + { + QColor rect_color(250, 221, 0); + rect_color.setAlpha(50); + rectItem->setBrush(rect_color); + rect_color.setAlpha(255); + rectItem->setPen(QPen(rect_color, 0, ::Qt::DashLine)); + rectItem->hide(); + rectItem->setZValue(10000); + } + + CGAL_INLINE_FUNCTION + GraphicsViewNavigation::~GraphicsViewNavigation() + { + delete rectItem; + } + + CGAL_INLINE_FUNCTION + bool + GraphicsViewNavigation::eventFilter(QObject *obj, QEvent *event) + { + QGraphicsView* v = qobject_cast(obj); + if(v == NULL) { + QWidget* viewport = qobject_cast(obj); + if(viewport == NULL) { + return false; + } + v = qobject_cast(viewport->parent()); + if(v == NULL) { + return false; + } + } + switch(event->type()) + { + case QEvent::KeyPress: { + QKeyEvent *keyEvent = static_cast(event); + int offset = 10; + if( (keyEvent->modifiers() & ::Qt::ShiftModifier) + || (keyEvent->modifiers() & ::Qt::ControlModifier) ) { + offset = 20; + } + switch (keyEvent->key()) { + case ::Qt::Key_Up: + translateView(v, 0, -offset); + break; + case ::Qt::Key_Down: + translateView(v, 0, offset); + break; + case ::Qt::Key_Left: + translateView(v, -offset, 0); + break; + case ::Qt::Key_Right: + translateView(v, offset, 0); + break; + case ::Qt::Key_PageUp: + v->rotate(-6); + break; + case ::Qt::Key_PageDown: + v->rotate(6); + break; + case ::Qt::Key_Plus: + scaleView(v, 1.2); + break; + case ::Qt::Key_Minus: + scaleView(v, 1 / 1.2); + break; + case ::Qt::Key_Control: + cursor_backup = v->cursor(); + v->setCursor(::Qt::CrossCursor); + default: + return false; + } + // display_parameters(); + return true; + break; + } // end case KeyPress + case QEvent::KeyRelease: { + QKeyEvent *keyEvent = static_cast(event); + if(keyEvent->key() == ::Qt::Key_Control) { + if(rectItem->isVisible() ) { + dragging = false; + v->scene()->removeItem(rectItem); + rectItem->hide(); + } + v->setCursor(cursor_backup); + return true; + } + return false; + break; + } // end case KeyRelease + case QEvent::Wheel: { + QWheelEvent *wheelEvent = static_cast(event); + if(wheelEvent->orientation() != ::Qt::Vertical) { + return false; + } + double zoom_ratio = 240.0; + if( (wheelEvent->modifiers() & ::Qt::ShiftModifier) + || (wheelEvent->modifiers() & ::Qt::ControlModifier) ) { + zoom_ratio = 120.0; + } + scaleView(v, pow((double)2, -wheelEvent->delta() / zoom_ratio)); + + // display_parameters(); + return true; + break; + } // end case Wheel + case QEvent::MouseButtonPress: { + QMouseEvent* mouseEvent = static_cast(event); + if( (mouseEvent->modifiers() == (::Qt::ControlModifier | ::Qt::ShiftModifier)) + && mouseEvent->button() == ::Qt::RightButton ) + { + QPoint offset = mouseEvent->pos() - v->viewport()->rect().center(); + translateView(v, offset.x(), offset.y()); + return true; + } + else if( mouseEvent->modifiers() == ::Qt::ControlModifier ) { + if(mouseEvent->button() == ::Qt::LeftButton) { + rect_first_point = v->mapToScene(mouseEvent->pos()); + rectItem->setRect(QRectF(rect_first_point, QSizeF(0.,0.))); + rectItem->show(); + v->scene()->addItem(rectItem); + return true; + } + else if( mouseEvent->button() == ::Qt::RightButton) { + dragging = true; + dragging_start = v->mapToScene(mouseEvent->pos()); + v->setCursor(::Qt::ClosedHandCursor); + return true; + } + } + return false; + break; + } // end case MouseRelease + case QEvent::MouseMove: { + QMouseEvent* mouseEvent = static_cast(event); + QPointF pos = v->mapToScene(mouseEvent->pos()); + QString xy = QString(" ") + QString::number(pos.x(),'g', 6) + " , " + QString::number(pos.y(),'g', 6) + " "; + emit mouseCoordinates(xy); + if(rectItem->isVisible()) { + QPointF size = v->mapToScene(mouseEvent->pos()); + size = size - rect_first_point; + rectItem->setRect(rect_first_point.x(), + rect_first_point.y(), + size.x(), + size.y()); + } + if( dragging ) + { +// std::cerr << boost::format("mouseMove: globalpos=(%1%, %2%)\n" +// " pos=(%3%, %4%)\n" +// " sender=%5% (class %6%), parent class %7%\n") +// % mouseEvent->globalPos().x() +// % mouseEvent->globalPos().y() +// % mouseEvent->pos().x() +// % mouseEvent->pos().y() +// % (&*obj) +// % obj->metaObject()->className() +// % obj->parent()->metaObject()->className(); + +// drag_to(mouseEvent->pos()); + } + break; + } // end MouseMove + case QEvent::MouseButtonRelease: { + QMouseEvent* mouseEvent = static_cast(event); + if(rectItem->isVisible() && mouseEvent->button() == ::Qt::LeftButton){ + v->setSceneRect(v->sceneRect() | rectItem->rect()); + v->fitInView(rectItem->rect(), ::Qt::KeepAspectRatio); + v->scene()->removeItem(rectItem); + rectItem->hide(); + return true; + } + else if( mouseEvent->button() == ::Qt::RightButton ) { + if(dragging) { + dragging = false; + drag_to(v, mouseEvent->pos()); + v->setCursor(cursor_backup); + return true; + } + } + return false; + break; + } // end MouseRelease + default: + return false; + } // end switch + return false; + } + + + CGAL_INLINE_FUNCTION + void + GraphicsViewNavigation::scaleView(QGraphicsView* v, qreal scaleFactor) + { + QPointF center = v->mapToScene(v->viewport()->rect().center()); +// qreal factor = v->matrix().scale(scaleFactor, scaleFactor).mapRect(QRectF(0, 0, 1, 1)).width(); + //if (factor < 0.001 || factor > 2000) + // return; + + v->scale(scaleFactor, scaleFactor); + QPoint offset = v->mapFromScene(center) - v->viewport()->rect().center(); + translateView(v, offset.x(), offset.y()); + } + + CGAL_INLINE_FUNCTION + void GraphicsViewNavigation::drag_to(QGraphicsView* v, QPoint new_pos) + { + QPoint dragging_start_in_view = v->mapFromScene(dragging_start); + QPoint offset = new_pos - dragging_start_in_view; +// std::cerr << boost::format("drag_to: origin=(%1%, %2%)\n" +// " offset=(%3%, %4%)\n") +// % dragging_start_in_view.x() % dragging_start_in_view.y() +// % offset.x() % offset.y(); + translateView(v, -offset.x(), -offset.y()); + dragging_start_in_view = v->mapFromScene(dragging_start); +// std::cerr << boost::format(" after=(%1%, %2%)\n") +// % dragging_start_in_view.x() % dragging_start_in_view.y(); + } + + CGAL_INLINE_FUNCTION + void GraphicsViewNavigation::translateView(QGraphicsView* v, int dx, int dy) + { + if( dx == 0 && dy == 0 ) { + return; + } + + int horizontalScrollBarValue = v->horizontalScrollBar()->value(); + int verticalScrollBarValue = v->verticalScrollBar()->value(); + + if( (horizontalScrollBarValue + dx <= + v->horizontalScrollBar()->maximum()) && + (horizontalScrollBarValue + dx >= + v->horizontalScrollBar()->minimum()) && + (verticalScrollBarValue + dy <= + v->verticalScrollBar()->maximum()) && + (verticalScrollBarValue + dy >= + v->verticalScrollBar()->minimum()) ) + { + v->horizontalScrollBar()->setValue(horizontalScrollBarValue + dx); + v->verticalScrollBar()->setValue(verticalScrollBarValue + dy); + } + else + { + QRect vp_rect = v->viewport()->rect(); + QPointF new_center = v->mapToScene(vp_rect.center() + QPoint(dx, dy)); + vp_rect |= vp_rect.translated(dx, dy); + QRectF rect = mapToScene(v, vp_rect); + v->setSceneRect(v->sceneRect() | rect); + v->centerOn(new_center); + + // QGraphicsView::centerOn makes rounding errors. + // The following two "if" make them unnoticable when dx==0 or dy==0. + if(dx == 0) { + v->horizontalScrollBar()->setValue(horizontalScrollBarValue); + } + if(dy == 0) { + v->verticalScrollBar()->setValue(verticalScrollBarValue); + } + } +// display_parameters(); + } + + CGAL_INLINE_FUNCTION + void GraphicsViewNavigation::display_parameters(QGraphicsView* v) + { + std::cerr << + boost::format("matrix translation=(%1%, %2%)\n" + " rotation=(%3% - %4% )\n" + " (%5% - %6% )\n") + % v->matrix().dx() + % v->matrix().dy() + % v->matrix().m11() + % v->matrix().m12() + % v->matrix().m21() + % v->matrix().m22(); + + QRect vp_rect = v->viewport()->rect(); + QPoint vp_top_left = vp_rect.topLeft(); + QPoint vp_bottom_right = vp_rect.bottomRight(); + QPointF top_left = v->mapToScene(vp_top_left); + QPointF bottom_right = v->mapToScene(vp_bottom_right); + + std::cerr << + boost::format("view=(%1% - %2%) x (%3% - %4%)\n") + % top_left.x() % bottom_right.x() + % top_left.y() % bottom_right.y(); + std::cerr << + boost::format("viewport=(%1% - %2%) x (%3% - %4%)\n") + % vp_top_left.x() % vp_bottom_right.x() + % vp_top_left.y() % vp_bottom_right.y(); + std::cerr << + boost::format("scrollbars=(%1% <= %2% <= %3%) x (%4% <= %5% <= %6%)\n") + % v->horizontalScrollBar()->minimum() + % v->horizontalScrollBar()->value() + % v->horizontalScrollBar()->maximum() + % v->verticalScrollBar()->minimum() + % v->verticalScrollBar()->value() + % v->verticalScrollBar()->maximum(); + } + +} // namespace Qt +} // namespace CGAL + diff --git a/GraphicsView/include/CGAL/Qt/GraphicsViewPolylineInput_impl.h b/GraphicsView/include/CGAL/Qt/GraphicsViewPolylineInput_impl.h new file mode 100644 index 00000000000..fa7a88b9c94 --- /dev/null +++ b/GraphicsView/include/CGAL/Qt/GraphicsViewPolylineInput_impl.h @@ -0,0 +1,208 @@ +// Copyright (c) 2008 GeometryFactory Sarl (France). +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org). +// You can redistribute it and/or modify it under the terms of the GNU +// General Public License as published by the Free Software Foundation, +// either version 3 of the License, or (at your option) any later version. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// +// +// Author(s) : Andreas Fabri +// Laurent Rineau + +#ifdef CGAL_HEADER_ONLY +#define CGAL_INLINE_FUNCTION inline +#else +#define CGAL_INLINE_FUNCTION +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +namespace CGAL { +namespace Qt { + +CGAL_INLINE_FUNCTION +GraphicsViewPolylineInput_non_templated_base:: +GraphicsViewPolylineInput_non_templated_base(QObject* parent, + QGraphicsScene* s, + int n, + bool closed) + : GraphicsViewInput(parent), closed_(closed), path_item(NULL), b(NULL), e(NULL), n_(n), scene_(s) +{} + + +CGAL_INLINE_FUNCTION +bool +GraphicsViewPolylineInput_non_templated_base::mousePressEvent(QGraphicsSceneMouseEvent *event) +{ + if( event->modifiers() ){ + return false; + } + if( event->button() != ::Qt::RightButton + && event->button() != ::Qt::LeftButton ){ + return false; + } + polygon.push_back(event->scenePos()); + if(path_item){ + scene_->removeItem(path_item); + delete path_item; + path_item = NULL; + } + if( (event->button() == ::Qt::RightButton) || (polygon.size() == n_) ){ + // call the virtual function generate_polygon(), that emit a + // CGAL::Object containing a list of points + generate_polygon(); + polygon.clear(); + if(b){ + scene_->removeItem(b); + delete b; + b = NULL; + } + if(e){ + scene_->removeItem(e); + delete e; + e = NULL; + } + return true; + } + if(event->button() == ::Qt::LeftButton){ + QPainterPath qpp; + qpp.addPolygon(polygon); + path_item = new QGraphicsPathItem(qpp); + path_item->setPen(QPen(::Qt::red, 0, ::Qt::SolidLine, ::Qt::RoundCap, ::Qt::RoundJoin)); + scene_->addItem(path_item); + return true; + } + return false; +} + + +CGAL_INLINE_FUNCTION +void +GraphicsViewPolylineInput_non_templated_base::rubberbands(const QPointF& p) +{ + if(polygon.empty()){ + return; + } + if(!b && closed_ ){ + b = new QGraphicsLineItem(); + b->setPen(QPen(::Qt::red, 0, ::Qt::SolidLine, ::Qt::RoundCap, ::Qt::RoundJoin)); + scene_->addItem(b); + } + if( !e){ + e = new QGraphicsLineItem(); + e->setPen(QPen(::Qt::red, 0, ::Qt::SolidLine, ::Qt::RoundCap, ::Qt::RoundJoin)); + scene_->addItem(e); + } + if(closed_){ + QLineF bLine(polygon.front(), p); + b->setLine(bLine); + } + QLineF eLine(polygon.back(), p); + e->setLine(eLine); +} + + +CGAL_INLINE_FUNCTION +void +GraphicsViewPolylineInput_non_templated_base::mouseMoveEvent(QGraphicsSceneMouseEvent *event) +{ + sp = event->scenePos(); + rubberbands(sp); +} + + +CGAL_INLINE_FUNCTION +bool +GraphicsViewPolylineInput_non_templated_base::keyPressEvent ( QKeyEvent * event ) +{ + if( event->modifiers() ) + return false; + + switch(event->key()) + { + case ::Qt::Key_Delete: + case ::Qt::Key_Escape: + case ::Qt::Key_Backspace: + break; + default: + return false; + } + if(polygon.empty()){ + return true; + } + polygon.pop_back(); + if(polygon.empty()){ + if(b){ + scene_->removeItem(b); + delete b; + b = NULL; + } + if(e){ + scene_->removeItem(e); + delete e; + e = NULL; + } + return true; + } + if(path_item){ + scene_->removeItem(path_item); + delete path_item; + path_item = NULL; + } + QPainterPath qpp; + qpp.addPolygon(polygon); + path_item = new QGraphicsPathItem(qpp); + path_item->setPen(QPen(::Qt::red, 0, ::Qt::SolidLine, ::Qt::RoundCap, ::Qt::RoundJoin)); + scene_->addItem(path_item); + rubberbands(sp); + return true; +} + + + +CGAL_INLINE_FUNCTION +bool +GraphicsViewPolylineInput_non_templated_base::eventFilter(QObject *obj, QEvent *event) +{ + if (event->type() == QEvent::GraphicsSceneMousePress) { + QGraphicsSceneMouseEvent *mouseEvent = static_cast(event); + if(!mousePressEvent(mouseEvent)) { + // standard event processing if mousePressEvent has returned false + return QObject::eventFilter(obj, event); + } + } else if (event->type() == QEvent::GraphicsSceneMouseMove) { + QGraphicsSceneMouseEvent *mouseEvent = static_cast(event); + mouseMoveEvent(mouseEvent); + return QObject::eventFilter(obj, event); + } else if (event->type() == QEvent::KeyPress) { + QKeyEvent *keyEvent = static_cast(event); + if(!keyPressEvent(keyEvent)) { + return QObject::eventFilter(obj, event); + } + } + // standard event processing if keyPressEvent has returned false + return QObject::eventFilter(obj, event); +} + +} // namespace Qt +} // namespace CGAL diff --git a/GraphicsView/include/CGAL/Qt/debug_impl.h b/GraphicsView/include/CGAL/Qt/debug_impl.h new file mode 100644 index 00000000000..e7bf2904420 --- /dev/null +++ b/GraphicsView/include/CGAL/Qt/debug_impl.h @@ -0,0 +1,60 @@ +// Copyright (c) 2008 GeometryFactory Sarl (France). +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org). +// You can redistribute it and/or modify it under the terms of the GNU +// General Public License as published by the Free Software Foundation, +// either version 3 of the License, or (at your option) any later version. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// +// +// Author(s) : Andreas Fabri +// Laurent Rineau + +#ifdef CGAL_HEADER_ONLY +#define CGAL_INLINE_FUNCTION inline +#else +#define CGAL_INLINE_FUNCTION +#endif + +#include +#include + +#include + +namespace CGAL { +namespace Qt { + + +CGAL_INLINE_FUNCTION +void traverse_resources(const QString& name, const QString& dirname, int indent) +{ + std::cerr << qPrintable(QString(indent, ' ')) + << qPrintable(name); + QString fullname = + dirname.isEmpty() ? + name : + dirname + "/" + name; + QDir dir(fullname); + if(dir.exists()) { + std::cerr << "/\n"; + Q_FOREACH(QString path, dir.entryList()) + { + traverse_resources(path, fullname, indent + 2); + } + } + else { + std::cerr << "\n"; + } +} + +} // namesapce Qt +} // namespace CGAL diff --git a/GraphicsView/include/CGAL/Qt/resources_impl.h b/GraphicsView/include/CGAL/Qt/resources_impl.h new file mode 100644 index 00000000000..bfe784c860c --- /dev/null +++ b/GraphicsView/include/CGAL/Qt/resources_impl.h @@ -0,0 +1,37 @@ +// Copyright (c) 2011 GeometryFactory Sarl (France). +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org). +// You can redistribute it and/or modify it under the terms of the GNU +// General Public License as published by the Free Software Foundation, +// either version 3 of the License, or (at your option) any later version. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// +// +// Author(s) : Laurent Rineau + +#ifdef CGAL_HEADER_ONLY +#define CGAL_INLINE_FUNCTION inline +#else +#define CGAL_INLINE_FUNCTION +#endif + +#include +#include + +// cannot use namespaces because of the Q_INIT_RESOURCE macro +CGAL_INLINE_FUNCTION +void CGAL_Qt4_init_resources() { + Q_INIT_RESOURCE(File); + Q_INIT_RESOURCE(Triangulation_2); + Q_INIT_RESOURCE(Input); + Q_INIT_RESOURCE(CGAL); +} diff --git a/GraphicsView/include/CGAL/Qt/utility_impl.h b/GraphicsView/include/CGAL/Qt/utility_impl.h new file mode 100644 index 00000000000..4fea3451f07 --- /dev/null +++ b/GraphicsView/include/CGAL/Qt/utility_impl.h @@ -0,0 +1,62 @@ +// Copyright (c) 2008 GeometryFactory Sarl (France). +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org). +// You can redistribute it and/or modify it under the terms of the GNU +// General Public License as published by the Free Software Foundation, +// either version 3 of the License, or (at your option) any later version. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// +// +// Author(s) : Andreas Fabri +// Laurent Rineau + +#ifdef CGAL_HEADER_ONLY +#define CGAL_INLINE_FUNCTION inline +#else +#define CGAL_INLINE_FUNCTION +#endif + +#include +#include +#include +#include +#include +#include + +namespace CGAL { +namespace Qt { + +CGAL_INLINE_FUNCTION +QRectF mapToScene(const QGraphicsView* v, const QRect rect) +{ + QPointF top_left = v->mapToScene(rect.topLeft()); + QPointF size = v->mapToScene(rect.bottomRight()); + size -= top_left; + return QRectF(top_left.x(), + top_left.y(), + size.x(), + size.y()); +} + +CGAL_INLINE_FUNCTION +QRectF viewportsBbox(const QGraphicsScene* scene) { + QRectF rect; + Q_FOREACH(QGraphicsView* view, scene->views()) + { + rect |= mapToScene(view, view->viewport()->rect()); + } + rect = rect.normalized(); + return rect; +} + +} // namespace Qt +} // namespace CGAL