示例#1
0
    def __init__(self, video_engine, parent=None):

        # Set up to sync with double-buffer, vertical refresh.  Add Alpha and Depth buffers.
        fmt = QtOpenGL.QGLFormat()
        fmt.setSwapInterval(2)
        fmt.setDoubleBuffer(True)
        fmt.setAlpha(True)
        fmt.setDepth(True)
        QtOpenGL.QGLWidget.__init__(self, fmt, parent)

        # set application settings
        self.settings = LuxSettings()

        # create a mutex for the state
        self.lock = QtCore.QMutex()

        # height and width of viewport
        self.width = 512
        self.height = 512

        # set dirty state
        self.dirty = True

        # start up an update timer
        self.timerId = self.startTimer(30)

        # whether GL is initialized
        self.initialized = False

        # Start the simulator audio client.  Connects to JACK server,
        # which must be running.
        self.makeCurrent()
        self.video_engine = video_engine
示例#2
0
    def __init__(self, parent, output_engine):
        QtGui.QWidget.__init__(self, parent)
        self.setupUi(self)
        self.output_engine = output_engine

        self.settings = LuxSettings()

        grid_pen = QtGui.QPen(Qt.blue)
        line_pen = QtGui.QPen(Qt.green)
        point_brush = QtGui.QBrush(Qt.red)
        background_brush = QtGui.QBrush(Qt.black)

        self.scene = QtGui.QGraphicsScene()
        self.scene.setSceneRect(-1.1, -1.1, 2.2, 2.2)

        for i in range(-5, 6):
            self.scene.addLine(i / 5.0, -1.0, i / 5.0, 1.0, grid_pen)
            self.scene.addLine(-1.0, i / 5.0, 1.0, i / 5.0, grid_pen)

        self.pts = []
        for i in range(4):
            self.pts.append(ControlPoint())

        for i in range(4):
            self.pts[i].setBrush(point_brush)
            self.pts[i].setRect(-5, -5, 10, 10)
            self.pts[i].setFlag(QtGui.QGraphicsItem.ItemIgnoresTransformations,
                                True)
            self.pts[i].setFlag(QtGui.QGraphicsItem.ItemIsMovable, True)
            self.pts[i].setFlag(QtGui.QGraphicsItem.ItemSendsGeometryChanges,
                                True)
            self.pts[i].form = self
            self.scene.addItem(self.pts[i])

        self.pl = QtGui.QGraphicsPolygonItem()
        self.pl.setPen(line_pen)
        self.scene.addItem(self.pl)

        self.calibrationView.setBackgroundBrush(background_brush)
        self.calibrationView.setScene(self.scene)
        self.calibrationView.fitInView(self.scene.sceneRect(),
                                       Qt.KeepAspectRatio)
        self.calibrationView.setRenderHints(QtGui.QPainter.Antialiasing)
        self.affine_matrix = QtGui.QTransform()

        self.currentAspect = -1

        self.resetPoints()
        self.resetDefaults()
        self.update()
示例#3
0
    def __init__(self, parent=None):

        # Set up to sync with double-buffer, vertical refresh.  Add Alpha and Depth buffers.
        fmt = QtOpenGL.QGLFormat()
        fmt.setSwapInterval(2)
        fmt.setDoubleBuffer(True)
        fmt.setAlpha(True)
        fmt.setDepth(True)
        QtOpenGL.QGLWidget.__init__(self, fmt, parent)

        # the display settings window
        self.displaySettings = None

        # set application settings
        self.settings = LuxSettings()

        # create a mutex for the state
        self.lock = QtCore.QMutex()

        # height and width of viewport
        self.width = 512
        self.height = 512

        # start up an update timer with an interval of 1ms.  This will
        # effectively draw frames as fast as the screen is updated.
        self.timerId = self.startTimer(1)

        # Start the simulator audio client.  Connects to JACK server,
        # which must be running.
        self.makeCurrent()
        self.simulator_engine = LuxSimulatorEngine("lux_simulator")
        self.simulator_engine.start()

        self.simulator_engine.connect_ports("lux_engine:out_x",
                                            "lux_simulator:in_x")
        self.simulator_engine.connect_ports("lux_engine:out_y",
                                            "lux_simulator:in_y")
        self.simulator_engine.connect_ports("lux_engine:out_r",
                                            "lux_simulator:in_r")
        self.simulator_engine.connect_ports("lux_engine:out_g",
                                            "lux_simulator:in_g")
        self.simulator_engine.connect_ports("lux_engine:out_b",
                                            "lux_simulator:in_b")
示例#4
0
    def __init__(self, audio_engine, video_engine, output_engine, parent=None):
        QtCore.QThread.__init__(self, parent)

        self.settings = LuxSettings()
        self.ol_update_params = True

        self.settings['video'].refreshWithDefault('videoMode', False)
        self.settings['video'].refreshWithDefault('threshold', 0.2 * 99.0)
        self.settings['video'].refreshWithDefault('blur', 1.5 / 5.0 * 99.0)
        self.settings['video'].refreshWithDefault('minArea',
                                                  100 / (640 * 480) * 99.0)
        self.settings['video'].refreshWithDefault('maxArea', 99.0)
        self.settings['video'].refreshWithDefault('maxNum', 10)

        self.settings['calibration'].refreshWithDefault(
            'parameterOverride', False)
        self.settings['calibration'].refreshWithDefault(
            'olRate', 30000 / 30000.0 * 99.0)
        self.settings['calibration'].refreshWithDefault('olOnSpeed', 100)
        self.settings['calibration'].refreshWithDefault('olOffSpeed', 20)
        self.settings['calibration'].refreshWithDefault('olStartDwell', 3)
        self.settings['calibration'].refreshWithDefault('olEndDwell', 3)
        self.settings['calibration'].refreshWithDefault('olCornerDwell', 4)
        self.settings['calibration'].refreshWithDefault('olCurveDwell', 0)
        self.settings['calibration'].refreshWithDefault('olStartWait', 8)
        self.settings['calibration'].refreshWithDefault('olEndWait', 7)

        # create a mutex and semaphore for managing this thread.
        self.lock = QtCore.QMutex()
        self.exiting = False

        self.audio_engine = audio_engine
        self.video_engine = video_engine
        self.output_engine = output_engine

        self.current_plugin_key = None
        self.current_plugin = None
        self.random_plugin()

        self.video_color_drift = ColorDriftPlugin()
        self.reset_plugin_on_next_frame = False
示例#5
0
    def __init__(self, lux_engine, output_engine, parent=None):
        QtGui.QMainWindow.__init__(self, parent)
        self.settings = LuxSettings()
        self.lux_engine = lux_engine
        self.output_engine = output_engine

        # set our title
        self.setWindowIcon(QtGui.QIcon())
        self.setWindowTitle('Fiat Lux')

        # Set tab positions
        self.setTabPosition(QtCore.Qt.LeftDockWidgetArea,
                            QtGui.QTabWidget.South)
        self.setTabPosition(QtCore.Qt.RightDockWidgetArea,
                            QtGui.QTabWidget.South)

        # create the display widgets in a QTabView
        self.displayTabWidget = QtGui.QTabWidget(self)
        self.displayTabWidget.setTabPosition(QtGui.QTabWidget.South)
        self.simWidget = SimulationDisplay(self)
        self.displayTabWidget.addTab(self.simWidget, "Laser Output")

        # MacOS X supports video capture using syphon.  Other platforms don't (yet!)
        if sys.platform == "darwin":
            self.videoWidget = VideoDisplay(lux_engine.video_engine,
                                            self.displayTabWidget)
            self.displayTabWidget.addTab(self.videoWidget, "Video Input")

        self.displayTabWidget.setVisible(True)
        self.setCentralWidget(self.displayTabWidget)

        self.displayTabWidget.setCurrentIndex(
            self.settings['main_window'].valueWithDefault('display_tab', 0))
        self.connect(self.displayTabWidget,
                     QtCore.SIGNAL('currentChanged(int)'),
                     self.displayTabChanged)

        # -----------------------------------------------------------------------
        #                              STATUS BAR
        # -----------------------------------------------------------------------

        # set up the status bar
        self.statusBar_ = QtGui.QStatusBar(self)
        self.statusLabel = QtGui.QLabel()
        self.statusLabel.setMargin(2)
        self.setStatus()  # set a default status
        self.statusBar_.addWidget(self.statusLabel)
        self.setStatusBar(self.statusBar_)

        self.quitAction = QtGui.QAction('&Quit', self)
        self.quitAction.setShortcut(QtCore.Qt.CTRL + QtCore.Qt.Key_Q)
        self.quitAction.setToolTip('Exit the program.')
        self.connect(self.quitAction, QtCore.SIGNAL('triggered(bool)'),
                     self.close)

        # -----------------------------------------------------------------------
        #                              SETTINGS PANELS
        # -----------------------------------------------------------------------

        self.settingsManager = SettingsPanelManager(self)

        self.settingsManager.add(
            SettingsPanel(name="Plugins",
                          message="",
                          widget=PluginSettings.PluginSettings(
                              self, self.lux_engine)))
        self.settingsManager.add(
            SettingsPanel(name="Output",
                          message="",
                          widget=OutputSettings.OutputSettings(
                              self, self.output_engine)))
        self.calibrationSettings = CalibrationSettings.CalibrationSettings(
            self, self.output_engine)
        self.settingsManager.add(
            SettingsPanel(name="Calibration",
                          message="",
                          widget=self.calibrationSettings))
        self.connect(self.calibrationSettings,
                     QtCore.SIGNAL('olParamsChanged()'),
                     self.lux_engine.updateOlParams)

        # -----------------------------------------------------------------------
        #                              MENU BAR
        # -----------------------------------------------------------------------

        self.menuBar_ = QtGui.QMenuBar(self)
        self.viewMenu = self.menuBar_.addMenu('&View')
        for action in self.settingsManager.toggleViewActions():
            self.viewMenu.addAction(action)
        self.setMenuBar(self.menuBar_)

        # Load previous window size and position, but set a sensible
        # defaults if those settings aren't available.
        self.move(QtCore.QPoint(40, 80))
        self.resize(QtCore.QSize(720, 480))

        # load the previous state of the docks and toolbars
        try:
            state = QtCore.QByteArray(
                self.settings['main_window'].state.decode('hex'))
            self.restoreState(state)
        except AttributeError:
            print "Warning: Could not restore window state."
            # ignore
            pass

        # load window settings
        self.resize(self.settings['main_window'].valueWithDefault(
            'size', self.size()))
        self.move(self.settings['main_window'].valueWithDefault(
            'position', self.pos()))
示例#6
0
    def __init__(self, parent, lux_engine):
        QtGui.QWidget.__init__(self, parent)
        self.setupUi(self)

        self.settings = LuxSettings()
        self.lux_engine = lux_engine
        self.video_engine = lux_engine.video_engine

        (self.plugin_keys, self.plugin_names,
         self.plugin_descriptions) = self.lux_engine.list_plugins()

        # Populate the pull-down menu and select the previous plugin
        # we were using, if it is available.
        prev_plugin = None
        if self.settings['plugins'].contains('current_plugin'):
            prev_plugin = self.settings['plugins'].current_plugin

        self.current_plugin_idx = -1
        for name in self.plugin_names:
            self.manualSelectionBox.addItem(name)

        idx = self.manualSelectionBox.findText(prev_plugin)
        if idx != -1:
            self.manualSelectionBox.setCurrentIndex(idx)

        # start up an update timer with an interval of 1000ms.  We
        # will use this to check whether it is time for a new random
        # plugin.
        self.timerId = self.startTimer(1000)

        # Read previous state from the settings file
        self.randomModeButton.setChecked(
            self.settings['plugins'].refreshWithDefault('random_mode', False))
        self.manualModeButton.setChecked(
            self.settings['plugins'].refreshWithDefault('manual_mode', True))

        self.videoMode.setChecked(self.settings['video'].refreshWithDefault(
            'videoMode', False))
        self.thresholdSlider.setValue(
            self.settings['video'].refreshWithDefault('threshold', 0.2) * 99)
        self.blurSlider.setValue(
            self.settings['video'].refreshWithDefault('blur', 1.5) * 99 / 5.0)
        self.minAreaSlider.setValue(
            self.settings['video'].refreshWithDefault('minArea', 100) /
            (640 * 480) * 99.0)
        self.maxAreaSlider.setValue(
            self.settings['video'].refreshWithDefault('maxArea', 99.0) /
            (640 * 480) * 99.0)
        self.maxNumSlider.setValue(self.settings['video'].refreshWithDefault(
            'maxNum', 10))

        self.edgeSelection.setCurrentIndex(
            self.settings['video'].refreshWithDefault('edgeDetectionMode', 0))
        self.modeSelection.setCurrentIndex(
            self.settings['video'].refreshWithDefault('contourMode', 1))
        self.methodSelection.setCurrentIndex(
            self.settings['video'].refreshWithDefault('contourMethod', 2))

        self.connect(self.prevButton, QtCore.SIGNAL('clicked()'),
                     self.prevClicked)
        self.connect(self.nextButton, QtCore.SIGNAL('clicked()'),
                     self.nextClicked)
        self.connect(self.randomButton, QtCore.SIGNAL('clicked()'),
                     self.randomClicked)

        self.update()
示例#7
0
    def __init__(self, lux_engine, output_engine, parent=None):
        QtGui.QMainWindow.__init__(self, parent)
        self.settings = LuxSettings()
        self.lux_engine = lux_engine
        self.output_engine = output_engine
        
        # set our title
        self.setWindowIcon(QtGui.QIcon())
        self.setWindowTitle('Fiat Lux')

        # create the display widgets in a QTabView
        self.displayTabWidget = QtGui.QTabWidget(self)
        self.simWidget = SimulationDisplay(self)
        self.displayTabWidget.addTab(self.simWidget, "Laser Output")
        # MacOS X supports video capture using syphon.  Other platforms don't (yet!)
        if sys.platform == "darwin":
            self.videoWidget = VideoDisplay(lux_engine.video_engine, self.displayTabWidget)
            self.displayTabWidget.addTab(self.videoWidget, "Video Input")

        self.displayTabWidget.setVisible(True)
        self.setCentralWidget(self.displayTabWidget)

        self.displayTabWidget.setCurrentIndex(self.settings['main_window'].valueWithDefault('display_tab', 0))
        self.connect(self.displayTabWidget, QtCore.SIGNAL('currentChanged(int)'), self.displayTabChanged)

        # This might be fun someday...
        #        self.ipythonWidget = IPythonConsole(self)
        #        self.setCentralWidget(self.ipythonWidget)
        

        # set up the status bar
        self.statusBar_ = QtGui.QStatusBar(self)
        self.statusLabel = QtGui.QLabel()
        self.statusLabel.setMargin(2)
        self.setStatus() # set a default status
        self.statusBar_.addWidget(self.statusLabel)
        self.setStatusBar(self.statusBar_)

        # setup our actions
        self.streamAction = QtGui.QAction(QtGui.QIcon(self.resource('play.png')),
                                          '&Stream',
                                          self)
        self.streamAction.setShortcut(QtCore.Qt.ALT + QtCore.Qt.Key_S)
        self.streamAction.setToolTip('Start/stop streaming frames from the camera.')
        self.streamAction.setCheckable(True)
        self.streamAction.setEnabled(False)
        # self.connect(self.streamAction,
        #              QtCore.SIGNAL('triggered(bool)'),
        #              self.playTriggered)

        # make a pause icon
        self.pauseAction = QtGui.QAction(QtGui.QIcon(self.resource('pause.png')),
                                          '&Pause',
                                          self)
        self.pauseAction.setShortcut(QtCore.Qt.ALT + QtCore.Qt.Key_P)
        self.pauseAction.setToolTip('Pause/resume streaming frames from the camera.')
        self.pauseAction.setCheckable(True)
        self.pauseAction.setEnabled(False)
        # self.connect(self.pauseAction,
        #              QtCore.SIGNAL('triggered(bool)'),
        #              self.pauseTriggered)

        self.recordAction = QtGui.QAction(QtGui.QIcon(self.resource('record.png')),
                                          '&Record',
                                          self)
        self.recordAction.setShortcut(QtCore.Qt.ALT + QtCore.Qt.Key_R)
        self.recordAction.setToolTip('Record the streamed frames to disk.')
        self.recordAction.setCheckable(True)
        self.recordAction.setEnabled(False)
        # self.connect(self.recordAction,
        #              QtCore.SIGNAL('triggered(bool)'),
        #              self.record)

        self.quitAction = QtGui.QAction('&Quit', self)
        self.quitAction.setShortcut(QtCore.Qt.CTRL + QtCore.Qt.Key_Q)
        self.quitAction.setToolTip('Exit the program.')
        self.connect(self.quitAction,
                     QtCore.SIGNAL('triggered(bool)'),
                     self.close)

        # add radio buttons
        self.displayPrefix = QtGui.QLabel(' View as: ')
        self.displayPrefix.setAlignment(QtCore.Qt.AlignVCenter)
        self.displayRawButton = QtGui.QRadioButton('Raw image')
        self.displayRawButton.setToolTip('Show the raw image, either coming from\nthe camera sensor or loaded from a file.')
        self.displayPinholeButton = QtGui.QRadioButton('Pinhole 3D (reset focus and pan)')
        self.displayPinholeButton.setToolTip('Show the light field as viewed through a pinhole.\nThis resets the focus and pan settings in the Optics tab.') 
        self.displayApertureButton = QtGui.QRadioButton('3D')
        self.displayApertureButton.setToolTip('Show a rendered 3D light field.')

        # self.connect(self.displayRawButton,
        #              QtCore.SIGNAL('clicked()'),
        #              self.emitDisplayModeChanged)
        # self.connect(self.displayPinholeButton,
        #              QtCore.SIGNAL('clicked()'),
        #              self.emitDisplayModeChanged)
        # self.connect(self.displayApertureButton,
        #              QtCore.SIGNAL('clicked()'),
        #              self.emitDisplayModeChanged)

        # set up the toolbars
        # self.controlBar = QtGui.QToolBar(self)
        # self.controlBar.setObjectName('Control Bar')
        # self.controlBar.addAction(self.streamAction)
        # self.controlBar.addAction(self.pauseAction)
        # self.displayBar = QtGui.QToolBar(self)
        # self.displayBar.setObjectName('Display Mode Bar')
        # self.displayBar.addWidget(self.displayPrefix)
        # self.displayBar.addWidget(self.displayRawButton)
        # self.displayBar.addWidget(self.displayPinholeButton)
        # self.displayBar.addWidget(self.displayApertureButton)
        # self.addToolBar(self.controlBar)
        # self.addToolBar(self.displayBar)

        # toolbar view control
        # self.viewControlBarAction = self.controlBar.toggleViewAction()
        # self.viewControlBarAction.setText('&Controls')
        # self.viewDisplayBarAction = self.displayBar.toggleViewAction()
        # self.viewDisplayBarAction.setText('&Display mode')

        # set up the settings panels
        self.settingsManager = SettingsPanelManager(self)
        
        self.settingsManager.add(SettingsPanel(name = "Plugins",
                                               message = "",
                                               widget = PluginSettings.PluginSettings(self,
                                                                                      self.lux_engine)
                                               ))
        self.settingsManager.add(SettingsPanel(name = "Output",
                                               message = "",
                                               widget = OutputSettings.OutputSettings(self,
                                                                                      self.output_engine)
                                               ))
        self. calibrationSettings = CalibrationSettings.CalibrationSettings(self, self.output_engine)
        self.settingsManager.add(SettingsPanel(name = "Calibration",
                                               message = "",
                                               widget = self.calibrationSettings))
        self.connect(self.calibrationSettings,
                     QtCore.SIGNAL('olParamsChanged()'),
                     self.lux_engine.updateOlParams)

        # set up the menu bar
        self.menuBar_ = QtGui.QMenuBar(self)
        self.viewMenu = self.menuBar_.addMenu('&View')
        for action in self.settingsManager.toggleViewActions():
            self.viewMenu.addAction(action)
        self.setMenuBar(self.menuBar_)

        # Load previous window size and position, but set a sensible
        # defaults if those settings aren't available.
        self.move(QtCore.QPoint(40,80))
        self.resize(QtCore.QSize(720,480))

        # load the previous state of the docks and toolbars
        try:
            state = QtCore.QByteArray(self.settings['main_window'].state.decode('hex'))
            self.restoreState(state)
        except AttributeError:
            print "Warning: Could not restore window state."
            # ignore
            pass

        # load window settings
        self.resize(self.settings['main_window'].valueWithDefault('size', self.size()))
        self.move(self.settings['main_window'].valueWithDefault('position', self.pos()))
示例#8
0
    def run(self):

        # Run the render loop.  This will repeatedly render frames of the current plugin.
        print '\t--> Starting up LUX Engine.'
        ftime = 0
        frames = 0

        # Initialize OpenLase.  This also creates the lux_engine jack endpoints.
        if (ol.init(3, 96000) != 0):
            raise Exception("Could not initialize openlase")

        # Connect the output engine to the lux_engine.
        self.output_engine.connect_ports("lux_engine:out_x", "lux_output:in_x")
        self.output_engine.connect_ports("lux_engine:out_y", "lux_output:in_y")
        self.output_engine.connect_ports("lux_engine:out_r", "lux_output:in_r")
        self.output_engine.connect_ports("lux_engine:out_g", "lux_output:in_g")
        self.output_engine.connect_ports("lux_engine:out_b", "lux_output:in_b")

        # Turn off the hardware safety interlock.
        self.output_engine.setOutputInitialized(True)

        # Create a local settings object for this thread.
        settings = LuxSettings()

        while not self.exiting:
            # Grab local references to these class variables
            self.lock.lock()
            current_plugin = self.current_plugin
            video_engine = self.video_engine
            self.lock.unlock()

            # SET PARAMETERS
            #
            # Check to see if the GUI parameter override has been set,
            # and we need to update OL parameters.
            if (self.ol_update_params
                    and settings['calibration'].parameterOverride
                    and current_plugin):
                current_plugin.setParametersToGuiValues()
                self.ol_update_params = False

            if (current_plugin
                    and not settings['calibration'].parameterOverride):
                current_plugin.setParameters()

            if (self.reset_plugin_on_next_frame):
                current_plugin.reset()
                self.reset_plugin_on_next_frame = False

            # RENDER
            #
            # We call out to the current plugin's draw() method, or
            # the video plugin, depending on the current state of the
            # GUI.
            if (current_plugin):
                if (settings['video'].videoMode):
                    # Cause video color cycling to happen
                    ol.loadIdentity3()
                    ol.loadIdentity()
                    ol.perspective(60, 1, 1, 100)
                    ol.translate3((0, 0, -3))

                    ol.color3(*(self.video_color_drift.color_cycle()))
                    video_engine.draw_lasers()
                else:
                    current_plugin.draw()

                frame_render_time = ol.renderFrame(
                    60)  # Takes max_fps as argument
                frames += 1
                ftime += frame_render_time
                #print "Frame time: %f, FPS:%f"%(frame_render_time, frame_render_time/ftime)
            else:
                # If there is no plugin for some reason, kill time
                # rather than burning CPU in a loop that does nothing.
                time.sleep(0.1)
示例#9
0
    def __init__(self, lux_engine, output_engine, parent=None):
        QtGui.QMainWindow.__init__(self, parent)
        self.settings = LuxSettings()
        self.lux_engine = lux_engine
        self.output_engine = output_engine

        # set our title
        self.setWindowIcon(QtGui.QIcon())
        self.setWindowTitle("Fiat Lux")

        # Set tab positions
        self.setTabPosition(QtCore.Qt.LeftDockWidgetArea, QtGui.QTabWidget.South)
        self.setTabPosition(QtCore.Qt.RightDockWidgetArea, QtGui.QTabWidget.South)

        # create the display widgets in a QTabView
        self.displayTabWidget = QtGui.QTabWidget(self)
        self.displayTabWidget.setTabPosition(QtGui.QTabWidget.South)
        self.simWidget = SimulationDisplay(self)
        self.displayTabWidget.addTab(self.simWidget, "Laser Output")

        # MacOS X supports video capture using syphon.  Other platforms don't (yet!)
        if sys.platform == "darwin":
            self.videoWidget = VideoDisplay(lux_engine.video_engine, self.displayTabWidget)
            self.displayTabWidget.addTab(self.videoWidget, "Video Input")

        self.displayTabWidget.setVisible(True)
        self.setCentralWidget(self.displayTabWidget)

        self.displayTabWidget.setCurrentIndex(self.settings["main_window"].valueWithDefault("display_tab", 0))
        self.connect(self.displayTabWidget, QtCore.SIGNAL("currentChanged(int)"), self.displayTabChanged)

        # -----------------------------------------------------------------------
        #                              STATUS BAR
        # -----------------------------------------------------------------------

        # set up the status bar
        self.statusBar_ = QtGui.QStatusBar(self)
        self.statusLabel = QtGui.QLabel()
        self.statusLabel.setMargin(2)
        self.setStatus()  # set a default status
        self.statusBar_.addWidget(self.statusLabel)
        self.setStatusBar(self.statusBar_)

        self.quitAction = QtGui.QAction("&Quit", self)
        self.quitAction.setShortcut(QtCore.Qt.CTRL + QtCore.Qt.Key_Q)
        self.quitAction.setToolTip("Exit the program.")
        self.connect(self.quitAction, QtCore.SIGNAL("triggered(bool)"), self.close)

        # -----------------------------------------------------------------------
        #                              SETTINGS PANELS
        # -----------------------------------------------------------------------

        self.settingsManager = SettingsPanelManager(self)

        self.settingsManager.add(
            SettingsPanel(name="Plugins", message="", widget=PluginSettings.PluginSettings(self, self.lux_engine))
        )
        self.settingsManager.add(
            SettingsPanel(name="Output", message="", widget=OutputSettings.OutputSettings(self, self.output_engine))
        )
        self.calibrationSettings = CalibrationSettings.CalibrationSettings(self, self.output_engine)
        self.settingsManager.add(SettingsPanel(name="Calibration", message="", widget=self.calibrationSettings))
        self.connect(self.calibrationSettings, QtCore.SIGNAL("olParamsChanged()"), self.lux_engine.updateOlParams)

        # -----------------------------------------------------------------------
        #                              MENU BAR
        # -----------------------------------------------------------------------

        self.menuBar_ = QtGui.QMenuBar(self)
        self.viewMenu = self.menuBar_.addMenu("&View")
        for action in self.settingsManager.toggleViewActions():
            self.viewMenu.addAction(action)
        self.setMenuBar(self.menuBar_)

        # Load previous window size and position, but set a sensible
        # defaults if those settings aren't available.
        self.move(QtCore.QPoint(40, 80))
        self.resize(QtCore.QSize(720, 480))

        # load the previous state of the docks and toolbars
        try:
            state = QtCore.QByteArray(self.settings["main_window"].state.decode("hex"))
            self.restoreState(state)
        except AttributeError:
            print "Warning: Could not restore window state."
            # ignore
            pass

        # load window settings
        self.resize(self.settings["main_window"].valueWithDefault("size", self.size()))
        self.move(self.settings["main_window"].valueWithDefault("position", self.pos()))