コード例 #1
0
class FileBrowser(BoxLayout):
    def __init__(self, name):
        super().__init__()
        self.orientation = "vertical"
        self.size_hint = (1, 1)

        self.scroll_body = ScrollView()
        self.add_widget(self.scroll_body)

        self.body = StackLayout(orientation="lr-tb", size_hint_y=None)
        self.scroll_body.add_widget(self.body)
        ##Settings##
        self.body.bind(minimum_height=self.body.setter('height'))

        self.draw()
        self.bind(pos=self.update_rectangles, size=self.update_rectangles)

        self.populate("placeholderforsource")

    def draw(self):
        self.canvas.before.clear()
        with self.canvas.before:
            Color(0.8, 1, 1, 1)
            self.rectangle = Rectangle(pos=self.pos, size=self.size)

    def update_rectangles(self, *args):
        self.rectangle.pos = self.pos
        self.rectangle.size = self.size

    def populate(self, source):  # a means of setting source
        for i in range(0, 10):
            self.body.add_widget(SpecialImage("placeholderfordirentry"))
コード例 #2
0
    def _create_popup(self, instance):

        content = GridLayout(cols=1, spacing='10dp')
        scrollview = ScrollView(do_scroll_x=False, size_hint=(1, 0.85))
        scrollcontent = StackLayout(size_hint=(1, None), spacing='5dp')
        scrollcontent.bind(minimum_height=scrollcontent.setter('height'))
        self.popup = popup = Popup(content=content,
                                   title=self.title,
                                   size_hint=(0.5, 0.9),
                                   auto_dismiss=False)
        popup.open()

        content.add_widget(Widget(size_hint_y=None, height=dp(2)))
        uid = str(self.uid)
        for option in self.options:
            state = 'down' if option == self.value else 'normal'
            btn = ToggleButton(text=option,
                               state=state,
                               group=uid,
                               height=dp(50),
                               size_hint=(1, None))
            btn.bind(on_release=self._set_option)
            scrollcontent.add_widget(btn)

        scrollview.add_widget(scrollcontent)
        content.add_widget(scrollview)
        btn = Button(text='Cancel', height=dp(50), size_hint=(1, None))
        btn.bind(on_release=popup.dismiss)
        content.add_widget(btn)
コード例 #3
0
 def fetchData(self, tab):
     tab.clear_widgets()
     cur.execute("SELECT id,name,due,amount FROM RECORDS")
     rows = cur.fetchall()
     rows.insert(0, ["Inv No", "Name", "Due Date", "Amount"])
     temp = ScrollView()
     root1 = StackLayout(size_hint_y=None, spacing=0, orientation="lr-tb")
     root1.bind(minimum_height=root1.setter('height'))
     i = 0
     for row in rows:
         for col in row:
             if i == 0:
                 root1.add_widget(
                     MDLabel(text=str(col),
                             height=30,
                             size_hint_x=1 / 4,
                             size_hint_y=None,
                             halign="center",
                             font_style="Body1"))
             else:
                 root1.add_widget(
                     MDLabel(text=str(col),
                             height=30,
                             size_hint_x=1 / 4,
                             size_hint_y=None,
                             halign="center",
                             font_style="Body2"))
         if i == 0:
             root1.add_widget(MDSeparator())
         i = i + 1
     temp.add_widget(root1)
     tab.add_widget(temp)
コード例 #4
0
    def display(self):
        scrolllist = []
        displist = []

        searchBar = TextInput(size_hint=(.75, .1), multiline=False)
        searchBar.bind(
            on_text_validate=lambda x: self.processQuery(searchBar.text))
        displist.append(searchBar)

        back = ColorButton("Go", (.125, .1), darkblue)
        back.bind(on_release=lambda x: self.processQuery(searchBar.text))
        displist.append(back)

        back = ColorButton("Back", (.125, .1), darkblue)
        back.bind(on_release=lambda x: self.switcher.switch("login"))
        displist.append(back)

        teamList = ScrollView(size_hint=(1, None),
                              size=(Window.width,
                                    Window.height - searchBar.height))
        displist.append(teamList)
        teamListLayout = StackLayout(size_hint_y=None)
        teamListLayout.bind(minimum_height=teamListLayout.setter('height'))
        teamList.add_widget(teamListLayout)

        database = sqlite3.connect("scoutingdatabase.db")
        cursor = database.cursor()
        cursor.execute("SELECT * FROM pitscoutingdata " + self.query)
        for teamData in cursor.fetchall():
            teamNumber = teamData[0]
            button = ColorButton(str(teamNumber), (.875, None),
                                 fairBlue,
                                 height=40)
            button.bind(on_release=self.pitScouterMainSwitch)
            scrolllist.append(button)
            hasBeenScouted = "scouted" if teamData[1] else "NOT SCOUTED"
            labelBackground = green if teamData[1] else red
            label = ColorLabel(hasBeenScouted, (.125, None),
                               labelBackground,
                               height=40)
            scrolllist.append(label)
        database.close()

        addTeam = ColorButton("add team", (.5, None), darkblue, height=40)
        addTeam.bind(on_release=lambda x: self.addPitRobot(addText.text))
        scrolllist.append(addTeam)
        addText = TextInput(text=str(""),
                            multiline=False,
                            size_hint=(.5, None),
                            height=40)
        addText.bind(on_validate_text=lambda x: self.addPitRobot(addText.text))
        scrolllist.append(addText)

        for widget in scrolllist:
            teamListLayout.add_widget(widget)

        self.clear_widgets()
        for widget in displist:
            self.add_widget(widget)
コード例 #5
0
ファイル: gui.py プロジェクト: geracobo/PyPiano
class LogBox(ScrollView):
    _current_selection = 0


    def __init__(self, root):
        super(LogBox, self).__init__()
        self.root = root
        self.size_hint = (1, None)
        self.height = 150

        self.stack = StackLayout()
        self.stack.orientation = 'lr-tb'
        self.stack.size_hint = (1, None)
        self.stack.bind(minimum_height=self.stack.setter('height'))

        self.add_widget(self.stack)



    def add(self, note):
        self.stack.add_widget(LogEntry(note))

    def get_entry(self, at):
        if at == 0:
            return None
        if at > len(self.stack.children):
            return None
        return self.stack.children[len(self.stack.children)-at]
    def get_current_entry(self):
        return self.get_entry(self.current_selection)

    @property
    def current_selection(self):
        return self._current_selection
    @current_selection.setter
    def current_selection(self, value):
        for child in self.stack.children:
            child.color = [1,1,1,1]

        if value > len(self.stack.children):
            self._current_selection = 0
            return

        self._current_selection = value
        self.stack.children[len(self.stack.children)-value].color = [1,0,0,1]

        # We send a KEY ON signal for each note
        # only if we are on play mode.
        # Reset done status for each note.
        if self.root.app.playing:
            for note in self.get_current_entry().notes:
                note['done'] = False
                arduino.send(str.format("+{0}", note['note']))
コード例 #6
0
    def createStack(self):
        """Works out how to display the league matches.

        Layout depends on the number of matches found.
        """
        matches = self.leagueobject.LeagueMatches
        x = len(matches)

        # Single column, no scrolling
        if x <= 10:
            self.spacer = True
            w = 1
            scroll = False
            self.h = 42 * x

        # Dual columns, no scrolling
        elif x <= 20:
            self.spacer = False
            w = 0.5
            scroll = False
            self.h = round(x/2.0) * 42

        # Dual columns, scrolling
        else:
            self.spacer = False
            w = 0.5
            scroll = True
            self.h = round(x/2.0) * 42

        # Create a stack layout
        stack = StackLayout(orientation="tb-lr",
                            size_hint_y=None,
                            height=self.h)

        stack.bind(minimum_height=stack.setter('height'))

        # Add the league matches to it.
        for l in matches:
            lg = LeagueGame(match=l, size_hint=(w, None))
            stack.add_widget(lg)

        # Create a scroll view
        scroll = ScrollView(size_hint=(1, 1))
        scroll.add_widget(stack)

        return scroll
コード例 #7
0
ファイル: gui.py プロジェクト: lioulun/livikit
class LivikitLines(ScrollView):
    def __init__(self, **kwargs):
        super(LivikitLines, self).__init__(**kwargs)

        self.do_scroll_y = True

        self.layout = StackLayout(orientation='lr-tb', size_hint_y=None)
        self.layout.bind(minimum_height=self.layout.setter('height'))
        self.add_widget(self.layout)

        self.add_info('Time', 'Text')

    def add_info(self, text1, text2):
        line = BoxLayout(size_hint_y=None, height=35)

        line.add_widget(Label(text=text1, size_hint_x=None, width=210))
        line.add_widget(Label(text=text2))

        self.layout.add_widget(line)

    def add_item(self, begin, end, text):
        line = BoxLayout(size_hint_y=None, height=63)

        time_part = BoxLayout(orientation='vertical')
        time_part.size_hint_x = None
        time_part.width = 210
        time_part.add_widget(self.new_label_time('begin', begin))
        time_part.add_widget(self.new_label_time('  end', end))
        line.add_widget(time_part)

        line.add_widget(TextInput(text=text, font_name=FONT_NAME))

        self.layout.add_widget(line)

    def new_label_time(self, label, text):
        pair = BoxLayout()
        pair.add_widget(Label(text=label, size_hint_x=None, width=49))
        pair.add_widget(TextInput(text=text, multiline=False, halign='center'))
        return pair
コード例 #8
0
class MP3k(Widget):
    playlist_width = NumericProperty()

    def __init__(self, **kwargs):
        Globals.CONFIG = App.get_running_app().config
        Globals.TESTING = Globals.CONFIG.get('Development', 'test_mode')

        self.playlist_width = int(
            Globals.CONFIG.get('Playlist', 'playlist_width'))

        Globals.API = GoogleMusicApi()
        self.login_failed_popup = None
        self.google_music_api_login()

        self.formatter = Formatter()

        self.player = Player()
        self.player.set_streaming_quality(
            Globals.CONFIG.get('Google Play Music', 'quality').split(':')[0])

        self.playlist = Playlist()

        self.librarymanager = LibraryManager()
        # self.librarymanager.load_library()

        self.history = History()
        self.playlist.queue = self.history.playlist_history

        self.updating_progress = False
        self.playlist_hidden = False

        super().__init__(**kwargs)
        self.player.bind(playing=self.update_play_button_state)
        self.player.bind(progress_percent=self.update_progress_slider)

        # Add search result views
        # Songs
        self.songlist = SongViewer()

        # Stations
        # self.stationlist = StationViewer()
        self.stationscroll = ScrollView(size_hint=(1, 1))
        self.stationscroll.do_scroll_x = False
        self.stationlist = StackLayout(size_hint_y=None, spacing=10)
        self.stationlist.bind(minimum_height=self.stationlist.setter('height'))
        self.stationscroll.add_widget(self.stationlist)

        # Albums
        self.albumlist = AlbumViewer()
        # Create and init screen manager
        self.sm = ScreenManager()
        self.init_screens()

        # Listen for Keyboard events
        self._keyboard = Window.request_keyboard(None, self, 'text')
        self._keyboard.bind(on_key_down=self._pressed_key)
        self.searchbar.focus = True

    def google_music_api_login(self):
        if Globals.API.login(
                Globals.CONFIG.get('Google Play Music', 'login'),
                Globals.CONFIG.get('Google Play Music', 'password'),
                Globals.CONFIG.get('Google Play Music', 'device_id')):
            Logger.debug('Google Music: Login successful')
            if self.login_failed_popup:
                self.login_failed_popup.dismiss()
                self.login_failed_popup = None
        else:
            Logger.warning("Google Music: Login Failed")
            if not self.login_failed_popup:
                popup = Popup(title='Google Play Music™ login',
                              content=LoginCredentials(),
                              auto_dismiss=False,
                              size_hint=(1, 1))
                self.login_failed_popup = popup

            if Globals.STARTED:  # login failed after configuration change
                self.login_failed_popup.open(
                )  # open popup because MP3k is completely rendered
                App.get_running_app().close_settings()

            else:  # login failed on start
                pass  # wait with popup until MP3k is completely rendered (MP3kApp opens the popup in on_start())

    def try_login_step_1(self, instance, google_login, google_password):
        # Credentials login without device ID
        if Globals.API.login(google_login, google_password, ''):
            # login successful
            Globals.CONFIG.set('Google Play Music', 'login', google_login)
            Globals.CONFIG.set('Google Play Music', 'password',
                               google_password)
            Globals.CONFIG.write()

            self.show_device_login()

        else:
            instance.login_failed_label.color = (1, 0, 0, 1)

    def try_login_step_2(self, button_container):
        # look for selected device
        for button in button_container.children:
            if button.state == 'down':  # got it
                Globals.CONFIG.set('Google Play Music', 'device_id',
                                   button.device_id)
                Globals.CONFIG.write()  # set device id in config

                if Globals.API.relogin(
                        Globals.CONFIG.get(
                            'Google Play Music',
                            'login'),  # re-login with valid device_id
                        Globals.CONFIG.get('Google Play Music', 'password'),
                        Globals.CONFIG.get('Google Play Music', 'device_id')):
                    self.login_failed_popup.dismiss()
                    break
        else:
            Logger.error('LOGIN: You have to select a device!')

    def show_device_login(self):
        self.login_failed_popup.dismiss()
        self.login_failed_popup = Popup(title='Google Play Music™ login',
                                        content=self.build_devices_login(),
                                        auto_dismiss=False,
                                        size_hint=(1, 1))
        self.login_failed_popup.open()

    @staticmethod
    def build_devices_login():
        devices = Globals.API.get_registered_mobile_devices(
        )  # get registered mobile devices
        login_devices = LoginDevices()

        # add buttons for devices
        for device in devices:
            btn = DeviceButton(text='{} (ID: {})'.format(
                device['name'], device['id']),
                               device_id=device['id'],
                               size_hint_y=None,
                               height=30,
                               group='devices')
            login_devices.device_button_container.add_widget(btn)

        return login_devices

    def init_screens(self):

        # Create screens
        screen_songs = Screen(name='Songs', size_hint=(1, 1))
        screen_stations = Screen(name='Stations', size_hint=(1, 1))
        screen_albums = Screen(name='Albums', size_hint=(1, 1))

        # Add content to screens
        screen_songs.add_widget(self.songlist)
        # screen_stations.add_widget(self.stationlist)
        screen_stations.add_widget(self.stationscroll)
        screen_albums.add_widget(self.albumlist)

        # Add screens
        self.sm.add_widget(screen_songs)
        self.sm.add_widget(screen_stations)
        self.sm.add_widget(screen_albums)

        # Add screen manager and playlist
        self.screenmanagercontainer.add_widget(self.sm)

    def _pressed_key(self, keyboard, keycode, text, modifiers):
        if not self.searchbar.focus:
            if keycode[1] == 'spacebar' or keycode[0] == 1073742085:
                Logger.debug('Keyboard: Pressed spacebar/play-pause-media-key')
                self.playbutton_callback()
            elif keycode[0] == 1073742083:  # 'previous track' media key
                Logger.debug("Keyboard: Pressed 'previous track' media key")
                self.previousbutton_callback()
            elif keycode[0] == 1073742082:  # 'next track' media key
                Logger.debug("Keyboard: Pressed 'next track' media key")
                self.nextbutton_callback()
            #else:
            #    print(keycode)

    def update_play_button_state(self, instance, value):
        if value:
            self.playbutton.icon = '../res/icons/glyphicons-175-pause_white.png'
        else:
            self.playbutton.icon = '../res/icons/glyphicons-174-play_white.png'

    def update_progress_slider(self, instance, value):
        self.progress_slider.value = value

    def update_playlist_position(self, window, width, height):
        self.playlist_view.pos_hint = {'x': .3, 'y': 90.0 / height}

    def update_playlist_view(self, instance, value):
        print('Updating playlist..')
        print('data_queue before: ' + str(len(self.playlist_view.data_queue)))
        # self.playlist_view.data_queue = self.playlist.queue  # ListView should be updated if we do it like this..
        self.playlist_view.children[0].adapter.data.clear(
        )  # ..but it isn't, so we do this
        self.playlist_view.children[0].adapter.data.extend(
            self.playlist.queue)  # and then this
        # self.playlist_view.content.listview.adapter.data = self.playlist.queue  # never do this, it replaces the
        # ObservableList and breaks kivy functionality
        print('data_queue after: ' + str(len(self.playlist_view.data_queue)))

    def _update_progress_interval(self, delta_time):
        if not self.updating_progress:
            self.updating_progress = True

            if self.player.current_track and self.player.playback_started and self.player.playing:
                # time_played_ms = pygame.mixer.music.get_pos()
                # duration_ms = int(self.musicmanager.current_track['duration_ms'])
                # progress = time_played_ms / (duration_ms / 100)

                progress_percent = self.player.send_cmd_to_mplayer(
                    'get_percent_pos', 'ANS_PERCENT_POSITION')
                if progress_percent is not False and progress_percent is not None:
                    old_progress_percent = self.player.progress_percent
                    self.player.progress_percent = interpolate(
                        old_progress_percent, int(progress_percent))
                    Logger.trace('Progress: ' +
                                 str(self.player.progress_percent))
                elif progress_percent is False:
                    Logger.debug('_update_progress_interval: Received ' +
                                 str(progress_percent) + ' as progress')
                    self.player.playback_finished()
                    self.play_next_track()
                else:
                    Logger.debug('_update_progress_interval: Received ' +
                                 str(progress_percent) + ' as progress')

            # remove schedule if no track selected
            elif not self.player.playback_started and not self.player.playing:
                Logger.debug(
                    'No song playing, removing slider update interval..')
                self.updating_progress = False
                return False

            self.updating_progress = False

    def on_config_changed(self, section, key, value):
        Logger.debug('Config: Config changed')

        if key == 'playlist_width':
            self.playlist_width = int(value)

        elif section == 'Google Play Music':
            Globals.API.logout()
            self.google_music_api_login()

        elif section == 'Development':
            if key == 'test_mode':
                Globals.TESTING = True if value == '1' else False

    def fix_scrolling_workaround(self):
        self.playlist_view.listview._reset_spopulate()

    def playbutton_state(self):
        Logger.debug('Playbuttonstate: ' + self.playbutton.state)
        return 'down' if self.player.playing else 'normal'

    def mark_playing_track(self):
        # track_item = self.playlist_view.get_track(0)
        # track_item.update_image('../res/icons/equalizer.gif')
        playing_text = '{} - {}'.format(self.player.current_track['title'],
                                        self.player.current_track['artist'])

        self.playinglabel.text = playing_text
        App.get_running_app().title = playing_text

    def restart_track(self):
        Logger.info('Restarting track..')
        self.play_track(self.player.current_track)

    def play_previous_track(self):
        Logger.info('Playing previous track')
        track = self.playlist.get_previous_track()
        if track:
            self.play_track(track)

    def play_next_track(self):
        Logger.info('Playing next track')
        track = self.playlist.get_next_track()
        if track:
            self.play_track(track)
        else:
            App.get_running_app(
            ).title = 'MusicPlayer 3000 for Google Play Music™'

    def switch_screen_callback(self, screen_title):
        self.sm.current = screen_title

    def play_callback(self, track, index):
        Logger.debug('Playing from songlist (left): Index ' + str(index))
        self.playlist.add_track_and_set_current(track)
        self.fix_scrolling_workaround()
        self.play_track(track)

    def play_album_callback(self, album_id):
        index = len(self.playlist.queue)
        self.add_album_to_playlist_callback(album_id)
        idx, track = self.playlist.set_current_track(index)
        self.play_track(track)

    def play_from_playlist_callback(self, track, index):
        Logger.debug('Playing from playlist (right): Index ' + str(index))
        self.playlist.set_current_track(index)
        self.play_track(track)

    def play_track(self, track):
        Logger.info('Playing track: ' + track['title'])
        self.player.play_track_from_id(track)
        self.mark_playing_track()
        # self.set_playing_icon()
        # unschedule possible previous intervals
        Clock.unschedule(self._update_progress_interval)
        # start interval for updating the progress slider
        Clock.schedule_interval(self._update_progress_interval, .1)

    def set_playing_icon(self):
        index, current_track = self.playlist.get_current_track()
        # self.playlist_view.children[0].adapter.data[index]

    def playbutton_callback(self):
        if self.player.current_track:  # we have a track selected
            if self.player.playback_started and self.player.playing:  # pause track
                self.player.pause_current_track()
            elif self.player.playback_started and not self.player.playing:  # resume track
                self.player.resume_current_track()
            else:  # playback has finished, restart track
                self.restart_track()
        else:  # No track selected but maybe we have elements in the playlist
            Logger.debug('No current track set!')
            track = self.playlist.get_start()
            if track:
                self.play_track(track)
            else:  # do nothing if no track selected
                #self.librarymanager.synchronize_library()
                pass

    def nextbutton_callback(self):
        if self.player.current_track:  # we have a track selected
            self.play_next_track()
        else:  # No track selected but maybe we have some in the playlist
            Logger.debug('No current track set!')
            track = self.playlist.get_start()
            if track:
                self.play_track(track)
            else:  # do nothing if no track selected
                pass

    def previousbutton_callback(self):
        if self.player.current_track:  # we have a track selected
            self.play_previous_track()
        else:  # No track selected but maybe we have some in the playlist
            Logger.debug('No current track set!')
            track = self.playlist.get_start()
            if track:
                self.play_track(track)
            else:  # do nothing if no track selected
                pass

    def shufflebutton_callback(self):
        if self.playlist.shuffle:
            Logger.info("I won't shuffle anymore..")
            self.playlist.shuffle = False
            self.shufflebutton.source = self.shufflebutton.source_img_alt
        else:
            Logger.info("Everyday I'm shuffling..")
            self.playlist.shuffle = True
            self.shufflebutton.source = self.shufflebutton.source_img

    def skip_callback(self, touch_pos):
        width = self.progress_slider.width
        touch_pos_x = touch_pos[0]
        position = touch_pos_x / (width / 100)
        if self.player.current_track:  # we need a track to skip into
            if not self.player.playback_started:  # song is not playing, restart song
                self.restart_track()
            self.player.skip_track_to(position)  # skip to position
        else:
            # self.progress_slider.value = 0  # keep slider position at 0
            # TODO: Look into slider implementation to keep slider at 0
            pass

    def add_to_playlist_callback(self, track):
        self.playlist.add_track(QueryDict(track))
        self.fix_scrolling_workaround()

    def remove_from_playlist_callback(self, index):
        self.playlist.remove_track(index)

    def add_album_to_playlist_callback(self, album_id):
        album = Globals.API.get_album_info(album_id)
        album_tracks = album['tracks']
        if album_tracks:
            album_tracks = self.formatter.format_tracks_list(album_tracks)
            for track in album_tracks:
                self.playlist.add_track(QueryDict(track))
            self.fix_scrolling_workaround()

    def play_station_callback(self, title, seed):
        tracks = Globals.API.get_station_tracks(title, seed)
        if tracks:
            tracks = self.formatter.format_tracks_list(tracks)
            self.playlist.clear()
            for track in tracks:
                self.playlist.add_track(track)
            self.fix_scrolling_workaround()
            # self.playlist.set_current_track(0)
            #self.playbutton_callback()
            track = self.playlist.get_start()
            if track:
                self.play_track(track)
            else:  # do nothing if no track selected
                pass

    def playlist_button_callback(self):
        if self.playlist_hidden:
            self.playlist_container.width = self.playlist_width
            self.playlist_hidden = False
        else:
            self.playlist_container.width = 0
            self.playlist_hidden = True

    def clear_playlist_callback(self):
        Logger.info('Clearing playlist')
        self.playlist.clear()
        # self.playlist.set_current_track(0)

    def search(self, text):
        if len(text) >= 3:
            try:
                search_results = Globals.API.search(text)
                # with open('search_test.json', 'w') as outfile:
                #    json.dump(search_results, outfile)

                self.display_search_results(search_results)
            except CallFailure:
                Logger.warning("Search: No All Access for this account!")
                # TODO: Show login popup
                # TODO: Remove try..except block when gmusicapi 9.0.1 is stable
        else:
            with open('search_test.json') as outfile:
                search_results = json.load(outfile)
                self.display_search_results(search_results)

    def display_search_results(self, search_results):
        Logger.info("Displaying results..")

        Logger.debug("Displaying song results")
        tracks = []
        for entry in search_results['song_hits']:
            tracks.append(entry['track'])
        # songs_sorted = sorted(songs, key=self.get_song_key)
        tracks_formatted = self.formatter.format_tracks_list(tracks)
        # self.ids['list_songs'].data_songs = tracks_formatted
        self.songlist.data_songs = tracks_formatted

        Logger.debug("Displaying station results")
        stations = []
        for entry in search_results['station_hits']:
            stations.append(entry['station'])
        stations_formatted = self.formatter.format_stations_list(stations)

        # add station list items
        # self.stationlist.data_stations = stations_formatted

        # add station panels
        self.stationlist.clear_widgets()
        for station in stations_formatted:
            self.stationlist.add_widget(StationPanelItem(station))

        Logger.debug("Displaying album results")
        albums = []
        for entry in search_results['album_hits']:
            albums.append(entry['album'])
        albums_formatted = self.formatter.format_albums_list(albums)
        self.albumlist.data_albums = albums_formatted
コード例 #9
0
ファイル: try-again.py プロジェクト: iangmhill/CrashCourse
class Catalog(BoxLayout):
    def __init__(self,**kwargs):
        super(Catalog, self).__init__(**kwargs)       

        #self.orientation = 'vertical'

        self.search_bar = BoxLayout(size_hint=(1.0,0.05))        
        self.search_bar.add_widget(Label(text='Search',size_hint=(0.25,1.0)))
        self.search_text = (TextInput(multiline=False))
        self.search_bar.add_widget(self.search_text)

        self.filter_bar = BoxLayout(size_hint=(1.0,0.05))        
        self.AHSE = ToggleButton(text='AHSE',size_hint=(0.25,1.0))
        self.ENGR = ToggleButton(text='ENGR',size_hint=(0.25,1.0))
        self.MTH = ToggleButton(text='MTH',size_hint=(0.25,1.0))
        self.SCI = ToggleButton(text='SCI',size_hint=(0.25,1.0))        
        self.filter_bar.add_widget(self.AHSE)
        self.filter_bar.add_widget(self.ENGR)
        self.filter_bar.add_widget(self.MTH)
        self.filter_bar.add_widget(self.SCI)

        self.scrollview = ScrollView(size_hint=(1.0,0.9),size=(400,400))
        self.courses = StackLayout(spacing=5,size_hint_y=None)
        self.courses.bind(minimum_height=self.courses.setter('height'))
        for course_object in catalog:
            course_item = Course_Item(course=course_object,size_hint=(0.245,None),height=200)                             
            self.courses.add_widget(course_item)
        self.scrollview.add_widget(self.courses)
                        
        self.add_widget(self.search_bar)
        self.add_widget(self.filter_bar)
        self.add_widget(self.scrollview)

        Clock.schedule_interval(self.update_favorites,0.1)
        Clock.schedule_interval(self.search_function,0.1)


    def search_function(self,instance):
        query = self.search_text.text.lower()        
        searched_items = []
        filtered_items = []

        #fills up the temp list the first time it runs
        if len(search_temp_list) == 0:
            for course_item in self.courses.children:
                search_temp_list.append(course_item)       
        
        #if the query is not empty, do term search
        if query != "":                      
            for course_item in search_temp_list:                            
                if query == course_item.course.name.lower() or query == course_item.course.code or query == course_item.course.prof.lower():
                    searched_items.append(course_item)
                for keyword in course_item.course.keywords:
                    if query == keyword.lower():                        
                        searched_items.append(course_item)           
        else:
            searched_items = search_temp_list
        
        if self.AHSE.state == 'normal' and self.ENGR.state == 'normal' and self.MTH.state == 'normal' and self.SCI.state == 'normal':
            filtered_items = searched_items

        else:                                
            if self.AHSE.state == 'down':
                for course_item in searched_items:                   
                    if course_item.course.credits['AHSE'] > 0:                                                  
                        filtered_items.append(course_item)
            if self.ENGR.state == 'down': 
                for course_item in searched_items:                      
                    if course_item.course.credits['ENGR'] > 0 and course_item not in filtered_items:                                                  
                        filtered_items.append(course_item)
            if self.MTH.state == 'down':                          
                for course_item in searched_items:
                    if course_item.course.credits['MTH'] > 0 and course_item not in filtered_items:                                                 
                        filtered_items.append(course_item)
            if self.SCI.state == 'down':
                for course_item in searched_items:                   
                    if course_item.course.credits['SCI'] > 0 and course_item not in filtered_items:                                             
                        filtered_items.append(course_item)

        if len(self.courses.children) != len(filtered_items):
            self.courses.clear_widgets()
            for course_item in filtered_items:
                self.courses.add_widget(course_item)   

    def update_favorites(self,instance):        
        for course_item in self.courses.children:
            if course_item.favorite.state == 'normal' and course_item.course in favorite_courses:
                favorite_courses.remove(course_item.course)
            if course_item.favorite.state == 'down' and course_item.course not in favorite_courses:
                favorite_courses.append(course_item.course)                
コード例 #10
0
ファイル: eventwidget.py プロジェクト: victor-rene/yes-group
class EventListbox(StackLayout):

  def __init__(self, **kwargs):
    super(EventListbox, self).__init__(**kwargs)
    self.is_updating = False
    self.orientation = 'lr-tb'
    self.items = []
    self.bind(pos=self.draw, size=self.draw)
    self.data_bindings = dict()
    self.selected_view = None
    self.selected_item = None
    # content
    self.content = StackLayout(orientation = 'lr-tb')
    self.content.size_hint_y = None #for scrollviewer
    self.content.bind(minimum_height=self.content.setter('height'))
    self.scrollview = ScrollView(size_hint=[1, 1])
    self.scrollview.do_scroll_x = False
    self.scrollview.add_widget(self.content)
    self.add_widget(self.scrollview)
    
  def begin_update(self):
    self.is_updating = True
    
  def end_update(self):
    self.is_updating = False
    self.draw()
    
  def add_item(self, item):
    self.items.append(item)
    if not self.is_updating:
      self.draw()
    
  def clear_items(self):
    del self.items[:]
    self.clear_selection()
    self.draw()
    
  def clear_selection(self):
    self.selected_view = None
    self.selected_item = None
    
  def draw(self, *args):
    self.content.clear_widgets()
    self.data_bindings.clear()
    n = len(self.items)
    i = 0
    while i < n:
      item_wgt = EventWidget(self.items[i])
      item_wgt.height = self.height/4
      item_wgt.size_hint = [1, None] #for scrollviewer parent
      item_wgt.bind(on_touch_down=self.selection_change)
      self.content.add_widget(item_wgt)
      self.data_bindings[item_wgt] = self.items[i]
      i += 1
    # self.draw_background()
      
  def selection_change(self, instance, touch):
    for item_wgt in self.content.children:
      if item_wgt.collide_point(touch.x, touch.y):
        self.selected_view = item_wgt
        self.selected_item = self.data_bindings[item_wgt]
コード例 #11
0
class HistToolApp(App):

    autosave_file_name = 'last_settings.hst'

    def __init__(self):
        super().__init__()
        self.models = []
        self.histLayout = None
        self.scrollView = None
        self.usedIDs = []
        self.all_settings = defaultdict(int)
        self.currID = self.loadSettings()
        self.initLayoutHeight = 10
        Window.bind(on_resize=self._on_resize)

    def saveSettings(self, fname=autosave_file_name):
        saved_settings = [
            self.all_settings[key] for key in self.all_settings
            if self.all_settings[key] != 0
        ]
        #print(saved_settings)
        with open(fname, 'w') as f:
            for item in saved_settings:
                f.write("%s\n" % item)

    def loadSettings(self, fname=autosave_file_name):
        idx = 0
        self.all_settings = defaultdict(int)
        with open(fname, 'r') as f:
            for line in f:
                self.all_settings[idx] = (eval(line))
                idx += 1
        return idx

    def build(self):

        if self.root is not None:
            self.root.clear_widgets()

        add_hist_button = Button(text='Add Histogram',
                                 font_size=14,
                                 on_press=self.addHistogram)
        create_hists_button = Button(text='Create Graphs',
                                     font_size=14,
                                     on_press=self.createHistograms)
        save_hists_button = Button(text='Save Histograms',
                                   font_size=14,
                                   on_press=self._save_button)
        load_hists_button = Button(text='Load Histograms',
                                   font_size=14,
                                   on_press=self._load_button)
        save_and_load = BoxLayout(orientation='vertical')
        save_and_load.add_widget(save_hists_button)
        save_and_load.add_widget(load_hists_button)

        btnLayout = BoxLayout(size_hint=(1, None), height=50)
        btnLayout.add_widget(add_hist_button)
        btnLayout.add_widget(create_hists_button)
        btnLayout.add_widget(save_and_load)

        self.scrollView = ScrollView(size_hint=(1, 1))
        self.scrollView.do_scroll_x = False
        self.histLayout = StackLayout(orientation='tb-lr')
        self.histLayout.size_hint = (1, None)
        self.histLayout.height = self.initLayoutHeight
        self.histLayout.bind(minimum_height=self.histLayout.setter('height'))
        self.scrollView.add_widget(self.histLayout)

        self.root = BoxLayout(orientation='vertical')
        self.root.add_widget(self.scrollView)
        self.root.add_widget(btnLayout)
        self.updateHistList()
        return self.root

    def _load_button(self, instance):
        filename = askopenfilename(
        )  # show an "Open" dialog box and return the path to the selected file
        if filename == '':
            return
        self.idx = self.loadSettings(filename)
        self.updateHistList()

    def _save_button(self, instance):
        filename = asksaveasfilename(
        )  # show an "Open" dialog box and return the path to the selected file
        if filename == '':
            return
        self.saveSettings(filename)
        self.updateHistList()

    def updateModels(self):
        self.models = []
        for key in self.all_settings:
            if self.all_settings[key] != 0:
                model = self.createModel(self.all_settings[key])
                self.models.append(model)

    def parseEvalString(self, string):
        varSt = 0
        varEnd = 0
        varReplacements = [
            'x', 'y', 'z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j',
            'k'
        ]
        vars = []
        remainingBrackets = True
        while remainingBrackets == True:
            remainingBrackets = False
            for idx, c in enumerate(string):
                if c == "{":
                    remainingBrackets = True
                    varSt = idx
                elif c == "}":
                    varEnd = idx
                    retVar = string[varSt + 1:varEnd]

                    if retVar in vars:
                        inserted = varReplacements[vars.index(retVar)]
                    else:
                        vars.append(retVar)
                        inserted = varReplacements[len(vars) - 1]

                    string = string[:varSt] + inserted + string[varEnd + 1:]
                    break

        if string == "":
            return None
        return (vars, "lambda " + ",".join(varReplacements[:len(vars)]) +
                " : " + string)

    def createModel(self, settings):
        eval_params1 = self.parseEvalString(settings[3])
        eval_params2 = self.parseEvalString(settings[5])
        if eval_params1 is None or eval_params2 is None:
            print("No evaluation parameters found. Histogram cancelled.")
            return

        #print(eval_params1)
        #print(eval_params2)

        model = hist_model()

        model.addTargetQuantity(settings[1])
        model.addParameter(0, eval_params1[0], eval(eval_params1[1]))
        model.addParameter(1, eval_params2[0], eval(eval_params2[1]))
        model.changeLog(settings[6])
        model.changeTitle(settings[0])
        model.changeLabels((settings[2], settings[4]))
        return model

    def addHistogram(self, instance):
        settings = histogram_screen()
        if settings == None:
            return
        elif None in settings or "" in settings:
            print("Error: at least one field was left blank.")
            return
        #['title', 'ID', 'label1', 'boolean1', 'label2', 'boolean2', True]
        #0           1       2           3           4       5           6

        self.all_settings[self.currID] = settings
        #displayed_settings[self.currID] = False
        self.currID += 1

        self.updateHistList()

    def createHistograms(self, instance):
        self.updateModels()
        hstats = hist_stats("results_with_data.csv")
        for model in self.models:
            hstats.addHistObject(model)

        hstats.execute()

    def editHist(self, key):
        setting = self.all_settings[key]
        new_setting = histogram_screen(*setting)
        if new_setting == None:
            new_setting = setting
        elif None in new_setting or "" in new_setting:
            print("Error: at least one field was left blank.")
            new_setting = setting
        self.all_settings[key] = new_setting
        #displayed_settings[key] = False
        self.updateHistList()

    def duplicateHist(self, key):
        print("CurrID: " + str(self.currID))
        self.all_settings[self.currID] = self.all_settings[key]
        self.currID += 1
        self.updateHistList()

    def updateHistList(self):
        #for widget in self.histLayout.children:
        #   print(widget.setting_id)
        #self.histLayout.remove_widget(widget)
        self.histLayout.clear_widgets()

        for key in range(self.currID + 1):
            if key in self.all_settings and self.all_settings[key] != 0:
                self.histLayout.add_widget(
                    HistDescriptor(self.all_settings[key][0],
                                   self,
                                   key,
                                   size_hint=(None, None)))

        self.histLayout.height = self.initLayoutHeight
        for child in self.histLayout.children:
            self.histLayout.height += child.height

        self.histLayout.bind(minimum_height=self.histLayout.setter('height'))

        self.saveSettings()
        print("HistLayout height: " + str(self.histLayout.height))

    def _on_resize(self, instance, w, h):
        self.root.size = (w, h)
        self.updateHistList()
コード例 #12
0
    def create(self, screen_manager):

        top_layout = AnchorLayout(size_hint=(1, 0.4), anchor_x='center', anchor_y='top')
        top = self.Top(size_hint=(1, 1), anchor_x='center', anchor_y='bottom')
        top.create()
        button_layout = AnchorLayout(size_hint=(1, 1), padding=(dp(20), dp(20), dp(20), dp(20)), anchor_x='left', anchor_y='top', opacity=0.5)
        back_button = BackButton()
        back_button.bind(on_release=lambda instance: setattr(screen_manager, 'current', 'RV'))
        button_layout.add_widget(back_button)
        top.add_widget(button_layout)
        top_layout.add_widget(top)

        self.float_layout.bind(images=lambda instance, value: top.insert_images(instance, value))

        background = AnchorLayout(size_hint=(1, 1), anchor_x='center', anchor_y='center')
        vertical_scroll_view = ScrollView(do_scroll=(False, True), size_hint=(1, 1), bar_inactive_color=(0, 0, 0, 0), bar_color=(0, 0, 0, 0))
        vertical_grid_layout = GridLayout(cols=1, size_hint=(1, None), padding=(dp(20), dp(20), dp(20), dp(20)))
        vertical_grid_layout.bind(minimum_height=vertical_grid_layout.setter('height'))
        details_layout = StackLayout(size_hint=(1, None), spacing=dp(20), padding=(dp(0), dp(20), dp(0), dp(0)))
        details_layout.bind(minimum_height=details_layout.setter('height'))

        author = CustomLabel(type='Author', txt=str(self.float_layout.author))
        self.float_layout.bind(author=lambda instance, value: setattr(author, 'txt', value))

        age = CustomLabel(type='Age', txt=str(self.float_layout.age))
        self.float_layout.bind(age=lambda instance, value: setattr(age, 'txt', value))

        breed = CustomLabel(type='Breed', txt=str(self.float_layout.breed))
        self.float_layout.bind(breed=lambda instance, value: setattr(breed, 'txt', value))

        location = CustomLabel(type='Location', txt=str(self.float_layout.location))
        self.float_layout.bind(location=lambda instance, value: setattr(location, 'txt', value))

        color = CustomLabel(type='Color', txt=str(self.float_layout.color))
        self.float_layout.bind(color=lambda instance, value: setattr(color, 'txt', value))

        date = CustomLabel(type='Date', txt=str(self.float_layout.date))
        self.float_layout.bind(date=lambda instance, value: setattr(date, 'txt', value))

        gender = CustomLabel(type='Gender', txt=str(self.float_layout.gender))
        self.float_layout.bind(gender=lambda instance, value: setattr(gender, 'txt', value))

        #petid = CustomLabel(type='Pet ID', txt=str(self.float_layout.petid))
        #self.float_layout.bind(petid=lambda instance, value: setattr(petid, 'txt', value))

        size = CustomLabel(type='Size', txt=str(self.float_layout.pet_size))
        self.float_layout.bind(pet_size=lambda instance, value: setattr(size, 'txt', value))

        status = CustomLabel(type='Status', txt=str(self.float_layout.status))
        self.float_layout.bind(status=lambda instance, value: setattr(status, 'txt', value.title()))

        zip = CustomLabel(type='Zip', txt=str(self.float_layout.zip))
        self.float_layout.bind(zip=lambda instance, value: setattr(zip, 'txt', value))

        details_layout.add_widget(author)
        details_layout.add_widget(age)
        details_layout.add_widget(breed)
        details_layout.add_widget(location)
        details_layout.add_widget(color)
        details_layout.add_widget(date)
        details_layout.add_widget(gender)
        #details_layout.add_widget(petid)
        details_layout.add_widget(size)
        details_layout.add_widget(status)
        details_layout.add_widget(zip)

        name_layout = AnchorLayout(size_hint=(1, None), height=dp(30), anchor_x='center', anchor_y='center')
        pet_name = CustomName(name=str(self.float_layout.name))
        self.float_layout.bind(name=lambda instance, value: setattr(pet_name, 'name', value))
        pet_name.bind(size=pet_name.setter('text_size'))
        name_layout.add_widget(pet_name)

        summary_layout = AnchorLayout(size_hint=(1, None), height=dp(42), anchor_x='center', anchor_y='center', padding=(dp(0), dp(0), dp(0), dp(20)))
        summary = Label(halign='left', valign='center', color=get_color_from_hex('#6e7c97'), font_size=dp(16), font_name='assets/Inter-SemiBold.ttf', text='Summary')
        summary.bind(size=summary.setter('text_size'))
        summary_layout.add_widget(summary)

        vertical_grid_layout.add_widget(name_layout)
        vertical_grid_layout.add_widget(details_layout)
        vertical_grid_layout.add_widget(summary_layout)
        summary_label = SummaryLabel()
        vertical_grid_layout.add_widget(summary_label)

        self.float_layout.bind(summary=lambda instance, value: setattr(summary_label, 'text', value))

        vertical_scroll_view.add_widget(vertical_grid_layout)
        background.add_widget(vertical_scroll_view)

        bottom_layout = AnchorLayout(size_hint=(1, 0.5), anchor_x='center', anchor_y='bottom')
        bottom_layout.add_widget(background)

        pin_and_message_layout = BoxLayout(size_hint=(1, None), height=dp(65), orientation='horizontal')
        message_button = MessageButton(icon='', text='Message', color=get_color_from_hex('#023b80'), padding=(dp(20), dp(20), dp(20), dp(0)))
        message_button.on_release = lambda: self.message_callback(self.root_sm)
        pin_and_message_layout.add_widget(message_button)

        self.float_layout.add_widget(top_layout)
        self.float_layout.add_widget(bottom_layout)
        self.float_layout.add_widget(pin_and_message_layout)

        return self.float_layout
コード例 #13
0
class Catalog(BoxLayout):
    """Tab that displays available courses and allows user to search for, see details about, and add courses to planner tab"""
    def __init__(self,sm,**kwargs):
        super(Catalog,self).__init__(**kwargs)
        self.orientation = 'vertical'
        self.sm = sm

        ## Search Bar ##
        self.search_bar = BoxLayout(size_hint=(1.0,0.05))
        self.search_text = TextInput(multiline=False,size_hint =(0.6,1.0))
        self.create_course_popup = Build_Course(self.sm)
        self.create_course_button = Button(text='Create a Course',size_hint=(0.2,1.0),on_press=self.create_course_popup.open_pop_up)        
        self.search_bar.add_widget(Label(text='Search',size_hint=(0.2,1.0)))
        self.search_bar.add_widget(self.search_text)
        self.search_bar.add_widget(self.create_course_button)

        ## Filter Buttons ##
        self.filter_bar = BoxLayout(size_hint=(1.0,0.05))        
        self.AHSE = ToggleButton(text='AHSE',size_hint=(0.25,1.0))
        self.ENGR = ToggleButton(text='ENGR',size_hint=(0.25,1.0))
        self.MTH = ToggleButton(text='MTH',size_hint=(0.25,1.0))
        self.SCI = ToggleButton(text='SCI',size_hint=(0.25,1.0))        
        self.filter_bar.add_widget(self.AHSE)
        self.filter_bar.add_widget(self.ENGR)
        self.filter_bar.add_widget(self.MTH)
        self.filter_bar.add_widget(self.SCI)

        ## Scrollview of Courses ##
        self.scrollview = ScrollView(size_hint=(1.0,0.9),size=(400,400),scroll_timeout=5)
        self.courses = StackLayout(spacing=5,size_hint_y=None)
        self.courses.bind(minimum_height=self.courses.setter('height'))
        self.scrollview.add_widget(self.courses)
        
        ## Add Widgets to Tab ##
        self.add_widget(self.search_bar)
        self.add_widget(self.filter_bar)
        self.add_widget(self.scrollview)

        Clock.schedule_interval(self.search_function,0.1)    

    def search_function(self,instance):
        """Allows user to search for courses by name, keyword, professor, or course code and filter courses by type"""
        query = self.search_text.text.lower()        
        searched_items = []
        filtered_items = []

        #fills up the temp list the first time the function is called (copy of list of all courses)
        if len(search_temp_list) == 0:
            for course_item in self.courses.children:
                search_temp_list.append(course_item)       
        
        #if the query is not empty, does term search first
        if query != "":                      
            for course_item in search_temp_list:                            
                if query == course_item.course.name.lower() or query == course_item.course.code or query == course_item.course.prof.lower():
                    searched_items.append(course_item)
                for keyword in course_item.course.keywords:
                    if query == keyword.lower():                        
                        searched_items.append(course_item)

        #if the query is empty, searched courses = all courses
        else:
            searched_items = search_temp_list
        
        #if none of the buttons are down, keep all searched courses
        if self.AHSE.state == 'normal' and self.ENGR.state == 'normal' and self.MTH.state == 'normal' and self.SCI.state == 'normal':
            filtered_items = searched_items

        #if a button is down, shows only courses in that category (holding multiple buttons shows more courses)
        else:                                
            if self.AHSE.state == 'down':
                for course_item in searched_items:                   
                    if course_item.course.credits['AHSE'] > 0:                                                  
                        filtered_items.append(course_item)
            if self.ENGR.state == 'down': 
                for course_item in searched_items:                      
                    if course_item.course.credits['ENGR'] > 0 and course_item not in filtered_items:                                                  
                        filtered_items.append(course_item)
            if self.MTH.state == 'down':                          
                for course_item in searched_items:
                    if course_item.course.credits['MTH'] > 0 and course_item not in filtered_items:                                                 
                        filtered_items.append(course_item)
            if self.SCI.state == 'down':
                for course_item in searched_items:                   
                    if course_item.course.credits['SCI'] > 0 and course_item not in filtered_items:                                             
                        filtered_items.append(course_item)

        if len(self.courses.children) != len(filtered_items):
            self.courses.clear_widgets()
            for course_item in filtered_items:
                self.courses.add_widget(course_item) 
コード例 #14
0
ファイル: Proto5.py プロジェクト: iangmhill/CrashCourse
class DragTab(BoxLayout):
	def __init__(self,**kwargs):
		super(DragTab,self).__init__(**kwargs)
		#Base Layer is a BoxLayout
		#right-hand column is StackLayout, lefthand is a vertical box layout		
		
		self.scrollview = ScrollView(size=(400,400),size_hint=(0.3,1))
		self.courses = StackLayout(spacing=5,size_hint_y=None,orientation='tb-rl')
		self.courses.bind(minimum_height=self.courses.setter('height'))
		self.scrollview.add_widget(self.courses)

		self.lefthand=BoxLayout(orientation='vertical', size_hint=(.7,1))
		self.Planner=GridLayout(size_hint=(1,.9),rows=2, cols=4, spacing=3)

		self.slot1=Semester(text="Fall "+ str(all_globals.user.grad_year-4))
		self.Planner.add_widget(self.slot1)
		self.slot2=Semester(text="Fall "+ str(all_globals.user.grad_year-3))
		self.Planner.add_widget(self.slot2)
		self.slot3=Semester(text="Fall "+ str(all_globals.user.grad_year-2))
		self.Planner.add_widget(self.slot3)
		self.slot4=Semester(text="Fall "+ str(all_globals.user.grad_year-1))
		self.Planner.add_widget(self.slot4)
		self.slot5=Semester(text="Spring "+ str(all_globals.user.grad_year-3))
		self.Planner.add_widget(self.slot5)
		self.slot6=Semester(text="Spring "+ str(all_globals.user.grad_year-2))
		self.Planner.add_widget(self.slot6)
		self.slot7=Semester(text="Spring "+ str(all_globals.user.grad_year-1))
		self.Planner.add_widget(self.slot7)
		self.slot8=Semester(text="Spring "+ str(all_globals.user.grad_year))
		self.Planner.add_widget(self.slot8)

		self.lefthand.add_widget(self.Planner)

		self.stats_widget=BoxLayout(size_hint=(1, .1))
		self.recycle=Button(size_hint=(.25, 1), text= 'Recycle \n Course')
		self.stats=Label(size_hint=(.75,1),color=(1,1,1,.3))
		self.stats_widget.add_widget(self.recycle)
		self.stats_widget.add_widget(self.stats)
		self.lefthand.add_widget(self.stats_widget)

		#Now stuff it all in
		self.add_widget(self.lefthand)
		self.add_widget(self.scrollview)

		# if len(self.lefthand.children)>=2:
		Clock.schedule_interval(self.update_stats_widget, .1)


	def add_Icon(self,course):

		Icon=DragableButton(course=course,text=course.keywords[0],height=100,size_hint_y=None,
							  droppable_zone_objects=[],
							  bound_zone_objects=[],
							  kill_zone_objects=[],
							  drag_opacity=.5,
							  remove_on_drag=True)
		# Icon.text_size=self.size
		Icon.bound_zone_objects.append(self.Planner)
		Icon.bound_zone_objects.append(self.scrollview)
		Icon.bound_zone_objects.append(self.recycle)

		Icon.droppable_zone_objects.append(self.slot1.coursehouse)
		Icon.droppable_zone_objects.append(self.slot2.coursehouse)
		Icon.droppable_zone_objects.append(self.slot3.coursehouse)
		Icon.droppable_zone_objects.append(self.slot4.coursehouse)
		Icon.droppable_zone_objects.append(self.slot5.coursehouse)
		Icon.droppable_zone_objects.append(self.slot6.coursehouse)
		Icon.droppable_zone_objects.append(self.slot7.coursehouse)
		Icon.droppable_zone_objects.append(self.slot8.coursehouse)

		Icon.droppable_zone_objects.append(self.courses)

		Icon.kill_zone_objects.append(self.recycle)

		self.courses.add_widget(Icon)
		print Icon.droppable_zone_objects

	def update_stats_widget(self, dt):		

		##DON'T REWRITE OVER THE USER INFORMATION WITH THE DUMMY DATA!!!!!!

		Fixed=False
		all_globals.user.credits['AHSE'] = 0#course.course.pre_credits['AHSE']												
		all_globals.user.credits['ENGR'] = 0#course.course.pre_credits['ENGR']													
		all_globals.user.credits['MTH'] = 0#course.course.pre_credits['MTH']													
		all_globals.user.credits['SCI'] = 0#course.course.pre_credits['SCI']
		for child in self.lefthand.children[:]:
			if child.height> 300:
				for semester_block in child.children[:]:
					for semester_element in semester_block.children[:]:
						if semester_element.height>100:
							for course in semester_element.children[:]:
								all_globals.user.credits['AHSE'] += course.course.credits['AHSE']												
								all_globals.user.credits['ENGR'] += course.course.credits['ENGR']													
								all_globals.user.credits['MTH'] += course.course.credits['MTH']													
								all_globals.user.credits['SCI'] += course.course.credits['SCI']
														
		for child in self.lefthand.children[:]:
			if child.height>300:
				Fixed=True
		if Fixed:
			for child in self.lefthand.children[:]:
				if child.height< 300:
					for grandchild in child.children[:]:
						if grandchild.width> 300:
							child.remove_widget(grandchild)

							stats=Label(size_hint=(1,1),text='AHSE:  '+str(all_globals.user.credits['AHSE'])+'  '+'ENGR:  '+str(all_globals.user.credits['ENGR'])+'  '+'MTH:  '+str(all_globals.user.credits['MTH'])+'  '+'SCI:  '+str(all_globals.user.credits['SCI'])+'  ',color=(1,1,1,1))

							child.add_widget(stats)
コード例 #15
0
    class Form:
        def __init__(self):
            self._states = None
            self._zip_codes = None
            self._cities = None
            self._selected_city = None
            self._selected_zip_code = None

            self._name = None
            self._gender = None
            self._age = None
            self._breed = None
            self._color = None
            self._size = None
            self._status = None
            self._date = None
            self._state = None
            self._summary = None
            self._zip = None
            self._city = None
            self._images = []
            self._image_upload = None
            self._images_grid_layout = None
            self._files = None
            self._button_submit = None

            self.raw_images = []

        def get_states(self):
            list = [
                'AL', 'AK', 'AZ', 'AR', 'CA', 'CO', 'CT', 'DE', 'FL', 'GA',
                'HI', 'ID', 'IL', 'IN', 'IA', 'KS', 'KY', 'LA', 'ME', 'MD',
                'MA', 'MI', 'MN', 'MS', 'MO', 'MT', 'NE', 'NV', 'NH', 'NJ',
                'NM', 'NY', 'NC', 'ND', 'OH', 'OK', 'OR', 'PA', 'RI', 'SC',
                'SD', 'TN', 'TX', 'UT', 'VT', 'VA', 'WA', 'WV', 'WI', 'WY'
            ]
            return list

        def get_date(self, date):
            self._date.ids.category.text = datetime.strptime(
                str(date), '%Y-%m-%d').strftime('%B %d, %Y')
            self._date.ids.category.color = get_color_from_hex('#023b80')
            self._date.ids.icon.color = get_color_from_hex('#023b80')

        def date_picker(self):
            date_dialog = MDDatePicker(callback=self.get_date)
            date_dialog.open()

        def load_files(self):
            try:
                from jnius import autoclass
                PythonActivity = autoclass('org.kivy.android.PythonActivity')
                self._files = MDFileManager(exit_manager=self.exit_manager,
                                            select_path=self.select_path,
                                            previous=True,
                                            ext=['png', 'jpg', 'jpeg'])
                self._files.show(PythonActivity.storagePath)
            except:
                self._files = MDFileManager(exit_manager=self.exit_manager,
                                            select_path=self.select_path,
                                            previous=True,
                                            ext=['png', 'jpg', 'jpeg'])
                self._files.show('/')

        def remove_image(self, instance, path=None):
            self._images_grid_layout.remove_widget(instance.parent.parent)
            self._images.remove(path)

        def select_path(self, path):
            self._image_upload.ids.svg.color = get_color_from_hex('#023b80')
            self._image_upload.ids.icon.color = get_color_from_hex('#023b80')
            self.exit_manager(path)
            self._images.append(path)
            anchor_layout = CustomAnchorLayout(size_hint=(None, None),
                                               size=(dp(95), dp(85)))
            layout = CustomStencilView()
            layout.add_widget(
                CustomImageUpload(size_hint=(None, None),
                                  pos_hint={
                                      'center_x': 0.5,
                                      'center_y': 0.5
                                  },
                                  keep_ratio=True,
                                  allow_stretch=True,
                                  source=path))
            anchor_layout.add_widget(layout)
            cancel_layout = AnchorLayout(anchor_x='right',
                                         anchor_y='top',
                                         padding=(dp(-5), dp(-5)))
            cancel_image = CancelImage()
            cancel_image.ids.cancel.text = ''
            cancel_layout.add_widget(cancel_image)
            anchor_layout.add_widget(cancel_layout)
            holder = AnchorLayout(size_hint=(None, None),
                                  size=(dp(95), dp(85)))
            holder.add_widget(anchor_layout)
            copy_cancel_layout = AnchorLayout(anchor_x='right',
                                              anchor_y='top',
                                              padding=(dp(-5), dp(-5)))
            copy_cancel_image = CancelImage()
            copy_cancel_image.ids.cancel.text = ''
            copy_cancel_image.fbind('on_release', self.remove_image, path=path)
            copy_cancel_layout.add_widget(copy_cancel_image)
            holder.add_widget(copy_cancel_layout)
            self._images_grid_layout.add_widget(holder)

        def exit_manager(self, path):
            self._files.close()

        def on_deselect(self, instance, icon=None, border=None):
            border.rgb = get_color_from_hex('#c9d0dc')

            if border.ids.category.text == border.type:
                icon.color = get_color_from_hex('#c9d0dc')

        def create_drop_down(self, button, list=None, icon=None, border=None):
            border.rgb = get_color_from_hex('#023b80')
            icon.color = get_color_from_hex('#023b80')

            drop_down = DropDown()
            drop_down.fbind('on_dismiss',
                            self.on_deselect,
                            icon=icon,
                            border=border)
            drop_down.bind(on_select=lambda instance, x:
                           (setattr(button.ids.category, 'text', x),
                            setattr(button.ids.category, 'color',
                                    get_color_from_hex('#023b80')),
                            setattr(button.ids.icon, 'color',
                                    get_color_from_hex('#023b80'))))

            for text in list:
                new_item = CustomMenu(size_hint=(1, None),
                                      height=dp(45),
                                      text=text)
                new_item.bind(
                    on_release=lambda item: drop_down.select(item.text))
                drop_down.add_widget(new_item)

            drop_down.open(button)

        def on_change_text(self, instance, value):
            for state, list in self._states.items():
                if state == value:
                    self._zip_codes = []
                    self._cities = []

                    for item in list:
                        self._zip_codes.append(item['zip'])
                        self._cities.append(item['city'])
                        self._cities.sort()

        def on_summary_focus(self, instance, value, icon=None, border=None):
            if value:
                border.rgb = get_color_from_hex('#023b80')
            else:
                border.rgb = get_color_from_hex('#c9d0dc')

            if instance.text == '':
                if value:
                    icon.color = get_color_from_hex('#023b80')
                else:
                    icon.color = get_color_from_hex('#c9d0dc')
            else:
                instance.text = instance.text

        def on_focus(self, instance, value, icon=None, border=None):
            if value:
                border.rgb = get_color_from_hex('#023b80')
            else:
                border.rgb = get_color_from_hex('#c9d0dc')

            if instance.text == '':
                if value:
                    icon.color = get_color_from_hex('#023b80')
                else:
                    icon.color = get_color_from_hex('#c9d0dc')
            else:
                instance.text = instance.text.title()

        def on_focus_city(self, instance, value, icon=None, border=None):
            if self._state.ids.category.text == 'State':
                instance.is_focusable = False
                Snackbar(text='Please select a state first!').show()
                instance.is_focusable = True
            else:
                if value:
                    border.rgb = get_color_from_hex('#023b80')
                else:
                    border.rgb = get_color_from_hex('#c9d0dc')

                if instance.text == '':
                    if value:
                        icon.color = get_color_from_hex('#023b80')
                    else:
                        icon.color = get_color_from_hex('#c9d0dc')
                else:
                    instance.text = self._selected_city

        def on_focus_zip(self, instance, value, icon=None, border=None):
            if self._state.ids.category.text == 'State':
                instance.is_focusable = False
                Snackbar(text='Please select a state first!').show()
                instance.is_focusable = True
            else:
                if value:
                    border.rgb = get_color_from_hex('#023b80')
                else:
                    border.rgb = get_color_from_hex('#c9d0dc')

                if instance.text == '':
                    if value:
                        icon.color = get_color_from_hex('#023b80')
                    else:
                        icon.color = get_color_from_hex('#c9d0dc')
                else:
                    instance.text = self._selected_zip_code

        def on_cities(self, instance, value):
            try:
                for city in self._cities:
                    if city.lower().startswith(value.lower()):
                        diff = re.split(value, city, flags=re.IGNORECASE)[1]
                        if diff != '':
                            self._city.ids.category.suggestion_text = diff
                            self._selected_city = city
                        break
            except:
                pass

        def on_zip_codes(self, instance, value):
            try:
                for zip in self._zip_codes:
                    if zip.startswith(value):
                        diff = re.split(value, zip)[1]
                        if diff != '':
                            self._zip.ids.category.suggestion_text = diff
                            self._selected_zip_code = zip
                        break
            except:
                pass

        def submit_data(self):
            name = self._name.ids.category.text.replace('Name', '')
            gender = self._gender.ids.category.text.replace('Gender', '')
            age = self._age.ids.category.text.replace('Age', '')
            breed = self._breed.ids.category.text.replace('Breed', '')
            color = self._color.ids.category.text.replace('Color', '')
            size = self._size.ids.category.text.replace('Size', '')
            status = self._status.ids.category.text.replace('Status', '')
            date = self._date.ids.category.text.replace('Date', '')
            state = self._state.ids.category.text.replace('State', '')
            summary = self._summary.ids.category.text.replace('Summary', '')
            zip = self._zip.ids.category.text.replace('Zip', '')
            city = self._city.ids.category.text.replace('City', '')
            images = self._images
            id = uuid.uuid4()
            dict = {
                'name': name.strip(),
                'gender': gender.strip(),
                'age': age.strip(),
                'breed': breed.strip(),
                'color': color.strip(),
                'size': size.strip(),
                'status': status.strip(),
                'date': date.strip(),
                'state': state.strip(),
                'zip': zip.strip(),
                'city': city.strip(),
                'summary': summary,
                'petid': id
            }

            for key, value in dict.items():
                if value == '':
                    Snackbar(text=key.title() + ' is missing.').show()
                    return

            if not images:
                Snackbar(text='Image is missing.').show()
                return

            Snackbar(text='Attempting to send requested pet...').show()
            print('All fields satisfied.')

            self._button_submit.disabled = True
            self._button_submit.text = 'SENDING'

            for image in images:
                tuple = (image, open(image, 'rb'))
                self.raw_images.append(tuple)

            #pool = Pool(1)
            #pool.apply_async(requests.post, args=['https://fur-finder.herokuapp.com/api/pets//'], kwds={'data': dict, 'files': self.raw_images}, callback=self.on_success, error_callback=self.on_error)

            th = Thread(target=self.post, args=(dict, ))
            th.setDaemon(True)
            th.start()

        def post(self, data):
            s = requests.Session()
            s.hooks['response'].append(self.callback)
            headers = {'Authorization': 'Token ' + LoginView.token}

            #pet_list_size = requests.get(url='https://fur-finder.herokuapp.com/api/pets//', headers=headers).json()
            #data['petid'] = len(pet_list_size) - 1
            resp = s.post('http://fur-finder.herokuapp.com/api/pets//',
                          data=data,
                          files=self.raw_images,
                          headers=headers)

            if resp.ok:
                pass
            else:
                print(resp.text)

        def callback(self, r, **kwargs):
            print(r.text)

            for raw_image in self.raw_images:
                raw_image[1].close()

            if r.ok:
                Snackbar(text='Successfully reported pet.').show()
                print('POST successful.')
            else:
                Snackbar(text='Could not report pet. Try different pictures.'
                         ).show()
                print('POST failed.')

            self._button_submit.disabled = False
            self._button_submit.text = 'SUBMIT'
            self.raw_images.clear()

        def create(self):
            with open(os.path.join(os.path.dirname(__file__),
                                   '../states.json')) as file:
                self._states = json.load(file)

            main_grid_layout = GridLayout(size_hint=(1, None),
                                          cols=1,
                                          spacing=dp(20),
                                          padding=(dp(20), dp(0), dp(20),
                                                   dp(0)))
            main_grid_layout.bind(
                minimum_height=main_grid_layout.setter('height'))

            self._name = FormInput(size_hint=(1, None),
                                   height=dp(45),
                                   icon='',
                                   type='Name',
                                   input_type='text',
                                   input_filter=None)
            self._name.ids.category.fbind('focus',
                                          self.on_focus,
                                          icon=self._name.ids.icon,
                                          border=self._name)

            self._breed = FormInput(size_hint=(1, None),
                                    height=dp(45),
                                    icon='',
                                    type='Breed',
                                    input_type='text',
                                    input_filter=None)
            self._breed.ids.category.fbind('focus',
                                           self.on_focus,
                                           icon=self._breed.ids.icon,
                                           border=self._breed)

            self._city = FormInput(size_hint=(1, None),
                                   height=dp(45),
                                   icon='',
                                   type='City',
                                   input_type='text',
                                   input_filter=None)
            self._city.ids.category.fbind('focus',
                                          self.on_focus_city,
                                          icon=self._city.ids.icon,
                                          border=self._city)
            self._city.ids.category.fbind('text', self.on_cities)

            self._zip = FormInput(size_hint=(1, None),
                                  height=dp(45),
                                  icon='',
                                  type='Zip',
                                  input_type='number',
                                  input_filter='int')
            self._zip.ids.category.fbind('focus',
                                         self.on_focus_zip,
                                         icon=self._zip.ids.icon,
                                         border=self._zip)
            self._zip.ids.category.fbind('text', self.on_zip_codes)

            self._date = FormLabel(size_hint=(1, None),
                                   height=dp(45),
                                   icon='',
                                   type='Date',
                                   chevron='')
            self._date.on_release = lambda: self.date_picker()

            self._gender = FormLabel(size_hint=(1, None),
                                     height=dp(45),
                                     icon='',
                                     type='Gender')
            self._gender.fbind('on_release',
                               self.create_drop_down,
                               list=['Male', 'Female'],
                               icon=self._gender.ids.icon,
                               border=self._gender)

            self._age = FormLabel(size_hint=(1, None),
                                  height=dp(45),
                                  icon='',
                                  type='Age')
            self._age.fbind('on_release',
                            self.create_drop_down,
                            list=['Puppy', 'Kitten', 'Adult', 'Senior'],
                            icon=self._age.ids.icon,
                            border=self._age)

            self._color = FormLabel(size_hint=(1, None),
                                    height=dp(45),
                                    icon='',
                                    type='Color')
            self._color.fbind('on_release',
                              self.create_drop_down,
                              list=[
                                  'Black', 'Blue', 'Brown', 'Cream', 'Fawn',
                                  'Gold', 'Grey', 'Multicolor', 'Orange',
                                  'Red', 'Tan', 'White'
                              ],
                              icon=self._color.ids.icon,
                              border=self._color)

            self._size = FormLabel(size_hint=(1, None),
                                   height=dp(45),
                                   icon='',
                                   type='Size')
            self._size.fbind('on_release',
                             self.create_drop_down,
                             list=['Small', 'Medium', 'Large'],
                             icon=self._size.ids.icon,
                             border=self._size)

            self._status = FormLabel(size_hint=(1, None),
                                     height=dp(45),
                                     icon='',
                                     type='Status')
            self._status.fbind('on_release',
                               self.create_drop_down,
                               list=['Lost', 'Found'],
                               icon=self._status.ids.icon,
                               border=self._status)

            self._state = FormLabel(size_hint=(1, None),
                                    height=dp(45),
                                    icon='',
                                    type='State')
            self._state.fbind('on_release',
                              self.create_drop_down,
                              list=self.get_states(),
                              icon=self._state.ids.icon,
                              border=self._state)
            self._state.ids.category.fbind('text', self.on_change_text)

            self._summary = SummaryInput(size_hint=(1, None),
                                         height=dp(135),
                                         icon='',
                                         type='Summary',
                                         input_type='text',
                                         input_filter=None)
            self._summary.ids.category.fbind('focus',
                                             self.on_summary_focus,
                                             icon=self._summary.ids.icon,
                                             border=self._summary)

            self._button_submit = Button(
                text='SUBMIT',
                background_normal='',
                background_color=get_color_from_hex('#023b80'),
                font_size=dp(16),
                font_name='assets/Inter-Medium.ttf',
                size_hint=(None, None),
                size=(dp(100), dp(50)))
            self._button_submit.on_release = lambda: self.submit_data()

            gender_and_age_grid_layout = GridLayout(size_hint=(1, None),
                                                    cols=2,
                                                    spacing=dp(20))
            gender_and_age_grid_layout.bind(
                minimum_height=gender_and_age_grid_layout.setter('height'))
            gender_and_age_grid_layout.add_widget(self._gender)
            gender_and_age_grid_layout.add_widget(self._age)

            color_and_size_grid_layout = GridLayout(size_hint=(1, None),
                                                    cols=2,
                                                    spacing=dp(20))
            color_and_size_grid_layout.bind(
                minimum_height=color_and_size_grid_layout.setter('height'))
            color_and_size_grid_layout.add_widget(self._color)
            color_and_size_grid_layout.add_widget(self._size)

            state_and_zip_grid_layout = GridLayout(size_hint=(1, None),
                                                   cols=2,
                                                   spacing=dp(20))
            state_and_zip_grid_layout.bind(
                minimum_height=state_and_zip_grid_layout.setter('height'))
            state_and_zip_grid_layout.add_widget(self._state)
            state_and_zip_grid_layout.add_widget(self._zip)

            status_and_date_grid_layout = GridLayout(size_hint=(1, None),
                                                     cols=2,
                                                     spacing=dp(20))
            status_and_date_grid_layout.bind(
                minimum_height=status_and_date_grid_layout.setter('height'))
            status_and_date_grid_layout.add_widget(self._status)
            status_and_date_grid_layout.add_widget(self._date)

            self._image_upload = FormImage(size_hint=(None, None),
                                           size=(dp(95), dp(85)))
            self._image_upload.ids.svg.text = ''
            self._image_upload.ids.icon.text = ''
            self._image_upload.on_release = lambda: self.load_files()
            self._images_grid_layout = StackLayout(size_hint=(1, None),
                                                   spacing=dp(20))
            self._images_grid_layout.bind(
                minimum_height=self._images_grid_layout.setter('height'))
            self._images_grid_layout.add_widget(self._image_upload)

            main_grid_layout.add_widget(self._name)
            main_grid_layout.add_widget(gender_and_age_grid_layout)
            main_grid_layout.add_widget(self._breed)
            main_grid_layout.add_widget(color_and_size_grid_layout)
            main_grid_layout.add_widget(status_and_date_grid_layout)
            main_grid_layout.add_widget(state_and_zip_grid_layout)
            main_grid_layout.add_widget(self._city)
            main_grid_layout.add_widget(self._summary)
            main_grid_layout.add_widget(self._images_grid_layout)
            main_grid_layout.add_widget(self._button_submit)

            scroll_view = ScrollView(size_hint=(1, 0.9),
                                     effect_cls=ScrollEffect,
                                     bar_inactive_color=(0, 0, 0, 0),
                                     bar_color=(0, 0, 0, 0))
            scroll_view.add_widget(main_grid_layout)

            return scroll_view
コード例 #16
0
class FileBrowser(BoxLayout):
    def __init__(self, name, **kwargs):
        super().__init__(**kwargs)
        self.orientation = "vertical"
        # the below is now handled
        #self.size_hint = (None, None) #it would be nice if this could be optionally passed in with kwargs
        #self.size = (width, height)
        self.source = ""
        self.show_file_names = True
        self.selected_image = SpecialImage(None)
        self.image_width_hint = 1  # big one
        self.bind(
            size=partial(self.set_image_width_hint)
        )  # will need size or just height, depending on what's being used in the function

        Window.bind(mouse_pos=self._mouse_move)
        self.hover_count = None  # set this during populate

        self.menu_bar = MenuBar(name, almost_black, light_grey, light_blue)
        self.add_widget(self.menu_bar)

        self.scroll_body = ScrollView(bar_width='12dp',
                                      scroll_wheel_distance='20dp',
                                      scroll_type=['bars', 'content'],
                                      bar_inactive_color=[.7, .7, .7, .2
                                                          ])  ### add settings
        self.add_widget(self.scroll_body)
        self.scroll_body.bind(on_scroll_stop=self.on_scroll_stop_function)

        self.body = StackLayout(
            orientation="lr-tb",
            size_hint_x=0.99,
            size_hint_y=None,
            spacing=[1, 5]
        )  # the horizontal spacing isn't like the website, but they didn't have background colours like I do
        self.scroll_body.add_widget(self.body)
        self.body.bind(minimum_height=self.body.setter('height'))
        self.body.bind(height=self.scroll_test_function)

        self.bottom_bar = BottomBar(size_hint=(1, None),
                                    height='17dp',
                                    font_size='13dp',
                                    bold=True)
        self.add_widget(self.bottom_bar)

        self.draw()
        self.bind(pos=self.update_rectangles, size=self.update_rectangles)

        self.bind(size=self.test_function)

        self.size = self.size

        self.test_function()

    def scroll_test_function(self, *args):
        self.scroll_body.scroll_wheel_distance = kivy.metrics.dp(20) * math.log(
            self.body.height
        ) / 4  #< I think I stumbled across a combination here hat's quite effective (it goes between 35-45 depending on number of items, maybe more maybe less)

    def test_function(self, *args):
        self.body.padding = [3, 5, kivy.metrics.dp(12), 0]
        #self.body.padding = [(self.width - (self.width * 0.99)), 5, kivy.metrics.dp(12), 0] #

    def draw(self):
        self.canvas.before.clear()
        with self.canvas.before:
            Color(1, 1, 1, 1)
            self.rectangle = Rectangle(pos=self.pos, size=self.size)

    def update_rectangles(self, *args):
        self.rectangle.pos = self.pos
        self.rectangle.size = self.size

    def populate(self, source):  # a means of setting source
        self.source = source
        if self.body.children != []:
            self.body.clear_widgets()

        if source != "":
            direntry_iterator = os.scandir(self.source)
            for direntry in direntry_iterator:
                if direntry.is_file(
                ) == True:  # Could also check if they are images (.png, .jpg)
                    a_special_image = SpecialImage(direntry)
                    self.body.add_widget(a_special_image)

                    a_special_image.be_within = self
                    a_special_image.be_not_within = self.menu_bar
                    a_special_image.be_not_within_two = self.bottom_bar

                    # set sizes of specialimage. This might be a dumb way to do it, they only need to be called once, you see.
                    a_special_image.update_height()
                    a_special_image.update_image_height()
                    a_special_image.update_boxlayout()
                    a_special_image.update_text_textboxes()

    def set_selected(self, a_special_image):
        if a_special_image != self.selected_image:

            if self.selected_image != None:
                self.selected_image.selected = False
                self.selected_image.set_deselected()

            self.selected_image = a_special_image
            a_special_image.set_selected()
            self.bottom_bar.update_text(self.selected_image.file_name +
                                        " selected")

    def set_image_width_hint(self, *args):
        pass

    def _mouse_move(self, *args):
        if not self.get_root_window():
            return

        is_collide = self.collide_point(*self.to_widget(*args[1]))

        hovered = False
        for child in self.body.children:
            if child.hover == True and child.selected == False:  # since until you on_exit a special image, and it's selected, hover will be true (and we don't want to have a hand cursor)
                hovered = True
                break

        if is_collide == True and hovered == True:
            Window.set_system_cursor("hand")
        elif is_collide == False:
            pass
        else:
            Window.set_system_cursor("arrow")

    def on_scroll_stop_function(self, *args):
        for child in self.body.children:  # i.e. when on_scroll_stop is called for scroll_body, iterate through the special images and get them to check if they should be on_hovered or exits (this wouldn't be done otherwise: because a scroll isn't a mouse move)
            child._mouse_move(
                "hifdidl", Window.mouse_pos
            )  # THANK F**K THAT THIS WORKS. My doubt was that it would pass some bull shit Window.mouse_pos.
コード例 #17
0
class DecksMenu(RelativeLayout):
    def __init__(self, cards, setts, username, **kwargs):
        super().__init__(**kwargs)

        self.username = username

        self.acc_decks = [cards[card] for card in cards]

        self.acc_decks = [Deck(deck) for deck in self.acc_decks]

        self.acc_settings = setts

        self.cardWidth = 100
        self.spacingSize = 10
        self.paddingSize = 50

        Window.clearcolor = colors.GRAY

        self.scroll = ScrollView()

        self.scroll.size = (Window.width, Window.height)

        self.scroll.bar_color = colors.WHITE
        self.scroll.bar_width = dp(12)
        self.scroll.scroll_distance = dp(80)

        # * default oreintation is horizontal

        self.load()

        self.add_widget(self.scroll)

        self.bottom_buttons = BoxLayout()

        self.new_deck_button = Button()
        self.new_deck_button.text = "New Deck"
        self.new_deck_button.size_hint = (1, None)
        self.new_deck_button.height = dp(50)
        self.new_deck_button.on_press = self.goto_deck_adding

        self.stats_button = Button()
        self.stats_button.text = "Stats"
        self.stats_button.size_hint = (1, None)
        self.stats_button.height = dp(50)
        self.stats_button.on_press = self.goto_stats

        self.manage_button = Button()
        self.manage_button.text = "Manage"
        self.manage_button.size_hint = (1, None)
        self.manage_button.height = dp(50)

        self.bottom_buttons.add_widget(self.new_deck_button)
        self.bottom_buttons.add_widget(self.stats_button)
        self.bottom_buttons.add_widget(self.manage_button)

        self.add_widget(self.bottom_buttons)

        self.top_loc = StackLayout()
        self.top_loc.orientation = "rl-tb"

        self.top_buttons = BoxLayout()

        self.settings_button = Button()
        self.settings_button.text = "Settings"
        self.settings_button.size_hint = (None, None)
        self.settings_button.size = (dp(100), dp(50))
        self.settings_button.on_press = self.goto_settings

        self.search_button = Button()
        self.search_button.text = "Search"
        self.search_button.size_hint = (None, None)
        self.search_button.size = (dp(100), dp(50))

        self.top_bar = TextInput()
        self.top_bar.multiline = False
        self.top_bar.hint_text = "Search Query"
        self.top_bar.size_hint = (None, None)
        self.top_bar.height = dp(50)
        self.top_bar.width = dp(500)
        self.top_bar.background_normal = ''
        self.top_bar.background_color = colors.GRAY
        self.top_bar.foreground_color = colors.WHITE
        self.top_bar.font_name = "Comfortaa"
        self.top_bar.font_size = 40

        self.top_loc.add_widget(self.top_bar)
        self.top_loc.add_widget(self.search_button)
        self.top_loc.add_widget(self.settings_button)

        # self.top_loc.add_widget(self.top_buttons)

        self.add_widget(self.top_loc)

    def goto_settings(self):
        self.add_widget(SettingsPage())

    def goto_deck_adding(self):
        self.add_widget(DeckAddPage())

    def goto_stats(self):
        self.add_widget(StatsPage())

    def load(self):

        try:
            for deck in self.acc_decks[:-1]:
                self.boxes.remove_widget(deck.cardview)
        except AttributeError:
            pass

        try:
            self.scroll.remove_widget(self.boxes)
        except AttributeError:
            pass

        self.init_boxes()

        for deck in self.acc_decks:

            deck.cardview.size_hint = (None, None)
            deck.cardview.size = (dp(self.cardWidth), dp(self.cardWidth * 1.5))

            self.boxes.add_widget(deck.cardview)

    def init_boxes(self):
        self.boxes = StackLayout()

        self.boxes.bind(minimum_height=self.boxes.setter('height'))

        self.boxes.padding = dp(self.paddingSize)

        self.boxes.size_hint = (1, None)

        self.boxes.orientation = "lr-tb"
        self.boxes.spacing = dp(self.spacingSize)
        self.boxes.background_color = colors.PGREEN

        self.scroll.add_widget(self.boxes)
コード例 #18
0
ファイル: BudgetGui.py プロジェクト: jgdurst/Budget
    def build(self):
        alloc_data = budget_backend.get_allocations_by_period(self.year, self.month)
        trans_data = budget_backend.get_trans_summ_by_period(self.year, self.month)


        root = ScrollView(size_hint=(1,None), size=(Window.height, Window.width))
        main_grid_layout = GridLayout(cols=7, spacing=10, size_hint_y=None, height=500)
        main_grid_layout.bind(minimum_height=main_grid_layout.setter('height'))
        main_box_layout = BoxLayout(orientation='vertical', size_hint_y=None)
        main_box_layout.bind(minimum_height=main_box_layout.setter('height'))
        top_stack_layout = StackLayout(size_hint_y=None, height=40)
        top_stack_layout.bind(minimum_height=top_stack_layout.setter('height'))

        back_btn = Button(text='Back', size_hint=(.1,None), height=40)
        back_btn.bind(on_press=lambda x: self.move_time_backward())
        top_stack_layout.add_widget(back_btn)
        self.widget_dict['Time'] = Label(text='[b]' + self.month_name + ' ' + str(self.year) + '[/b]', size_hint=(.1,None), height=40, markup=True)
        top_stack_layout.add_widget(self.widget_dict['Time'])
        forward_btn = Button(text='Next', size_hint=(.1,None), height=40)
        forward_btn.bind(on_press=lambda x: self.move_time_forward())
        top_stack_layout.add_widget(forward_btn)
        self.widget_dict['Status'] = Label(text='', size_hint=(0.15,None), height=40)
        top_stack_layout.add_widget(self.widget_dict['Status'])
        # status_bar = FloatLayout()
        # self.widget_dict['Status'] = Label(text='TEST', size_hint=(None,None), height=40, pos_hint={'right':1, 'center_y':0.5})
        # status_bar.add_widget(self.widget_dict['Status'])
        # top_stack_layout.add_widget(status_bar)

        main_grid_layout.add_widget(Label(text='[b]Section[/b]', size_hint_y=None, height=80, font_size='20sp', markup=True))
        main_grid_layout.add_widget(Label(text='[b]Category[/b]', size_hint_y=None, height=80, font_size='20sp', markup=True))
        main_grid_layout.add_widget(Label(text='[b]Allocated[/b]', size_hint_y=None, height=80, font_size='20sp', markup=True))
        main_grid_layout.add_widget(Label(text='[b]Spent[/b]', size_hint_y=None, height=80, font_size='20sp', markup=True))
        main_grid_layout.add_widget(Label(text='', size_hint_y=None, height=80, font_size='20sp', markup=True))
        main_grid_layout.add_widget(Label(text='', size_hint_y=None, height=80, font_size='20sp', markup=True))
        main_grid_layout.add_widget(Label(text='', size_hint_y=None, height=80, font_size='20sp', markup=True))

        for row in alloc_data.itertuples():
            try:
                sum_trans_amt = trans_data.loc[trans_data['Category'] == row.Category, 'SumAmount'].iloc[0]
            except IndexError:
                sum_trans_amt = 0

            if (row.Amount < sum_trans_amt):
                color_tag = '[color=#FF0040]' #red
            elif (row.Amount > sum_trans_amt):
                color_tag = '[color=#F7FE2E]' #yellow
            else:
                color_tag = '[color=#FFFFFF]' #white

            self.widget_dict['Section_' + row.Category] = Label(text=row.Section, size_hint_y=None, height=40)
            main_grid_layout.add_widget(self.widget_dict['Section_' + row.Category])

            self.widget_dict['Label_' + row.Category] = Label(text=row.Category, size_hint_y=None, height=40)
            main_grid_layout.add_widget(self.widget_dict['Label_' + row.Category])


            self.widget_dict['Alloc_' + row.Category] = Label(text=color_tag + str(row.Amount) + '[/color]',
                                                              size_hint_y=None, height=40, markup=True)
            main_grid_layout.add_widget(self.widget_dict['Alloc_' + row.Category])

            self.widget_dict['Trans_' + row.Category] = Label(text=color_tag + str(sum_trans_amt) + '[/color]',
                                                              size_hint_y=None, height=40, markup=True)
            main_grid_layout.add_widget(self.widget_dict['Trans_' + row.Category])

            self.widget_dict['Input_' + row.Category] = AllocationTextInput(
                size_hint_y=None, height=40, multiline=False, category=row.Category)
            self.widget_dict['Input_' + row.Category].bind(text=partial(update_btn_values, parent=self))
            main_grid_layout.add_widget(self.widget_dict['Input_' + row.Category])

            self.widget_dict['SetBtn_' + row.Category] = AllocationButton(
                text='Set', size_hint_y=None, height=40, category=row.Category)
            self.widget_dict['SetBtn_' + row.Category].bind(
                on_press=partial(change_allocation, arg_alloc_type='set', top_layout=self))
            main_grid_layout.add_widget(self.widget_dict['SetBtn_' + row.Category])

            self.widget_dict['AddBtn_' + row.Category] = AllocationButton(
                text='Add', size_hint_y=None, height=40, category=row.Category)
            self.widget_dict['AddBtn_' + row.Category].bind(
                on_press=partial(change_allocation, arg_alloc_type='add', top_layout=self))
            main_grid_layout.add_widget(self.widget_dict['AddBtn_' + row.Category])


        main_box_layout.add_widget(top_stack_layout)
        main_box_layout.add_widget(main_grid_layout)
        root.add_widget(main_box_layout)
        return root
コード例 #19
0
ファイル: bookmarks.py プロジェクト: krakan/plocka
    def __init__(self, **kwargs):
        super(BookmarkList, self).__init__(**kwargs)

        scrollBox = ScrollView(
            do_scroll_x=False,
        )
        self.add_widget(scrollBox)

        stack = StackLayout(size_hint=(1, None))
        stack.bind(
            minimum_height=stack.setter('height')
        )
        scrollBox.add_widget(stack)

        bookmarks = sorted(glob(f'{self.dataDir}/bookmarks/*.json'), key = os.path.getmtime)[::-1]
        for filename in bookmarks:
            bookmark = filename[len(f'{self.dataDir}/bookmarks/'):-5]
            label = LongpressButton(
                text = bookmark,
                height = self.settings['itemSize'],
                background_color = self.settings['sectionColor'],
                size_hint = (1, None),
                on_long_press = lambda w: edit(w),
                on_short_press = lambda w: choose(w)
            )
            label.selected = False
            stack.add_widget(label)

        buttonBar = BoxLayout()
        self.add_widget(buttonBar)
        cancelBtn = ImageButton(
            source = 'data/delete.png',
            color_normal = self.settings['inactiveColor'],
            size_hint = (1, None),
            height = self.settings['headerSize'],
            on_release = lambda w: self.parent.parent.parent.dismiss(),
        )
        deleteBtn = ImageButton(
            source = 'data/trash.png',
            color_normal = self.settings['inactiveColor'],
            size_hint = (1, None),
            height = self.settings['headerSize'],
            on_release = lambda w: deleteSelected(),
        )
        buttonBar.add_widget(deleteBtn)
        buttonBar.add_widget(cancelBtn)

        def choose(item):
            selection = False
            for sibling in item.parent.children:
                if sibling.selected:
                    selection = True
                    break
            if selection:
                if item.selected:
                    deselect(item)
                else:
                    select(item)
            else:
                self.chosen = item.text
                self.parent.parent.parent.dismiss()

        def edit(w):
            editBox = BoxLayout(
                height = self.settings['itemSize'],
                size_hint = (1, None),
            )
            entry = TextInput(
                text = w.text,
                multiline = False,
                on_text_validate = lambda w: updateItem(w),
            )
            delete = ImageButton(
                size_hint_x = None,
                width = self.settings['itemSize'],
                source = 'data/trash.png',
                color_normal = self.settings['actionColor'],
                on_release = lambda w: selectItem(entry),
            )
            ok = ImageButton(
                size_hint_x = None,
                width = self.settings['itemSize'],
                source = 'data/ok.png',
                color_normal = [0, .5, 0, 1],
                on_release = lambda w: updateItem(entry),
            )
            editBox.add_widget(delete)
            editBox.add_widget(entry)
            editBox.add_widget(ok)

            entry.index = stack.children.index(w)
            entry.orig = w
            stack.add_widget(editBox, entry.index)
            stack.remove_widget(w)

        def remove_widgets(entry):
            for item in entry.children:
                entry.remove_widget(item)
            entry.parent.remove_widget(entry)

        def updateItem(entry):
            reservedChars = '[?:"*|/\\\<>]'
            entry.text = re.sub(reservedChars, '-', entry.text)
            os.rename(f'{self.dataDir}/bookmarks/{entry.orig.text}.json', f'{self.dataDir}/bookmarks/{entry.text}.json')
            entry.orig.text = entry.text
            stack.add_widget(entry.orig, entry.index)
            remove_widgets(entry.parent)

        def selectItem(entry):
            stack.add_widget(entry.orig, entry.index)
            select(entry.orig)
            remove_widgets(entry.parent)
            deleteBtn.color = self.settings['redColor']

        def select(item):
            item.selected = True
            item.background_color = self.settings['actionColor']

        def deselect(item):
            item.selected = False
            item.background_color = self.settings['sectionColor']

        def deleteSelected():
            for item in stack.children[:]:
                if item.selected:
                    os.remove(f'{self.dataDir}/bookmarks/{item.text}.json')
                    stack.remove_widget(item)
コード例 #20
0
class FilePane(BoxLayout):

    tiles = None
    mainlayout = None
    slider = None
    startPath = None
    main = None
    count2 = 0

    count  = 0 
    total_size = 0
    images = ['.jpeg', '.png', '.jpeg', '.bmp', '.dpx', '.exr', '.gif', '.ico', '.jpg2000', '.jpg',
                '.jls', '.pam', '.pbm', '.pcx', '.pgm', '.pgmyuv', '.pic',
                '.ppm', '.ptx', '.sgi', '.ras', '.tga', '.tiff', '.webp', '.xbm',
                '.xface', '.xwd']


    def __init__(self, width, height, foldername, mainlayout):
        
        super(FilePane, self).__init__()
    
        # Add Option bar to top of right panel -----
        #topOptionBar =  RelativeLayout(size = (width, resY *.04), size_hint_y = None)

        self.size = (width, height)
        self.size_hint = (None,None)
        self.startPath = foldername
        self.auto_bring_to_front = False
        self.mainlayout = mainlayout


        self.orientation = 'horizontal'

        self.tiles = StackLayout(size = (width*.9, height), size_hint_x = None, padding=10, spacing=10)
        #print self.tiles.size    
        #print self.tiles.minimum_height


        self.tiles.bind(minimum_height = self.tiles.setter('height'))



        self.add_widget(self.tiles)


        r = RelativeLayout(height = self.height)
        scrollbar = Slider(orientation = 'vertical')
        

        r.add_widget(scrollbar)
        self.add_widget(r)



        print self.tiles.height

        try:
            dirs = os.listdir( foldername )

            # This would print all the files and directories
            for file in dirs:
                if(self.isImage(file)):
                    self.addFile(self.startPath+ "\\" + file, file)
        except OSError:
            print OSError
            print "FilePane: no files found"

        print self.tiles.height


        scrollbar.range = (0, self.tiles.height)
        scrollbar.bind(value = self.updatePos)





    def updatePos(self, instance, value):
        self.tiles.y = value





    def on_touch_down(self, touch):
        if super(FilePane, self).on_touch_down(touch):
            return False
        if not self.collide_point(touch.x, touch.y):
            return False

        touch.grab(self)
        touch.ud[self] = True

        return False


    


    def isImage(self,  file):
        for i in self.images:
            if(file.endswith(i)):
                return True



    def addFile(self, path, name): 

     
        r = RelativeLayout(size_hint =(None,None))
        file = FileWidget(path, name, self, r)

 
        r.add_widget(file)
  
        r.size = file.size

        self.total_size += r.size[1]
        self.tiles.height = self.total_size - self.height
    
        self.tiles.add_widget(r)




    def getMain(self):
        return self.mainlayout;
    def getRoot(self):
        return self.tiles
コード例 #21
0
ファイル: Proto6.py プロジェクト: iangmhill/CrashCourse
class DragTab(BoxLayout):
	def __init__(self,**kwargs):
		super(DragTab,self).__init__(**kwargs)
		#Base Layer is a BoxLayout
		#right-hand column is StackLayout, lefthand is a vertical box layout		
		FreshColor=[0.2,0.65,0.8,0.85]
		SophColor=[0.2,0.65,0.8,0.75]
		JuniColor=[0.2,0.65,0.8,0.6]
		SeniColor=[0.2,0.65,0.8,0.45]

		self.scrollview = ScrollView(size=(400,400),size_hint=(0.3,1.0),scroll_timeout=10)
		self.courses = StackLayout(spacing=5,size_hint_y=None,orientation='rl-tb')	
		self.courses.bind(minimum_height=self.courses.setter('height'))
		self.scrollview.add_widget(self.courses)	
		
		self.lefthand=BoxLayout(orientation='vertical', size_hint=(.7,1))
		self.Planner=GridLayout(size_hint=(1,.85),rows=2, cols=4, spacing=3)

		self.slot1=Semester(text="Fall "+ str(all_globals.user.grad_year-4), color=FreshColor)
		self.slot2=Semester(text="Fall "+ str(all_globals.user.grad_year-3), color=SophColor)
		self.slot3=Semester(text="Fall "+ str(all_globals.user.grad_year-2), color=JuniColor)
		self.slot4=Semester(text="Fall "+ str(all_globals.user.grad_year-1), color=SeniColor)
		self.slot5=Semester(text="Spring "+ str(all_globals.user.grad_year-3), color=FreshColor)
		self.slot6=Semester(text="Spring "+ str(all_globals.user.grad_year-2), color=SophColor)
		self.slot7=Semester(text="Spring "+ str(all_globals.user.grad_year-1), color=JuniColor)
		self.slot8=Semester(text="Spring "+ str(all_globals.user.grad_year), color=SeniColor)

		self.slots=[self.slot1, self.slot2, self.slot3, self.slot4, self.slot5, self.slot6, self.slot7, self.slot8]
		
		for sem_obj in self.slots:
			self.Planner.add_widget(sem_obj)

		self.lefthand.add_widget(self.Planner)

		self.stats_widget=BoxLayout(size_hint=(1, .15))
		self.recycle=Button(size_hint=(.2, 1),background_normal='recycle.png',background_down='recycle.png')#,text= 'Recycle \n Course')
		self.stats=Label(size_hint=(1,1),color=(1,1,1,.3))
		self.stats_widget.add_widget(self.recycle)
		self.stats_widget.add_widget(self.stats)
		self.lefthand.add_widget(self.stats_widget)

		#Now stuff it all in
		self.add_widget(self.lefthand)
		self.add_widget(self.scrollview)

		Clock.schedule_interval(self.update_stats_widget, .1)


	def add_Icon(self,course):

		Icon=DragableButton(course=course,text=course.keywords[0],height=100,size_hint_y=None,
							  droppable_zone_objects=[],
							  bound_zone_objects=[],
							  kill_zone_objects=[],
							  drag_opacity=.5,
							  remove_on_drag=True)
		
		Icon.bound_zone_objects.append(self.Planner)
		Icon.bound_zone_objects.append(self.scrollview)
		Icon.bound_zone_objects.append(self.courses)
		Icon.bound_zone_objects.append(self.recycle)

		for sem in self.slots:
			Icon.add_droppable_zone(sem.coursehouse)
		
		Icon.droppable_zone_objects.append(self.scrollview)
		Icon.droppable_zone_objects.append(self.courses)

		Icon.kill_zone_objects.append(self.recycle)

		self.courses.add_widget(Icon)

	def update_stats_widget(self, dt):		
		# When the user gets pre-credits as an attribute, we can stop writing over 
		# Fixed=False
		all_globals.user.credits['AHSE'] = 0#course.course.pre_credits['AHSE']												
		all_globals.user.credits['ENGR'] = 0#course.course.pre_credits['ENGR']													
		all_globals.user.credits['MTH'] = 0#course.course.pre_credits['MTH']													
		all_globals.user.credits['SCI'] = 0#course.course.pre_credits['SCI']
		all_globals.user.courses=[]
		for semester_obj in self.slots:
			for icon in semester_obj.coursehouse.children[:]:
				all_globals.user.courses.append(icon.course.code)
				all_globals.user.credits['AHSE'] += icon.course.credits['AHSE']												
				all_globals.user.credits['ENGR'] += icon.course.credits['ENGR']													
				all_globals.user.credits['MTH'] += icon.course.credits['MTH']													
				all_globals.user.credits['SCI'] += icon.course.credits['SCI']
		
		self.stats_widget.remove_widget(self.stats)
		self.stats=Label(size_hint=(1,1),text='AHSE:  '+str(all_globals.user.credits['AHSE'])+'  '+'ENGR:  '+str(all_globals.user.credits['ENGR'])+'  '+'MTH:  '+str(all_globals.user.credits['MTH'])+'  '+'SCI:  '+str(all_globals.user.credits['SCI'])+'  ',color=(1,1,1,1))
		print all_globals.user.courses
		self.stats_widget.add_widget(self.stats)

		for sem in self.slots:
			sem.Me.clear_widgets()

		adjust=4
		for sem in self.slots[0:4]:
			sem.Me.add_widget(Label(text="Fall "+ str(all_globals.user.grad_year-adjust)))
			adjust-=1
		adjust=3
		for sem in self.slots[4:]:
			sem.Me.add_widget(Label(text="Spring "+ str(all_globals.user.grad_year-adjust)))
			adjust-=1
コード例 #22
0
    def __init__(self, **kwargs):
        super(CheckList, self).__init__(**kwargs)

        if platform == "android":
            from android.storage import primary_external_storage_path
            from android.permissions import request_permissions, check_permission, Permission

            sdcard = primary_external_storage_path()
            dataDir = sdcard + '/plocka'

            if not os.path.exists(dataDir):
                request_permissions([
                    Permission.READ_EXTERNAL_STORAGE,
                    Permission.WRITE_EXTERNAL_STORAGE
                ])
                while not check_permission(Permission.WRITE_EXTERNAL_STORAGE):
                    time.sleep(1)
        else:
            dataDir = os.environ['HOME'] + '/.config/Plocka'

        os.makedirs(dataDir, exist_ok=True)

        scriptDir = os.path.dirname(os.path.realpath(__file__))

        global shoppingList
        try:
            with open(dataDir + '/Plocka.json') as fd:
                shoppingList = json.load(fd)
        except:
            shoppingList = [{
                "section":
                "Section 1",
                "items": [{
                    "item": "Item 1",
                    "done": False
                }, {
                    "item": "Item 2",
                    "done": True
                }, {
                    "item": "Item 3",
                    "done": True
                }]
            }, {
                "section":
                "Section 2",
                "items": [{
                    "item": "Item 1",
                    "done": True
                }, {
                    "item": "Item 2",
                    "done": False
                }, {
                    "item": "Item 3",
                    "done": False
                }, {
                    "item": "Item 4",
                    "done": True
                }]
            }, {
                "section":
                "Section 3",
                "items": [{
                    "item": "Item 1",
                    "done": True
                }, {
                    "item": "Item 2",
                    "done": True
                }, {
                    "item": "Item 3",
                    "done": False
                }]
            }]

        defaultSettings = {
            'headerSize': '40sp',
            'sectionSize': '20sp',
            'sectionColor': [0.1, 0.2, 0.2, 1],
            'sectionTextSize': '10sp',
            'itemSize': '30sp',
            'itemColor': [0.20, 0.25, 0.29, 1],
            'doneColor': [0.24, 0.30, 0.35, 1],
            'actionColor': [.2, .7, .9, 1],
            'activeColor': [1, 1, 1, 1],
            'inactiveColor': [1, 1, 1, 0.5],
            'redColor': [1, 0, 0, 0.5],
            'greenColor': [0, 1, 0, 0.5],
            'backupsToKeep': 10,
            'maxBackupAge': 1,
            'showSections': 'maybe',
        }
        try:
            with open(dataDir + '/settings.json') as fd:
                settings = json.load(fd)
                for key in defaultSettings:
                    if not key in settings:
                        settings[key] = defaultSettings[key]
        except:
            settings = defaultSettings

        backups = sorted(glob(f'{dataDir}/Plocka-*.json'))
        cutoff = (
            datetime.now() -
            timedelta(days=settings['maxBackupAge'])).strftime("%Y%m%d%H%M%S")
        for backup in backups[:-settings['backupsToKeep']]:
            if backup < f'{dataDir}/Plocka-{cutoff}.json':
                print('deleting backup file ' + backup)
                os.remove(backup)

        def hide(widget):
            if widget.height:
                widget.restore = widget.height
            widget.height = 0
            widget.opacity = 0
            widget.disabled = True

        def unhide(widget):
            if widget.disabled:
                widget.height = widget.restore
                widget.opacity = 1
                widget.disabled = False

        def checkSection(stack, current):
            for item in stack.children[::-1]:
                if item.type == 'section':
                    section = item
                if item == current:
                    break
            index = stack.children.index(section)
            for item in stack.children[index - 1::-1]:
                if item.type == 'item' and item.check.state == 'normal':
                    return
                if item.type == 'section':
                    break
            hide(section)

        self.writeDeferred = False

        def writeFile(dt):
            if dt and not self.writeDeferred:
                return
            self.writeDeferred = False
            activeList = []
            for item in stack.children[::-1]:
                if item.type == 'item':
                    entry = {
                        "item": item.text,
                        "done": item.check.state == 'down'
                    }
                    section["items"].append(entry)
                elif item.type == 'section':
                    section = {"section": item.origText, "items": []}
                    activeList.append(section)
            shoppingList['lists'][shoppingList['active']]['name'] = title.text
            shoppingList['lists'][shoppingList['active']]['list'] = activeList

            now = datetime.now().strftime("%Y%m%d%H%M%S")
            if os.path.exists(f'{dataDir}/Plocka.json'):
                os.rename(f'{dataDir}/Plocka.json',
                          f'{dataDir}/Plocka-{now}.json')
            with open(f'{dataDir}/Plocka.json', 'w', encoding='utf8') as fd:
                json.dump(shoppingList, fd, indent=2, ensure_ascii=False)
            saveBtn.color = settings['greenColor']

        def undo(instance):
            global shoppingList
            try:
                last = sorted(glob(f'{dataDir}/Plocka-*.json'))[-1]
                os.rename(last, f'{dataDir}/Plocka.json')
                with open(dataDir + '/Plocka.json') as fd:
                    shoppingList = json.load(fd)
                populate()
                hideUnHide(hideBtn)
            except:
                pass

        def toggle(instance):
            if instance.check.state == 'down':
                instance.background_color = settings['itemColor']
                instance.color = settings['activeColor']
                instance.check.state = 'normal'
            else:
                instance.background_color = settings['doneColor']
                instance.color = settings['inactiveColor']
                instance.check.state = 'down'

            if not self.writeDeferred:
                self.writeDeferred = True
                saveBtn.color = settings['actionColor']
                Clock.schedule_once(writeFile, 10)

            if hideBtn.state == 'down' and instance.check.state == 'down':
                hide(instance.check)
                hide(instance)
                checkSection(stack, instance)

        def hideUnHide(instance):
            if hideBtn.state != "down" and not searchInput.text:
                for item in stack.children[:]:
                    unhide(item)

            elif searchInput.text == searchInput.text.upper(
            ) and searchInput.text != searchInput.text.lower():
                activeSection = False
                for item in stack.children[::-1]:
                    if item.type == 'section':
                        if re.search(searchInput.text, item.text):
                            activeSection = True
                        else:
                            activeSection = False
                    if activeSection and (
                            hideBtn.state != 'down' or item.type != 'item'
                            and item.type != 'check' or hideBtn.state == 'down'
                            and item.type == 'check' and item.state != 'down'
                            or hideBtn.state == 'down' and item.type == 'item'
                            and item.check.state != 'down'):
                        unhide(item)
                    else:
                        hide(item)

            else:
                hasChildren = False
                regexp = searchInput.text if searchInput.text else '.'
                for item in stack.children[:]:
                    if item.type == 'item':
                        if hideBtn.state == "down" and item.check.state == 'down' or not re.search(
                                regexp, item.text, re.IGNORECASE):
                            hide(item.check)
                            hide(item)
                        else:
                            unhide(item.check)
                            unhide(item)
                            hasChildren = True
                    elif item.type == 'section':
                        if hasChildren and settings['showSections'] == 'always':
                            unhide(item)
                            hasChildren = False
                        else:
                            hide(item)

        def crossCheck(instance):
            toggle(instance.label)

        def edit(instance):
            entry = TextInput(
                text=instance.text,
                size_hint=(0.5, None),
                height=settings['itemSize'],
                multiline=False,
                on_text_validate=lambda w: updateItem(w),
            )
            if instance.type == 'section':
                entry.text = instance.origText
            relative = ImageButton(
                source='data/left.png'
                if instance.type == 'item' else 'data/right.png',
                color_normal=[1, 1, 1, .7],
                height=settings['itemSize'],
                size_hint=(0.1, None),
                on_release=lambda w: updateItem(entry),
            )
            before = ImageButton(
                source='data/up.png',
                color_normal=[1, 1, 1, .7],
                height=settings['itemSize'],
                size_hint=(0.1, None),
                on_release=lambda w: updateItem(entry),
            )
            replace = ImageButton(
                source='data/ok.png',
                color_normal=[0, .5, 0, 1],
                height=settings['itemSize'],
                size_hint=(0.1, None),
                on_release=lambda w: updateItem(entry),
            )
            after = ImageButton(
                source='data/down.png',
                color_normal=[1, 1, 1, .7],
                height=settings['itemSize'],
                size_hint=(0.1, None),
                on_release=lambda w: updateItem(entry),
            )
            delete = ImageButton(
                source='data/delete.png',
                color_normal=[.5, 0, 0, 1],
                height=settings['itemSize'],
                size_hint=(0.1, None),
                on_release=lambda w: updateItem(entry),
            )
            entry.orig = instance
            entry.relative = relative
            entry.before = before
            entry.replace = replace
            entry.after = after
            entry.delete = delete

            entry.type = 'entry'
            relative.type = 'relative'
            before.type = 'before'
            replace.type = 'replace'
            after.type = 'after'
            delete.type = 'delete'

            hide(instance)
            if instance.type == 'item':
                hide(instance.check)
            index = stack.children.index(instance)
            stack.add_widget(delete, index)
            stack.add_widget(entry, index)
            stack.add_widget(relative, index)
            stack.add_widget(before, index)
            stack.add_widget(replace, index)
            stack.add_widget(after, index)

            entry.select_all()
            Clock.schedule_once(lambda dt: reselect(entry), 0.5)

        def reselect(entry):
            # repeat select_all after half a second to avoid losing focus on release
            entry.focused = True
            entry.select_all()

        def updateItem(entry):
            todo = 'replace'
            if entry.delete.state == 'down':
                todo = 'delete'
            elif entry.before.state == 'down':
                todo = 'before'
            elif entry.after.state == 'down':
                todo = 'after'
            elif entry.relative.state == 'down':
                if entry.orig.type == 'section':
                    todo = 'item'
                else:
                    todo = 'section'

            orig = entry.orig
            text = entry.text

            stack.remove_widget(entry.relative)
            stack.remove_widget(entry.before)
            stack.remove_widget(entry.replace)
            stack.remove_widget(entry.after)
            stack.remove_widget(entry.delete)
            stack.remove_widget(entry)

            if todo == 'delete':
                stack.remove_widget(orig)
                if orig.type == 'item':
                    stack.remove_widget(orig.check)
            else:
                unhide(orig)
                if orig.type == 'item':
                    unhide(orig.check)
                if todo == 'replace':
                    if orig.type == 'section':
                        orig.origText = text
                        orig.text = text.upper()
                    else:
                        orig.text = text
                else:
                    if orig.type == 'section' and todo != 'item' or todo == 'section':
                        label = sectionButton(text)
                    else:
                        label = itemButtonPair(text, False)

                    index = stack.children.index(orig)
                    if todo == 'before' or todo == 'section':
                        index += 1
                    if orig.type == 'item':
                        if todo == 'before' or todo == 'section':
                            index += 1
                    if label.type == 'item':
                        stack.add_widget(label.check, index)
                    stack.add_widget(label, index)
                    edit(label)

            writeFile(0)

        self.searchDeferred = False

        def doSearch(text, undo):
            if not self.searchDeferred:
                self.searchDeferred = True
                Clock.schedule_once(filterOut, 1)
            return text

        def filterOut(dt):
            self.searchDeferred = False
            hideUnHide(hideBtn)

        def setBookmark():
            now = datetime.now().strftime("%Y-%m-%dT%H-%M-%S")
            os.makedirs(f'{dataDir}/bookmarks', exist_ok=True)
            print(f"set bookmark '{dataDir}/bookmarks/{now}.json'")
            shutil.copy(f'{dataDir}/Plocka.json',
                        f'{dataDir}/bookmarks/{now}.json')

        bookmark = ''

        def getBookmark():
            popup = Popup(
                title="Bookmarks",
                content=BookmarkList(
                    dataDir=dataDir,
                    settings=settings,
                    orientation='vertical',
                ),
                size_hint=(0.9, 0.9),
            )
            popup.bind(on_pre_dismiss=useBookmark)
            popup.open()

        def useBookmark(w):
            global shoppingList
            bookmark = w.content.chosen
            if not bookmark:
                print('no bookmark chosen')
                return
            writeFile(0)
            shutil.copy(f'{dataDir}/bookmarks/{bookmark}.json',
                        f'{dataDir}/Plocka.json')
            with open(f'{dataDir}/Plocka.json') as fd:
                shoppingList = json.load(fd)
            populate()

        def selectList(w):
            global shoppingList

            dropdown = DropDown(
                on_select=lambda instance, selected: setActive(selected),
            )
            index = -1
            for item in shoppingList['lists']:
                index += 1
                if index == shoppingList['active']:
                    continue
                btn = Button(
                    text=item['name'],
                    size_hint_y=None,
                    background_color=settings['sectionColor'],
                    height=settings['itemSize'],
                )
                btn.index = index
                btn.bind(on_release=lambda btn: dropdown.select(btn.index))
                dropdown.add_widget(btn)

            about = Button(
                text="About Plocka",
                size_hint_y=None,
                background_color=settings['sectionColor'],
                height=settings['itemSize'],
            )
            about.bind(on_release=lambda about: dropdown.select(-1))
            dropdown.add_widget(about)

            dropdown.open(w)

        def setActive(selected):
            if selected > -1:
                global shoppingList
                shoppingList['active'] = selected
                populate()
                writeFile(0)
            else:

                with open(scriptDir + '/ABOUT.rst') as fd:
                    about = fd.read()

                with open(scriptDir + '/LICENSE') as fd:
                    license = fd.read()

                aboutText = RstDocument(text=about +
                                        '\n\nLicense\n-------\n\n' + license, )
                popup = Popup(
                    title="Plocka " + __version__,
                    content=aboutText,
                )
                popup.open()

        def editList(w):
            buttonBox = BoxLayout()
            top.add_widget(buttonBox)
            delete = ImageButton(
                source='data/delete.png',
                color_normal=[.5, 0, 0, 1],
                size_hint_x=None,
                width=settings['headerSize'],
                on_release=lambda w: deleteList(w),
            )
            buttonBox.add_widget(delete)
            entry = TextInput(
                text=w.text,
                height=settings['headerSize'],
                multiline=False,
                on_text_validate=lambda w: setListName(w),
            )
            buttonBox.add_widget(entry)
            saveBtn = ImageButton(
                source="data/ok.png",
                color_normal=settings['greenColor'],
                size_hint_x=None,
                width=settings['headerSize'],
                on_release=lambda x: setListName(entry),
            )
            buttonBox.add_widget(saveBtn)
            copy = ImageButton(
                source='data/copy.png',
                color_normal=[1, 1, 1, .7],
                size_hint_x=None,
                width=settings['headerSize'],
                on_release=lambda w: copyList(w),
            )
            buttonBox.add_widget(copy)
            new = ImageButton(
                source='data/new.png',
                color_normal=settings['greenColor'],
                size_hint_x=None,
                width=settings['headerSize'],
                on_release=lambda w: createList(entry),
            )
            buttonBox.add_widget(new)

            top.remove_widget(title)
            top.remove_widget(searchBtn)
            entry.focused = True

        def closeEditor(w):
            top.add_widget(title)
            top.add_widget(searchBtn)
            top.remove_widget(w.parent)

        def setListName(w):
            title.text = w.text
            closeEditor(w)
            writeFile(0)

        def createList(w):
            global shoppingList
            new = {
                'name': 'New list',
                'list': [{
                    'section': 'Section',
                    'items': []
                }]
            }
            at = shoppingList['active'] + 1
            shoppingList['lists'].insert(at, new)
            setActive(at)
            closeEditor(w)

        def copyList(w):
            global shoppingList
            at = shoppingList['active']
            new = json.loads(json.dumps(shoppingList['lists'][at]))
            new['name'] += ' 2'
            at += 1
            shoppingList['lists'].insert(at, new)
            setActive(at)
            closeEditor(w)

        def deleteList(w):
            at = shoppingList['active']
            del (shoppingList['lists'][at])
            if at >= len(shoppingList['lists']):
                at = at - 1
            setActive(at)
            closeEditor(w)

        # Widgets

        def sectionButton(text):
            label = LongpressButton(
                text=text.upper(),
                font_size=settings['sectionTextSize'],
                height=settings['sectionSize'],
                background_color=settings['sectionColor'],
                size_hint=(1, None),
                on_long_press=lambda w: edit(w),
            )
            label.origText = text
            label.type = 'section'
            return label

        def itemButtonPair(text, done):
            label = LongpressButton(
                text=text,
                height=settings['itemSize'],
                background_color=settings['itemColor'],
                size_hint=(0.95, None),
                on_short_press=lambda w: toggle(w),
                on_long_press=lambda w: edit(w),
            )
            label.type = 'item'
            check = CheckBox(
                height=settings['itemSize'],
                size_hint=(0.05, None),
                on_release=lambda w: crossCheck(w),
            )
            if done:
                label.background_color = settings['doneColor']
                label.color = settings['inactiveColor']
                check.state = 'down'
            check.type = 'check'
            check.label = label
            label.check = check
            return label

        def populate():
            global shoppingList
            if not 'lists' in shoppingList:
                shoppingList = {
                    'lists': [{
                        'name': 'Plocka',
                        'list': shoppingList
                    }]
                }
            if not 'active' in shoppingList:
                shoppingList['active'] = 0
            title.text = shoppingList['lists'][shoppingList['active']]['name']
            stack.clear_widgets()
            for section in shoppingList['lists'][
                    shoppingList['active']]['list']:
                if settings['showSections'] != 'never':
                    sectionLabel = sectionButton(section['section'])
                    stack.add_widget(sectionLabel)
                for item in section['items']:
                    label = itemButtonPair(item['item'], item['done'])
                    stack.add_widget(label.check)
                    stack.add_widget(label)

        def toggleSearch(widget):
            if searchInput.disabled:
                top.add_widget(searchInput, 1)
                searchInput.disabled = False
                searchInput.focused = True
            else:
                searchInput.text = ''
                searchInput.disabled = True
                top.remove_widget(searchInput)
                hideUnHide(hideBtn)

        # MAIN

        top = BoxLayout(
            size_hint=(1, None),
            height=settings['headerSize'],
        )
        self.add_widget(top)

        title = LongpressButton(
            text='Unknown',
            background_color=settings['sectionColor'],
            on_short_press=selectList,
            on_long_press=editList,
        )
        top.add_widget(title)

        searchBtn = ImageButton(
            source='data/search.png',
            width=settings['headerSize'],
            color_normal=[1, 1, 1, .6],
            on_release=toggleSearch,
            size_hint_x=None,
        )
        top.add_widget(searchBtn)
        searchInput = TextInput(
            disabled=True,
            multiline=False,
            input_filter=doSearch,
            on_text_validate=lambda w: hideUnHide(hideBtn),
        )

        scrollBox = ScrollView(
            size_hint=(1, .9),
            do_scroll_x=False,
        )
        self.add_widget(scrollBox)

        stack = StackLayout(size_hint=(1, None))
        stack.bind(minimum_height=stack.setter('height'))
        scrollBox.add_widget(stack)

        populate()

        buttons = BoxLayout(
            size_hint=(1, None),
            height=settings['headerSize'],
        )
        self.add_widget(buttons)
        saveBtn = ImageButton(
            source="data/ok.png",
            color_normal=settings['greenColor'],
            on_release=lambda x: writeFile(0),
        )
        buttons.add_widget(saveBtn)

        hideBtn = ToggleImageButton(
            image_down="data/show.png",
            image_normal="data/hide.png",
            color_down=[1, 1, 1, .9],
            color_normal=[1, 1, 1, .6],
            on_release=hideUnHide,
        )
        buttons.add_widget(hideBtn)

        undoBtn = ImageButton(
            source='data/undo.png',
            color_normal=settings['redColor'],
            on_release=undo,
        )
        buttons.add_widget(undoBtn)

        bookmarkBtn = LongpressImageButton(
            source='data/bookmark.png',
            color_normal=settings['greenColor'],
            on_short_press=lambda w: setBookmark(),
            on_long_press=lambda w: getBookmark(),
        )
        buttons.add_widget(bookmarkBtn)