Continuing vector graphics exercise

New classes :
 - DrawingElement (Base class for every other element)
 - Group : Groups DrawingElements together

Modified Circle to work with DrawingElement
Corrected a *maybe* failed vector copy in Polynomial.tpp
This commit is contained in:
trotFunky 2019-05-16 01:16:19 +02:00
parent 5567a9910b
commit 71ce85cec4
9 changed files with 405 additions and 29 deletions

View file

@ -39,7 +39,8 @@ endif()
add_executable(compte_mots compte_mots.cpp) add_executable(compte_mots compte_mots.cpp)
add_executable(parseXML xmlParser.cpp xmlParser.h Circle.h Circle.cpp) add_executable(parseXML xmlParser.cpp xmlParser.h Circle.h Circle.cpp Group.cpp Group.h DrawingElement.cpp DrawingElement.h DrawingElement.cpp)
target_link_libraries(parseXML sfml-window sfml-graphics)
find_path(PugiXML_INCLUDE_DIR pugixml.hpp) find_path(PugiXML_INCLUDE_DIR pugixml.hpp)
target_link_libraries(parseXML pugixml) target_link_libraries(parseXML pugixml)
@ -48,7 +49,9 @@ target_link_directories(parseXML PRIVATE ${PugiXML_INCLUDE_DIR})
if(GTest_FOUND) if(GTest_FOUND)
add_executable(xmlTest gTestXMLParser.cpp Circle.h xmlParser.h xmlParser.cpp Circle.cpp) add_executable(xmlTest gTestXMLParser.cpp Circle.h xmlParser.h xmlParser.cpp Circle.cpp Group.cpp Group.h DrawingElement.cpp DrawingElement.h DrawingElement.cpp)
target_link_libraries(xmlTest sfml-window sfml-graphics)
target_include_directories(xmlTest PRIVATE ${PugiXML_INCLUDE_DIR}) target_include_directories(xmlTest PRIVATE ${PugiXML_INCLUDE_DIR})
target_link_directories(xmlTest PRIVATE ${PugiXML_INCLUDE_DIR}) target_link_directories(xmlTest PRIVATE ${PugiXML_INCLUDE_DIR})

View file

@ -6,10 +6,39 @@
namespace xmlParser namespace xmlParser
{ {
Circle::Circle() : x(0), y(1), r(2), label("Test circle")
{}
Circle::Circle(pugi::xml_node& node) : x(node.attribute("x").as_int(0)), y(node.attribute("y").as_int(1)), Circle::Circle() : DrawingElement(), r(2)
r(node.attribute("r").as_int(2)), label(node.attribute("label").as_string("Test circle")) {
{} label = "Test Circle";
shape = new sf::CircleShape(r);
shape->setPosition(x,y);
shape->setFillColor(color);
}
Circle::Circle(const pugi::xml_node& node) : DrawingElement(node), r(node.attribute("r").as_int(2))
{
if(label == "Test DrawingElement")
{
label = "Test Circle";
}
shape = new sf::CircleShape(r);
shape->setPosition(x,y);
shape->setFillColor(color);
}
void Circle::draw(sf::RenderWindow& window)
{
window.draw(*(dynamic_cast<sf::CircleShape*>(shape)));
}
int Circle::getR() const
{
return r;
}
void Circle::setR(int newR)
{
r = newR;
dynamic_cast<sf::CircleShape*>(shape)->setRadius(r);
}
} }

View file

@ -7,20 +7,25 @@
#include <string> #include <string>
#include <pugixml.hpp> #include <pugixml.hpp>
#include <SFML/Graphics.hpp>
#include "DrawingElement.h"
namespace xmlParser namespace xmlParser
{ {
class Circle class Circle : public DrawingElement
{ {
public: public:
Circle(); Circle();
explicit Circle(pugi::xml_node&); explicit Circle(const pugi::xml_node&);
int x; void draw(sf::RenderWindow&) override;
int y;
int getR() const;
void setR(int newR);
private:
int r; int r;
std::string label;
}; };
} }
#endif //SNIPPETS_CIRCLE_H #endif //SNIPPETS_CIRCLE_H

103
snippets/DrawingElement.cpp Normal file
View file

@ -0,0 +1,103 @@
//
// Created by trotfunky on 15/05/19.
//
#include "DrawingElement.h"
namespace xmlParser
{
DrawingElement::DrawingElement() : x(0), y(1), label("Test DrawingElement"), color(sf::Color::Yellow), shape(nullptr)
{}
DrawingElement::DrawingElement(const pugi::xml_node& node) : x(node.attribute("x").as_int(0)),
y(node.attribute("y").as_int(1)), label(node.attribute("label").as_string("Test DrawingElement")), shape(nullptr)
{
setColor(node.attribute("color").as_string("Yellow"));
}
int xmlParser::DrawingElement::getX() const
{
return x;
}
void xmlParser::DrawingElement::setX(int newX)
{
x = newX;
if(shape)
{
shape->setPosition(x,y);
}
}
int xmlParser::DrawingElement::getY() const
{
return y;
}
void xmlParser::DrawingElement::setY(int newY)
{
y = newY;
if(shape)
{
shape->setPosition(x,y);
}
}
const sf::Color& xmlParser::DrawingElement::getColor() const
{
return color;
}
void xmlParser::DrawingElement::setColor(const sf::Color& newColor)
{
color = newColor;
if(shape)
{
shape->setFillColor(color);
}
}
void DrawingElement::setColor(const std::string& stringColor)
{
if(stringColor == "Black")
{
color = sf::Color::Black;
}
else if(stringColor == "White")
{
color = sf::Color::White;
}
else if(stringColor == "Red")
{
color = sf::Color::Red;
}
else if(stringColor == "Green")
{
color = sf::Color::Green;
}
else if(stringColor == "Blue")
{
color = sf::Color::Blue;
}
else if(stringColor == "Yellow")
{
color = sf::Color::Yellow;
}
else if(stringColor == "Magenta")
{
color = sf::Color::Magenta;
}
else if(stringColor == "Cyan")
{
color = sf::Color::Cyan;
}
else
{
color = sf::Color::Green;
}
}
}

45
snippets/DrawingElement.h Normal file
View file

@ -0,0 +1,45 @@
//
// Created by trotfunky on 15/05/19.
//
#ifndef SNIPPETS_DRAWINGELEMENT_H
#define SNIPPETS_DRAWINGELEMENT_H
#include <SFML/Graphics.hpp>
#include <pugixml.hpp>
#include <string>
namespace xmlParser
{
class DrawingElement
{
public:
DrawingElement();
explicit DrawingElement(const pugi::xml_node&);
virtual void draw(sf::RenderWindow&) = 0;
std::string label;
int getX() const;
void setX(int newX);
int getY() const;
void setY(int newY);
const sf::Color& getColor() const;
void setColor(const sf::Color& newColor);
void setColor(const std::string& stringColor);
protected:
int x;
int y;
sf::Color color;
sf::Shape* shape;
};
}
#endif //SNIPPETS_DRAWINGELEMENT_H

65
snippets/Group.cpp Normal file
View file

@ -0,0 +1,65 @@
//
// Created by trotfunky on 15/05/19.
//
#include "Group.h"
namespace xmlParser
{
Group::Group() : DrawingElement(), drawingElements({})
{
label = "Test Group";
}
Group::Group(const pugi::xml_node& node) : DrawingElement(node)
{
if(label == "Test DrawingElement")
{
label = "Test Group";
}
pugi::xml_object_range circleChildren = node.children();
for(pugi::xml_node_iterator child : circleChildren)
{
pugi::xml_node& childNode = (*child);
DrawingElement* newElement = !strncmp(childNode.name(),"Circle",6) ? dynamic_cast<DrawingElement*>(new Circle(childNode)) :
!strncmp(childNode.name(),"Group",5) ? dynamic_cast<DrawingElement*>(new Group(childNode)) : nullptr;
if(newElement)
{
drawingElements.insert(std::make_pair(newElement->label,newElement));
}
}
}
Group::Group(const std::map<std::string, DrawingElement*>& elements) : Group()
{
std::transform(elements.begin(),elements.end(),std::inserter(drawingElements,drawingElements.begin()),
[](std::pair<std::string,DrawingElement*> pair)
{
return(pair);
});
}
bool Group::addDrawingElement(DrawingElement* drawingElement)
{
return(drawingElements.insert(std::make_pair(drawingElement->label,drawingElement)).second);
}
bool Group::removeDrawingElement(const std::string& label)
{
return(drawingElements.erase(label));
}
DrawingElement* Group::getDrawingElement(const std::string& label)
{
return(drawingElements.at(label));
}
void Group::draw(sf::RenderWindow& window)
{
for(auto element : drawingElements)
{
element.second->draw(window);
}
}
}

38
snippets/Group.h Normal file
View file

@ -0,0 +1,38 @@
//
// Created by trotfunky on 15/05/19.
//
#ifndef SNIPPETS_GROUP_H
#define SNIPPETS_GROUP_H
#include <pugixml.hpp>
#include <map>
#include <cstring>
#include <algorithm>
#include "Circle.h"
#include "DrawingElement.h"
namespace xmlParser
{
class Group : public DrawingElement
{
public:
Group();
explicit Group(const pugi::xml_node&);
explicit Group(const std::map<std::string, DrawingElement*>&);
bool addDrawingElement(DrawingElement* drawingElement);
bool removeDrawingElement(const std::string& label);
DrawingElement* getDrawingElement(const std::string&);
void draw(sf::RenderWindow&) override;
private:
std::map<std::string,DrawingElement*> drawingElements;
};
}
#endif //SNIPPETS_GROUP_H

View file

@ -9,6 +9,7 @@
#include <map> #include <map>
#include <iostream> #include <iostream>
#include <math.h> #include <math.h>
#include <algorithm>
template <typename T> class Polynomial; template <typename T> class Polynomial;
@ -72,6 +73,11 @@ Polynomial<T>::Polynomial(const std::vector<T>& polynomialFactors) : Polynomial<
{ {
if(polynomialFactors.size()>0) if(polynomialFactors.size()>0)
{ {
std::transform(polynomialFactors.begin(),polynomialFactors.end(),std::back_inserter(factors),
[](T factor)
{
return(factor);
});
factors = polynomialFactors; factors = polynomialFactors;
} }
} }

View file

@ -6,44 +6,126 @@
#include "Circle.h" #include "Circle.h"
#include "xmlParser.h" #include "xmlParser.h"
#include "SFML/Graphics.hpp"
#include "Group.h"
TEST(readXML,initEmptyCircle)
TEST(xmlParserInits,initEmptyCircle)
{ {
xmlParser::Circle cercle = xmlParser::Circle(); xmlParser::Circle cercle = xmlParser::Circle();
ASSERT_EQ(cercle.x,0); EXPECT_EQ(cercle.getX(),0);
ASSERT_EQ(cercle.y,1); EXPECT_EQ(cercle.getY(),1);
ASSERT_EQ(cercle.r,2); EXPECT_EQ(cercle.getR(),2);
ASSERT_EQ(cercle.label,"Test circle"); EXPECT_EQ(cercle.label,"Test Circle");
EXPECT_EQ(cercle.getColor(),sf::Color::Yellow);
} }
TEST(readXML,initEmptyCirclePugiXML) TEST(xmlParserInits,initEmptyCirclePugiXML)
{ {
xmlParser::Circle cercle = xmlParser::Circle(); xmlParser::Circle cercle = xmlParser::Circle();
pugi::xml_node node; pugi::xml_node node;
ASSERT_EQ(cercle.x,0); EXPECT_EQ(cercle.getX(),0);
ASSERT_EQ(cercle.y,1); EXPECT_EQ(cercle.getY(),1);
ASSERT_EQ(cercle.r,2); EXPECT_EQ(cercle.getR(),2);
ASSERT_EQ(cercle.label,"Test circle"); EXPECT_EQ(cercle.label,"Test Circle");
EXPECT_EQ(cercle.getColor(),sf::Color::Yellow);
} }
TEST(readXML,parseXMLCircle) TEST(xmlParserInits,initEmptyGroup)
{
xmlParser::Group group = xmlParser::Group();
EXPECT_EQ(group.getX(),0);
EXPECT_EQ(group.getY(),1);
EXPECT_EQ(group.label,"Test Group");
}
TEST(xmlParserInits,initEmptyGroupPugiXML)
{
pugi::xml_node node;
xmlParser::Group group = xmlParser::Group(node);
EXPECT_EQ(group.getX(),0);
EXPECT_EQ(group.getY(),1);
EXPECT_EQ(group.label,"Test Group");
}
TEST(parseXML,parseXMLCircle)
{ {
std::string xml = "<?xml version = \"1.0\"?>\n" std::string xml = "<?xml version = \"1.0\"?>\n"
"<Circle label=\"testCircle\" x=\"0\" y=\"1\" r=\"2\" color=\"Black\"/>"; "<Circle label=\"testCircle\" x=\"0\" y=\"1\" r=\"2\" color=\"Black\"/>";
pugi::xml_document doc; pugi::xml_document doc;
pugi::xml_parse_result result = doc.load_string(xml.c_str()); pugi::xml_parse_result result = doc.load_string(xml.c_str());
EXPECT_NE(0,result); ASSERT_NE(0,result);
pugi::xml_node node = doc.child("Circle"); pugi::xml_node node = doc.child("Circle");
xmlParser::Circle cercle = xmlParser::Circle(node); xmlParser::Circle cercle = xmlParser::Circle(node);
ASSERT_EQ(cercle.x,0); EXPECT_EQ(cercle.getX(),0);
ASSERT_EQ(cercle.y,1); EXPECT_EQ(cercle.getY(),1);
ASSERT_EQ(cercle.r,2); EXPECT_EQ(cercle.getR(),2);
ASSERT_EQ(cercle.label,"testCircle"); EXPECT_EQ(cercle.label,"testCircle");
EXPECT_EQ(cercle.getColor(),sf::Color::Black);
}
TEST(parseXML,parseXMLGroup)
{
std::string xml = "<?xml version = \"1.0\"?>\n"
"<Group label=\"testGroup\" x=\"0\" y=\"1\">\n"
" <Circle label=\"testCircle1\" x=\"2\" y=\"3\" r=\"4\" color=\"Black\"/>\n"
" <Circle label=\"testCircle2\" x=\"5\" y=\"6\" r=\"7\" color=\"Black\"/>\n"
"</Group>";
pugi::xml_document doc;
pugi::xml_parse_result result = doc.load_string(xml.c_str());
ASSERT_NE(0,result);
pugi::xml_node node = doc.child("Group");
xmlParser::Group group = xmlParser::Group(node);
EXPECT_EQ(group.getX(),0);
EXPECT_EQ(group.getY(),1);
EXPECT_EQ(group.label,"testGroup");
ASSERT_TRUE(group.getDrawingElement("testCircle1"));
xmlParser::Circle* testCircle1 = dynamic_cast<xmlParser::Circle*>(group.getDrawingElement("testCircle1"));
EXPECT_EQ(testCircle1->getX(),2);
EXPECT_EQ(testCircle1->getY(),3);
EXPECT_EQ(testCircle1->getR(),4);
EXPECT_EQ(testCircle1->getColor(),sf::Color::Black);
ASSERT_TRUE(group.getDrawingElement("testCircle2"));
xmlParser::Circle* testCircle2 = dynamic_cast<xmlParser::Circle*>(group.getDrawingElement("testCircle2"));
EXPECT_EQ(testCircle2->getX(),5);
EXPECT_EQ(testCircle2->getY(),6);
EXPECT_EQ(testCircle2->getR(),7);
EXPECT_EQ(testCircle2->getColor(),sf::Color::Black);
}
TEST(parseXML,parseXMLNestGroup)
{
std::string xml = "<?xml version = \"1.0\"?>\n"
"<Group label=\"testGroup1\" x=\"0\" y=\"1\">\n"
" <Circle label=\"testCircle\" x=\"2\" y=\"3\" r=\"4\" color=\"Black\"/>\n"
" <Group label=\"testGroup2\" x=\"5\" y=\"6\"/>\n"
"</Group>";
pugi::xml_document doc;
pugi::xml_parse_result result = doc.load_string(xml.c_str());
ASSERT_NE(0,result);
pugi::xml_node node = doc.child("Group");
xmlParser::Group group = xmlParser::Group(node);
ASSERT_TRUE(group.getDrawingElement("testGroup2"));
xmlParser::Group* testGroup2 = dynamic_cast<xmlParser::Group*>(group.getDrawingElement("testGroup2"));
EXPECT_EQ(testGroup2->getX(),5);
EXPECT_EQ(testGroup2->getY(),6);
EXPECT_EQ(testGroup2->label,"testGroup2");
} }
int main(int argc, char** argv) int main(int argc, char** argv)