From dd206439d6880c065e2567393c534dc9355ca60d Mon Sep 17 00:00:00 2001
From: EndrII <EndrIIMail@gmail.com>
Date: Fri, 13 Aug 2021 22:07:19 +0300
Subject: [PATCH] added store view implementation

---
 src/Client/languages/de.ts          | 22 ++++++++++
 src/Client/languages/en.ts          | 22 ++++++++++
 src/Client/languages/es.ts          | 22 ++++++++++
 src/Client/languages/fr.ts          | 22 ++++++++++
 src/Client/languages/ja.ts          | 22 ++++++++++
 src/Client/languages/pl.ts          | 22 ++++++++++
 src/Client/languages/ru.ts          | 22 ++++++++++
 src/Client/languages/tr.ts          | 22 ++++++++++
 src/Client/languages/uk.ts          | 22 ++++++++++
 src/Client/languages/zh.ts          | 22 ++++++++++
 src/Core/Crawl.qrc                  |  1 +
 src/Core/Crawl/clientapp.cpp        | 13 +++---
 src/Core/Crawl/clientapp.h          |  7 +++-
 src/Core/CrawlModule/Crawl.qml      |  5 +++
 src/Core/CrawlModule/StoreView.qml  | 65 +++++++++++++++++++++++++++++
 src/Core/private/engine.cpp         | 10 ++---
 src/Core/private/engine.h           |  7 ----
 src/Core/private/storeviewmodel.cpp | 21 +++++++++-
 src/Core/private/storeviewmodel.h   | 36 ++++++++++++++--
 src/Core/private/user.cpp           |  2 +
 src/Core/private/user.h             |  6 +++
 21 files changed, 365 insertions(+), 28 deletions(-)
 create mode 100644 src/Core/CrawlModule/StoreView.qml

diff --git a/src/Client/languages/de.ts b/src/Client/languages/de.ts
index 12ce0f2..90f1bf4 100644
--- a/src/Client/languages/de.ts
+++ b/src/Client/languages/de.ts
@@ -37,6 +37,17 @@
         <translation type="unfinished"></translation>
     </message>
 </context>
+<context>
+    <name>JungleLvl::Snake</name>
+    <message>
+        <source>JungleSnake</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>JungleSnake Snake</source>
+        <translation type="unfinished"></translation>
+    </message>
+</context>
 <context>
     <name>JungleLvl::World</name>
     <message>
@@ -100,4 +111,15 @@
         <translation type="unfinished"></translation>
     </message>
 </context>
+<context>
+    <name>TestLvl::TestSnake</name>
+    <message>
+        <source>TestSnake</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>TestSnake Snake</source>
+        <translation type="unfinished"></translation>
+    </message>
+</context>
 </TS>
diff --git a/src/Client/languages/en.ts b/src/Client/languages/en.ts
index ff6a4b6..565092a 100644
--- a/src/Client/languages/en.ts
+++ b/src/Client/languages/en.ts
@@ -37,6 +37,17 @@
         <translation type="unfinished"></translation>
     </message>
 </context>
+<context>
+    <name>JungleLvl::Snake</name>
+    <message>
+        <source>JungleSnake</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>JungleSnake Snake</source>
+        <translation type="unfinished"></translation>
+    </message>
+</context>
 <context>
     <name>JungleLvl::World</name>
     <message>
@@ -100,4 +111,15 @@
         <translation type="unfinished"></translation>
     </message>
 </context>
+<context>
+    <name>TestLvl::TestSnake</name>
+    <message>
+        <source>TestSnake</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>TestSnake Snake</source>
+        <translation type="unfinished"></translation>
+    </message>
+</context>
 </TS>
diff --git a/src/Client/languages/es.ts b/src/Client/languages/es.ts
index 285d0f2..2a94079 100644
--- a/src/Client/languages/es.ts
+++ b/src/Client/languages/es.ts
@@ -37,6 +37,17 @@
         <translation type="unfinished"></translation>
     </message>
 </context>
+<context>
+    <name>JungleLvl::Snake</name>
+    <message>
+        <source>JungleSnake</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>JungleSnake Snake</source>
+        <translation type="unfinished"></translation>
+    </message>
+</context>
 <context>
     <name>JungleLvl::World</name>
     <message>
@@ -100,4 +111,15 @@
         <translation type="unfinished"></translation>
     </message>
 </context>
+<context>
+    <name>TestLvl::TestSnake</name>
+    <message>
+        <source>TestSnake</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>TestSnake Snake</source>
+        <translation type="unfinished"></translation>
+    </message>
+</context>
 </TS>
diff --git a/src/Client/languages/fr.ts b/src/Client/languages/fr.ts
index ff6a4b6..565092a 100644
--- a/src/Client/languages/fr.ts
+++ b/src/Client/languages/fr.ts
@@ -37,6 +37,17 @@
         <translation type="unfinished"></translation>
     </message>
 </context>
+<context>
+    <name>JungleLvl::Snake</name>
+    <message>
+        <source>JungleSnake</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>JungleSnake Snake</source>
+        <translation type="unfinished"></translation>
+    </message>
+</context>
 <context>
     <name>JungleLvl::World</name>
     <message>
@@ -100,4 +111,15 @@
         <translation type="unfinished"></translation>
     </message>
 </context>
+<context>
+    <name>TestLvl::TestSnake</name>
+    <message>
+        <source>TestSnake</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>TestSnake Snake</source>
+        <translation type="unfinished"></translation>
+    </message>
+</context>
 </TS>
diff --git a/src/Client/languages/ja.ts b/src/Client/languages/ja.ts
index ff6a4b6..565092a 100644
--- a/src/Client/languages/ja.ts
+++ b/src/Client/languages/ja.ts
@@ -37,6 +37,17 @@
         <translation type="unfinished"></translation>
     </message>
 </context>
+<context>
+    <name>JungleLvl::Snake</name>
+    <message>
+        <source>JungleSnake</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>JungleSnake Snake</source>
+        <translation type="unfinished"></translation>
+    </message>
+</context>
 <context>
     <name>JungleLvl::World</name>
     <message>
@@ -100,4 +111,15 @@
         <translation type="unfinished"></translation>
     </message>
 </context>
+<context>
+    <name>TestLvl::TestSnake</name>
+    <message>
+        <source>TestSnake</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>TestSnake Snake</source>
+        <translation type="unfinished"></translation>
+    </message>
+</context>
 </TS>
diff --git a/src/Client/languages/pl.ts b/src/Client/languages/pl.ts
index ff6a4b6..565092a 100644
--- a/src/Client/languages/pl.ts
+++ b/src/Client/languages/pl.ts
@@ -37,6 +37,17 @@
         <translation type="unfinished"></translation>
     </message>
 </context>
+<context>
+    <name>JungleLvl::Snake</name>
+    <message>
+        <source>JungleSnake</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>JungleSnake Snake</source>
+        <translation type="unfinished"></translation>
+    </message>
+</context>
 <context>
     <name>JungleLvl::World</name>
     <message>
@@ -100,4 +111,15 @@
         <translation type="unfinished"></translation>
     </message>
 </context>
+<context>
+    <name>TestLvl::TestSnake</name>
+    <message>
+        <source>TestSnake</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>TestSnake Snake</source>
+        <translation type="unfinished"></translation>
+    </message>
+</context>
 </TS>
diff --git a/src/Client/languages/ru.ts b/src/Client/languages/ru.ts
index ff6a4b6..565092a 100644
--- a/src/Client/languages/ru.ts
+++ b/src/Client/languages/ru.ts
@@ -37,6 +37,17 @@
         <translation type="unfinished"></translation>
     </message>
 </context>
+<context>
+    <name>JungleLvl::Snake</name>
+    <message>
+        <source>JungleSnake</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>JungleSnake Snake</source>
+        <translation type="unfinished"></translation>
+    </message>
+</context>
 <context>
     <name>JungleLvl::World</name>
     <message>
@@ -100,4 +111,15 @@
         <translation type="unfinished"></translation>
     </message>
 </context>
+<context>
+    <name>TestLvl::TestSnake</name>
+    <message>
+        <source>TestSnake</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>TestSnake Snake</source>
+        <translation type="unfinished"></translation>
+    </message>
+</context>
 </TS>
diff --git a/src/Client/languages/tr.ts b/src/Client/languages/tr.ts
index ff6a4b6..565092a 100644
--- a/src/Client/languages/tr.ts
+++ b/src/Client/languages/tr.ts
@@ -37,6 +37,17 @@
         <translation type="unfinished"></translation>
     </message>
 </context>
+<context>
+    <name>JungleLvl::Snake</name>
+    <message>
+        <source>JungleSnake</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>JungleSnake Snake</source>
+        <translation type="unfinished"></translation>
+    </message>
+</context>
 <context>
     <name>JungleLvl::World</name>
     <message>
@@ -100,4 +111,15 @@
         <translation type="unfinished"></translation>
     </message>
 </context>
+<context>
+    <name>TestLvl::TestSnake</name>
+    <message>
+        <source>TestSnake</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>TestSnake Snake</source>
+        <translation type="unfinished"></translation>
+    </message>
+</context>
 </TS>
diff --git a/src/Client/languages/uk.ts b/src/Client/languages/uk.ts
index ff6a4b6..565092a 100644
--- a/src/Client/languages/uk.ts
+++ b/src/Client/languages/uk.ts
@@ -37,6 +37,17 @@
         <translation type="unfinished"></translation>
     </message>
 </context>
+<context>
+    <name>JungleLvl::Snake</name>
+    <message>
+        <source>JungleSnake</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>JungleSnake Snake</source>
+        <translation type="unfinished"></translation>
+    </message>
+</context>
 <context>
     <name>JungleLvl::World</name>
     <message>
@@ -100,4 +111,15 @@
         <translation type="unfinished"></translation>
     </message>
 </context>
+<context>
+    <name>TestLvl::TestSnake</name>
+    <message>
+        <source>TestSnake</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>TestSnake Snake</source>
+        <translation type="unfinished"></translation>
+    </message>
+</context>
 </TS>
diff --git a/src/Client/languages/zh.ts b/src/Client/languages/zh.ts
index ff6a4b6..565092a 100644
--- a/src/Client/languages/zh.ts
+++ b/src/Client/languages/zh.ts
@@ -37,6 +37,17 @@
         <translation type="unfinished"></translation>
     </message>
 </context>
+<context>
+    <name>JungleLvl::Snake</name>
+    <message>
+        <source>JungleSnake</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>JungleSnake Snake</source>
+        <translation type="unfinished"></translation>
+    </message>
+</context>
 <context>
     <name>JungleLvl::World</name>
     <message>
@@ -100,4 +111,15 @@
         <translation type="unfinished"></translation>
     </message>
 </context>
+<context>
+    <name>TestLvl::TestSnake</name>
+    <message>
+        <source>TestSnake</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>TestSnake Snake</source>
+        <translation type="unfinished"></translation>
+    </message>
+</context>
 </TS>
diff --git a/src/Core/Crawl.qrc b/src/Core/Crawl.qrc
index d91496d..c596ba9 100644
--- a/src/Core/Crawl.qrc
+++ b/src/Core/Crawl.qrc
@@ -25,5 +25,6 @@
         <file>CrawlModule/particles/Fire.qml</file>
         <file>CrawlModule/particles/Wint.qml</file>
         <file>CrawlModule/PreviewControl.qml</file>
+        <file>CrawlModule/StoreView.qml</file>
     </qresource>
 </RCC>
diff --git a/src/Core/Crawl/clientapp.cpp b/src/Core/Crawl/clientapp.cpp
index 5d18c6a..5cf76f7 100644
--- a/src/Core/Crawl/clientapp.cpp
+++ b/src/Core/Crawl/clientapp.cpp
@@ -67,14 +67,11 @@ ClientApp::~ClientApp() {
     _availableLvls.clear();
 }
 
-void ClientApp::initStore(Store *store) {
-    QMultiHash<int, const IItem *> storeItems;
+void ClientApp::initStore(QMultiHash<int, const IItem *> & result) {
     for (const auto &data : qAsConst(_availableLvls)) {
         if (data.model && data.model->world())
-            storeItems.unite(data.model->world()->childItemsRecursive());
+            result.unite(data.model->world()->childItemsRecursive());
     }
-
-    store->init(storeItems);
 }
 
 void ClientApp::changeLevel(int lvl) {
@@ -133,9 +130,11 @@ bool ClientApp::init(QQmlApplicationEngine *engine) {
     if (engine->rootObjects().isEmpty())
         return false;
 
+    QMultiHash<int, const IItem *> availabelItems;
+    initStore(availabelItems);
+    _engine->initStore(availabelItems);
+
     _engine->setLevel(getLastLevel());
-    _engine->setQmlEngine(engine);
-    initStore(_engine->store());
 
     return true;
 }
diff --git a/src/Core/Crawl/clientapp.h b/src/Core/Crawl/clientapp.h
index c697900..3b55e37 100644
--- a/src/Core/Crawl/clientapp.h
+++ b/src/Core/Crawl/clientapp.h
@@ -69,7 +69,12 @@ private:
     QByteArray initTheme();
     ILevel *getLastLevel();
 
-    void initStore(Store* store);
+    /**
+     * @brief initStore This method push to @a result map all available store items.
+     * @param result This is result value. Hash map of the available items.
+     */
+    void initStore(QMultiHash<int, const IItem *> &result);
+
     /**
      * @brief addLvl This method should be add level to game.
      * @param levelWordl This is world instance
diff --git a/src/Core/CrawlModule/Crawl.qml b/src/Core/CrawlModule/Crawl.qml
index c2e1d58..8d8351b 100644
--- a/src/Core/CrawlModule/Crawl.qml
+++ b/src/Core/CrawlModule/Crawl.qml
@@ -34,6 +34,11 @@ ApplicationWindow {
         anchors.fill: parent;
     }
 
+    StoreView {
+        model: (mainWindow.model)? mainWindow.model.storeView: null
+        anchors.fill: parent;
+    }
+
     MainMenu {
 
         model: (mainmenu)? mainmenu: null;
diff --git a/src/Core/CrawlModule/StoreView.qml b/src/Core/CrawlModule/StoreView.qml
new file mode 100644
index 0000000..fee908e
--- /dev/null
+++ b/src/Core/CrawlModule/StoreView.qml
@@ -0,0 +1,65 @@
+import QtQuick
+import ViewSolutionsModule
+import QtQuick.Controls
+import QtQuick.Controls.Material
+import QtQuick.Layouts
+
+Page {
+    id: store
+    property var model: null;
+    visible: model && model.visible
+    ColumnLayout {
+        anchors.fill: parent
+        ListView {
+            id: listView
+            Layout.fillHeight: true
+            Layout.fillWidth: true
+            model: store.model
+            delegate: delegateRow
+
+            Component {
+                id: delegateRow
+
+                RowLayout {
+                    width: listView.width
+                    height: 100
+                    Image {
+                        id: img
+                        fillMode: Image.PreserveAspectCrop
+                        source: itemImage
+                        Layout.fillHeight: true
+                        Layout.preferredWidth: height * 2
+                    }
+
+                    Label {
+                        text: itemName
+                        Layout.fillHeight: true
+                    }
+
+                    Label {
+                        text: itemDescription
+                        Layout.fillWidth: true
+                        Layout.fillHeight: true
+                    }
+
+                    CheckBox {
+                        id: buyStatus
+                        tristate: false
+                        checkState: (itemWasBuy)? Qt.Checked: Qt.Unchecked
+                        enabled: false
+                    }
+
+                    Button {
+                        text: qsTr("Buy");
+                        visible: !itemWasBuy
+
+                        onClicked: () => {
+                                        if (store.model)
+                                            store.model.buy(itemId);
+                                   }
+                    }
+                }
+            }
+        }
+    }
+}
diff --git a/src/Core/private/engine.cpp b/src/Core/private/engine.cpp
index 4a5a8ef..e0c421a 100644
--- a/src/Core/private/engine.cpp
+++ b/src/Core/private/engine.cpp
@@ -24,6 +24,7 @@ namespace CRAWL {
 Engine::Engine(QObject *parent): QObject(parent) {
     _store = new Store();
     _storeView = new StoreViewModel;
+    _currentUser = new User();
 
 }
 
@@ -36,14 +37,9 @@ QObject *Engine::scane() {
     return _scane;
 }
 
-void Engine::setQmlEngine(QQmlEngine *newEngine) {
-    if (_engine == newEngine)
-        return;
-
-    _engine = newEngine;
-}
-
 void Engine::setLevel(ILevel *world) {
+    _storeView->setVisible(!world);
+
     if (_currentLevel == world)
         return ;
 
diff --git a/src/Core/private/engine.h b/src/Core/private/engine.h
index 1b80c12..01e4f0f 100644
--- a/src/Core/private/engine.h
+++ b/src/Core/private/engine.h
@@ -45,12 +45,6 @@ public:
      */
     Q_INVOKABLE QObject* scane();
 
-    /**
-     * @brief setQmlEngine This method sets qml engine
-     * @param newEngine This is pointer to the qml engine.
-     */
-    void setQmlEngine(QQmlEngine *newEngine);
-
     /**
      * @brief setLevel This method set new world level for game.
      * @param world This is pointer to new world level.
@@ -157,7 +151,6 @@ private:
     void renderLoop();
 
     QObject *_scane = nullptr;
-    QQmlEngine *_engine = nullptr;
     ILevel* _currentLevel = nullptr;
 
     quint64 _oldTimeRender = 0;
diff --git a/src/Core/private/storeviewmodel.cpp b/src/Core/private/storeviewmodel.cpp
index e0a5429..c19395b 100644
--- a/src/Core/private/storeviewmodel.cpp
+++ b/src/Core/private/storeviewmodel.cpp
@@ -60,7 +60,7 @@ QHash<int, QByteArray> StoreViewModel::roleNames() const {
     return roles;
 }
 
-void StoreViewModel::init(const Store * store, const User* user) {
+void StoreViewModel::init(Store *store, User *user) {
     setUser(user);
 
     int diff = store->size() - _keys.size();
@@ -86,8 +86,25 @@ void StoreViewModel::init(const Store * store, const User* user) {
     }
 }
 
-void StoreViewModel::setUser(const User *user) {
+void StoreViewModel::setUser(User *user) {
     _currentUser = user;
     emit dataChanged(index(0,0), index(rowCount() - 1, columnCount() - 1), {ItemWasBuy});
 }
+
+bool StoreViewModel::visible() const {
+    return _visible;
+}
+
+void StoreViewModel::setVisible(bool newVisible) {
+    if (_visible == newVisible)
+        return;
+    _visible = newVisible;
+    emit visibleChanged();
+}
+
+void StoreViewModel::buy(int item) {
+    if (_store && _currentUser) {
+        _store->buy(*_currentUser, item);
+    }
+}
 }
diff --git a/src/Core/private/storeviewmodel.h b/src/Core/private/storeviewmodel.h
index ffd2b5d..7bd6d6b 100644
--- a/src/Core/private/storeviewmodel.h
+++ b/src/Core/private/storeviewmodel.h
@@ -21,6 +21,11 @@ class User;
 class StoreViewModel: public QAbstractListModel
 {
     Q_OBJECT
+    /**
+     * @brief visible If you sets thsis proprtye to false then store view qml view will be hide.
+    */
+    Q_PROPERTY(bool visible READ visible  NOTIFY visibleChanged)
+
 public:
     StoreViewModel();
 
@@ -36,13 +41,35 @@ public:
      * @param user This is new pointer to current user.
      * @see StoreViewModel::setUser
      */
-    void init(const Store * store, const User* user);
+    void init(Store * store, User* user);
 
     /**
      * @brief setUser This method update user pointer
      * @param user This is new pointer to current user.
      */
-    void setUser(const User* user);
+    void setUser(User* user);
+
+    /**
+     * @brief visible This method return true if the store view is visible.
+     * @return true if the store view is visible.
+     */
+    bool visible() const;
+
+    /**
+     * @brief setVisible This method chnge the visible state of the qml view of store.
+     * @param newVisible This is new value of the qml-store visible
+     */
+    void setVisible(bool newVisible);
+
+    /**
+     * @brief buy This is qml method for receive signal from view about buying item.
+     * @param item This is item id that user want to buy.
+     */
+    Q_INVOKABLE void buy(int item);
+
+signals:
+    void visibleChanged();
+
 private:
 
     enum StoreRoles {
@@ -53,9 +80,10 @@ private:
         ItemWasBuy
     };
 
-    const Store *_store = nullptr;
+    Store *_store = nullptr;
     QList<int> _keys;
-    const User* _currentUser = nullptr;
+    User* _currentUser = nullptr;
+    bool _visible = false;
 };
 
 }
diff --git a/src/Core/private/user.cpp b/src/Core/private/user.cpp
index 2c939ed..1cd95c8 100644
--- a/src/Core/private/user.cpp
+++ b/src/Core/private/user.cpp
@@ -60,6 +60,7 @@ bool User::isUnlocked(int item) const {
 
 void User::unclokItem(int item) {
     _unlockedItems.insert(item);
+    emit itemUlocked({item});
 }
 
 void User::droppItem(int item) {
@@ -68,6 +69,7 @@ void User::droppItem(int item) {
 
 void User::setUnlockedItems(const QSet<int> &newUnlockedItems) {
     _unlockedItems = newUnlockedItems;
+    emit itemUlocked(newUnlockedItems);
 }
 
 int User::recalcTier() {
diff --git a/src/Core/private/user.h b/src/Core/private/user.h
index ec0da42..990ffb0 100644
--- a/src/Core/private/user.h
+++ b/src/Core/private/user.h
@@ -144,6 +144,12 @@ signals:
     void tierChanged();
     void xpChanged();
 
+    /**
+     * @brief itemUlocked This signal emited when user unlocked item.
+     * @param unclokedItems This is unlocked items set. Each items in the set is id of the unclocked item.
+     */
+    void itemUlocked(const QSet<int> & unclokedItems);
+
 protected:
     /**
      * @brief setUnlockedItems This method sets new set of uncloked items