From 5b5069535eff4df7d97eafe9912235dd35823bad Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Tue, 1 Apr 2014 10:04:14 +0200 Subject: [PATCH 1/9] keep track of active cells in PagedWorldspaceWidget and update SubView title accordingly --- .../view/render/pagedworldspacewidget.cpp | 37 ++++++++++++++++++- .../view/render/pagedworldspacewidget.hpp | 14 +++++++ apps/opencs/view/render/worldspacewidget.cpp | 2 + apps/opencs/view/render/worldspacewidget.hpp | 3 ++ apps/opencs/view/world/scenesubview.cpp | 30 ++++++++++++++- apps/opencs/view/world/scenesubview.hpp | 4 ++ 6 files changed, 87 insertions(+), 3 deletions(-) diff --git a/apps/opencs/view/render/pagedworldspacewidget.cpp b/apps/opencs/view/render/pagedworldspacewidget.cpp index fa32e3959..96d44543e 100644 --- a/apps/opencs/view/render/pagedworldspacewidget.cpp +++ b/apps/opencs/view/render/pagedworldspacewidget.cpp @@ -1,6 +1,39 @@ #include "pagedworldspacewidget.hpp" +#include + CSVRender::PagedWorldspaceWidget::PagedWorldspaceWidget (QWidget *parent) -: WorldspaceWidget (parent) -{} \ No newline at end of file +: WorldspaceWidget (parent), mMin (std::make_pair (0, 0)), mMax (std::make_pair (-1, -1)) +{} + +void CSVRender::PagedWorldspaceWidget::useViewHint (const std::string& hint) +{ + if (!hint.empty()) + { + if (hint[0]=='c') + { + char ignore1, ignore2, ignore3; + std::pair cellIndex; + + std::istringstream stream (hint.c_str()); + if (stream >> ignore1 >> ignore2 >> ignore3 >> cellIndex.first >> cellIndex.second) + { + setCellIndex (cellIndex, cellIndex); + + /// \todo adjust camera position + } + } + + /// \todo implement 'r' type hints + } +} + +void CSVRender::PagedWorldspaceWidget::setCellIndex (const std::pair& min, + const std::pair& max) +{ + mMin = min; + mMax = max; + + emit cellIndexChanged (mMin, mMax); +} \ No newline at end of file diff --git a/apps/opencs/view/render/pagedworldspacewidget.hpp b/apps/opencs/view/render/pagedworldspacewidget.hpp index 172e2477a..9a4b79c3a 100644 --- a/apps/opencs/view/render/pagedworldspacewidget.hpp +++ b/apps/opencs/view/render/pagedworldspacewidget.hpp @@ -9,9 +9,23 @@ namespace CSVRender { Q_OBJECT + std::pair mMin; + std::pair mMax; + public: PagedWorldspaceWidget (QWidget *parent); + ///< \note Sets the cell area selection to an invalid value to indicate that currently + /// no cells are displayed. The cells to be displayed will be specified later through + /// hint system. + + virtual void useViewHint (const std::string& hint); + + void setCellIndex (const std::pair& min, const std::pair& max); + + signals: + + void cellIndexChanged (const std::pair& min, const std::pair& max); }; } diff --git a/apps/opencs/view/render/worldspacewidget.cpp b/apps/opencs/view/render/worldspacewidget.cpp index 9959c5a67..4d2442c89 100644 --- a/apps/opencs/view/render/worldspacewidget.cpp +++ b/apps/opencs/view/render/worldspacewidget.cpp @@ -26,6 +26,8 @@ void CSVRender::WorldspaceWidget::selectNavigationMode (const std::string& mode) setNavigation (&mOrbit); } +void CSVRender::WorldspaceWidget::useViewHint (const std::string& hint) {} + void CSVRender::WorldspaceWidget::selectDefaultNavigationMode() { setNavigation (&m1st); diff --git a/apps/opencs/view/render/worldspacewidget.hpp b/apps/opencs/view/render/worldspacewidget.hpp index 7921c3560..f7208d7a1 100644 --- a/apps/opencs/view/render/worldspacewidget.hpp +++ b/apps/opencs/view/render/worldspacewidget.hpp @@ -33,6 +33,9 @@ namespace CSVRender void selectDefaultNavigationMode(); + virtual void useViewHint (const std::string& hint); + ///< Default-implementation: ignored. + private slots: void selectNavigationMode (const std::string& mode); diff --git a/apps/opencs/view/world/scenesubview.cpp b/apps/opencs/view/world/scenesubview.cpp index 10e8b4071..c075cb4d6 100644 --- a/apps/opencs/view/world/scenesubview.cpp +++ b/apps/opencs/view/world/scenesubview.cpp @@ -1,6 +1,8 @@ #include "scenesubview.hpp" +#include + #include #include #include @@ -35,7 +37,14 @@ CSVWorld::SceneSubView::SceneSubView (const CSMWorld::UniversalId& id, CSMDoc::D SceneToolbar *toolbar = new SceneToolbar (48, this); if (id.getId()=="sys::default") - mScene = new CSVRender::PagedWorldspaceWidget (this); + { + CSVRender::PagedWorldspaceWidget *widget = new CSVRender::PagedWorldspaceWidget (this); + mScene = widget; + connect (widget, + SIGNAL (cellIndexChanged (const std::pair&, const std::pair&)), + this, + SLOT (cellIndexChanged (const std::pair&, const std::pair&))); + } else mScene = new CSVRender::UnpagedWorldspaceWidget (id.getId(), document, this); @@ -83,7 +92,26 @@ void CSVWorld::SceneSubView::setStatusBar (bool show) mBottom->setStatusBar (show); } +void CSVWorld::SceneSubView::useHint (const std::string& hint) +{ + mScene->useViewHint (hint); +} + void CSVWorld::SceneSubView::closeRequest() { deleteLater(); +} + +void CSVWorld::SceneSubView::cellIndexChanged (const std::pair& min, + const std::pair& max) +{ + std::ostringstream stream; + stream << "Scene: " << getUniversalId().getId() << " (" << min.first << ", " << min.second; + + if (min!=max) + stream << " to " << max.first << ", " << max.second; + + stream << ")"; + + setWindowTitle (QString::fromUtf8 (stream.str().c_str())); } \ No newline at end of file diff --git a/apps/opencs/view/world/scenesubview.hpp b/apps/opencs/view/world/scenesubview.hpp index ecf3fe4e4..ee5b7b41f 100644 --- a/apps/opencs/view/world/scenesubview.hpp +++ b/apps/opencs/view/world/scenesubview.hpp @@ -38,9 +38,13 @@ namespace CSVWorld virtual void setStatusBar (bool show); + virtual void useHint (const std::string& hint); + private slots: void closeRequest(); + + void cellIndexChanged (const std::pair& min, const std::pair& max); }; } From 5d422fec8abd5f52adb1de423cd0effb3d4a6cb4 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Thu, 3 Apr 2014 13:00:19 +0200 Subject: [PATCH 2/9] fixed scene toolbar layout problems --- apps/opencs/view/world/scenetool.cpp | 1 + apps/opencs/view/world/scenetoolbar.cpp | 7 ++++++- apps/opencs/view/world/scenetoolbar.hpp | 3 +++ apps/opencs/view/world/scenetoolmode.cpp | 3 ++- apps/opencs/view/world/scenetoolmode.hpp | 1 + 5 files changed, 13 insertions(+), 2 deletions(-) diff --git a/apps/opencs/view/world/scenetool.cpp b/apps/opencs/view/world/scenetool.cpp index 320deb1ba..612b4c6d3 100644 --- a/apps/opencs/view/world/scenetool.cpp +++ b/apps/opencs/view/world/scenetool.cpp @@ -6,6 +6,7 @@ CSVWorld::SceneTool::SceneTool (SceneToolbar *parent) : QPushButton (parent) { setSizePolicy (QSizePolicy (QSizePolicy::Fixed, QSizePolicy::Fixed)); + setIconSize (QSize (parent->getIconSize(), parent->getIconSize())); setFixedSize (parent->getButtonSize(), parent->getButtonSize()); connect (this, SIGNAL (clicked()), this, SLOT (openRequest())); diff --git a/apps/opencs/view/world/scenetoolbar.cpp b/apps/opencs/view/world/scenetoolbar.cpp index 2972c5391..9eb02ce2f 100644 --- a/apps/opencs/view/world/scenetoolbar.cpp +++ b/apps/opencs/view/world/scenetoolbar.cpp @@ -6,7 +6,7 @@ #include "scenetool.hpp" CSVWorld::SceneToolbar::SceneToolbar (int buttonSize, QWidget *parent) -: QWidget (parent), mButtonSize (buttonSize) +: QWidget (parent), mButtonSize (buttonSize), mIconSize (buttonSize-8) { setFixedWidth (mButtonSize); @@ -26,4 +26,9 @@ void CSVWorld::SceneToolbar::addTool (SceneTool *tool) int CSVWorld::SceneToolbar::getButtonSize() const { return mButtonSize; +} + +int CSVWorld::SceneToolbar::getIconSize() const +{ + return mIconSize; } \ No newline at end of file diff --git a/apps/opencs/view/world/scenetoolbar.hpp b/apps/opencs/view/world/scenetoolbar.hpp index f713ca3df..731806cc5 100644 --- a/apps/opencs/view/world/scenetoolbar.hpp +++ b/apps/opencs/view/world/scenetoolbar.hpp @@ -15,6 +15,7 @@ namespace CSVWorld QVBoxLayout *mLayout; int mButtonSize; + int mIconSize; public: @@ -23,6 +24,8 @@ namespace CSVWorld void addTool (SceneTool *tool); int getButtonSize() const; + + int getIconSize() const; }; } diff --git a/apps/opencs/view/world/scenetoolmode.cpp b/apps/opencs/view/world/scenetoolmode.cpp index 281d703b6..73b01ae3a 100644 --- a/apps/opencs/view/world/scenetoolmode.cpp +++ b/apps/opencs/view/world/scenetoolmode.cpp @@ -8,7 +8,7 @@ #include "scenetoolbar.hpp" CSVWorld::SceneToolMode::SceneToolMode (SceneToolbar *parent) -: SceneTool (parent), mButtonSize (parent->getButtonSize()) +: SceneTool (parent), mButtonSize (parent->getButtonSize()), mIconSize (parent->getIconSize()) { mPanel = new QFrame (this, Qt::Popup); @@ -29,6 +29,7 @@ void CSVWorld::SceneToolMode::addButton (const std::string& icon, const std::str { QPushButton *button = new QPushButton (QIcon (QPixmap (icon.c_str())), "", mPanel); button->setSizePolicy (QSizePolicy (QSizePolicy::Fixed, QSizePolicy::Fixed)); + button->setIconSize (QSize (mIconSize, mIconSize)); button->setFixedSize (mButtonSize, mButtonSize); mLayout->addWidget (button); diff --git a/apps/opencs/view/world/scenetoolmode.hpp b/apps/opencs/view/world/scenetoolmode.hpp index a8fe2b5a6..a156c0c95 100644 --- a/apps/opencs/view/world/scenetoolmode.hpp +++ b/apps/opencs/view/world/scenetoolmode.hpp @@ -20,6 +20,7 @@ namespace CSVWorld QHBoxLayout *mLayout; std::map mButtons; // widget, id int mButtonSize; + int mIconSize; public: From 3a58da9ad78ade99a388923dafdfb29bc4110d8d Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Thu, 3 Apr 2014 13:30:22 +0200 Subject: [PATCH 3/9] size adjustment --- apps/opencs/view/world/scenetoolbar.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/opencs/view/world/scenetoolbar.cpp b/apps/opencs/view/world/scenetoolbar.cpp index 9eb02ce2f..d60240da7 100644 --- a/apps/opencs/view/world/scenetoolbar.cpp +++ b/apps/opencs/view/world/scenetoolbar.cpp @@ -6,7 +6,7 @@ #include "scenetool.hpp" CSVWorld::SceneToolbar::SceneToolbar (int buttonSize, QWidget *parent) -: QWidget (parent), mButtonSize (buttonSize), mIconSize (buttonSize-8) +: QWidget (parent), mButtonSize (buttonSize), mIconSize (buttonSize-6) { setFixedWidth (mButtonSize); From baf30ba29295a8535f3af18961060e72d8ec9a09 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Thu, 3 Apr 2014 14:44:48 +0200 Subject: [PATCH 4/9] added grid tool (does not work yet) --- apps/opencs/CMakeLists.txt | 2 +- apps/opencs/view/world/scenesubview.cpp | 13 ++++ apps/opencs/view/world/scenetoolgrid.cpp | 75 ++++++++++++++++++++++++ apps/opencs/view/world/scenetoolgrid.hpp | 29 +++++++++ 4 files changed, 118 insertions(+), 1 deletion(-) create mode 100644 apps/opencs/view/world/scenetoolgrid.cpp create mode 100644 apps/opencs/view/world/scenetoolgrid.hpp diff --git a/apps/opencs/CMakeLists.txt b/apps/opencs/CMakeLists.txt index a7a694463..05cc93f89 100644 --- a/apps/opencs/CMakeLists.txt +++ b/apps/opencs/CMakeLists.txt @@ -60,7 +60,7 @@ opencs_hdrs_noqt (view/doc opencs_units (view/world table tablesubview scriptsubview util regionmapsubview tablebottombox creator genericcreator cellcreator referenceablecreator referencecreator scenesubview scenetoolbar scenetool - scenetoolmode infocreator scriptedit dialoguesubview previewsubview + scenetoolmode infocreator scriptedit dialoguesubview previewsubview scenetoolgrid ) opencs_units (view/render diff --git a/apps/opencs/view/world/scenesubview.cpp b/apps/opencs/view/world/scenesubview.cpp index c075cb4d6..dedaf014b 100644 --- a/apps/opencs/view/world/scenesubview.cpp +++ b/apps/opencs/view/world/scenesubview.cpp @@ -18,6 +18,7 @@ #include "creator.hpp" #include "scenetoolbar.hpp" #include "scenetoolmode.hpp" +#include "scenetoolgrid.hpp" CSVWorld::SceneSubView::SceneSubView (const CSMWorld::UniversalId& id, CSMDoc::Document& document) : SubView (id) @@ -36,6 +37,8 @@ CSVWorld::SceneSubView::SceneSubView (const CSMWorld::UniversalId& id, CSMDoc::D SceneToolbar *toolbar = new SceneToolbar (48, this); + SceneToolGrid *gridTool = 0; + if (id.getId()=="sys::default") { CSVRender::PagedWorldspaceWidget *widget = new CSVRender::PagedWorldspaceWidget (this); @@ -44,6 +47,13 @@ CSVWorld::SceneSubView::SceneSubView (const CSMWorld::UniversalId& id, CSMDoc::D SIGNAL (cellIndexChanged (const std::pair&, const std::pair&)), this, SLOT (cellIndexChanged (const std::pair&, const std::pair&))); + + gridTool = new SceneToolGrid (toolbar); + + connect (widget, + SIGNAL (cellIndexChanged (const std::pair&, const std::pair&)), + gridTool, + SLOT (cellIndexChanged (const std::pair&, const std::pair&))); } else mScene = new CSVRender::UnpagedWorldspaceWidget (id.getId(), document, this); @@ -54,6 +64,9 @@ CSVWorld::SceneSubView::SceneSubView (const CSMWorld::UniversalId& id, CSMDoc::D SceneToolMode *lightingTool = mScene->makeLightingSelector (toolbar); toolbar->addTool (lightingTool); + if (gridTool) + toolbar->addTool (gridTool); + layout2->addWidget (toolbar, 0); layout2->addWidget (mScene, 1); diff --git a/apps/opencs/view/world/scenetoolgrid.cpp b/apps/opencs/view/world/scenetoolgrid.cpp new file mode 100644 index 000000000..0769be168 --- /dev/null +++ b/apps/opencs/view/world/scenetoolgrid.cpp @@ -0,0 +1,75 @@ + +#include "scenetoolgrid.hpp" + +#include + +#include +#include +#include + +#include "scenetoolbar.hpp" + +CSVWorld::SceneToolGrid::SceneToolGrid (SceneToolbar *parent) +: SceneTool (parent), mIconSize (parent->getIconSize()) +{ +} + +void CSVWorld::SceneToolGrid::showPanel (const QPoint& position) +{ + + +} + +void CSVWorld::SceneToolGrid::cellIndexChanged (const std::pair& min, + const std::pair& max) +{ + /// \todo make font size configurable + const int fontSize = 8; + + /// \todo replace with proper icon + QPixmap image (mIconSize, mIconSize); + image.fill (QColor (0, 0, 0, 0)); + + { + QPainter painter (&image); + painter.setPen (Qt::black); + QFont font (QApplication::font().family(), fontSize); + painter.setFont (font); + + QFontMetrics metrics (font); + + if (min==max) + { + // single cell + std::ostringstream stream; + stream << min.first << ", " << min.second; + + QString text = QString::fromUtf8 (stream.str().c_str()); + + painter.drawText (QPoint ((mIconSize-metrics.width (text))/2, mIconSize/2+fontSize/2), + text); + } + else + { + // range + { + std::ostringstream stream; + stream << min.first << ", " << min.second; + painter.drawText (QPoint (0, mIconSize), + QString::fromUtf8 (stream.str().c_str())); + } + + { + std::ostringstream stream; + stream << max.first << ", " << max.second; + + QString text = QString::fromUtf8 (stream.str().c_str()); + + painter.drawText (QPoint (mIconSize-metrics.width (text), fontSize), text); + } + } + } + + QIcon icon (image); + setIcon (icon); +} \ No newline at end of file diff --git a/apps/opencs/view/world/scenetoolgrid.hpp b/apps/opencs/view/world/scenetoolgrid.hpp new file mode 100644 index 000000000..917df2a16 --- /dev/null +++ b/apps/opencs/view/world/scenetoolgrid.hpp @@ -0,0 +1,29 @@ +#ifndef CSV_WORLD_SCENETOOL_GRID_H +#define CSV_WORLD_SCENETOOL_GRID_H + +#include "scenetool.hpp" + +namespace CSVWorld +{ + class SceneToolbar; + + ///< \brief Cell grid selector tool + class SceneToolGrid : public SceneTool + { + Q_OBJECT + + int mIconSize; + + public: + + SceneToolGrid (SceneToolbar *parent); + + virtual void showPanel (const QPoint& position); + + public slots: + + void cellIndexChanged (const std::pair& min, const std::pair& max); + }; +} + +#endif From 0fe67b586a6c8156eb598887550b995dce8c7304 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sat, 5 Apr 2014 13:16:13 +0200 Subject: [PATCH 5/9] increased scene toolbar button size --- apps/opencs/view/world/previewsubview.cpp | 2 +- apps/opencs/view/world/scenesubview.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/opencs/view/world/previewsubview.cpp b/apps/opencs/view/world/previewsubview.cpp index ac9776d22..e9a30e65d 100644 --- a/apps/opencs/view/world/previewsubview.cpp +++ b/apps/opencs/view/world/previewsubview.cpp @@ -28,7 +28,7 @@ CSVWorld::PreviewSubView::PreviewSubView (const CSMWorld::UniversalId& id, CSMDo else mScene = new CSVRender::PreviewWidget (document.getData(), id.getId(), this); - SceneToolbar *toolbar = new SceneToolbar (48, this); + SceneToolbar *toolbar = new SceneToolbar (48+6, this); SceneToolMode *lightingTool = mScene->makeLightingSelector (toolbar); toolbar->addTool (lightingTool); diff --git a/apps/opencs/view/world/scenesubview.cpp b/apps/opencs/view/world/scenesubview.cpp index dedaf014b..d62793cc9 100644 --- a/apps/opencs/view/world/scenesubview.cpp +++ b/apps/opencs/view/world/scenesubview.cpp @@ -35,7 +35,7 @@ CSVWorld::SceneSubView::SceneSubView (const CSMWorld::UniversalId& id, CSMDoc::D layout2->setContentsMargins (QMargins (0, 0, 0, 0)); - SceneToolbar *toolbar = new SceneToolbar (48, this); + SceneToolbar *toolbar = new SceneToolbar (48+6, this); SceneToolGrid *gridTool = 0; From 324b2743d447bb3d6f2a18dae780ea3783857070 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Mon, 7 Apr 2014 10:21:26 +0200 Subject: [PATCH 6/9] removed grid button (discarding the first attempt at a cell selector) --- apps/opencs/CMakeLists.txt | 2 +- apps/opencs/view/world/scenesubview.cpp | 13 ---- apps/opencs/view/world/scenetoolgrid.cpp | 75 ------------------------ apps/opencs/view/world/scenetoolgrid.hpp | 29 --------- 4 files changed, 1 insertion(+), 118 deletions(-) delete mode 100644 apps/opencs/view/world/scenetoolgrid.cpp delete mode 100644 apps/opencs/view/world/scenetoolgrid.hpp diff --git a/apps/opencs/CMakeLists.txt b/apps/opencs/CMakeLists.txt index 05cc93f89..a7a694463 100644 --- a/apps/opencs/CMakeLists.txt +++ b/apps/opencs/CMakeLists.txt @@ -60,7 +60,7 @@ opencs_hdrs_noqt (view/doc opencs_units (view/world table tablesubview scriptsubview util regionmapsubview tablebottombox creator genericcreator cellcreator referenceablecreator referencecreator scenesubview scenetoolbar scenetool - scenetoolmode infocreator scriptedit dialoguesubview previewsubview scenetoolgrid + scenetoolmode infocreator scriptedit dialoguesubview previewsubview ) opencs_units (view/render diff --git a/apps/opencs/view/world/scenesubview.cpp b/apps/opencs/view/world/scenesubview.cpp index d62793cc9..4ebaa9352 100644 --- a/apps/opencs/view/world/scenesubview.cpp +++ b/apps/opencs/view/world/scenesubview.cpp @@ -18,7 +18,6 @@ #include "creator.hpp" #include "scenetoolbar.hpp" #include "scenetoolmode.hpp" -#include "scenetoolgrid.hpp" CSVWorld::SceneSubView::SceneSubView (const CSMWorld::UniversalId& id, CSMDoc::Document& document) : SubView (id) @@ -37,8 +36,6 @@ CSVWorld::SceneSubView::SceneSubView (const CSMWorld::UniversalId& id, CSMDoc::D SceneToolbar *toolbar = new SceneToolbar (48+6, this); - SceneToolGrid *gridTool = 0; - if (id.getId()=="sys::default") { CSVRender::PagedWorldspaceWidget *widget = new CSVRender::PagedWorldspaceWidget (this); @@ -47,13 +44,6 @@ CSVWorld::SceneSubView::SceneSubView (const CSMWorld::UniversalId& id, CSMDoc::D SIGNAL (cellIndexChanged (const std::pair&, const std::pair&)), this, SLOT (cellIndexChanged (const std::pair&, const std::pair&))); - - gridTool = new SceneToolGrid (toolbar); - - connect (widget, - SIGNAL (cellIndexChanged (const std::pair&, const std::pair&)), - gridTool, - SLOT (cellIndexChanged (const std::pair&, const std::pair&))); } else mScene = new CSVRender::UnpagedWorldspaceWidget (id.getId(), document, this); @@ -64,9 +54,6 @@ CSVWorld::SceneSubView::SceneSubView (const CSMWorld::UniversalId& id, CSMDoc::D SceneToolMode *lightingTool = mScene->makeLightingSelector (toolbar); toolbar->addTool (lightingTool); - if (gridTool) - toolbar->addTool (gridTool); - layout2->addWidget (toolbar, 0); layout2->addWidget (mScene, 1); diff --git a/apps/opencs/view/world/scenetoolgrid.cpp b/apps/opencs/view/world/scenetoolgrid.cpp deleted file mode 100644 index 0769be168..000000000 --- a/apps/opencs/view/world/scenetoolgrid.cpp +++ /dev/null @@ -1,75 +0,0 @@ - -#include "scenetoolgrid.hpp" - -#include - -#include -#include -#include - -#include "scenetoolbar.hpp" - -CSVWorld::SceneToolGrid::SceneToolGrid (SceneToolbar *parent) -: SceneTool (parent), mIconSize (parent->getIconSize()) -{ -} - -void CSVWorld::SceneToolGrid::showPanel (const QPoint& position) -{ - - -} - -void CSVWorld::SceneToolGrid::cellIndexChanged (const std::pair& min, - const std::pair& max) -{ - /// \todo make font size configurable - const int fontSize = 8; - - /// \todo replace with proper icon - QPixmap image (mIconSize, mIconSize); - image.fill (QColor (0, 0, 0, 0)); - - { - QPainter painter (&image); - painter.setPen (Qt::black); - QFont font (QApplication::font().family(), fontSize); - painter.setFont (font); - - QFontMetrics metrics (font); - - if (min==max) - { - // single cell - std::ostringstream stream; - stream << min.first << ", " << min.second; - - QString text = QString::fromUtf8 (stream.str().c_str()); - - painter.drawText (QPoint ((mIconSize-metrics.width (text))/2, mIconSize/2+fontSize/2), - text); - } - else - { - // range - { - std::ostringstream stream; - stream << min.first << ", " << min.second; - painter.drawText (QPoint (0, mIconSize), - QString::fromUtf8 (stream.str().c_str())); - } - - { - std::ostringstream stream; - stream << max.first << ", " << max.second; - - QString text = QString::fromUtf8 (stream.str().c_str()); - - painter.drawText (QPoint (mIconSize-metrics.width (text), fontSize), text); - } - } - } - - QIcon icon (image); - setIcon (icon); -} \ No newline at end of file diff --git a/apps/opencs/view/world/scenetoolgrid.hpp b/apps/opencs/view/world/scenetoolgrid.hpp deleted file mode 100644 index 917df2a16..000000000 --- a/apps/opencs/view/world/scenetoolgrid.hpp +++ /dev/null @@ -1,29 +0,0 @@ -#ifndef CSV_WORLD_SCENETOOL_GRID_H -#define CSV_WORLD_SCENETOOL_GRID_H - -#include "scenetool.hpp" - -namespace CSVWorld -{ - class SceneToolbar; - - ///< \brief Cell grid selector tool - class SceneToolGrid : public SceneTool - { - Q_OBJECT - - int mIconSize; - - public: - - SceneToolGrid (SceneToolbar *parent); - - virtual void showPanel (const QPoint& position); - - public slots: - - void cellIndexChanged (const std::pair& min, const std::pair& max); - }; -} - -#endif From 67965ec10cc211469308c443363ea28e25fdf304 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Mon, 7 Apr 2014 13:42:00 +0200 Subject: [PATCH 7/9] added CellCoordinates and CellSelection classes --- apps/opencs/CMakeLists.txt | 2 +- apps/opencs/model/world/cellcoordinates.cpp | 60 +++++++++++++++ apps/opencs/model/world/cellcoordinates.hpp | 42 +++++++++++ apps/opencs/model/world/cellselection.cpp | 83 +++++++++++++++++++++ apps/opencs/model/world/cellselection.hpp | 57 ++++++++++++++ 5 files changed, 243 insertions(+), 1 deletion(-) create mode 100644 apps/opencs/model/world/cellcoordinates.cpp create mode 100644 apps/opencs/model/world/cellcoordinates.hpp create mode 100644 apps/opencs/model/world/cellselection.cpp create mode 100644 apps/opencs/model/world/cellselection.hpp diff --git a/apps/opencs/CMakeLists.txt b/apps/opencs/CMakeLists.txt index a7a694463..d9e271498 100644 --- a/apps/opencs/CMakeLists.txt +++ b/apps/opencs/CMakeLists.txt @@ -24,7 +24,7 @@ opencs_units (model/world opencs_units_noqt (model/world universalid record commands columnbase scriptcontext cell refidcollection - refidadapter refiddata refidadapterimp ref collectionbase refcollection columns infocollection tablemimedata + refidadapter refiddata refidadapterimp ref collectionbase refcollection columns infocollection tablemimedata cellcoordinates cellselection ) opencs_hdrs_noqt (model/world diff --git a/apps/opencs/model/world/cellcoordinates.cpp b/apps/opencs/model/world/cellcoordinates.cpp new file mode 100644 index 000000000..b1c8441e6 --- /dev/null +++ b/apps/opencs/model/world/cellcoordinates.cpp @@ -0,0 +1,60 @@ + +#include "cellcoordinates.hpp" + +#include +#include + +CSMWorld::CellCoordinates::CellCoordinates() : mX (0), mY (0) {} + +CSMWorld::CellCoordinates::CellCoordinates (int x, int y) : mX (x), mY (y) {} + +int CSMWorld::CellCoordinates::getX() const +{ + return mX; +} + +int CSMWorld::CellCoordinates::getY() const +{ + return mY; +} + +CSMWorld::CellCoordinates CSMWorld::CellCoordinates::move (int x, int y) const +{ + return CellCoordinates (mX + x, mY + y); +} + +std::string CSMWorld::CellCoordinates::getId (const std::string& worldspace) const +{ + // we ignore the worldspace for now, since there is only one (will change in 1.1) + std::ostringstream stream; + + stream << "#" << mX << " " << mY; + + return stream.str(); +} + +bool CSMWorld::operator== (const CellCoordinates& left, const CellCoordinates& right) +{ + return left.getX()==right.getX() && left.getY()==right.getY(); +} + +bool CSMWorld::operator!= (const CellCoordinates& left, const CellCoordinates& right) +{ + return !(left==right); +} + +bool CSMWorld::operator< (const CellCoordinates& left, const CellCoordinates& right) +{ + if (left.getX()right.getX()) + return false; + + return left.getY() +#include + +#include + +namespace CSMWorld +{ + class CellCoordinates + { + int mX; + int mY; + + public: + + CellCoordinates(); + + CellCoordinates (int x, int y); + + int getX() const; + + int getY() const; + + CellCoordinates move (int x, int y) const; + ///< Return a copy of *this, moved by the given offset. + + std::string getId (const std::string& worldspace) const; + ///< Return the ID for the cell at these coordinates. + }; + + bool operator== (const CellCoordinates& left, const CellCoordinates& right); + bool operator!= (const CellCoordinates& left, const CellCoordinates& right); + bool operator< (const CellCoordinates& left, const CellCoordinates& right); + + std::ostream& operator<< (std::ostream& stream, const CellCoordinates& coordiantes); +} + +Q_DECLARE_METATYPE (CSMWorld::CellCoordinates) + +#endif diff --git a/apps/opencs/model/world/cellselection.cpp b/apps/opencs/model/world/cellselection.cpp new file mode 100644 index 000000000..73b5196f1 --- /dev/null +++ b/apps/opencs/model/world/cellselection.cpp @@ -0,0 +1,83 @@ + +#include "cellselection.hpp" + +#include +#include +#include + +CSMWorld::CellSelection::Iterator CSMWorld::CellSelection::begin() const +{ + return mCells.begin(); +} + +CSMWorld::CellSelection::Iterator CSMWorld::CellSelection::end() const +{ + return mCells.end(); +} + +bool CSMWorld::CellSelection::add (const CellCoordinates& coordinates) +{ + return mCells.insert (coordinates).second; +} + +void CSMWorld::CellSelection::remove (const CellCoordinates& coordinates) +{ + mCells.erase (coordinates); +} + +bool CSMWorld::CellSelection::has (const CellCoordinates& coordinates) const +{ + return mCells.find (coordinates)!=end(); +} + +int CSMWorld::CellSelection::getSize() const +{ + return mCells.size(); +} + +CSMWorld::CellCoordinates CSMWorld::CellSelection::getCentre() const +{ + if (mCells.empty()) + throw std::logic_error ("call of getCentre on empty cell selection"); + + double x = 0; + double y = 0; + + for (Iterator iter = begin(); iter!=end(); ++iter) + { + x += iter->getX(); + y += iter->getY(); + } + + x /= mCells.size(); + y /= mCells.size(); + + Iterator closest = begin(); + double distance = std::numeric_limits::max(); + + for (Iterator iter (begin()); iter!=end(); ++iter) + { + double deltaX = x - iter->getX(); + double deltaY = y - iter->getY(); + + double delta = std::sqrt (deltaX * deltaX + deltaY * deltaY); + + if (deltamove (x, y)); + + mCells.swap (moved); +} diff --git a/apps/opencs/model/world/cellselection.hpp b/apps/opencs/model/world/cellselection.hpp new file mode 100644 index 000000000..042416a33 --- /dev/null +++ b/apps/opencs/model/world/cellselection.hpp @@ -0,0 +1,57 @@ +#ifndef CSM_WOLRD_CELLSELECTION_H +#define CSM_WOLRD_CELLSELECTION_H + +#include + +#include + +#include "cellcoordinates.hpp" + +namespace CSMWorld +{ + /// \brief Selection of cells in a paged worldspace + /// + /// \note The CellSelection does not specify the worldspace it applies to. + class CellSelection + { + public: + + typedef std::set Container; + typedef Container::const_iterator Iterator; + + private: + + Container mCells; + + public: + + Iterator begin() const; + + Iterator end() const; + + bool add (const CellCoordinates& coordinates); + ///< Ignored if the cell specified by \a coordinates is already part of the selection. + /// + /// \return Was a cell added to the collection? + + void remove (const CellCoordinates& coordinates); + ///< ignored if the cell specified by \a coordinates is not part of the selection. + + bool has (const CellCoordinates& coordinates) const; + ///< \return Is the cell specified by \a coordinates part of the selection? + + int getSize() const; + ///< Return number of cells. + + CellCoordinates getCentre() const; + ///< Return the selected cell that is closest to the geometric centre of the selection. + /// + /// \attention This function must not be called on selections that are empty. + + void move (int x, int y); + }; +} + +Q_DECLARE_METATYPE (CSMWorld::CellSelection) + +#endif From 0d352cb8832863445b7ad464610f8351c2588323 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Mon, 7 Apr 2014 14:16:02 +0200 Subject: [PATCH 8/9] replaced rectangular cell selection with a CellSelection object --- .../view/render/pagedworldspacewidget.cpp | 21 ++++++------ .../view/render/pagedworldspacewidget.hpp | 9 +++--- apps/opencs/view/world/scenesubview.cpp | 32 +++++++++++++------ apps/opencs/view/world/scenesubview.hpp | 7 +++- 4 files changed, 44 insertions(+), 25 deletions(-) diff --git a/apps/opencs/view/render/pagedworldspacewidget.cpp b/apps/opencs/view/render/pagedworldspacewidget.cpp index 96d44543e..ab02d63ee 100644 --- a/apps/opencs/view/render/pagedworldspacewidget.cpp +++ b/apps/opencs/view/render/pagedworldspacewidget.cpp @@ -4,36 +4,37 @@ #include CSVRender::PagedWorldspaceWidget::PagedWorldspaceWidget (QWidget *parent) -: WorldspaceWidget (parent), mMin (std::make_pair (0, 0)), mMax (std::make_pair (-1, -1)) +: WorldspaceWidget (parent) {} void CSVRender::PagedWorldspaceWidget::useViewHint (const std::string& hint) { if (!hint.empty()) { + CSMWorld::CellSelection selection; + if (hint[0]=='c') { char ignore1, ignore2, ignore3; - std::pair cellIndex; + int x, y; std::istringstream stream (hint.c_str()); - if (stream >> ignore1 >> ignore2 >> ignore3 >> cellIndex.first >> cellIndex.second) + if (stream >> ignore1 >> ignore2 >> ignore3 >> x >> y) { - setCellIndex (cellIndex, cellIndex); + selection.add (CSMWorld::CellCoordinates (x, y)); /// \todo adjust camera position } } /// \todo implement 'r' type hints + + setCellSelection (selection); } } -void CSVRender::PagedWorldspaceWidget::setCellIndex (const std::pair& min, - const std::pair& max) +void CSVRender::PagedWorldspaceWidget::setCellSelection (const CSMWorld::CellSelection& selection) { - mMin = min; - mMax = max; - - emit cellIndexChanged (mMin, mMax); + mSelection = selection; + emit cellSelectionChanged (mSelection); } \ No newline at end of file diff --git a/apps/opencs/view/render/pagedworldspacewidget.hpp b/apps/opencs/view/render/pagedworldspacewidget.hpp index 9a4b79c3a..f6ff32dc1 100644 --- a/apps/opencs/view/render/pagedworldspacewidget.hpp +++ b/apps/opencs/view/render/pagedworldspacewidget.hpp @@ -1,6 +1,8 @@ #ifndef OPENCS_VIEW_PAGEDWORLDSPACEWIDGET_H #define OPENCS_VIEW_PAGEDWORLDSPACEWIDGET_H +#include "../../model/world/cellselection.hpp" + #include "worldspacewidget.hpp" namespace CSVRender @@ -9,8 +11,7 @@ namespace CSVRender { Q_OBJECT - std::pair mMin; - std::pair mMax; + CSMWorld::CellSelection mSelection; public: @@ -21,11 +22,11 @@ namespace CSVRender virtual void useViewHint (const std::string& hint); - void setCellIndex (const std::pair& min, const std::pair& max); + void setCellSelection (const CSMWorld::CellSelection& selection); signals: - void cellIndexChanged (const std::pair& min, const std::pair& max); + void cellSelectionChanged (const CSMWorld::CellSelection& selection); }; } diff --git a/apps/opencs/view/world/scenesubview.cpp b/apps/opencs/view/world/scenesubview.cpp index 4ebaa9352..0bb11ce8c 100644 --- a/apps/opencs/view/world/scenesubview.cpp +++ b/apps/opencs/view/world/scenesubview.cpp @@ -9,6 +9,8 @@ #include "../../model/doc/document.hpp" +#include "../../model/world/cellselection.hpp" + #include "../filter/filterbox.hpp" #include "../render/pagedworldspacewidget.hpp" @@ -40,10 +42,8 @@ CSVWorld::SceneSubView::SceneSubView (const CSMWorld::UniversalId& id, CSMDoc::D { CSVRender::PagedWorldspaceWidget *widget = new CSVRender::PagedWorldspaceWidget (this); mScene = widget; - connect (widget, - SIGNAL (cellIndexChanged (const std::pair&, const std::pair&)), - this, - SLOT (cellIndexChanged (const std::pair&, const std::pair&))); + connect (widget, SIGNAL (cellSelectionChanged (const CSMWorld::CellSelection&)), + this, SLOT (cellSelectionChanged (const CSMWorld::CellSelection&))); } else mScene = new CSVRender::UnpagedWorldspaceWidget (id.getId(), document, this); @@ -102,16 +102,28 @@ void CSVWorld::SceneSubView::closeRequest() deleteLater(); } -void CSVWorld::SceneSubView::cellIndexChanged (const std::pair& min, - const std::pair& max) +void CSVWorld::SceneSubView::cellSelectionChanged (const CSMWorld::CellSelection& selection) { + int size = selection.getSize(); + std::ostringstream stream; - stream << "Scene: " << getUniversalId().getId() << " (" << min.first << ", " << min.second; + stream << "Scene: " << getUniversalId().getId(); - if (min!=max) - stream << " to " << max.first << ", " << max.second; + if (size==0) + stream << " (empty)"; + else if (size==1) + { + stream << " (" << *selection.begin() << ")"; + } + else + { + stream << " (" << selection.getCentre() << " and " << size-1 << " more "; - stream << ")"; + if (size>1) + stream << "cells around it)"; + else + stream << "cell around it)"; + } setWindowTitle (QString::fromUtf8 (stream.str().c_str())); } \ No newline at end of file diff --git a/apps/opencs/view/world/scenesubview.hpp b/apps/opencs/view/world/scenesubview.hpp index ee5b7b41f..0b15ea541 100644 --- a/apps/opencs/view/world/scenesubview.hpp +++ b/apps/opencs/view/world/scenesubview.hpp @@ -5,6 +5,11 @@ class QModelIndex; +namespace CSMWorld +{ + class CellSelection; +} + namespace CSMDoc { class Document; @@ -44,7 +49,7 @@ namespace CSVWorld void closeRequest(); - void cellIndexChanged (const std::pair& min, const std::pair& max); + void cellSelectionChanged (const CSMWorld::CellSelection& selection); }; } From e0550ba336e7d0bd0b884ceb3facbc51b61d51c9 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Mon, 7 Apr 2014 15:23:14 +0200 Subject: [PATCH 9/9] allow multiple cell coordinates in c-type hint for scene subviews --- .../view/render/pagedworldspacewidget.cpp | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/apps/opencs/view/render/pagedworldspacewidget.cpp b/apps/opencs/view/render/pagedworldspacewidget.cpp index ab02d63ee..0f23dfe7b 100644 --- a/apps/opencs/view/render/pagedworldspacewidget.cpp +++ b/apps/opencs/view/render/pagedworldspacewidget.cpp @@ -15,19 +15,26 @@ void CSVRender::PagedWorldspaceWidget::useViewHint (const std::string& hint) if (hint[0]=='c') { - char ignore1, ignore2, ignore3; - int x, y; + // syntax: c:#x1 y1; #x2 y2 (number of coordinate pairs can be 0 or larger) + char ignore; std::istringstream stream (hint.c_str()); - if (stream >> ignore1 >> ignore2 >> ignore3 >> x >> y) + if (stream >> ignore) { - selection.add (CSMWorld::CellCoordinates (x, y)); + char ignore1; // : or ; + char ignore2; // # + int x, y; + + while (stream >> ignore1 >> ignore2 >> x >> y) + selection.add (CSMWorld::CellCoordinates (x, y)); /// \todo adjust camera position } } - - /// \todo implement 'r' type hints + else if (hint[0]=='r') + { + /// \todo implement 'r' type hints + } setCellSelection (selection); }