Skip to content

Instantly share code, notes, and snippets.

@jedie
Created November 25, 2017 16:44
Show Gist options
  • Select an option

  • Save jedie/6c96323fbbd1cd173c746f5dae6cf715 to your computer and use it in GitHub Desktop.

Select an option

Save jedie/6c96323fbbd1cd173c746f5dae6cf715 to your computer and use it in GitHub Desktop.
from __future__ import print_function, absolute_import, unicode_literals
from functools import partial
import datetime
from kivy.config import Config
import re
Config.set("kivy", "log_level", "debug")
from kivy.app import App
from kivy.uix.label import Label
from kivy.uix.textinput import TextInput
from kivy.uix.boxlayout import BoxLayout
from kivy.logger import Logger
class IntegerInput(TextInput):
def __init__(self, min_value=None, max_value=None, **kwargs):
self.str2number_func = int
self.min_value=min_value
self.max_value=max_value
super(IntegerInput, self).__init__(**kwargs)
def is_valid(self, substring):
try:
value = self.str2number_func(substring)
except ValueError as err:
Logger.debug("insert_text(): %s", err)
return False
if self.min_value is not None and value<self.min_value:
Logger.debug("Validation error min value")
return False
if self.max_value is not None and value>self.max_value:
Logger.debug("Validation error max value")
return False
return True
def insert_text(self, substring, from_undo=False):
if not self.is_valid(self.text + substring):
substring = ""
Logger.debug("insert_text(): %r" % substring)
return super(IntegerInput, self).insert_text(substring, from_undo=from_undo)
class TimeTextInput(BoxLayout):
def __init__(self, **kwargs):
self.register_event_type('on_time')
super(TimeTextInput, self).__init__(**kwargs)
self.time = datetime.time(hour=0, minute=0, second=0)
self.text_hh = IntegerInput(
multiline=False,
min_value=0, max_value=None,
)
self.text_hh.bind(text=partial(self.on_value, key="hour"))
self.add_widget(self.text_hh)
self.add_widget(Label(text=":"))
self.text_mm = IntegerInput(
multiline=False,
min_value=0, max_value=59,
)
self.text_mm.bind(text=partial(self.on_value, key="minute"))
self.add_widget(self.text_mm)
self.add_widget(Label(text=":"))
self.text_ss = IntegerInput(
multiline=False,
min_value=0, max_value=59,
)
self.text_ss.bind(text=partial(self.on_value, key="second"))
self.add_widget(self.text_ss)
self.update_text()
def update_text(self):
self.text_hh.text = "%i" % self.time.hour
self.text_mm.text = "%i" % self.time.minute
self.text_ss.text = "%i" % self.time.second
self.dispatch('on_time', self.time)
def set_seconds(self, seconds):
print("TODO: %s" % seconds)
def on_value(self, instance, value, key):
if value:
try:
value = int(value)
except ValueError as err:
Logger.error("on_value(): %s", err)
else:
kwargs={key: value}
try:
self.time = self.time.replace(**kwargs)
except ValueError as err:
Logger.error("Wrong time: %s", err)
else:
self.update_text()
def on_time(self, time):
pass
class RunCalcApp(App):
def __init__(self, *args, **kwargs):
super(RunCalcApp, self).__init__(*args, **kwargs)
self.distance = None
self.time = None
self.pace = None
def build(self):
root = BoxLayout(orientation='vertical')
#---------------------------------------------------------------------
root.add_widget(Label(text='Distance [km]'))
text_distance = TextInput(multiline=False)
text_distance.bind(text=self.on_distance)
root.add_widget(text_distance)
#---------------------------------------------------------------------
root.add_widget(Label(text='Time [hh:mm:ss]'))
text_time = TimeTextInput()
text_time.bind(on_time=self.on_time)
root.add_widget(text_time)
#---------------------------------------------------------------------
root.add_widget(Label(text='Pace [mm:ss]'))
self.text_pace = TimeTextInput()
self.text_pace.bind(on_time=self.on_pace)
root.add_widget(self.text_pace)
#---------------------------------------------------------------------
root.add_widget(Label(text='info:'))
self.textbox_info = TextInput(multiline=False)
root.add_widget(self.textbox_info)
return root
def calculate_pace(self):
if self.distance is None:
Logger.info("Distance emtpy")
return
if self.time is None:
Logger.info("Time emtpy")
return
td = datetime.timedelta(
hours=self.time.hour,
minutes=self.time.minute,
seconds=self.time.second
)
seconds = td.total_seconds()
pace = self.distance / seconds
Logger.info("Pace: %r", pace)
self.text_pace.text = "%r" % pace
def on_distance(self, instance, value):
print("on_distance():", repr(value))
if value:
try:
self.distance = float(value)
except ValueError as err:
Logger.error("on_distance(): %s", err)
self.textbox_info.text = "Distance value error %s" % err
else:
self.textbox_info.text = "Set distance to: %s" % instance.text
self.calculate_pace()
instance.text = "%.4f" % self.distance
def on_time(self, instance, time):
Logger.debug("RunCalcApp().on_time(): %r", time)
self.time = time
self.calculate_pace()
return True # ignore other binds
def on_pace(self, instance, time):
Logger.debug("RunCalcApp().on_pace(): %r", time)
return True # ignore other binds
if __name__ == '__main__':
RunCalcApp().run()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment