Better workaround for issue with RPi touch screen + hide cursor

This commit is contained in:
Admar Schoonen 2023-04-10 22:11:21 +02:00
parent a86412edcb
commit e0a9074670
1 changed files with 82 additions and 29 deletions

111
clock.py
View File

@ -7,6 +7,7 @@ import traceback
import copy
import os
from kivy.config import Config
import time
def is_arm():
if (os.uname()[4][:3] == 'arm') or (os.uname()[4][:7] == 'aarch64'):
@ -53,6 +54,10 @@ from kivy.uix.button import Button
from kivy.clock import Clock
from kivy.lang import Builder
from kivy.graphics import Color, Line, Rectangle
from kivy.core.window import Window
if is_arm():
Window.show_cursor = False
import pulsectl
import vlc
@ -279,6 +284,11 @@ class Touch():
def clear(self):
self = Touch()
class TouchEvent():
def __init__(self, x=None):
self.time = time.time()
self.touch = copy.deepcopy(x)
class MyClockWidget(FloatLayout):
grabbed = ""
face_numbers = []
@ -295,6 +305,13 @@ class MyClockWidget(FloatLayout):
intensity_target_prev = None
rgbw_prev = None
# Ugly workaround for issue with Kivy and Raspberry Pi 3 + touch screen
# For each type of touch event, handling of the event is ignored until the last event is more than touch_delay_time seconds old
touch_delay_time = 0.1
last_touch_down_event = None
last_touch_move_event = None
last_touch_up_event = None
# view can be one of the following strings:
# - "clock"
# - "set_alarm"
@ -368,12 +385,12 @@ class MyClockWidget(FloatLayout):
alarm_settings = App.get_running_app().alarm_settings
if self.view == "set_alarm":
time = alarm_settings.alarm_time
t = alarm_settings.alarm_time
else:
time = datetime.datetime.now()
t = datetime.datetime.now()
for i in range(1, 13):
if time.hour < 12:
if t.hour < 12:
offset = 0
else:
offset = 12
@ -393,12 +410,12 @@ class MyClockWidget(FloatLayout):
alarm_settings = App.get_running_app().alarm_settings
if self.view == "set_alarm":
time = alarm_settings.alarm_time
t = alarm_settings.alarm_time
else:
time = datetime.datetime.now()
t = datetime.datetime.now()
for i in range(0, 12):
if time.hour < 12:
if t.hour < 12:
offset = 0
else:
offset = 12
@ -511,7 +528,7 @@ class MyClockWidget(FloatLayout):
led_color = self.intensity_to_rgbw(self.intensity_curr)
if self.rgbw_prev != led_color.rgbw:
self.rgbw_prev = led_color.rgbw
print(self.light_state + ", t: " + str(self.seconds_to_next_alarm) + ", i: " + str(self.intensity_curr) + ", rgbw: " + str(led_color.rgbw))
# print(self.light_state + ", t: " + str(self.seconds_to_next_alarm) + ", i: " + str(self.intensity_curr) + ", rgbw: " + str(led_color.rgbw))
pixels.fill(led_color.rgbw)
pixels.show()
else:
@ -519,7 +536,7 @@ class MyClockWidget(FloatLayout):
rgbw = [0, 0, 0, round(self.intensity_curr * 255)]
if self.rgbw_prev != rgbw:
self.rgbw_prev = rgbw
print(self.light_state + ", t: " + str(self.seconds_to_next_alarm) + ", i: " + str(self.intensity_curr) + ", rgbw: " + str(rgbw))
# print(self.light_state + ", t: " + str(self.seconds_to_next_alarm) + ", i: " + str(self.intensity_curr) + ", rgbw: " + str(rgbw))
def sunrise(self):
alarm_settings = App.get_running_app().alarm_settings
@ -553,16 +570,15 @@ class MyClockWidget(FloatLayout):
elif (self.light_state == "on"):
self.intensity_target = alarm_settings.wake_up_brightness / 20.0
step = self.intensity_target - self.intensity_curr
stepsize = 0.01
weight = 0.05
intensity_next = weight * self.intensity_target + (1 - weight) * self.intensity_curr
if step > stepsize:
step = stepsize
elif step < -stepsize:
step = -stepsize
step = intensity_next - self.intensity_curr
#self.intensity_curr = self.intensity_curr + stepsize
self.intensity_curr = self.intensity_target
if abs(step) < 0.001:
step = self.intensity_target - self.intensity_curr
self.intensity_curr = self.intensity_curr + step
def check_play_sound(self):
alarm_settings = App.get_running_app().alarm_settings
@ -601,14 +617,14 @@ class MyClockWidget(FloatLayout):
alarm_settings = App.get_running_app().alarm_settings
if self.view == "set_alarm":
time = alarm_settings.alarm_time
t = alarm_settings.alarm_time
else:
time = datetime.datetime.now()
t = datetime.datetime.now()
hands = self.ids["hands"]
seconds_hand = self.position_on_clock(time.second/60, length=0.45*hands.size[0])
minutes_hand = self.position_on_clock(time.minute/60+time.second/3600, length=0.40*hands.size[0])
hours_hand = self.position_on_clock(time.hour/12 + time.minute/720, length=0.35*hands.size[0])
seconds_hand = self.position_on_clock(t.second/60, length=0.45*hands.size[0])
minutes_hand = self.position_on_clock(t.minute/60+t.second/3600, length=0.40*hands.size[0])
hours_hand = self.position_on_clock(t.hour/12 + t.minute/720, length=0.35*hands.size[0])
self.update_face()
@ -673,8 +689,23 @@ class MyClockWidget(FloatLayout):
print("Unknown draw command: " + i[0])
self.draw_list_last_frame = self.draw_list_curr_frame
self.draw_list_curr_frame = []
def process_touch_events(self):
t = time.time()
if (self.last_touch_down_event is not None) and (t - self.last_touch_down_event.time > self.touch_delay_time):
self.touch_down_function(self.last_touch_down_event.touch)
self.last_touch_down_event = None
if (self.last_touch_move_event is not None) and (t - self.last_touch_move_event.time > self.touch_delay_time):
self.touch_move_function(self.last_touch_move_event.touch)
self.last_touch_move_event = None
if (self.last_touch_up_event is not None) and (t - self.last_touch_up_event.time > self.touch_delay_time):
self.touch_up_function(self.last_touch_up_event.touch)
self.last_touch_up_event = None
def update_display(self, *args):
self.process_touch_events()
self.check_alarm()
# Hide all dynamic widgets; will be enabled when updating respecive view
@ -776,6 +807,7 @@ class MyClockWidget(FloatLayout):
self.set_backlight(alarm_settings.display_brightness)
def on_light_button_pressed(self):
print("light button pressed from view " + self.view)
alarm_settings = App.get_running_app().alarm_settings
if self.light_state == "off":
@ -799,6 +831,7 @@ class MyClockWidget(FloatLayout):
self.stop_sound()
def on_play_button_pressed(self):
print("play button pressed from view " + self.view)
alarm_settings = App.get_running_app().alarm_settings
if alarm_settings.alarm_playing:
self.stop_sound()
@ -806,6 +839,7 @@ class MyClockWidget(FloatLayout):
self.play_sound(alarm_settings.sound_source)
def on_alarm_button_pressed(self):
print("alarm button pressed from view " + self.view)
alarm_settings = App.get_running_app().alarm_settings
alarm_settings.alarm_modified = False
@ -826,7 +860,7 @@ class MyClockWidget(FloatLayout):
self.view = "clock"
print("view updated to " + self.view)
def on_touch_up(self, touch):
def touch_up_function(self, touch):
self.grabbed = ""
self.light_button_move_init = []
alarm_settings = App.get_running_app().alarm_settings
@ -837,7 +871,7 @@ class MyClockWidget(FloatLayout):
super(MyClockWidget, self).on_touch_up(touch)
def on_touch_move(self, touch):
def touch_move_function(self, touch):
if self.grabbed == "":
return
@ -963,13 +997,12 @@ class MyClockWidget(FloatLayout):
super(MyClockWidget, self).on_touch_move(touch)
def on_touch_down(self, touch):
def touch_down_function(self, touch):
alarm_settings = App.get_running_app().alarm_settings
time = alarm_settings.alarm_time
t = alarm_settings.alarm_time
hands = self.ids["hands"]
minutes_hand = self.position_on_clock(time.minute/60+time.second/3600, length=0.40*hands.size[0])
hours_hand = self.position_on_clock(time.hour/12 + time.minute/720, length=0.35*hands.size[0])
minutes_hand = self.position_on_clock(t.minute/60+t.second/3600, length=0.40*hands.size[0])
hours_hand = self.position_on_clock(t.hour/12 + t.minute/720, length=0.35*hands.size[0])
if (0.05 <= touch.spos[0] <= 0.25) and (0.85 <= touch.spos[1] <= 0.95):
if self.grabbed == "":
@ -994,7 +1027,6 @@ class MyClockWidget(FloatLayout):
self.touch_prev.clear()
else:
self.grabbed = ""
print("grabbed: " + self.grabbed)
elif self.view == "settings_menu":
pass
elif self.view == "clock":
@ -1002,6 +1034,27 @@ class MyClockWidget(FloatLayout):
super(MyClockWidget, self).on_touch_down(touch)
def on_touch_down(self, touch, after=False):
if after:
self.last_touch_down_event = TouchEvent(touch)
else:
Clock.schedule_once(lambda dt: self.on_touch_down(touch, True))
return super(MyClockWidget, self).on_touch_down(touch)
def on_touch_move(self, touch, after=False):
if after:
# Do not delay processing of move events
self.touch_move_function(touch)
else:
Clock.schedule_once(lambda dt: self.on_touch_move(touch, True))
return super(MyClockWidget, self).on_touch_move(touch)
def on_touch_up(self, touch, after=False):
if after:
self.last_touch_up_event = TouchEvent(touch)
else:
Clock.schedule_once(lambda dt: self.on_touch_up(touch, True))
return super(MyClockWidget, self).on_touch_up(touch)
class MyApp(App):
alarm_settings = AlarmSettings()