/
main.py
143 lines (124 loc) · 4.92 KB
/
main.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
#!/usr/bin/python
import kivy
kivy.require('1.8.0')
from time import time
from signal import signal, SIGINT
from Queue import Queue, Empty
from kivy.app import App
from kivy.event import EventDispatcher
from kivy.uix.label import Label
from kivy.lang import Builder
from kivy.properties import NumericProperty, StringProperty, BooleanProperty,\
ListProperty, ObjectProperty
from kivy.clock import Clock
from kivy.uix.tabbedpanel import TabbedPanel
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.actionbar import ActionBar
from kivy.uix.button import Button
from kivy.uix.label import Label
from kivy.uix.popup import Popup
from kivy.adapters.listadapter import ListAdapter
from kivy.uix.listview import ListView, ListItemButton
from olalistener import OLAListener, UIEvent
from settingsscreen import MainScreen, PatchingPopup
from monitorscreen import MonitorScreen
from consolescreen import ConsoleScreen
from ola.OlaClient import OlaClient, Universe
from ola.ClientWrapper import SelectServer
class ScreenTabs(TabbedPanel):
"""Class for the widget that holds all the Screens in a tabbed view"""
def __init__(self, **kwargs):
super(ScreenTabs, self).__init__(**kwargs)
self.previous_tab = self.current_tab
def on_size(self, inst, value):
"""Ensures that the tabs fill the entire top bar"""
width = value[0]
self.tab_width = int(width / len(self.tab_list))
def on_current_tab(self, *args):
"""When the current tab changes, fire Screen methods for enter/exit"""
if self.previous_tab.content:
self.previous_tab.content.on_leave()
if self.current_tab.content:
self.current_tab.content.on_enter()
self.previous_tab = self.current_tab
class UniverseSelectedService(EventDispatcher):
selected_universe = ObjectProperty(Universe(None, None, None), allownone=True)
class RPiUI(App):
"""Class for drawing and handling the Kivy application itself."""
EVENT_POLL_INTERVAL = 1 / 20
UNIVERSE_POLL_INTERVAL = 1 / 10
index = NumericProperty(-1)
time = NumericProperty(0)
current_title = StringProperty()
screen_names = ListProperty([])
def build(self):
"""Initializes the user interface and starts timed events."""
#TODO: Reorganize and consolidate; make necessary helper functions
self.title = 'Open Lighting Architecture'
self.ui_queue = Queue()
self.layout = BoxLayout(orientation='vertical')
self.selected_universe_service = UniverseSelectedService()
self.ola_listener = OLAListener(self.ui_queue,
self.create_select_server,
self.create_ola_client,
self.start_ola,
self.stop_ola)
#Screen creation and layout placing
self.screen_tabs = ScreenTabs()
self.monitor_screen = MonitorScreen(self.ola_listener,
self.selected_universe_service,
name='DMX Monitor')
self.console_screen = ConsoleScreen(self.ola_listener,
self.selected_universe_service,
name='DMX Console')
self.devsets = MainScreen(self.ola_listener,
self.selected_universe_service,
name='Device Settings')
self.screen_tabs.ids.monitor_screen.add_widget(self.monitor_screen)
self.screen_tabs.ids.console_screen.add_widget(self.console_screen)
self.screen_tabs.ids.settings_screen.add_widget(self.devsets)
self.layout.add_widget(self.screen_tabs)
Clock.schedule_interval(lambda dt: self.display_tasks(),
self.EVENT_POLL_INTERVAL)
Clock.schedule_interval(self._update_clock, 1 / 60.)
return self.layout
def on_start(self):
"""Executed after build()"""
signal(SIGINT, self.stop) #Captures ctrl-c to exit correctly
self.ola_listener.start()
def on_stop(self):
"""Executed when the application quits"""
self.ola_listener.stop()
def on_pause(self):
"""Pausing is not allowed; the application will close instead"""
return False
def on_resume(self):
"""Because pausing is not allowed, nothing to do here"""
pass
@staticmethod
def create_select_server():
return SelectServer()
@staticmethod
def create_ola_client():
return OlaClient()
def start_ola(self):
"""Executed when OLAD starts, enables proper UI actions"""
self.devsets.start_ola(self.UNIVERSE_POLL_INTERVAL)
def stop_ola(self):
"""Executed when OLAD stops, disables proper UI actions"""
self.devsets.stop_ola()
def display_tasks(self):
"""Polls for events that need to update the UI,
then updates the UI accordingly.
"""
try:
event = self.ui_queue.get(False)
event.run()
except Empty:
pass
def _update_clock(self, dt):
self.time = time()
def olad_listen(self, dt):
self.ola_listener.listen(self)
if __name__ == '__main__':
RPiUI().run()