class SettingThemePicker(SettingItem): '''Implementation of a MDThemePicker setting on top of a :class:`SettingItem`. It is visualized with a :class:`~kivy.uix.label.Label` widget that, when clicked, will open a :class:`~kivymd.pickers.MDThemePicker` so the user can select customs colors. ''' md_theme_picker = ObjectProperty(None) '''(internal) Used to store the current MDThemePicker and to listen for changes. :attr:`md_theme_picker` is an :class:`~kivy.properties.ObjectProperty` and defaults to None. ''' def on_panel(self, instance, value): if value is None: return self.bind(on_release=self._theme_picker_open) def _theme_picker_open(self, instance): if not self.md_theme_picker: self.md_theme_picker = MDThemePicker() self.md_theme_picker.bind(on_dismiss=self._validate) self.md_theme_picker.open() def _validate(self, instance): #value = self.textinput.text.strip() value = self.md_theme_picker.theme_cls.theme_style\ + ", " + self.md_theme_picker.theme_cls.primary_palette\ +", " + self.md_theme_picker.theme_cls.accent_palette self.value = value
class MainFrame(Screen): def __init__(self, **kw): super().__init__(**kw) self.create_stack_floating_buttons = False self.md_theme_picker = None def on_enter(self): from kivymd.stackfloatingbuttons import MDStackFloatingButtons def set_my_language(instance_button): toast(instance_button.icon) if not self.create_stack_floating_buttons: screen = self.parent.get_screen("MainFrame") screen.add_widget( MDStackFloatingButtons( icon="lead-pencil", floating_data={ "Create New Data": "new-box", "Delete": "delete-circle", "Edit": "circle-edit-outline", }, callback=set_my_language, ) ) self.create_stack_floating_buttons = True def show_screen(self, screen_name): if screen_name == "Log Out": screen_manager = self.parent screen_manager.transition = NoTransition() print(screen_manager.current) screen_manager.current = "login" return screen_manager = self.ids['scr_mngr'] screen_manager.transition = NoTransition() screen_manager.current = screen_name def theme_picker_open(self): if not self.md_theme_picker: from kivymd.pickers import MDThemePicker self.md_theme_picker = MDThemePicker() self.md_theme_picker.open()
def theme_picker_open(self): if not self.md_theme_picker: from kivymd.pickers import MDThemePicker self.md_theme_picker = MDThemePicker() self.md_theme_picker.open()
class KitchenSink(App, Screens): theme_cls = ThemeManager() theme_cls.primary_palette = 'Blue' previous_date = ObjectProperty() title = "Kitchen Sink" # theme_cls.theme_style = 'Dark' def __init__(self, **kwargs): super(KitchenSink, self).__init__(**kwargs) self.menu_items = [{ 'viewclass': 'MDMenuItem', 'text': 'Example item %d' % i, 'callback': self.callback_for_menu_items } for i in range(15)] self.Window = Window self.manager = None self.md_app_bar = None self.instance_menu_demo_apps = None self.md_theme_picker = None self.long_dialog = None self.input_dialog = None self.alert_dialog = None self.ok_cancel_dialog = None self.long_dialog = None self.dialog = None self.manager_open = False self.cards_created = False self.user_card = None self.bs_menu_1 = None self.bs_menu_2 = None self.my_snackbar = None self._interval = 0 self.tick = 0 self.create_stack_floating_buttons = False self.previous_text = \ "Welcome to the application [b][color={COLOR}]Kitchen Sink"\ "[/color][/b].\nTo see [b][color={COLOR}]KivyMD[/color][/b] "\ "examples, open the menu and select from the list the desired "\ "example or".format(COLOR=get_hex_from_color( self.theme_cls.primary_color)) self.previous_text_end = \ "for show example apps\n\n"\ "Author - [b][color={COLOR}]Andrés Rodríguez[/color][/b]\n"\ "[u][b][color={COLOR}][email protected][/color]"\ "[/b][/u]\n\n"\ "Author this Fork - [b][color={COLOR}]Ivanov Yuri[/color][/b]\n"\ "[u][b][color={COLOR}][email protected][/color]"\ "[/b][u]".format(COLOR=get_hex_from_color( self.theme_cls.primary_color)) self.names_contacts = ('Alexandr Taylor', 'Yuri Ivanov', 'Robert Patric', 'Bob Marley', 'Magnus Carlsen', 'Jon Romero', 'Anna Bell', 'Maxim Kramerer', 'Sasha Gray', 'Vladimir Ivanenko') self.demo_apps_list = ['Shop Window'] self.menu_for_demo_apps = [] Window.bind(on_keyboard=self.events) crop_image( (Window.width, int(dp(Window.height * 35 // 100))), '{}/assets/guitar-1139397_1280.png'.format(self.directory), '{}/assets/guitar-1139397_1280_crop.png'.format(self.directory)) def crop_image_for_tile(self, instance, size, path_to_crop_image): if not os.path.exists(os.path.join(self.directory, path_to_crop_image)): size = (int(size[0]), int(size[1])) path_to_origin_image = path_to_crop_image.replace('_tile_crop', '') crop_image(size, path_to_origin_image, path_to_crop_image) instance.source = path_to_crop_image def theme_picker_open(self): if not self.md_theme_picker: from kivymd.pickers import MDThemePicker self.md_theme_picker = MDThemePicker() self.md_theme_picker.open() def example_add_stack_floating_buttons(self): from kivymd.stackfloatingbuttons import MDStackFloatingButtons def set_my_language(instance_button): toast(instance_button.icon) if not self.create_stack_floating_buttons: screen = self.main_widget.ids.scr_mngr.get_screen('stack buttons') screen.add_widget( MDStackFloatingButtons(icon='lead-pencil', floating_data={ 'Python': 'language-python', 'Php': 'language-php', 'C++': 'language-cpp' }, callback=set_my_language)) self.create_stack_floating_buttons = True def set_accordion_list(self): from kivymd.accordionlistitem import MDAccordionListItem def callback(text): toast('{} to {}'.format(text, content.name_item)) content = ContentForAnimCard(callback=callback) for name_contact in self.names_contacts: self.accordion_list.ids.anim_list.add_widget( MDAccordionListItem(content=content, icon='assets/kivymd_logo.png', title=name_contact)) def set_chevron_back_screen(self): """Sets the return chevron to the previous screen in ToolBar.""" self.main_widget.ids.toolbar.right_action_items = [[ 'dots-vertical', lambda x: self.root.toggle_nav_drawer() ]] def download_progress_hide(self, instance_progress, value): """Hides progress progress.""" self.main_widget.ids.toolbar.right_action_items =\ [['download', lambda x: self.download_progress_show(instance_progress)]] def download_progress_show(self, instance_progress): self.set_chevron_back_screen() instance_progress.open() instance_progress.animation_progress_from_fade() def show_example_download_file(self, interval): from kivymd.progressloader import MDProgressLoader def get_connect(host="8.8.8.8", port=53, timeout=3): import socket try: socket.setdefaulttimeout(timeout) socket.socket(socket.AF_INET, socket.SOCK_STREAM).connect( (host, port)) return True except (TimeoutError, ConnectionError, OSError): return False if get_connect(): link = 'https://www.python.org/ftp/python/3.5.1/'\ 'python-3.5.1-embed-win32.zip' progress = MDProgressLoader( url_on_image=link, path_to_file=os.path.join(self.directory, 'python-3.5.1.zip'), download_complete=self.download_complete, download_hide=self.download_progress_hide) progress.start(self.download_file.ids.box_flt) else: toast('Connect error!') def download_complete(self): self.set_chevron_back_screen() toast('Done') def file_manager_open(self): from kivymd.filemanager import MDFileManager from kivymd.dialog import MDDialog def open_file_manager(text_item, dialog): previous = False if text_item == 'List' else True self.manager = ModalView(size_hint=(1, 1), auto_dismiss=False) self.file_manager = MDFileManager(exit_manager=self.exit_manager, select_path=self.select_path, previous=previous) self.manager.add_widget(self.file_manager) self.file_manager.show(self.user_data_dir) self.manager_open = True self.manager.open() MDDialog(title='Title', size_hint=(.8, .4), text_button_ok='List', text="Open manager with 'list' or 'previous' mode?", text_button_cancel='Previous', events_callback=open_file_manager).open() def select_path(self, path): """It will be called when you click on the file name or the catalog selection button. :type path: str; :param path: path to the selected directory or file; """ self.exit_manager() toast(path) def exit_manager(self, *args): """Called when the user reaches the root of the directory tree.""" self.manager.dismiss() self.manager_open = False self.set_chevron_menu() def set_chevron_menu(self): self.main_widget.ids.toolbar.left_action_items = [[ 'menu', lambda x: self.root.toggle_nav_drawer() ]] def events(self, instance, keyboard, keycode, text, modifiers): """Called when buttons are pressed on the mobile device..""" if keyboard in (1001, 27): if self.manager_open: self.file_manager.back() return True def callback_for_menu_items(self, *args): toast(args[0]) def add_cards(self, instance_grid_card): from kivymd.cards import MDCardPost def callback(instance, value): if value is None: toast('Delete post %s' % str(instance)) elif isinstance(value, int): toast('Set like in %d stars' % value) elif isinstance(value, str): toast('Repost with %s ' % value) elif isinstance(value, list): toast(value[1]) if not self.cards_created: self.cards_created = True menu_items = [{ 'viewclass': 'MDMenuItem', 'text': 'Example item %d' % i, 'callback': self.callback_for_menu_items } for i in range(2)] buttons = ['facebook', 'vk', 'twitter'] instance_grid_card.add_widget( MDCardPost(text_post='Card with text', swipe=True, callback=callback)) instance_grid_card.add_widget( MDCardPost( right_menu=menu_items, swipe=True, text_post='Card with a button to open the menu MDDropDown', callback=callback)) instance_grid_card.add_widget( MDCardPost(likes_stars=True, callback=callback, swipe=True, text_post='Card with asterisks for voting.')) instance_grid_card.add_widget( MDCardPost( source="./assets/kitten-1049129_1280.png", tile_text="Little Baby", tile_font_style="H5", text_post="This is my favorite cat. He's only six months " "old. He loves milk and steals sausages :) " "And he likes to play in the garden.", with_image=True, swipe=True, callback=callback, buttons=buttons)) def update_screen(self, instance): def update_screen(interval): self.tick += 1 if self.tick > 2: instance.update = True self.tick = 0 self.update_spinner.ids.upd_lbl.text = "New string" Clock.unschedule(update_screen) Clock.schedule_interval(update_screen, 1) main_widget = None def build(self): self.main_widget = Builder.load_string(main_widget_kv) # self.bottom_navigation_remove_mobile(self.main_widget) return self.main_widget def set_popup_screen(self, content_popup): popup_menu = ContentForAnimCard() popup_menu.add_widget(Widget(size_hint_y=None, height=dp(150))) popup_screen = self.popup_screen.ids.popup_screen popup_screen.screen = popup_menu popup_screen.background_color = [.3, .3, .3, 1] popup_screen.max_height = content_popup.ids.image.height + dp(5) def bottom_navigation_remove_mobile(self, widget): # Removes some items from bottom-navigation demo when on mobile if DEVICE_TYPE == 'mobile': widget.ids.bottom_navigation_demo.remove_widget( widget.ids.bottom_navigation_desktop_2) if DEVICE_TYPE == 'mobile' or DEVICE_TYPE == 'tablet': widget.ids.bottom_navigation_demo.remove_widget( widget.ids.bottom_navigation_desktop_1) def show_user_example_animation_card(self): from kivymd.useranimationcard import MDUserAnimationCard def main_back_callback(): toast('Close card') if not self.user_card: self.user_card = MDUserAnimationCard( user_name="Lion Lion", path_to_avatar="./assets/guitar-1139397_1280.png", callback=main_back_callback) self.user_card.box_content.add_widget(ContentForAnimCard()) self.user_card.open() def show_example_snackbar(self, snack_type): def callback(instance): toast(instance.text) def wait_interval(interval): self._interval += interval if self._interval > self.my_snackbar.duration: anim = Animation(y=dp(10), d=.2) anim.start(self.snackbar.ids.button) Clock.unschedule(wait_interval) self._interval = 0 self.my_snackbar = None from kivymd.snackbars import Snackbar if snack_type == 'simple': Snackbar(text="This is a snackbar!").show() elif snack_type == 'button': Snackbar(text="This is a snackbar", button_text="with a button!", button_callback=callback).show() elif snack_type == 'verylong': Snackbar(text="This is a very very very very very very very " "long snackbar!").show() elif snack_type == 'float': if not self.my_snackbar: self.my_snackbar = Snackbar(text="This is a snackbar!", button_text='Button', duration=3, button_callback=callback) self.my_snackbar.show() anim = Animation(y=dp(72), d=.2) anim.bind(on_complete=lambda *args: Clock.schedule_interval( wait_interval, 0)) anim.start(self.snackbar.ids.button) def show_example_input_dialog(self): def result(text_button, instance): toast(instance.text_field.text) if not self.input_dialog: from kivymd.dialog import MDInputDialog self.input_dialog = MDInputDialog(title='Title', hint_text='Hint text', size_hint=(.8, .4), text_button_ok='Ok', events_callback=result) self.input_dialog.open() def show_example_alert_dialog(self): if not self.alert_dialog: from kivymd.dialog import MDDialog self.alert_dialog = MDDialog( title='Title', size_hint=(.8, .4), text_button_ok='Ok', text="This is Alert dialog", events_callback=self.callback_for_menu_items) self.alert_dialog.open() def show_example_ok_cancel_dialog(self): if not self.ok_cancel_dialog: from kivymd.dialog import MDDialog self.ok_cancel_dialog = MDDialog( title='Title', size_hint=(.8, .4), text_button_ok='Ok', text="This is Ok Cancel dialog", text_button_cancel='Cancel', events_callback=self.callback_for_menu_items) self.ok_cancel_dialog.open() def show_example_long_dialog(self): if not self.long_dialog: from kivymd.dialog import MDDialog self.long_dialog = MDDialog( text="Lorem ipsum dolor sit amet, consectetur adipiscing " "elit, sed do eiusmod tempor incididunt ut labore et " "dolore magna aliqua. Ut enim ad minim veniam, quis " "nostrud exercitation ullamco laboris nisi ut aliquip " "ex ea commodo consequat. Duis aute irure dolor in " "reprehenderit in voluptate velit esse cillum dolore eu " "fugiat nulla pariatur. Excepteur sint occaecat " "cupidatat non proident, sunt in culpa qui officia " "deserunt mollit anim id est laborum.", title='Title', size_hint=(.8, .4), text_button_ok='Yes', events_callback=self.callback_for_menu_items) self.long_dialog.open() def get_time_picker_date(self, instance, time): """Get date for MDTimePicker from the screen Pickers.""" self.pickers.ids.time_picker_label.text = str(time) self.previous_time = time def show_example_time_picker(self): """Show MDTimePicker from the screen Pickers.""" from kivymd.pickers import MDTimePicker time_dialog = MDTimePicker() time_dialog.bind(time=self.get_time_picker_date) if self.pickers.ids.time_picker_use_previous_time.active: try: time_dialog.set_time(self.previous_time) except AttributeError: pass time_dialog.open() def set_previous_date(self, date_obj): """Set previous date for MDDatePicker from the screen Pickers.""" self.previous_date = date_obj self.pickers.ids.date_picker_label.text = str(date_obj) def show_example_date_picker(self): """Show MDDatePicker from the screen Pickers.""" from kivymd.pickers import MDDatePicker if self.pickers.ids.date_picker_use_previous_date.active: pd = self.previous_date try: MDDatePicker(self.set_previous_date, pd.year, pd.month, pd.day).open() except AttributeError: MDDatePicker(self.set_previous_date).open() else: MDDatePicker(self.set_previous_date).open() def show_example_bottom_sheet(self): """Show menu from the screen BottomSheet.""" from kivymd.bottomsheet import MDListBottomSheet if not self.bs_menu_1: self.bs_menu_1 = MDListBottomSheet() self.bs_menu_1.add_item( "Here's an item with text only", lambda x: self. callback_for_menu_items("Here's an item with text only")) self.bs_menu_1.add_item("Here's an item with an icon", lambda x: self.callback_for_menu_items( "Here's an item with an icon"), icon='clipboard-account') self.bs_menu_1.add_item( "Here's another!", lambda x: self.callback_for_menu_items("Here's another!"), icon='nfc') self.bs_menu_1.open() def show_example_grid_bottom_sheet(self): """Show menu from the screen BottomSheet.""" if not self.bs_menu_2: from kivymd.bottomsheet import MDGridBottomSheet self.bs_menu_2 = MDGridBottomSheet() self.bs_menu_2.add_item( "Facebook", lambda x: self.callback_for_menu_items("Facebook"), icon_src='./assets/facebook-box.png') self.bs_menu_2.add_item( "YouTube", lambda x: self.callback_for_menu_items("YouTube"), icon_src='./assets/youtube-play.png') self.bs_menu_2.add_item( "Twitter", lambda x: self.callback_for_menu_items("Twitter"), icon_src='./assets/twitter.png') self.bs_menu_2.add_item( "Da Cloud", lambda x: self.callback_for_menu_items("Da Cloud"), icon_src='./assets/cloud-upload.png') self.bs_menu_2.add_item( "Camera", lambda x: self.callback_for_menu_items("Camera"), icon_src='./assets/camera.png') self.bs_menu_2.open() def set_title_toolbar(self, title): """Set string title in MDToolbar for the whole application.""" self.main_widget.ids.toolbar.title = title def set_appbar(self): """Create MDBottomAppBar for the screen BottomAppBar.""" from kivymd.toolbar import MDBottomAppBar def press_button(inctance): toast('Press Button') self.md_app_bar = MDBottomAppBar( md_bg_color=self.theme_cls.primary_color, left_action_items=[['menu', lambda x: x], ['clock', lambda x: x], ['dots-vertical', lambda x: x]], anchor='right', callback=press_button) def move_item_menu(self, anchor): """Sets icons in MDBottomAppBar for the screen BottomAppBar.""" md_app_bar = self.md_app_bar if md_app_bar.anchor != anchor: if len(md_app_bar.right_action_items): md_app_bar.left_action_items.append( md_app_bar.right_action_items[0]) md_app_bar.right_action_items = [] else: left_action_items = md_app_bar.left_action_items action_items = left_action_items[0:2] md_app_bar.right_action_items = [left_action_items[-1]] md_app_bar.left_action_items = action_items def set_error_message(self, *args): """Checks text of TextField with type "on_error" for the screen TextFields.""" if len(self.root.ids.text_field_error.text) == 2: self.root.ids.text_field_error.error = True else: self.root.ids.text_field_error.error = False def set_list_md_icons(self, text='', search=False): """Builds a list of icons for the screen MDIcons.""" def add_icon_item(name_icon): self.main_widget.ids.scr_mngr.get_screen( 'md icons').ids.rv.data.append({ 'viewclass': 'MDIconItemForMdIconsList', 'icon': name_icon, 'text': name_icon, 'callback': self.callback_for_menu_items }) self.main_widget.ids.scr_mngr.get_screen('md icons').ids.rv.data = [] for name_icon in md_icons.keys(): if search: if text in name_icon: add_icon_item(name_icon) else: add_icon_item(name_icon) def set_menu_for_demo_apps1(self): if not len(self.app.menu_for_demo_apps): for name_item in self.app.demo_apps_list: self.app.menu_for_demo_apps.append({ 'viewclass': 'OneLineListItem', 'text': name_item, 'on_release': lambda x=name_item: self.show_demo_apps(name_item) }) def on_pause(self): return True def on_stop(self): pass def open_settings(self, *args): return False
class Mergency(App, Designer): theme_cls = ThemeManager() theme_cls.accent_palette = 'Orange' previous_date = ObjectProperty() title = "Mergency" theme_cls.theme_style = 'Dark' def __init__(self, **kwargs): super().__init__(**kwargs) self.menu_items = [{ 'viewclass': 'MDMenuItem', 'text': 'Example item %d' % i, 'callback': self.callback_for_menu_items } for i in range(15)] self.Window = Window self.manager = None self.md_app_bar = None self.instance_menu_demo_apps = None self.md_theme_picker = None self.long_dialog = None self.input_dialog = None self.alert_dialog = None self.ok_cancel_dialog = None self.long_dialog = None self.dialog = None self.manager_open = False self.cards_created = False self.user_card = None self.bs_menu_1 = None self.bs_menu_2 = None self.my_snackbar = None self._interval = 0 self.tick = 0 self.create_stack_floating_buttons = False Window.bind(on_keyboard=self.events) crop_image( (Window.width, int(dp(Window.height * 35 // 100))), '{}/assets/guitar-1139397_1280.png'.format(self.directory), '{}/assets/guitar-1139397_1280_crop.png'.format(self.directory)) # DB Data ======================================================= self.db = None self.host = StringProperty(None) self.user = StringProperty(None) self.password = StringProperty(None) self.service = StringProperty(None) self.port = StringProperty(None) # TABS Data ===================================================== self.accidents = None self.hospitals = None self.ambulances = None self.doctors = None self.patients = None def crop_image_for_tile(self, instance, size, path_to_crop_image): """Crop images for Grid screen.""" if not os.path.exists(os.path.join(self.directory, path_to_crop_image)): size = (int(size[0]), int(size[1])) path_to_origin_image = path_to_crop_image.replace('_tile_crop', '') crop_image(size, path_to_origin_image, path_to_crop_image) instance.source = path_to_crop_image def theme_picker_open(self): if not self.md_theme_picker: from kivymd.pickers import MDThemePicker self.md_theme_picker = MDThemePicker() self.md_theme_picker.open() def example_add_stack_floating_buttons(self): from kivymd.stackfloatingbuttons import MDStackFloatingButtons def set_my_language(instance_button): toast(instance_button.icon) if not self.create_stack_floating_buttons: screen = self.main_widget.ids.scr_mngr.get_screen('stack buttons') screen.add_widget( MDStackFloatingButtons(icon='lead-pencil', floating_data={ 'Python': 'language-python', 'Php': 'language-php', 'C++': 'language-cpp' }, callback=set_my_language)) self.create_stack_floating_buttons = True def set_accordion_list(self): from kivymd.accordionlistitem import MDAccordionListItem def callback(text): toast('{} to {}'.format(text, content.name_item)) content = ContentForAnimCard(callback=callback) for name_contact in self.names_contacts: self.accordion_list.ids.anim_list.add_widget( MDAccordionListItem(content=content, icon='assets/kivymd_logo.png', title=name_contact)) def set_chevron_back_screen(self): """Sets the return chevron to the previous screen in ToolBar.""" self.main_widget.ids.toolbar.right_action_items = [[ 'dots-vertical', lambda x: self.root.toggle_nav_drawer() ]] def download_progress_hide(self, instance_progress, value): """Hides progress progress.""" self.main_widget.ids.toolbar.right_action_items =\ [['download', lambda x: self.download_progress_show(instance_progress)]] def download_progress_show(self, instance_progress): self.set_chevron_back_screen() instance_progress.open() instance_progress.animation_progress_from_fade() def show_example_download_file(self, interval): from kivymd.progressloader import MDProgressLoader def get_connect(host="8.8.8.8", port=53, timeout=3): import socket try: socket.setdefaulttimeout(timeout) socket.socket(socket.AF_INET, socket.SOCK_STREAM).connect( (host, port)) return True except (TimeoutError, ConnectionError, OSError): return False if get_connect(): link = 'https://www.python.org/ftp/python/3.5.1/'\ 'python-3.5.1-embed-win32.zip' progress = MDProgressLoader( url_on_image=link, path_to_file=os.path.join(self.directory, 'python-3.5.1.zip'), download_complete=self.download_complete, download_hide=self.download_progress_hide) progress.start(self.download_file.ids.box_flt) else: toast('Connect error!') def download_complete(self): self.set_chevron_back_screen() toast('Done') def file_manager_open(self): from kivymd.filemanager import MDFileManager from kivymd.dialog import MDDialog def open_file_manager(text_item, dialog): previous = False if text_item == 'List' else True self.manager = ModalView(size_hint=(1, 1), auto_dismiss=False) self.file_manager = MDFileManager(exit_manager=self.exit_manager, select_path=self.select_path, previous=previous) self.manager.add_widget(self.file_manager) self.file_manager.show(self.user_data_dir) self.manager_open = True self.manager.open() MDDialog(title='Title', size_hint=(.8, .4), text_button_ok='List', text="Open manager with 'list' or 'previous' mode?", text_button_cancel='Previous', events_callback=open_file_manager).open() def select_path(self, path): """It will be called when you click on the file name or the catalog selection button. :type path: str; :param path: path to the selected directory or file; """ self.exit_manager() toast(path) def exit_manager(self, *args): """Called when the user reaches the root of the directory tree.""" self.manager.dismiss() self.manager_open = False self.set_chevron_menu() def set_chevron_menu(self): self.main_widget.ids.toolbar.left_action_items = [[ 'menu', lambda x: self.root.toggle_nav_drawer() ]] def events(self, instance, keyboard, keycode, text, modifiers): """Called when buttons are pressed on the mobile device.""" if keyboard in (1001, 27): if self.manager_open: self.file_manager.back() return True def callback_for_menu_items(self, *args): toast(args[0]) def add_cards(self, instance_grid_card): """Adds MDCardPost objects to the screen Cards when the screen is open.""" from kivymd.cards import MDCardPost def callback(instance, value): if value is None: toast('Delete post %s' % str(instance)) elif isinstance(value, int): toast('Set like in %d stars' % value) elif isinstance(value, str): toast('Repost with %s ' % value) elif isinstance(value, list): toast(value[1]) if not self.cards_created: self.cards_created = True menu_items = [{ 'viewclass': 'MDMenuItem', 'text': 'Example item %d' % i, 'callback': self.callback_for_menu_items } for i in range(2)] buttons = ['facebook', 'vk', 'twitter'] instance_grid_card.add_widget( MDCardPost(text_post='Card with text', swipe=True, callback=callback)) instance_grid_card.add_widget( MDCardPost( right_menu=menu_items, swipe=True, text_post='Card with a button to open the menu MDDropDown', callback=callback)) instance_grid_card.add_widget( MDCardPost(likes_stars=True, callback=callback, swipe=True, text_post='Card with asterisks for voting.')) instance_grid_card.add_widget( MDCardPost( source="./assets/kitten-1049129_1280.png", tile_text="Little Baby", tile_font_style="H5", text_post="This is my favorite cat. He's only six months " "old. He loves milk and steals sausages :) " "And he likes to play in the garden.", with_image=True, swipe=True, callback=callback, buttons=buttons)) def update_screen(self, instance): """Set new label on the screen UpdateSpinner.""" def update_screen(interval): self.tick += 1 if self.tick > 2: instance.update = True self.tick = 0 self.update_spinner.ids.upd_lbl.text = "New string" Clock.unschedule(update_screen) Clock.schedule_interval(update_screen, 1) main_widget = None def set_popup_screen(self, content_popup): popup_menu = ContentForAnimCard() popup_menu.add_widget(Widget(size_hint_y=None, height=dp(150))) popup_screen = self.popup_screen.ids.popup_screen popup_screen.screen = popup_menu popup_screen.background_color = [.3, .3, .3, 1] popup_screen.max_height = content_popup.ids.image.height + dp(5) def show_user_example_animation_card(self): """Create and open instance MDUserAnimationCard for the screen UserCard.""" from kivymd.useranimationcard import MDUserAnimationCard def main_back_callback(): toast('Close card') if not self.user_card: self.user_card = MDUserAnimationCard( user_name="Lion Lion", path_to_avatar="./assets/guitar-1139397_1280.png", callback=main_back_callback) self.user_card.box_content.add_widget(ContentForAnimCard()) self.user_card.open() def show_example_snackbar(self, snack_type): """Create and show instance Snackbar for the screen MySnackBar.""" def callback(instance): toast(instance.text) def wait_interval(interval): self._interval += interval if self._interval > self.my_snackbar.duration: anim = Animation(y=dp(10), d=.2) anim.start(self.snackbar.ids.button) Clock.unschedule(wait_interval) self._interval = 0 self.my_snackbar = None from kivymd.snackbars import Snackbar if snack_type == 'simple': Snackbar(text="This is a snackbar!").show() elif snack_type == 'button': Snackbar(text="This is a snackbar", button_text="with a button!", button_callback=callback).show() elif snack_type == 'verylong': Snackbar(text="This is a very very very very very very very " "long snackbar!").show() elif snack_type == 'float': if not self.my_snackbar: self.my_snackbar = Snackbar(text="This is a snackbar!", button_text='Button', duration=3, button_callback=callback) self.my_snackbar.show() anim = Animation(y=dp(72), d=.2) anim.bind(on_complete=lambda *args: Clock.schedule_interval( wait_interval, 0)) anim.start(self.snackbar.ids.button) def show_example_input_dialog(self): """Creates an instance of the dialog box and displays it on the screen for the screen Dialogs.""" def result(text_button, instance): toast(instance.text_field.text) if not self.input_dialog: from kivymd.dialog import MDInputDialog self.input_dialog = MDInputDialog(title='Title', hint_text='Hint text', size_hint=(.8, .4), text_button_ok='Ok', events_callback=result) self.input_dialog.open() def show_example_alert_dialog(self): if not self.alert_dialog: from kivymd.dialog import MDDialog self.alert_dialog = MDDialog( title='Title', size_hint=(.8, .4), text_button_ok='Ok', text="This is Alert dialog", events_callback=self.callback_for_menu_items) self.alert_dialog.open() def show_example_ok_cancel_dialog(self): if not self.ok_cancel_dialog: from kivymd.dialog import MDDialog self.ok_cancel_dialog = MDDialog( title='Title', size_hint=(.8, .4), text_button_ok='Ok', text="This is Ok Cancel dialog", text_button_cancel='Cancel', events_callback=self.callback_for_menu_items) self.ok_cancel_dialog.open() def show_example_long_dialog(self): if not self.long_dialog: from kivymd.dialog import MDDialog self.long_dialog = MDDialog( text="Lorem ipsum dolor sit amet, consectetur adipiscing " "elit, sed do eiusmod tempor incididunt ut labore et " "dolore magna aliqua. Ut enim ad minim veniam, quis " "nostrud exercitation ullamco laboris nisi ut aliquip " "ex ea commodo consequat. Duis aute irure dolor in " "reprehenderit in voluptate velit esse cillum dolore eu " "fugiat nulla pariatur. Excepteur sint occaecat " "cupidatat non proident, sunt in culpa qui officia " "deserunt mollit anim id est laborum.", title='Title', size_hint=(.8, .4), text_button_ok='Yes', events_callback=self.callback_for_menu_items) self.long_dialog.open() def get_time_picker_date(self, instance, time): """Get date for MDTimePicker from the screen Pickers.""" self.pickers.ids.time_picker_label.text = str(time) self.previous_time = time def show_example_time_picker(self): """Show MDTimePicker from the screen Pickers.""" from kivymd.pickers import MDTimePicker time_dialog = MDTimePicker() time_dialog.bind(time=self.get_time_picker_date) if self.pickers.ids.time_picker_use_previous_time.active: try: time_dialog.set_time(self.previous_time) except AttributeError: pass time_dialog.open() def set_previous_date(self, date_obj): """Set previous date for MDDatePicker from the screen Pickers.""" self.previous_date = date_obj self.pickers.ids.date_picker_label.text = str(date_obj) def show_example_date_picker(self): """Show MDDatePicker from the screen Pickers.""" from kivymd.pickers import MDDatePicker if self.pickers.ids.date_picker_use_previous_date.active: pd = self.previous_date try: MDDatePicker(self.set_previous_date, pd.year, pd.month, pd.day).open() except AttributeError: MDDatePicker(self.set_previous_date).open() else: MDDatePicker(self.set_previous_date).open() def show_example_bottom_sheet(self): """Show menu from the screen BottomSheet.""" from kivymd.bottomsheet import MDListBottomSheet if not self.bs_menu_1: self.bs_menu_1 = MDListBottomSheet() self.bs_menu_1.add_item( "Here's an item with text only", lambda x: self. callback_for_menu_items("Here's an item with text only")) self.bs_menu_1.add_item("Here's an item with an icon", lambda x: self.callback_for_menu_items( "Here's an item with an icon"), icon='clipboard-account') self.bs_menu_1.add_item( "Here's another!", lambda x: self.callback_for_menu_items("Here's another!"), icon='nfc') self.bs_menu_1.open() def show_example_grid_bottom_sheet(self): """Show menu from the screen BottomSheet.""" if not self.bs_menu_2: from kivymd.bottomsheet import MDGridBottomSheet self.bs_menu_2 = MDGridBottomSheet() self.bs_menu_2.add_item( "Facebook", lambda x: self.callback_for_menu_items("Facebook"), icon_src='./assets/facebook-box.png') self.bs_menu_2.add_item( "YouTube", lambda x: self.callback_for_menu_items("YouTube"), icon_src='./assets/youtube-play.png') self.bs_menu_2.add_item( "Twitter", lambda x: self.callback_for_menu_items("Twitter"), icon_src='./assets/twitter.png') self.bs_menu_2.add_item( "Da Cloud", lambda x: self.callback_for_menu_items("Da Cloud"), icon_src='./assets/cloud-upload.png') self.bs_menu_2.add_item( "Camera", lambda x: self.callback_for_menu_items("Camera"), icon_src='./assets/camera.png') self.bs_menu_2.open() def set_title_toolbar(self, title): """Set string title in MDToolbar for the whole application.""" self.main_widget.ids.toolbar.title = title def set_appbar(self): """Create MDBottomAppBar for the screen BottomAppBar.""" from kivymd.toolbar import MDBottomAppBar def press_button(inctance): toast('Press Button') self.md_app_bar = MDBottomAppBar( md_bg_color=self.theme_cls.primary_color, left_action_items=[['menu', lambda x: x], ['clock', lambda x: x], ['dots-vertical', lambda x: x]], anchor='right', callback=press_button) def move_item_menu(self, anchor): """Sets icons in MDBottomAppBar for the screen BottomAppBar.""" md_app_bar = self.md_app_bar if md_app_bar.anchor != anchor: if len(md_app_bar.right_action_items): md_app_bar.left_action_items.append( md_app_bar.right_action_items[0]) md_app_bar.right_action_items = [] else: left_action_items = md_app_bar.left_action_items action_items = left_action_items[0:2] md_app_bar.right_action_items = [left_action_items[-1]] md_app_bar.left_action_items = action_items def set_error_message(self, *args): """Checks text of TextField with type "on_error" for the screen TextFields.""" text_field_error = args[0] if len(text_field_error.text) == 2: text_field_error.error = True else: text_field_error.error = False def set_list_md_icons(self, text='', search=False): """Builds a list of icons for the screen MDIcons.""" def add_icon_item(name_icon): self.main_widget.ids.scr_mngr.get_screen( 'md icons').ids.rv.data.append({ 'viewclass': 'MDIconItemForMdIconsList', 'icon': name_icon, 'text': name_icon, 'callback': self.callback_for_menu_items }) self.main_widget.ids.scr_mngr.get_screen('md icons').ids.rv.data = [] for name_icon in md_icons.keys(): if search: if text in name_icon: add_icon_item(name_icon) else: add_icon_item(name_icon) def set_menu_for_demo_apps(self): if not len(self.menu_for_demo_apps): for name_item in self.demo_apps_list: self.menu_for_demo_apps.append({ 'viewclass': 'OneLineListItem', 'text': name_item, 'on_release': lambda x=name_item: self.show_demo_apps(x) }) def show_demo_apps(self, name_item): name_item = name_item.lower() { 'coffee menu': self.show_coffee_menu, 'shop window': self.show_shop_window, 'registration': self.show_registration_form_one, 'fitness club': self.show_fitness_club }[name_item]() self.main_widget.ids.scr_mngr.current = name_item self.instance_menu_demo_apps.dismiss() # CUSTOM ======================================================================== def button_connect(self, host, service, port, user, password): self.db = Database(host, service, port, user, password) self.db.connect() return def button_disconnect(self): if (self.db != None): self.db.disconnect() self.db = None else: pass return def dummy_push(self): if (self.db != None): self.db.init_tables(DB_SCHEMA) self.db.dummy_insert() self.db.dummy_select() else: pass return def dummy_pop(self): if (self.db != None): self.db.rollback_tables(DB_SCHEMA) else: pass return def remove_cards(self, tab): if (len(tab.children) != 0): tab.clear_widgets() else: pass return # IMPORTANT # Need to separate these methods into update and refresh for correct # content management, at this moment everytime a tab is accesed it # just adds again the content of the DB table over the old one! # FIX ASAP! def get_accidents(self, instance_grid_card): print( "ACCIDENTS --------------------------------------------------------------" ) """Adds MDCardPost objects to the screen Cards when the screen is open.""" from kivymd.cards import MDCardPost def callback(instance, value): if value is None: toast('Delete post %s' % str(instance)) elif isinstance(value, int): toast('Set like in %d stars' % value) elif isinstance(value, str): toast('Repost with %s ' % value) elif isinstance(value, list): toast(value[1]) menu_items = [{ 'viewclass': 'MDMenuItem', 'text': 'Remove', 'callback': self.callback_for_menu_items } for _ in range(1)] # Implement a method to check empty tables and change above! if (self.db != None): try: self.accidents = self.db.get_info("Accident", "*") except Exception as ex: print(ex) return for _ in range(len(self.accidents)): instance_grid_card.add_widget( MDCardPost( right_menu=menu_items, swipe=True, name_data= f"County: {self.accidents[_][1]}\nID: {self.accidents[_][0]}\nAdress: {self.accidents[_][2]}\nDetails: {self.accidents[_][3]}", tile_font_style='H4', path_to_avatar="assets/m_tab_accidents.png", card_size=(Window.width, Window.height - 480), text_post="", callback=callback)) else: pass # Implement to add here a Label to say that the DB table is empty return def get_hospitals(self, instance_grid_card): print( "HOSPITALS --------------------------------------------------------------" ) """Adds MDCardPost objects to the screen Cards when the screen is open.""" from kivymd.cards import MDCardPost def callback(instance, value): if value is None: toast('Delete post %s' % str(instance)) elif isinstance(value, int): toast('Set like in %d stars' % value) elif isinstance(value, str): toast('Repost with %s ' % value) elif isinstance(value, list): toast(value[1]) menu_items = [{ 'viewclass': 'MDMenuItem', 'text': 'Remove', 'callback': self.callback_for_menu_items } for _ in range(1)] # Implement a method to check empty tables and change above! if (self.db != None): try: self.hospitals = self.db.get_info("Hospital", "*") except Exception as ex: print(ex) return for _ in range(len(self.hospitals)): instance_grid_card.add_widget( MDCardPost( right_menu=menu_items, swipe=True, name_data= f"{self.hospitals[_][1]}\nID: {self.hospitals[_][0]}\nAdress: {self.hospitals[_][2]}\n", tile_font_style='H4', path_to_avatar="assets/m_tab_hospitals.png", card_size=(Window.width, Window.height - 480), text_post="", callback=callback)) else: pass # Implement to add here a Label to say that the DB table is empty return def get_ambulances(self, instance_grid_card): print( "AMBULANCES -------------------------------------------------------------" ) """Adds MDCardPost objects to the screen Cards when the screen is open.""" from kivymd.cards import MDCardPost def callback(instance, value): if value is None: toast('Delete post %s' % str(instance)) elif isinstance(value, int): toast('Set like in %d stars' % value) elif isinstance(value, str): toast('Repost with %s ' % value) elif isinstance(value, list): toast(value[1]) menu_items = [{ 'viewclass': 'MDMenuItem', 'text': 'Remove', 'callback': self.callback_for_menu_items } for _ in range(1)] # Implement a method to check empty tables and change above! if (self.db != None): try: self.ambulances = self.db.get_info("Ambulance", "*") except Exception as ex: print(ex) return for _ in range(len(self.ambulances)): # 706F6F # FFAA00 if (self.ambulances[_][4] == 0): s = "assets/m_tab_ambulances_0.png" elif (self.ambulances[_][4] == 1): s = "assets/m_tab_ambulances_1.png" else: s = "assets/m_tab_ambulances_1.png" instance_grid_card.add_widget( MDCardPost( right_menu=menu_items, swipe=True, name_data= f"{self.ambulances[_][2]}\nID: {self.ambulances[_][0]}", tile_font_style='H4', path_to_avatar=s, card_size=(Window.width, Window.height - 480), text_post= f"Producer: {self.ambulances[_][1]}\nCapacity: {self.ambulances[_][3]} persons", callback=callback)) else: pass # Implement to add here a Label to say that the DB table is empty return def get_doctors(self, instance_grid_card): print( "DOCTORS ----------------------------------------------------------------" ) """Adds MDCardPost objects to the screen Cards when the screen is open.""" from kivymd.cards import MDCardPost def callback(instance, value): if value is None: toast('Delete post %s' % str(instance)) elif isinstance(value, int): toast('Set like in %d stars' % value) elif isinstance(value, str): toast('Repost with %s ' % value) elif isinstance(value, list): toast(value[1]) menu_items = [{ 'viewclass': 'MDMenuItem', 'text': 'Remove', 'callback': self.callback_for_menu_items } for _ in range(1)] # Implement a method to check empty tables and change above! if (self.db != None): try: self.doctors = self.db.get_info("Doctor", "*") except Exception as ex: print(ex) return for _ in range(len(self.doctors)): if (self.doctors[_][3] == "M"): s = "assets/m_tab_doctors_m.png" elif (self.doctors[_][3] == "F"): s = "assets/m_tab_doctors_f.png" else: s = "assets/m_tab_doctors_m.png" instance_grid_card.add_widget( MDCardPost( right_menu=menu_items, swipe=True, name_data= f"{self.doctors[_][2]} {self.doctors[_][1]} ({self.doctors[_][3]})\nID: {self.doctors[_][0]}", tile_font_style='H4', path_to_avatar=s, card_size=(Window.width, Window.height - 480), text_post=f"Birthday: {self.doctors[_][4]}", callback=callback)) else: pass # Implement to add here a Label to say that the DB table is empty return def get_patients(self, instance_grid_card): print( "PATIENTS ---------------------------------------------------------------" ) """Adds MDCardPost objects to the screen Cards when the screen is open.""" from kivymd.cards import MDCardPost def callback(instance, value): if value is None: toast('Delete post %s' % str(instance)) elif isinstance(value, int): toast('Set like in %d stars' % value) elif isinstance(value, str): toast('Repost with %s ' % value) elif isinstance(value, list): toast(value[1]) menu_items = [{ 'viewclass': 'MDMenuItem', 'text': 'Remove', 'callback': self.callback_for_menu_items } for _ in range(1)] # Implement a method to check empty tables and change above! if (self.db != None): try: self.patients = self.db.get_info("Patient", "*") except Exception as ex: print(ex) return for _ in range(len(self.patients)): if (self.patients[_][3] == "M"): s = "assets/m_tab_pacients_m.png" elif (self.patients[_][3] == "F"): s = "assets/m_tab_pacients_f.png" else: s = "assets/m_tab_pacients_m.png" instance_grid_card.add_widget( MDCardPost( right_menu=menu_items, swipe=True, name_data= f"{self.patients[_][2]} {self.patients[_][1]} ({self.patients[_][3]})\nID: {self.patients[_][0]}", tile_font_style='H4', path_to_avatar=s, card_size=(Window.width, Window.height - 480), text_post= f"Birthday: {self.patients[_][4]}\nBlood Type: {self.patients[_][5]}\nRH: {self.patients[_][6]}", callback=callback)) else: pass # Implement to add here a Label to say that the DB table is empty return # CUSTOM ======================================================================== def build(self): self.main_widget = Builder.load_file( os.path.join(os.path.dirname(__file__), "./Mergency.kv")) return self.main_widget def on_pause(self): return True def on_stop(self): pass def open_settings(self, *args): return False
def _theme_picker_open(self, instance): if not self.md_theme_picker: self.md_theme_picker = MDThemePicker() self.md_theme_picker.bind(on_dismiss=self._validate) self.md_theme_picker.open()
class KitchenSink(App, Screens): theme_cls = ThemeManager() theme_cls.primary_palette = "BlueGray" theme_cls.accent_palette = "Gray" previous_date = ObjectProperty() title = "Kitchen Sink" theme_cls.theme_style = "Dark" def __init__(self, **kwargs): super().__init__(**kwargs) self.menu_items = [{ "viewclass": "MDMenuItem", "text": "Example item %d" % i, "callback": self.callback_for_menu_items, } for i in range(15)] self.Window = Window self.manager = None self.md_app_bar = None self.instance_menu_demo_apps = None self.md_theme_picker = None self.long_dialog = None self.input_dialog = None self.alert_dialog = None self.ok_cancel_dialog = None self.long_dialog = None self.dialog = None self.manager_open = False self.cards_created = False self.user_card = None self.bs_menu_1 = None self.bs_menu_2 = None self.my_snackbar = None self._interval = 0 self.tick = 0 self.x = 0 self.y = 25 self.create_stack_floating_buttons = False self.hex_primary_color = get_hex_from_color( self.theme_cls.primary_color) self.previous_text = ( f"Welcome to the application [b][color={self.hex_primary_color}]" f"Kitchen Sink[/color][/b].\nTo see [b]" f"[color={self.hex_primary_color}]KivyMD[/color][/b] " f"examples, open the menu and select from the list the desired " f"example or") self.previous_text_end = ( f"for show example apps\n\n" f"Author - [b][color={self.hex_primary_color}]" f"Andrés Rodríguez[/color][/b]\n" f"[u][b][color={self.hex_primary_color}]" f"[email protected][/color][/b][/u]\n\n" f"Author this Fork - [b][color={self.hex_primary_color}]" f"Ivanov Yuri[/color][/b]\n" f"[u][b][color={self.hex_primary_color}]" f"[email protected][/color][/b][u]") self.names_contacts = ( "Alexandr Taylor", "Yuri Ivanov", "Robert Patric", "Bob Marley", "Magnus Carlsen", "Jon Romero", "Anna Bell", "Maxim Kramerer", "Sasha Gray", "Vladimir Ivanenko", ) self.demo_apps_list = [ "Shop Window", "Coffee Menu", "Fitness Club", "Registration", "Account Page", ] self.menu_for_demo_apps = [] self.list_name_icons = list(md_icons.keys())[0:15] Window.bind(on_keyboard=self.events) crop_image( (Window.width, int(dp(Window.height * 35 // 100))), f"{self.directory}/assets/guitar-1139397_1280.png", f"{self.directory}/assets/guitar-1139397_1280_crop.png", ) def set_list_for_refresh_layout(self): async def set_list_for_refresh_layout(): names_icons_list = list(md_icons.keys())[self.x:self.y] for name_icon in names_icons_list: await asynckivy.sleep(0) self.data["Refresh Layout"]["object"].ids.box.add_widget( ItemForListRefreshLayout(icon=name_icon, text=name_icon)) self.data["Refresh Layout"][ "object"].ids.refresh_layout.refresh_done() asynckivy.start(set_list_for_refresh_layout()) def refresh_callback(self, *args): """A method that updates the state of your application while the spinner remains on the screen.""" def refresh_callback(interval): self.data["Refresh Layout"]["object"].ids.box.clear_widgets() if self.x == 0: self.x, self.y = 25, 50 else: self.x, self.y = 0, 25 self.set_list_for_refresh_layout() self.tick = 0 Clock.schedule_once(refresh_callback, 1) def build_tabs(self): for name_tab in self.list_name_icons: tab = Factory.MyTab(text=name_tab) self.data["Tabs"]["object"].ids.android_tabs.add_widget(tab) def switch_tabs_to_icon(self, istance_android_tabs): for i, instance_tab in enumerate( istance_android_tabs.ids.scrollview.children[0].children): istance_android_tabs.ids.scrollview.children[0].remove_widget( instance_tab) istance_android_tabs.add_widget( Factory.MyTab(text=self.list_name_icons[i])) def switch_tabs_to_text(self, istance_android_tabs): for instance_tab in istance_android_tabs.ids.scrollview.children[ 0].children: for k, v in md_icons.items(): if v == instance_tab.text: istance_android_tabs.ids.scrollview.children[ 0].remove_widget(instance_tab) istance_android_tabs.add_widget( Factory.MyTab( text=" ".join(k.split("-")).capitalize())) break def crop_image_for_tile(self, instance, size, path_to_crop_image): """Crop images for Grid screen.""" if not os.path.exists(os.path.join(self.directory, path_to_crop_image)): size = (int(size[0]), int(size[1])) path_to_origin_image = path_to_crop_image.replace("_tile_crop", "") crop_image(size, path_to_origin_image, path_to_crop_image) instance.source = path_to_crop_image def theme_picker_open(self): if not self.md_theme_picker: from kivymd.pickers import MDThemePicker self.md_theme_picker = MDThemePicker() self.md_theme_picker.open() def example_add_stack_floating_buttons(self): from kivymd.stackfloatingbuttons import MDStackFloatingButtons def set_my_language(instance_button): toast(instance_button.icon) if not self.create_stack_floating_buttons: screen = self.main_widget.ids.scr_mngr.get_screen("stack buttons") screen.add_widget( MDStackFloatingButtons( icon="lead-pencil", floating_data={ "Python": "language-python", "Php": "language-php", "C++": "language-cpp", }, callback=set_my_language, )) self.create_stack_floating_buttons = True def set_accordion_list(self): from kivymd.accordionlistitem import MDAccordionListItem def callback(text): toast(f"{text} to {content.name_item}") content = ContentForAnimCard(callback=callback) for name_contact in self.names_contacts: self.data["Accordion List"]["object"].ids.anim_list.add_widget( MDAccordionListItem( content=content, icon="assets/kivy-logo-white-512.png", title=name_contact, )) def set_chevron_back_screen(self): """Sets the return chevron to the previous screen in ToolBar.""" self.main_widget.ids.toolbar.right_action_items = [[ "dots-vertical", lambda x: self.root.toggle_nav_drawer() ]] def download_progress_hide(self, instance_progress, value): """Hides progress progress.""" self.main_widget.ids.toolbar.right_action_items = [[ "download", lambda x: self.download_progress_show(instance_progress), ]] def download_progress_show(self, instance_progress): self.set_chevron_back_screen() instance_progress.open() instance_progress.animation_progress_from_fade() def show_example_download_file(self, interval): from kivymd.progressloader import MDProgressLoader def get_connect(host="8.8.8.8", port=53, timeout=3): import socket try: socket.setdefaulttimeout(timeout) socket.socket(socket.AF_INET, socket.SOCK_STREAM).connect( (host, port)) return True except (TimeoutError, ConnectionError, OSError): return False if get_connect(): link = ("https://www.python.org/ftp/python/3.5.1/" "python-3.5.1-embed-win32.zip") progress = MDProgressLoader( url_on_image=link, path_to_file=os.path.join(self.directory, "python-3.5.1.zip"), download_complete=self.download_complete, download_hide=self.download_progress_hide, ) progress.start(self.data["Download File"]["object"].ids.box_flt) else: toast("Connect error!") def download_complete(self): self.set_chevron_back_screen() toast("Done") def file_manager_open(self): from kivymd.filemanager import MDFileManager from kivymd.dialog import MDDialog def open_file_manager(text_item, dialog): previous = False if text_item == "List" else True self.manager = ModalView(size_hint=(1, 1), auto_dismiss=False) self.file_manager = MDFileManager( exit_manager=self.exit_manager, select_path=self.select_path, previous=previous, ) self.manager.add_widget(self.file_manager) self.file_manager.show(self.user_data_dir) self.manager_open = True self.manager.open() MDDialog( title="Title", size_hint=(0.8, 0.4), text_button_ok="List", text="Open manager with 'list' or 'previous' mode?", text_button_cancel="Previous", events_callback=open_file_manager, ).open() def select_path(self, path): """It will be called when you click on the file name or the catalog selection button. :type path: str; :param path: path to the selected directory or file; """ self.exit_manager() toast(path) def exit_manager(self, *args): """Called when the user reaches the root of the directory tree.""" self.manager.dismiss() self.manager_open = False self.set_chevron_menu() def set_chevron_menu(self): self.main_widget.ids.toolbar.left_action_items = [[ "menu", lambda x: self.root.toggle_nav_drawer() ]] def events(self, instance, keyboard, keycode, text, modifiers): """Called when buttons are pressed on the mobile device.""" if keyboard in (1001, 27): if self.manager_open: self.file_manager.back() return True def callback_for_menu_items(self, *args): toast(args[0]) def add_cards(self, instance_grid_card): """Adds MDCardPost objects to the screen Cards when the screen is open.""" from kivymd.cards import MDCardPost def callback(instance, value): if value is None: toast("Delete post %s" % str(instance)) elif isinstance(value, int): toast("Set like in %d stars" % value) elif isinstance(value, str): toast("Repost with %s " % value) elif isinstance(value, list): toast(value[1]) if not self.cards_created: self.cards_created = True menu_items = [{ "viewclass": "MDMenuItem", "text": "Example item %d" % i, "callback": self.callback_for_menu_items, } for i in range(2)] buttons = ["facebook", "vk", "twitter"] instance_grid_card.add_widget( MDCardPost(text_post="Card with text", swipe=True, callback=callback)) instance_grid_card.add_widget( MDCardPost( right_menu=menu_items, swipe=True, text_post="Card with a button to open the menu MDDropDown", callback=callback, )) instance_grid_card.add_widget( MDCardPost( likes_stars=True, callback=callback, swipe=True, text_post="Card with asterisks for voting.", )) instance_grid_card.add_widget( MDCardPost( source="./assets/kitten-1049129_1280.png", tile_text="Little Baby", tile_font_style="H5", text_post="This is my favorite cat. He's only six months " "old. He loves milk and steals sausages :) " "And he likes to play in the garden.", with_image=True, swipe=True, callback=callback, buttons=buttons, )) def update_screen(self, instance): """Set new label on the screen UpdateSpinner.""" def update_screen(interval): self.tick += 1 if self.tick > 2: instance.update = True self.tick = 0 self.data["Update Screen Widget"][ "object"].ids.upd_lbl.text = "New string" Clock.unschedule(update_screen) Clock.schedule_interval(update_screen, 1) main_widget = None def build(self): self.main_widget = Builder.load_string(main_widget_kv) return self.main_widget def set_popup_screen(self, content_popup): popup_menu = ContentForAnimCard() popup_menu.add_widget(Widget(size_hint_y=None, height=dp(150))) popup_screen = self.data["Popup Screen"]["object"].ids.popup_screen popup_screen.screen = popup_menu popup_screen.background_color = [0.3, 0.3, 0.3, 1] popup_screen.max_height = content_popup.ids.image.height + dp(5) def show_user_example_animation_card(self): """Create and open instance MDUserAnimationCard for the screen UserCard.""" from kivymd.useranimationcard import MDUserAnimationCard def main_back_callback(): toast("Close card") if not self.user_card: self.user_card = MDUserAnimationCard( user_name="Lion Lion", path_to_avatar="./assets/guitar-1139397_1280.png", callback=main_back_callback, ) self.user_card.box_content.add_widget(ContentForAnimCard()) self.user_card.open() def show_example_snackbar(self, snack_type): """Create and show instance Snackbar for the screen MySnackBar.""" def callback(instance): toast(instance.text) def wait_interval(interval): self._interval += interval if self._interval > self.my_snackbar.duration: anim = Animation(y=dp(10), d=0.2) anim.start(self.data["Snackbars"]["object"].ids.button) Clock.unschedule(wait_interval) self._interval = 0 self.my_snackbar = None from kivymd.snackbars import Snackbar if snack_type == "simple": Snackbar(text="This is a snackbar!").show() elif snack_type == "button": Snackbar( text="This is a snackbar", button_text="with a button!", button_callback=callback, ).show() elif snack_type == "verylong": Snackbar(text="This is a very very very very very very very " "long snackbar!").show() elif snack_type == "float": if not self.my_snackbar: self.my_snackbar = Snackbar( text="This is a snackbar!", button_text="Button", duration=3, button_callback=callback, ) self.my_snackbar.show() anim = Animation(y=dp(72), d=0.2) anim.bind(on_complete=lambda *args: Clock.schedule_interval( wait_interval, 0)) anim.start(self.data["Snackbars"]["object"].ids.button) def show_example_input_dialog(self): """Creates an instance of the dialog box and displays it on the screen for the screen Dialogs.""" def result(text_button, instance): toast(instance.text_field.text) if not self.input_dialog: from kivymd.dialog import MDInputDialog self.input_dialog = MDInputDialog( title="Title", hint_text="Hint text", size_hint=(0.8, 0.4), text_button_ok="Ok", events_callback=result, ) self.input_dialog.open() def show_example_alert_dialog(self): if not self.alert_dialog: from kivymd.dialog import MDDialog self.alert_dialog = MDDialog( title="Title", size_hint=(0.8, 0.4), text_button_ok="Ok", text="This is Alert dialog", events_callback=self.callback_for_menu_items, ) self.alert_dialog.open() def show_example_ok_cancel_dialog(self): if not self.ok_cancel_dialog: from kivymd.dialog import MDDialog self.ok_cancel_dialog = MDDialog( title="Title", size_hint=(0.8, 0.4), text_button_ok="Ok", text="This is Ok Cancel dialog", text_button_cancel="Cancel", events_callback=self.callback_for_menu_items, ) self.ok_cancel_dialog.open() def show_example_long_dialog(self): if not self.long_dialog: from kivymd.dialog import MDDialog self.long_dialog = MDDialog( text="Lorem ipsum dolor sit amet, consectetur adipiscing " "elit, sed do eiusmod tempor incididunt ut labore et " "dolore magna aliqua. Ut enim ad minim veniam, quis " "nostrud exercitation ullamco laboris nisi ut aliquip " "ex ea commodo consequat. Duis aute irure dolor in " "reprehenderit in voluptate velit esse cillum dolore eu " "fugiat nulla pariatur. Excepteur sint occaecat " "cupidatat non proident, sunt in culpa qui officia " "deserunt mollit anim id est laborum.", title="Title", size_hint=(0.8, 0.4), text_button_ok="Yes", events_callback=self.callback_for_menu_items, ) self.long_dialog.open() def get_time_picker_date(self, instance, time): """Get date for MDTimePicker from the screen Pickers.""" self.data["Pickers"]["object"].ids.time_picker_label.text = str(time) self.previous_time = time def show_example_time_picker(self): """Show MDTimePicker from the screen Pickers.""" from kivymd.pickers import MDTimePicker time_dialog = MDTimePicker() time_dialog.bind(time=self.get_time_picker_date) if self.data["Pickers"][ "object"].ids.time_picker_use_previous_time.active: try: time_dialog.set_time(self.previous_time) except AttributeError: pass time_dialog.open() def set_previous_date(self, date_obj): """Set previous date for MDDatePicker from the screen Pickers.""" self.previous_date = date_obj self.data["Pickers"]["object"].ids.date_picker_label.text = str( date_obj) def show_example_date_picker(self): """Show MDDatePicker from the screen Pickers.""" from kivymd.pickers import MDDatePicker if self.data["Pickers"][ "object"].ids.date_picker_use_previous_date.active: pd = self.previous_date try: MDDatePicker(self.set_previous_date, pd.year, pd.month, pd.day).open() except AttributeError: MDDatePicker(self.set_previous_date).open() else: MDDatePicker(self.set_previous_date).open() def show_example_bottom_sheet(self): """Show menu from the screen BottomSheet.""" from kivymd.bottomsheet import MDListBottomSheet if not self.bs_menu_1: self.bs_menu_1 = MDListBottomSheet() self.bs_menu_1.add_item( "Here's an item with text only", lambda x: self.callback_for_menu_items( "Here's an item with text only"), ) self.bs_menu_1.add_item( "Here's an item with an icon", lambda x: self.callback_for_menu_items( "Here's an item with an icon"), icon="clipboard-account", ) self.bs_menu_1.add_item( "Here's another!", lambda x: self.callback_for_menu_items("Here's another!"), icon="nfc", ) self.bs_menu_1.open() def show_example_grid_bottom_sheet(self): """Show menu from the screen BottomSheet.""" if not self.bs_menu_2: from kivymd.bottomsheet import MDGridBottomSheet self.bs_menu_2 = MDGridBottomSheet() self.bs_menu_2.add_item( "Facebook", lambda x: self.callback_for_menu_items("Facebook"), icon_src="./assets/facebook-box.png", ) self.bs_menu_2.add_item( "YouTube", lambda x: self.callback_for_menu_items("YouTube"), icon_src="./assets/youtube-play.png", ) self.bs_menu_2.add_item( "Twitter", lambda x: self.callback_for_menu_items("Twitter"), icon_src="./assets/twitter.png", ) self.bs_menu_2.add_item( "Da Cloud", lambda x: self.callback_for_menu_items("Da Cloud"), icon_src="./assets/cloud-upload.png", ) self.bs_menu_2.add_item( "Camera", lambda x: self.callback_for_menu_items("Camera"), icon_src="./assets/camera.png", ) self.bs_menu_2.open() def set_title_toolbar(self, title): """Set string title in MDToolbar for the whole application.""" self.main_widget.ids.toolbar.title = title def set_appbar(self): """Create MDBottomAppBar for the screen BottomAppBar.""" from kivymd.toolbar import MDBottomAppBar def press_button(inctance): toast("Press Button") self.md_app_bar = MDBottomAppBar( md_bg_color=self.theme_cls.primary_color, left_action_items=[ ["menu", lambda x: x], ["clock", lambda x: x], ["dots-vertical", lambda x: x], ], anchor="right", callback=press_button, ) def move_item_menu(self, anchor): """Sets icons in MDBottomAppBar for the screen BottomAppBar.""" md_app_bar = self.md_app_bar if md_app_bar.anchor != anchor: if len(md_app_bar.right_action_items): md_app_bar.left_action_items.append( md_app_bar.right_action_items[0]) md_app_bar.right_action_items = [] else: left_action_items = md_app_bar.left_action_items action_items = left_action_items[0:2] md_app_bar.right_action_items = [left_action_items[-1]] md_app_bar.left_action_items = action_items def show_password(self, field, button): """ Called when you press the right button in the password field for the screen TextFields. instance_field: kivy.uix.textinput.TextInput; instance_button: kivymd.button.MDIconButton; """ # Show or hide text of password, set focus field # and set icon of right button. field.password = not field.password field.focus = True button.icon = "eye" if button.icon == "eye-off" else "eye-off" def set_error_message(self, *args): """Checks text of TextField with type "on_error" for the screen TextFields.""" text_field_error = args[0] if len(text_field_error.text) == 2: text_field_error.error = True else: text_field_error.error = False def set_list_md_icons(self, text="", search=False): """Builds a list of icons for the screen MDIcons.""" def add_icon_item(name_icon): self.main_widget.ids.scr_mngr.get_screen( "md icons").ids.rv.data.append({ "viewclass": "MDIconItemForMdIconsList", "icon": name_icon, "text": name_icon, "callback": self.callback_for_menu_items, }) self.main_widget.ids.scr_mngr.get_screen("md icons").ids.rv.data = [] for name_icon in md_icons.keys(): if search: if text in name_icon: add_icon_item(name_icon) else: add_icon_item(name_icon) def set_menu_for_demo_apps(self): if not len(self.menu_for_demo_apps): for name_item in self.demo_apps_list: self.menu_for_demo_apps.append({ "viewclass": "OneLineListItem", "text": name_item, "on_release": lambda x=name_item: self.show_demo_apps(x), }) def show_demo_apps(self, name_item): self.show_screens_demo(name_item) self.main_widget.ids.scr_mngr.current = name_item.lower() self.instance_menu_demo_apps.dismiss() def on_pause(self): return True def on_stop(self): pass def open_settings(self, *args): return False
class MainApp(App): # Color themes firebase_url = "https://one-hundred-days-of-sweat.firebaseio.com/" theme_cls = ThemeManager() md_theme_picker = None theme_cls.primary_palette = 'Blue' theme_cls.primary_hue = '700' theme_cls.accent_palette = 'DeepOrange' theme_cls.theme_style = 'Light' is_editing_start_date = False iphone_x_notch_height = dp(30) notch_color = ColorProperty([1, 1, 1, 0]) notch_source = StringProperty("FirebaseLoginScreen/wallpaper.jpg") # app height should be 30 px less if run on iphones type X, XR, or XS MAX window_height = Window.height if ( Window.height != 2436 and Window.height != 2688 and Window.height != 1792) else Window.height - iphone_x_notch_height options_menu = None # Dropdown menu celebrations = [ "Nice job!", "Keep it up!", "Way to go!", "Good going!", "Yes!!", "You rock!", "Great job!", "Sweet!", "Fantastic!", "Awesome!" ] workout_suggestions = [ "Jumping jacks", "Body weight squats", "Jogging", "Knee push-ups", "Sit ups", "Jogging", "Lunges" ] saved_dates_file = "saved_dates.txt" hundred_days_file = "hundred_days.txt" color_theme_file = "color_theme.txt" hundred_days = [] saved_dates = [] bottom_label = None date_picker = None # Main widget has_loaded_motivations = False # Used to make sure we only load them once submission_dialog = None view_submissions_popup = None def on_start(self): self.submission_dialog = SubmissionDialog() self.view_submissions_popup = ViewSubmissionsPopup() def on_login(self): #def on_start(self): # Fix file names on ios self.saved_dates_file = App.get_running_app( ).user_data_dir + "/" + self.saved_dates_file self.hundred_days_file = App.get_running_app( ).user_data_dir + "/" + self.hundred_days_file self.color_theme_file = App.get_running_app( ).user_data_dir + "/" + self.color_theme_file # Debug debug = False if debug: # Clear all saved info by the app, like the user login credentials # Forces user to sign in again (for testing the login screen) with open(self.root.ids.firebase_login_screen.refresh_token_file, "w") as f: f.write("") with open(self.saved_dates_file, "w") as f: f.write("") with open(self.hundred_days_file, "w") as f: f.write("") with open(self.color_theme_file, "w") as f: f.write("") # Read the color theme file try: with open(self.color_theme_file, "r") as f: self.theme_cls.primary_palette = f.read() except: # No saved color theme pass # Read the saved workout dates before loading calendar try: with open(self.saved_dates_file, "r") as f: self.saved_dates = ast.literal_eval(f.read()) except: pass # Try to get their start time if it's not their first time in the app try: with open(self.hundred_days_file, "r") as f: self.hundred_days = ast.literal_eval(f.read()) # Immediately build the calendar self.build_interface() # Immediately switch to the main screen self.switch_to_main_screen() except: # It is their first time in the app # Open the start date picker popup self.open_start_date_menu(is_editing_start_date=False) # Wait half a second while the popup is displayed, then quietly # switch screens behind it Clock.schedule_once( partial(self.switch_to_main_screen, duration=0), .5) # Build dropdown list items = [] options = [['View Motivation', self.view_motivation], ['Send Motivation', self.submit_motivation], ['Change Color', self.change_color_theme], ['Edit Start Date', self.open_start_date_menu]] for option in options: items.append({ 'viewclass': 'OneLineListItem', 'text': option[0], 'on_release': option[1] }) self.options_menu = MDDropdownMenu(items=items, width_mult=4) # Attempt to finish the options menu UrlRequest(self.firebase_url + "num_users.json", ca_file=certifi.where(), on_success=self.finish_dropdown_menu) def switch_to_main_screen(self, *args, duration=1): # Switch to the main app screen self.root.ids.sm.transition = CardTransition(direction='down', mode='pop', duration=duration) # Quickly add an image to the current firebase screen to fix eyesore when changing screen screen = self.root.ids.firebase_login_screen.ids.screen_manager.current screen = self.root.ids.firebase_login_screen.ids[screen] with screen.canvas.before: Rectangle(size=screen.size, pos=screen.pos, source='FirebaseLoginScreen/wallpaper.jpg') self.root.ids.sm.current = 'main_screen' def finish_dropdown_menu(self, req, *args): num_users = req.result # Can only finish building dropdown menu after querying firebase self.options_menu.items.append({ 'viewclass': 'MDLabel', 'text': '[i]Global participants: %s[/i]' % num_users, 'halign': 'center', 'markup': True }) def open_start_date_menu(self, *args, is_editing_start_date=True): self.is_editing_start_date = is_editing_start_date if self.options_menu: self.options_menu.dismiss() StandardMDDatePicker(self.choose_start_date).open() def choose_start_date(self, start_date): # Get the next 100 days current_date = start_date self.hundred_days = [] self.hundred_days.append( [current_date.day, current_date.month, current_date.year]) for i in range(99): next_date = current_date + timedelta(days=1) current_date = next_date self.hundred_days.append( [current_date.day, current_date.month, current_date.year]) # Save their hundred days with open(self.hundred_days_file, "w") as f: f.write(str(self.hundred_days)) self.build_interface() def build_interface(self): # Change notch color and image self.notch_color = self.theme_cls.primary_color self.notch_source = "" # Buid the calendar widget if self.date_picker: # The user picked a new date and needs to update the calendar self.root.ids.main_layout.remove_widget(self.date_picker) self.root.ids.main_layout.remove_widget(self.bottom_label) self.date_picker = MDDatePicker(elevation=0) self.root.ids.main_layout.add_widget(self.date_picker) # Build the scrolling suggestion field day = calendar.day_name[date.today().weekday()] # 'Wednesday' colored_label = self.date_picker.ids.label_full_date self.bottom_label = MDLabel( text=day + "'s suggested activity: " + self.workout_suggestions[date.today().weekday()], text_color=colored_label.text_color, theme_text_color='Custom', halign='center') colored_label.bind(text_color=self.reset_bottom_text_color) self.root.ids.main_layout.add_widget(self.bottom_label) def reset_bottom_text_color(self, *args): self.bottom_label.text_color = self.date_picker.ids.label_full_date.text_color def display_menu(self, *args): self.options_menu.open(self.root.ids.toolbar) def open_verify_workout_popup(self, daybutton, active): # Saves the date that was selected to local storage # displays a small popup (toasts) a compliment day = int(daybutton.owner.sel_day) month = int(daybutton.owner.sel_month) year = int(daybutton.owner.sel_year) if active: self.saved_dates.append([day, month, year]) with open(self.saved_dates_file, "w") as f: f.write(str(self.saved_dates)) self.toast_random_celebration() else: self.saved_dates.remove([day, month, year]) with open(self.saved_dates_file, "w") as f: f.write(str(self.saved_dates)) def toast_random_celebration(self): # Choose a random celebration from the list of celebrations r = randint(0, len(self.celebrations) - 1) toast(self.celebrations[r]) def view_motivation(self, *args): self.options_menu.dismiss() self.view_submissions_popup.open() def submit_motivation(self, *args): self.options_menu.dismiss() self.submission_dialog.open() def change_color_theme(self, *args): # Open up the themepicker popup self.options_menu.dismiss() if not self.md_theme_picker: self.md_theme_picker = MDThemePicker() self.md_theme_picker.open() def save_color_theme(self, *args): with open(self.color_theme_file, "w") as f: f.write(self.theme_cls.primary_palette) def update_notch_color(self, *args): self.notch_color = self.theme_cls.primary_color def calculate_remaining_days(self, *args): time_remaining = date.today() - date(self.hundred_days[-1][2], self.hundred_days[-1][1], self.hundred_days[-1][0]) if time_remaining.days > 0: # Past the end date return "100 Days of Sweat Complete!" else: return "Days remaining: " + str(abs(time_remaining.days))
def change_color_theme(self, *args): # Open up the themepicker popup self.options_menu.dismiss() if not self.md_theme_picker: self.md_theme_picker = MDThemePicker() self.md_theme_picker.open()