Commit cc1fb1dd authored by Julien Finet's avatar Julien Finet

Add vtkAbstractContextItem::StackAbove and StackUnder

Convenience methods are exposed for plots in vtkChartXY

Change-Id: Iccccc18011b74314af3fcd1474ac792a15627ceb
parent 089067dc
......@@ -56,6 +56,7 @@ vtk_add_test_cxx(${vtk-module}CxxTests tests
TestChartXYZ.cxx
TestContext.cxx
TestContextImage.cxx
TestContextItemStacking.cxx
TestContextUnicode.cxx
TestControlPointsHandleItem.cxx
TestDiagram.cxx
......
/*=========================================================================
Program: Visualization Toolkit
Module: TestContextItemStacking.cxx
Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
All rights reserved.
See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the above copyright notice for more information.
=========================================================================*/
#include "vtkRenderer.h"
#include "vtkRenderWindow.h"
#include "vtkRenderWindowInteractor.h"
#include "vtkSmartPointer.h"
#include "vtkBlockItem.h"
#include "vtkContextTransform.h"
#include "vtkContextView.h"
#include "vtkContextScene.h"
#include "vtkNew.h"
//----------------------------------------------------------------------------
int TestContextItemStacking(int ,char * [] )
{
// Set up a 2D context view, context test object and add it to the scene
vtkNew<vtkContextView> view;
view->GetRenderer()->SetBackground(0.32, 0.40, 0.47);
view->GetRenderWindow()->SetSize(400, 400);
vtkNew<vtkBlockItem> rootItem;
rootItem->SetDimensions(0, 350, 50, 50);
int i = 0;
int s = 120;
int step = s/3;
vtkNew<vtkBlockItem> test1;
test1->SetDimensions(i, i, s, s);
test1->SetLabel("1");
i += step;
vtkNew<vtkBlockItem> test2;
test2->SetDimensions(i, i, s, s);
test2->SetLabel("2");
i += step;
vtkNew<vtkBlockItem> test3;
test3->SetDimensions(i, i, s, s);
test3->SetLabel("3");
i += step;
vtkNew<vtkBlockItem> test4;
test4->SetDimensions(i, i, s, s);
test4->SetLabel("4");
i += step;
vtkNew<vtkBlockItem> test41;
test41->SetDimensions(i, i, s, s);
test41->SetLabel("4.1");
i += step;
vtkNew<vtkBlockItem> test411;
test411->SetDimensions(i, i, s, s);
test411->SetLabel("4.1.1");
i += step;
vtkNew<vtkBlockItem> test42;
test42->SetDimensions(i, i, s, s);
test42->SetLabel("4.2");
i += step;
vtkNew<vtkBlockItem> test5;
test5->SetDimensions(i, i, s, s);
test5->SetLabel("5");
// Build up our multi-level scene
unsigned int index1 = rootItem->AddItem(test1.GetPointer());
unsigned int index2 = rootItem->AddItem(test2.GetPointer());
unsigned int index3 = rootItem->AddItem(test3.GetPointer());
unsigned int index4 = rootItem->AddItem(test4.GetPointer());
unsigned int index41 = test4->AddItem(test41.GetPointer());
unsigned int index411 = test41->AddItem(test411.GetPointer());
unsigned int index42 = test4->AddItem(test42.GetPointer());
unsigned int index5 = rootItem->AddItem(test5.GetPointer());
view->GetScene()->AddItem(rootItem.GetPointer());
// Check indexes
if (index1 != 0 || index2 != 1 || index3 != 2 || index4 != 3 ||
index41 != 0 || index411 != 0 || index42 != 1 || index5 != 4)
{
std::cerr << "AddItem, bad indexes: "
<< index1 << ", " << index2 << ", " << index3 << ", "
<< index4 << ", " << index41 << ", " << index411 << ", "
<< index42 << ", " << index5 << std::endl;
return EXIT_FAILURE;
}
// Restack item 3 under all items
int res = rootItem->Lower(rootItem->GetItemIndex(test3.GetPointer()));
index1 = rootItem->GetItemIndex(test1.GetPointer());
index2 = rootItem->GetItemIndex(test2.GetPointer());
index3 = rootItem->GetItemIndex(test3.GetPointer());
index4 = rootItem->GetItemIndex(test4.GetPointer());
if (res != 0 || index1 != 1 || index2 != 2 || index3 != 0 || index4 != 3)
{
std::cerr << "Lower, bad indexes: " << res << "->"
<< index1 << ", " << index2 << ", " << index3 << ", "
<< index4 << ", " << index41 << ", " << index411 << ", "
<< index42 << ", " << index5 << std::endl;
return EXIT_FAILURE;
}
// Restack item 1 above 4
res = rootItem->StackAbove(index1, index4);
index1 = rootItem->GetItemIndex(test1.GetPointer());
index2 = rootItem->GetItemIndex(test2.GetPointer());
index3 = rootItem->GetItemIndex(test3.GetPointer());
index4 = rootItem->GetItemIndex(test4.GetPointer());
index41 = test4->GetItemIndex(test41.GetPointer());
index42 = test4->GetItemIndex(test42.GetPointer());
index5 = rootItem->GetItemIndex(test5.GetPointer());
if (res != 3 || index1 != 3 || index2 != 1 || index3 != 0 || index4 != 2 ||
index41 != 0 || index411 != 0 || index42 != 1 || index5 != 4)
{
std::cerr << "StackAbove, bad indexes: " << res << "->"
<< index1 << ", " << index2 << ", " << index3 << ", "
<< index4 << ", " << index41 << ", " << index411 << ", "
<< index42 << ", " << index5 << std::endl;
return EXIT_FAILURE;
}
// Restack item 41 above 42
res = test4->Raise(index41);
index1 = rootItem->GetItemIndex(test1.GetPointer());
index2 = rootItem->GetItemIndex(test2.GetPointer());
index3 = rootItem->GetItemIndex(test3.GetPointer());
index4 = rootItem->GetItemIndex(test4.GetPointer());
index41 = test4->GetItemIndex(test41.GetPointer());
index42 = test4->GetItemIndex(test42.GetPointer());
index5 = rootItem->GetItemIndex(test5.GetPointer());
if (res != 1 || index1 != 3 || index2 != 1 || index3 != 0 || index4 != 2 ||
index41 != 1 || index411 != 0 || index42 != 0 || index5 != 4)
{
std::cerr << "Raise, bad indexes: " << res << "->"
<< index1 << ", " << index2 << ", " << index3 << ", "
<< index4 << ", " << index41 << ", " << index411 << ", "
<< index42 << ", " << index5 << std::endl;
return EXIT_FAILURE;
}
// Restack item 1 above 4
res = rootItem->StackUnder(index2, index3);
index1 = rootItem->GetItemIndex(test1.GetPointer());
index2 = rootItem->GetItemIndex(test2.GetPointer());
index3 = rootItem->GetItemIndex(test3.GetPointer());
index4 = rootItem->GetItemIndex(test4.GetPointer());
index41 = test4->GetItemIndex(test41.GetPointer());
index42 = test4->GetItemIndex(test42.GetPointer());
index5 = rootItem->GetItemIndex(test5.GetPointer());
if (res != 0 || index1 != 3 || index2 != 0 || index3 != 1 || index4 != 2 ||
index41 != 1 || index411 != 0 || index42 != 0 || index5 != 4)
{
std::cerr << "StackUnder, bad indexes: " << res << "->"
<< index1 << ", " << index2 << ", " << index3 << ", "
<< index4 << ", " << index41 << ", " << index411 << ", "
<< index42 << ", " << index5 << std::endl;
return EXIT_FAILURE;
}
// Turn off the color buffer
view->GetScene()->SetUseBufferId(false);
//Finally render the scene and compare the image to a reference image
view->GetRenderWindow()->SetMultiSamples(0);
view->GetInteractor()->Initialize();
view->GetInteractor()->Start();
return EXIT_SUCCESS;
}
......@@ -1229,6 +1229,69 @@ vtkPlot* vtkChartXY::GetPlot(vtkIdType index)
}
}
//-----------------------------------------------------------------------------
vtkIdType vtkChartXY::GetPlotIndex(vtkPlot* plot)
{
int corner = this->GetPlotCorner(plot);
return corner >= 0 && corner < 4 ?
this->ChartPrivate->PlotCorners[corner]->GetItemIndex(plot) :
static_cast<vtkIdType>(-1);
}
//-----------------------------------------------------------------------------
vtkIdType vtkChartXY::RaisePlot(vtkPlot* plot)
{
vtkIdType plotIndex = this->GetPlotIndex(plot);
int corner = this->GetPlotCorner(plot);
if (corner < 0 || corner >=4)
{
return plotIndex;
}
return this->ChartPrivate->PlotCorners[corner]->Raise(plotIndex);
}
//-----------------------------------------------------------------------------
vtkIdType vtkChartXY::StackPlotAbove(vtkPlot* plot, vtkPlot* under)
{
vtkIdType plotIndex = this->GetPlotIndex(plot);
vtkIdType underIndex = this->GetPlotIndex(under);
int corner = this->GetPlotCorner(plot);
if (corner < 0 || corner >=4 ||
underIndex != this->GetPlotCorner(under))
{
return plotIndex;
}
return this->ChartPrivate->PlotCorners[corner]->StackAbove(plotIndex,
underIndex);
}
//-----------------------------------------------------------------------------
vtkIdType vtkChartXY::LowerPlot(vtkPlot* plot)
{
vtkIdType plotIndex = this->GetPlotIndex(plot);
int corner = this->GetPlotCorner(plot);
if (corner < 0 || corner >=4)
{
return plotIndex;
}
return this->ChartPrivate->PlotCorners[corner]->Lower(plotIndex);
}
//-----------------------------------------------------------------------------
vtkIdType vtkChartXY::StackPlotUnder(vtkPlot* plot, vtkPlot* above)
{
vtkIdType plotIndex = this->GetPlotIndex(plot);
vtkIdType aboveIndex = this->GetPlotIndex(above);
int corner = this->GetPlotCorner(plot);
if (corner < 0 || corner >=4 ||
corner != this->GetPlotCorner(above))
{
return plotIndex;
}
return this->ChartPrivate->PlotCorners[corner]->StackUnder(plotIndex,
aboveIndex);
}
//-----------------------------------------------------------------------------
void vtkChartXY::SetShowLegend(bool visible)
{
......
......@@ -78,6 +78,37 @@ public:
// Get the plot at the specified index, returns null if the index is invalid.
virtual vtkPlot* GetPlot(vtkIdType index);
// Description:
// Get the index of the specified plot, returns -1 if the plot does not
// belong to the chart.
virtual vtkIdType GetPlotIndex(vtkPlot*);
// Description:
// Raises the \a plot to the top of the plot's stack.
// \return The new index of the plot
// \sa StackPlotAbove(), LowerPlot(), StackPlotUnder()
vtkIdType RaisePlot(vtkPlot* plot);
// Description:
// Raises the \a plot above the \a under plot. If \a under is null,
// the plot is raised to the top of the plot's stack.
// \return The new index of the plot
// \sa RaisePlot(), LowerPlot(), StackPlotUnder()
virtual vtkIdType StackPlotAbove(vtkPlot* plot, vtkPlot* under);
// Description:
// Lowers the \a plot to the bottom of the plot's stack.
// \return The new index of the plot
// \sa StackPlotUnder(), RaisePlot(), StackPlotAbove()
vtkIdType LowerPlot(vtkPlot* plot);
// Description:
// Lowers the \a plot under the \a above plot. If \a above is null,
// the plot is lowered to the bottom of the plot's stack
// \return The new index of the plot
// \sa StackPlotUnder(), RaisePlot(), StackPlotAbove()
virtual vtkIdType StackPlotUnder(vtkPlot* plot, vtkPlot* above);
// Description:
// Get the number of plots the chart contains.
virtual vtkIdType GetNumberOfPlots();
......
......@@ -18,6 +18,9 @@
#include "vtkContextMouseEvent.h"
#include "vtkContextScenePrivate.h"
// STL headers
#include <algorithm>
//-----------------------------------------------------------------------------
vtkAbstractContextItem::vtkAbstractContextItem()
{
......@@ -84,6 +87,18 @@ vtkAbstractContextItem* vtkAbstractContextItem::GetItem(unsigned int index)
}
}
//-----------------------------------------------------------------------------
unsigned int vtkAbstractContextItem::GetItemIndex(vtkAbstractContextItem* item)
{
vtkContextScenePrivate::const_iterator it =
std::find(this->Children->begin(), this->Children->end(), item);
if (it == this->Children->end())
{
return static_cast<unsigned int>(-1);
}
return it - this->Children->begin();
}
//-----------------------------------------------------------------------------
unsigned int vtkAbstractContextItem::GetNumberOfItems()
{
......@@ -96,6 +111,64 @@ void vtkAbstractContextItem::ClearItems()
this->Children->Clear();
}
//-----------------------------------------------------------------------------
unsigned int vtkAbstractContextItem::Raise(unsigned int index)
{
return this->StackAbove(index, this->GetNumberOfItems() - 1);
}
//-----------------------------------------------------------------------------
unsigned int vtkAbstractContextItem::StackAbove(unsigned int index,
unsigned int under)
{
unsigned int res = index;
if (index == under)
{
return res;
}
unsigned int start = 0;
unsigned int middle = 0;
unsigned int end = 0;
if (under == static_cast<unsigned int>(-1))
{
start = 0;
middle = index;
end = index + 1;
res = 0;
}
else if (index > under)
{
start = under + 1;
middle = index;
end = index + 1;
res = start;
}
else // if (index < under)
{
start = index;
middle = index + 1;
end = under + 1;
res = end - 1;
}
std::rotate(this->Children->begin() + start,
this->Children->begin() + middle,
this->Children->begin() + end);
return res;
}
//-----------------------------------------------------------------------------
unsigned int vtkAbstractContextItem::Lower(unsigned int index)
{
return this->StackUnder(index, 0);
}
//-----------------------------------------------------------------------------
unsigned int vtkAbstractContextItem::StackUnder(unsigned int child,
unsigned int above)
{
return this->StackAbove(child, above - 1);
}
//-----------------------------------------------------------------------------
bool vtkAbstractContextItem::Hit(const vtkContextMouseEvent &)
{
......
......@@ -82,6 +82,11 @@ public:
// \return the item at the specified index (null if index is invalid).
vtkAbstractContextItem* GetItem(unsigned int index);
// Description:
// Get the index of the specified item.
// \return the index of the item (-1 if item is not a valid child).
unsigned int GetItemIndex(vtkAbstractContextItem* item);
// Description:
// Get the number of child items.
unsigned int GetNumberOfItems();
......@@ -90,6 +95,34 @@ public:
// Remove all child items from this item.
void ClearItems();
// Description:
// Raises the \a child to the top of the item's stack.
// \return The new index of the item
// \sa StackAbove(), Lower(), LowerUnder()
unsigned int Raise(unsigned int index);
// Description:
// Raises the \a child above the \a under sibling. If \a under is invalid,
// the item is raised to the top of the item's stack.
// \return The new index of the item
// \sa Raise(), Lower(), StackUnder()
virtual unsigned int StackAbove(unsigned int index,
unsigned int under);
// Description:
// Lowers the \a child to the bottom of the item's stack.
// \return The new index of the item
// \sa StackUnder(), Raise(), StackAbove()
unsigned int Lower(unsigned int index);
// Description:
// Lowers the \a child under the \a above sibling. If \a above is invalid,
// the item is lowered to the bottom of the item's stack
// \return The new index of the item
// \sa Lower(), Raise(), StackAbove()
virtual unsigned int StackUnder(unsigned int child,
unsigned int above);
//BTX
// Description:
// Return true if the supplied x, y coordinate is inside the item.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment