Beispiel #1
0
class ClockWidget(Widget):
    time = StringProperty()

    def update_time(self, dt):
        self.time = datetime.now().strftime(
            "[color=#ffffff]%H:%M:%S\n%m/%d/%Y[/color]")
class ShapeCutter35ScreenClass(Screen):
    
    info_button = ObjectProperty()
    vacuum_toggle = ObjectProperty()
    
    screen_number = StringProperty("[b]35[/b]")
    title_label = StringProperty("[b]Check spindle power[/b]")
    user_instructions = StringProperty("Press the button. The spindle should come on for 2 seconds.\n\n" \
                                       "If not, check that it\'s connected and switched on, then retry by pressing the button again.")
    
    def __init__(self, **kwargs):
        super(ShapeCutter35ScreenClass, self).__init__(**kwargs)
        self.shapecutter_sm = kwargs['shapecutter']
        self.m=kwargs['machine']

    def on_pre_enter(self):
        self.info_button.opacity = 0

# Action buttons       
    def get_info(self):
        pass
    
    def go_back(self):
        self.shapecutter_sm.previous_screen()    
    
    def next_screen(self):
        self.shapecutter_sm.next_screen()
    
# Tab functions

    def prepare(self):
        self.shapecutter_sm.prepare_tab()
    
    def load(self):
        self.shapecutter_sm.load_tab()
    
    def define(self):
        self.shapecutter_sm.define_tab()
    
    def position(self):
        self.shapecutter_sm.position_tab()
    
    def check(self):
        self.shapecutter_sm.check_tab()
    
    def exit(self):
        self.shapecutter_sm.exit_shapecutter()
    
# Screen specific

    def set_spindle(self):
        if self.spindle_toggle.state == 'normal':
            self.next_button.disabled = False
            self.back_button.disabled = False
            self.spindle_image.source = "./asmcnc/skavaUI/img/spindle_off.png"
            self.m.spindle_off()
        else: 
            self.spindle_image.source = "./asmcnc/skavaUI/img/spindle_on.png"
            self.next_button.disabled = True
            self.back_button.disabled = True
            self.m.spindle_on()
            Clock.schedule_once(self.reset_spindle, 2)

    def reset_spindle(self, dt):
        #self.m.vac_on()
        self.spindle_toggle.state = 'normal'
        self.set_spindle()
Beispiel #3
0
class NavigationDrawerIconButton(OneLineIconListItem):
    """An item in the :class:`MDNavigationDrawer`."""

    _active = BooleanProperty(False)
    _active_color = ListProperty()
    _icon = ObjectProperty()
    divider = None

    active_color = ListProperty()
    """Custom active color.
    This option only takes effect when :attr:`active_color_type` = 'custom'.

    :attr:`active_color` is a :class:`~kivy.properties.ListProperty`
    and defaults to None.
    """

    active_color_type = OptionProperty('primary',
                                       options=['primary', 'accent', 'custom'])
    """Decides which color should be used for the active color.
    This option only takes effect when :attr:`use_active` = True.

    Options:
        primary: Active color will be the primary theme color.

        accent: Active color will be the theme's accent color.

        custom: Active color will be taken from the :attr:`active_color` attribute.

    :attr:`active_color_type` is a :class:`~kivy.properties.OptionProperty`
    and defaults to 'primary'.
    """

    icon = StringProperty('checkbox-blank-circle')
    """Icon that appears to the left of the widget.

    :attr:`icon` is a :class:`~kivy.properties.StringProperty` and defaults
    to 'checkbox-blank-circle'.
    """
    badge_text = StringProperty('')
    """
    Text that appears on the right side of the item, usually
    for displaying a count of sorts.


    :attr:`badge_text` is a :class:`~kivy.properties.StringProperty`
    and defaults to ''.
    """
    use_active = BooleanProperty(True)
    """If the button should change to the active color when selected.

    :attr:`use_active` is a :class:`~kivy.properties.BooleanProperty`
    and defaults to True.

    See also:
        :attr:`active_color`

        :attr:`active_color_type`
    """

    # active_color = get_color_from_hex(colors['Red']['500'])
    # active_color_type = 'custom'

    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        self._set_active_color()
        self.theme_cls.bind(primary_color=self._set_active_color_primary,
                            accent_color=self._set_active_color_accent)
        Clock.schedule_once(lambda x: self.on_icon(self, self.icon))

    def _set_active(self, active, nav_drawer):
        if self.use_active:
            self._active = active
            if nav_drawer.active_item != self:
                if nav_drawer.active_item is not None:
                    nav_drawer.active_item._active = False
            nav_drawer.active_item = self

    def _set_active_color(self, *args):
        if self.active_color_type == 'primary':
            self._set_active_color_primary()
        elif self.active_color_type == 'accent':
            self._set_active_color_accent()

    # Note to future developers/myself: These must be separate functions
    def _set_active_color_primary(self, *args):
        if self.active_color_type == 'primary':
            self._active_color = self.theme_cls.primary_color

    def _set_active_color_accent(self, *args):
        if self.active_color_type == 'accent':
            self._active_color = self.theme_cls.accent_color

    def on_icon(self, instance, value):
        super().__init__()
        self.ids._icon.text = u'{}'.format(md_icons[value])

    def on_active_color_type(self, *args):
        self._set_active_color(args)
Beispiel #4
0
class ElectrumWindow(App):

    electrum_config = ObjectProperty(None)
    language = StringProperty('en')

    # properties might be updated by the network
    num_blocks = NumericProperty(0)
    num_nodes = NumericProperty(0)
    server_host = StringProperty('')
    server_port = StringProperty('')
    num_chains = NumericProperty(0)
    blockchain_name = StringProperty('')
    fee_status = StringProperty('Fee')
    balance = StringProperty('')
    fiat_balance = StringProperty('')
    is_fiat = BooleanProperty(False)
    blockchain_forkpoint = NumericProperty(0)

    auto_connect = BooleanProperty(False)
    def on_auto_connect(self, instance, x):
        net_params = self.network.get_parameters()
        net_params = net_params._replace(auto_connect=self.auto_connect)
        self.network.run_from_another_thread(self.network.set_parameters(net_params))
    def toggle_auto_connect(self, x):
        self.auto_connect = not self.auto_connect

    oneserver = BooleanProperty(False)
    def on_oneserver(self, instance, x):
        net_params = self.network.get_parameters()
        net_params = net_params._replace(oneserver=self.oneserver)
        self.network.run_from_another_thread(self.network.set_parameters(net_params))
    def toggle_oneserver(self, x):
        self.oneserver = not self.oneserver

    proxy_str = StringProperty('')
    def update_proxy_str(self, proxy: dict):
        mode = proxy.get('mode')
        host = proxy.get('host')
        port = proxy.get('port')
        self.proxy_str = (host + ':' + port) if mode else _('None')

    def choose_server_dialog(self, popup):
        from .uix.dialogs.choice_dialog import ChoiceDialog
        protocol = 's'
        def cb2(host):
            from electrum import constants
            pp = servers.get(host, constants.net.DEFAULT_PORTS)
            port = pp.get(protocol, '')
            popup.ids.host.text = host
            popup.ids.port.text = port
        servers = self.network.get_servers()
        ChoiceDialog(_('Choose a server'), sorted(servers), popup.ids.host.text, cb2).open()

    def choose_blockchain_dialog(self, dt):
        from .uix.dialogs.choice_dialog import ChoiceDialog
        chains = self.network.get_blockchains()
        def cb(name):
            with blockchain.blockchains_lock: blockchain_items = list(blockchain.blockchains.items())
            for chain_id, b in blockchain_items:
                if name == b.get_name():
                    self.network.run_from_another_thread(self.network.follow_chain_given_id(chain_id))
        chain_objects = [blockchain.blockchains.get(chain_id) for chain_id in chains]
        chain_objects = filter(lambda b: b is not None, chain_objects)
        names = [b.get_name() for b in chain_objects]
        if len(names) > 1:
            cur_chain = self.network.blockchain().get_name()
            ChoiceDialog(_('Choose your chain'), names, cur_chain, cb).open()

    use_rbf = BooleanProperty(False)
    def on_use_rbf(self, instance, x):
        self.electrum_config.set_key('use_rbf', self.use_rbf, True)

    use_change = BooleanProperty(False)
    def on_use_change(self, instance, x):
        self.electrum_config.set_key('use_change', self.use_change, True)

    use_unconfirmed = BooleanProperty(False)
    def on_use_unconfirmed(self, instance, x):
        self.electrum_config.set_key('confirmed_only', not self.use_unconfirmed, True)

    def set_URI(self, uri):
        self.switch_to('send')
        self.send_screen.set_URI(uri)

    def on_new_intent(self, intent):
        if intent.getScheme() != 'bitcoin':
            return
        uri = intent.getDataString()
        self.set_URI(uri)

    def on_language(self, instance, language):
        Logger.info('language: {}'.format(language))
        _.switch_lang(language)

    def update_history(self, *dt):
        if self.history_screen:
            self.history_screen.update()

    def on_quotes(self, d):
        Logger.info("on_quotes")
        self._trigger_update_status()
        self._trigger_update_history()

    def on_history(self, d):
        Logger.info("on_history")
        if self.wallet:
            self.wallet.clear_coin_price_cache()
        self._trigger_update_history()

    def on_fee_histogram(self, *args):
        self._trigger_update_history()

    def _get_bu(self):
        decimal_point = self.electrum_config.get('decimal_point', DECIMAL_POINT_DEFAULT)
        try:
            return decimal_point_to_base_unit_name(decimal_point)
        except UnknownBaseUnit:
            return decimal_point_to_base_unit_name(DECIMAL_POINT_DEFAULT)

    def _set_bu(self, value):
        assert value in base_units.keys()
        decimal_point = base_unit_name_to_decimal_point(value)
        self.electrum_config.set_key('decimal_point', decimal_point, True)
        self._trigger_update_status()
        self._trigger_update_history()

    wallet_name = StringProperty(_('No Wallet'))
    base_unit = AliasProperty(_get_bu, _set_bu)
    fiat_unit = StringProperty('')

    def on_fiat_unit(self, a, b):
        self._trigger_update_history()

    def decimal_point(self):
        return base_units[self.base_unit]

    def btc_to_fiat(self, amount_str):
        if not amount_str:
            return ''
        if not self.fx.is_enabled():
            return ''
        rate = self.fx.exchange_rate()
        if rate.is_nan():
            return ''
        fiat_amount = self.get_amount(amount_str + ' ' + self.base_unit) * rate / pow(10, 8)
        return "{:.2f}".format(fiat_amount).rstrip('0').rstrip('.')

    def fiat_to_btc(self, fiat_amount):
        if not fiat_amount:
            return ''
        rate = self.fx.exchange_rate()
        if rate.is_nan():
            return ''
        satoshis = int(pow(10,8) * Decimal(fiat_amount) / Decimal(rate))
        return format_satoshis_plain(satoshis, self.decimal_point())

    def get_amount(self, amount_str):
        a, u = amount_str.split()
        assert u == self.base_unit
        try:
            x = Decimal(a)
        except:
            return None
        p = pow(10, self.decimal_point())
        return int(p * x)


    _orientation = OptionProperty('landscape',
                                 options=('landscape', 'portrait'))

    def _get_orientation(self):
        return self._orientation

    orientation = AliasProperty(_get_orientation,
                                None,
                                bind=('_orientation',))
    '''Tries to ascertain the kind of device the app is running on.
    Cane be one of `tablet` or `phone`.

    :data:`orientation` is a read only `AliasProperty` Defaults to 'landscape'
    '''

    _ui_mode = OptionProperty('phone', options=('tablet', 'phone'))

    def _get_ui_mode(self):
        return self._ui_mode

    ui_mode = AliasProperty(_get_ui_mode,
                            None,
                            bind=('_ui_mode',))
    '''Defines tries to ascertain the kind of device the app is running on.
    Cane be one of `tablet` or `phone`.

    :data:`ui_mode` is a read only `AliasProperty` Defaults to 'phone'
    '''

    def __init__(self, **kwargs):
        # initialize variables
        self._clipboard = Clipboard
        self.info_bubble = None
        self.nfcscanner = None
        self.tabs = None
        self.is_exit = False
        self.wallet = None
        self.pause_time = 0
        self.asyncio_loop = asyncio.get_event_loop()

        App.__init__(self)#, **kwargs)

        title = _('Electrum App')
        self.electrum_config = config = kwargs.get('config', None)
        self.language = config.get('language', 'en')
        self.network = network = kwargs.get('network', None)  # type: Network
        if self.network:
            self.num_blocks = self.network.get_local_height()
            self.num_nodes = len(self.network.get_interfaces())
            net_params = self.network.get_parameters()
            self.server_host = net_params.host
            self.server_port = net_params.port
            self.auto_connect = net_params.auto_connect
            self.oneserver = net_params.oneserver
            self.proxy_config = net_params.proxy if net_params.proxy else {}
            self.update_proxy_str(self.proxy_config)

        self.plugins = kwargs.get('plugins', [])
        self.gui_object = kwargs.get('gui_object', None)
        self.daemon = self.gui_object.daemon
        self.fx = self.daemon.fx

        self.use_rbf = config.get('use_rbf', True)
        self.use_change = config.get('use_change', True)
        self.use_unconfirmed = not config.get('confirmed_only', False)

        # create triggers so as to minimize updating a max of 2 times a sec
        self._trigger_update_wallet = Clock.create_trigger(self.update_wallet, .5)
        self._trigger_update_status = Clock.create_trigger(self.update_status, .5)
        self._trigger_update_history = Clock.create_trigger(self.update_history, .5)
        self._trigger_update_interfaces = Clock.create_trigger(self.update_interfaces, .5)

        self._periodic_update_status_during_sync = Clock.schedule_interval(self.update_wallet_synchronizing_progress, .5)

        # cached dialogs
        self._settings_dialog = None
        self._password_dialog = None
        self.fee_status = self.electrum_config.get_fee_status()

    def on_pr(self, pr):
        if not self.wallet:
            self.show_error(_('No wallet loaded.'))
            return
        if pr.verify(self.wallet.contacts):
            key = self.wallet.invoices.add(pr)
            if self.invoices_screen:
                self.invoices_screen.update()
            status = self.wallet.invoices.get_status(key)
            if status == PR_PAID:
                self.show_error("invoice already paid")
                self.send_screen.do_clear()
            else:
                if pr.has_expired():
                    self.show_error(_('Payment request has expired'))
                else:
                    self.switch_to('send')
                    self.send_screen.set_request(pr)
        else:
            self.show_error("invoice error:" + pr.error)
            self.send_screen.do_clear()

    def on_qr(self, data):
        from electrum.bitcoin import base_decode, is_address
        data = data.strip()
        if is_address(data):
            self.set_URI(data)
            return
        if data.startswith('bitcoin:'):
            self.set_URI(data)
            return
        # try to decode transaction
        from electrum.transaction import Transaction
        from electrum.util import bh2u
        try:
            text = bh2u(base_decode(data, None, base=43))
            tx = Transaction(text)
            tx.deserialize()
        except:
            tx = None
        if tx:
            self.tx_dialog(tx)
            return
        # show error
        self.show_error("Unable to decode QR data")

    def update_tab(self, name):
        s = getattr(self, name + '_screen', None)
        if s:
            s.update()

    @profiler
    def update_tabs(self):
        for tab in ['invoices', 'send', 'history', 'receive', 'address']:
            self.update_tab(tab)

    def switch_to(self, name):
        s = getattr(self, name + '_screen', None)
        if s is None:
            s = self.tabs.ids[name + '_screen']
            s.load_screen()
        panel = self.tabs.ids.panel
        tab = self.tabs.ids[name + '_tab']
        panel.switch_to(tab)

    def show_request(self, addr):
        self.switch_to('receive')
        self.receive_screen.screen.address = addr

    def show_pr_details(self, req, status, is_invoice):
        from electrum.util import format_time
        requestor = req.get('requestor')
        exp = req.get('exp')
        memo = req.get('memo')
        amount = req.get('amount')
        fund = req.get('fund')
        popup = Builder.load_file('electrum/gui/kivy/uix/ui_screens/invoice.kv')
        popup.is_invoice = is_invoice
        popup.amount = amount
        popup.requestor = requestor if is_invoice else req.get('address')
        popup.exp = format_time(exp) if exp else ''
        popup.description = memo if memo else ''
        popup.signature = req.get('signature', '')
        popup.status = status
        popup.fund = fund if fund else 0
        txid = req.get('txid')
        popup.tx_hash = txid or ''
        popup.on_open = lambda: popup.ids.output_list.update(req.get('outputs', []))
        popup.export = self.export_private_keys
        popup.open()

    def show_addr_details(self, req, status):
        from electrum.util import format_time
        fund = req.get('fund')
        isaddr = 'y'
        popup = Builder.load_file('electrum/gui/kivy/uix/ui_screens/invoice.kv')
        popup.isaddr = isaddr
        popup.is_invoice = False
        popup.status = status
        popup.requestor = req.get('address')
        popup.fund = fund if fund else 0
        popup.export = self.export_private_keys
        popup.open()

    def qr_dialog(self, title, data, show_text=False, text_for_clipboard=None):
        from .uix.dialogs.qr_dialog import QRDialog
        def on_qr_failure():
            popup.dismiss()
            msg = _('Failed to display QR code.')
            if text_for_clipboard:
                msg += '\n' + _('Text copied to clipboard.')
                self._clipboard.copy(text_for_clipboard)
            Clock.schedule_once(lambda dt: self.show_info(msg))
        popup = QRDialog(title, data, show_text, failure_cb=on_qr_failure,
                         text_for_clipboard=text_for_clipboard)
        popup.open()

    def scan_qr(self, on_complete):
        if platform != 'android':
            return
        from jnius import autoclass, cast
        from android import activity
        PythonActivity = autoclass('org.kivy.android.PythonActivity')
        SimpleScannerActivity = autoclass("org.electrum.qr.SimpleScannerActivity")
        Intent = autoclass('android.content.Intent')
        intent = Intent(PythonActivity.mActivity, SimpleScannerActivity)

        def on_qr_result(requestCode, resultCode, intent):
            try:
                if resultCode == -1:  # RESULT_OK:
                    #  this doesn't work due to some bug in jnius:
                    # contents = intent.getStringExtra("text")
                    String = autoclass("java.lang.String")
                    contents = intent.getStringExtra(String("text"))
                    on_complete(contents)
            except Exception as e:  # exc would otherwise get lost
                send_exception_to_crash_reporter(e)
            finally:
                activity.unbind(on_activity_result=on_qr_result)
        activity.bind(on_activity_result=on_qr_result)
        PythonActivity.mActivity.startActivityForResult(intent, 0)

    def do_share(self, data, title):
        if platform != 'android':
            return
        from jnius import autoclass, cast
        JS = autoclass('java.lang.String')
        Intent = autoclass('android.content.Intent')
        sendIntent = Intent()
        sendIntent.setAction(Intent.ACTION_SEND)
        sendIntent.setType("text/plain")
        sendIntent.putExtra(Intent.EXTRA_TEXT, JS(data))
        PythonActivity = autoclass('org.kivy.android.PythonActivity')
        currentActivity = cast('android.app.Activity', PythonActivity.mActivity)
        it = Intent.createChooser(sendIntent, cast('java.lang.CharSequence', JS(title)))
        currentActivity.startActivity(it)

    def build(self):
        return Builder.load_file('electrum/gui/kivy/main.kv')

    def _pause(self):
        if platform == 'android':
            # move activity to back
            from jnius import autoclass
            python_act = autoclass('org.kivy.android.PythonActivity')
            mActivity = python_act.mActivity
            mActivity.moveTaskToBack(True)

    def on_start(self):
        ''' This is the start point of the kivy ui
        '''
        import time
        Logger.info('Time to on_start: {} <<<<<<<<'.format(time.clock()))
        win = Window
        win.bind(size=self.on_size, on_keyboard=self.on_keyboard)
        win.bind(on_key_down=self.on_key_down)
        #win.softinput_mode = 'below_target'
        self.on_size(win, win.size)
        self.init_ui()
        crash_reporter.ExceptionHook(self)
        # init plugins
        run_hook('init_kivy', self)
        # fiat currency
        self.fiat_unit = self.fx.ccy if self.fx.is_enabled() else ''
        # default tab
        self.switch_to('history')
        # bind intent for bitcoin: URI scheme
        if platform == 'android':
            from android import activity
            from jnius import autoclass
            PythonActivity = autoclass('org.kivy.android.PythonActivity')
            mactivity = PythonActivity.mActivity
            self.on_new_intent(mactivity.getIntent())
            activity.bind(on_new_intent=self.on_new_intent)
        # connect callbacks
        if self.network:
            interests = ['wallet_updated', 'network_updated', 'blockchain_updated',
                         'status', 'new_transaction', 'verified']
            self.network.register_callback(self.on_network_event, interests)
            self.network.register_callback(self.on_fee, ['fee'])
            self.network.register_callback(self.on_fee_histogram, ['fee_histogram'])
            self.network.register_callback(self.on_quotes, ['on_quotes'])
            self.network.register_callback(self.on_history, ['on_history'])
        # load wallet
        self.load_wallet_by_name(self.electrum_config.get_wallet_path())
        # URI passed in config
        uri = self.electrum_config.get('url')
        if uri:
            self.set_URI(uri)


    def get_wallet_path(self):
        if self.wallet:
            return self.wallet.storage.path
        else:
            return ''

    def on_wizard_complete(self, wizard, storage):
        if storage:
            wallet = Wallet(storage)
            wallet.start_network(self.daemon.network)
            self.daemon.add_wallet(wallet)
            self.load_wallet(wallet)
        elif not self.wallet:
            # wizard did not return a wallet; and there is no wallet open atm
            # try to open last saved wallet (potentially start wizard again)
            self.load_wallet_by_name(self.electrum_config.get_wallet_path(), ask_if_wizard=True)

    def load_wallet_by_name(self, path, ask_if_wizard=False):
        if not path:
            return
        if self.wallet and self.wallet.storage.path == path:
            return
        wallet = self.daemon.load_wallet(path, None)
        if wallet:
            if wallet.has_password():
                self.password_dialog(wallet, _('Enter PIN code'), lambda x: self.load_wallet(wallet), self.stop)
            else:
                self.load_wallet(wallet)
        else:
            def launch_wizard():
                wizard = Factory.InstallWizard(self.electrum_config, self.plugins)
                wizard.path = path
                wizard.bind(on_wizard_complete=self.on_wizard_complete)
                storage = WalletStorage(path, manual_upgrades=True)
                if not storage.file_exists():
                    wizard.run('new')
                elif storage.is_encrypted():
                    raise Exception("Kivy GUI does not support encrypted wallet files.")
                elif storage.requires_upgrade():
                    wizard.upgrade_storage(storage)
                else:
                    raise Exception("unexpected storage file situation")
            if not ask_if_wizard:
                launch_wizard()
            else:
                from .uix.dialogs.question import Question
                def handle_answer(b: bool):
                    if b:
                        launch_wizard()
                    else:
                        try: os.unlink(path)
                        except FileNotFoundError: pass
                        self.stop()
                d = Question(_('Do you want to launch the wizard again?'), handle_answer)
                d.open()

    def on_stop(self):
        Logger.info('on_stop')
        if self.wallet:
            self.electrum_config.save_last_wallet(self.wallet)
        self.stop_wallet()

    def stop_wallet(self):
        if self.wallet:
            self.daemon.stop_wallet(self.wallet.storage.path)
            self.wallet = None

    def on_key_down(self, instance, key, keycode, codepoint, modifiers):
        if 'ctrl' in modifiers:
            # q=24 w=25
            if keycode in (24, 25):
                self.stop()
            elif keycode == 27:
                # r=27
                # force update wallet
                self.update_wallet()
            elif keycode == 112:
                # pageup
                #TODO move to next tab
                pass
            elif keycode == 117:
                # pagedown
                #TODO move to prev tab
                pass
        #TODO: alt+tab_number to activate the particular tab

    def on_keyboard(self, instance, key, keycode, codepoint, modifiers):
        if key == 27 and self.is_exit is False:
            self.is_exit = True
            self.show_info(_('Press again to exit'))
            return True
        # override settings button
        if key in (319, 282): #f1/settings button on android
            #self.gui.main_gui.toggle_settings(self)
            return True

    def settings_dialog(self):
        from .uix.dialogs.settings import SettingsDialog
        if self._settings_dialog is None:
            self._settings_dialog = SettingsDialog(self)
        self._settings_dialog.update()
        self._settings_dialog.open()

    def popup_dialog(self, name):
        if name == 'settings':
            self.settings_dialog()
        elif name == 'wallets':
            from .uix.dialogs.wallets import WalletDialog
            d = WalletDialog()
            d.open()
        elif name == 'status':
            popup = Builder.load_file('electrum/gui/kivy/uix/ui_screens/'+name+'.kv')
            master_public_keys_layout = popup.ids.master_public_keys
            for xpub in self.wallet.get_master_public_keys()[1:]:
                master_public_keys_layout.add_widget(TopLabel(text=_('Master Public Key')))
                ref = RefLabel()
                ref.name = _('Master Public Key')
                ref.data = xpub
                master_public_keys_layout.add_widget(ref)
            popup.open()
        else:
            popup = Builder.load_file('electrum/gui/kivy/uix/ui_screens/'+name+'.kv')
            popup.open()

    @profiler
    def init_ui(self):
        ''' Initialize The Ux part of electrum. This function performs the basic
        tasks of setting up the ui.
        '''
        #from weakref import ref

        self.funds_error = False
        # setup UX
        self.screens = {}

        #setup lazy imports for mainscreen
        Factory.register('AnimatedPopup',
                         module='electrum.gui.kivy.uix.dialogs')
        Factory.register('QRCodeWidget',
                         module='electrum.gui.kivy.uix.qrcodewidget')

        # preload widgets. Remove this if you want to load the widgets on demand
        #Cache.append('electrum_widgets', 'AnimatedPopup', Factory.AnimatedPopup())
        #Cache.append('electrum_widgets', 'QRCodeWidget', Factory.QRCodeWidget())

        # load and focus the ui
        self.root.manager = self.root.ids['manager']

        self.history_screen = None
        self.contacts_screen = None
        self.send_screen = None
        self.invoices_screen = None
        self.receive_screen = None
        self.requests_screen = None
        self.address_screen = None
        self.icon = "electrum/gui/icons/electrum.png"
        self.tabs = self.root.ids['tabs']

    def update_interfaces(self, dt):
        net_params = self.network.get_parameters()
        self.num_nodes = len(self.network.get_interfaces())
        self.num_chains = len(self.network.get_blockchains())
        chain = self.network.blockchain()
        self.blockchain_forkpoint = chain.get_max_forkpoint()
        self.blockchain_name = chain.get_name()
        interface = self.network.interface
        if interface:
            self.server_host = interface.host
        else:
            self.server_host = str(net_params.host) + ' (connecting...)'
        self.proxy_config = net_params.proxy or {}
        self.update_proxy_str(self.proxy_config)

    def on_network_event(self, event, *args):
        Logger.info('network event: '+ event)
        if event == 'network_updated':
            self._trigger_update_interfaces()
            self._trigger_update_status()
        elif event == 'wallet_updated':
            self._trigger_update_wallet()
            self._trigger_update_status()
        elif event == 'blockchain_updated':
            # to update number of confirmations in history
            self._trigger_update_wallet()
        elif event == 'status':
            self._trigger_update_status()
        elif event == 'new_transaction':
            self._trigger_update_wallet()
        elif event == 'verified':
            self._trigger_update_wallet()

    @profiler
    def load_wallet(self, wallet):
        if self.wallet:
            self.stop_wallet()
        self.wallet = wallet
        self.wallet_name = wallet.basename()
        self.update_wallet()
        # Once GUI has been initialized check if we want to announce something
        # since the callback has been called before the GUI was initialized
        if self.receive_screen:
            self.receive_screen.clear()
        self.update_tabs()
        run_hook('load_wallet', wallet, self)
        try:
            wallet.try_detecting_internal_addresses_corruption()
        except InternalAddressCorruption as e:
            self.show_error(str(e))
            send_exception_to_crash_reporter(e)

    def update_status(self, *dt):
        if not self.wallet:
            return
        if self.network is None or not self.network.is_connected():
            status = _("Offline")
        elif self.network.is_connected():
            self.num_blocks = self.network.get_local_height()
            server_height = self.network.get_server_height()
            server_lag = self.num_blocks - server_height
            if not self.wallet.up_to_date or server_height == 0:
                num_sent, num_answered = self.wallet.get_history_sync_state_details()
                status = ("{} [size=18dp]({}/{})[/size]"
                          .format(_("Synchronizing..."), num_answered, num_sent))
            elif server_lag > 1:
                status = _("Server is lagging ({} blocks)").format(server_lag)
            else:
                status = ''
        else:
            status = _("Disconnected")
        if status:
            self.balance = status
            self.fiat_balance = status
        else:
            c, u, x = self.wallet.get_balance()
            text = self.format_amount(c+x+u)
            self.balance = str(text.strip()) + ' [size=22dp]%s[/size]'% self.base_unit
            self.fiat_balance = self.fx.format_amount(c+u+x) + ' [size=22dp]%s[/size]'% self.fx.ccy

    def update_wallet_synchronizing_progress(self, *dt):
        if not self.wallet:
            return
        if not self.wallet.up_to_date:
            self._trigger_update_status()

    def get_max_amount(self):
        from electrum.transaction import TxOutput
        if run_hook('abort_send', self):
            return ''
        inputs = self.wallet.get_spendable_coins(None, self.electrum_config)
        if not inputs:
            return ''
        addr = str(self.send_screen.screen.address) or self.wallet.dummy_address()
        outputs = [TxOutput(TYPE_ADDRESS, addr, '!')]
        try:
            tx = self.wallet.make_unsigned_transaction(inputs, outputs, self.electrum_config)
        except NoDynamicFeeEstimates as e:
            Clock.schedule_once(lambda dt, bound_e=e: self.show_error(str(bound_e)))
            return ''
        except NotEnoughFunds:
            return ''
        except InternalAddressCorruption as e:
            self.show_error(str(e))
            send_exception_to_crash_reporter(e)
            return ''
        amount = tx.output_value()
        __, x_fee_amount = run_hook('get_tx_extra_fee', self.wallet, tx) or (None, 0)
        amount_after_all_fees = amount - x_fee_amount
        return format_satoshis_plain(amount_after_all_fees, self.decimal_point())

    def format_amount(self, x, is_diff=False, whitespaces=False):
        return format_satoshis(x, 0, self.decimal_point(), is_diff=is_diff, whitespaces=whitespaces)

    def format_amount_and_units(self, x):
        return format_satoshis_plain(x, self.decimal_point()) + ' ' + self.base_unit

    def format_fee_rate(self, fee_rate):
        # fee_rate is in sat/kB
        return format_fee_satoshis(fee_rate/1000) + ' sat/byte'

    #@profiler
    def update_wallet(self, *dt):
        self._trigger_update_status()
        if self.wallet and (self.wallet.up_to_date or not self.network or not self.network.is_connected()):
            self.update_tabs()

    def notify(self, message):
        try:
            global notification, os
            if not notification:
                from plyer import notification
            icon = (os.path.dirname(os.path.realpath(__file__))
                    + '/../../' + self.icon)
            notification.notify('Electrum', message,
                            app_icon=icon, app_name='Electrum')
        except ImportError:
            Logger.Error('Notification: needs plyer; `sudo python3 -m pip install plyer`')

    def on_pause(self):
        self.pause_time = time.time()
        # pause nfc
        if self.nfcscanner:
            self.nfcscanner.nfc_disable()
        return True

    def on_resume(self):
        now = time.time()
        if self.wallet and self.wallet.has_password() and now - self.pause_time > 60:
            self.password_dialog(self.wallet, _('Enter PIN'), None, self.stop)
        if self.nfcscanner:
            self.nfcscanner.nfc_enable()

    def on_size(self, instance, value):
        width, height = value
        self._orientation = 'landscape' if width > height else 'portrait'
        self._ui_mode = 'tablet' if min(width, height) > inch(3.51) else 'phone'

    def on_ref_label(self, label, touch):
        if label.touched:
            label.touched = False
            self.qr_dialog(label.name, label.data, True)
        else:
            label.touched = True
            self._clipboard.copy(label.data)
            Clock.schedule_once(lambda dt: self.show_info(_('Text copied to clipboard.\nTap again to display it as QR code.')))

    def show_error(self, error, width='200dp', pos=None, arrow_pos=None,
        exit=False, icon='atlas://electrum/gui/kivy/theming/light/error', duration=0,
        modal=False):
        ''' Show an error Message Bubble.
        '''
        self.show_info_bubble( text=error, icon=icon, width=width,
            pos=pos or Window.center, arrow_pos=arrow_pos, exit=exit,
            duration=duration, modal=modal)

    def show_info(self, error, width='200dp', pos=None, arrow_pos=None,
        exit=False, duration=0, modal=False):
        ''' Show an Info Message Bubble.
        '''
        self.show_error(error, icon='atlas://electrum/gui/kivy/theming/light/important',
            duration=duration, modal=modal, exit=exit, pos=pos,
            arrow_pos=arrow_pos)

    def show_info_bubble(self, text=_('Hello World'), pos=None, duration=0,
        arrow_pos='bottom_mid', width=None, icon='', modal=False, exit=False):
        '''Method to show an Information Bubble

        .. parameters::
            text: Message to be displayed
            pos: position for the bubble
            duration: duration the bubble remains on screen. 0 = click to hide
            width: width of the Bubble
            arrow_pos: arrow position for the bubble
        '''
        info_bubble = self.info_bubble
        if not info_bubble:
            info_bubble = self.info_bubble = Factory.InfoBubble()

        win = Window
        if info_bubble.parent:
            win.remove_widget(info_bubble
                                 if not info_bubble.modal else
                                 info_bubble._modal_view)

        if not arrow_pos:
            info_bubble.show_arrow = False
        else:
            info_bubble.show_arrow = True
            info_bubble.arrow_pos = arrow_pos
        img = info_bubble.ids.img
        if text == 'texture':
            # icon holds a texture not a source image
            # display the texture in full screen
            text = ''
            img.texture = icon
            info_bubble.fs = True
            info_bubble.show_arrow = False
            img.allow_stretch = True
            info_bubble.dim_background = True
            info_bubble.background_image = 'atlas://electrum/gui/kivy/theming/light/card'
        else:
            info_bubble.fs = False
            info_bubble.icon = icon
            #if img.texture and img._coreimage:
            #    img.reload()
            img.allow_stretch = False
            info_bubble.dim_background = False
            info_bubble.background_image = 'atlas://data/images/defaulttheme/bubble'
        info_bubble.message = text
        if not pos:
            pos = (win.center[0], win.center[1] - (info_bubble.height/2))
        info_bubble.show(pos, duration, width, modal=modal, exit=exit)

    def tx_dialog(self, tx):
        from .uix.dialogs.tx_dialog import TxDialog
        d = TxDialog(self, tx)
        d.open()

    def sign_tx(self, *args):
        threading.Thread(target=self._sign_tx, args=args).start()

    def _sign_tx(self, tx, password, on_success, on_failure):
        try:
            self.wallet.sign_transaction(tx, password)
        except InvalidPassword:
            Clock.schedule_once(lambda dt: on_failure(_("Invalid PIN")))
            return
        on_success = run_hook('tc_sign_wrapper', self.wallet, tx, on_success, on_failure) or on_success
        Clock.schedule_once(lambda dt: on_success(tx))

    def _broadcast_thread(self, tx, on_complete):
        status = False
        try:
            self.network.run_from_another_thread(self.network.broadcast_transaction(tx))
        except TxBroadcastError as e:
            msg = e.get_message_for_gui()
        except BestEffortRequestFailed as e:
            msg = repr(e)
        else:
            status, msg = True, tx.txid()
        Clock.schedule_once(lambda dt: on_complete(status, msg))

    def broadcast(self, tx, pr=None):
        def on_complete(ok, msg):
            if ok:
                self.show_info(_('Payment sent.'))
                if self.send_screen:
                    self.send_screen.do_clear()
                if pr:
                    self.wallet.invoices.set_paid(pr, tx.txid())
                    self.wallet.invoices.save()
                    self.update_tab('invoices')
            else:
                msg = msg or ''
                self.show_error(msg)

        if self.network and self.network.is_connected():
            self.show_info(_('Sending'))
            threading.Thread(target=self._broadcast_thread, args=(tx, on_complete)).start()
        else:
            self.show_info(_('Cannot broadcast transaction') + ':\n' + _('Not connected'))

    def description_dialog(self, screen):
        from .uix.dialogs.label_dialog import LabelDialog
        text = screen.message
        def callback(text):
            screen.message = text
        d = LabelDialog(_('Enter description'), text, callback)
        d.open()

    def amount_dialog(self, screen, show_max):
        from .uix.dialogs.amount_dialog import AmountDialog
        amount = screen.amount
        if amount:
            amount, u = str(amount).split()
            assert u == self.base_unit
        def cb(amount):
            screen.amount = amount
        popup = AmountDialog(show_max, amount, cb)
        popup.open()

    def invoices_dialog(self, screen):
        from .uix.dialogs.invoices import InvoicesDialog
        if len(self.wallet.invoices.sorted_list()) == 0:
            self.show_info(' '.join([
                _('No saved invoices.'),
                _('Signed invoices are saved automatically when you scan them.'),
                _('You may also save unsigned requests or contact addresses using the save button.')
            ]))
            return
        popup = InvoicesDialog(self, screen, None)
        popup.update()
        popup.open()

    def requests_dialog(self, screen):
        from .uix.dialogs.requests import RequestsDialog
        if len(self.wallet.get_sorted_requests(self.electrum_config)) == 0:
            self.show_info(_('No saved requests.'))
            return
        popup = RequestsDialog(self, screen, None)
        popup.update()
        popup.open()

    def addresses_dialog(self, screen):
        from .uix.dialogs.addresses import AddressesDialog
        popup = AddressesDialog(self, screen, None)
        popup.update()
        popup.open()

    def fee_dialog(self, label, dt):
        from .uix.dialogs.fee_dialog import FeeDialog
        def cb():
            self.fee_status = self.electrum_config.get_fee_status()
        fee_dialog = FeeDialog(self, self.electrum_config, cb)
        fee_dialog.open()

    def on_fee(self, event, *arg):
        self.fee_status = self.electrum_config.get_fee_status()

    def protected(self, msg, f, args):
        if self.wallet.has_password():
            on_success = lambda pw: f(*(args + (pw,)))
            self.password_dialog(self.wallet, msg, on_success, lambda: None)
        else:
            f(*(args + (None,)))

    def delete_wallet(self):
        from .uix.dialogs.question import Question
        basename = os.path.basename(self.wallet.storage.path)
        d = Question(_('Delete wallet?') + '\n' + basename, self._delete_wallet)
        d.open()

    def _delete_wallet(self, b):
        if b:
            basename = self.wallet.basename()
            self.protected(_("Enter your PIN code to confirm deletion of {}").format(basename), self.__delete_wallet, ())

    def __delete_wallet(self, pw):
        wallet_path = self.get_wallet_path()
        dirname = os.path.dirname(wallet_path)
        basename = os.path.basename(wallet_path)
        if self.wallet.has_password():
            try:
                self.wallet.check_password(pw)
            except:
                self.show_error("Invalid PIN")
                return
        self.stop_wallet()
        os.unlink(wallet_path)
        self.show_error(_("Wallet removed: {}").format(basename))
        new_path = self.electrum_config.get_wallet_path()
        self.load_wallet_by_name(new_path)

    def show_seed(self, label):
        self.protected(_("Enter your PIN code in order to decrypt your seed"), self._show_seed, (label,))

    def _show_seed(self, label, password):
        if self.wallet.has_password() and password is None:
            return
        keystore = self.wallet.keystore
        try:
            seed = keystore.get_seed(password)
            passphrase = keystore.get_passphrase(password)
        except:
            self.show_error("Invalid PIN")
            return
        label.text = _('Seed') + ':\n' + seed
        if passphrase:
            label.text += '\n\n' + _('Passphrase') + ': ' + passphrase

    def password_dialog(self, wallet, msg, on_success, on_failure):
        from .uix.dialogs.password_dialog import PasswordDialog
        if self._password_dialog is None:
            self._password_dialog = PasswordDialog()
        self._password_dialog.init(self, wallet, msg, on_success, on_failure)
        self._password_dialog.open()

    def change_password(self, cb):
        from .uix.dialogs.password_dialog import PasswordDialog
        if self._password_dialog is None:
            self._password_dialog = PasswordDialog()
        message = _("Changing PIN code.") + '\n' + _("Enter your current PIN:")
        def on_success(old_password, new_password):
            self.wallet.update_password(old_password, new_password)
            self.show_info(_("Your PIN code was updated"))
        on_failure = lambda: self.show_error(_("PIN codes do not match"))
        self._password_dialog.init(self, self.wallet, message, on_success, on_failure, is_change=1)
        self._password_dialog.open()

    def export_private_keys(self, pk_label, addr):
        if self.wallet.is_watching_only():
            self.show_info(_('This is a watching-only wallet. It does not contain private keys.'))
            return
        def show_private_key(addr, pk_label, password):
            if self.wallet.has_password() and password is None:
                return
            if not self.wallet.can_export():
                return
            try:
                key = str(self.wallet.export_private_key(addr, password)[0])
                pk_label.data = key
            except InvalidPassword:
                self.show_error("Invalid PIN")
                return
        self.protected(_("Enter your PIN code in order to decrypt your private key"), show_private_key, (addr, pk_label))
Beispiel #5
0
class MDUserAnimationCard(ThemableBehavior, ModalView):
    user_name = StringProperty()
    path_to_avatar = StringProperty()
    box_content = ObjectProperty()
    callback = ObjectProperty()
    _anim_bottom = True

    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        self._primary_color = self.theme_cls.primary_color
        self._primary_color[3] = 0
        self.user_animation_card = UserAnimationCard(
            user_name=self.user_name,
            path_to_avatar=self.path_to_avatar,
            _callback_back=self._callback_back,
            _primary_color=self._primary_color,
        )
        self.user_animation_card.ids.user_name.pos = (
            dp(15),
            Window.height - self.user_animation_card.ids.image.height,
        )
        self.box_content = self.user_animation_card.ids.box_content
        self.add_widget(self.user_animation_card)

        self._obj_avatar = self.user_animation_card.ids.image
        self._obj_user_name = self.user_animation_card.ids.user_name
        self._obj_toolbar = self.user_animation_card.ids.toolbar
        self._obj_scroll = self.user_animation_card.ids.scroll
        self._set_current_pos_objects()

    def _callback_back(self):
        self.dismiss()
        if self.callback:
            self.callback()

    def on_open(self):
        self._primary_color = self.theme_cls.primary_color
        self._primary_color[3] = 0
        self.user_animation_card._primary_color = self._primary_color

    def _set_current_pos_objects(self):
        self._avatar_y = self._obj_avatar.y
        self._toolbar_y = self._obj_toolbar.y
        self._user_name_y = self._obj_user_name.y
        self._scroll_y = self._obj_scroll.y

    def on_touch_move(self, touch):
        if touch.ud["swipe_begin"] < touch.y:
            if self._anim_bottom:
                self._anim_bottom = False
                self.animation_to_top()
        else:
            if not self._anim_bottom:
                self._anim_bottom = True
                self.animation_to_bottom()

    def on_touch_down(self, touch):
        touch.ud["swipe_begin"] = touch.y
        return super().on_touch_down(touch)

    def on_touch_up(self, touch):
        touch.ud["swipe_begin"] = 0

    def animation_to_bottom(self):
        Animation(y=self._scroll_y, d=0.4,
                  t="in_out_cubic").start(self._obj_scroll)
        Animation(y=self._user_name_y, d=0.5, x=dp(15),
                  t="in_out_cubic").start(self._obj_user_name)
        Animation(font_size=sp(36), d=0.3,
                  t="in_out_cubic").start(self._obj_user_name)
        Animation(_primary_color=[0, 0, 0, 0], d=0.3,
                  t="in_out_cubic").start(self.user_animation_card)
        Animation(y=self._avatar_y, d=0.4,
                  t="in_out_cubic").start(self._obj_avatar)

    def animation_to_top(self):
        user_name_y = (Window.height - self._obj_toolbar.height +
                       (self.theme_cls.standard_increment // 2 - dp(12)))
        user_name_x = self.theme_cls.horizontal_margins + dp(12) * 5

        Animation(y=-self._obj_toolbar.height, d=0.4,
                  t="in_out_cubic").start(self._obj_scroll)
        Animation(y=user_name_y, d=0.3, x=user_name_x,
                  t="in_out_cubic").start(self._obj_user_name)
        Animation(font_size=sp(20), d=0.3,
                  t="in_out_cubic").start(self._obj_user_name)
        Animation(_primary_color=self.theme_cls.primary_color,
                  d=0.3,
                  t="in_out_cubic").start(self.user_animation_card)
        Animation(y=self._obj_avatar.y + 30, d=0.4,
                  t="in_out_cubic").start(self._obj_avatar)
Beispiel #6
0
class MDCardSwipe(RelativeLayout):
    """
    :Events:
        :attr:`on_swipe_complete`
            Called when a swipe of card is completed.
    """

    open_progress = NumericProperty(0.0)
    """
    Percent of visible part of side panel. The percent is specified as a
    floating point number in the range 0-1. 0.0 if panel is closed and 1.0 if
    panel is opened.

    :attr:`open_progress` is a :class:`~kivy.properties.NumericProperty`
    and defaults to `0.0`.
    """

    opening_transition = StringProperty("out_cubic")
    """
    The name of the animation transition type to use when animating to
    the :attr:`state` `'opened'`.

    :attr:`opening_transition` is a :class:`~kivy.properties.StringProperty`
    and defaults to `'out_cubic'`.
    """

    closing_transition = StringProperty("out_sine")
    """
    The name of the animation transition type to use when animating to
    the :attr:`state` 'closed'.

    :attr:`closing_transition` is a :class:`~kivy.properties.StringProperty`
    and defaults to `'out_sine'`.
    """

    anchor = OptionProperty("left", options=("left", "right"))
    """
    Anchoring screen edge for card. Available options are: `'left'`, `'right'`.

    :attr:`anchor` is a :class:`~kivy.properties.OptionProperty`
    and defaults to `left`.
    """

    swipe_distance = NumericProperty(50)
    """
    The distance of the swipe with which the movement of navigation drawer
    begins.

    :attr:`swipe_distance` is a :class:`~kivy.properties.NumericProperty`
    and defaults to `50`.
    """

    opening_time = NumericProperty(0.2)
    """
    The time taken for the card to slide to the :attr:`state` `'open'`.

    :attr:`opening_time` is a :class:`~kivy.properties.NumericProperty`
    and defaults to `0.2`.
    """

    state = OptionProperty("closed", options=("closed", "opened"))
    """
    Detailed state. Sets before :attr:`state`. Bind to :attr:`state` instead
    of :attr:`status`. Available options are: `'closed'`,  `'opened'`.

    :attr:`status` is a :class:`~kivy.properties.OptionProperty`
    and defaults to `'closed'`.
    """

    max_swipe_x = NumericProperty(0.3)
    """
    If, after the events of :attr:`~on_touch_up` card position exceeds this
    value - will automatically execute the method :attr:`~open_card`,
    and if not - will automatically be :attr:`~close_card` method.

    :attr:`max_swipe_x` is a :class:`~kivy.properties.NumericProperty`
    and defaults to `0.3`.
    """

    max_opened_x = NumericProperty("100dp")
    """
    The value of the position the card shifts to when :attr:`~type_swipe`
    s set to `'hand'`.

    :attr:`max_opened_x` is a :class:`~kivy.properties.NumericProperty`
    and defaults to `100dp`.
    """

    type_swipe = OptionProperty("hand", options=("auto", "hand"))
    """
    Type of card opening when swipe. Shift the card to the edge or to
    a set position :attr:`~max_opened_x`. Available options are:
    `'auto'`, `'hand'`.

    :attr:`type_swipe` is a :class:`~kivy.properties.OptionProperty`
    and defaults to `auto`.
    """

    _opens_process = False
    _to_closed = True

    def __init__(self, **kw):
        self.register_event_type("on_swipe_complete")
        super().__init__(**kw)

    def _on_swipe_complete(self, *args):
        self.dispatch("on_swipe_complete")

    def add_widget(self, widget, index=0, canvas=None):
        if isinstance(widget, (MDCardSwipeFrontBox, MDCardSwipeLayerBox)):
            return super().add_widget(widget)

    def on_swipe_complete(self, *args):
        """Called when a swipe of card is completed."""

    def on_anchor(self, instance, value):
        if value == "right":
            self.open_progress = 1.0
        else:
            self.open_progress = 0.0

    def on_open_progress(self, instance, value):
        if self.anchor == "left":
            self.children[0].x = self.width * value
        else:
            self.children[0].x = self.width * value - self.width

    def on_touch_move(self, touch):
        if self.collide_point(touch.x, touch.y):
            expr = (
                touch.x < self.swipe_distance
                if self.anchor == "left"
                else touch.x > self.width - self.swipe_distance
            )
            if expr and not self._opens_process:
                self._opens_process = True
                self._to_closed = False
            if self._opens_process:
                self.open_progress = max(
                    min(self.open_progress + touch.dx / self.width, 2.5), 0
                )
        return super().on_touch_move(touch)

    def on_touch_up(self, touch):
        if self.collide_point(touch.x, touch.y):
            if not self._to_closed:
                self._opens_process = False
                self.complete_swipe()
        return super().on_touch_up(touch)

    def on_touch_down(self, touch):
        if self.collide_point(touch.x, touch.y):
            if self.state == "opened":
                self._to_closed = True
                self.close_card()
        return super().on_touch_down(touch)

    def complete_swipe(self):
        expr = (
            self.open_progress <= self.max_swipe_x
            if self.anchor == "left"
            else self.open_progress >= self.max_swipe_x
        )
        if expr:
            self.close_card()
        else:
            self.open_card()

    def open_card(self):
        if self.type_swipe == "hand":
            swipe_x = (
                self.max_opened_x
                if self.anchor == "left"
                else -self.max_opened_x
            )
        else:
            swipe_x = self.width if self.anchor == "left" else 0
        anim = Animation(
            x=swipe_x, t=self.opening_transition, d=self.opening_time
        )
        anim.bind(on_complete=self._on_swipe_complete)
        anim.start(self.children[0])
        self.state = "opened"

    def close_card(self):
        anim = Animation(x=0, t=self.closing_transition, d=self.opening_time)
        anim.bind(on_complete=self._reset_open_progress)
        anim.start(self.children[0])
        self.state = "closed"

    def _reset_open_progress(self, *args):
        self.open_progress = 0.0 if self.anchor == "left" else 1.0
        self._to_closed = False
        self.dispatch("on_swipe_complete")
Beispiel #7
0
class Carousel(StencilView):
    '''Carousel class. See module documentation for more information.
    '''

    slides = ListProperty([])
    '''List of slides inside the Carousel. The slides are the
    widgets added to the Carousel using the :attr:`add_widget` method.

    :attr:`slides` is a :class:`~kivy.properties.ListProperty` and is
    read-only.
    '''
    def _get_slides_container(self):
        return [x.parent for x in self.slides]

    slides_container = AliasProperty(_get_slides_container,
                                     None,
                                     bind=('slides', ))

    direction = OptionProperty('right',
                               options=('right', 'left', 'top', 'bottom'))
    '''Specifies the direction in which the slides are ordered. This
    corresponds to the direction from which the user swipes to go from one
    slide to the next. It
    can be `right`, `left`, `top`, or `bottom`. For example, with
    the default value of `right`, the second slide is to the right
    of the first and the user would swipe from the right towards the
    left to get to the second slide.

    :attr:`direction` is an :class:`~kivy.properties.OptionProperty` and
    defaults to 'right'.
    '''

    min_move = NumericProperty(0.2)
    '''Defines the minimum distance to be covered before the touch is
    considered a swipe gesture and the Carousel content changed.
    This is a expressed as a fraction of the Carousel's width.
    If the movement doesn't reach this minimum value, the movement is
    cancelled and the content is restored to its original position.

    :attr:`min_move` is a :class:`~kivy.properties.NumericProperty` and
    defaults to 0.2.
    '''

    anim_move_duration = NumericProperty(0.5)
    '''Defines the duration of the Carousel animation between pages.

    :attr:`anim_move_duration` is a :class:`~kivy.properties.NumericProperty`
    and defaults to 0.5.
    '''

    anim_cancel_duration = NumericProperty(0.3)
    '''Defines the duration of the animation when a swipe movement is not
    accepted. This is generally when the user does not make a large enough
    swipe. See :attr:`min_move`.

    :attr:`anim_cancel_duration` is a :class:`~kivy.properties.NumericProperty`
    and defaults to 0.3.
    '''

    loop = BooleanProperty(False)
    '''Allow the Carousel to loop infinitely. If True, when the user tries to
    swipe beyond last page, it will return to the first. If False, it will
    remain on the last page.

    :attr:`loop` is a :class:`~kivy.properties.BooleanProperty` and
    defaults to False.
    '''

    def _get_index(self):
        if self.slides:
            return self._index % len(self.slides)
        return None

    def _set_index(self, value):
        if self.slides:
            self._index = value % len(self.slides)
        else:
            self._index = None

    index = AliasProperty(_get_index, _set_index, bind=('_index', 'slides'))
    '''Get/Set the current slide based on the index.

    :attr:`index` is an :class:`~kivy.properties.AliasProperty` and defaults
    to 0 (the first item).
    '''

    def _prev_slide(self):
        slides = self.slides
        len_slides = len(slides)
        index = self.index
        if len_slides < 2:  # None, or 1 slide
            return None
        if len_slides == 2:
            if index == 0:
                return None
            if index == 1:
                return slides[0]
        if self.loop and index == 0:
            return slides[-1]
        if index > 0:
            return slides[index - 1]

    previous_slide = AliasProperty(_prev_slide, None, bind=('slides', 'index'))
    '''The previous slide in the Carousel. It is None if the current slide is
    the first slide in the Carousel. This ordering reflects the order in which
    the slides are added: their presentation varies according to the
    :attr:`direction` property.

    :attr:`previous_slide` is an :class:`~kivy.properties.AliasProperty`.

    .. versionchanged:: 1.5.0
        This property no longer exposes the slides container. It returns
        the widget you have added.
    '''

    def _curr_slide(self):
        if len(self.slides):
            return self.slides[self.index]

    current_slide = AliasProperty(_curr_slide, None, bind=('slides', 'index'))
    '''The currently shown slide.

    :attr:`current_slide` is an :class:`~kivy.properties.AliasProperty`.

    .. versionchanged:: 1.5.0
        The property no longer exposes the slides container. It returns
        the widget you have added.
    '''

    def _next_slide(self):
        if len(self.slides) < 2:  # None, or 1 slide
            return None
        if len(self.slides) == 2:
            if self.index == 0:
                return self.slides[1]
            if self.index == 1:
                return None
        if self.loop and self.index == len(self.slides) - 1:
            return self.slides[0]
        if self.index < len(self.slides) - 1:
            return self.slides[self.index + 1]

    next_slide = AliasProperty(_next_slide, None, bind=('slides', 'index'))
    '''The next slide in the Carousel. It is None if the current slide is
    the last slide in the Carousel. This ordering reflects the order in which
    the slides are added: their presentation varies according to the
    :attr:`direction` property.

    :attr:`next_slide` is an :class:`~kivy.properties.AliasProperty`.

    .. versionchanged:: 1.5.0
        The property no longer exposes the slides container.
        It returns the widget you have added.
    '''

    scroll_timeout = NumericProperty(200)
    '''Timeout allowed to trigger the :attr:`scroll_distance`, in milliseconds.
    If the user has not moved :attr:`scroll_distance` within the timeout,
    no scrolling will occur and the touch event will go to the children.

    :attr:`scroll_timeout` is a :class:`~kivy.properties.NumericProperty` and
    defaults to 200 (milliseconds)

    .. versionadded:: 1.5.0
    '''

    scroll_distance = NumericProperty('20dp')
    '''Distance to move before scrolling the :class:`Carousel` in pixels. As
    soon as the distance has been traveled, the :class:`Carousel` will start
    to scroll, and no touch event will go to children.
    It is advisable that you base this value on the dpi of your target device's
    screen.

    :attr:`scroll_distance` is a :class:`~kivy.properties.NumericProperty` and
    defaults to 20dp.

    .. versionadded:: 1.5.0
    '''

    anim_type = StringProperty('out_quad')
    '''Type of animation to use while animating to the next/previous slide.
    This should be the name of an
    :class:`~kivy.animation.AnimationTransition` function.

    :attr:`anim_type` is a :class:`~kivy.properties.StringProperty` and
    defaults to 'out_quad'.

    .. versionadded:: 1.8.0
    '''

    ignore_perpendicular_swipes = BooleanProperty(False)
    '''Ignore swipes on axis perpendicular to direction.

    :attr:`ignore_perpendicular_swipes` is a
    :class:`~kivy.properties.BooleanProperty` and defaults to False.

    .. versionadded:: 1.10.0
    '''

    # private properties, for internal use only ###
    _index = NumericProperty(0, allownone=True)
    _prev = ObjectProperty(None, allownone=True)
    _current = ObjectProperty(None, allownone=True)
    _next = ObjectProperty(None, allownone=True)
    _offset = NumericProperty(0)
    _touch = ObjectProperty(None, allownone=True)

    _change_touch_mode_ev = None

    def __init__(self, **kwargs):
        self._trigger_position_visible_slides = Clock.create_trigger(
            self._position_visible_slides, -1)
        super(Carousel, self).__init__(**kwargs)
        self._skip_slide = None
        self.touch_mode_change = False

    def load_slide(self, slide):
        '''Animate to the slide that is passed as the argument.

        .. versionchanged:: 1.8.0
        '''
        slides = self.slides
        start, stop = slides.index(self.current_slide), slides.index(slide)
        if start == stop:
            return

        self._skip_slide = stop
        if stop > start:
            self._insert_visible_slides(_next_slide=slide)
            self.load_next()
        else:
            self._insert_visible_slides(_prev_slide=slide)
            self.load_previous()

    def load_previous(self):
        '''Animate to the previous slide.

        .. versionadded:: 1.7.0
        '''
        self.load_next(mode='prev')

    def load_next(self, mode='next'):
        '''Animate to the next slide.

        .. versionadded:: 1.7.0
        '''
        if self.index is not None:
            w, h = self.size
            _direction = {
                'top': -h / 2,
                'bottom': h / 2,
                'left': w / 2,
                'right': -w / 2
            }
            _offset = _direction[self.direction]
            if mode == 'prev':
                _offset = -_offset

            self._start_animation(min_move=0, offset=_offset)

    def get_slide_container(self, slide):
        return slide.parent

    def _insert_visible_slides(self, _next_slide=None, _prev_slide=None):
        get_slide_container = self.get_slide_container

        previous_slide = _prev_slide if _prev_slide else self.previous_slide
        if previous_slide:
            self._prev = get_slide_container(previous_slide)
        else:
            self._prev = None

        current_slide = self.current_slide
        if current_slide:
            self._current = get_slide_container(current_slide)
        else:
            self._current = None

        next_slide = _next_slide if _next_slide else self.next_slide
        if next_slide:
            self._next = get_slide_container(next_slide)
        else:
            self._next = None

        super_remove = super(Carousel, self).remove_widget
        for container in self.slides_container:
            super_remove(container)

        if self._prev and self._prev.parent is not self:
            super(Carousel, self).add_widget(self._prev)
        if self._next and self._next.parent is not self:
            super(Carousel, self).add_widget(self._next)
        if self._current:
            super(Carousel, self).add_widget(self._current)

    def _position_visible_slides(self, *args):
        slides, index = self.slides, self.index
        no_of_slides = len(slides) - 1
        if not slides:
            return
        x, y, width, height = self.x, self.y, self.width, self.height
        _offset, direction = self._offset, self.direction
        _prev, _next, _current = self._prev, self._next, self._current
        get_slide_container = self.get_slide_container
        last_slide = get_slide_container(slides[-1])
        first_slide = get_slide_container(slides[0])
        skip_next = False
        _loop = self.loop

        if direction[0] in ['r', 'l']:
            xoff = x + _offset
            x_prev = {'l': xoff + width, 'r': xoff - width}
            x_next = {'l': xoff - width, 'r': xoff + width}
            if _prev:
                _prev.pos = (x_prev[direction[0]], y)
            elif _loop and _next and index == 0:
                # if first slide is moving to right with direction set to right
                # or toward left with direction set to left
                if ((_offset > 0 and direction[0] == 'r')
                        or (_offset < 0 and direction[0] == 'l')):
                    # put last_slide before first slide
                    last_slide.pos = (x_prev[direction[0]], y)
                    skip_next = True
            if _current:
                _current.pos = (xoff, y)
            if skip_next:
                return
            if _next:
                _next.pos = (x_next[direction[0]], y)
            elif _loop and _prev and index == no_of_slides:
                if ((_offset < 0 and direction[0] == 'r')
                        or (_offset > 0 and direction[0] == 'l')):
                    first_slide.pos = (x_next[direction[0]], y)
        if direction[0] in ['t', 'b']:
            yoff = y + _offset
            y_prev = {'t': yoff - height, 'b': yoff + height}
            y_next = {'t': yoff + height, 'b': yoff - height}
            if _prev:
                _prev.pos = (x, y_prev[direction[0]])
            elif _loop and _next and index == 0:
                if ((_offset > 0 and direction[0] == 't')
                        or (_offset < 0 and direction[0] == 'b')):
                    last_slide.pos = (x, y_prev[direction[0]])
                    skip_next = True
            if _current:
                _current.pos = (x, yoff)
            if skip_next:
                return
            if _next:
                _next.pos = (x, y_next[direction[0]])
            elif _loop and _prev and index == no_of_slides:
                if ((_offset < 0 and direction[0] == 't')
                        or (_offset > 0 and direction[0] == 'b')):
                    first_slide.pos = (x, y_next[direction[0]])

    def on_size(self, *args):
        size = self.size
        for slide in self.slides_container:
            slide.size = size
        self._trigger_position_visible_slides()

    def on_pos(self, *args):
        self._trigger_position_visible_slides()

    def on_index(self, *args):
        self._insert_visible_slides()
        self._trigger_position_visible_slides()
        self._offset = 0

    def on_slides(self, *args):
        if self.slides:
            self.index = self.index % len(self.slides)
        self._insert_visible_slides()
        self._trigger_position_visible_slides()

    def on__offset(self, *args):
        self._trigger_position_visible_slides()
        # if reached full offset, switch index to next or prev
        direction = self.direction
        _offset = self._offset
        width = self.width
        height = self.height
        index = self.index
        if self._skip_slide is not None or index is None:
            return

        if direction[0] == 'r':
            if _offset <= -width:
                index += 1
            if _offset >= width:
                index -= 1
        if direction[0] == 'l':
            if _offset <= -width:
                index -= 1
            if _offset >= width:
                index += 1
        if direction[0] == 't':
            if _offset <= -height:
                index += 1
            if _offset >= height:
                index -= 1
        if direction[0] == 'b':
            if _offset <= -height:
                index -= 1
            if _offset >= height:
                index += 1
        self.index = index

    def _start_animation(self, *args, **kwargs):
        # compute target offset for ease back, next or prev
        new_offset = 0
        direction = kwargs.get('direction', self.direction)
        is_horizontal = direction[0] in ['r', 'l']
        extent = self.width if is_horizontal else self.height
        min_move = kwargs.get('min_move', self.min_move)
        _offset = kwargs.get('offset', self._offset)

        if _offset < min_move * -extent:
            new_offset = -extent
        elif _offset > min_move * extent:
            new_offset = extent

        # if new_offset is 0, it wasnt enough to go next/prev
        dur = self.anim_move_duration
        if new_offset == 0:
            dur = self.anim_cancel_duration

        # detect edge cases if not looping
        len_slides = len(self.slides)
        index = self.index
        if not self.loop or len_slides == 1:
            is_first = (index == 0)
            is_last = (index == len_slides - 1)
            if direction[0] in ['r', 't']:
                towards_prev = (new_offset > 0)
                towards_next = (new_offset < 0)
            else:
                towards_prev = (new_offset < 0)
                towards_next = (new_offset > 0)
            if (is_first and towards_prev) or (is_last and towards_next):
                new_offset = 0

        anim = Animation(_offset=new_offset, d=dur, t=self.anim_type)
        anim.cancel_all(self)

        def _cmp(*l):
            if self._skip_slide is not None:
                self.index = self._skip_slide
                self._skip_slide = None

        anim.bind(on_complete=_cmp)
        anim.start(self)

    def _get_uid(self, prefix='sv'):
        return '{0}.{1}'.format(prefix, self.uid)

    def on_touch_down(self, touch):
        if not self.collide_point(*touch.pos):
            touch.ud[self._get_uid('cavoid')] = True
            return
        if self.disabled:
            return True
        if self._touch:
            return super(Carousel, self).on_touch_down(touch)
        Animation.cancel_all(self)
        self._touch = touch
        uid = self._get_uid()
        touch.grab(self)
        touch.ud[uid] = {'mode': 'unknown', 'time': touch.time_start}
        self._change_touch_mode_ev = Clock.schedule_once(
            self._change_touch_mode, self.scroll_timeout / 1000.)
        self.touch_mode_change = False
        return True

    def on_touch_move(self, touch):
        if not self.touch_mode_change:
            if self.ignore_perpendicular_swipes and \
                    self.direction in ('top', 'bottom'):
                if abs(touch.oy - touch.y) < self.scroll_distance:
                    if abs(touch.ox - touch.x) > self.scroll_distance:
                        self._change_touch_mode()
                        self.touchModeChange = True
            elif self.ignore_perpendicular_swipes and \
                    self.direction in ('right', 'left'):
                if abs(touch.ox - touch.x) < self.scroll_distance:
                    if abs(touch.oy - touch.y) > self.scroll_distance:
                        self._change_touch_mode()
                        self.touchModeChange = True

        if self._get_uid('cavoid') in touch.ud:
            return
        if self._touch is not touch:
            super(Carousel, self).on_touch_move(touch)
            return self._get_uid() in touch.ud
        if touch.grab_current is not self:
            return True
        ud = touch.ud[self._get_uid()]
        direction = self.direction
        if ud['mode'] == 'unknown':
            if direction[0] in ('r', 'l'):
                distance = abs(touch.ox - touch.x)
            else:
                distance = abs(touch.oy - touch.y)
            if distance > self.scroll_distance:
                ev = self._change_touch_mode_ev
                if ev is not None:
                    ev.cancel()
                ud['mode'] = 'scroll'
        else:
            if direction[0] in ('r', 'l'):
                self._offset += touch.dx
            if direction[0] in ('t', 'b'):
                self._offset += touch.dy
        return True

    def on_touch_up(self, touch):
        if self._get_uid('cavoid') in touch.ud:
            return
        if self in [x() for x in touch.grab_list]:
            touch.ungrab(self)
            self._touch = None
            ud = touch.ud[self._get_uid()]
            if ud['mode'] == 'unknown':
                ev = self._change_touch_mode_ev
                if ev is not None:
                    ev.cancel()
                super(Carousel, self).on_touch_down(touch)
                Clock.schedule_once(partial(self._do_touch_up, touch), .1)
            else:
                self._start_animation()

        else:
            if self._touch is not touch and self.uid not in touch.ud:
                super(Carousel, self).on_touch_up(touch)
        return self._get_uid() in touch.ud

    def _do_touch_up(self, touch, *largs):
        super(Carousel, self).on_touch_up(touch)
        # don't forget about grab event!
        for x in touch.grab_list[:]:
            touch.grab_list.remove(x)
            x = x()
            if not x:
                continue
            touch.grab_current = x
            super(Carousel, self).on_touch_up(touch)
        touch.grab_current = None

    def _change_touch_mode(self, *largs):
        if not self._touch:
            return
        self._start_animation()
        uid = self._get_uid()
        touch = self._touch
        ud = touch.ud[uid]
        if ud['mode'] == 'unknown':
            touch.ungrab(self)
            self._touch = None
            super(Carousel, self).on_touch_down(touch)
            return

    def add_widget(self, widget, index=0, canvas=None):
        slide = RelativeLayout(size=self.size, x=self.x - self.width, y=self.y)
        slide.add_widget(widget)
        super(Carousel, self).add_widget(slide, index, canvas)
        if index != 0:
            self.slides.insert(index - len(self.slides), widget)
        else:
            self.slides.append(widget)

    def remove_widget(self, widget, *args, **kwargs):
        # XXX be careful, the widget.parent refer to the RelativeLayout
        # added in add_widget(). But it will break if RelativeLayout
        # implementation change.
        # if we passed the real widget
        if widget in self.slides:
            slide = widget.parent
            self.slides.remove(widget)
            return slide.remove_widget(widget, *args, **kwargs)
        return super(Carousel, self).remove_widget(widget, *args, **kwargs)

    def clear_widgets(self):
        for slide in self.slides[:]:
            self.remove_widget(slide)
        super(Carousel, self).clear_widgets()
Beispiel #8
0
class LinkTree(TreeView):
    """ link to the favorites section of link bar """
    _favs = ObjectProperty(None)
    _computer_node = None

    favorites_string = StringProperty('')
    libraries_string = StringProperty('')
    computer_string = StringProperty('')

    def fill_tree(self, fav_list):
        if platform == 'win':
            user_path = expanduser(u'~')
            if not isdir(user_path + sep + 'Desktop'):
                user_path = dirname(user_path) + sep
            else:
                user_path += sep
        else:
            user_path = expanduser(u'~') + sep
        self._favs = self.add_node(
            TreeLabel(text=self.favorites_string,
                      is_open=True,
                      no_selection=True))
        self.reload_favs(fav_list)

        libs = self.add_node(
            TreeLabel(text=self.libraries_string,
                      is_open=True,
                      no_selection=True))
        places = ('Documents', 'Music', 'Pictures', 'Videos')
        for place in places:
            if isdir(user_path + place):
                self.add_node(TreeLabel(text=place, path=user_path + place),
                              libs)
        self._computer_node = self.add_node(
            TreeLabel(text=self.computer_string,
                      is_open=True,
                      no_selection=True))
        self._computer_node.bind(on_touch_down=self._drives_touch)
        self.reload_drives()

    def _drives_touch(self, obj, touch):
        if obj.collide_point(*touch.pos):
            self.reload_drives()

    def reload_drives(self):
        nodes = [(node, node.text + node.path) for node in\
                 self._computer_node.nodes if isinstance(node, TreeLabel)]
        sigs = [s[1] for s in nodes]
        nodes_new = []
        sig_new = []
        for path, name in get_drives():
            if platform == 'win':
                text = u'{}({})'.format((name + ' ') if name else '', path)
            else:
                text = name
            nodes_new.append((text, path))
            sig_new.append(text + path + sep)
        for node, sig in nodes:
            if sig not in sig_new:
                self.remove_node(node)
        for text, path in nodes_new:
            if text + path + sep not in sigs:
                self.add_node(TreeLabel(text=text, path=path + sep),
                              self._computer_node)

    def reload_favs(self, fav_list):
        if platform == 'win':
            user_path = expanduser(u'~')
            if not isdir(user_path + sep + 'Desktop'):
                user_path = dirname(user_path) + sep
            else:
                user_path += sep
        else:
            user_path = expanduser('~') + sep
        favs = self._favs
        remove = []
        for node in self.iterate_all_nodes(favs):
            if node != favs:
                remove.append(node)
        for node in remove:
            self.remove_node(node)
        places = ('Desktop', 'Downloads')
        for place in places:
            if isdir(user_path + place):
                self.add_node(TreeLabel(text=place, path=user_path + place),
                              favs)
        for path, name in fav_list:
            if isdir(path):
                self.add_node(TreeLabel(text=name, path=path), favs)

    def trigger_populate(self, node):
        if not node.path or node.nodes:
            return
        parent = node.path
        next = walk(parent).next()
        if next:
            for path in next[1]:
                self.add_node(TreeLabel(text=path, path=parent + sep + path),
                              node)
Beispiel #9
0
class FileBrowser(BoxLayout):
    """FileBrowser class, see module documentation for more information.
    """

    __events__ = ('on_canceled', 'on_success', 'on_submit')

    select_state = OptionProperty('normal', options=('normal', 'down'))
    '''State of the 'select' button, must be one of 'normal' or 'down'.
    The state is 'down' only when the button is currently touched/clicked,
    otherwise 'normal'. This button functions as the typical Ok/Select/Save
    button.

    :data:`select_state` is an :class:`~kivy.properties.OptionProperty`.
    '''
    cancel_state = OptionProperty('normal', options=('normal', 'down'))
    '''State of the 'cancel' button, must be one of 'normal' or 'down'.
    The state is 'down' only when the button is currently touched/clicked,
    otherwise 'normal'. This button functions as the typical cancel button.

    :data:`cancel_state` is an :class:`~kivy.properties.OptionProperty`.
    '''

    select_string = StringProperty('Ok')
    '''Label of the 'select' button.

    :data:`select_string` is an :class:`~kivy.properties.StringProperty`,
    defaults to 'Ok'.
    '''

    cancel_string = StringProperty('Cancel')
    '''Label of the 'cancel' button.

    :data:`cancel_string` is an :class:`~kivy.properties.StringProperty`,
    defaults to 'Cancel'.
    '''

    listview_string = StringProperty('List View')
    '''Label of the 'list view' button.

    :data:`listview_string` is an :class:`~kivy.properties.StringProperty`,
    defaults to 'List View'.
    '''

    iconview_string = StringProperty('Icon View')
    '''Label of the 'icon view' button.

    :data:`iconview_string` is an :class:`~kivy.properties.StringProperty`,
    defaults to 'Icon View'.
    '''

    favorites_string = StringProperty('Favorites')
    '''Label of the 'Favorites' Section

    :data:`favorites_string` is an :class:`~kivy.properties.StringProperty`,
    defaults to 'Favorites'.
    '''

    libraries_string = StringProperty('Libraries')
    '''Label of the 'Libraries' Section

    :data:`libraries_string` is an :class:`~kivy.properties.StringProperty`,
    defaults to 'Libraries'.
    '''

    computer_string = StringProperty('Computer')
    '''Label of the 'Computer' Section

    :data:`computer_string` is an :class:`~kivy.properties.StringProperty`,
    defaults to 'Computer'.
    '''

    location_string = StringProperty('Locations')
    '''Label of the 'Locations' Section

    :data:`Locations_string` is an :class:`~kivy.properties.StringProperty`,
    defaults to 'Locations'.
    '''

    filename = StringProperty('')
    '''The current text in the filename field. Read only. When multiselect is
    True, the list of selected filenames is shortened. If shortened, filename
    will contain an ellipsis.

    :data:`filename` is an :class:`~kivy.properties.StringProperty`,
    defaults to ''.

    .. versionchanged:: 1.1
    '''

    selection = ListProperty([])
    '''Read-only :class:`~kivy.properties.ListProperty`.
    Contains the list of files that are currently selected in the current tab.
    See :kivy_fchooser:`kivy.uix.filechooser.FileChooserController.selection`.

    .. versionchanged:: 1.1
    '''

    path = StringProperty(u'/')
    '''
    :class:`~kivy.properties.StringProperty`, defaults to the current working
    directory as a unicode string. It specifies the path on the filesystem that
    browser should refer to.
    See :kivy_fchooser:`kivy.uix.filechooser.FileChooserController.path`.

    .. versionadded:: 1.1
    '''

    filters = ListProperty([])
    ''':class:`~kivy.properties.ListProperty`, defaults to []
    Specifies the filters to be applied to the files in the directory.
    See :kivy_fchooser:`kivy.uix.filechooser.FileChooserController.filters`.

    Filering keywords that the user types into the filter field as a comma
    separated list will be reflected here.

    .. versionadded:: 1.1
    '''

    filter_dirs = BooleanProperty(False)
    '''
    :class:`~kivy.properties.BooleanProperty`, defaults to False.
    Indicates whether filters should also apply to directories.
    See
    :kivy_fchooser:`kivy.uix.filechooser.FileChooserController.filter_dirs`.

    .. versionadded:: 1.1
    '''

    show_hidden = BooleanProperty(False)
    '''
    :class:`~kivy.properties.BooleanProperty`, defaults to False.
    Determines whether hidden files and folders should be shown.
    See
    :kivy_fchooser:`kivy.uix.filechooser.FileChooserController.show_hidden`.

    .. versionadded:: 1.1
    '''

    show_fileinput = BooleanProperty(True)
    '''
    :class:`~kivy.properties.BooleanProperty`, defaults to True.
    Determines whether the file name input field should be shown.

    .. versionadded:: 1.2
    '''

    show_filterinput = BooleanProperty(True)
    '''
    :class:`~kivy.properties.BooleanProperty`, defaults to True.
    Determines whether the filter input filed should be shown.

    .. versionadded:: 1.2
    '''

    multiselect = BooleanProperty(False)
    '''
    :class:`~kivy.properties.BooleanProperty`, defaults to False.
    Determines whether the user is able to select multiple files or not.
    See
    :kivy_fchooser:`kivy.uix.filechooser.FileChooserController.multiselect`.

    .. versionadded:: 1.1
    '''

    dirselect = BooleanProperty(False)
    '''
    :class:`~kivy.properties.BooleanProperty`, defaults to False.
    Determines whether directories are valid selections or not.
    See
    :kivy_fchooser:`kivy.uix.filechooser.FileChooserController.dirselect`.

    .. versionadded:: 1.1
    '''

    rootpath = StringProperty(None, allownone=True)
    '''
    Root path to use instead of the system root path. If set, it will not show
    a ".." directory to go up to the root path. For example, if you set
    rootpath to /users/foo, the user will be unable to go to /users or to any
    other directory not starting with /users/foo.
    :class:`~kivy.properties.StringProperty`, defaults to None.
    See :kivy_fchooser:`kivy.uix.filechooser.FileChooserController.rootpath`.

    .. versionadded:: 1.1
    '''

    favorites = ListProperty([])
    '''A list of the paths added to the favorites link bar. Each element
    is a tuple where the first element is a string containing the full path
    to the location, while the second element is a string with the name of
    path to be displayed.

    :data:`favorites` is an :class:`~kivy.properties.ListProperty`,
    defaults to '[]'.
    '''

    transition = ObjectProperty(None)
    '''
    :class:`~kivy.propertiesObjectProperty`, defaults to False.
    sets the transition type between icon view and list view
    If not set, the screenmananager default transition is used (slide)
    .. versionadded:: 1.2
    '''
    def on_success(self):
        pass

    def on_canceled(self):
        pass

    def on_submit(self):
        pass

    def __init__(self, **kwargs):
        super(FileBrowser, self).__init__(**kwargs)
        Clock.schedule_once(self._post_init)

    def _post_init(self, *largs):
        self.ids.icon_view.bind(selection=partial(self._attr_callback,
                                                  'selection'),
                                path=partial(self._attr_callback, 'path'),
                                filters=partial(self._attr_callback,
                                                'filters'),
                                filter_dirs=partial(self._attr_callback,
                                                    'filter_dirs'),
                                show_hidden=partial(self._attr_callback,
                                                    'show_hidden'),
                                multiselect=partial(self._attr_callback,
                                                    'multiselect'),
                                dirselect=partial(self._attr_callback,
                                                  'dirselect'),
                                rootpath=partial(self._attr_callback,
                                                 'rootpath'))
        self.ids.list_view.bind(selection=partial(self._attr_callback,
                                                  'selection'),
                                path=partial(self._attr_callback, 'path'),
                                filters=partial(self._attr_callback,
                                                'filters'),
                                filter_dirs=partial(self._attr_callback,
                                                    'filter_dirs'),
                                show_hidden=partial(self._attr_callback,
                                                    'show_hidden'),
                                multiselect=partial(self._attr_callback,
                                                    'multiselect'),
                                dirselect=partial(self._attr_callback,
                                                  'dirselect'),
                                rootpath=partial(self._attr_callback,
                                                 'rootpath'))

        if not self.show_fileinput:
            self.ids.box_text.remove_widget(self.ids.file_text)
        if not self.show_filterinput:
            self.ids.box_text.remove_widget(self.ids.filt_text)
        if (not self.show_fileinput) and (not self.show_filterinput):
            self.remove_widget(self.ids.spacer1)
            self.remove_widget(self.ids.box_text)

        self.ids.link_tree.libraries_string = self.libraries_string
        self.ids.link_tree.favorites_string = self.favorites_string
        self.ids.link_tree.computer_string = self.computer_string
        self.ids.link_tree.fill_tree(self.favorites)
        self.ids.link_tree.root_options = {
            'text': self.location_string,
            'no_selection': True
        }

        if self.transition:
            self.ids.sm.transition = self.transition

    def _shorten_filenames(self, filenames):
        if not len(filenames):
            return ''
        elif len(filenames) == 1:
            return filenames[0]
        elif len(filenames) == 2:
            return filenames[0] + ', ' + filenames[1]
        else:
            return filenames[0] + ', _..._, ' + filenames[-1]

    def _attr_callback(self, attr, obj, value):
        setattr(self, attr, getattr(obj, attr))
Beispiel #10
0
class Data(EventDispatcher):
    '''

    Data is a set of variables which are essentially global variables which hold information
    about the gcode file opened, the machine which is connected, and the user's settings. These
    variables are NOT thread-safe. The queue system should always be used for passing information
    between threads.

    '''
    '''
    Data available to all widgets
    '''

    #Gcodes contains all of the lines of gcode in the opened file
    gcode = ObjectProperty([])
    version = '1.23'
    #all of the available COM ports
    comPorts = []
    #This defines which COM port is used
    comport = StringProperty("")
    #The index of the next unread line of Gcode
    gcodeIndex = NumericProperty(0)
    #Index of changes in z
    zMoves = ObjectProperty([])
    #Holds the current value of the feed rate
    feedRate = 20
    #holds the address of the g-code file so that the gcode can be refreshed
    gcodeFile = StringProperty("")
    #the current position of the cutting head
    currentpos = [0.0, 0.0, 0.0]
    target = [0.0, 0.0, 0.0]
    units = OptionProperty("MM", options=["MM", "INCHES"])
    tolerance = NumericProperty(0.5)
    gcodeShift = ObjectProperty(
        [0.0, 0.0])  #the amount that the gcode has been shifted
    logger = Logger(
    )  #the module which records the machines behavior to review later

    # Background image stuff, persist but not saved
    backgroundFile = None
    backgroundTexture = None
    backgroundManualReg = []
    backgroundRedraw = BooleanProperty(False)
    '''
    Flags
    '''
    #sets a flag if the gcode is being uploaded currently
    uploadFlag = BooleanProperty(0)
    #this is used to determine the first time the position is received from the machine
    firstTimePosFlag = 0
    #report if the serial connection is open
    connectionStatus = BooleanProperty(0)
    #is the calibration process currently underway 0 -> false
    calibrationInProcess = False
    '''
    Pointers to Objects
    '''
    config = None  #pointer to the program configuration object...used for writing to settings
    serialPort = None  #this is a pointer to the program serial port object
    '''

    Colors

    '''
    fontColor = StringProperty('[color=7a7a7a]')
    drawingColor = ObjectProperty([.47, .47, .47])
    iconPath = StringProperty('./Images/Icons/normal/')
    posIndicatorColor = ObjectProperty([0, 0, 0])
    targetIndicatorColor = ObjectProperty([1, 0, 0])
    '''
    Misc UI bits that need to be saved between invocations (but not saved)
    '''
    zPush = None
    zPushUnits = 'MM'
    zReadoutPos = 0.00
    zPopupUnits = None
    zStepSizeVal = 0.1
    '''
    Queues
    '''
    message_queue = LoggingQueue(logger)
    gcode_queue = Queue.Queue()
    quick_queue = Queue.Queue()

    def __init__(self):
        '''

        Initializations.

        '''
        self.logger.data = self
Beispiel #11
0
class TreeLabel(TreeViewLabel):
    """Full path to the location this node points to.
    :class:`~kivy.properties.StringProperty`, defaults to ''
    """
    path = StringProperty('')
Beispiel #12
0
class MDTabs(ThemableBehavior, SpecificBackgroundColorBehavior, AnchorLayout):
    """
    You can use this class to create your own tabbed panel..

    :Events:
        `on_tab_switch`
            Called when switching tabs.
    """

    default_tab = NumericProperty(0)
    """
    Index of the default tab.

    :attr:`default_tab` is an :class:`~kivy.properties.NumericProperty`
    and defaults to `0`.
    """

    tab_bar_height = NumericProperty("48dp")
    """
    Height of the tab bar.

    :attr:`tab_bar_height` is an :class:`~kivy.properties.NumericProperty`
    and defaults to `'48dp'`.
    """

    tab_indicator_anim = BooleanProperty(False)
    """
    Tab indicator animation. If you want use animation set it to ``True``.

    :attr:`tab_indicator_anim` is an :class:`~kivy.properties.BooleanProperty`
    and defaults to `False`.
    """

    tab_indicator_height = NumericProperty("2dp")
    """
    Height of the tab indicator.

    :attr:`tab_indicator_height` is an :class:`~kivy.properties.NumericProperty`
    and defaults to `'2dp'`.
    """

    anim_duration = NumericProperty(0.2)
    """
    Duration of the slide animation.

    :attr:`anim_duration` is an :class:`~kivy.properties.NumericProperty`
    and defaults to `0.2`.
    """

    anim_threshold = BoundedNumericProperty(0.8,
                                            min=0.0,
                                            max=1.0,
                                            errorhandler=lambda x: 0.0
                                            if x < 0.0 else 1.0)
    """
    Animation threshold allow you to change the tab indicator animation effect.

    :attr:`anim_threshold` is an :class:`~kivy.properties.BoundedNumericProperty`
    and defaults to `0.8`.
    """

    allow_stretch = BooleanProperty(True)
    """
    If False - tabs will not stretch to full screen.

    :attr:`allow_stretch` is an :class:`~kivy.properties.BooleanProperty`
    and defaults to `True`.
    """

    background_color = ListProperty()
    """
    Background color of tabs in ``rgba`` format.

    :attr:`background_color` is an :class:`~kivy.properties.ListProperty`
    and defaults to `[]`.
    """

    text_color_normal = ListProperty((1, 1, 1, 1))
    """
    Text color of the label when it is not selected.

    :attr:`text_color_normal` is an :class:`~kivy.properties.ListProperty`
    and defaults to `(1, 1, 1, 1)`.
    """

    text_color_active = ListProperty((1, 1, 1, 1))
    """
    Text color of the label when it is selected.

    :attr:`text_color_active` is an :class:`~kivy.properties.ListProperty`
    and defaults to `(1, 1, 1, 1)`.
    """

    elevation = NumericProperty(0)
    """
    Tab value elevation.

    .. seealso::

        `Behaviors/Elevation <https://kivymd.readthedocs.io/en/latest/behaviors/elevation/index.html>`_

    :attr:`elevation` is an :class:`~kivy.properties.NumericProperty`
    and defaults to `0`.
    """

    color_indicator = ListProperty()
    """
    Color indicator in ``rgba`` format.

    :attr:`color_indicator` is an :class:`~kivy.properties.ListProperty`
    and defaults to `[]`.
    """

    callback = ObjectProperty()
    """
    User callback. The method will be called when the ``on_ref_press`` event
    occurs in the :class:`~MDTabsLabel` class.

    :attr:`callback` is an :class:`~kivy.properties.ObjectProperty`
    and defaults to `None`.
    """

    lock_swiping = BooleanProperty(False)
    """
    If True - disable switching tabs by swipe.

    :attr:`lock_swiping` is an :class:`~kivy.properties.BooleanProperty`
    and defaults to `False`.
    """

    font_name = StringProperty("Roboto")

    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        self.register_event_type("on_tab_switch")
        self.register_event_type("on_slide_progress")
        Clock.schedule_once(self._carousel_bind, 1)

    def _carousel_bind(self, i):
        self.carousel.bind(on_slide_progress=self._on_slide_progress)

    def on_slide_progress(self, *args):
        pass

    def on_tab_switch(self, *args):
        """Called when switching tabs."""

    def _on_slide_progress(self, *args):
        self.dispatch("on_slide_progress", args)

    def get_tab_list(self):
        """Returns a list of tab objects."""

        return self.tab_bar.layout.children

    def on_carousel_index(self, carousel, index):
        # when the index of the carousel change, update
        # tab indicator, select the current tab and reset threshold data.
        current_tab_label = carousel.current_slide.tab_label
        if current_tab_label.state == "normal":
            current_tab_label._do_press()
        self.tab_bar.update_indicator(current_tab_label.x,
                                      current_tab_label.width)

    def add_widget(self, widget, index=0, canvas=None):
        # You can add only subclass of MDTabsBase.
        if len(self.children) >= 2:
            try:
                widget.tab_label.group = str(self)
                widget.tab_label.callback = self.callback
                widget.tab_label.tab_bar = self.tab_bar
                widget.tab_label.text_color_normal = self.text_color_normal
                widget.tab_label.text_color_active = self.text_color_active
                self.bind(text_color_normal=widget.tab_label.setter(
                    "text_color_normal"))
                self.bind(text_color_active=widget.tab_label.setter(
                    "text_color_active"))
                self.bind(font_name=widget.tab_label.setter("font_name"))
                self.tab_bar.layout.add_widget(widget.tab_label)
                self.carousel.add_widget(widget)
                return
            except AttributeError:
                pass
        return super().add_widget(widget)

    def remove_widget(self, widget):
        # You can remove only subclass of MDTabsLabel.
        if not issubclass(widget.__class__, MDTabsLabel):
            raise MDTabsException(
                "MDTabs can remove only subclass of MDTabsLabel")
        self.tab_bar.layout.remove_widget(widget)
        for tab in self.carousel.slides:
            if tab.text == widget.text:
                self.carousel.slides.remove(tab)
                break
class MenuIconItem(BasedMenuItem, ThemableBehavior):
    icon = StringProperty("circle-outline")
    icon_color = ListProperty()
    icon_size = NumericProperty()
Beispiel #14
0
class MDFloatingLabel(MDCard):
    text = StringProperty()
Beispiel #15
0
class ScrolllabelLabel(ScrollView):
    game_log = StringProperty('')

    def __init__(self, **kwargs):
        super(ScrolllabelLabel, self).__init__(**kwargs)
class AnimatedButton(Label):

    state = OptionProperty('normal', options=('normal', 'down'))

    allow_stretch = BooleanProperty(True)

    keep_ratio = BooleanProperty(False)

    border = ObjectProperty(None)

    anim_delay = ObjectProperty(None)

    background_normal = StringProperty(
            'atlas://data/images/defaulttheme/button')

    texture_background = ObjectProperty(None)

    background_down = StringProperty(
            'atlas://data/images/defaulttheme/button_pressed')

    def __init__(self, **kwargs):
        super(AnimatedButton, self).__init__(**kwargs)

        self.register_event_type('on_press')
        self.register_event_type('on_release')
        #borderImage.border by default is ...
        self.border = (16, 16, 16, 16)
        #Image to display depending on state
        self.img = Image(source = self.background_normal,
                        allow_stretch = self.allow_stretch,
                        keep_ratio = self.keep_ratio, mipmap = True)
        #reset animation if anim_delay is changed
        def anim_reset(*l):
            self.img.anim_delay = self.anim_delay
        self.bind(anim_delay = anim_reset)
        self.anim_delay = .1
        #update self.texture when image.texture changes
        self.img.bind(texture = self.on_tex_changed)
        self.on_tex_changed()
        #update image source when background image is changed
        def background_changed(*l):
            self.img.source = self.background_normal
            self.anim_delay = .1
        self.bind(background_normal = background_changed)

    def on_tex_changed(self, *largs):
        self.texture_background = self.img.texture

    def _do_press(self):
        self.state = 'down'

    def _do_release(self):
        self.state = 'normal'

    def on_touch_down(self, touch):
        if not self.collide_point(touch.x, touch.y):
            return False
        if repr(self) in touch.ud:
            return False
        touch.grab(self)
        touch.ud[repr(self)] = True
        _animdelay = self.img.anim_delay
        self.img.source = self.background_down
        self.img.anim_delay = _animdelay
        self._do_press()
        self.dispatch('on_press')
        return True

    def on_touch_move(self, touch):
        return repr(self) in touch.ud

    def on_touch_up(self, touch):
        if touch.grab_current is not self:
            return
        assert(repr(self) in touch.ud)
        touch.ungrab(self)
        _animdelay = self.img._coreimage.anim_delay
        self.img.source = self.background_normal
        self.anim_delay = _animdelay
        self._do_release()
        self.dispatch('on_release')
        return True

    def on_press(self):
        pass

    def on_release(self):
        pass
Beispiel #17
0
class MDCard(
    ThemableBehavior,
    BackgroundColorBehavior,
    RectangularElevationBehavior,
    FocusBehavior,
    BoxLayout,
    RectangularRippleBehavior,
):
    background = StringProperty()
    """
    Background image path.

    :attr:`background` is a :class:`~kivy.properties.StringProperty`
    and defaults to `''`.
    """

    focus_behavior = BooleanProperty(False)
    """
    Using focus when hovering over a card.

    :attr:`focus_behavior` is a :class:`~kivy.properties.BooleanProperty`
    and defaults to `False`.
    """

    ripple_behavior = BooleanProperty(False)
    """
    Use ripple effect for card.

    :attr:`ripple_behavior` is a :class:`~kivy.properties.BooleanProperty`
    and defaults to `False`.
    """

    elevation = NumericProperty(None, allownone=True)
    """
    Elevation value.

    :attr:`elevation` is an :class:`~kivy.properties.NumericProperty`
    and defaults to 1.
    """

    _bg_color_map = (
        get_color_from_hex(colors["Light"]["CardsDialogs"]),
        get_color_from_hex(colors["Dark"]["CardsDialogs"]),
        [1.0, 1.0, 1.0, 0.0],
    )

    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        self.theme_cls.bind(theme_style=self.update_md_bg_color)
        Clock.schedule_once(lambda x: self._on_elevation(self.elevation))
        Clock.schedule_once(
            lambda x: self._on_ripple_behavior(self.ripple_behavior)
        )
        self.update_md_bg_color(self, self.theme_cls.theme_style)

    def update_md_bg_color(self, instance, value):
        if self.md_bg_color in self._bg_color_map:
            self.md_bg_color = get_color_from_hex(colors[value]["CardsDialogs"])

    def on_radius(self, instance, value):
        if self.radius != [0, 0, 0, 0]:
            self.background = f"{images_path}/transparent.png"

    def _on_elevation(self, value):
        if value is None:
            self.elevation = 6
        else:
            self.elevation = value

    def _on_ripple_behavior(self, value):
        self._no_ripple_effect = False if value else True
Beispiel #18
0
class InfoBubble(Factory.Bubble):
    '''Bubble to be used to display short Help Information'''

    message = StringProperty(_('Nothing set !'))
    '''Message to be displayed; defaults to "nothing set"'''

    icon = StringProperty('')
    ''' Icon to be displayed along with the message defaults to ''

    :attr:`icon` is a  `StringProperty` defaults to `''`
    '''

    fs = BooleanProperty(False)
    ''' Show Bubble in half screen mode

    :attr:`fs` is a `BooleanProperty` defaults to `False`
    '''

    modal = BooleanProperty(False)
    ''' Allow bubble to be hidden on touch.

    :attr:`modal` is a `BooleanProperty` defauult to `False`.
    '''

    exit = BooleanProperty(False)
    '''Indicates whether to exit app after bubble is closed.

    :attr:`exit` is a `BooleanProperty` defaults to False.
    '''

    dim_background = BooleanProperty(False)
    ''' Indicates Whether to draw a background on the windows behind the bubble.

    :attr:`dim` is a `BooleanProperty` defaults to `False`.
    '''
    def on_touch_down(self, touch):
        if self.modal:
            return True
        self.hide()
        if self.collide_point(*touch.pos):
            return True

    def show(self, pos, duration, width=None, modal=False, exit=False):
        '''Animate the bubble into position'''
        self.modal, self.exit = modal, exit
        if width:
            self.width = width
        if self.modal:
            from kivy.uix.modalview import ModalView
            self._modal_view = m = ModalView(background_color=[.5, .5, .5, .2])
            Window.add_widget(m)
            m.add_widget(self)
        else:
            Window.add_widget(self)

        # wait for the bubble to adjust it's size according to text then animate
        Clock.schedule_once(lambda dt: self._show(pos, duration))

    def _show(self, pos, duration):
        def on_stop(*l):
            if duration:
                Clock.schedule_once(self.hide, duration + .5)

        self.opacity = 0
        arrow_pos = self.arrow_pos
        if arrow_pos[0] in ('l', 'r'):
            pos = pos[0], pos[1] - (self.height / 2)
        else:
            pos = pos[0] - (self.width / 2), pos[1]

        self.limit_to = Window

        anim = Factory.Animation(opacity=1, pos=pos, d=.32)
        anim.bind(on_complete=on_stop)
        anim.cancel_all(self)
        anim.start(self)

    def hide(self, now=False):
        ''' Auto fade out the Bubble
        '''
        def on_stop(*l):
            if self.modal:
                m = self._modal_view
                m.remove_widget(self)
                Window.remove_widget(m)
            Window.remove_widget(self)
            if self.exit:
                App.get_running_app().stop()
                import sys
                sys.exit()
            else:
                App.get_running_app().is_exit = False

        if now:
            return on_stop()

        anim = Factory.Animation(opacity=0, d=.25)
        anim.bind(on_complete=on_stop)
        anim.cancel_all(self)
        anim.start(self)
Beispiel #19
0
class SnakeGame(Widget):

    head = ObjectProperty(None)
    fruit = ObjectProperty(None)
    score = NumericProperty(0)
    player_size = NumericProperty(PLAYER_SIZE)
    game_over = StringProperty("")

    def __init__(self):
        super(SnakeGame, self).__init__()

        Window.size = (WINDOW_WIDTH, WINDOW_HEIGHT)
        Window.bind(on_key_down=self.key_action)

        if PLAYER_SIZE < 3:
            raise ValueError("Player size should be at least 3 px")

        if WINDOW_HEIGHT < 3 * PLAYER_SIZE or WINDOW_WIDTH < 3 * PLAYER_SIZE:
            raise ValueError(
                "Window size must be at least 3 times larger than player size")

        self.timer = Clock.schedule_interval(self.refresh, GAME_SPEED)
        self.tail = []
        self.restart_game()

    def restart_game(self):
        """Resets the game to its initial state
        """
        self.occupied = smartGrid()

        # resets the timer
        self.timer.cancel()
        self.timer = Clock.schedule_interval(self.refresh, GAME_SPEED)

        self.head.reset_pos()
        self.score = 0

        for block in self.tail:
            self.remove_widget(block)

        # the tail is indexed in a way that the last block is idx 0
        self.tail = []

        # first two blocks added to the tail
        self.tail.append(
            SnakeTail(pos=(self.head.pos[0] - PLAYER_SIZE, self.head.pos[1]),
                      size=(self.head.size)))
        self.add_widget(self.tail[-1])
        self.occupied[self.tail[-1].pos] = True

        self.tail.append(
            SnakeTail(pos=(self.head.pos[0] - 2 * PLAYER_SIZE,
                           self.head.pos[1]),
                      size=(self.head.size)))
        self.add_widget(self.tail[-1])
        self.occupied[self.tail[1].pos] = True

        self.spawn_fruit()

    def refresh(self, dt):
        """This block of code is executed every GAME_SPEED seconds

        'dt' must be used to allow kivy.Clock objects to use this function
        """

        # outside the boundaries of the game
        if not (0 <= self.head.pos[0] < WINDOW_WIDTH) or \
           not (0 <= self.head.pos[1] < WINDOW_HEIGHT):
            self.restart_game()
            return

        # collides with its tail
        if self.occupied[self.head.pos] is True:
            self.restart_game()
            return

        # move the tail
        self.occupied[self.tail[-1].pos] = False
        self.tail[-1].move(self.tail[-2].pos)

        for i in range(2, len(self.tail)):
            self.tail[-i].move(new_pos=(self.tail[-(i + 1)].pos))

        self.tail[0].move(new_pos=self.head.pos)
        self.occupied[self.tail[0].pos] = True

        # move the head
        self.head.move()

        # check if we found the fruit, if so, add another tail
        if self.head.pos == self.fruit.pos:
            self.score += 1
            self.tail.append(SnakeTail(pos=self.head.pos, size=self.head.size))
            self.add_widget(self.tail[-1])
            self.spawn_fruit()

    def spawn_fruit(self):

        roll = self.fruit.pos
        found = False
        while not found:

            # roll new random positions until one is free
            roll = [
                PLAYER_SIZE * randint(0,
                                      int(WINDOW_WIDTH / PLAYER_SIZE) - 1),
                PLAYER_SIZE * randint(0,
                                      int(WINDOW_HEIGHT / PLAYER_SIZE) - 1)
            ]

            if self.occupied[roll] is True or \
                    roll == self.head.pos:
                continue

            found = True

        self.fruit.move(roll)

    def key_action(self, *args):
        """This handles user input
        """

        command = list(args)[3]

        if command == 'w' or command == 'up':
            self.head.orientation = (0, PLAYER_SIZE)
        elif command == 's' or command == 'down':
            self.head.orientation = (0, -PLAYER_SIZE)
        elif command == 'a' or command == 'left':
            self.head.orientation = (-PLAYER_SIZE, 0)
        elif command == 'd' or command == 'right':
            self.head.orientation = (PLAYER_SIZE, 0)
        elif command == 'r':
            self.restart_game()
Beispiel #20
0
class ImageChooserCell(Widget):
    image_location = StringProperty("None")
    image_chooser = ObjectProperty(None)

    def cell_press(self):
        self.image_chooser.select(self.image_location)
Beispiel #21
0
class ScrollableLabel(ScrollView):
    text = StringProperty(
        color_text("Hello. Ask me to create a reminder.\n\n"))
Beispiel #22
0
class ParticlePanel(Widget):
    particle_builder = ObjectProperty(None)
    texture_path = StringProperty("media/particle.png")
    max_num_particles = NumericProperty(200.)
    max_num_particles_min = NumericProperty(1.)
    max_num_particles_max = NumericProperty(500.)
    life_span = NumericProperty(2.)
    life_span_min = NumericProperty(.01)
    life_span_max = NumericProperty(10.)
    life_span_variance = NumericProperty(0.)
    life_span_variance_min = NumericProperty(0.)
    life_span_variance_max = NumericProperty(10.)
    start_size = NumericProperty(8.)
    start_size_min = NumericProperty(0.)
    start_size_max = NumericProperty(256.)
    start_size_variance = NumericProperty(0.)
    start_size_variance_min = NumericProperty(0.)
    start_size_variance_max = NumericProperty(256.)
    end_size = NumericProperty(8.)
    end_size_min = NumericProperty(0.)
    end_size_max = NumericProperty(256.)
    end_size_variance = NumericProperty(0.)
    end_size_variance_min = NumericProperty(0.)
    end_size_variance_max = NumericProperty(256.)
    emit_angle = NumericProperty(0.)
    emit_angle_min = NumericProperty(0.)
    emit_angle_max = NumericProperty(360.)
    emit_angle_variance = NumericProperty(0.)
    emit_angle_variance_min = NumericProperty(0.)
    emit_angle_variance_max = NumericProperty(360.)
    start_rotation = NumericProperty(0.)
    start_rotation_min = NumericProperty(0.)
    start_rotation_max = NumericProperty(360.)
    start_rotation_variance = NumericProperty(0.)
    start_rotation_variance_min = NumericProperty(0.)
    start_rotation_variance_max = NumericProperty(360.)
    end_rotation = NumericProperty(0.)
    end_rotation_min = NumericProperty(0.)
    end_rotation_max = NumericProperty(360.)
    end_rotation_variance = NumericProperty(0.)
    end_rotation_variance_min = NumericProperty(0.)
    end_rotation_variance_max = NumericProperty(360.)

    def __init__(self, pbuilder, **kwargs):
        super(ParticlePanel, self).__init__(**kwargs)
        self.particle_builder = pbuilder.parent

    def on_max_num_particles(self, instance, value):
        self.particle_builder.demo_particle.max_num_particles = value

    def on_life_span(self, instance, value):
        self.particle_builder.demo_particle.life_span = value

    def on_life_span_variance(self, instance, value):
        self.particle_builder.demo_particle.life_span_variance = value

    def on_start_size(self, instance, value):
        self.particle_builder.demo_particle.start_size = value

    def on_start_size_variance(self, instance, value):
        self.particle_builder.demo_particle.start_size_variance = value

    def on_end_size(self, instance, value):
        self.particle_builder.demo_particle.end_size = value

    def on_end_size_variance(self, instance, value):
        self.particle_builder.demo_particle.end_size_variance = value

    def on_emit_angle(self, instance, value):
        self.particle_builder.demo_particle.emit_angle = value * 0.0174532925

    def on_emit_angle_variance(self, instance, value):
        self.particle_builder.demo_particle.emit_angle_variance = value * 0.0174532925

    def on_start_rotation(self, instance, value):
        self.particle_builder.demo_particle.start_rotation = value

    def on_start_rotation_variance(self, instance, value):
        self.particle_builder.demo_particle.start_rotation_variance = value

    def on_end_rotation(self, instance, value):
        self.particle_builder.demo_particle.end_rotation = value

    def on_end_rotation_variance(self, instance, value):
        self.particle_builder.demo_particle.end_rotation_variance = value

    def on_texture_path(self,instance,value):
        self.particle_builder.demo_particle.texture_path = value
        self.particle_builder.demo_particle.texture = Image(value).texture

    def get_values_from_particle(self):
        properties = ['max_num_particles', 'life_span', 'life_span_variance', 'start_size', 'start_size_variance', 
                    'end_size', 'end_size_variance', 'emit_angle', 'emit_angle_variance', 'start_rotation', 
                    'start_rotation_variance', 'end_rotation', 'end_rotation_variance', 'texture_path']
    
        for p in properties:
            if p in ['emit_angle', 'emit_angle_variance', ]:
                setattr(self,p,getattr(self.particle_builder.demo_particle,p) / 0.0174532925 )
            else:
                setattr(self,p,getattr(self.particle_builder.demo_particle,p))

        self.image_chooser_button.image_location = self.particle_builder.demo_particle.texture_path
class FrontPage(Screen, MakesmithInitFuncs):
    textconsole = ObjectProperty(None)
    connectmenu = ObjectProperty(
        None)  #make ConnectMenu object accessible at this scope
    gcodecanvas = ObjectProperty(None)
    screenControls = ObjectProperty(None)

    target = [0, 0, 0]

    connectionStatus = StringProperty("Not Connected")

    xReadoutPos = StringProperty("0 mm")
    yReadoutPos = StringProperty("0 mm")
    zReadoutPos = StringProperty("0 mm")

    numericalPosX = 0.0
    numericalPosY = 0.0

    stepsizeval = 0
    feedRate = 0

    shiftX = 0
    shiftY = 0

    consoleText = StringProperty(" ")

    units = StringProperty("MM")
    gcodeLineNumber = StringProperty('0')

    def __init__(self, data, **kwargs):
        super(FrontPage, self).__init__(**kwargs)
        self.data = data

    def setPosReadout(self, xPos, yPos, zPos, units):
        self.xReadoutPos = str(xPos) + " " + units
        self.yReadoutPos = str(yPos) + " " + units
        self.zReadoutPos = str(zPos) + " " + units
        self.numericalPosX = xPos
        self.numericalPosY = yPos

    def setUpData(self, data):
        self.gcodecanvas.setUpData(data)
        self.screenControls.setUpData(data)
        self.data.bind(connectionStatus=self.updateConnectionStatus)
        self.data.bind(units=self.onUnitsSwitch)
        self.data.bind(gcodeIndex=self.onIndexMove)

    def updateConnectionStatus(self, callback, connected):

        if connected:
            self.connectionStatus = "Connected"
        else:
            self.connectionStatus = "Connection Lost"

    def switchUnits(self):
        if self.data.units == "INCHES":
            self.data.units = "MM"
        else:
            self.data.units = "INCHES"

    def onUnitsSwitch(self, callback, newUnits):
        self.units = newUnits
        #the behavior of notifying the machine doesn't really belong here
        #but I'm not really sure where else it does belong
        if newUnits == "INCHES":
            self.data.gcode_queue.put('G20 ')
            self.moveDistInput.text = str(float(self.moveDistInput.text) / 25)
        else:
            self.data.gcode_queue.put('G21 ')
            self.moveDistInput.text = str(float(self.moveDistInput.text) * 25)

    def onIndexMove(self, callback, newIndex):
        self.gcodeLineNumber = str(newIndex)

    def moveGcodeIndex(self, dist):
        self.data.gcodeIndex = self.data.gcodeIndex + dist
        gCodeLine = self.data.gcode[self.data.gcodeIndex]
        print gCodeLine

        xTarget = 0
        yTarget = 0

        x = re.search("X(?=.)([+-]?([0-9]*)(\.([0-9]+))?)", gCodeLine)
        if x:
            xTarget = float(x.groups()[0])

        y = re.search("Y(?=.)([+-]?([0-9]*)(\.([0-9]+))?)", gCodeLine)
        if y:
            yTarget = float(y.groups()[0])

        self.gcodecanvas.targetIndicator.setPos(xTarget, yTarget,
                                                self.data.units)

    def pause(self):
        self.data.uploadFlag = 0
        self.data.quick_queue.put("STOP")
        with self.data.gcode_queue.mutex:
            self.data.gcode_queue.queue.clear()
        print("Run Paused")

    def jmpsize(self):
        try:
            self.stepsizeval = float(self.moveDistInput.text)
        except:
            pass
        try:
            self.feedRate = float(self.moveSpeedInput.text)
        except:
            pass

    def test(self):
        self.data.gcode_queue.put("B01")

    def upLeft(self):
        self.jmpsize()
        xtarget = -1 * self.target[0] - float(self.stepsizeval)
        ytarget = self.target[1] + float(self.stepsizeval)
        self.data.gcode_queue.put("G00 F" + str(float(self.feedRate)) + " X" +
                                  str(xtarget) + " Y" + str(ytarget) + " ")
        self.target[0] = self.target[0] + float(self.stepsizeval)
        self.target[1] = self.target[1] + float(self.stepsizeval)

    def upRight(self):
        self.jmpsize()
        xtarget = -1 * self.target[0] + float(self.stepsizeval)
        ytarget = self.target[1] + float(self.stepsizeval)
        self.data.gcode_queue.put("G00 F" + str(float(self.feedRate)) + " X" +
                                  str(xtarget) + " Y" + str(ytarget) + " ")
        self.target[0] = self.target[0] - float(self.stepsizeval)
        self.target[1] = self.target[1] + float(self.stepsizeval)

    def up(self):
        self.jmpsize()
        target = self.target[1] + float(self.stepsizeval)
        self.data.gcode_queue.put("G00 F" + str(float(self.feedRate)) + " Y" +
                                  str(target) + " ")
        self.target[1] = self.target[1] + float(self.stepsizeval)

    def left(self):
        self.jmpsize()
        target = -1 * self.target[0] - float(self.stepsizeval)
        self.data.gcode_queue.put("G00 F" + str(float(self.feedRate)) + " X" +
                                  str(target) + " ")
        self.target[0] = self.target[0] + float(self.stepsizeval)

    def right(self):
        self.jmpsize()
        target = -1 * self.target[0] + float(self.stepsizeval)
        self.data.gcode_queue.put("G00 F" + str(float(self.feedRate)) + " X" +
                                  str(target) + " ")
        self.target[0] = self.target[0] - float(self.stepsizeval)

    def downLeft(self):
        self.jmpsize()
        xtarget = -1 * self.target[0] - float(self.stepsizeval)
        ytarget = self.target[1] - float(self.stepsizeval)
        self.data.gcode_queue.put("G00 F" + str(float(self.feedRate)) + " X" +
                                  str(xtarget) + " Y" + str(ytarget) + " ")
        self.target[0] = self.target[0] + float(self.stepsizeval)
        self.target[1] = self.target[1] - float(self.stepsizeval)

    def down(self):
        self.jmpsize()
        target = self.target[1] - float(self.stepsizeval)
        self.data.gcode_queue.put("G00 F" + str(float(self.feedRate)) + " Y" +
                                  str(target) + " ")
        self.target[1] = self.target[1] - float(self.stepsizeval)

    def downRight(self):
        self.jmpsize()
        xtarget = -1 * self.target[0] + float(self.stepsizeval)
        ytarget = self.target[1] - float(self.stepsizeval)
        self.data.gcode_queue.put("G00 F" + str(float(self.feedRate)) + " X" +
                                  str(xtarget) + " Y" + str(ytarget) + " ")
        self.target[0] = self.target[0] - float(self.stepsizeval)
        self.target[1] = self.target[1] - float(self.stepsizeval)

    def zUp(self):
        self.jmpsize()
        target = self.target[2] + 0.10 * float(self.stepsizeval)
        self.data.gcode_queue.put("G00 F" + str(float(self.feedRate)) + " Z" +
                                  str(target) + " ")
        self.target[2] = self.target[2] + 0.10 * float(self.stepsizeval)

    def zDown(self):
        self.jmpsize()
        target = self.target[2] - 0.10 * float(self.stepsizeval)
        self.data.gcode_queue.put("G00 F" + str(float(self.feedRate)) + " Z" +
                                  str(target) + " ")
        self.target[2] = self.target[2] - 0.10 * float(self.stepsizeval)

    def home(self):
        if self.target[2] < 0:
            self.data.gcode_queue.put("G00 F" + str(float(self.feedRate)) +
                                      " Z0 ")
            self.data.gcode_queue.put("G00 F" + str(float(self.feedRate)) +
                                      " X0 Y0 Z0 ")
        if self.target[2] >= 0:
            self.data.gcode_queue.put("G00 F" + str(float(self.feedRate)) +
                                      " X0 Y0 ")
            self.data.gcode_queue.put("G00 F" + str(float(self.feedRate)) +
                                      " Z0 ")
        self.target[0] = 0.0
        self.target[1] = 0.0
        self.target[2] = 0.0

    def reZero(self):
        self.target = [0, 0, 0]

        self.data.gcode_queue.put("G10 X0 Y0 Z0 ")

    def moveLine(self, gcodeLine, moveXBy, moveYBy):

        originalLine = gcodeLine

        try:
            gcodeLine = gcodeLine.upper() + " "

            x = gcodeLine.find('X')
            if x != -1:
                space = gcodeLine.find(' ', x)
                number = float(gcodeLine[x + 1:space]) + moveXBy
                gcodeLine = gcodeLine[0:x +
                                      1] + str(number) + gcodeLine[space:]

            y = gcodeLine.find('Y')
            if y != -1:
                space = gcodeLine.find(' ', y)
                number = float(gcodeLine[y + 1:space]) + moveYBy
                gcodeLine = gcodeLine[0:y +
                                      1] + str(number) + gcodeLine[space:]

            return gcodeLine
        except ValueError:
            print "line could not be moved:"
            print originalLine
            return originalLine

    def moveOrigin(self):

        if self.data.units == "INCHES":
            amtToShiftX = self.numericalPosX - self.shiftX
            amtToShiftY = self.numericalPosY - self.shiftY
            self.shiftX = self.shiftX + amtToShiftX
            self.shiftY = self.shiftY + amtToShiftY
        else:
            amtToShiftX = self.numericalPosX - self.shiftX
            amtToShiftY = self.numericalPosY - self.shiftY
            self.shiftX = self.shiftX + amtToShiftX
            self.shiftY = self.shiftY + amtToShiftY

        shiftedGcode = []

        for line in self.data.gcode:
            shiftedGcode.append(self.moveLine(line, amtToShiftX, amtToShiftY))

        self.data.gcode = shiftedGcode

    def startRun(self):

        self.data.uploadFlag = 1
        self.sendLine()

    def sendLine(self):
        try:
            self.data.gcode_queue.put(self.data.gcode[self.data.gcodeIndex])
            self.data.gcodeIndex = self.data.gcodeIndex + 1
        except:
            print "gcode run complete"
            self.gcodecanvas.uploadFlag = 0
            self.data.gcodeIndex = 0

    def stopRun(self):
        self.data.uploadFlag = 0
        self.data.gcodeIndex = 0
        self.data.quick_queue.put("STOP")
        with self.data.gcode_queue.mutex:
            self.data.gcode_queue.queue.clear()
        print("Gode Stopped")

    def textInputPopup(self, target):

        self.targetWidget = target

        self.popupContent = TouchNumberInput(done=self.dismiss_popup)
        self._popup = Popup(title="Load file",
                            content=self.popupContent,
                            size_hint=(0.9, 0.9))
        self._popup.open()

    def dismiss_popup(self):
        '''
        
        Close The Pop-up
        
        '''

        self.targetWidget.text = self.popupContent.textInput.text
        self._popup.dismiss()
Beispiel #24
0
class WorkingFile(Widget):
    filename = StringProperty(None)
Beispiel #25
0
class UserAnimationCard(ThemableBehavior, FloatLayout):
    user_name = StringProperty()
    path_to_avatar = StringProperty()
    _callback_back = ObjectProperty()
    _primary_color = ListProperty()
Beispiel #26
0
class AndroidApp(App):
    #have a reference toscreen manager called mang

    navbar_label = StringProperty()
    logged_in = False

    login_text = StringProperty()

    patent_matches = NumericProperty()

    welcome = StringProperty()
    search_term = StringProperty()
    search_sentiment = StringProperty()

    my_token = StringProperty()

    response = StringProperty()

    search0 = StringProperty()
    search1 = StringProperty()
    search2 = StringProperty()
    search3 = StringProperty()
    search4 = StringProperty()

    search_titl0 = StringProperty()
    search_titl1 = StringProperty()
    search_titl2 = StringProperty()
    search_titl3 = StringProperty()
    search_titl4 = StringProperty()

    s_confidence = StringProperty()
    s1_confidence = StringProperty()
    s2_confidence = StringProperty()

    local_result = ListProperty()
    local_search_term = ListProperty()
    confidence = NumericProperty()

    litigation_count0 = StringProperty()
    litigation_count1 = StringProperty()
    litigation_count2 = StringProperty()
    litigation_count3 = StringProperty()
    litigation_count4 = StringProperty()

    own_name0 = StringProperty()
    own_name1 = StringProperty()
    own_name2 = StringProperty()
    own_name3 = StringProperty()
    own_name4 = StringProperty()

    own_num0 = StringProperty()
    own_num1 = StringProperty()
    own_num2 = StringProperty()
    own_num3 = StringProperty()
    own_num4 = StringProperty()

    def analyquery(title, artist, idea):
        global titles
        global spotifys
        global distances
        global tit_dic
        num = tit_dic[title]
        index = 0
        mindex = 0
        least = 100
        for val in distances:
            if val < least:
                least = val
                mindex = index
            index += 1

        return (titles[mindex], spotifys[mindex])

        sorted(distances)

    def mail(self, ID):
        fromaddr = '*****@*****.**'
        toaddr = '*****@*****.**'
        msg = "\r\n".join([
            "Subject: Your Saved Patent", "", "Hello Oski! \n\n",
            "You saved a patent using the Patent Fox app.\n",
            "Here is the link: \n",
            "https://drive.google.com/viewerng/viewer?url=patentimages.storage.googleapis.com/pdfs/US6477117.pdf"
            "https://www.google.com/patents/US" + ID
        ])

        username = '******'
        password = '******'
        send_mail(username, password, fromaddr, toaddr, msg)

    def login(self, email, password):
        time.sleep(.75)
        auth_token = ""
        #payload = urllib.urlencode({'email': email, 'password': password})
        endpoint = "http://calwatson.herokuapp.com/users/sign_in"
        headers = {
            'Content-type': 'application/x-www-form-urlencoded',
            'Accept': 'text/plain'
        }
        #r = UrlRequest(endpoint, req_body=payload, req_headers=headers,debug=True)
        #r.wait()

        if True:
            self.navbar_label = "Logged in as " + email
            self.login_text = 'Welcome!'
            self.my_token = "tokentoek"  #r.result['auth_token']
            self.logged_in = True
            self.manager.current = 'analysis'
            #change Screen!
        else:
            print "Should never get here"
        return auth_token

    def signup(self, email, password):
        payload = urllib.urlencode({'email': email, 'password': password})
        #endpoint = "http://calwatson.herokuapp.com/users/sign_up"
        headers = {
            'Content-type': 'application/x-www-form-urlencoded',
            'Accept': 'text/plain'
        }
        #r = UrlRequest(endpoint, req_body=payload, req_headers=headers,debug=True)
        r.wait()
        if r.result == "Successful sign up":
            self.login_text = 'Welcome!'
            self.login(email, password)

        elif r.result == "That email is already taken.":
            self.login_text = r.result
            pass
        else:
            print "Should never get here"
        return

    def get_last_five_queries(self, token):
        payload = urllib.urlencode({'token': token})
        endpoint = "http://calwatson.herokuapp.com/users/last_requests"
        headers = {
            'Content-type': 'application/x-www-form-urlencoded',
            'Accept': 'text/plain'
        }
        r = UrlRequest(endpoint,
                       req_body=payload,
                       req_headers=headers,
                       debug=True)
        r.wait()

        try:
            last_queries = r.result['answers']
        except:
            # not able to find auth token
            pass
        return last_queries

    def getAbstract(self, data):
        try:
            return data[0]
        except:
            return "No abstract found."

    def getPatentNumber(self, data):
        try:
            return data[1]
        except:
            return "19283"

    def getInventor(self, data):
        try:
            return data[2]
        except:
            return "Vishnay Kuram"

    def getPhoneNumber(self, data):
        try:
            return data[3]
        except:
            return "938-374-3948"

    def getLitigations(self, data):
        try:
            return data[4]
        except:
            exit()
            return "0"

    def local_query(self, term):
        #set confidence interval
        time.sleep(.5)
        amount_found = 0
        results = [
            documents[word] for word in self.patent_traits if word in term
        ]
        self.patent_matches = len(results)
        if self.patent_matches < 6:
            #extremely precise patent measure based on machine learning and big-data
            self.confidence = 75 + random.randint(0, 16)
        else:
            self.confidence = 0.73
        i = 5 - self.patent_matches
        if i > 0:
            while i > 0:
                rando = random.choice(list(documents.values()))
                if rando not in results:
                    results.append(rando)
                    i -= 1

        self.search_titl0 = "US" + self.getPatentNumber(results[0])

        self.search_titl1 = "US" + self.getPatentNumber(results[1])

        self.search_titl2 = "US" + self.getPatentNumber(results[2])

        self.search_titl3 = "US" + self.getPatentNumber(results[3])

        self.search_titl4 = "US" + self.getPatentNumber(results[4])

        self.search0 = self.getAbstract(results[0])
        self.search1 = self.getAbstract(results[1])
        self.search2 = self.getAbstract(results[2])
        self.search3 = self.getAbstract(results[3])
        self.search4 = self.getAbstract(results[4])

        self.litigation_count0 = self.getLitigations(results[0])

        self.litigation_count1 = self.getLitigations(results[1])

        self.litigation_count2 = self.getLitigations(results[2])

        self.litigation_count3 = self.getLitigations(results[3])

        self.litigation_count4 = self.getLitigations(results[4])

        self.own_name0 = self.getInventor(results[0])
        self.own_name1 = self.getInventor(results[1])
        self.own_name2 = self.getInventor(results[2])
        self.own_name3 = self.getInventor(results[3])
        self.own_name4 = self.getInventor(results[4])

        self.own_num0 = self.getPhoneNumber(results[0])
        self.own_num1 = self.getPhoneNumber(results[1])
        self.own_num2 = self.getPhoneNumber(results[2])
        self.own_num3 = self.getPhoneNumber(results[3])
        self.own_num4 = self.getPhoneNumber(results[4])

        return results

    def query(self, term):
        payload = urllib.urlencode({
            'question': "{0}".format(term),
            'token': self.my_token
        })
        headers = {
            'Content-type': 'application/x-www-form-urlencoded',
            'Accept': 'text/plain'
        }
        r = UrlRequest(endpoint,
                       req_body=payload,
                       req_headers=headers,
                       debug=True)
        r.wait()
        print r.result

        try:
            d = r.result

            search0 = d['question']['evidencelist'][0]['text']
            self.s_confidence = d['question']['evidencelist'][0]['value']

            search1 = d['question']['evidencelist'][1]['text']
            self.s1_confidence = d['question']['evidencelist'][1]['value']

            search2 = d['question']['evidencelist'][2]['text']
            self.s2_confidence = d['question']['evidencelist'][2]['value']
        except:
            search0 = 'Not found'
            search1 = 'Not found'
            search2 = 'Not found'

            self.s_confidence = ''
            self.s2_confidence = ''
            self.s3_confidence = ''

        self.search0 = ''
        self.search1 = ''
        self.search2 = ''
        j = 0

        chars_per_line = 8

        for i in search0.split():

            if j == 40:
                break
            if j % chars_per_line == 0:
                self.search0 += '\n'
                pass
            self.search0 += i + ' '
            j += 1
        j = 0
        for i in search1.split():

            if j == 40:
                break

            if j % chars_per_line == 0:
                self.search1 += '\n'
            self.search1 += i + ' '
            j += 1

        j = 0
        for i in search2.split():

            if j == 40:
                break

            if j % chars_per_line == 0:
                self.search2 += '\n'
            self.search2 += i + ' '
            j += 1

        return self.response

    def build(self):
        global RootApp
        RootApp = self
        # NavigationDrawer
        self.navigationdrawer = NavDrawer()
        #self.navigationdrawer.side_panel_width = .2

        # SidePanel
        side_panel = SidePanel()

        self.navigationdrawer.add_widget(side_panel)
        self.navigationdrawer.logged_in = False

        # MainPanel
        self.main_panel = MainPanel()

        self.navigationdrawer.anim_type = 'slide_above_anim'
        self.navigationdrawer.add_widget(self.main_panel)

        self.navbar_label = 'Tent'

        return self.navigationdrawer

    def toggle_sidepanel(self):
        self.navigationdrawer.toggle_state()

    def on_saved(self):
        self.navigationdrawer.close_sidepanel()
        if self.logged_in != True:
            self.login_text = 'Please login before continuing.'
        else:
            self.manager.current = 'saved_searches'
        #switch to saved
    def on_history(self):

        self.navigationdrawer.close_sidepanel()
        if self.logged_in != True:
            self.login_text = 'Please login before continuing.'
        else:
            self.manager.current = 'search_history'

    def on_settings(self):
        self.navigationdrawer.close_sidepanel()
        if self.logged_in != True:
            self.login_text = 'Please login before continuing.'
        else:
            self.manager.current = 'settings'

    def on_search(self):
        print('why??')
        self.navigationdrawer.close_sidepanel()
        print('why!?')
        if self.logged_in != True:
            self.login_text = 'Please login before continuing.'
        else:
            self.manager.current = 'analysis'

    def _switch_main_page(self, key, panel):
        self.navigationdrawer.close_sidepanel()
        if not SidePanel_AppMenu[key][id_AppMenu_PANEL]:
            SidePanel_AppMenu[key][id_AppMenu_PANEL] = panel()
        main_panel = SidePanel_AppMenu[key][id_AppMenu_PANEL]
        self.navigationdrawer.remove_widget(
            self.main_panel)  # FACCIO REMOVE ED ADD perchè la set_main_panel
        self.navigationdrawer.add_widget(
            main_panel)  # dà un'eccezione e non ho capito perchè
        self.main_panel = main_panel
Beispiel #27
0
class DiscordToolbar(CustomToolbar, DiscordTheme):
    text_color = ListProperty()
    title = StringProperty()
    font_size = NumericProperty("20dp")
Beispiel #28
0
class RulesWindow(Screen):
    rules = StringProperty('')

    def __init__(self, **kwargs):
        super(RulesWindow, self).__init__(**kwargs)
        self.rules = rules_string
Beispiel #29
0
class NavigationLayout(VendorNavigationDrawer, ThemableBehavior):
    """The container layout that manages the :class:`MDNavigationDrawer`."""

    opening_transition = StringProperty('out_sine')
    closing_transition = StringProperty('out_sine')
    min_dist_to_open = NumericProperty(.2)
    min_dist_to_close = NumericProperty(.8)
    anim_time = NumericProperty(.2)
    separator_image = StringProperty('{}'.format(images_path +
                                                 '/transparent.png'))
    side_panel_positioning = 'left'
    side_panel_width = (dp(320) * 80) // 100\
        if dp(320) >= Window.width else dp(320)
    max_shadow_opacity = NumericProperty(.5)
    anim_type = StringProperty('slide_above_simple')

    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        self.on_anim_type()

    def _anim_relax(self):
        if self.state == 'open':
            if self._anim_progress < self.min_dist_to_close:
                self.anim_to_state('closed')
            else:
                self.anim_to_state('open')
        else:
            if self._anim_progress > self.min_dist_to_open:
                self.anim_to_state('open')
            else:
                self.anim_to_state('closed')

    def on__anim_progress(self, *args):
        self.side_panel.shadow_color = [
            0, 0, 0, self.max_shadow_opacity * self._anim_progress
        ]
        self.side_panel.elevation = 1 * self._anim_progress
        if self._anim_progress > 1:
            self._anim_progress = 1
        elif self._anim_progress < 0:
            self._anim_progress = 0
        if self._anim_progress >= 1:
            self.state = 'open'
        elif self._anim_progress <= 0:
            self.state = 'closed'

    def add_widget(self, widget, **kwargs):
        """
        First widget added must be the content for the side/sliding panel.
        The next widget must be the main content.

        This layout only accepts two widgets, any more than two widgets will
        raise a ValueError
        """

        # Internal default BoxLayouts
        if len(self.children) == 0:
            super().add_widget(widget, **kwargs)
            self._side_panel = widget
        elif len(self.children) == 1:
            super().add_widget(widget, **kwargs)
            self._main_panel = widget
        elif len(self.children) == 2:
            super().add_widget(widget, **kwargs)
            self._join_image = widget

        # Adding of user widgets
        elif self.side_panel is None:
            self.set_side_panel(widget)
            widget.panel = self
        elif self.main_panel is None:
            self.set_main_panel(widget)
        else:
            raise ValueError(
                'Can\'t add more than two widgets directly to NavigationLayout'
            )

    def toggle_nav_drawer(self):
        self.toggle_state(True)
Beispiel #30
0
class CustomOneLineIconListItem(OneLineIconListItem):
    icon = StringProperty()