diff --git a/src/Core/Crawl.qrc b/src/Core/Crawl.qrc
index c596ba9..0d84981 100644
--- a/src/Core/Crawl.qrc
+++ b/src/Core/Crawl.qrc
@@ -26,5 +26,6 @@
CrawlModule/particles/Wint.qml
CrawlModule/PreviewControl.qml
CrawlModule/StoreView.qml
+ CrawlModule/SelectLevelView.qml
diff --git a/src/Core/CrawlModule/SelectLevelView.qml b/src/Core/CrawlModule/SelectLevelView.qml
new file mode 100644
index 0000000..75c80cf
--- /dev/null
+++ b/src/Core/CrawlModule/SelectLevelView.qml
@@ -0,0 +1,64 @@
+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
+
+ Rectangle {
+ anchors.fill: parent
+
+ color: (itemId == currentLevel) ? "#ffaf2c": "#00000000"
+ 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
+ }
+
+ Button {
+ text: qsTr("Select");
+ visible: !itemWasBuy
+
+ onClicked: () => {
+ if (store.model)
+ store.model.select(itemId);
+ }
+ }
+ }
+ }
+
+ }
+ }
+ }
+}
diff --git a/src/Core/private/availablelevelsmodel.cpp b/src/Core/private/availablelevelsmodel.cpp
new file mode 100644
index 0000000..5224b2e
--- /dev/null
+++ b/src/Core/private/availablelevelsmodel.cpp
@@ -0,0 +1,45 @@
+//#
+//# Copyright (C) 2021-2021 QuasarApp.
+//# Distributed under the GPLv3 software license, see the accompanying
+//# Everyone is permitted to copy and distribute verbatim copies
+//# of this license document, but changing it is not allowed.
+//#
+
+#include "availablelevelsmodel.h"
+#include "user.h"
+#include
+
+namespace CRAWL {
+
+AvailableLevelsModel::AvailableLevelsModel() {
+
+}
+
+void AvailableLevelsModel::setAllLevels(const QList &newAllLevels) {
+ _allLevels = newAllLevels;
+ QList keys;
+ for (auto level: qAsConst(_allLevels)) {
+ keys += level->itemId();
+ }
+
+ setKeys(keys);
+}
+
+int AvailableLevelsModel::getCurrentLevel() const {
+ return currentLevel;
+}
+
+void AvailableLevelsModel::setCurrentLevel(int newCurrentLevel) {
+ if (currentLevel == newCurrentLevel)
+ return;
+ currentLevel = newCurrentLevel;
+ emit currentLevelChanged();
+}
+
+void AvailableLevelsModel::select(int levelId) {
+ if (getUser()->isUnlocked(levelId)) {
+ emit sigUserSelectLevel(levelId);
+ }
+}
+
+}
diff --git a/src/Core/private/availablelevelsmodel.h b/src/Core/private/availablelevelsmodel.h
new file mode 100644
index 0000000..9d31813
--- /dev/null
+++ b/src/Core/private/availablelevelsmodel.h
@@ -0,0 +1,88 @@
+//#
+//# Copyright (C) 2021-2021 QuasarApp.
+//# Distributed under the GPLv3 software license, see the accompanying
+//# Everyone is permitted to copy and distribute verbatim copies
+//# of this license document, but changing it is not allowed.
+//#
+
+#ifndef AVAILABLELEVELSMODEL_H
+#define AVAILABLELEVELSMODEL_H
+
+#include "baseuserlistmodel.h"
+
+namespace CRAWL {
+
+class User;
+class IItem;
+
+/**
+ * @brief The AvailableLevelsModel class is model of the available levels qml view.
+ * This model just show available levels of the current user.
+ */
+class AvailableLevelsModel: public BaseUserListModel
+{
+ Q_OBJECT
+ /**
+ * @brief currentLevel This property contains id of the loaded level.
+ * @see AvailableLevelsModel::getCurrentLevel
+ * @see AvailableLevelsModel::setCurrentLevel
+ * @see AvailableLevelsModel::currentLevelChanged
+
+ */
+ Q_PROPERTY(int currentLevel READ getCurrentLevel WRITE setCurrentLevel NOTIFY currentLevelChanged)
+
+public:
+ AvailableLevelsModel();
+
+ /**
+ * @brief setAllLevels This method sets list of the available levels in game.
+ * @param newAllLevels This is new value of thge availabel games list.
+ */
+ void setAllLevels(const QList &newAllLevels);
+
+ /**
+ * @brief getCurrentLevel This method return value of the curernt level property
+ * @return value of the curernt level property
+ * @see AvailableLevelsModel::currentLevel
+ * @see AvailableLevelsModel::setCurrentLevel
+ * @see AvailableLevelsModel::currentLevelChanged
+ */
+ int getCurrentLevel() const;
+
+ /**
+ * @brief setCurrentLevel This method sets new current level.
+ * @param newCurrentLevel This is new value of the current level.
+ * @see AvailableLevelsModel::getCurrentLevel
+ * @see AvailableLevelsModel::currentLevel
+ * @see AvailableLevelsModel::currentLevelChanged
+ */
+ void setCurrentLevel(int newCurrentLevel);
+
+ /**
+ * @brief select This method select new level of user.
+ * @param levelId This is id of the selected level.
+ */
+ Q_INVOKABLE void select(int levelId);
+
+signals:
+ /**
+ * @brief currentLevelChanged This signal emited when the currentLevel propertye is changed.
+ * @see AvailableLevelsModel::getCurrentLevel
+ * @see AvailableLevelsModel::setCurrentLevel
+ * @see AvailableLevelsModel::currentLevel
+ */
+ void currentLevelChanged();
+
+ /**
+ * @brief sigUserSelectLevel This signal emited when user select new level.
+ * @param level This is level id that user selected.
+ */
+ void sigUserSelectLevel(int level);
+
+private:
+ QList _allLevels;
+ int currentLevel = -1;
+};
+
+}
+#endif // AVAILABLELEVELSMODEL_H
diff --git a/src/Core/private/baseuserlistmodel.cpp b/src/Core/private/baseuserlistmodel.cpp
new file mode 100644
index 0000000..b7c4df2
--- /dev/null
+++ b/src/Core/private/baseuserlistmodel.cpp
@@ -0,0 +1,144 @@
+//#
+//# Copyright (C) 2021-2021 QuasarApp.
+//# Distributed under the GPLv3 software license, see the accompanying
+//# Everyone is permitted to copy and distribute verbatim copies
+//# of this license document, but changing it is not allowed.
+//#
+
+
+#include "baseuserlistmodel.h"
+#include "user.h"
+
+#include
+
+namespace CRAWL {
+
+BaseUserListModel::BaseUserListModel() {
+
+}
+
+void BaseUserListModel::setUser(User *newUser) {
+ if (_user) {
+ disconnect(_user, &User::sigDropped,
+ this, &BaseUserListModel::handleDroppedItem);
+ disconnect(_user, &User::sigUnlcoked,
+ this, &BaseUserListModel::handleUnlockedItem);
+ disconnect(_user, &User::sigUlockedItemsChanged,
+ this, &BaseUserListModel::handleUnlockedItemsListChanged);
+ }
+
+ _user = newUser;
+
+ if (_user) {
+ connect(_user, &User::sigDropped,
+ this, &BaseUserListModel::handleDroppedItem);
+ connect(_user, &User::sigUnlcoked,
+ this, &BaseUserListModel::handleUnlockedItem);
+ connect(_user, &User::sigUlockedItemsChanged,
+ this, &BaseUserListModel::handleUnlockedItemsListChanged);
+ }
+}
+
+int BaseUserListModel::getIndexById(int id) const {
+ return _keysIndexes.value(id, -1);
+}
+
+const QList &BaseUserListModel::keys() const {
+ return _keys;
+}
+
+void BaseUserListModel::setKeys(const QList &visibleKeysList) {
+ int diff = visibleKeysList.size() - _keys.size();
+
+ auto update = [this](const QList & list) {
+ _keys = list;
+ for (int index = 0; index < _keys.size(); ++index) {
+ _keysIndexes[_keys[index]] = index;
+ }
+ };
+
+ if (diff > 0) {
+ beginInsertRows({}, _keys.size(), visibleKeysList.size() - 1);
+ update(visibleKeysList);
+ endInsertRows();
+
+ } else if (diff == 0) {
+ emit dataChanged(index(0,0), index(rowCount() - 1, columnCount() - 1));
+
+ } else {
+ beginRemoveRows({}, visibleKeysList.size(), _keys.size() - 1);
+ update(visibleKeysList);
+ endRemoveRows();
+ }
+}
+
+int BaseUserListModel::rowCount(const QModelIndex &) const {
+ return _keys.size();
+}
+
+int BaseUserListModel::columnCount(const QModelIndex &) const {
+ return 1;
+}
+
+QVariant BaseUserListModel::data(const QModelIndex &index, int role) const {
+
+ if (index.row() >= rowCount()) {
+ return {};
+ }
+
+ int id = _keys.at(index.row());
+
+ const IItem* item = getItem(id);
+
+ if (!item)
+ return {};
+
+ switch (role) {
+ case ItemId: return id;
+ case ItemName: return item->itemName();
+ case ItemImage: return item->image();
+ case ItemDescription: return item->description();
+ case ItemWasBuy: return getUser() && getUser()->isUnlocked(id);
+ default:
+ return {};
+ }
+}
+
+QHash BaseUserListModel::roleNames() const {
+ QHash roles;
+
+ roles[ItemId] = "itemId";
+ roles[ItemName] = "itemName";
+ roles[ItemDescription] = "itemDescription";
+ roles[ItemImage] = "itemImage";
+ roles[ItemWasBuy] = "itemWasBuy";
+
+ return roles;
+}
+
+User *BaseUserListModel::getUser() const {
+ return _user;
+}
+
+void BaseUserListModel::handleUnlockedItem(int item) {
+ int idx = _keysIndexes.value(item, -1);
+
+ if (idx >= 0) {
+ emit dataChanged(index(idx,0), index(idx, 0), {ItemWasBuy});
+ }
+}
+
+void BaseUserListModel::handleDroppedItem(int item) {
+ int idx = _keysIndexes.value(item, -1);
+
+ if (idx >= 0) {
+ emit dataChanged(index(idx,0), index(idx, 0), {ItemWasBuy});
+ }
+}
+
+void BaseUserListModel::handleUnlockedItemsListChanged(const QSet &) {
+ emit dataChanged(index(0,0), index(_keys.size() - 1, 0), {ItemWasBuy});
+
+}
+
+}
diff --git a/src/Core/private/baseuserlistmodel.h b/src/Core/private/baseuserlistmodel.h
new file mode 100644
index 0000000..2b863d9
--- /dev/null
+++ b/src/Core/private/baseuserlistmodel.h
@@ -0,0 +1,107 @@
+//#
+//# Copyright (C) 2021-2021 QuasarApp.
+//# Distributed under the GPLv3 software license, see the accompanying
+//# Everyone is permitted to copy and distribute verbatim copies
+//# of this license document, but changing it is not allowed.
+//#
+
+#ifndef BASEUSERLISTMODEL_H
+#define BASEUSERLISTMODEL_H
+
+#include
+
+namespace CRAWL {
+
+class User;
+class IItem;
+
+/**
+ * @brief The BaseUserListModel class This is base class wint implementation methods for working with user object.
+ */
+class BaseUserListModel: public QAbstractListModel
+{
+ Q_OBJECT
+public:
+ BaseUserListModel();
+
+ /**
+ * @brief setUser This method update user pointer
+ * @param user This is new pointer to current user.
+ */
+ void setUser(User *newUser);
+
+ /**
+ * @brief keys This method retutn curent visible items list.
+ * @return visible items list.
+ * @see BaseUserListModel::setKeys
+ */
+ const QList &keys() const;
+
+ /**
+ * @brief setKeys This method sets lsit of the keys for view.
+ * @param visibleKeysList This is new valud of the visible keys list.
+ * @see BaseUserListModel::keys
+ */
+ void setKeys(const QList& visibleKeysList);
+
+ int rowCount(const QModelIndex &parent = {}) const override;
+ int columnCount(const QModelIndex &parent = {}) const override;
+ QVariant data(const QModelIndex &index, int role) const override;
+ QHash roleNames() const override;
+
+protected:
+
+ /**
+ * @brief getUser This method return pointer to current user.
+ * @return pointer to current user.
+ */
+ User* getUser() const;
+
+ /**
+ * @brief handleUnlockedItem This slot invoked when emited the User::unclokItem signal.
+ * @param item This is id of the unlocked item
+ */
+ virtual void handleUnlockedItem(int item);
+
+ /**
+ * @brief handleUnlockedItem This slot invoked when emited the User::droppItem signal.
+ * @param item This is id of the dropped item
+ */
+ virtual void handleDroppedItem(int item);
+
+ /**
+ * @brief handleUnlockedItem This slot invoked when emited the User::setUnlockedItems signal.
+ * @param item This is new list of the unclod items.
+ */
+ virtual void handleUnlockedItemsListChanged(const QSet& newSet);
+
+ /**
+ * @brief getItem This method should be return the item by id. Override this method for correct works this model.
+ * @param id This is item id
+ * @return const pointer to item object.
+ */
+ virtual const IItem* getItem(int id) const = 0;
+
+ /**
+ * @brief getIndexById This method return index of the item by id.
+ * @param id This is id of the needed item
+ * @return index of the needed item. If the item with id not exists then return -1
+ */
+ int getIndexById(int id) const;
+private:
+
+ enum ViewItemRoles {
+ ItemId,
+ ItemName,
+ ItemImage,
+ ItemDescription,
+ ItemWasBuy
+ };
+
+ User * _user = nullptr;
+ QList _keys;
+ QHash _keysIndexes;
+};
+
+}
+#endif // BASEUSERLISTMODEL_H
diff --git a/src/Core/private/storeviewmodel.cpp b/src/Core/private/storeviewmodel.cpp
index 67cc00c..51fdcd2 100644
--- a/src/Core/private/storeviewmodel.cpp
+++ b/src/Core/private/storeviewmodel.cpp
@@ -10,95 +10,10 @@ StoreViewModel::StoreViewModel() {
}
-int StoreViewModel::rowCount(const QModelIndex &) const {
- return _keys.size();
-}
-
-int StoreViewModel::columnCount(const QModelIndex &) const {
- return 1;
-}
-
-QVariant StoreViewModel::data(const QModelIndex &index, int role) const {
- if (!_store)
- return {};
-
- if (index.row() >= rowCount()) {
- return {};
- }
-
- int id = _keys.at(index.row());
-
- const IItem* item = _store->getItemById(id);
-
- if (!item)
- return {};
-
- switch (role) {
- case ItemId: return id;
- case ItemName: return item->itemName();
- case ItemImage: return item->image();
- case ItemDescription: return item->description();
- case ItemWasBuy: return _currentUser && _currentUser->isUnlocked(id);
- default:
- return {};
- }
-}
-
-QHash StoreViewModel::roleNames() const {
- QHash roles;
-
- roles[ItemId] = "itemId";
- roles[ItemName] = "itemName";
- roles[ItemDescription] = "itemDescription";
- roles[ItemImage] = "itemImage";
- roles[ItemWasBuy] = "itemWasBuy";
-
- return roles;
-}
-
void StoreViewModel::init(Store *store, User *user) {
setUser(user);
-
- int diff = store->size() - _keys.size();
-
- auto update = [this](Store *store) {
- _store = store;
- _keys = store->keysList();
- for (int index = 0; index < _keys.size(); ++index) {
- _keysIndexes[index] = _keys[index];
- }
- };
-
- if (diff > 0) {
- beginInsertRows({}, _keys.size(), store->size() - 1);
- update(store);
- endInsertRows();
-
- } else if (diff == 0) {
- emit dataChanged(index(0,0), index(rowCount() - 1, columnCount() - 1));
-
- } else {
- beginRemoveRows({}, store->size(), _keys.size() - 1);
- update(store);
- endRemoveRows();
- }
-}
-
-void StoreViewModel::setUser(User *user) {
- if (_currentUser) {
- disconnect(_currentUser, &User::sigItemsUlocked,
- this, &StoreViewModel::handleItemsUnlocked);
-
- }
-
- _currentUser = user;
-
- if (_currentUser) {
- connect(_currentUser, &User::sigItemsUlocked,
- this, &StoreViewModel::handleItemsUnlocked);
-
- handleItemsUnlocked(_currentUser->unlockedItems());
- }
+ setKeys(store->keysList());
+ _store = store;
}
bool StoreViewModel::visible() const {
@@ -113,15 +28,16 @@ void StoreViewModel::setVisible(bool newVisible) {
}
void StoreViewModel::buy(int item) {
- if (_store && _currentUser) {
- _store->buy(*_currentUser, item);
+ if (_store && getUser()) {
+ _store->buy(*getUser(), item);
}
}
-void StoreViewModel::handleItemsUnlocked (const QSet & ) {
-
- emit dataChanged(index(0,0), index(_keys.size() - 1, 0), {ItemWasBuy});
+const IItem *StoreViewModel::getItem(int id) const {
+ if (!_store)
+ return nullptr;
+ return _store->getItemById(id);
}
}
diff --git a/src/Core/private/storeviewmodel.h b/src/Core/private/storeviewmodel.h
index 8bfff79..ca39aa9 100644
--- a/src/Core/private/storeviewmodel.h
+++ b/src/Core/private/storeviewmodel.h
@@ -8,7 +8,7 @@
#ifndef STOREVIEWMODEL_H
#define STOREVIEWMODEL_H
-#include
+#include "baseuserlistmodel.h"
namespace CRAWL {
@@ -18,7 +18,7 @@ class User;
/**
* @brief The StoreViewModel class This is view model of the store. The object of this class should be initialized it he Store class.
*/
-class StoreViewModel: public QAbstractListModel
+class StoreViewModel: public BaseUserListModel
{
Q_OBJECT
/**
@@ -29,11 +29,6 @@ class StoreViewModel: public QAbstractListModel
public:
StoreViewModel();
- int rowCount(const QModelIndex &parent = {}) const override;
- int columnCount(const QModelIndex &parent = {}) const override;
- QVariant data(const QModelIndex &index, int role) const override;
- QHash roleNames() const override;
-
/**
* @brief init This method initialize data of the view model.
* @param _store This is poiter to store that contains all inforamtion about store items.
@@ -42,12 +37,6 @@ public:
*/
void init(Store * store, User* user);
- /**
- * @brief setUser This method update user pointer
- * @param user This is new pointer to current 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.
@@ -66,33 +55,20 @@ public:
*/
Q_INVOKABLE void buy(int item);
+ // BaseUserListModel interface
+protected:
+ const IItem *getItem(int id) const;
+
signals:
/**
* @brief visibleChanged This slot emited when store visibel changed
*/
void visibleChanged();
-private slots:
- void handleItemsUnlocked(const QSet &);
-
private:
- void updateView();
-
- enum StoreRoles {
- ItemId,
- ItemName,
- ItemImage,
- ItemDescription,
- ItemWasBuy
- };
-
Store *_store = nullptr;
- QList _keys;
- QHash _keysIndexes;
- User* _currentUser = nullptr;
bool _visible = false;
-
};
}
diff --git a/src/Core/private/user.cpp b/src/Core/private/user.cpp
index 917164c..f15c0f6 100644
--- a/src/Core/private/user.cpp
+++ b/src/Core/private/user.cpp
@@ -60,16 +60,17 @@ bool User::isUnlocked(int item) const {
void User::unclokItem(int item) {
_unlockedItems.insert(item);
- emit sigItemsUlocked({item});
+ emit sigUnlcoked(item);
}
void User::droppItem(int item) {
_unlockedItems.remove(item);
+ emit sigDropped(item);
}
void User::setUnlockedItems(const QSet &newUnlockedItems) {
_unlockedItems = newUnlockedItems;
- emit sigItemsUlocked(newUnlockedItems);
+ emit sigUlockedItemsChanged(newUnlockedItems);
}
int User::recalcTier() {
diff --git a/src/Core/private/user.h b/src/Core/private/user.h
index 4ced0e8..e8f96db 100644
--- a/src/Core/private/user.h
+++ b/src/Core/private/user.h
@@ -145,10 +145,24 @@ signals:
void xpChanged();
/**
- * @brief sigItemsUlocked This signal emited when user unlocked item.
+ * @brief sigUlockedItemsChanged This signal emited when users list of unclode items is changed..
* @param unclokedItems This is unlocked items set. Each items in the set is id of the unclocked item.
*/
- void sigItemsUlocked(const QSet & unclokedItems);
+ void sigUlockedItemsChanged(const QSet & unclokedItems);
+
+ /**
+ * @brief sigUnlcoked This signal emmited when user unlock one item.
+ * @param item This is unlocked item id.
+ * @see User::unclokItem
+ */
+ void sigUnlcoked(int item);
+
+ /**
+ * @brief sigDropped This signal emmited when user dropped one item.
+ * @param item This is dpopped item id.
+ * @see User::droppItem
+ */
+ void sigDropped(int item);
protected:
/**