diff --git a/pyproject.toml b/pyproject.toml index 8b44eaf..7546765 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -24,8 +24,6 @@ dependencies = [ "pluggy", "pyinstaller", "pyinstaller-hooks-contrib", - "PyQt6-Qt6", - "PyQt6-sip", "PySide6", "PySide6_Addons", "PySide6_Essentials", diff --git a/src/createthesun/old/gamedefine.py b/src/createthesun/gamedefine.py similarity index 71% rename from src/createthesun/old/gamedefine.py rename to src/createthesun/gamedefine.py index f9b1e06..7f04b36 100644 --- a/src/createthesun/old/gamedefine.py +++ b/src/createthesun/gamedefine.py @@ -1,19 +1,265 @@ +####### +from __future__ import annotations +####### + import json import time from copy import deepcopy from dataclasses import asdict, dataclass +from typing import Self import deepdiff import regex import versions from dacite import from_dict from PySide6.QtWidgets import QTabWidget +from PySide6.QtCore import QObject, Signal, Slot, Property as QProperty + +from . import quickload -from .. import quickload -from .gameLogic import automationGameLogic +items: dict[str, object] = {} + +# Base Classes +class _Item(QObject): + """This is the base class for all items, will not be accessed directly. It supports switch items, which are items that have been modified from the base item. + + Note that switches are guranteed to always be in the same order, so the first switch will always be the first switch, and so on. + The use of switch items are optional, so this class can be used without them. + """ + nameChanged = Signal(str) + descriptionChanged = Signal(str) + amountChanged = Signal(int) + + def __init__(self): + super().__init__() + global items + items[self.__class__.__name__] = self + + self._name: str = "" + self._description: str = "" + + self._amount: int = 0 + + self.internalName: str = "" + self.singlarName: str = "" + self.cost: list[dict[str, int]] = [] + self.costEquation: str = "" + self.gives: list[dict[object, int]] = [] + self.switches: list[object] = [] + + def getSwitch(self, switch: int) -> object: + """This function will return the correct switch item based on the switch number. + + Args: + switch (int): The switch number. + + Returns: + Item_Switch: The correct switch item. + """ + return self.switches[switch] + + @QProperty(str, notify=nameChanged) + def name(self) -> str: + return self._name + + @name.setter + def name(self, value: str): + self._name = value + self.nameChanged.emit(value) + + + @QProperty(str, notify=descriptionChanged) + def description(self) -> str: + return self._description + + @description.setter + def description(self, value: str): + self._description = value + self.descriptionChanged.emit(value) + + @QProperty(int, notify=amountChanged) + def amount(self) -> int: + return self._amount + + @amount.setter + def amount(self, value: int): + self._amount = value + self.amountChanged.emit(value) + + @Slot(result=str) + def getName(self) -> str: + if not self.amount == 1: + return self.name + else: + return self.singlarName + + + + +class _LevelAutomation: + """This is the base class for all automations, will not be accessed directly, even when instantiated. + It should instead be used with the Automation class, which will return the correct LevelAutomation class. + """ + def __init__(self): + + self.name: str = "" + self.description: str = "" + self.upgradeName: str = "" + self.upgradeDescription: str = "" + + self.statDescription: str = "" + self.upgradeStatDescription: str = "" + self.statDescriptionBlank: str = "" + + self.disabledText: str = "" + + + self.startLevel: int = 0 + self.upgradeCost: list[dict[str, int]] = [] + self.withRequirement: bool = False + self.type: str = "" + self.idleGenerator: dict[str, int] = {} + +class Automation: + """This is the base class for all automations, will not be accessed directly. + + """ + def __init__(self): + self.firstCost: list[dict[str, int]] = [] + self.maxLevel: int = 0 + self.multiLevelUpgradesStarts: list[int] = [] + self.multiLevelUpgrades: list[Automation] = [] + + def getAutomationClass(self, level: int) -> _LevelAutomation: + """This function will return the correct LevelAutomation class based on the level of the automation. + + Args: + level (int): The level of the automation. + + Returns: + _LevelAutomation: The correct LevelAutomation class. + """ + return self.multiLevelUpgrades[self.getMultiLevel(level)] + + def getMultiLevel(self, level: int) -> int: + """This function will return the correct LevelAutomation class based on the level of the automation. + + Args: + level (int): The level of the automation. + + Returns: + int: The correct LevelAutomation class. + """ + _ = 0 + while level >= self.multiLevelUpgradesStarts[_]: + _ += 1 + + return self.multiLevelUpgrades[_] + +class Achevement: + pass + +class Unlockable: + pass + +class Rewrite: + pass initalized = False +class Quarks(_Item): + def __init__(self): + super().__init__() + self.name = "Quarks" + self.singlarName = "Quark" + self.description = "Quarks are the building blocks of protons. They are made of nothing...?" + self.internalName = "quarks" + + self.cost = [{"what": None, "amount": -1}] + self.defaultCost = -1 + self.costEquation = "" + self.gives = [{"what": "quarks", "amount": 1}] +Quarks() + +class Electrons(_Item): + def __init__(self): + super().__init__() + self.name = "Electrons" + self.singlarName = "Electron" + self.description = "Electrons are the building blocks of atoms." + self.internalName = "electrons" + + self.cost = [{"what": None, "amount": -1}] + self.defaultCost = -1 + self.costEquation = "" + self.gives = [{"what": "Electrons", "amount": 1}] +Electrons() + +class Protons(_Item): + def __init__(self): + super().__init__() + self.name = "Protons" + self.singlarName = "Proton" + self.description = "Protons are the building blocks of atoms. They are made of quarks." + self.internalName = "protons" + self.amount = 3 + self.cost = [{"what": Quarks, "amount": 3}] + self.costEquation = "%1 * 3" + self.gives = [{"what": "Protons", "amount": 1}] +Protons() + +class Hydrogen(_Item): + def __init__(self): + super().__init__() + self.name = "Hydrogen" + self.singlarName = "Hydrogen" + self.description = "Hydrogen is the simplest element. It is made of one proton and one electron." + + self.internalName = "hydrogen" + self.cost = [{"what": Quarks, "amount": 3}] + self.costEquation = "%1 * 3" + self.gives = [{"what": "Hydrogen", "amount": 1}] +Hydrogen() + +class Stars(_Item): + def __init__(self): + super().__init__() + self.name = "Stars" + self.singlarName = "Star" + self.description = "Stars are the building blocks of galaxies. They are made of hydrogen." + + self.internalName = "stars" + self.cost = [{"what": Hydrogen, "amount": 1e57}] + self.costEquation = "%1 * 1e57" + self.gives = [{"what": "Stars", "amount": 2}] +Stars() + +class Galaxies(_Item): + def __init__(self): + super().__init__() + self.name = "Galaxies" + self.singlarName = "Galaxy" + self.description = "Galaxies are the building blocks of superclusters. They are made of stars." + + self.internalName = "galaxies" + self.cost = [{"what": Stars, "amount": 1e11}] + self.costEquation = "%1 * 1e11" + self.gives = [{"what": "galaxies", "amount": 1}] +Galaxies() + +class Superclusters(_Item): + def __init__(self): + super().__init__() + self.name = "Superclusters" + self.singlarName = "Supercluster" + self.description = "Superclusters are the building blocks of the universe. They are made of galaxies." + + self.internalName = "superclusters" + self.cost = [{"what": Galaxies, "amount": 100000}] + self.costEquation = "%1 * 100000" + self.gives = [{"what": "superclusters", "amount": 1}] +Superclusters() + defualtGameDefine = { "itemVisualDefine": { "quarks": { @@ -206,8 +452,8 @@ "description": "Accelerates particles to create quarks.", "upgradeVisualName": "Increase Loop Size", "upgradeDescription": "Increase the size of the particle accelerator loop for more quarks per second.", - "firstupgradeUsefulDescription": "Creates 1 Quark per second", - "currentUpgradeUsefulDescription": "You are currently gaining 1 Quark every %%% seconds", + "firstupgradeUsefulDescription": "Creates 1 Quark per second", # rolled into statDescription (See below) + "currentUpgradeUsefulDescription": "You are currently gaining 1 Quark every %%% seconds", # renamed to statDescription "upgradeUsefulDescription": "Upgrade to gain 1 Quark every %%% seconds", "usefulDescriptionBlank": "tickTime", "disabledText": "How are you seeing this?", @@ -532,57 +778,57 @@ class GameDefine: autosaveTime = 300000 -def loadSave(saveDict: list[dict]): - global gamedefine - newsave = deepcopy(defualtGameDefine) +# def loadSave(saveDict: list[dict]): +# global gamedefine +# newsave = deepcopy(defualtGameDefine) - for item in saveDict: - changes = item["changes"] - location: str - location = item["location"] +# for item in saveDict: +# changes = item["changes"] +# location: str +# location = item["location"] - try: - exec(f"newsave{location} = changes") - except IndexError: - # example where this path would be triggered: - # dict = {"hello": []} - # diff = [{"changes": 1, "location": ["hello"][2]}] - # so in this case, we need to add 3 items to the list, so we reach the third index - # this will allow us to use the index based assignment +# try: +# exec(f"newsave{location} = changes") +# except IndexError: +# # example where this path would be triggered: +# # dict = {"hello": []} +# # diff = [{"changes": 1, "location": ["hello"][2]}] +# # so in this case, we need to add 3 items to the list, so we reach the third index +# # this will allow us to use the index based assignment - # Ignore the comments above, i've just made it so the item is appended to the list. +# # Ignore the comments above, i've just made it so the item is appended to the list. - # make sure all quotes are double - location = location.replace("'", '"') +# # make sure all quotes are double +# location = location.replace("'", '"') - # match all keys - matches = regex.findall(r"[^[\]]*", location) +# # match all keys +# matches = regex.findall(r"[^[\]]*", location) - # remove the last key (which would be the list index) +# # remove the last key (which would be the list index) - # the regex removes the brackets, we have to add it back +# # the regex removes the brackets, we have to add it back - matches = [i for i in matches if not len(i) == 0] - amount = matches.pop() - matches = [f"[{i}]" for i in matches] +# matches = [i for i in matches if not len(i) == 0] +# amount = matches.pop() +# matches = [f"[{i}]" for i in matches] - what = "".join(matches) - oldCode = f""" -toAppend = newsave{what} -for i in range({amount} + 1): - toAppend.append(None) - """ - code = f"newsave{location}.append(changes)" - exec(code) +# what = "".join(matches) +# oldCode = f""" +# toAppend = newsave{what} +# for i in range({amount} + 1): +# toAppend.append(None) +# """ +# code = f"newsave{location}.append(changes)" +# exec(code) - gamedefine = from_dict(data_class=GameDefine, data=newsave) - gamedefine.mainTabBuyMultiple = 1 +# gamedefine = from_dict(data_class=GameDefine, data=newsave) +# gamedefine.mainTabBuyMultiple = 1 - for item in gamedefine.automationLevels: - if gamedefine.automationLevels[item] > 0: - automationGameLogic.updateAutomationStatus(item) +# for item in gamedefine.automationLevels: +# if gamedefine.automationLevels[item] > 0: +# automationGameLogic.updateAutomationStatus(item) - return gamedefine +# return gamedefine def getSaveData(data: GameDefine | None = None) -> list[dict]: diff --git a/src/createthesun/iLoveModelsTotally.py b/src/createthesun/iLoveModelsTotally.py new file mode 100644 index 0000000..ec1381d --- /dev/null +++ b/src/createthesun/iLoveModelsTotally.py @@ -0,0 +1,51 @@ +from PySide6.QtCore import QAbstractListModel, QByteArray, QModelIndex, Qt + +import dataclasses + +@dataclasses.dataclass +class listModelItem: + thing: str = "" + things: str = "" + objects: str = "" + multi: str = "" + +class ListModel(QAbstractListModel): + def __init__(self, contains = listModelItem): + super().__init__() + self._contentsList = [] + + self.contains = contains + + def data(self, index: QModelIndex, role: int = Qt.ItemDataRole.DisplayRole): + if 0 <= index.row() < self.rowCount(): + item = self._contentsList[index.row()] + name = self.roleNames().get(role) + if name: + return getattr(item, name.decode()) + + def roleNames(self) -> dict[int, QByteArray]: + d = {} + for i, field in enumerate(dataclasses.fields(self.contains)): + d[Qt.ItemDataRole.DisplayRole + i] = field.name.encode() + return d + + def rowCount(self, parent=None): + return len(self._contentsList) + + def addItem(self, item: object): + self.beginInsertRows(QModelIndex(), 0, 0) + self._contentsList.insert(0, item) + self.endInsertRows() + + def moveItem(self, fromIndex: int, toIndex: int): + self.beginMoveRows(QModelIndex(), fromIndex, fromIndex, QModelIndex(), toIndex) + self._contentsList.insert(toIndex, self._contentsList.pop(fromIndex)) + self.endMoveRows() + + def clear(self): + self.beginResetModel() + self._contentsList.clear() + self.endResetModel() + + def count(self): + return len(self._contentsList) \ No newline at end of file diff --git a/src/createthesun/main~2x3x.qml b/src/createthesun/main~2x3x.qml index 679e507..e701a98 100644 --- a/src/createthesun/main~2x3x.qml +++ b/src/createthesun/main~2x3x.qml @@ -18,6 +18,12 @@ ApplicationWindow { Connections { target: Backend + + function onLoadComplete() { + console.log("Loaded") + console.log(ItemsModel) + console.log(Backend.activeTab) + } } Connections { @@ -40,6 +46,7 @@ ApplicationWindow { header: Text { id: headertext + text: root.title font.pixelSize: 24 diff --git a/src/createthesun/qml/electrons.qml b/src/createthesun/qml/electrons.qml index c57fe3a..9fe9f90 100644 --- a/src/createthesun/qml/electrons.qml +++ b/src/createthesun/qml/electrons.qml @@ -3,6 +3,8 @@ import QtQuick.Controls import QtQuick.Layouts import Qt.labs.platform +import "./qml/" as ProgressBar + Item { id: root property QtObject mainModel // absract list model from python @@ -20,11 +22,22 @@ Item { Text { id: text - text: "Electrons" - color: Theme.primary + text: backend.items.electrons.count + color: Theme.tertiary font.pixelSize: 24 anchors.horizontalCenter: parent.horizontalCenter anchors.verticalCenter: parent.verticalCenter } + ProgressBar { + id: progress + anchors.fill: parent + percent: 50 + fillColor: Theme.tertiary + backgroundColor: "transparent" + radius: 5 + border.color: Theme.tertiary + border.width: 2 + } + } \ No newline at end of file diff --git a/src/createthesun/qml/progressbar.qml b/src/createthesun/qml/progressbar.qml index 2807813..4fe5bc0 100644 --- a/src/createthesun/qml/progressbar.qml +++ b/src/createthesun/qml/progressbar.qml @@ -1,3 +1,62 @@ +// import QtQuick +// import QtQuick.Controls +// import QtQuick.Layouts +// import QtQuick.Shapes + +// Item { +// id: root + +// width: 50 +// height: 100 + +// anchors.horizontalCenter: parent.horizontalCenter +// anchors.verticalCenter: parent.verticalCenter + + +// property real percent: 50 +// property bool vertical: true + +// property alias fillColor: fill.color +// property alias backgroundColor: background.color + +// property alias radius: background.radius + +// property alias border: background.border + +// fillColor: red +// backgroundColor: transparent + +// Rectangle { +// id: background +// clip: true +// anchors.fill: parent + +// Rectangle { +// id: fill +// width: (root.vertical) ? parent.width : parent.width * (root.percent / 100) +// height: (root.vertical) ? parent.height * (root.percent / 100) : parent.height + + +// anchors.bottom: parent.bottom +// color: "red" + +// } +// } + +// Item { +// anchors.centerIn: parent +// id: radii +// width: background.width +// height: background.height +// property string color: 'transparent' +// property int rightTopCornerRadius: 5 +// property int rightBottomCornerRadius: 5 +// property int leftBottomCornerRadius: 5 +// property int leftTopCornerRadius: 5 +// } + +// } + import QtQuick import QtQuick.Controls import QtQuick.Layouts @@ -14,7 +73,7 @@ Item { property real percent: 50 - property bool vertical: true + property bool vertical: false property alias fillColor: fill.color property alias backgroundColor: background.color @@ -23,56 +82,16 @@ Item { property alias border: background.border - fillColor: red - backgroundColor: transparent - + Behavior on percent { + NumberAnimation { + duration: 100 + } + } Rectangle { id: background clip: true anchors.fill: parent - containmentMask: mask - - Shape { - id: mask - - containsMode: shape.fillContains - ShapePath { - strokeWidth: 5 - strokeColor: radii.color - startX: radii.leftTopCornerRadius > 0 ? radii.leftTopCornerRadius : 0 - startY: 0 - fillColor: "transparent" - capStyle: ShapePath.RoundCap - fillRule: ShapePath.WindingFill - - PathLine { y: 0; x:radii.width - radii.rightTopCornerRadius} - PathArc { - x: radii.width; y: radii.rightTopCornerRadius - radiusX: radii.rightTopCornerRadius; radiusY: radii.rightTopCornerRadius - - } - - PathLine { x:radii.width; y:radii.height - radii.rightBottomCornerRadius} - PathArc { - x:radii.width - radii.rightBottomCornerRadius; y: radii.height - radiusX: radii.rightBottomCornerRadius; radiusY: radii.rightBottomCornerRadius - } - - PathLine { x:radii.leftBottomCornerRadius; y:radii.height} - PathArc { - x:0; y: radii.height - radii.leftBottomCornerRadius - radiusX: radii.leftBottomCornerRadius; radiusY: radii.leftBottomCornerRadius - } - - PathLine { x:0; y:radii.leftTopCornerRadius} - PathArc { - x:radii.leftTopCornerRadius; y: 0 - radiusX: radii.leftTopCornerRadius; radiusY: radii.leftTopCornerRadius - } - } - } - Rectangle { id: fill width: (root.vertical) ? parent.width : parent.width * (root.percent / 100) @@ -84,17 +103,4 @@ Item { } } - - Item { - anchors.centerIn: parent - id: radii - width: background.width - height: background.height - property string color: 'transparent' - property int rightTopCornerRadius: 5 - property int rightBottomCornerRadius: 5 - property int leftBottomCornerRadius: 5 - property int leftTopCornerRadius: 5 - } - } diff --git a/src/createthesun/qml/tabs/mainTab.qml b/src/createthesun/qml/tabs/mainTab.qml index 035ef01..ab059a4 100644 --- a/src/createthesun/qml/tabs/mainTab.qml +++ b/src/createthesun/qml/tabs/mainTab.qml @@ -15,12 +15,57 @@ Item { Connections { target:Theme } + anchors.fill: parent + + ListView { + id: tabBar + model: ItemsModel + + anchors.left: parent.left + anchors.right: parent.right + anchors.top: parent.top + + height: (43 / 2) + 10 + + orientation: ListView.Vertical + + spacing: 2 + delegate: Rectangle { + id: rect + topRightRadius: 10/2 + topLeftRadius: 10/2 + + width: metrics.width + 10 + height: 43 / 2 + + color: Theme.surfaceContainer + + border.color: Theme.primaryFixed + border.width: 1/2 + + Text { + id: tabText + text: "You have " + model.item.amount + " " + model.item.getName() + color: Theme.onSurface + font.pixelSize: 18 + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + anchors.fill: parent + + Behavior on color { + ColorAnimation { + easing.type: Easing.InOutQuad + duration: 200 + } + } + } + + TextMetrics { + id: metrics + text: tabText.text + font: tabText.font + } - Rectangle { - anchors.fill: parent - id: background - color: Theme.primary - Behavior on color { ColorAnimation { easing.type: Easing.InOutQuad @@ -28,5 +73,6 @@ Item { } } } +} } \ No newline at end of file diff --git a/src/createthesun/qmlver.py b/src/createthesun/qmlver.py index 6757ff3..5d5356a 100644 --- a/src/createthesun/qmlver.py +++ b/src/createthesun/qmlver.py @@ -5,6 +5,7 @@ import random import sys import threading +import time import requests from PySide6.QtCore import Property as Property @@ -12,7 +13,7 @@ # library imports from PySide6.QtCore import QAbstractListModel, QByteArray, QModelIndex, QObject, Qt, QTimer from PySide6.QtCore import Signal as QSignal -from PySide6.QtCore import Slot as Slot +from PySide6.QtCore import Slot as Slot, QDir from PySide6.QtGui import QAction, QFont, QIcon from PySide6.QtQml import ( QmlElement, @@ -24,56 +25,12 @@ from PySide6.QtWidgets import QApplication # local imports -from . import materialInterface, urbanistFont +from . import materialInterface, urbanistFont, gamedefine, iLoveModelsTotally + -@dataclasses.dataclass -class Item: - thing: str = "" - things: str = "" - objects: str = "" - multi: str = "" -class ListModel(QAbstractListModel): - def __init__(self, contains = Item): - super().__init__() - self._contentsList = [] - self.contains = contains - - def data(self, index: QModelIndex, role: int = Qt.ItemDataRole.DisplayRole): - if 0 <= index.row() < self.rowCount(): - item = self._contentsList[index.row()] - name = self.roleNames().get(role) - if name: - return getattr(item, name.decode()) - - def roleNames(self) -> dict[int, QByteArray]: - d = {} - for i, field in enumerate(dataclasses.fields(self.contains)): - d[Qt.ItemDataRole.DisplayRole + i] = field.name.encode() - return d - - def rowCount(self, parent=None): - return len(self._contentsList) - - def addItem(self, item: object): - self.beginInsertRows(QModelIndex(), 0, 0) - self._contentsList.insert(0, item) - self.endInsertRows() - - def moveItem(self, fromIndex: int, toIndex: int): - self.beginMoveRows(QModelIndex(), fromIndex, fromIndex, QModelIndex(), toIndex) - self._contentsList.insert(toIndex, self._contentsList.pop(fromIndex)) - self.endMoveRows() - - def clear(self): - self.beginResetModel() - self._contentsList.clear() - self.endResetModel() - - def count(self): - return len(self._contentsList) @dataclasses.dataclass class Tab: name: str = "" @@ -83,13 +40,21 @@ class Tab: QML_IMPORT_MAJOR_VERSION = 1 QML_IMPORT_MINOR_VERSION = 0 +class Items(QObject): + def __init__(self): + super().__init__() + for i in gamedefine.items: + setattr(self, i.lower(), gamedefine.items[i]) + + @Slot(str, result=QObject) + def getItem(self, name: str): + return getattr(self, name.lower()) + @QmlElement -@QmlSingleton class Backend(QObject): - modelChanged = QSignal(QAbstractListModel, name="modelChanged", arguments=['model']) loadComplete = QSignal(name="loadComplete") activeTabChanged = QSignal(name="activeTabChanged") - + # tabModelChanged = QSignal(name="tabModelChanged") _instance = None def __init__(self): @@ -98,9 +63,8 @@ def __init__(self): self.initialized = True self._value = 0 - self.activeTab = "mainTab" - self.model = ListModel() - + self._activeTab = "mainTab" + @Property(str, notify=activeTabChanged) def activeTab(self): return self._activeTab @@ -119,10 +83,9 @@ def findQmlFile() -> str | None: if file == 'main~2x3x.qml': return os.path.join(path, file) return None - - + def createTabModel(): - model = ListModel(contains=Tab) + model = iLoveModelsTotally.ListModel(contains=Tab) model.addItem(Tab(name = "Stats", internalName = "stats")) model.addItem(Tab("Save & Load", internalName = "saveLoad")) model.addItem(Tab("Goals", internalName = "goals")) @@ -134,9 +97,19 @@ def createTabModel(): def generateRandomHexColor(): return random.randint(0, 0xFFFFFF) +@dataclasses.dataclass +class Item: + item: QObject = None + +def createItemModel(): + ItemsModel = iLoveModelsTotally.ListModel(contains=Item) + for i in gamedefine.items: + ItemsModel.addItem(Item(item=gamedefine.items[i])) + + return ItemsModel + + def main(): - theme = materialInterface.Theme() - theme.get_dynamicColors(0xDCAB5C, True, 0.0) app = QApplication() fonts = urbanistFont.createFonts() @@ -147,14 +120,12 @@ def main(): engine.quit.connect(app.quit) qml = findQmlFile() - backend: Backend = Backend() - # print(backend) - # qmlRegisterSingletonInstance(Backend, QML_IMPORT_NAME, QML_IMPORT_MAJOR_VERSION, QML_IMPORT_MINOR_VERSION, "Backend", backend) - - theme: materialInterface.Theme = materialInterface.Theme() + backend = Backend() + + theme = materialInterface.Theme() theme.get_dynamicColors(generateRandomHexColor(), True, 0.0) - # print(theme) - # qmlRegisterSingletonInstance(materialInterface.Theme, QML_IMPORT_NAME, QML_IMPORT_MAJOR_VERSION, QML_IMPORT_MINOR_VERSION, "Theme", theme) + items = Items() + if not qml: print('Could not find QML file') @@ -164,11 +135,14 @@ def main(): engine.rootContext().setContextProperty("Theme", theme) engine.rootContext().setContextProperty("Backend", backend) + engine.rootContext().setContextProperty("Items", items) + + tabsModel = createTabModel() + engine.rootObjects()[0].setProperty("tabsModel", tabsModel) - engine.rootObjects()[0].setProperty('theme', theme) - tabModel = createTabModel() - engine.rootObjects()[0].setProperty('tabsModel', tabModel) + ItemsModel = createItemModel() + engine.rootContext().setContextProperty("ItemsModel", ItemsModel) tim = QTimer() tim.setInterval(1000) @@ -176,7 +150,8 @@ def main(): tim.start() - + print(QDir.currentPath()) + time.sleep(0.3) # Main Theme Source Color: #DCAB5C backend.loadComplete.emit() engine.rootObjects()[0].show() diff --git a/src/createthesun/s.py b/src/createthesun/s.py new file mode 100644 index 0000000..79eaab3 --- /dev/null +++ b/src/createthesun/s.py @@ -0,0 +1,20 @@ +class A: + def __init__(self): + print("A") + +class B: + def __init__(self): + print("B") + +class C(A, B): + def initAll(cls): + _ = list(cls.__mro__); _.remove(object); _.remove(cls) + for i in _: + i.__init__() + + def __init__(self): + self.initAll() + + + +C() \ No newline at end of file diff --git a/src/createthesun/saving.md b/src/createthesun/saving.md new file mode 100644 index 0000000..38b8af9 --- /dev/null +++ b/src/createthesun/saving.md @@ -0,0 +1,33 @@ +lets see... we need to fix saving (again) + +Instead of using nested dictionaries, I want to use classes *and* nested dictionaries. The reason for this is to access the data from the QML using the `@property` decorator. This will allow me to use the `onPropertyChanged` signal to update the QML when the data changes. + +When a piece of data needs to be accesed from QML, it will be stored as a class property. When it doesn't, it can be stored in either a class property *or* a dictionary. The dictionary will be used to store data that is not accessed from QML. + +Example: +```python + "quarks": { + "visualName": "Quarks", + "description": "Quarks are the building blocks of protons. They are made of nothing...?", + "id": ["quarks", 0], + } + + "itemInternalDefine": { + "quarks": { + "whatItCosts": [{"what": "nothing", "amount": -1}], + "defaultCost": -1, + "costEquation": "", + "whatItGives": [{"what": "quarks", "amount": 1}], + } + } + # snippet from gamedefine +``` +In this example, `quarks` will become a class. `visualName`, `description`, and `id` will be class properties. `whatItCosts`, `defaultCost`, `costEquation`, and `whatItGives` will be stored in the nested dictionary. as a class variable. + +Actual Saving: +Instead of saving the JSON, I will save it in a SQLite database. + +Currently: All changes to item (for example costs) are made *directly* to the gamedefine dictionary. Then, during saving, we step through each key in gamedefine to see if it was changed. If so, we then save that key. This works, but I think it's inefficient. + +All changes are not random. for example, the cost of protons is only changed when the user purcases the rewrite "quark efficiency". So, I will use "switch" items to store each change indiviually. The used switch item will change depending on what the user does. The only thing that needs to be stored is a number indicating which switch to use. This will be stored in the database. +The amount of each item a player has will be stored in the db also. \ No newline at end of file