<commit_before>//
// Name:		SceneGraphDlg.cpp
//
// Copyright (c) 2001-2004 Virtual Terrain Project
// Free for all uses, see license.txt for details.
//

#ifdef __GNUG__
	#pragma implementation "SceneGraphDlg.cpp"
#endif

// For compilers that support precompilation, includes "wx/wx.h".
#include "wx/wxprec.h"

#ifndef WX_PRECOMP
#include "wx/wx.h"
#endif

#include "wx/treectrl.h"
#include "wx/image.h"

#include "vtlib/vtlib.h"
#include "vtlib/core/Engine.h"
#include "vtui/wxString2.h"
#include "SceneGraphDlg.h"

#include <typeinfo>
using namespace std;

#if defined(__WXGTK__) || defined(__WXMOTIF__)
#  include "icon1.xpm"
#  include "icon2.xpm"
#  include "icon3.xpm"
#  include "icon4.xpm"
#  include "icon5.xpm"
#  include "icon6.xpm"
#  include "icon7.xpm"
#  include "icon8.xpm"
#  include "icon9.xpm"
#  include "icon10.xpm"
#endif

/////////////////////////////

class MyTreeItemData : public wxTreeItemData
{
public:
	MyTreeItemData(vtNodeBase *pNode, vtEngine *pEngine)
	{
		m_pNode = pNode;
		m_pEngine = pEngine;
	}
	vtNodeBase *m_pNode;
	vtEngine *m_pEngine;
};

// WDR: class implementations

//----------------------------------------------------------------------------
// SceneGraphDlg
//----------------------------------------------------------------------------

// WDR: event table for SceneGraphDlg

BEGIN_EVENT_TABLE(SceneGraphDlg,wxDialog)
	EVT_INIT_DIALOG (SceneGraphDlg::OnInitDialog)
	EVT_TREE_SEL_CHANGED( ID_SCENETREE, SceneGraphDlg::OnTreeSelChanged )
	EVT_CHECKBOX( ID_ENABLED, SceneGraphDlg::OnEnabled )
	EVT_BUTTON( ID_ZOOMTO, SceneGraphDlg::OnZoomTo )
	EVT_BUTTON( ID_REFRESH, SceneGraphDlg::OnRefresh )
END_EVENT_TABLE()

SceneGraphDlg::SceneGraphDlg( wxWindow *parent, wxWindowID id, const wxString &title,
	const wxPoint &position, const wxSize& size, long style ) :
	wxDialog( parent, id, title, position, size, style )
{
	SceneGraphFunc( this, TRUE );

	m_pZoomTo = GetZoomto();
	m_pEnabled = GetEnabled();
	m_pTree = GetScenetree();

	m_pZoomTo->Enable(false);

	m_imageListNormal = NULL;
	CreateImageList(16);
}

SceneGraphDlg::~SceneGraphDlg()
{
	delete m_imageListNormal;
}

///////////

void SceneGraphDlg::CreateImageList(int size)
{
	delete m_imageListNormal;

	if ( size == -1 )
	{
		m_imageListNormal = NULL;
		return;
	}
	// Make an image list containing small icons
	m_imageListNormal = new wxImageList(size, size, TRUE);

	wxIcon icons[10];
	icons[0] = wxICON(icon1);
	icons[1] = wxICON(icon2);
	icons[2] = wxICON(icon3);
	icons[3] = wxICON(icon4);
	icons[4] = wxICON(icon5);
	icons[5] = wxICON(icon6);
	icons[6] = wxICON(icon7);
	icons[7] = wxICON(icon8);
	icons[8] = wxICON(icon9);
	icons[9] = wxICON(icon10);

	int sizeOrig = icons[0].GetWidth();
	for ( size_t i = 0; i < WXSIZEOF(icons); i++ )
	{
		if ( size == sizeOrig )
			m_imageListNormal->Add(icons[i]);
		else
			m_imageListNormal->Add(wxBitmap(wxBitmap(icons[i]).ConvertToImage().Rescale(size, size)));
	}
	m_pTree->SetImageList(m_imageListNormal);
}

void SceneGraphDlg::RefreshTreeContents()
{
	vtScene* scene = vtGetScene();
	if (!scene)
		return;

	// start with a blank slate
	m_pTree->DeleteAllItems();

	// Fill in the tree with nodes
	m_bFirst = true;
	vtNodeBase *pRoot = scene->GetRoot();
	if (pRoot) AddNodeItemsRecursively(wxTreeItemId(), pRoot, 0);

	wxTreeItemId hRoot = m_pTree->GetRootItem();
	wxTreeItemId hEngRoot = m_pTree->AppendItem(hRoot, _("Engines"), 7, 7);

	// Fill in the tree with engines
	int num = scene->GetNumEngines();
	vtTarget *target;
	for (int i = 0; i < num; i++)
	{
		vtEngine *pEng = scene->GetEngine(i);
		wxString2 str = pEng->GetName2();
		int targets = pEng->NumTargets();
		target = pEng->GetTarget();
		if (target)
		{
			str += _T(" -> ");
			vtNodeBase *node = dynamic_cast<vtNodeBase*>(target);
			if (node)
			{
				str += _T("\"");
				str += wxString::FromAscii(node->GetName2());
				str += _T("\"");
			}
			else
				str += _("(non-node)");
		}
		if (targets > 1)
		{
			wxString2 plus;
			plus.Printf(_(" (%d targets total)"), targets);
			str += plus;
		}
		wxTreeItemId hEng = m_pTree->AppendItem(hEngRoot, str, 1, 1);
		m_pTree->SetItemData(hEng, new MyTreeItemData(NULL, pEng));
	}
	m_pTree->Expand(hEngRoot);

	m_pSelectedEngine = NULL;
	m_pSelectedNode = NULL;
}

void SceneGraphDlg::AddNodeItemsRecursively(wxTreeItemId hParentItem,
										vtNodeBase *pNode, int depth)
{
	wxString str;
	int nImage;
	wxTreeItemId hNewItem;

	if (!pNode) return;

	if (dynamic_cast<vtLight*>(pNode))
	{
		str = _("Light");
		nImage = 4;
	}
	else if (dynamic_cast<vtGeom*>(pNode))
	{
		str = _("Geometry");
		nImage = 2;
	}
	else if (dynamic_cast<vtLOD*>(pNode))
	{
		str = _T("LOD");
		nImage = 5;
	}
	else if (dynamic_cast<vtTransform*>(pNode))
	{
		str = _T("XForm");
		nImage = 9;
	}
	else if (dynamic_cast<vtGroupBase*>(pNode))
	{
		// must be just a group for grouping's sake
		str = _("Group");
		nImage = 3;
	}
	else
	{
		// must be something else
		str = _("Other");
		nImage = 8;
	}
	if (pNode->GetName2())
	{
		str += _T(" \"");
		str += wxString::FromAscii(pNode->GetName2());
		str += _T("\"");
	}

	if (m_bFirst)
	{
		hNewItem = m_pTree->AddRoot(str);
		m_bFirst = false;
	}
	else
		hNewItem = m_pTree->AppendItem(hParentItem, str, nImage, nImage);

	const std::type_info &t1 = typeid(*pNode);
	if (t1 == typeid(vtGeom))
	{
		vtGeom *pGeom = dynamic_cast<vtGeom*>(pNode);
		int num_mesh = pGeom->GetNumMeshes();
		wxTreeItemId	hGeomItem;

		for (int i = 0; i < num_mesh; i++)
		{
			vtMesh *pMesh = pGeom->GetMesh(i);
			if (pMesh)
			{
				int iNumPrim = pMesh->GetNumPrims();
				int iNumVert = pMesh->GetNumVertices();

				GLenum pt = pMesh->GetPrimType();
				const char *mtype;
				switch (pt)
				{
				case GL_POINTS: mtype = "Points"; break;
				case GL_LINES: mtype = "Lines"; break;
				case GL_LINE_LOOP: mtype = "LineLoop"; break;
				case GL_LINE_STRIP: mtype = "LineStrip"; break;
				case GL_TRIANGLES: mtype = "Triangles"; break;
				case GL_TRIANGLE_STRIP: mtype = "TriStrip"; break;
				case GL_TRIANGLE_FAN: mtype = "TriFan"; break;
				case GL_QUADS: mtype = "Quads"; break;
				case GL_QUAD_STRIP: mtype = "QuadStrip"; break;
				case GL_POLYGON: mtype = "Polygon"; break;
				}
				str.Printf(_("Mesh %d, %hs, %d verts, %d prims"), i, mtype, iNumVert, iNumPrim);
				hGeomItem = m_pTree->AppendItem(hNewItem, str, 6, 6);
			}
			else
				hGeomItem = m_pTree->AppendItem(hNewItem, _("Text Mesh"), 6, 6);
		}
	}

	m_pTree->SetItemData(hNewItem, new MyTreeItemData(pNode, NULL));

	wxTreeItemId hSubItem;
	vtGroupBase *pGroup = dynamic_cast<vtGroupBase*>(pNode);
	if (pGroup)
	{
		int num_children = pGroup->GetNumChildren();
		if (num_children > 200)
		{
			str.Printf(_("(%d children)"), num_children);
			hSubItem = m_pTree->AppendItem(hNewItem, str, 8, 8);
		}
		else
		{
			for (int i = 0; i < num_children; i++)
			{
				vtNode *pChild = pGroup->GetChild(i);
				if (pChild)
					AddNodeItemsRecursively(hNewItem, pChild, depth+1);
				else
					hSubItem = m_pTree->AppendItem(hNewItem, _("(internal node)"), 8, 8);
			}
		}
	}
	// expand a bit so that the tree is initially partially exposed
	if (depth < 2)
		m_pTree->Expand(hNewItem);
}

// WDR: handler implementations for SceneGraphDlg

void SceneGraphDlg::OnRefresh( wxCommandEvent &event )
{
	RefreshTreeContents();
}

void SceneGraphDlg::OnZoomTo( wxCommandEvent &event )
{
	if (m_pSelectedNode)
	{
		FSphere sph;
		m_pSelectedNode->GetBoundSphere(sph, true);	// global bounds
		vtGetScene()->GetCamera()->ZoomToSphere(sph);
	}
}

void SceneGraphDlg::OnEnabled( wxCommandEvent &event )
{
	if (m_pSelectedEngine)
		m_pSelectedEngine->SetEnabled(m_pEnabled->GetValue());
	if (m_pSelectedNode)
		m_pSelectedNode->SetEnabled(m_pEnabled->GetValue());
}

void SceneGraphDlg::OnTreeSelChanged( wxTreeEvent &event )
{
	wxTreeItemId item = event.GetItem();
	MyTreeItemData *data = (MyTreeItemData *)m_pTree->GetItemData(item);

	m_pEnabled->Enable(data != NULL);

	m_pSelectedEngine = NULL;
	m_pSelectedNode = NULL;

	if (data && data->m_pEngine)
	{
		m_pSelectedEngine = data->m_pEngine;
		m_pEnabled->SetValue(m_pSelectedEngine->GetEnabled());
	}
	if (data && data->m_pNode)
	{
		m_pSelectedNode = data->m_pNode;
		m_pEnabled->SetValue(m_pSelectedNode->GetEnabled());
		m_pZoomTo->Enable(true);
	}
	else
		m_pZoomTo->Enable(false);
}

void SceneGraphDlg::OnInitDialog(wxInitDialogEvent& event)
{
	RefreshTreeContents();

	wxWindow::OnInitDialog(event);
}

<commit_msg>improved 'Zoom To' in layer and scenegraph dialogs to consider vertical FOV to place whole object in view<commit_after>//
// Name:		SceneGraphDlg.cpp
//
// Copyright (c) 2001-2004 Virtual Terrain Project
// Free for all uses, see license.txt for details.
//

#ifdef __GNUG__
	#pragma implementation "SceneGraphDlg.cpp"
#endif

// For compilers that support precompilation, includes "wx/wx.h".
#include "wx/wxprec.h"

#ifndef WX_PRECOMP
#include "wx/wx.h"
#endif

#include "wx/treectrl.h"
#include "wx/image.h"

#include "vtlib/vtlib.h"
#include "vtlib/core/Engine.h"
#include "vtui/wxString2.h"
#include "SceneGraphDlg.h"

#include <typeinfo>
using namespace std;

#if defined(__WXGTK__) || defined(__WXMOTIF__)
#  include "icon1.xpm"
#  include "icon2.xpm"
#  include "icon3.xpm"
#  include "icon4.xpm"
#  include "icon5.xpm"
#  include "icon6.xpm"
#  include "icon7.xpm"
#  include "icon8.xpm"
#  include "icon9.xpm"
#  include "icon10.xpm"
#endif

/////////////////////////////

class MyTreeItemData : public wxTreeItemData
{
public:
	MyTreeItemData(vtNodeBase *pNode, vtEngine *pEngine)
	{
		m_pNode = pNode;
		m_pEngine = pEngine;
	}
	vtNodeBase *m_pNode;
	vtEngine *m_pEngine;
};

// WDR: class implementations

//----------------------------------------------------------------------------
// SceneGraphDlg
//----------------------------------------------------------------------------

// WDR: event table for SceneGraphDlg

BEGIN_EVENT_TABLE(SceneGraphDlg,wxDialog)
	EVT_INIT_DIALOG (SceneGraphDlg::OnInitDialog)
	EVT_TREE_SEL_CHANGED( ID_SCENETREE, SceneGraphDlg::OnTreeSelChanged )
	EVT_CHECKBOX( ID_ENABLED, SceneGraphDlg::OnEnabled )
	EVT_BUTTON( ID_ZOOMTO, SceneGraphDlg::OnZoomTo )
	EVT_BUTTON( ID_REFRESH, SceneGraphDlg::OnRefresh )
END_EVENT_TABLE()

SceneGraphDlg::SceneGraphDlg( wxWindow *parent, wxWindowID id, const wxString &title,
	const wxPoint &position, const wxSize& size, long style ) :
	wxDialog( parent, id, title, position, size, style )
{
	SceneGraphFunc( this, TRUE );

	m_pZoomTo = GetZoomto();
	m_pEnabled = GetEnabled();
	m_pTree = GetScenetree();

	m_pZoomTo->Enable(false);

	m_imageListNormal = NULL;
	CreateImageList(16);
}

SceneGraphDlg::~SceneGraphDlg()
{
	delete m_imageListNormal;
}

///////////

void SceneGraphDlg::CreateImageList(int size)
{
	delete m_imageListNormal;

	if ( size == -1 )
	{
		m_imageListNormal = NULL;
		return;
	}
	// Make an image list containing small icons
	m_imageListNormal = new wxImageList(size, size, TRUE);

	wxIcon icons[10];
	icons[0] = wxICON(icon1);
	icons[1] = wxICON(icon2);
	icons[2] = wxICON(icon3);
	icons[3] = wxICON(icon4);
	icons[4] = wxICON(icon5);
	icons[5] = wxICON(icon6);
	icons[6] = wxICON(icon7);
	icons[7] = wxICON(icon8);
	icons[8] = wxICON(icon9);
	icons[9] = wxICON(icon10);

	int sizeOrig = icons[0].GetWidth();
	for ( size_t i = 0; i < WXSIZEOF(icons); i++ )
	{
		if ( size == sizeOrig )
			m_imageListNormal->Add(icons[i]);
		else
			m_imageListNormal->Add(wxBitmap(wxBitmap(icons[i]).ConvertToImage().Rescale(size, size)));
	}
	m_pTree->SetImageList(m_imageListNormal);
}

void SceneGraphDlg::RefreshTreeContents()
{
	vtScene* scene = vtGetScene();
	if (!scene)
		return;

	// start with a blank slate
	m_pTree->DeleteAllItems();

	// Fill in the tree with nodes
	m_bFirst = true;
	vtNodeBase *pRoot = scene->GetRoot();
	if (pRoot) AddNodeItemsRecursively(wxTreeItemId(), pRoot, 0);

	wxTreeItemId hRoot = m_pTree->GetRootItem();
	wxTreeItemId hEngRoot = m_pTree->AppendItem(hRoot, _("Engines"), 7, 7);

	// Fill in the tree with engines
	int num = scene->GetNumEngines();
	vtTarget *target;
	for (int i = 0; i < num; i++)
	{
		vtEngine *pEng = scene->GetEngine(i);
		wxString2 str = pEng->GetName2();
		int targets = pEng->NumTargets();
		target = pEng->GetTarget();
		if (target)
		{
			str += _T(" -> ");
			vtNodeBase *node = dynamic_cast<vtNodeBase*>(target);
			if (node)
			{
				str += _T("\"");
				str += wxString::FromAscii(node->GetName2());
				str += _T("\"");
			}
			else
				str += _("(non-node)");
		}
		if (targets > 1)
		{
			wxString2 plus;
			plus.Printf(_(" (%d targets total)"), targets);
			str += plus;
		}
		wxTreeItemId hEng = m_pTree->AppendItem(hEngRoot, str, 1, 1);
		m_pTree->SetItemData(hEng, new MyTreeItemData(NULL, pEng));
	}
	m_pTree->Expand(hEngRoot);

	m_pSelectedEngine = NULL;
	m_pSelectedNode = NULL;
}

void SceneGraphDlg::AddNodeItemsRecursively(wxTreeItemId hParentItem,
										vtNodeBase *pNode, int depth)
{
	wxString str;
	int nImage;
	wxTreeItemId hNewItem;

	if (!pNode) return;

	if (dynamic_cast<vtLight*>(pNode))
	{
		str = _("Light");
		nImage = 4;
	}
	else if (dynamic_cast<vtGeom*>(pNode))
	{
		str = _("Geometry");
		nImage = 2;
	}
	else if (dynamic_cast<vtLOD*>(pNode))
	{
		str = _T("LOD");
		nImage = 5;
	}
	else if (dynamic_cast<vtTransform*>(pNode))
	{
		str = _T("XForm");
		nImage = 9;
	}
	else if (dynamic_cast<vtGroupBase*>(pNode))
	{
		// must be just a group for grouping's sake
		str = _("Group");
		nImage = 3;
	}
	else
	{
		// must be something else
		str = _("Other");
		nImage = 8;
	}
	if (pNode->GetName2())
	{
		str += _T(" \"");
		str += wxString::FromAscii(pNode->GetName2());
		str += _T("\"");
	}

	if (m_bFirst)
	{
		hNewItem = m_pTree->AddRoot(str);
		m_bFirst = false;
	}
	else
		hNewItem = m_pTree->AppendItem(hParentItem, str, nImage, nImage);

	const std::type_info &t1 = typeid(*pNode);
	if (t1 == typeid(vtGeom))
	{
		vtGeom *pGeom = dynamic_cast<vtGeom*>(pNode);
		int num_mesh = pGeom->GetNumMeshes();
		wxTreeItemId	hGeomItem;

		for (int i = 0; i < num_mesh; i++)
		{
			vtMesh *pMesh = pGeom->GetMesh(i);
			if (pMesh)
			{
				int iNumPrim = pMesh->GetNumPrims();
				int iNumVert = pMesh->GetNumVertices();

				GLenum pt = pMesh->GetPrimType();
				const char *mtype;
				switch (pt)
				{
				case GL_POINTS: mtype = "Points"; break;
				case GL_LINES: mtype = "Lines"; break;
				case GL_LINE_LOOP: mtype = "LineLoop"; break;
				case GL_LINE_STRIP: mtype = "LineStrip"; break;
				case GL_TRIANGLES: mtype = "Triangles"; break;
				case GL_TRIANGLE_STRIP: mtype = "TriStrip"; break;
				case GL_TRIANGLE_FAN: mtype = "TriFan"; break;
				case GL_QUADS: mtype = "Quads"; break;
				case GL_QUAD_STRIP: mtype = "QuadStrip"; break;
				case GL_POLYGON: mtype = "Polygon"; break;
				}
				str.Printf(_("Mesh %d, %hs, %d verts, %d prims"), i, mtype, iNumVert, iNumPrim);
				hGeomItem = m_pTree->AppendItem(hNewItem, str, 6, 6);
			}
			else
				hGeomItem = m_pTree->AppendItem(hNewItem, _("Text Mesh"), 6, 6);
		}
	}

	m_pTree->SetItemData(hNewItem, new MyTreeItemData(pNode, NULL));

	wxTreeItemId hSubItem;
	vtGroupBase *pGroup = dynamic_cast<vtGroupBase*>(pNode);
	if (pGroup)
	{
		int num_children = pGroup->GetNumChildren();
		if (num_children > 200)
		{
			str.Printf(_("(%d children)"), num_children);
			hSubItem = m_pTree->AppendItem(hNewItem, str, 8, 8);
		}
		else
		{
			for (int i = 0; i < num_children; i++)
			{
				vtNode *pChild = pGroup->GetChild(i);
				if (pChild)
					AddNodeItemsRecursively(hNewItem, pChild, depth+1);
				else
					hSubItem = m_pTree->AppendItem(hNewItem, _("(internal node)"), 8, 8);
			}
		}
	}
	// expand a bit so that the tree is initially partially exposed
	if (depth < 2)
		m_pTree->Expand(hNewItem);
}

// WDR: handler implementations for SceneGraphDlg

void SceneGraphDlg::OnRefresh( wxCommandEvent &event )
{
	RefreshTreeContents();
}

void SceneGraphDlg::OnZoomTo( wxCommandEvent &event )
{
	if (m_pSelectedNode)
	{
		FSphere sph;
		m_pSelectedNode->GetBoundSphere(sph, true);	// global bounds

		// a bit back to make sure whole volume of bounding sphere is in view
		vtCamera *pCam = vtGetScene()->GetCamera();
		float smallest = min(pCam->GetFOV(), pCam->GetVertFOV());
		float alpha = smallest / 2.0f;
		float distance = sph.radius / tanf(alpha);
		sph.radius = distance;

		pCam->ZoomToSphere(sph);
	}
}

void SceneGraphDlg::OnEnabled( wxCommandEvent &event )
{
	if (m_pSelectedEngine)
		m_pSelectedEngine->SetEnabled(m_pEnabled->GetValue());
	if (m_pSelectedNode)
		m_pSelectedNode->SetEnabled(m_pEnabled->GetValue());
}

void SceneGraphDlg::OnTreeSelChanged( wxTreeEvent &event )
{
	wxTreeItemId item = event.GetItem();
	MyTreeItemData *data = (MyTreeItemData *)m_pTree->GetItemData(item);

	m_pEnabled->Enable(data != NULL);

	m_pSelectedEngine = NULL;
	m_pSelectedNode = NULL;

	if (data && data->m_pEngine)
	{
		m_pSelectedEngine = data->m_pEngine;
		m_pEnabled->SetValue(m_pSelectedEngine->GetEnabled());
	}
	if (data && data->m_pNode)
	{
		m_pSelectedNode = data->m_pNode;
		m_pEnabled->SetValue(m_pSelectedNode->GetEnabled());
		m_pZoomTo->Enable(true);
	}
	else
		m_pZoomTo->Enable(false);
}

void SceneGraphDlg::OnInitDialog(wxInitDialogEvent& event)
{
	RefreshTreeContents();

	wxWindow::OnInitDialog(event);
}

<|endoftext|>


<commit_before>// This file is part of the dune-gdt project:
//   http://users.dune-project.org/projects/dune-gdt
// Copyright holders: Felix Albrecht
// License: BSD 2-Clause License (http://opensource.org/licenses/BSD-2-Clause)

#ifndef DUNE_GDT_DISCRETEFUNCTION_DIFFERENCE_HH
#define DUNE_GDT_DISCRETEFUNCTION_DIFFERENCE_HH

#include <type_traits>

#include <dune/stuff/functions/interfaces.hh>

namespace Dune {
namespace GDT {

namespace LocalFunction {

template <class MinuendType, class SubrahendImp, class D, int d, class R, int rR, int rC = 1>
class Difference;

template <class MinuendType, class SubrahendImp, class D, int d, class R, int rR, int rC = 1>
class DifferenceTraits;

template <class MinuendType, class SubtrahendType, class D, int d, class R, int r>
class DifferenceTraits<MinuendType, SubtrahendType, D, d, R, r, 1>
{
  static_assert(
      std::is_base_of<Stuff::LocalFunctionInterface<typename MinuendType::Traits, D, d, R, r, 1>, MinuendType>::value,
      "MinuendType has to be derived from Stuff::LocalFunctionInterface< ..., D, d, R, r, 1 >");
  static_assert(std::is_base_of<Stuff::LocalFunctionInterface<typename SubtrahendType::Traits, D, d, R, r, 1>,
                                SubtrahendType>::value,
                "SubtrahendType has to be derived from Stuff::LocalFunctionInterface< ..., D, d, R, r, 1 >");
  static_assert(std::is_same<typename MinuendType::EntityType, typename SubtrahendType::EntityType>::value,
                "EntityType of MinuendType and SubtrahendType do not match!");

public:
  typedef Difference<MinuendType, SubtrahendType, D, d, R, r, 1> derived_type;
  typedef typename MinuendType::EntityType EntityType;
};

template <class MinuendType, class SubtrahendType, class D, int d, class R, int r>
class Difference<MinuendType, SubtrahendType, D, d, R, r, 1>
    : public Stuff::LocalFunctionInterface<DifferenceTraits<MinuendType, SubtrahendType, D, d, R, r, 1>, D, d, R, r, 1>
{
public:
  typedef DifferenceTraits<MinuendType, SubtrahendType, D, d, R, r, 1> Traits;
  typedef typename Traits::EntityType EntityType;

  typedef D DomainFieldType;
  static const unsigned int dimDomain = d;
  typedef Dune::FieldVector<DomainFieldType, dimDomain> DomainType;

  typedef R RangeFieldType;
  static const unsigned int dimRange     = r;
  static const unsigned int dimRangeRows = dimRange;
  static const unsigned int dimRangeCols = 1;
  typedef Dune::FieldVector<RangeFieldType, dimRange> RangeType;

  typedef Dune::FieldMatrix<RangeFieldType, dimRange, dimDomain> JacobianRangeType;

  Difference(const MinuendType& minuend, const SubtrahendType& subtrahend)
    : minuend_(minuend)
    , subtrahend_(subtrahend)
    , tmp_value_(0)
    , tmp_jacobian_value_(0)
  {
    assert(minuend_.entity() == subtrahend_.entity());
  }

  const EntityType& entity() const
  {
    return minuend_.entity();
  }

  virtual int order() const
  {
    if ((minuend_.order() < 0) || (subtrahend_.order() < 0))
      return -1;
    else
      return std::max(minuend_.order(), subtrahend_.order());
  }

  void evaluate(const DomainType& xx, RangeType& ret) const
  {
    minuend_.evaluate(xx, ret);
    subtrahend_.evaluate(xx, tmp_value_);
    ret -= tmp_value_;
  }

  void jacobian(const DomainType& xx, JacobianRangeType& ret) const
  {
    minuend_.evaluate(xx, ret);
    subtrahend_.evaluate(xx, tmp_jacobian_value_);
    ret -= tmp_jacobian_value_;
  }

private:
  const MinuendType& minuend_;
  const SubtrahendType& subtrahend_;
  mutable RangeType tmp_value_;
  mutable JacobianRangeType tmp_jacobian_value_;
};

} // namespace LocalFunction

namespace DiscreteFunction {

template <class MinuendType, class SubtrahendType>
class Difference : public Stuff::LocalizableFunction
{
public:
  template <class EntityType>
  class LocalFunction
  {
    typedef typename MinuendType::template LocalFunction<EntityType> LocalMinuendType;
    typedef typename SubtrahendType::template LocalFunction<EntityType> LocalSubtrahendType;
    typedef typename LocalMinuendType::DomainFieldType DomainFieldType;
    static_assert(std::is_same<DomainFieldType, typename LocalSubtrahendType::DomainFieldType>::value,
                  "DomainFieldType of LocalMinuendType and LocalSubtrahendType do not match!");
    static const unsigned int dimDomain = LocalMinuendType::dimDomain;
    static_assert(dimDomain == LocalSubtrahendType::dimDomain,
                  "dimDomain of LocalMinuendType and LocalSubtrahendType do not match!");
    typedef typename LocalMinuendType::RangeFieldType RangeFieldType;
    static_assert(std::is_same<RangeFieldType, typename LocalSubtrahendType::RangeFieldType>::value,
                  "RangeFieldType of LocalMinuendType and LocalSubtrahendType do not match!");
    static const unsigned int dimRangeRows = LocalMinuendType::dimRangeRows;
    static_assert(dimRangeRows == LocalSubtrahendType::dimRangeRows,
                  "dimRangeRows of LocalMinuendType and LocalSubtrahendType do not match!");
    static const unsigned int dimRangeCols = LocalMinuendType::dimRangeCols;
    static_assert(dimRangeCols == LocalSubtrahendType::dimRangeCols,
                  "dimRangeCols of LocalMinuendType and LocalSubtrahendType do not match!");

  public:
    typedef GDT::LocalFunction::Difference<LocalMinuendType, LocalSubtrahendType, DomainFieldType, dimDomain,
                                           RangeFieldType, dimRangeRows, dimRangeCols> Type;
  };

  Difference(const MinuendType& minuend, const SubtrahendType& subtrahend)
    : minuend_(minuend)
    , subtrahend_(subtrahend)
  {
  }

  template <class EntityType>
  typename LocalFunction<EntityType>::Type localFunction(const EntityType& entity) const
  {
    return typename LocalFunction<EntityType>::Type(minuend_.localFunction(entity), subtrahend_.localFunction(entity));
  }

private:
  const MinuendType& minuend_;
  const SubtrahendType& subtrahend_;
}; // class Difference

} // namespace DiscreteFunction
} // namespace GDT
} // namespace Dune

#endif // DUNE_GDT_DISCRETEFUNCTION_DIFFERENCE_HH
<commit_msg>[discretefunction.difference] is now usable<commit_after>// This file is part of the dune-gdt project:
//   http://users.dune-project.org/projects/dune-gdt
// Copyright holders: Felix Albrecht
// License: BSD 2-Clause License (http://opensource.org/licenses/BSD-2-Clause)

#ifndef DUNE_GDT_DISCRETEFUNCTION_DIFFERENCE_HH
#define DUNE_GDT_DISCRETEFUNCTION_DIFFERENCE_HH

#include <type_traits>

#include <dune/stuff/functions/interfaces.hh>

namespace Dune {
namespace GDT {

namespace LocalFunction {

template <class EntityType, class MinuendType, class SubtrahendType>
class Difference;

template <class EntityImp, class MinuendType, class SubtrahendType>
class DifferenceTraits
{
public:
  typedef typename MinuendType::template LocalFunction<EntityImp>::Type LocalMinuendType;
  typedef typename SubtrahendType::template LocalFunction<EntityImp>::Type LocalSubtrahendType;
  typedef typename LocalMinuendType::DomainFieldType DomainFieldType;
  static_assert(std::is_same<DomainFieldType, typename LocalSubtrahendType::DomainFieldType>::value,
                "DomainFieldType of LocalMinuendType and LocalSubtrahendType do not match!");
  static const unsigned int dimDomain = LocalMinuendType::dimDomain;
  static_assert(dimDomain == LocalSubtrahendType::dimDomain,
                "dimDomain of LocalMinuendType and LocalSubtrahendType do not match!");
  typedef typename LocalMinuendType::RangeFieldType RangeFieldType;
  static_assert(std::is_same<RangeFieldType, typename LocalSubtrahendType::RangeFieldType>::value,
                "RangeFieldType of LocalMinuendType and LocalSubtrahendType do not match!");
  static const unsigned int dimRangeRows = LocalMinuendType::dimRangeRows;
  static_assert(dimRangeRows == LocalSubtrahendType::dimRangeRows,
                "dimRangeRows of LocalMinuendType and LocalSubtrahendType do not match!");
  static const unsigned int dimRangeCols = LocalMinuendType::dimRangeCols;
  static_assert(dimRangeCols == LocalSubtrahendType::dimRangeCols,
                "dimRangeCols of LocalMinuendType and LocalSubtrahendType do not match!");
  typedef EntityImp EntityType;
  typedef Difference<EntityType, MinuendType, SubtrahendType> derived_type;
  static_assert(std::is_base_of<Stuff::LocalFunctionInterface<typename LocalMinuendType::Traits, DomainFieldType,
                                                              dimDomain, RangeFieldType, dimRangeRows, dimRangeCols>,
                                LocalMinuendType>::value,
                "LocalMinuendType has to be derived from Stuff::LocalFunctionInterface!");
  static_assert(std::is_base_of<Stuff::LocalFunctionInterface<typename LocalSubtrahendType::Traits, DomainFieldType,
                                                              dimDomain, RangeFieldType, dimRangeRows, dimRangeCols>,
                                LocalSubtrahendType>::value,
                "LocalSubtrahendType has to be derived from Stuff::LocalFunctionInterface!");
};

template <class EntityImp, class MinuendType, class SubtrahendType>
class Difference
    : public Stuff::
          LocalFunctionInterface<DifferenceTraits<EntityImp, MinuendType, SubtrahendType>,
                                 typename DifferenceTraits<EntityImp, MinuendType, SubtrahendType>::DomainFieldType,
                                 DifferenceTraits<EntityImp, MinuendType, SubtrahendType>::dimDomain,
                                 typename DifferenceTraits<EntityImp, MinuendType, SubtrahendType>::RangeFieldType,
                                 DifferenceTraits<EntityImp, MinuendType, SubtrahendType>::dimRangeRows,
                                 DifferenceTraits<EntityImp, MinuendType, SubtrahendType>::dimRangeCols>
{
  typedef Stuff::
      LocalFunctionInterface<DifferenceTraits<EntityImp, MinuendType, SubtrahendType>,
                             typename DifferenceTraits<EntityImp, MinuendType, SubtrahendType>::DomainFieldType,
                             DifferenceTraits<EntityImp, MinuendType, SubtrahendType>::dimDomain,
                             typename DifferenceTraits<EntityImp, MinuendType, SubtrahendType>::RangeFieldType,
                             DifferenceTraits<EntityImp, MinuendType, SubtrahendType>::dimRangeRows,
                             DifferenceTraits<EntityImp, MinuendType, SubtrahendType>::dimRangeCols> BaseType;

public:
  typedef DifferenceTraits<EntityImp, MinuendType, SubtrahendType> Traits;
  typedef typename Traits::EntityType EntityType;

  typedef typename BaseType::DomainType DomainType;
  typedef typename BaseType::RangeType RangeType;
  typedef typename BaseType::JacobianRangeType JacobianRangeType;

  Difference(const EntityType& entity, const MinuendType& minuend, const SubtrahendType& subtrahend)
    : entity_(entity)
    , minuend_(minuend.localFunction(entity))
    , subtrahend_(subtrahend.localFunction(entity))
    , tmp_value_(0)
    , tmp_jacobian_value_(0)
  {
  }

  const EntityType& entity() const
  {
    return entity_;
  }

  virtual int order() const
  {
    if ((minuend_.order() < 0) || (subtrahend_.order() < 0))
      return -1;
    else
      return std::max(minuend_.order(), subtrahend_.order());
  }

  void evaluate(const DomainType& xx, RangeType& ret) const
  {
    minuend_.evaluate(xx, ret);
    subtrahend_.evaluate(xx, tmp_value_);
    ret -= tmp_value_;
  }

  void jacobian(const DomainType& xx, JacobianRangeType& ret) const
  {
    minuend_.evaluate(xx, ret);
    subtrahend_.evaluate(xx, tmp_jacobian_value_);
    ret -= tmp_jacobian_value_;
  }

private:
  const EntityType& entity_;
  const typename Traits::LocalMinuendType& minuend_;
  const typename Traits::LocalSubtrahendType& subtrahend_;
  mutable RangeType tmp_value_;
  mutable JacobianRangeType tmp_jacobian_value_;
};

} // namespace LocalFunction

namespace DiscreteFunction {

template <class MinuendType, class SubtrahendType>
class Difference : public Stuff::LocalizableFunction
{
  static_assert(std::is_base_of<Stuff::LocalizableFunction, MinuendType>::value,
                "MinuendType has to be derived from Stuff::LocalizableFunction!");
  static_assert(std::is_base_of<Stuff::LocalizableFunction, SubtrahendType>::value,
                "SubtrahendType has to be derived from Stuff::LocalizableFunction!");

public:
  template <class EntityType>
  class LocalFunction
  {
  public:
    typedef GDT::LocalFunction::Difference<EntityType, MinuendType, SubtrahendType> Type;
  };

  Difference(const MinuendType& minuend, const SubtrahendType& subtrahend)
    : minuend_(minuend)
    , subtrahend_(subtrahend)
  {
  }

  template <class EntityType>
  typename LocalFunction<EntityType>::Type localFunction(const EntityType& entity) const
  {
    return typename LocalFunction<EntityType>::Type(entity, minuend_, subtrahend_);
  }

private:
  const MinuendType& minuend_;
  const SubtrahendType& subtrahend_;
}; // class Difference

} // namespace DiscreteFunction
} // namespace GDT
} // namespace Dune

#endif // DUNE_GDT_DISCRETEFUNCTION_DIFFERENCE_HH
<|endoftext|>


<commit_before>#include "VDUtils.h"

using namespace VideoDromm;

VDUtils::VDUtils(VDSettingsRef aVDSettings)
{
	mVDSettings = aVDSettings;
	CI_LOG_V("VDUtils constructor");
	x1LeftOrTop = 0;
	y1LeftOrTop = 0;
	x2LeftOrTop = mVDSettings->mFboWidth;
	y2LeftOrTop = mVDSettings->mFboHeight;
	x1RightOrBottom = 0;
	y1RightOrBottom = 0;
	x2RightOrBottom = mVDSettings->mFboWidth;
	y2RightOrBottom = mVDSettings->mFboHeight;

}
float VDUtils::formatFloat(float f)
{
	int i;
	f *= 100;
	i = ((int)f) / 100;
	return (float)i;
}

void VDUtils::setup()
{
	createWarpFbos();
}

void VDUtils::createWarpFbos()
{
	// vector + dynamic resize
	/*for (int a = 0; a < 12; a++)
	{
	WarpFbo newWarpFbo;
	if (a == 0)
	{
	newWarpFbo.textureIndex = 0; // spout
	newWarpFbo.textureMode = mVDSettings->TEXTUREMODEINPUT;
	newWarpFbo.active = true;
	newWarpFbo.fbo = gl::Fbo::create(mVDSettings->mFboWidth, mVDSettings->mFboHeight);
	}
	else
	{
	newWarpFbo.textureIndex = 0; // index of MixFbo for shadamixa
	newWarpFbo.textureMode = mVDSettings->TEXTUREMODESHADER;
	newWarpFbo.active = false;
	newWarpFbo.fbo = gl::Fbo::create(mVDSettings->mPreviewFboWidth, mVDSettings->mPreviewFboHeight);
	}
	mVDSettings->mWarpFbos.push_back(newWarpFbo);
	}*/
}

int VDUtils::getWindowsResolution()
{
	CI_LOG_V("VDUtils::getWindowsResolution start");

	mVDSettings->mDisplayCount = 0;
	int w = 1024;// Display::getMainDisplay()->getWidth();
	int h = 768;//Display::getMainDisplay()->getHeight();
	CI_LOG_V("VDUtils::getWindowsResolution 1");

	// Display sizes
	if (mVDSettings->mAutoLayout)
	{
	CI_LOG_V("VDUtils::getWindowsResolution 2");

		mVDSettings->mMainWindowWidth = w;
		mVDSettings->mMainWindowHeight = h;
		mVDSettings->mRenderX = mVDSettings->mMainWindowWidth;
		// for MODE_MIX and triplehead(or doublehead), we only want 1/3 of the screen centered
		for (auto display : Display::getDisplays())
		{
			CI_LOG_V("VDUtils Window #" + toString(mVDSettings->mDisplayCount) + ": " + toString(display->getWidth()) + "x" + toString(display->getHeight()));
			mVDSettings->mDisplayCount++;
			mVDSettings->mRenderWidth = display->getWidth();
			mVDSettings->mRenderHeight = display->getHeight();
		}
	}
	else
	{
	CI_LOG_V("VDUtils::getWindowsResolution 3");

		for (auto display : Display::getDisplays())
		{
			CI_LOG_V("VDUtils Window #" + toString(mVDSettings->mDisplayCount) + ": " + toString(display->getWidth()) + "x" + toString(display->getHeight()));
			mVDSettings->mDisplayCount++;
		}
	}
	mVDSettings->mRenderY = 0;

	CI_LOG_V("VDUtils mMainDisplayWidth:" + toString(mVDSettings->mMainWindowWidth) + " mMainDisplayHeight:" + toString(mVDSettings->mMainWindowHeight));
	CI_LOG_V("VDUtils mRenderWidth:" + toString(mVDSettings->mRenderWidth) + " mRenderHeight:" + toString(mVDSettings->mRenderHeight));
	CI_LOG_V("VDUtils mRenderX:" + toString(mVDSettings->mRenderX) + " mRenderY:" + toString(mVDSettings->mRenderY));
	//mVDSettings->mRenderResoXY = vec2(mVDSettings->mRenderWidth, mVDSettings->mRenderHeight);
	// in case only one screen , render from x = 0
	if (mVDSettings->mDisplayCount == 1) mVDSettings->mRenderX = 0;
	splitWarp(mVDSettings->mFboWidth, mVDSettings->mFboHeight);
	return w;
}
void VDUtils::splitWarp(int fboWidth, int fboHeight) {

	x1LeftOrTop = x1RightOrBottom = 0;
	y1LeftOrTop = y1RightOrBottom = 0;
	x2LeftOrTop = x2RightOrBottom = mVDSettings->mFboWidth;
	y2LeftOrTop = y2RightOrBottom = mVDSettings->mFboHeight;

	if (mVDSettings->mSplitWarpH) {
		x2LeftOrTop = (fboWidth / 2) - 1;

		x1RightOrBottom = fboWidth / 2;
		x2RightOrBottom = fboWidth;
	}
	else if (mVDSettings->mSplitWarpV) {
		y2LeftOrTop = (fboHeight / 2) - 1;
		y1RightOrBottom = fboHeight / 2;
		y2RightOrBottom = fboHeight;
	}
	else
	{
		// no change
	}
	mSrcAreaLeftOrTop = Area(x1LeftOrTop, y1LeftOrTop, x2LeftOrTop, y2LeftOrTop);
	mSrcAreaRightOrBottom = Area(x1RightOrBottom, y1RightOrBottom, x2RightOrBottom, y2RightOrBottom);

}
void VDUtils::moveX1LeftOrTop(int x1) {
	x1LeftOrTop = x1;
	mSrcAreaLeftOrTop = Area(x1LeftOrTop, y1LeftOrTop, x2LeftOrTop, y2LeftOrTop);
}
void VDUtils::moveY1LeftOrTop(int y1) {
	y1LeftOrTop = y1;
	mSrcAreaLeftOrTop = Area(x1LeftOrTop, y1LeftOrTop, x2LeftOrTop, y2LeftOrTop);
}

Area VDUtils::getSrcAreaLeftOrTop() {
	return mSrcAreaLeftOrTop;
}
Area VDUtils::getSrcAreaRightOrBottom() {
	return mSrcAreaRightOrBottom;
}

fs::path VDUtils::getPath(string path)
{
	fs::path p = app::getAssetPath("");
	if (path.length() > 0) { p += fs::path("/" + path); }
	return p;
}
string VDUtils::getFileNameFromFullPath(string path)
{
	fs::path fullPath = path;
	return fullPath.filename().string();
}
<commit_msg>Displays not working on linux<commit_after>#include "VDUtils.h"

using namespace VideoDromm;

VDUtils::VDUtils(VDSettingsRef aVDSettings)
{
	mVDSettings = aVDSettings;
	CI_LOG_V("VDUtils constructor");
	x1LeftOrTop = 0;
	y1LeftOrTop = 0;
	x2LeftOrTop = mVDSettings->mFboWidth;
	y2LeftOrTop = mVDSettings->mFboHeight;
	x1RightOrBottom = 0;
	y1RightOrBottom = 0;
	x2RightOrBottom = mVDSettings->mFboWidth;
	y2RightOrBottom = mVDSettings->mFboHeight;

}
float VDUtils::formatFloat(float f)
{
	int i;
	f *= 100;
	i = ((int)f) / 100;
	return (float)i;
}

void VDUtils::setup()
{
	createWarpFbos();
}

void VDUtils::createWarpFbos()
{
	// vector + dynamic resize
	/*for (int a = 0; a < 12; a++)
	{
	WarpFbo newWarpFbo;
	if (a == 0)
	{
	newWarpFbo.textureIndex = 0; // spout
	newWarpFbo.textureMode = mVDSettings->TEXTUREMODEINPUT;
	newWarpFbo.active = true;
	newWarpFbo.fbo = gl::Fbo::create(mVDSettings->mFboWidth, mVDSettings->mFboHeight);
	}
	else
	{
	newWarpFbo.textureIndex = 0; // index of MixFbo for shadamixa
	newWarpFbo.textureMode = mVDSettings->TEXTUREMODESHADER;
	newWarpFbo.active = false;
	newWarpFbo.fbo = gl::Fbo::create(mVDSettings->mPreviewFboWidth, mVDSettings->mPreviewFboHeight);
	}
	mVDSettings->mWarpFbos.push_back(newWarpFbo);
	}*/
}

int VDUtils::getWindowsResolution()
{

	mVDSettings->mDisplayCount = 0;
	int w = Display::getMainDisplay()->getWidth();
	int h = Display::getMainDisplay()->getHeight();

	// Display sizes
	if (mVDSettings->mAutoLayout)
	{
		mVDSettings->mMainWindowWidth = w;
		mVDSettings->mMainWindowHeight = h;
		mVDSettings->mRenderX = mVDSettings->mMainWindowWidth;
		// for MODE_MIX and triplehead(or doublehead), we only want 1/3 of the screen centered
		for (auto display : Display::getDisplays())
		{
			CI_LOG_V("VDUtils Window #" + toString(mVDSettings->mDisplayCount) + ": " + toString(display->getWidth()) + "x" + toString(display->getHeight()));
			mVDSettings->mDisplayCount++;
			mVDSettings->mRenderWidth = display->getWidth();
			mVDSettings->mRenderHeight = display->getHeight();
		}
	}
	else
	{
		for (auto display : Display::getDisplays())
		{
			CI_LOG_V("VDUtils Window #" + toString(mVDSettings->mDisplayCount) + ": " + toString(display->getWidth()) + "x" + toString(display->getHeight()));
			mVDSettings->mDisplayCount++;
		}
	}
	mVDSettings->mRenderY = 0;

	CI_LOG_V("VDUtils mMainDisplayWidth:" + toString(mVDSettings->mMainWindowWidth) + " mMainDisplayHeight:" + toString(mVDSettings->mMainWindowHeight));
	CI_LOG_V("VDUtils mRenderWidth:" + toString(mVDSettings->mRenderWidth) + " mRenderHeight:" + toString(mVDSettings->mRenderHeight));
	CI_LOG_V("VDUtils mRenderX:" + toString(mVDSettings->mRenderX) + " mRenderY:" + toString(mVDSettings->mRenderY));
	//mVDSettings->mRenderResoXY = vec2(mVDSettings->mRenderWidth, mVDSettings->mRenderHeight);
	// in case only one screen , render from x = 0
	if (mVDSettings->mDisplayCount == 1) mVDSettings->mRenderX = 0;
	splitWarp(mVDSettings->mFboWidth, mVDSettings->mFboHeight);

	return w;
}
void VDUtils::splitWarp(int fboWidth, int fboHeight) {

	x1LeftOrTop = x1RightOrBottom = 0;
	y1LeftOrTop = y1RightOrBottom = 0;
	x2LeftOrTop = x2RightOrBottom = mVDSettings->mFboWidth;
	y2LeftOrTop = y2RightOrBottom = mVDSettings->mFboHeight;

	if (mVDSettings->mSplitWarpH) {
		x2LeftOrTop = (fboWidth / 2) - 1;

		x1RightOrBottom = fboWidth / 2;
		x2RightOrBottom = fboWidth;
	}
	else if (mVDSettings->mSplitWarpV) {
		y2LeftOrTop = (fboHeight / 2) - 1;
		y1RightOrBottom = fboHeight / 2;
		y2RightOrBottom = fboHeight;
	}
	else
	{
		// no change
	}
	mSrcAreaLeftOrTop = Area(x1LeftOrTop, y1LeftOrTop, x2LeftOrTop, y2LeftOrTop);
	mSrcAreaRightOrBottom = Area(x1RightOrBottom, y1RightOrBottom, x2RightOrBottom, y2RightOrBottom);

}
void VDUtils::moveX1LeftOrTop(int x1) {
	x1LeftOrTop = x1;
	mSrcAreaLeftOrTop = Area(x1LeftOrTop, y1LeftOrTop, x2LeftOrTop, y2LeftOrTop);
}
void VDUtils::moveY1LeftOrTop(int y1) {
	y1LeftOrTop = y1;
	mSrcAreaLeftOrTop = Area(x1LeftOrTop, y1LeftOrTop, x2LeftOrTop, y2LeftOrTop);
}

Area VDUtils::getSrcAreaLeftOrTop() {
	return mSrcAreaLeftOrTop;
}
Area VDUtils::getSrcAreaRightOrBottom() {
	return mSrcAreaRightOrBottom;
}

fs::path VDUtils::getPath(string path)
{
	fs::path p = app::getAssetPath("");
	if (path.length() > 0) { p += fs::path("/" + path); }
	return p;
}
string VDUtils::getFileNameFromFullPath(string path)
{
	fs::path fullPath = path;
	return fullPath.filename().string();
}
<|endoftext|>


<commit_before>/*===================================================================
QGroundControl Open Source Ground Control Station

(c) 2009, 2010 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>

This file is part of the QGROUNDCONTROL project

    QGROUNDCONTROL is free software: 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.

    QGROUNDCONTROL is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with QGROUNDCONTROL. If not, see <http://www.gnu.org/licenses/>.

======================================================================*/

/**
 * @file
 *   @brief Waypoint class
 *
 *   @author Benjamin Knecht <mavteam@student.ethz.ch>
 *   @author Petri Tanskanen <mavteam@student.ethz.ch>
 *
 */

#include "QsLog.h"
#include "Waypoint.h"
#include <QStringList>

Waypoint::Waypoint(quint16 _id, double _x, double _y, double _z, double _param1, double _param2, double _param3, double _param4,
                   bool _autocontinue, bool _current, MAV_FRAME _frame, MAV_CMD _action, const QString& _description)
    : id(_id),
      x(_x),
      y(_y),
      z(_z),
      yaw(_param4),
      frame(_frame),
      action(_action),
      autocontinue(_autocontinue),
      current(_current),
      orbit(_param3),
      param1(_param1),
      param2(_param2),
      name(QString("WP%1").arg(id, 2, 10, QChar('0'))),
      description(_description),
      reachedTime(0)
{
}

Waypoint::Waypoint(const Waypoint& waypoint)
    : id(waypoint.getId()),
      x(waypoint.getX()),
      y(waypoint.getY()),
      z(waypoint.getZ()),
      yaw(waypoint.getYaw()),
      frame(waypoint.getFrame()),
      action(waypoint.getAction()),
      autocontinue(waypoint.getAutoContinue()),
      current(waypoint.getCurrent()),
      orbit(waypoint.getParam3()),
      param1(waypoint.getParam1()),
      param2(waypoint.getParam2()),
      name(waypoint.getName()),
      description(waypoint.getDescription()),
      reachedTime(waypoint.getReachedTime())
{
    // Copy Constrcutor
}

Waypoint::~Waypoint()
{
}

bool Waypoint::isNavigationType()
{
    return (action < MAV_CMD_NAV_LAST);
}

void Waypoint::save(QTextStream &saveStream)
{
    QString position("%1\t%2\t%3");
    position = position.arg(x, 0, 'g', 18);
    position = position.arg(y, 0, 'g', 18);
    position = position.arg(z, 0, 'g', 18);
    QString parameters("%1\t%2\t%3\t%4");
    parameters = parameters.arg(param1, 0, 'g', 18).arg(param2, 0, 'g', 18).arg(orbit, 0, 'g', 18).arg(yaw, 0, 'g', 18);
    // FORMAT: <INDEX> <CURRENT WP> <COORD FRAME> <COMMAND> <PARAM1> <PARAM2> <PARAM3> <PARAM4> <PARAM5/X/LONGITUDE> <PARAM6/Y/LATITUDE> <PARAM7/Z/ALTITUDE> <AUTOCONTINUE> <DESCRIPTION>
    // as documented here: http://qgroundcontrol.org/waypoint_protocol
    saveStream << this->getId() << "\t" << this->getCurrent() << "\t" << this->getFrame() << "\t" << this->getAction() << "\t"  << parameters << "\t" << position  << "\t" << this->getAutoContinue() << "\r\n"; //"\t" << this->getDescription() << "\r\n";
}

bool Waypoint::load(QTextStream &loadStream)
{
    QString readLine;
    do {
        readLine = loadStream.readLine();
    } while(readLine.startsWith("#"));

    const QStringList& wpParams = readLine.split("\t");

    if (wpParams.size() == 12) {
        this->id = wpParams[0].toInt();
        this->current = (wpParams[1].toInt() == 1 ? true : false);
        this->frame = (MAV_FRAME) wpParams[2].toInt();
        this->action = (MAV_CMD) wpParams[3].toInt();
        this->param1 = wpParams[4].toDouble();
        this->param2 = wpParams[5].toDouble();
        this->orbit = wpParams[6].toDouble();
        this->yaw = wpParams[7].toDouble();
        this->x = wpParams[8].toDouble();
        this->y = wpParams[9].toDouble();
        this->z = wpParams[10].toDouble();
        this->autocontinue = (wpParams[11].toInt() == 1 ? true : false);
        //this->description = wpParams[12];
        return true;
    }
    return false;
}

void Waypoint::setId(quint16 id)
{
    this->id = id;
    this->name = QString("WP%1").arg(id, 2, 10, QChar('0'));
    emit changed(this);
}

void Waypoint::setX(double x)
{
    if (!isinf(x) && !isnan(x) && ((this->frame == MAV_FRAME_LOCAL_NED) || (this->frame == MAV_FRAME_LOCAL_ENU)))
    {
        this->x = x;
        emit changed(this);
    }
}

void Waypoint::setY(double y)
{
    if (!isinf(y) && !isnan(y) && ((this->frame == MAV_FRAME_LOCAL_NED) || (this->frame == MAV_FRAME_LOCAL_ENU)))
    {
        this->y = y;
        emit changed(this);
    }
}

void Waypoint::setZ(double z)
{
    if (!isinf(z) && !isnan(z) && ((this->frame == MAV_FRAME_LOCAL_NED) || (this->frame == MAV_FRAME_LOCAL_ENU)))
    {
        this->z = z;
        emit changed(this);
    }
}

void Waypoint::setLatitude(double lat)
{
    if (this->x != lat && ((this->frame == MAV_FRAME_GLOBAL) || (this->frame == MAV_FRAME_GLOBAL_RELATIVE_ALT)))
    {
        this->x = lat;
        emit changed(this);
    }
}

void Waypoint::setLongitude(double lon)
{
    if (this->y != lon && ((this->frame == MAV_FRAME_GLOBAL) || (this->frame == MAV_FRAME_GLOBAL_RELATIVE_ALT)))
    {
        this->y = lon;
        emit changed(this);
    }
}

void Waypoint::setAltitude(double altitude)
{
    if (this->z != altitude && ((this->frame == MAV_FRAME_GLOBAL) || (this->frame == MAV_FRAME_GLOBAL_RELATIVE_ALT)))
    {
        this->z = altitude;
        emit changed(this);
    }
}

void Waypoint::setYaw(int yaw)
{
    if (this->yaw != yaw)
    {
        this->yaw = yaw;
        emit changed(this);
    }
}

void Waypoint::setYaw(double yaw)
{
    if (this->yaw != yaw)
    {
        this->yaw = yaw;
        emit changed(this);
    }
}

void Waypoint::setAction(int action)
{
    if (this->action != (MAV_CMD)action)
    {
        this->action = (MAV_CMD)action;
        emit changed(this);
    }
}

void Waypoint::setAction(MAV_CMD action)
{
    if (this->action != action) {
        this->action = action;
        emit changed(this);
    }
}

void Waypoint::setFrame(MAV_FRAME frame)
{
    if (this->frame != frame) {
        this->frame = frame;
        emit changed(this);
    }
}

void Waypoint::setAutocontinue(bool autoContinue)
{
    if (this->autocontinue != autoContinue) {
        this->autocontinue = autoContinue;
        emit changed(this);
    }
}

void Waypoint::setCurrent(bool current)
{
    if (this->current != current)
    {
        this->current = current;
        emit changed(this);
    }
}

void Waypoint::setAcceptanceRadius(double radius)
{
    if (this->param2 != radius)
    {
        this->param2 = radius;
        emit changed(this);
    }
}

void Waypoint::setParam1(double param1)
{
    QLOG_DEBUG() << "SENDER:" << QObject::sender();
    QLOG_DEBUG()  << "PARAM1 SET REQ:" << param1;
    if (this->param1 != param1)
    {
        this->param1 = param1;
        emit changed(this);
    }
}

void Waypoint::setParam2(double param2)
{
    if (this->param2 != param2)
    {
        this->param2 = param2;
        emit changed(this);
    }
}

void Waypoint::setParam3(double param3)
{
    if (this->orbit != param3) {
        this->orbit = param3;
        emit changed(this);
    }
}

void Waypoint::setParam4(double param4)
{
    if (this->yaw != param4) {
        this->yaw = param4;
        emit changed(this);
    }
}

void Waypoint::setParam5(double param5)
{
    if (this->x != param5) {
        this->x = param5;
        emit changed(this);
    }
}

void Waypoint::setParam6(double param6)
{
    if (this->y != param6) {
        this->y = param6;
        emit changed(this);
    }
}

void Waypoint::setParam7(double param7)
{
    if (this->z != param7) {
        this->z = param7;
        emit changed(this);
    }
}

void Waypoint::setLoiterOrbit(double orbit)
{
    if (this->orbit != orbit) {
        this->orbit = orbit;
        emit changed(this);
    }
}

void Waypoint::setHoldTime(int holdTime)
{
    if (this->param1 != holdTime) {
        this->param1 = holdTime;
        emit changed(this);
    }
}

void Waypoint::setHoldTime(double holdTime)
{
    if (this->param1 != holdTime) {
        this->param1 = holdTime;
        emit changed(this);
    }
}

void Waypoint::setTurns(int turns)
{
    if (this->param1 != turns) {
        this->param1 = turns;
        emit changed(this);
    }
}

QString Waypoint::debugString()
{
     QString debugString("Waypoint: " + name
                + " id: " + QString::number(id)
                + " x:" + QString::number(x)
                + " y:" + QString::number(y)
                + " z:" + QString::number(z)
                + " yaw:" + QString::number(yaw)
                + " MAV_FRAME:" + QString::number(frame)
                + " MAV_CMD:" + QString::number(action)
                + " autocontinue:" + autocontinue
                + " current:" + current
                + " orbit:" + QString::number(orbit)
                + " param1:" + QString::number(param1)
                + " param2:" + QString::number(param2)
                + " turns:" + QString::number(turns)
                + " description:" + description
                + " reachedTime:" + QString::number(reachedTime)) ;
    return debugString;
}
<commit_msg>Mission Widget: Fix issue where optional description field created a crash<commit_after>/*===================================================================
QGroundControl Open Source Ground Control Station

(c) 2009, 2010 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>

This file is part of the QGROUNDCONTROL project

    QGROUNDCONTROL is free software: 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.

    QGROUNDCONTROL is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with QGROUNDCONTROL. If not, see <http://www.gnu.org/licenses/>.

======================================================================*/

/**
 * @file
 *   @brief Waypoint class
 *
 *   @author Benjamin Knecht <mavteam@student.ethz.ch>
 *   @author Petri Tanskanen <mavteam@student.ethz.ch>
 *
 */

#include "QsLog.h"
#include "Waypoint.h"
#include <QStringList>

Waypoint::Waypoint(quint16 _id, double _x, double _y, double _z, double _param1, double _param2, double _param3, double _param4,
                   bool _autocontinue, bool _current, MAV_FRAME _frame, MAV_CMD _action, const QString& _description)
    : id(_id),
      x(_x),
      y(_y),
      z(_z),
      yaw(_param4),
      frame(_frame),
      action(_action),
      autocontinue(_autocontinue),
      current(_current),
      orbit(_param3),
      param1(_param1),
      param2(_param2),
      name(QString("WP%1").arg(id, 2, 10, QChar('0'))),
      description(_description),
      reachedTime(0)
{
}

Waypoint::Waypoint(const Waypoint& waypoint)
    : id(waypoint.getId()),
      x(waypoint.getX()),
      y(waypoint.getY()),
      z(waypoint.getZ()),
      yaw(waypoint.getYaw()),
      frame(waypoint.getFrame()),
      action(waypoint.getAction()),
      autocontinue(waypoint.getAutoContinue()),
      current(waypoint.getCurrent()),
      orbit(waypoint.getParam3()),
      param1(waypoint.getParam1()),
      param2(waypoint.getParam2()),
      name(waypoint.getName()),
      description(waypoint.getDescription()),
      reachedTime(waypoint.getReachedTime())
{
    // Copy Constrcutor
}

Waypoint::~Waypoint()
{
}

bool Waypoint::isNavigationType()
{
    return (action < MAV_CMD_NAV_LAST);
}

void Waypoint::save(QTextStream &saveStream)
{
    QString position("%1\t%2\t%3");
    position = position.arg(x, 0, 'g', 18);
    position = position.arg(y, 0, 'g', 18);
    position = position.arg(z, 0, 'g', 18);
    QString parameters("%1\t%2\t%3\t%4");
    parameters = parameters.arg(param1, 0, 'g', 18).arg(param2, 0, 'g', 18).arg(orbit, 0, 'g', 18).arg(yaw, 0, 'g', 18);
    // FORMAT: <INDEX> <CURRENT WP> <COORD FRAME> <COMMAND> <PARAM1> <PARAM2> <PARAM3> <PARAM4> <PARAM5/X/LONGITUDE> <PARAM6/Y/LATITUDE> <PARAM7/Z/ALTITUDE> <AUTOCONTINUE> <DESCRIPTION>
    // as documented here: http://qgroundcontrol.org/waypoint_protocol
    saveStream << this->getId() << "\t" << this->getCurrent() << "\t" << this->getFrame() << "\t" << this->getAction() << "\t"  << parameters << "\t" << position  << "\t" << this->getAutoContinue() << "\r\n"; //"\t" << this->getDescription() << "\r\n";
}

bool Waypoint::load(QTextStream &loadStream)
{
    QString readLine;
    do {
        readLine = loadStream.readLine();
    } while(readLine.startsWith("#"));

    const QStringList& wpParams = readLine.split("\t");

    if ((wpParams.size() >= 12)
        &&(wpParams.size() <= 13)){
        this->id = wpParams[0].toInt();
        this->current = (wpParams[1].toInt() == 1 ? true : false);
        this->frame = (MAV_FRAME) wpParams[2].toInt();
        this->action = (MAV_CMD) wpParams[3].toInt();
        this->param1 = wpParams[4].toDouble();
        this->param2 = wpParams[5].toDouble();
        this->orbit = wpParams[6].toDouble();
        this->yaw = wpParams[7].toDouble();
        this->x = wpParams[8].toDouble();
        this->y = wpParams[9].toDouble();
        this->z = wpParams[10].toDouble();
        this->autocontinue = (wpParams[11].toInt() == 1 ? true : false);
        if(wpParams.size() == 13) { // Optional Description
            this->description = wpParams[12];
        }
        return true;
    }
    return false;
}

void Waypoint::setId(quint16 id)
{
    this->id = id;
    this->name = QString("WP%1").arg(id, 2, 10, QChar('0'));
    emit changed(this);
}

void Waypoint::setX(double x)
{
    if (!isinf(x) && !isnan(x) && ((this->frame == MAV_FRAME_LOCAL_NED) || (this->frame == MAV_FRAME_LOCAL_ENU)))
    {
        this->x = x;
        emit changed(this);
    }
}

void Waypoint::setY(double y)
{
    if (!isinf(y) && !isnan(y) && ((this->frame == MAV_FRAME_LOCAL_NED) || (this->frame == MAV_FRAME_LOCAL_ENU)))
    {
        this->y = y;
        emit changed(this);
    }
}

void Waypoint::setZ(double z)
{
    if (!isinf(z) && !isnan(z) && ((this->frame == MAV_FRAME_LOCAL_NED) || (this->frame == MAV_FRAME_LOCAL_ENU)))
    {
        this->z = z;
        emit changed(this);
    }
}

void Waypoint::setLatitude(double lat)
{
    if (this->x != lat && ((this->frame == MAV_FRAME_GLOBAL) || (this->frame == MAV_FRAME_GLOBAL_RELATIVE_ALT)))
    {
        this->x = lat;
        emit changed(this);
    }
}

void Waypoint::setLongitude(double lon)
{
    if (this->y != lon && ((this->frame == MAV_FRAME_GLOBAL) || (this->frame == MAV_FRAME_GLOBAL_RELATIVE_ALT)))
    {
        this->y = lon;
        emit changed(this);
    }
}

void Waypoint::setAltitude(double altitude)
{
    if (this->z != altitude && ((this->frame == MAV_FRAME_GLOBAL) || (this->frame == MAV_FRAME_GLOBAL_RELATIVE_ALT)))
    {
        this->z = altitude;
        emit changed(this);
    }
}

void Waypoint::setYaw(int yaw)
{
    if (this->yaw != yaw)
    {
        this->yaw = yaw;
        emit changed(this);
    }
}

void Waypoint::setYaw(double yaw)
{
    if (this->yaw != yaw)
    {
        this->yaw = yaw;
        emit changed(this);
    }
}

void Waypoint::setAction(int action)
{
    if (this->action != (MAV_CMD)action)
    {
        this->action = (MAV_CMD)action;
        emit changed(this);
    }
}

void Waypoint::setAction(MAV_CMD action)
{
    if (this->action != action) {
        this->action = action;
        emit changed(this);
    }
}

void Waypoint::setFrame(MAV_FRAME frame)
{
    if (this->frame != frame) {
        this->frame = frame;
        emit changed(this);
    }
}

void Waypoint::setAutocontinue(bool autoContinue)
{
    if (this->autocontinue != autoContinue) {
        this->autocontinue = autoContinue;
        emit changed(this);
    }
}

void Waypoint::setCurrent(bool current)
{
    if (this->current != current)
    {
        this->current = current;
        emit changed(this);
    }
}

void Waypoint::setAcceptanceRadius(double radius)
{
    if (this->param2 != radius)
    {
        this->param2 = radius;
        emit changed(this);
    }
}

void Waypoint::setParam1(double param1)
{
    QLOG_DEBUG() << "SENDER:" << QObject::sender();
    QLOG_DEBUG()  << "PARAM1 SET REQ:" << param1;
    if (this->param1 != param1)
    {
        this->param1 = param1;
        emit changed(this);
    }
}

void Waypoint::setParam2(double param2)
{
    if (this->param2 != param2)
    {
        this->param2 = param2;
        emit changed(this);
    }
}

void Waypoint::setParam3(double param3)
{
    if (this->orbit != param3) {
        this->orbit = param3;
        emit changed(this);
    }
}

void Waypoint::setParam4(double param4)
{
    if (this->yaw != param4) {
        this->yaw = param4;
        emit changed(this);
    }
}

void Waypoint::setParam5(double param5)
{
    if (this->x != param5) {
        this->x = param5;
        emit changed(this);
    }
}

void Waypoint::setParam6(double param6)
{
    if (this->y != param6) {
        this->y = param6;
        emit changed(this);
    }
}

void Waypoint::setParam7(double param7)
{
    if (this->z != param7) {
        this->z = param7;
        emit changed(this);
    }
}

void Waypoint::setLoiterOrbit(double orbit)
{
    if (this->orbit != orbit) {
        this->orbit = orbit;
        emit changed(this);
    }
}

void Waypoint::setHoldTime(int holdTime)
{
    if (this->param1 != holdTime) {
        this->param1 = holdTime;
        emit changed(this);
    }
}

void Waypoint::setHoldTime(double holdTime)
{
    if (this->param1 != holdTime) {
        this->param1 = holdTime;
        emit changed(this);
    }
}

void Waypoint::setTurns(int turns)
{
    if (this->param1 != turns) {
        this->param1 = turns;
        emit changed(this);
    }
}

QString Waypoint::debugString()
{
     QString debugString("Waypoint: " + name
                + " id: " + QString::number(id)
                + " x:" + QString::number(x)
                + " y:" + QString::number(y)
                + " z:" + QString::number(z)
                + " yaw:" + QString::number(yaw)
                + " MAV_FRAME:" + QString::number(frame)
                + " MAV_CMD:" + QString::number(action)
                + " autocontinue:" + autocontinue
                + " current:" + current
                + " orbit:" + QString::number(orbit)
                + " param1:" + QString::number(param1)
                + " param2:" + QString::number(param2)
                + " turns:" + QString::number(turns)
                + " description:" + description
                + " reachedTime:" + QString::number(reachedTime)) ;
    return debugString;
}
<|endoftext|>


<commit_before>// Copyright 2015-2020 Elviss Strazdins. All rights reserved.

#include "../../core/Setup.h"
#include <cstdio>
#include <cstring>
#include <system_error>
#include <unordered_map>
#include <dirent.h>
#include <fcntl.h>
#include <unistd.h>
#include <linux/joystick.h>
#if OUZEL_SUPPORTS_X11
#  include <X11/cursorfont.h>
#endif
#include "InputSystemLinux.hpp"
#include "CursorLinux.hpp"
#include "../../core/linux/EngineLinux.hpp"
#include "../../core/linux/NativeWindowLinux.hpp"

namespace ouzel::input::linux
{
    InputSystem::InputSystem(const std::function<std::future<bool>(const Event&)>& initCallback):
#if OUZEL_SUPPORTS_X11
        input::InputSystem(initCallback),
        keyboardDevice(std::make_unique<KeyboardDevice>(*this, getNextDeviceId())),
        mouseDevice(std::make_unique<MouseDevice>(*this, getNextDeviceId())),
        touchpadDevice(std::make_unique<TouchpadDevice>(*this, getNextDeviceId(), true))
#else
        InputSystem(initCallback)
#endif
    {
#if OUZEL_SUPPORTS_X11
        auto engineLinux = static_cast<core::linux::Engine*>(engine);
        auto display = engineLinux->getDisplay();

        char data[1] = {0};

        Pixmap pixmap = XCreateBitmapFromData(display, DefaultRootWindow(display), data, 1, 1);
        if (pixmap)
        {
            XColor color;
            color.red = color.green = color.blue = 0;

            emptyCursor = XCreatePixmapCursor(display, pixmap, pixmap, &color, &color, 0, 0);
            XFreePixmap(display, pixmap);
        }
#endif

        using CloseDirFunction = int(*)(DIR*);
        std::unique_ptr<DIR, CloseDirFunction> dir(opendir("/dev/input"), closedir);
        if (!dir)
            throw std::system_error(errno, std::system_category(), "Failed to open directory");

        while (const dirent* ent = readdir(dir.get()))
        {
            if (std::strncmp("event", ent->d_name, 5) == 0)
            {
                try
                {
                    std::string filename = std::string("/dev/input/") + ent->d_name;
                    auto eventDevice = std::make_unique<EventDevice>(*this, filename);
                    eventDevices.insert(std::pair(eventDevice->getFd(), std::move(eventDevice)));
                }
                catch (const std::exception&)
                {
                }
            }
        }
    }

    InputSystem::~InputSystem()
    {
#if OUZEL_SUPPORTS_X11
        auto engineLinux = static_cast<core::linux::Engine*>(engine);
        if (emptyCursor != None) XFreeCursor(engineLinux->getDisplay(), emptyCursor);
#endif
    }

    void InputSystem::executeCommand(const Command& command)
    {
        switch (command.type)
        {
            case Command::Type::startDeviceDiscovery:
                discovering = true;
                break;
            case Command::Type::stopDeviceDiscovery:
                discovering = false;
                break;
            case Command::Type::setPlayerIndex:
            {
                break;
            }
            case Command::Type::setVibration:
            {
                break;
            }
            case Command::Type::setPosition:
            {
                if (InputDevice* inputDevice = getInputDevice(command.deviceId))
                {
                    if (inputDevice == mouseDevice.get())
                        mouseDevice->setPosition(command.position);
                }
                break;
            }
            case Command::Type::initCursor:
            {
                if (command.cursorResource > cursors.size())
                    cursors.resize(command.cursorResource);

                if (command.data.empty())
                {
                    auto cursor = std::make_unique<Cursor>(command.systemCursor);
                    cursors[command.cursorResource - 1] = std::move(cursor);
                }
                else
                {
                    auto cursor = std::make_unique<Cursor>(command.data, command.size,
                                                           command.pixelFormat, command.hotSpot);
                    cursors[command.cursorResource - 1] = std::move(cursor);
                }
                break;
            }
            case Command::Type::destroyCursor:
            {
#if OUZEL_SUPPORTS_X11
                Cursor* cursor = cursors[command.cursorResource - 1].get();

                if (mouseDevice->getCursor() == cursor)
                {
                    mouseDevice->setCursor(nullptr);
                    updateCursor();
                }
#endif

                cursors[command.cursorResource - 1].reset();
                break;
            }
            case Command::Type::setCursor:
            {
                if (InputDevice* inputDevice = getInputDevice(command.deviceId))
                {
                    if (inputDevice == mouseDevice.get())
                    {
                        if (command.cursorResource)
                            mouseDevice->setCursor(cursors[command.cursorResource - 1].get());
                        else
                            mouseDevice->setCursor(nullptr);
#if OUZEL_SUPPORTS_X11
                        updateCursor();
#endif
                    }
                }
                break;
            }
            case Command::Type::setCursorVisible:
            {
                if (InputDevice* inputDevice = getInputDevice(command.deviceId))
                {
                    if (inputDevice == mouseDevice.get())
                        mouseDevice->setCursorVisible(command.visible);
                }
                break;
            }
            case Command::Type::setCursorLocked:
            {
                if (InputDevice* inputDevice = getInputDevice(command.deviceId))
                {
                    if (inputDevice == mouseDevice.get())
                        mouseDevice->setCursorLocked(command.locked);
                }
                break;
            }
            default:
                break;
        }
    }

    void InputSystem::update()
    {
        fd_set rfds;
        struct timeval tv;
        tv.tv_sec = 0;
        tv.tv_usec = 0;

        FD_ZERO(&rfds);

        int maxFd = 0;

        for (const auto& i : eventDevices)
        {
            FD_SET(i.first, &rfds);
            if (i.first > maxFd) maxFd = i.first;
        }

        int retval;
        if ((retval = select(maxFd + 1, &rfds, nullptr, nullptr, &tv)) == -1)
            throw std::system_error(errno, std::system_category(), "Select failed");

        if (retval > 0)
        {
            for (auto i = eventDevices.begin(); i != eventDevices.end();)
            {
                if (FD_ISSET(i->first, &rfds))
                {
                    try
                    {
                        i->second->update();
                        ++i;
                    }
                    catch (const std::exception&)
                    {
                        i = eventDevices.erase(i);
                    }
                }
                else
                    ++i;
            }
        }

        if (discovering)
        {
            using CloseDirFunction = int(*)(DIR*);
            std::unique_ptr<DIR, CloseDirFunction> dir(opendir("/dev/input"), closedir);

            if (!dir)
                throw std::system_error(errno, std::system_category(), "Failed to open directory");

            while (const dirent* ent = readdir(dir.get()))
            {
                if (std::strncmp("event", ent->d_name, 5) == 0)
                {
                    try
                    {
                        std::string filename = std::string("/dev/input/") + ent->d_name;
                        auto eventDevice = std::make_unique<EventDevice>(*this, filename);
                        eventDevices.insert(std::pair(eventDevice->getFd(), std::move(eventDevice)));
                    }
                    catch (const std::exception&)
                    {
                    }
                }
            }
        }
    }

#if OUZEL_SUPPORTS_X11
    void InputSystem::updateCursor() const
    {
        auto engineLinux = static_cast<core::linux::Engine*>(engine);
        auto windowLinux = static_cast<core::linux::NativeWindow*>(engine->getWindow()->getNativeWindow());
        auto display = engineLinux->getDisplay();
        auto window = windowLinux->getNativeWindow();

        if (mouseDevice->isCursorVisible())
        {
            if (mouseDevice->getCursor())
                XDefineCursor(display, window, mouseDevice->getCursor()->getCursor());
            else
                XUndefineCursor(display, window);
        }
        else
            XDefineCursor(display, window, emptyCursor);
    }
#endif
}
<commit_msg>Fix the initialization of the input system on raspberry Pi<commit_after>// Copyright 2015-2020 Elviss Strazdins. All rights reserved.

#include "../../core/Setup.h"
#include <cstdio>
#include <cstring>
#include <system_error>
#include <unordered_map>
#include <dirent.h>
#include <fcntl.h>
#include <unistd.h>
#include <linux/joystick.h>
#if OUZEL_SUPPORTS_X11
#  include <X11/cursorfont.h>
#endif
#include "InputSystemLinux.hpp"
#include "CursorLinux.hpp"
#include "../../core/linux/EngineLinux.hpp"
#include "../../core/linux/NativeWindowLinux.hpp"

namespace ouzel::input::linux
{
    InputSystem::InputSystem(const std::function<std::future<bool>(const Event&)>& initCallback):
#if OUZEL_SUPPORTS_X11
        input::InputSystem(initCallback),
        keyboardDevice(std::make_unique<KeyboardDevice>(*this, getNextDeviceId())),
        mouseDevice(std::make_unique<MouseDevice>(*this, getNextDeviceId())),
        touchpadDevice(std::make_unique<TouchpadDevice>(*this, getNextDeviceId(), true))
#else
        input::InputSystem(initCallback)
#endif
    {
#if OUZEL_SUPPORTS_X11
        auto engineLinux = static_cast<core::linux::Engine*>(engine);
        auto display = engineLinux->getDisplay();

        char data[1] = {0};

        Pixmap pixmap = XCreateBitmapFromData(display, DefaultRootWindow(display), data, 1, 1);
        if (pixmap)
        {
            XColor color;
            color.red = color.green = color.blue = 0;

            emptyCursor = XCreatePixmapCursor(display, pixmap, pixmap, &color, &color, 0, 0);
            XFreePixmap(display, pixmap);
        }
#endif

        using CloseDirFunction = int(*)(DIR*);
        std::unique_ptr<DIR, CloseDirFunction> dir(opendir("/dev/input"), closedir);
        if (!dir)
            throw std::system_error(errno, std::system_category(), "Failed to open directory");

        while (const dirent* ent = readdir(dir.get()))
        {
            if (std::strncmp("event", ent->d_name, 5) == 0)
            {
                try
                {
                    std::string filename = std::string("/dev/input/") + ent->d_name;
                    auto eventDevice = std::make_unique<EventDevice>(*this, filename);
                    eventDevices.insert(std::pair(eventDevice->getFd(), std::move(eventDevice)));
                }
                catch (const std::exception&)
                {
                }
            }
        }
    }

    InputSystem::~InputSystem()
    {
#if OUZEL_SUPPORTS_X11
        auto engineLinux = static_cast<core::linux::Engine*>(engine);
        if (emptyCursor != None) XFreeCursor(engineLinux->getDisplay(), emptyCursor);
#endif
    }

    void InputSystem::executeCommand(const Command& command)
    {
        switch (command.type)
        {
            case Command::Type::startDeviceDiscovery:
                discovering = true;
                break;
            case Command::Type::stopDeviceDiscovery:
                discovering = false;
                break;
            case Command::Type::setPlayerIndex:
            {
                break;
            }
            case Command::Type::setVibration:
            {
                break;
            }
            case Command::Type::setPosition:
            {
                if (InputDevice* inputDevice = getInputDevice(command.deviceId))
                {
                    if (inputDevice == mouseDevice.get())
                        mouseDevice->setPosition(command.position);
                }
                break;
            }
            case Command::Type::initCursor:
            {
                if (command.cursorResource > cursors.size())
                    cursors.resize(command.cursorResource);

                if (command.data.empty())
                {
                    auto cursor = std::make_unique<Cursor>(command.systemCursor);
                    cursors[command.cursorResource - 1] = std::move(cursor);
                }
                else
                {
                    auto cursor = std::make_unique<Cursor>(command.data, command.size,
                                                           command.pixelFormat, command.hotSpot);
                    cursors[command.cursorResource - 1] = std::move(cursor);
                }
                break;
            }
            case Command::Type::destroyCursor:
            {
#if OUZEL_SUPPORTS_X11
                Cursor* cursor = cursors[command.cursorResource - 1].get();

                if (mouseDevice->getCursor() == cursor)
                {
                    mouseDevice->setCursor(nullptr);
                    updateCursor();
                }
#endif

                cursors[command.cursorResource - 1].reset();
                break;
            }
            case Command::Type::setCursor:
            {
                if (InputDevice* inputDevice = getInputDevice(command.deviceId))
                {
                    if (inputDevice == mouseDevice.get())
                    {
                        if (command.cursorResource)
                            mouseDevice->setCursor(cursors[command.cursorResource - 1].get());
                        else
                            mouseDevice->setCursor(nullptr);
#if OUZEL_SUPPORTS_X11
                        updateCursor();
#endif
                    }
                }
                break;
            }
            case Command::Type::setCursorVisible:
            {
                if (InputDevice* inputDevice = getInputDevice(command.deviceId))
                {
                    if (inputDevice == mouseDevice.get())
                        mouseDevice->setCursorVisible(command.visible);
                }
                break;
            }
            case Command::Type::setCursorLocked:
            {
                if (InputDevice* inputDevice = getInputDevice(command.deviceId))
                {
                    if (inputDevice == mouseDevice.get())
                        mouseDevice->setCursorLocked(command.locked);
                }
                break;
            }
            default:
                break;
        }
    }

    void InputSystem::update()
    {
        fd_set rfds;
        struct timeval tv;
        tv.tv_sec = 0;
        tv.tv_usec = 0;

        FD_ZERO(&rfds);

        int maxFd = 0;

        for (const auto& i : eventDevices)
        {
            FD_SET(i.first, &rfds);
            if (i.first > maxFd) maxFd = i.first;
        }

        int retval;
        if ((retval = select(maxFd + 1, &rfds, nullptr, nullptr, &tv)) == -1)
            throw std::system_error(errno, std::system_category(), "Select failed");

        if (retval > 0)
        {
            for (auto i = eventDevices.begin(); i != eventDevices.end();)
            {
                if (FD_ISSET(i->first, &rfds))
                {
                    try
                    {
                        i->second->update();
                        ++i;
                    }
                    catch (const std::exception&)
                    {
                        i = eventDevices.erase(i);
                    }
                }
                else
                    ++i;
            }
        }

        if (discovering)
        {
            using CloseDirFunction = int(*)(DIR*);
            std::unique_ptr<DIR, CloseDirFunction> dir(opendir("/dev/input"), closedir);

            if (!dir)
                throw std::system_error(errno, std::system_category(), "Failed to open directory");

            while (const dirent* ent = readdir(dir.get()))
            {
                if (std::strncmp("event", ent->d_name, 5) == 0)
                {
                    try
                    {
                        std::string filename = std::string("/dev/input/") + ent->d_name;
                        auto eventDevice = std::make_unique<EventDevice>(*this, filename);
                        eventDevices.insert(std::pair(eventDevice->getFd(), std::move(eventDevice)));
                    }
                    catch (const std::exception&)
                    {
                    }
                }
            }
        }
    }

#if OUZEL_SUPPORTS_X11
    void InputSystem::updateCursor() const
    {
        auto engineLinux = static_cast<core::linux::Engine*>(engine);
        auto windowLinux = static_cast<core::linux::NativeWindow*>(engine->getWindow()->getNativeWindow());
        auto display = engineLinux->getDisplay();
        auto window = windowLinux->getNativeWindow();

        if (mouseDevice->isCursorVisible())
        {
            if (mouseDevice->getCursor())
                XDefineCursor(display, window, mouseDevice->getCursor()->getCursor());
            else
                XUndefineCursor(display, window);
        }
        else
            XDefineCursor(display, window, emptyCursor);
    }
#endif
}
<|endoftext|>


<commit_before>/*
 * Copyright 1999-2004 The Apache Software Foundation.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
#if !defined(XALANMEMMGRHELPER_HEADER_GUARD_1357924680)
#define XALANMEMMGRHELPER_HEADER_GUARD_1357924680

// Base include file.  Must be first.
#include <xalanc/PlatformSupport/PlatformSupportDefinitions.hpp>

#include <xalanc/Include/XalanMemMgrAutoPtr.hpp>

XALAN_CPP_NAMESPACE_BEGIN

template <class Type>
Type*
cloneObjWithMemMgr(const Type& other, MemoryManagerType& theManager)
{

    XalanMemMgrAutoPtr<Type, false> theGuard( theManager , (Type*)theManager.allocate(sizeof(Type)));

    Type* theResult = theGuard.get();

    new (theResult) Type(other, theManager);

    theGuard.release();

    return theResult;
}

template <class Type>
Type*
cloneObj(const Type& other, MemoryManagerType& theManager)
{

    XalanMemMgrAutoPtr<Type, false> theGuard( theManager , (Type*)theManager.allocate(sizeof(Type)));

    Type* theResult = theGuard.get();

    new (theResult) Type(other);

    theGuard.release();

    return theResult;
}

template <class Type>
class CreateObjFunctor
{
public:
	Type*
	operator()(MemoryManagerType& theManager)
	{

		XalanMemMgrAutoPtr<Type, false> theGuard( theManager , (Type*)theManager.allocate(sizeof(Type)));

		Type* theResult = theGuard.get();

		new (theResult) Type(theManager);

		theGuard.release();

		return theResult;
	}
};

template <class Type>
void
destroyObjWithMemMgr( Type* ptr, MemoryManagerType& theManager)
{
    if( ptr == 0 )
        return;

    ptr->~Type();

    theManager.deallocate((void*)ptr);
}

XALAN_CPP_NAMESPACE_END

#endif	// if !defined(XALANMEMMGRHELPER_HEADER_GUARD_1357924680)
<commit_msg>Fix for Jira issue XALANC-504.<commit_after>/*
 * Copyright 1999-2004 The Apache Software Foundation.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
#if !defined(XALANMEMMGRHELPER_HEADER_GUARD_1357924680)
#define XALANMEMMGRHELPER_HEADER_GUARD_1357924680

// Base include file.  Must be first.
#include <xalanc/PlatformSupport/PlatformSupportDefinitions.hpp>

#include <xalanc/Include/XalanMemMgrAutoPtr.hpp>

XALAN_CPP_NAMESPACE_BEGIN

template <class Type>
Type*
cloneObjWithMemMgr(const Type& other, MemoryManagerType& theManager)
{

    XalanMemMgrAutoPtr<Type, false> theGuard( theManager , (Type*)theManager.allocate(sizeof(Type)));

    Type* theResult = theGuard.get();

    new (theResult) Type(other, theManager);

    theGuard.release();

    return theResult;
}

template <class Type>
Type*
cloneObj(const Type& other, MemoryManagerType& theManager)
{

    XalanMemMgrAutoPtr<Type, false> theGuard( theManager , (Type*)theManager.allocate(sizeof(Type)));

    Type* theResult = theGuard.get();

    new (theResult) Type(other);

    theGuard.release();

    return theResult;
}

template <class Type>
class CreateObjFunctor
{
public:
	Type*
	operator()(MemoryManagerType& theManager)
	{

		XalanMemMgrAutoPtr<Type, false> theGuard( theManager , (Type*)theManager.allocate(sizeof(Type)));

		Type* theResult = theGuard.get();

		new (theResult) Type(theManager);

		theGuard.release();

		return theResult;
	}
};

template <class Type>
void
destroyObjWithMemMgr(const Type* ptr, MemoryManagerType& theManager)
{
    if (ptr != 0)
    {
        Type* const     nonConstPointer =
#if defined(XALAN_OLD_STYLE_CASTS)
            (const Type*)ptr;
#else
            const_cast<Type*>(ptr);
#endif
        nonConstPointer->~Type();

        theManager.deallocate(nonConstPointer);
    }
}

XALAN_CPP_NAMESPACE_END

#endif	// if !defined(XALANMEMMGRHELPER_HEADER_GUARD_1357924680)
<|endoftext|>


<commit_before>/*=========================================================================

  Program:   Monteverdi2
  Language:  C++

  Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
  See Copyright.txt for details.

  Monteverdi2 is distributed under the CeCILL licence version 2. See
  Licence_CeCILL_V2-en.txt or
  http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt for more 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 notices for more information.

=========================================================================*/
#include "Gui/mvdPixelDescriptionWidget.h"
#include "Gui/ui_mvdPixelDescriptionWidget.h"

/*****************************************************************************/
/* INCLUDE SECTION                                                           */

//
// Qt includes (sorted by alphabetic order)
//// Must be included before system/custom includes.

//
// System includes (sorted by alphabetic order)

//
// ITK includes (sorted by alphabetic order)

//
// OTB includes (sorted by alphabetic order)

//
// Monteverdi includes (sorted by alphabetic order)
#include "Core/mvdAlgorithm.h"

namespace mvd
{
/*
  TRANSLATOR mvd::PixelDescriptionWidget

  Necessary for lupdate to be aware of C++ namespaces.

  Context comment for translator.
*/

/*****************************************************************************/
/* CONSTANTS                                                                 */

/*****************************************************************************/
/* STATIC IMPLEMENTATION SECTION                                             */

/*****************************************************************************/
/* CLASS IMPLEMENTATION SECTION                                              */

/*******************************************************************************/
PixelDescriptionWidget
::PixelDescriptionWidget( QWidget* parent, Qt::WindowFlags flags  ):
  QWidget( parent, flags ),
  m_UI( new mvd::Ui::PixelDescriptionWidget() )
{
  m_UI->setupUi( this );

  SetupUI();
}

/*******************************************************************************/
PixelDescriptionWidget
::~PixelDescriptionWidget()
{
}

/*******************************************************************************/
void
PixelDescriptionWidget
::SetupUI()
{
  //
  // Cartographic coordiantes
  m_CartographicRootItem = new QTreeWidgetItem( GetDescriptionTree() );
  //m_CartographicRootItem->setText(0, tr("Cartographic"));
  m_CartographicRootItem->setExpanded(true);

  // m_CartographicItem = new QTreeWidgetItem( m_CartographicRootItem );
  // m_CartographicItem->setText(0, tr("Coordinates"));

  //
  // Geographic coordinates
  m_GeographicRootItem = new QTreeWidgetItem( GetDescriptionTree() );
  m_GeographicRootItem->setText(0, tr("Geographic"));
  m_GeographicRootItem->setExpanded(true);

  //m_GeographicItem = new QTreeWidgetItem( m_GeographicRootItem );
  //m_GeographicItem->setText(0, tr("Coordinates"));

  //
  // Child items will be created + updated in a dedicated slot
  m_PixelValueRootItem = new QTreeWidgetItem( GetDescriptionTree() );
  m_PixelValueRootItem->setText(0, tr("Pixel Values"));
  m_PixelValueRootItem->setExpanded(true);
}

/*******************************************************************************/
QTreeWidget *
PixelDescriptionWidget
::GetDescriptionTree()
{
  return m_UI->m_DescriptionTree;
}

/*******************************************************************************/
/* SLOTS                                                                       */
/*******************************************************************************/
void
PixelDescriptionWidget
::OnCurrentPhysicalUpdated(const QStringList & currentPhysical)
{
  //m_CartographicItem->setText(1, currentPhysical);

  if (!currentPhysical.empty())
    {
    // remove the previous QTreeWidgetItem  of m_GeographicRootItem
    while( m_CartographicRootItem->childCount()>0 )
      {
      // Remove QTreeWidgetItem
      QTreeWidgetItem* child = m_CartographicRootItem->takeChild( 0 );

      // Delete it from memory.
      delete child;
      child = NULL;
      }

    m_CartographicRootItem->setText(0, QString("%1").arg(currentPhysical[0]));

    // fill with the new values
    QTreeWidgetItem * iCartoXItem = new QTreeWidgetItem( m_CartographicRootItem );
    iCartoXItem->setText(0,QString( tr("X") ));
    iCartoXItem->setText(1, QString("%1").arg(currentPhysical[1] ) );

    QTreeWidgetItem * iCartoYItem = new QTreeWidgetItem( m_CartographicRootItem );
    iCartoYItem->setText(0,QString( tr("Y") ));
    iCartoYItem->setText(1, QString("%1").arg(currentPhysical[2] ) );
    }
}

/*******************************************************************************/
void
PixelDescriptionWidget
::OnCurrentGeographicUpdated(const QStringList&/*const QString &*/ currentGeo)
{
  if (!currentGeo.empty())
    {
    // remove the previous QTreeWidgetItem  of m_GeographicRootItem
    while( m_GeographicRootItem->childCount()>0 )
      {
      // Remove QTreeWidgetItem
      QTreeWidgetItem* child = m_GeographicRootItem->takeChild( 0 );

      // Delete it from memory.
      delete child;
      child = NULL;
      }

    m_GeographicRootItem->setText(0, QString("%1").arg(currentGeo[0]));
    // fill with the new values
    QTreeWidgetItem * iGeoLongItem = new QTreeWidgetItem( m_GeographicRootItem );
    iGeoLongItem->setText(0,QString( tr("Long") ));
    iGeoLongItem->setText(1, QString("%1").arg(currentGeo[1] ) );

    QTreeWidgetItem * iGeoLatItem = new QTreeWidgetItem( m_GeographicRootItem );
    iGeoLatItem->setText(0,QString( tr("Lat") ));
    iGeoLatItem->setText(1, QString("%1").arg(currentGeo[2] ) );

    QTreeWidgetItem * iGeoElevationItem = new QTreeWidgetItem( m_GeographicRootItem );
    iGeoElevationItem->setText(0,QString( tr("Elevation") ));
    if(currentGeo.size() > 3)
      {
      iGeoElevationItem->setText(1, QString("%1").arg(currentGeo[3] ) );
      }
    else
      {
      iGeoElevationItem->setText(1, QString(tr("Not available")));
      }
    }
}
/*******************************************************************************/
void
PixelDescriptionWidget
::OnCurrentPixelValueUpdated(const VectorImageType::PixelType & currentPixel,
                             const QStringList& bandNames)
{
  //
  // remove the previous QTreeWidgetItem  of m_PixelValueRootItem
  while( m_PixelValueRootItem->childCount()>0 )
    {
    // Remove QTreeWidgetItem
    QTreeWidgetItem* child = m_PixelValueRootItem->takeChild( 0 );

    // Delete it from memory.
    delete child;
    child = NULL;
    }

  // fill with the new values
  for (unsigned int idx = 0; idx < currentPixel.GetSize(); idx++)
    {
    QTreeWidgetItem * iBandItem = new QTreeWidgetItem( m_PixelValueRootItem );

    // figure out if a band name is available, if not use Band idx
    if( !bandNames[ idx ].isEmpty() &&
	static_cast< unsigned int >( bandNames.size() )==currentPixel.GetSize() )
      {
      iBandItem->setText(0, bandNames[ idx ] );
      }
    else
      {
      iBandItem->setText(0, QString( tr("Band") )+ QString(" %1").arg(idx) );
      }
    // set the value
    iBandItem->setText(1, QString("%1").arg(currentPixel.GetElement( idx )) );
    }
}

/*******************************************************************************/

} // end namespace 'mvd'
<commit_msg>ENH: let pixel description for radiometric value<commit_after>/*=========================================================================

  Program:   Monteverdi2
  Language:  C++

  Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
  See Copyright.txt for details.

  Monteverdi2 is distributed under the CeCILL licence version 2. See
  Licence_CeCILL_V2-en.txt or
  http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt for more 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 notices for more information.

=========================================================================*/
#include "Gui/mvdPixelDescriptionWidget.h"
#include "Gui/ui_mvdPixelDescriptionWidget.h"

/*****************************************************************************/
/* INCLUDE SECTION                                                           */

//
// Qt includes (sorted by alphabetic order)
//// Must be included before system/custom includes.

//
// System includes (sorted by alphabetic order)

//
// ITK includes (sorted by alphabetic order)

//
// OTB includes (sorted by alphabetic order)

//
// Monteverdi includes (sorted by alphabetic order)
#include "Core/mvdAlgorithm.h"

namespace mvd
{
/*
  TRANSLATOR mvd::PixelDescriptionWidget

  Necessary for lupdate to be aware of C++ namespaces.

  Context comment for translator.
*/

/*****************************************************************************/
/* CONSTANTS                                                                 */

/*****************************************************************************/
/* STATIC IMPLEMENTATION SECTION                                             */

/*****************************************************************************/
/* CLASS IMPLEMENTATION SECTION                                              */

/*******************************************************************************/
PixelDescriptionWidget
::PixelDescriptionWidget( QWidget* parent, Qt::WindowFlags flags  ):
  QWidget( parent, flags ),
  m_UI( new mvd::Ui::PixelDescriptionWidget() )
{
  m_UI->setupUi( this );

  SetupUI();
}

/*******************************************************************************/
PixelDescriptionWidget
::~PixelDescriptionWidget()
{
}

/*******************************************************************************/
void
PixelDescriptionWidget
::SetupUI()
{
  //
  // Cartographic coordiantes
  m_CartographicRootItem = new QTreeWidgetItem( GetDescriptionTree() );
  //m_CartographicRootItem->setText(0, tr("Cartographic"));
  m_CartographicRootItem->setExpanded(true);

  // m_CartographicItem = new QTreeWidgetItem( m_CartographicRootItem );
  // m_CartographicItem->setText(0, tr("Coordinates"));

  //
  // Geographic coordinates
  m_GeographicRootItem = new QTreeWidgetItem( GetDescriptionTree() );
  m_GeographicRootItem->setText(0, tr("Geographic"));
  m_GeographicRootItem->setExpanded(true);

  //m_GeographicItem = new QTreeWidgetItem( m_GeographicRootItem );
  //m_GeographicItem->setText(0, tr("Coordinates"));

  //
  // Child items will be created + updated in a dedicated slot
  m_PixelValueRootItem = new QTreeWidgetItem( GetDescriptionTree() );
  m_PixelValueRootItem->setText(0, tr("Pixel Values"));
  m_PixelValueRootItem->setExpanded(true);
}

/*******************************************************************************/
QTreeWidget *
PixelDescriptionWidget
::GetDescriptionTree()
{
  return m_UI->m_DescriptionTree;
}

/*******************************************************************************/
/* SLOTS                                                                       */
/*******************************************************************************/
void
PixelDescriptionWidget
::OnCurrentPhysicalUpdated(const QStringList & currentPhysical)
{
  //m_CartographicItem->setText(1, currentPhysical);

  if (!currentPhysical.empty())
    {
    // remove the previous QTreeWidgetItem  of m_GeographicRootItem
    while( m_CartographicRootItem->childCount()>0 )
      {
      // Remove QTreeWidgetItem
      QTreeWidgetItem* child = m_CartographicRootItem->takeChild( 0 );

      // Delete it from memory.
      delete child;
      child = NULL;
      }

    m_CartographicRootItem->setText(0, QString("%1").arg(currentPhysical[0]));

    // fill with the new values
    QTreeWidgetItem * iCartoXItem = new QTreeWidgetItem( m_CartographicRootItem );
    iCartoXItem->setText(0,QString( tr("X") ));
    iCartoXItem->setText(1, QString("%1").arg(currentPhysical[1] ) );

    QTreeWidgetItem * iCartoYItem = new QTreeWidgetItem( m_CartographicRootItem );
    iCartoYItem->setText(0,QString( tr("Y") ));
    iCartoYItem->setText(1, QString("%1").arg(currentPhysical[2] ) );
    }
}

/*******************************************************************************/
void
PixelDescriptionWidget
::OnCurrentGeographicUpdated(const QStringList&/*const QString &*/ currentGeo)
{
  if (!currentGeo.empty())
    {
    // remove the previous QTreeWidgetItem  of m_GeographicRootItem
    while( m_GeographicRootItem->childCount()>0 )
      {
      // Remove QTreeWidgetItem
      QTreeWidgetItem* child = m_GeographicRootItem->takeChild( 0 );

      // Delete it from memory.
      delete child;
      child = NULL;
      }

    m_GeographicRootItem->setText(0, QString("%1").arg(currentGeo[0]));
    // fill with the new values
    QTreeWidgetItem * iGeoLongItem = new QTreeWidgetItem( m_GeographicRootItem );
    iGeoLongItem->setText(0,QString( tr("Long") ));
    iGeoLongItem->setText(1, QString("%1").arg(currentGeo[1] ) );

    QTreeWidgetItem * iGeoLatItem = new QTreeWidgetItem( m_GeographicRootItem );
    iGeoLatItem->setText(0,QString( tr("Lat") ));
    iGeoLatItem->setText(1, QString("%1").arg(currentGeo[2] ) );

    QTreeWidgetItem * iGeoElevationItem = new QTreeWidgetItem( m_GeographicRootItem );
    iGeoElevationItem->setText(0,QString( tr("Elevation") ));
    if(currentGeo.size() > 3)
      {
      iGeoElevationItem->setText(1, QString("%1").arg(currentGeo[3] ) );
      }
    else
      {
      iGeoElevationItem->setText(1, QString(tr("Not available")));
      }
    }
}
/*******************************************************************************/
void
PixelDescriptionWidget
::OnCurrentPixelValueUpdated(const VectorImageType::PixelType & currentPixel,
                             const QStringList& bandNames)
{
  if (!bandNames.empty() || currentPixel.GetSize() != 0)
    {
    //
    // remove the previous QTreeWidgetItem  of m_PixelValueRootItem
    while( m_PixelValueRootItem->childCount()>0 )
      {
      // Remove QTreeWidgetItem
      QTreeWidgetItem* child = m_PixelValueRootItem->takeChild( 0 );

      // Delete it from memory.
      delete child;
      child = NULL;
      }

    // fill with the new values
    for (unsigned int idx = 0; idx < currentPixel.GetSize(); idx++)
      {
      QTreeWidgetItem * iBandItem = new QTreeWidgetItem( m_PixelValueRootItem );

      // figure out if a band name is available, if not use Band idx
      if( !bandNames[ idx ].isEmpty() &&
          static_cast< unsigned int >( bandNames.size() )==currentPixel.GetSize() )
        {
        iBandItem->setText(0, bandNames[ idx ] );
        }
      else
        {
        iBandItem->setText(0, QString( tr("Band") )+ QString(" %1").arg(idx) );
        }
      // set the value
      iBandItem->setText(1, QString("%1").arg(currentPixel.GetElement( idx )) );
      }
    }
}

/*******************************************************************************/

} // end namespace 'mvd'
<|endoftext|>