Example #1
0
class ZenDisplay(QtWidgets.QSystemTrayIcon):
    """System tray icon class"""
    def __init__(self):
        super().__init__()

        self.controller = Controller()
        self.displays = Displays()

        if len(self.displays) == 0:
            print('Could not find supported displays')
            quit()

        self.sensors = LuminanceSourceManager()
        self.sensors.add_source_type(LuminanceIIO)
        self.sensors.add_source_type(LuminanceMQTT, {
            'topic': MQTT_TOPIC,
            'host': MQTT_HOST
        })
        manual_parameters = self.controller.get_range()
        manual_parameters.update({'value': self.displays.get_brightness()})
        self.sensors.add_source_type(LuminanceManual, manual_parameters)
        self.sensors.activate(DEFAULT_SENSOR)

        self.menu = self.construct_menu()
        self.menu_visible = False
        self.setContextMenu(self.menu)
        self.activated.connect(lambda reason: self.action_click(reason, self))

        self.timer = QtCore.QTimer()
        self.timer.timeout.connect(self.main_control)
        self.timer.start(1000)

        if MQTT_PUBLISH is True:
            self.mqtt_publisher = LuminanceMQTT(name="mqttp",
                                                path=MQTT_TOPIC,
                                                host=MQTT_HOST)

    def toggle_menu(self):
        """Toggle context menu visibility"""
        if self.menu_visible:
            self.menu.hide()
        else:
            self.menu.popup(QtGui.QCursor.pos())
        self.menu_visible = not self.menu_visible

    def construct_menu(self):
        """Construct a menu from the sitemap"""
        menu = QtWidgets.QMenu()
        self.construct_menu_displays(menu)
        self.construct_menu_sensors(menu)

        # Create quit button
        menu.addSeparator()
        action_quit = menu.addAction("Quit")
        action_quit.triggered.connect(lambda _: quit())
        return menu

    def construct_menu_displays(self, parent):
        """Create submenu for displays"""
        display_menu = parent.addMenu('Displays')
        for display in self.displays:
            action = display_menu.addAction(display['name'])
            action.setCheckable(True)
            action.setChecked(display['use'])
            did = display['id']
            action.triggered.connect(
                lambda state, did=did: self.displays.set_active(did, state))

    def construct_menu_sensors(self, parent):
        """Create submenu for sensors"""
        sensor_menu = parent.addMenu('Sensors')
        sensor_group = QtWidgets.QActionGroup(sensor_menu, exclusive=True)
        for sensor in self.sensors:
            action = sensor_menu.addAction(sensor.name + " (" + sensor.path +
                                           ")")
            action.setCheckable(True)
            if sensor.uid == self.sensors.get_active():
                action.setChecked(True)
            sid = sensor.uid
            action.triggered.connect(
                lambda state, sid=sid: self.sensors.activate(sid))
            sensor_group.addAction(action)

    def main_control(self):
        """Main control function, sets display brightness dynamically"""
        luminance = self.sensors.get_luminance()
        current_brightness = self.displays.get_brightness()
        recommended_brightness = self.controller.recommend_brightness(
            luminance, current_brightness)
        self.setToolTip('Brightness: ' + str(recommended_brightness) + '%')
        self.displays.set_brightness(recommended_brightness)
        if MQTT_PUBLISH is True:
            self.mqtt_publisher.publish(luminance)

    def event(self, event):
        """Event handler for QEvent objects"""
        if event.type() == QtCore.QEvent.Wheel:
            new_value = None
            if event.angleDelta().y() < 0:
                new_value = self.sensors[self.sensors.get_active()].decrease()
            else:
                new_value = self.sensors[self.sensors.get_active()].increase()
            if new_value is not None and self.supportsMessages():
                self.showMessage('Brightness', str(new_value) + '%', msecs=500)
            return True
        return False

    @classmethod
    @QtCore.pyqtSlot()
    def action_click(cls, reason, tray):
        """Toggle menu on click"""
        if reason in [
                QtWidgets.QSystemTrayIcon.Trigger,
                QtWidgets.QSystemTrayIcon.Context
        ]:
            tray.toggle_menu()