diff --git a/controller.h b/controller.h new file mode 100644 index 0000000..6e4e350 --- /dev/null +++ b/controller.h @@ -0,0 +1,30 @@ +#pragma once +#include "model.h" +#include "gliph.h" + +class MenuController { +public: + MenuController(MenuModel& model): + m_model(model) + {} + + void createNewDocument(std::string docName) { m_model.createDocument(docName); } + void importDocument(std::string docName) {m_model.importDocument(docName); } + void exportDocument(std::string asFile) { m_model.exportDocument(asFile); } + + Glyph* createGlyph(GlyphType glyph, std::string description) { return m_model.createGlyph(glyph, description); } +private: + MenuModel& m_model; +}; + +class DrawController { +public: + DrawController(DrawModel& model): + m_model(model) + {} + + void drawGlyph(Glyph* gliph, int x, int y) {m_model.drawGliph(gliph, x, y);} + void deleteGlyph(Glyph* gliph) {m_model.deleteGliph(gliph);} +private: + DrawModel& m_model; +}; diff --git a/gliph.h b/gliph.h new file mode 100644 index 0000000..43ddfcf --- /dev/null +++ b/gliph.h @@ -0,0 +1,24 @@ +#pragma once +#include + +enum class GlyphType { + SIMPLE_GLYPH, + OTHER_GLYPH +}; + +class Glyph { +public: + Glyph(std::string description): + m_description(description) + {} + std::string getDescription() { return m_description;} +private: + std::string m_description; +}; + +class SimpleGlyph: public Glyph { +public: + SimpleGlyph(std::string description): + Glyph(description) + {} +}; diff --git a/main.cpp b/main.cpp new file mode 100644 index 0000000..7de0cf1 --- /dev/null +++ b/main.cpp @@ -0,0 +1,40 @@ +#include +#include "controller.h" +#include "model.h" +#include "view.h" +#include "gliph.h" + +//1. Adding new gliphs is just creating new classes inheritable from Gliph +//2. Database interconnection is a new functions in MenuModel +//3. Modification of gliphs needs adding an access to their properties. Gliphstore in DrawModel allows to find elements and call appropriates methods for changing their properties +//4. Gliphstore in DrawModel allows to iterate through gliphs and work with them (replace, modification, etc) + +int main() +{ + MenuModel menuModel{}; + DrawModel drawModel{}; + MenuController menuController(menuModel); + DrawController drawController(drawModel); + + View menuView {}; + View drawView {}; + + menuModel.connect([&](Model* m) { + menuView.printStateOfDocument(m); + }); + + drawModel.connect([&](Model* m) { + drawView.printStateOfDocument(m); + }); + + menuController.createNewDocument("picture.jpg"); + menuController.exportDocument("awesome_drawing.pdf"); + menuController.importDocument("other_picture.jpg"); + + auto glyph = menuController.createGlyph(GlyphType::SIMPLE_GLYPH, "simple glyph"); + + drawController.drawGlyph(glyph, 0, 0); + drawController.deleteGlyph(glyph); + + return 0; +} diff --git a/model.cpp b/model.cpp new file mode 100644 index 0000000..423f2b0 --- /dev/null +++ b/model.cpp @@ -0,0 +1,112 @@ +#include "model.h" + +int DrawModel::m_counter = 0; + +Model::~Model() +{} + +void Model::notify() +{ + for(const auto& view: m_listeners) + view(this); +} + +void DrawModel::drawGliph(Glyph* gliph, int x, int y) +{ + m_counter++; + std::cout << "New glyph " << gliph->getDescription() << " with number " << m_counter + << " and coordinates: " << x << ", " << y << " created" << std::endl; + + InternalData data = { data.x = x, data.y = y, data.number = m_counter }; + m_gliphStore.emplace(gliph, data); + notify(); +} + +void DrawModel::deleteGliph(Glyph* gliph) +{ + m_counter--; + auto result = m_gliphStore.find(gliph); + if(result == m_gliphStore.end()) + return; + std::cout << "Glyph " << gliph->getDescription() << " with number " << result->second.number + << " and coordinates: " << result->second.x << ", " << result->second.y << " deleted" << std::endl; + m_gliphStore.erase(result); + notify(); +} + +std::string DrawModel::printState() +{ + std::string strRepresentation; + strRepresentation.append("Drawing current document: "); + strRepresentation.append(m_docName); + strRepresentation.append("\n"); + for(const auto& pair: m_gliphStore) + { + strRepresentation.append("glyph name: "); + strRepresentation.append(pair.first->getDescription()); + strRepresentation.append(", number: "); + strRepresentation.append(std::to_string(pair.second.number)); + strRepresentation.append(" and coordinates: "); + strRepresentation.append(std::to_string(pair.second.x)); + strRepresentation.append(", "); + strRepresentation.append(std::to_string(pair.second.y)); + strRepresentation.append("\n"); + } + + return strRepresentation; +} + +void MenuModel::createDocument(std::string &docName) +{ + std::cout << "Manipulation for creating new document with name " << docName << std::endl; + m_docName = docName; + m_state = MenuModelState::DOC_CREATED; + notify(); +} + +void MenuModel::importDocument(std::string &docName) +{ + std::cout << "Manipulation for importing document " << docName << std::endl; + m_docName = docName; + m_state = MenuModelState::DOC_IMPORTED; + notify(); +} + +void MenuModel::exportDocument(std::string& asFile) +{ + std::cout << "Manipulation for exporting project as document " << asFile << std::endl; + m_state = MenuModelState::DOC_EXPORTED; + notify(); +} + +Glyph *MenuModel::createGlyph(GlyphType glyph, std::string description) +{ + std::cout << "Choosing glyph type from menu collection" << std::endl; + switch(static_cast(glyph)){ + case static_cast(GlyphType::SIMPLE_GLYPH): + return new SimpleGlyph(description); + default: + return nullptr; + } +} + +std::string MenuModel::printState() +{ + std::string strRepresentation; + strRepresentation.append("Current document: "); + strRepresentation.append(m_docName); + strRepresentation.append("\n"); + switch(static_cast(m_state)){ + case static_cast(MenuModelState::DOC_CREATED): + strRepresentation.append("It was created here"); + break; + case static_cast(MenuModelState::DOC_IMPORTED): + strRepresentation.append("It was imported"); + break; + case static_cast(MenuModelState::DOC_EXPORTED): + strRepresentation.append("It was succesfully exported"); + break; + } + strRepresentation.append("\n"); + return strRepresentation; +} diff --git a/model.h b/model.h new file mode 100644 index 0000000..6f24398 --- /dev/null +++ b/model.h @@ -0,0 +1,62 @@ +#pragma once +#include +#include +#include +#include +#include "gliph.h" + +enum class MenuModelState { + DOC_CREATED, + DOC_IMPORTED, + DOC_EXPORTED +}; + +class Model; +using Listener = std::function; + +class Model { +public: + virtual ~Model(); + + void connect(Listener view) { m_listeners.emplace_back(view); } + virtual std::string printState() = 0; +protected: + void notify(); +private: + std::list m_listeners; +protected: + std::string m_docName; +}; + +class MenuModel: public Model { +public: + MenuModel() = default; + ~MenuModel() {} + void createDocument(std::string& docName); + void importDocument(std::string& docName); + void exportDocument(std::string& docName); + + Glyph* createGlyph(GlyphType glyph, std::string description); + virtual std::string printState(); +private: + MenuModelState m_state; +}; + +class DrawModel: public Model { +public: + DrawModel() = default; + ~DrawModel() {} + void drawGliph(Glyph* gliphName, int x, int y); + void deleteGliph(Glyph* gliphName); + + virtual std::string printState(); + +private: + struct InternalData { + int x, y, number; + }; + +private: + std::map m_gliphStore; + static int m_counter; +}; diff --git a/view.h b/view.h new file mode 100644 index 0000000..5ba9581 --- /dev/null +++ b/view.h @@ -0,0 +1,11 @@ +#pragma once +#include +#include "model.h" + + +class View { +public: + View() = default; + void printStateOfDocument(Model* model) { std::cout << model->printState() << std::endl; } +}; +