diff --git a/.gitignore b/.gitignore index b6e4761..6034e6b 100644 --- a/.gitignore +++ b/.gitignore @@ -127,3 +127,6 @@ dmypy.json # Pyre type checker .pyre/ + +# Kivy +.buildozer/ diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..1d0af2d --- /dev/null +++ b/requirements.txt @@ -0,0 +1,11 @@ +certifi==2022.12.7 +charset-normalizer==3.1.0 +docutils==0.19 +idna==3.4 +Kivy==2.1.0 +Kivy-Garden==0.1.5 +kivymd==1.1.1 +Pillow==9.4.0 +Pygments==2.14.0 +requests==2.28.2 +urllib3==1.26.15 diff --git a/src/main.py b/src/main.py index 7f5a552..37fbd06 100644 --- a/src/main.py +++ b/src/main.py @@ -1,60 +1,94 @@ +from os import name from kivy.app import App from kivy.properties import ListProperty, StringProperty, BooleanProperty, ObjectProperty from kivy.uix.boxlayout import BoxLayout from kivy.uix.button import Label -from kivy.uix.screenmanager import Screen +from kivy.uix.screenmanager import Screen, ScreenManager from kivy.config import Config +from kivymd.app import MDApp +from kivymd.uix.button import MDFlatButton +from kivymd.uix.card.card import MDBoxLayout +from kivymd.uix.dialog import MDDialog +from kivymd.uix.list import OneLineAvatarIconListItem + Config.set('graphics', 'resizable', '0') Config.set('graphics', 'height', '1000') Config.set('graphics', 'width', '620') -class ShoppingEntry(BoxLayout): - text = StringProperty() - is_checked = BooleanProperty() +class ShoppingEntry(OneLineAvatarIconListItem): + def __init__(self, text, **kwargs): + super().__init__(**kwargs) + self.text = text + self.is_checked = False + + def delete(self, shopping_entry): + self.parent.remove_widget(shopping_entry) + +class AddDialog(MDBoxLayout): def __init__(self, **kwargs): - super(ShoppingEntry, self).__init__(**kwargs) + super().__init__(**kwargs) -class MainScreen(Screen): - shoppingEntries = ListProperty([]) - shop = ObjectProperty(BoxLayout()) +class ShoppingEntryScreen(Screen): + add_dialog: MDDialog | None = None - def __init__(self, *args, **kwargs): - super(MainScreen, self).__init__(*args, **kwargs) - self.add_shopping_entry("Test", True) + def open_add_popup(self): + if self.add_dialog: + return - def add_shopping_entry(self, text: str, is_checked: bool): - entry = ShoppingEntry() - entry.text = text - entry.is_checked = is_checked + # SPRACHE + buttons = [ + MDFlatButton(text='Abbrechen', on_release=self.close_add_popup), + MDFlatButton(text='Bestätigen', on_release=lambda args: self.add_shopping_entry("Text")) + ] + # SPRACHE + self.add_dialog = MDDialog( + title='Eintrag hinzufügen', + type='custom', + content_cls=AddDialog(), + buttons=buttons + ) - self.shop.add_widget(entry) - self.shop.add_widget(Label(text="Hallo")) - print("ADD_ENTRY") + self.add_dialog.open() - self.shoppingEntries.append(entry) + # *args ist noetig, da weitere Parameter mitgegeben werden, die aber nicht genutzt werden + def close_add_popup(self, *args): + if not self.add_dialog: + return - # load existing shopping entries - def on_enter(self): - print("ENTER_MAIN_SCREEN") + self.add_dialog.dismiss() + self.add_dialog = None - entry = ShoppingEntry() - entry.text = "Test" - entry.is_checked = True - #self.ids["shop"].add_widget(entry) + + def add_shopping_entry(self, text): + self.ids['shopping_list'].add_widget(ShoppingEntry(text=text)) + self.close_add_popup() + + def delete_entry(self): + pass + + def navigate_to_settings(self): + self.manager.transition.direction = 'left' + self.manager.current = 'settings' class SettingsScreen(Screen): - pass + def navigate_to_shopping_list(self): + self.manager.transition.direction = 'right' + self.manager.current = 'shopping' -class MainPage(BoxLayout): - pass - -class ShoppingListApp(App): +class ShoppingListApp(MDApp): def build(self): + self.theme_cls.primary_palette = "Teal" + self.theme_cls.theme_style = "Light" self.title = 'Shopping List App' - return MainPage() - + + sm = ScreenManager() + sm.add_widget(ShoppingEntryScreen(name='shopping')) + sm.add_widget(SettingsScreen(name='settings')) + + return sm + if __name__ == "__main__": app = ShoppingListApp() app.run() diff --git a/src/shoppinglist.kv b/src/shoppinglist.kv index e7d7ef5..3925f03 100644 --- a/src/shoppinglist.kv +++ b/src/shoppinglist.kv @@ -1,86 +1,121 @@ : - orientation: 'horizontal' - CheckBox: - active: root.is_checked - Label: - text: root.text - Button: - background_normal: 'res/delete.png' + id: shopping_entry + markup: True - - id: float_root # Giving id to button - size_hint: (None, None) - text: '' - btn_size: (70, 70) - size: (70, 70) - bg_color: (0.404, 0.227, 0.718, 1.0) - - # Adding shape and all, size, position to button - Button: - text: float_root.text - markup: True - font_size: 40 - size_hint: (None, None) - size: float_root.btn_size - pos_hint: {'right': 8.5, 'top': 1.25} - background_normal: '' - background_color: (0, 0, 0, 0) - canvas.before: - Color: - rgba: (0.3, 0.5, 0.2, 1.0) - Ellipse: - size: self.size - pos: self.pos + ImageLeftWidget: + MDCheckbox: + id: shopping_entry_check + # bind to property -: - shop: shop + IconRightWidget: + icon: 'res/delete.png' + on_release: root.delete(shopping_entry) - name: 'main' - MainTitleBar: - BoxLayout: - id: shop +: + size_hint: 1, None + height: '40dp' + orientation: 'vertical' + spacing: '5dp' + + MDTextField: + id: shopping_entry_text + pos_hint: { 'center_y': 0.4 } + # SPRACHE + hint_text: 'Neuer Eintrag' + +: + MDBoxLayout: orientation: 'vertical' - FloatButton: - text: '+' - markup: True - background_color: 1, 0, 1, 0 + pos_hint: { 'center_x': 0.5, 'center_y': 0.5 } + + MDTopAppBar: + #SPRACHE + title: 'Shopping-List-App' + md_bg_color: app.theme_cls.primary_color + specific_text_color: '#000000' + right_action_items: [['res/settings.png', lambda x: root.navigate_to_settings()]] + + ScrollView: + size_hint: 0.85, 0.85 + pos_hint: { 'center_y': 1, 'center_x': 0.5 } + MDList: + id: shopping_list + + MDFloatingActionButton: + icon: 'plus' + elevation_normal: 5 + pos_hint: { 'center_x': 0.925, 'center_y': 0.05 } + on_release: root.open_add_popup() : - name: 'settings' - SettingsTitleBar: - Label: - text: 'hi settings' + MDBoxLayout: + orientation: 'vertical' + MDTopAppBar: + #SPRACHE + title: 'Shopping-List-App' + md_bg_color: app.theme_cls.primary_color + specific_text_color: '#000000' + left_action_items: [['res/arrow_back.png', lambda x: root.navigate_to_shopping_list()]] -: - pos_hint: {'top':1} - ActionView: - ActionPrevious: - title: 'Shopping Liste' - app_icon: 'res/shopping_bag.png' - with_previous: False - ActionButton: - text: 'Sort' - icon: 'res/filter_list.png' - ActionButton: - text: 'Settings' - icon: 'res/settings.png' - on_release: - app.root.ids.sm.current = 'settings' - app.root.ids.sm.transition.direction = 'left' + MDBoxLayout: + orientation: 'horizontal' + pos_hint: { 'center_x': 0.5 } + size_hint: (0.5, 0.25) + # SPRACHE + MDLabel: + text: 'Sprache' + MDDropDownItem: + id: language_drop_down + text: 'Deutsch' -: - pos_hint: {'top':1} - ActionView: - ActionPrevious: - title: 'Einstellungen' - app_icon: 'res/settings.png' - on_release: - app.root.ids.sm.current = 'main' - app.root.ids.sm.transition.direction = 'right' + MDBoxLayout: + orientation: 'horizontal' + pos_hint: { 'center_x': 0.5 } + size_hint: (0.5, 0.25) + # SPRACHE + MDLabel: + text: 'Theme' + MDSwitch: + width: dp(36) + + MDBoxLayout: + orientation: 'horizontal' + pos_hint: { 'center_x': 0.5 } + size_hint: (0.5, 0.25) + # SPRACHE + MDLabel: + text: 'MQTT-Server' + MDTextField: + hint_text: 'mqtt.server.de' + + MDBoxLayout: + orientation: 'horizontal' + pos_hint: { 'center_x': 0.5 } + size_hint: (0.5, 0.25) + # SPRACHE + MDLabel: + text: 'MQTT-Topic' + MDTextField: + hint_text: 'topic' + + MDBoxLayout: + orientation: 'horizontal' + pos_hint: { 'center_x': 0.5 } + size_hint: (0.5, 0.25) + # SPRACHE + MDLabel: + text: 'MQTT-Benutzername' + MDTextField: + hint_text: 'username' + + MDBoxLayout: + orientation: 'horizontal' + pos_hint: { 'center_x': 0.5 } + size_hint: (0.5, 0.25) + # SPRACHE + MDLabel: + text: 'MQTT-Passwort' + MDTextField: + password: True -: - ScreenManager: - id: sm - MainScreen: - SettingsScreen