Пример #1
0
class InfoScreen(Screen):
    def __init__(self, **kw):
        super().__init__(**kw)
        self.info = None
        """
        0 = id
        1 = name
        2 = address
        3 = phone number
        4 = website
        5 to 11 = Monday - Sunday
        12 = latitude
        13 = longitude
        14 = information
        15 = distance in miles
        16 = zip code latitude
        17 = zip code longitude
        """
        self.url = None
        self.phone_number = None
        self.map = None
        self.marker = None
        self.midpoint = None
        self.ideal_zoom = None

        self.phone_dialog = MDDialog(
            title="Phone Number",
            text="",
            buttons=[
                MDFlatButton(
                    text="Close",
                    text_color=MDApp.get_running_app().theme_cls.primary_color,
                    on_release=self.close_phone_number_dialog,
                ),
                MDFlatButton(
                    text="Copy",
                    text_color=MDApp.get_running_app().theme_cls.primary_color,
                    on_release=self.copy_phone_number,
                ),
            ],
        )

        self.schedule_data = None

    def on_enter(self, *args):
        self.info = MDApp.get_running_app().row
        self.ids.center_panel.ids.title_box.ids.title.text = self.info[1]
        self.ids.center_panel.ids.list_box.ids.address.text = self.info[2]

        print(
            self.ids.center_panel.ids.buttons_box.ids.call_container.ids.call_button.size
        )

        day = datetime.datetime.today().weekday()
        day_name = [
            "Monday",
            "Tuesday",
            "Wednesday",
            "Thursday",
            "Friday",
            "Saturday",
            "Sunday",
        ]
        for index in range(5, 12):
            if self.info[index] is None:
                self.info[index] = "Closed"
        self.ids.center_panel.ids.list_box.ids.hours.text = f"""{day_name[day]}: [color={get_hex_from_color(
            MDApp.get_running_app().theme_cls.primary_color)}]{self.info[day + 5]}[/color]"""

        if self.info[14] is not None:
            self.ids.center_panel.ids.information.text = self.info[14]

        self.ids.center_panel.ids.title_box.ids.distance.text = (
            str(self.info[15]) + " Miles Away"
        )

        # Modify the schedule data table
        # TODO: Make the data table take up the width of the screen
        self.schedule_data = MDDataTable(
            size_hint=(0.9, 0.8),
            column_data=[("Day", dp(20)), ("Hours", dp(35))],
            row_data=[
                ("Monday", self.info[5]),
                ("Tuesday", self.info[6]),
                ("Wednesday", self.info[7]),
                ("Thursday", self.info[8]),
                ("Friday", self.info[9]),
                ("Saturday", self.info[10]),
                ("Sunday", self.info[11]),
            ],
        )
        self.schedule_data.table_data.rows_num = 7
        self.schedule_data.table_data.set_row_data()

        self.map = self.ids.map

        # calculates and sets the view to the midpoint of the foodbank and the person, calculates an ideal zoom value
        self.midpoint = midpoint(
            self.info[12], self.info[13], self.info[16], self.info[17]
        )
        self.map.center_on(self.midpoint[0], self.midpoint[1])
        self.map.zoom = 17
        box = self.map.get_bbox()
        while not (
            box[0] < (self.info[12] and self.info[16]) < box[2]
            and box[1] < (self.info[13] and self.info[17]) < box[3]
        ):
            self.map.zoom -= 1
            box = self.map.get_bbox()
        self.ideal_zoom = self.map.zoom - 1
        self.map.zoom = self.ideal_zoom

        # Adds the foodbank to the map
        self.marker = Marker(
            float(self.info[12]), float(self.info[13]), self.map, self.ideal_zoom
        )
        self.map.add_widget(self.marker)

        # Disables the website button if there is no website
        self.url = self.info[4]
        if self.url is None:
            self.ids.center_panel.ids.buttons_box.ids.website_container.ids.website_button.disabled = (
                True
            )
            self.ids.center_panel.ids.buttons_box.ids.website_container.ids.website_button_text.text_color = (
                MDApp.get_running_app().theme_cls.disabled_hint_text_color
            )
        else:
            self.ids.center_panel.ids.buttons_box.ids.website_container.ids.website_button.disabled = (
                False
            )
            self.ids.center_panel.ids.buttons_box.ids.website_container.ids.website_button_text.text_color = (
                MDApp.get_running_app().theme_cls.primary_color
            )

        # Disables the call button if there is no phone number
        self.phone_number = self.info[3]
        if self.phone_number is None:
            self.ids.center_panel.ids.buttons_box.ids.call_container.ids.call_button.disabled = (
                True
            )
            self.ids.center_panel.ids.buttons_box.ids.call_container.ids.call_button_text.text_color = (
                MDApp.get_running_app().theme_cls.disabled_hint_text_color
            )
        else:
            # Modify the phone dialog
            self.phone_dialog.text = self.info[3]
            self.phone_dialog.size_hint_x = 0.8
            self.phone_dialog.size[1] += 100
            self.ids.center_panel.ids.buttons_box.ids.call_container.ids.call_button.disabled = (
                False
            )
            self.ids.center_panel.ids.buttons_box.ids.call_container.ids.call_button_text.text_color = (
                MDApp.get_running_app().theme_cls.primary_color
            )

        # Set the map size
        Clock.schedule_once(lambda _: self.resize_map())

    def resize_map(self):
        self.ids.map.size = 100, Window.size[1] - self.ids.center_panel.height + 40
        print(f"{self.ids.map.size} is the new size of the map")

    def open_url(self):
        print("opened url")
        webbrowser.open(self.url)

    def call_number(self):
        PythonActivity = autoclass("org.kivy.android.PythonActivity")
        Intent = autoclass("android.content.Intent")
        Uri = autoclass("android.net.Uri")

        number = Uri.parse(f"tel:{self.info[3].replace('-', '')}")
        intent = Intent(Intent.ACTION_DIAL, number)

        currentActivity = cast("android.app.Activity", PythonActivity.mActivity)
        currentActivity.startActivity(intent)

    def open_google_maps(self):
        PythonActivity = autoclass("org.kivy.android.PythonActivity")
        Intent = autoclass("android.content.Intent")
        Uri = autoclass("android.net.Uri")

        location = Uri.parse(f'geo:0,0?q={self.info[2].replace(" ", "+")}')
        intent = Intent(Intent.ACTION_VIEW, location)

        currentActivity = cast("android.app.Activity", PythonActivity.mActivity)
        currentActivity.startActivity(intent)

    def open_schedule_data(self):
        self.schedule_data.open()

    def center_on_midpoint(self):
        self.map.center_on(self.midpoint[0], self.midpoint[1])
        self.map.zoom = self.ideal_zoom

    def copy_phone_number(self, _):
        Clipboard.copy(self.info[3])
        Snackbar(text="Copied to Clipboard!").show()

    def close_phone_number_dialog(self, _):
        self.phone_dialog.dismiss()

    def close_schedule_data(self, _):
        self.schedule_data.dismiss()

    def go_back(self):
        self.map.remove_widget(self.marker)
        self.manager.current = "results_screen"
Пример #2
0
class sonarApp(MDApp):
    #Since we named class 'sonarApp', kivy auto-builds 'sonar.kv'.
    def build(self):
        self.theme_cls.primary_palette = 'DeepPurple'
    
    #Runs when user starts app.
    def on_start(self):
        self.conn = sqlite3.connect('database.db')
        #Ensure that results from sqlite queries are returned as dictionaries.
        self.conn.row_factory = database.dictFactory 
        self.cursor = self.conn.cursor()

        #Make all relevant tables if they do not yet exist.
        database.dbSetup(self.conn, self.cursor)
        
        #Get hosts on network from a single ARP broadcast.
        hostsOnNetwork = networking.surveyNetwork('255.255.255.0', 1)
        
        currentNetworkId = database.getNetworkId(hostsOnNetwork, self.conn, self.cursor)
        
        self.cursor.execute('SELECT * FROM networks WHERE id = ?', [currentNetworkId])
        currentNetwork = { currentNetworkId : self.cursor.fetchone() }
        
        self.cursor.execute('SELECT * FROM networks WHERE id != ?', [currentNetworkId])
        restOfNetworks = { network['id'] : network
            for network in self.cursor.fetchall() }
        
        #Ensure that currentNetwork is first in 'networks', and thus on GUI.
        networks = { **currentNetwork, **restOfNetworks }

        #Create list of networks, which give a table of hosts when clicked.
        for network in networks.values():
            columnWidth = (self.root.width * 0.69) / 5 / 5

            networkListItem = OneLineListItem(
                text = network['ssid'],
                on_press = (
                    lambda _, network = network, columnWidth = columnWidth:
                    self.networkTable(network, columnWidth) 
                )
            )

            self.root.ids['networksList'].add_widget(networkListItem)

        self.hosts = database.catalogNetwork(
            self.conn, self.cursor, hostsOnNetwork) 
        hostIdsOnNetwork = networking.getHostsOnNetwork(
            hostsOnNetwork, self.hosts)
        
        for hostId in self.hosts:
            onNetwork = (hostId in hostIdsOnNetwork)
            self.hosts[hostId]['onNetwork'] = onNetwork
        
        notifsQ = multiprocessing.Queue()
        hostsQ = multiprocessing.Queue()

        self.notifsProducerP = multiprocessing.Process(
            target = notifsProducer,
            args = (hostsOnNetwork, self.hosts, notifsQ, hostsQ,)
        )
        self.notifsProducerP.start()

        #Play ringtone for each notif-enabled host that entered network.
        #Update self.hosts data.
        def notifsConsumer(_):
            if not notifsQ.empty():
                for hostId in notifsQ.get_nowait():
                    MDDialog(
                        title = '%s has entered the network' % self.hosts[hostId]['macAddr']
                    ).open()
                    self.playRingtone(self.hosts[hostId]['tone'])
            
            #update host values.
            if not hostsQ.empty():
                currentHosts = hostsQ.get_nowait()
                
                for hostId, host in currentHosts.items():
                    self.hosts[hostId] = host


        #Check / react to contents of notifsQ every 5 seconds.
        self.notifChecker = Clock.schedule_interval(notifsConsumer, 5)

    #Plays ringtone no. given from file in 'ringtones'.
    #Needs to be method of app class so it can be called from '.kv' file.
    def playRingtone(self, ringtoneNo):
        if ringtoneNo not in range(1,10):
            return

        else:
            #kivy's audio module has issues on debian systems (inc. mine), so we use pygame.
            pygame.mixer.init()
            filepath = os.path.abspath(__file__)
            filedir = os.path.dirname(filepath)
            musicpath = os.path.join(filedir, "ringtones/%d.wav" % ringtoneNo)
            pygame.mixer.music.load(os.path.abspath(musicpath))
            pygame.mixer.music.play()
    
    #When user clicks a network row, display table showing its hosts.
    def networkTable(self, network, columnWidth):
        keysToShow = ['macAddr', 'ipAddr', 'manufacturer', 'notificationEnabled', 'onNetwork']

        hostsRowData = [
            list({
                    key:value 
                    for (key, value) in host.items()
                    if key in keysToShow
                }.values())
            for host in self.hosts.values()
        ]

        self.hostsTable = MDDataTable(
            column_data =  [
                ('MAC Address', columnWidth),
                ('IP Address', columnWidth),
                ('Manufacturer', columnWidth),
                ('Notifications Enabled', columnWidth),
                ('On Network', columnWidth)
            ],
            row_data = hostsRowData,
            size_hint = (0.7, 0.7)
        )

        self.hostsTable.bind(on_row_press = self.onHostPress)
        self.hostsTable.open()
    
    #If user clicks row corresponding for host in self.hostsTable, display dialog.
    #Dialog allows user to enable notifications / set notif tone for relevant host.
    def onHostPress(self, instanceTable, instanceRow):
        rowIndex = floor(instanceRow.index / 5)
        hostData = instanceTable.row_data[rowIndex]
        content = notificationSettings(enabled = hostData[3])
        hostId = list(self.hosts.values())[rowIndex]['id']

        self.hostDialog = MDDialog(
            title = 'Notifications for %s' % hostData[0],
            content_cls = content,
            type = 'custom',
            buttons = [
                ToggleButtonClass(
                    text = 'Cancel',
                    group = 'submit',
                    on_release = (lambda _: self.hostDialog.dismiss(force = 1))
                ),
                ToggleButtonClass(
                    text = 'OK',
                    group = 'submit',
                    on_release = (lambda _: self.hostDialogSubmit(hostId, rowIndex))
                )
            ]
        )
        
        #Nth value of checkbox bools indicate if checkbox n is selected.
        checkboxBools = [0] * 9
        
        if hostData[3]:
            checkboxBools[int(self.hosts[hostId]['tone']) - 1] = 1
        
        musicItems = [
            itemConfirmMusic(
                text = ('Ringtone %d' % num),
                active = (checkboxBools[num - 1]),
                index = num
            )
            for num in range(1,10)
        ]
        
        for item in musicItems:
            self.hostDialog.content_cls.ids['notifList'].add_widget(item)

        self.hostDialog.open()

    #When user submits host dialog, input info into db and update self.hosts.
    def hostDialogSubmit(self, hostId, hostIndex):
        #Get binary value of switch.
        notificationsEnabled = int(
            self.hostDialog.content_cls.ids['notificationsEnabled'].active)

        self.hosts[hostId]['notificationEnabled']  = notificationsEnabled

        if notificationsEnabled:
            selectedItem = None
            widgetList = list(enumerate(
                self.hostDialog.content_cls.ids['notifList'].children
            ))

            for index, widget in reversed(widgetList):
                if widget.ids['check'].active:
                    selectedIndex = widget.index

                    #update db;
                    self.cursor.execute(
                        'UPDATE hosts SET notificationEnabled = 1, tone = ? WHERE id = ?', 
                        [selectedIndex, hostId])
                    self.conn.commit()

                    self.hosts[hostId]['tone'] = selectedIndex
                    
                    #Close host's table and host dialog.
                    #MDDataTable can't be updated, so we need to close.
                    self.hostDialog.dismiss(force = 1)
                    self.hostsTable.dismiss(force = 1)
                    
                    return

            #Tell user to select a tone value, since none were selected.
            Snackbar(
                text = "Please select an option",
                padding = "20dp"
            ).open()

        else:
            self.hostsTable.table_data.row_data[hostIndex][3] = '1'
            self.cursor.execute('UPDATE hosts SET notificationEnabled = 0 WHERE id = ?',
                [hostId])
            self.conn.commit()
            self.hostDialog.dismiss(force = 1)
    
    #Callback to make "tone" checkboxes visible when user enables notifs.
    def selectNotifType(self):
        self.hostDialog.content_cls.ids['options'].opacity = 1
        self.hostDialog.update_height()   
Пример #3
0
class SmartBricksApp(MDApp):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        Window.bind(on_keyboard=self.events)
        self.manager_open = False
        self.file_manager = MDFileManager(exit_manager=self.exit_manager,
                                          select_path=self.select_path,
                                          previous=True,
                                          ext=['jpeg', 'png', 'jpg'])

        #self.menu_2 = self.create_menu("Button dots", self.root.ids.toolbar.ids.button_2)
        #print('HEREEEEEEE!!!!', self.root)
        #cm = CustomToolbar

        try:

            request_permissions([
                Permission.WRITE_EXTERNAL_STORAGE,
                Permission.READ_EXTERNAL_STORAGE
            ])
        except NameError:
            pass

    def dropdown(self, id):

        self.menu_2 = self.create_menu("Button dots", id)
        self.menu_2.open()

    def create_menu(self, instance):

        menu_items = [
            {
                "right_content_cls": RightContentCls(
                    #text=f"R", icon="apple-keyboard-command",
                ),
                "icon": "apple-keyboard-command",
                "text": text,
            } for text in ('RENAME', 'DELETE')
        ]
        return MDDropdownMenu(caller=instance, items=menu_items, width_mult=4)

    def build(self):
        #Window.bind(on_keyboard=self.key_input)
        self.screen = Builder.load_file("main.kv")

        return self.screen

    def on_pause(self):
        return True

    #def key_input(self, window, key, scancode, codepoint, modifier):
    #  if key == 27:
    #     return True  # override the default behaviour
    #  else:           # the key now does nothing
#         return False

#settings_path = app_storage_path()

    path = os.getcwd()
    df = pd.read_csv('%s/legoKeys.cvs' % (path), sep='\t')

    try:
        SD_CARD = primary_external_storage_path() + '/' + 'DCIM/Camera'
        out_dir = '%s/smartbricks_outputs/' % (primary_external_storage_path())
        print('ANDROID mmodules loaded...')

    except NameError:
        print('ANDROID modules failed...')
        SD_CARD = '/home/omar/Pictures'
        out_dir = '%s/myproj_out/' % (path)
        pass

    isdir = os.path.isdir(out_dir)

    def plist(self):

        if self.isdir:
            plist_ = os.listdir(self.out_dir)
        else:
            os.mkdir(self.out_dir)
            plist_ = None

        return plist_

    custom_sheet = None

    def callback_for_menu_items(self, *args):
        toast(args[0])

    def openScreen(self, itemdrawer):
        self.openScreenName(itemdrawer.target)
        self.root.ids.nav_drawer.set_state("close")

    def openScreenName(self, screenName):
        self.root.ids.screen_manager.current = screenName

    def ifproject(self):

        print('PLIST!!!!!!!!!', self.plist())
        print('PLIST TYPE!!!!!!!!!', type(self.plist()))

        if ((self.isdir) & (self.plist() is not None)):

            #clear widgets if any previously load to avoid staking of color palettes between projects
            self.root.ids.grid_list.clear_widgets()
            #self.root.ids.grid_list.remove_widget(self.root.ids.grid_list)

            self.openScreenName('projects')

            #if ((self.isdir) & (self.plist is not None)):
            for dir_ in self.plist():
                self.root.ids.grid_list.add_widget(
                    CustomSmartTileWithLabel(
                        source=self.out_dir + dir_ + '/all.jpeg',
                        text="[size=32]%s[/size]" % (dir_)))

        else:
            self.callback_for_menu_items(
                'No projects saved yet. Select START to start a new project.')

    def chooseproject(self, img_source):

        #clear widgets if any previously load to avoid staking of color palettes between projects
        self.root.ids.content_drawer.ids.md_list.clear_widgets()

        self.root.ids.image.source = img_source
        self.openScreenName('main')

        self.img_path = os.path.dirname(img_source)
        tab = np.load(self.img_path + '/table.npz')
        self.tab = tab['data']

        row_data = []
        n2x2, n2x1, n1x1 = 0, 0, 0

        for num, i in enumerate(self.tab.T[0][:-1]):
            if i == '0.0_0.0_0.0': continue
            R, G, B = i.split("_")
            R, G, B = [np.int(np.float(j)) for j in [R, G, B]]
            mask = (self.df['R'] == R) & (self.df['G'] == G) & (self.df['B']
                                                                == B)
            Nbrick, color_name = self.df['LEGO No.'][mask].item(
            ), self.df['Color'][mask].item()
            #print(R,G,B, Nbrick, color_name)

            #
            self.root.ids.content_drawer.ids.md_list.add_widget(
                CustomMDIconButton(color=(R / 256, G / 256, B / 256, 1),
                                   text=color_name,
                                   text_color=(1, 0, 0, 1),
                                   icon='checkbox-blank-circle-outline'))

            n2x2 += int(self.tab.T[1][num])
            n2x1 += int(self.tab.T[2][num])
            n1x1 += int(self.tab.T[3][num])

            row_data.append(
                (color_name, self.tab.T[1][num], self.tab.T[2][num],
                 self.tab.T[3][num], int(self.tab.T[1][num]) +
                 int(self.tab.T[2][num]) + int(self.tab.T[3][num])))

        row_data.append(('Total', n2x2, n2x1, n1x1, n2x2 + n2x1 + n1x1))
        #if len(row_data) > 10: pagination = True
        #else: pagination = False

        self.data_tables = MDDataTable(
            size_hint=(0.9, 0.6),
            rows_num=20,
            use_pagination=True if len(row_data) > 20 else False,
            check=False,
            column_data=[("Color", dp(40)), ("2x2", dp(10)), ("2x1", dp(10)),
                         ("1x1", dp(10)), ("All", dp(10))],
            row_data=row_data,
        )

        self.root.ids.content_drawer.ids.md_list.add_widget(
            CustomMDIconButton(
                color=self.theme_cls.primary_color,
                text='All',
                icon='checkbox-blank-circle-outline',
                #text_color=(R/256,G/256,B/256,1),
                #icon='checkbox-marked-circle'
            ))

        self.root.ids.content_drawer.ids.md_list.add_widget(
            CustomMDIconButton(color=self.theme_cls.primary_color,
                               text='Original',
                               icon=''))

        keep = self.tab.T[0] == 'total'

        b2x2 = self.root.ids.brick_2x2
        b2x1 = self.root.ids.brick_2x1
        b1x1 = self.root.ids.brick_1x1
        for num, brick, brickLab in zip([1, 2, 3], [b2x2, b2x1, b1x1],
                                        ['2x2', '2x1', '1x1']):
            brick.text = brickLab + ': ' + self.tab.T[num][keep][0]

    def choose_palette(self, img_bg_color, text, id):

        self.root.ids.palette_toolbar.md_bg_color = img_bg_color

        self.img_path = os.path.dirname(self.root.ids.image.source)
        #R,G,B = np.float(img_bg_color[0]*256), np.float(img_bg_color[1]*256), np.float(img_bg_color[2]*256)
        R, G, B = np.int(img_bg_color[0] * 256), np.int(
            img_bg_color[1] * 256), np.int(img_bg_color[2] * 256)

        mean = np.mean([R, G, B])
        #print(R,G,B)

        #self.root.ids.image.parent.remove_widget(self.root.ids.image)

        if text not in ['All', 'Original']:
            self.root.ids.image.clear_widgets()
            self.root.ids.image.source = self.img_path + '/%s_%s_%s.zip' % (
                str(R), str(G), str(B))
        else:
            self.root.ids.image.source = self.img_path + '/%s.jpeg' % (
                text.lower())

        print('SOURCE!!!!!!!', self.root.ids.image.source)
        print('TEXT!!!!!!!', text)

        id.icon = 'checkbox-marked-circle'

        #Get bricks counts
        tab = np.load(self.img_path + '/table.npz')
        self.tab = tab['data']

        if text not in ['All', 'Original']:
            keep = self.tab.T[0] == '%s_%s_%s' % (str(R), str(G), str(B))
        else:
            keep = self.tab.T[0] == 'total'

        b2x2 = self.root.ids.brick_2x2
        b2x1 = self.root.ids.brick_2x1
        b1x1 = self.root.ids.brick_1x1

        if mean > 180:
            test_color = [0, 0, 0, 1]  #black
            invert = False
        else:
            test_color = [1, 1, 1, 1]  #withe
            invert = True

        id.text_color = test_color

        for num, brick, brickLab in zip([1, 2, 3], [b2x2, b2x1, b1x1],
                                        ['2x2', '2x1', '1x1']):
            brick.text = brickLab + ': ' + self.tab.T[num][keep][0]
            brick.text_color = test_color
            #print(brick.text_color)

        b2x2_i = self.root.ids.brick_2x2_icon
        b2x1_i = self.root.ids.brick_2x1_icon
        b1x1_i = self.root.ids.brick_1x1_icon

        for num, brick, brickLab in zip([1, 2, 3], [b2x2_i, b2x1_i, b1x1_i],
                                        ['2x2', '2x1', '1x1']):

            #print('MAIN PATH:', self.path)

            if invert:
                brick.icon = "%s/images/%s_invert.jpg" % (self.path, brickLab)
            else:
                brick.icon = "%s/images/%s.jpg" % (self.path, brickLab)

        #self.root.ids.brick_2x2.text = '2x2: '+self.tab.T[1][keep][0]
        #self.root.ids.brick_2x1.text = '2x1: '+self.tab.T[2][keep][0]
        #self.root.ids.brick_1x1.text = '1x1: '+self.tab.T[3][keep][0]

        #print(mean, test_color, self.root.ids.brick_2x2.text_color)
        #self.root.ids.brick_2x2.text_color=test_color

        #if invert: self.root.ids.brick_2x2_icon.icon="/home/omar/myproj/SmartBricks/2x2_invert.jpg"
        #else: self.root.ids.brick_2x2_icon.icon="/home/omar/myproj/SmartBricks/2x2.jpg"
        #print(self.root.ids.brick_2x2.text_color)

    #def test(self, R, G, B):
    #    return R,G,B,1

    def callback_mosaic_size(self, instance, value):
        toast('mosaic size: %s' % (value))
        self.mosaic_size_val = value

    def callback_mosaic_color(self, instance, value):
        toast('mosaic colors: %s' % (value))
        self.mosaic_color_val = value

    def callback_mosaic_name(self, instance, value):
        toast('mosaic name: %s' % (value))
        self.mosaic_name = value

    def show_alert_dialog(self, name):

        if not self.dialog:
            self.dialog = MDDialog(
                title="Replace existing project?",
                text=
                "Project '%s' already exists. Do you want to replace existing project?"
                % (name),
                buttons=[
                    MDFlatButton(text="CANCEL",
                                 text_color=self.theme_cls.primary_color,
                                 on_press=lambda x: self.dialog.dismiss()),
                    MDFlatButton(
                        text="ACCEPT",
                        text_color=self.theme_cls.primary_color,
                        on_press=lambda x: self.show_dialog_progress()),
                ],
            )
        else:
            self.dialog.dismiss()
        self.dialog.open()

    def create_mosaic(self):

        print('LOWSIZE --------', type(self.mosaic_size_val))
        print('NCOLORS --------', type(self.mosaic_color_val))
        print('OUTDIR --------', type(self.root.ids.project_name.text))

        if (self.mosaic_size_val is
                None) or (self.mosaic_color_val is
                          None) or (self.root.ids.project_name.text == ''):

            ttext = 'Define mosaic input values'

            if (self.mosaic_size_val is None): ttext += ', lower size'
            if (self.mosaic_color_val is None): ttext += ', colors'
            if (self.root.ids.project_name.text == ''):
                ttext += ', project name'

            print('TEXT ------ ', ttext)

            toast(ttext)
        #elif
        #elif (if not self.root.ids.project_name.text):
        #    toast('Choose a project name first')
        else:
            #print(self.root.ids.setup_image.source)
            #print(int(self.mosaic_size_val))
            #print(int(self.mosaic_color_val))
            #print(self.root.ids.project_name.text)
            #print(self.out_dir+self.root.ids.project_name.text)

            self.imgpath = str(self.root.ids.setup_image.source)
            self.Ncolors = np.int(self.mosaic_color_val)
            self.lowsize = np.int(self.mosaic_size_val)
            self.outdir = str(self.out_dir + self.root.ids.project_name.text)

            for i in [self.imgpath, self.Ncolors, self.lowsize, self.outdir]:
                print(i, type(i))

            if (self.plist() is not None):
                if (self.root.ids.project_name.text in self.plist()):

                    print('project name already exist...')
                    self.show_alert_dialog(
                        name=self.root.ids.project_name.text)
                else:
                    self.show_dialog_progress()
            else:
                self.show_dialog_progress()

    def show_dialog_progress(self):

        #if not self.dialog2:
        self.dialog2 = MDDialog(
            title="Creating mosaic. Please wait.",
            type="custom",
            #text="Creating mosaic. Please wait.",
            content_cls=progress_bar(),  #self.pb,
            on_open=self.run_mosaic
            #on_open=self.puopen)
            #on_open=self.run_mosaic(imgpath=imgpath, Ncolors=Ncolors, lowsize=lowsize, outdir=outdir)
        )
        self.dialog2.open()

        if self.dialog: self.dialog.dismiss()
        #self.dialog2.bind(on_open=self.run_mosaic)
        #self.run_mosaic

    #def run_mosaic(self, imgpath=None, Ncolors=None, lowsize=None, outdir=None):
    def run_mosaic(self, instance):

        #clear widgets if any previously load to avoid staking of color palettes between projects
        #self.pb.load_bar.clear_widgets()
        self.pb = progress_bar()
        #self.pb.load_bar.parent.remove_widget(self.pb.load_bar)
        self.pb.load_bar.value = 0

        #print(self.pb.load_bar.value)
        #Nmax = np.int(self.mosaic_color_val) #+ 3

        start = time.time()
        SB = SmartBricks(imgpath=self.imgpath,
                         Ncolors=self.Ncolors,
                         lowsize=self.lowsize,
                         outdir=self.outdir)
        #print(SB.img)
        #print(SB.res1x1)
        #SB.saveProj()
        end = time.time()
        print('Total run time #1: %f sec' % (end - start))
        print('point size', SB.size)

        import matplotlib.pyplot as plt
        ispathdir = os.path.isdir(self.outdir)
        if not ispathdir: os.makedirs(self.outdir, exist_ok=True)
        else:
            files = os.listdir(self.outdir)
            #print(self.outdir)
            for f in files:
                os.remove(self.outdir + '/' + f)

        start = time.time()

        #lmax = 10

        if SB.w > SB.h: x_size, y_size = SB.lmax, SB.h * SB.lmax / SB.w
        else: x_size, y_size = SB.w * SB.lmax / SB.h, SB.lmax

        fig = plt.figure(figsize=(x_size, y_size))
        #fig = plt.figure(figsize=(12,12))
        ax = plt.gca()

        SB.bricksCanvas(img=SB.img,
                        fig=fig,
                        ax=ax,
                        RGB=None,
                        res2x2=SB.res2x2,
                        res2x1=SB.res2x1,
                        res1x1=SB.res1x1)
        figcvs = fig
        figall = fig
        #figoriginal = fig.copy

        #paletteLego = SB.palette(SB.img)
        #palette_flat = SB.imgFlat(paletteLego)
        Nmax = len(SB.palette_flat)
        self.pb.load_bar.max = Nmax

        table = []
        #for num, pal in enumerate(palette_flat):
        for i in range(Nmax):

            print(self.pb.load_bar.value)

            pal = SB.palette_flat[i]
            N2x2, N2x1, N1x1 = SB.makeGiff(
                img=SB.img,
                RGB=pal,
                idxs=[SB.res2x2[2], SB.res2x1[2], SB.res1x1[2]],
                pathdir=self.outdir,
                fig=figcvs,
                ax=ax)
            r, g, b = pal
            color = '%s_%s_%s' % (r, g, b)
            table.append([color, N2x2, N2x1, N1x1])
            self.pb.load_bar.value = i + 1
            #self.value99 = i+1

        t = np.array(table)
        N2x2total = np.sum(t[:, 1].astype(int))
        N2x1total = np.sum(t[:, 2].astype(int))
        N1x1total = np.sum(t[:, 3].astype(int))
        table.append(['total', N2x2total, N2x1total, N1x1total])

        end = time.time()
        print('Total run time #2: %f sec' % (end - start))

        start = time.time()

        figall.subplots_adjust(left=SB.left,
                               bottom=SB.bottom,
                               right=SB.right,
                               top=SB.top,
                               wspace=None,
                               hspace=None)
        ax = figall.add_subplot(111)
        ax.imshow(SB.img)
        #True if testing App from PC.
        if SB.frompc:
            figall.savefig('%s/all.jpeg' % (self.outdir),
                           bbox_inches='tight',
                           pad_inches=0)
        else:
            buffer = io.BytesIO()
            canvas = plt.get_current_fig_manager().canvas
            canvas.draw()
            pil_image = PIL.Image.frombytes('RGB', canvas.get_width_height(),
                                            canvas.tostring_rgb())
            pil_image.save('%s/all.jpeg' % (self.outdir), 'JPEG')

        fig0 = plt.figure(figsize=(x_size, y_size))
        fig0.subplots_adjust(left=SB.left,
                             bottom=SB.bottom,
                             right=SB.right,
                             top=SB.top,
                             wspace=None,
                             hspace=None)
        ax = plt.gca()
        ax = fig0.add_subplot(111)
        ax.imshow(SB.img_original)
        if SB.frompc:
            fig0.savefig('%s/original.jpeg' % (self.outdir),
                         bbox_inches='tight',
                         pad_inches=0)
        else:
            buffer = io.BytesIO()
            canvas = plt.get_current_fig_manager().canvas
            canvas.draw()
            pil_image = PIL.Image.frombytes('RGB', canvas.get_width_height(),
                                            canvas.tostring_rgb())
            pil_image.save('%s/original.jpeg' % (self.outdir), 'JPEG')

        #ax = figall.add_subplot(111)
        #ax.imshow(SB.img)
        #figall.savefig('%s/all.jpeg' %(self.outdir), bbox_inches = 'tight', pad_inches = 0)

        #fig0 = plt.figure(figsize=(12,12))
        #ax = fig0.add_subplot(111)
        #plt.imshow(SB.img_original)
        #fig0.savefig('%s/original.jpeg' %(self.outdir), bbox_inches = 'tight', pad_inches = 0)

        np.savez_compressed('%s/table' % (self.outdir), data=table)

        end = time.time()
        print('Total run time #3: %f sec' % (end - start))

        if Nmax == self.pb.load_bar.value:
            self.dialog2.dismiss()

        #SmartBricks(imgpath=self.imgpath, Ncolors=self.Ncolors, lowsize=self.lowsize, outdir=self.outdir).saveProj(self.pb.load_bar.value)

        self.chooseproject(self.outdir + '/all.jpeg')

    def next(self, dt):

        #if self.times == 0:
        #self.run_mosaic
        #    SmartBricks(imgpath=self.imgpath, Ncolors=self.Ncolors, lowsize=self.lowsize, outdir=self.outdir).saveProj()
        #    self.times = 1

        if os.path.exists(self.outdir):
            #self.value99 += 1
            print(self.pb.load_bar.value)
            Nmax = np.int(self.mosaic_color_val) + 3
            self.pb.load_bar.max = Nmax
            Ncurrent = len(
                os.listdir(str(self.out_dir +
                               self.root.ids.project_name.text)))
            print(self.pb.load_bar.value, self.pb.load_bar.max, Ncurrent)
            #print(self.pb.load_bar.value, self.pb.load_bar.max)

            if self.pb.load_bar.value >= Nmax:
                return False
            else:
                self.pb.load_bar.value = Ncurrent
                #self.pb.load_bar.value = self.value99
        else:
            print('PATH DOES NOT EXIST YET!')
            #print(self.times)

    def puopen(self, instance):

        #self.times = 0

        Clock.schedule_interval(self.next, 1 / 25)
        #self.run_mosaic

    def on_start(self):

        self.imgpath = None
        self.Ncolors = None
        self.lowsize = None
        self.outdir = None

        self.mosaic_size_val = None
        self.mosaic_color_val = None
        self.mosaic_name = None
        self.dialog = None
        self.dialog2 = None
        self.value99 = 0
        #self.pb = progress_bar()

        self.menu_2 = self.create_menu(self.root.ids.toolbar)

        self.root.ids.avatar.source = '%s/images/logo.zip' % (self.path)

        self.root.ids.brick_2x2_icon.icon = "%s/images/%s.jpg" % (self.path,
                                                                  '2x2')
        self.root.ids.brick_2x1_icon.icon = "%s/images/%s.jpg" % (self.path,
                                                                  '2x1')
        self.root.ids.brick_1x1_icon.icon = "%s/images/%s.jpg" % (self.path,
                                                                  '1x1')

        for i in np.arange(8, 72, 8):
            self.root.ids.mosaic_size.add_widget(
                CustomMDChip(label='%s' % (str(i)),
                             cb=self.callback_mosaic_size,
                             icon='grid'))

        for i in np.arange(2, 18, 2):
            self.root.ids.mosaic_colors.add_widget(
                CustomMDChip(label=str(i),
                             cb=self.callback_mosaic_color,
                             icon='palette'))

            #print(self.custbutt.palette.md_bg_color)

            #self.root.ids.content_drawer.ids.palette.md_bg_color = (i/100,i/10,0,1)
            #md_bg_color=(1,0,0,1)

            #


#        self.root.ids.content_drawer.ids.md_list.add_widget(
#            ItemDrawer(target="screen1", text="Screen 1",
#                       icon="home-circle-outline",
#                       on_release=self.openScreen)
#        )
#        self.root.ids.content_drawer.ids.md_list.add_widget(
#            ItemDrawer(target="screen2", text="Screen 2",
#                       icon="settings-outline",
#                       on_release=self.openScreen)
#        )

    def custom_bottom_sheet(self):
        self.custom_sheet = MDCustomBottomSheet(
            screen=Factory.ContentCustomSheet())
        self.custom_sheet.open()

    def show_gallery(self):

        self.openScreenName('camera')

        types = ('*.png', '*.jpeg', '*.jpg')  # the tuple of file types
        files_grabbed = []
        for files in types:
            files_grabbed.extend(glob.glob(os.path.join(self.SD_CARD, files)))

        files_grabbed.sort(key=os.path.getmtime)
        files_grabbed.reverse()

        for file in files_grabbed[:20]:
            self.root.ids.grid_list_camera.add_widget(
                CustomSmartTileWithLabelGallery(source=file,
                                                text="[size=18]%s[/size]" %
                                                (os.path.basename(file))))

    def file_manager_open(self):
        #self.file_manager.show('/home/omar/Pictures')  # output manager to the screen
        #self.file_manager.show(self.settings_path)
        self.file_manager.show(self.SD_CARD)
        self.manager_open = True

    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;
        '''

        try:
            self.exit_manager()
        except:
            pass

        self.openScreenName('setup')
        self.root.ids.setup_image.source = path
        toast(path)

    def exit_manager(self, *args):
        '''Called when the user reaches the root of the directory tree.'''

        self.manager_open = False
        self.file_manager.close()

    def show_dialog_eddit(self):

        if self.dialog:
            self.dialog.dismiss()

        #if not self.dialog2:
        self.dialog = MDDialog(
            title="Eddit project?",
            text="Make a new project with same image.",
            buttons=[
                MDFlatButton(text="CANCEL",
                             text_color=self.theme_cls.primary_color,
                             on_press=lambda x: self.dialog.dismiss()),
                MDFlatButton(text="ACCEPT",
                             text_color=self.theme_cls.primary_color,
                             on_press=lambda x: self.eddit_project()),
            ])
        self.dialog.open()

    def eddit_project(self):

        #self.img_path = os.path.dirname(self.root.ids.image.source)
        img_path = self.img_path + '/original.jpeg'
        self.openScreenName('setup')
        if self.dialog: self.dialog.dismiss()
        self.root.ids.setup_image.source = img_path
        toast(img_path)

    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 goto_table(self):

        #self.openScreenName('mosaic_details')
        self.data_tables.open(self.root.ids.details)

    def back_main(self):

        self.data_tables.dismiss()
        self.openScreenName('main')

    def show_dialog_buy(self):

        if self.dialog:
            self.dialog.dismiss()

        #if not self.dialog2:
        self.dialog = MDDialog(
            title="Cooming Soon",
            text=
            "Apologies, SmartBricks does not deliver yet. We are working to deliver your favourite mosaic to you. Are you interested in buying? ",
            buttons=[
                MDFlatButton(text="NO",
                             text_color=self.theme_cls.primary_color,
                             on_press=lambda x: self.dialog.dismiss()),
                MDFlatButton(text="YES",
                             text_color=self.theme_cls.primary_color,
                             on_press=lambda x: self.dialog.dismiss()),
            ])
        self.dialog.open()

    def show_dialog_empty(self):

        if self.dialog:
            self.dialog.dismiss()

        #if not self.dialog2:
        self.dialog = MDDialog(
            title="Cooming Soon",
            text="This option is not yet available.",
            buttons=[
                MDFlatButton(text="Cancel",
                             text_color=self.theme_cls.primary_color,
                             on_press=lambda x: self.dialog.dismiss())
            ])
        self.dialog.open()