Exemple #1
0
def makeDisplayContext(namespace, splash):
    """Creates the top-level *FSLeyes* :class:`.DisplayContext` and
    :class:`.OverlayList` .

    This function does the following:

     1. Creates the :class:`.OverlayList` and the top level
        :class:`.DisplayContext`.

     2. Loads and configures all of the overlays which were passed in on the
        command line.

    :arg namesace: Parsed command line arguments (see :func:`parseArgs`).

    :arg splash:   The :class:`.FSLeyesSplash` frame, created in :func:`init`.

    :returns: a tuple containing:
                - the :class:`.OverlayList`
                - the master :class:`.DisplayContext`
    """

    import fsleyes_widgets.utils.status as status
    import fsleyes.overlay as fsloverlay
    import fsleyes.parseargs as parseargs
    import fsleyes.displaycontext as displaycontext

    # Splash status update must be
    # performed on the main thread.
    def splashStatus(msg):
        wx.CallAfter(splash.SetStatus, msg)

    # Redirect status updates
    # to the splash frame
    status.setTarget(splashStatus)

    # Create the overlay list (only one of these
    # ever exists) and the master DisplayContext.
    # A new DisplayContext instance will be
    # created for every new view that is opened
    # in the FSLeyesFrame, but all child
    # DisplayContext instances will be linked to
    # this master one.
    overlayList = fsloverlay.OverlayList()
    displayCtx = displaycontext.DisplayContext(overlayList)

    log.debug('Created overlay list and master DisplayContext ({})'.format(
        id(displayCtx)))

    # Load the images - the splash screen status will
    # be updated with the currently loading overlay name.
    parseargs.applyMainArgs(namespace, overlayList, displayCtx)
    parseargs.applyOverlayArgs(namespace, overlayList, displayCtx)

    return overlayList, displayCtx
Exemple #2
0
def test_clearStatus():
    target = MockTarget()
    status.setTarget(target)

    status.update('Status1', None)
    assert target.msg == 'Status1'
    status.clearStatus()
    assert target.msg == ''

    status.update('Status1', 0.25)
    assert target.msg == 'Status1'
    status.clearStatus()
    assert target.msg == ''
Exemple #3
0
def test_update():

    # Test without a target
    status.setTarget(None)
    status.update('Status')

    target = MockTarget()

    status.setTarget(target)

    assert target.msg is None
    status.update('Status1', None)
    assert target.msg == 'Status1'
    status.update('Status2', None)
    assert target.msg == 'Status2'
def test_ClearThread_die():
    target = MockTarget()
    status.setTarget(target)

    # make sure the clearthread is running
    status.update('Status1', 1.0)
    time.sleep(1.1)

    # and can be killed
    status._clearThread.die()
    status._clearThread.clear(0.1)
    status._clearThread.join()
    status._clearThread = None

    # and then gets restarted again
    status.update('Status1', 0.25)
    assert target.msg == 'Status1'
    time.sleep(0.5)
    assert target.msg == ''
Exemple #5
0
def test_update_timeout():

    status.setTarget(None)
    status.clearStatus()

    target = MockTarget()
    status.setTarget(target)

    # Test that the message gets cleared
    status.update('Status1', 0.25)
    assert target.msg == 'Status1'
    time.sleep(0.5)
    assert target.msg == ''

    # If a timed update is followed by an untimed
    # update, the untimed one should persist
    status.update('Status2', 0.25)
    status.update('Status3', None)
    time.sleep(0.5)
    assert target.msg == 'Status3'
Exemple #6
0
def run_with_fsleyes(func, *args, **kwargs):
    """Create a ``FSLeyesFrame`` and run the given function. """

    from fsl.utils.platform import platform as fslplatform
    import fsleyes_widgets.utils.status as status

    fsleyes.configLogging()

    gc.collect()
    idle.idleLoop.reset()
    idle.idleLoop.allowErrors = True

    propagateRaise = kwargs.pop('propagateRaise', True)
    startingDelay = kwargs.pop('startingDelay', 500)
    finishingDelay = kwargs.pop('finishingDelay', 5)
    callAfterApp = kwargs.pop('callAfterApp', None)

    class State(object):
        pass

    state = State()
    state.result = None
    state.raised = None
    state.frame = None
    state.app = None
    state.dummy = None
    state.panel = None

    glver = os.environ.get('FSLEYES_TEST_GL', '2.1')
    glver = [int(v) for v in glver.split('.')]

    def init():
        fsleyes.initialise()
        props.initGUI()
        colourmaps.init()
        initialised[0] = True
        fslgl.bootstrap(glver)
        wx.CallAfter(run)

    def finish():
        state.frame.Close(askUnsaved=False, askLayout=False)
        state.dummy.Close()
        waitUntilIdle()
        realYield(100)
        state.app.ExitMainLoop()

    def run():

        overlayList = fsloverlay.OverlayList()
        displayCtx = dc.DisplayContext(overlayList)
        state.frame = fslframe.FSLeyesFrame(None, overlayList, displayCtx)

        state.app.SetOverlayListAndDisplayContext(overlayList, displayCtx)
        state.app.SetTopWindow(state.frame)

        state.frame.Show()

        try:
            if func is not None:
                state.result = func(state.frame, overlayList, displayCtx,
                                    *args, **kwargs)

        except Exception as e:
            traceback.print_exc()
            state.raised = e

        finally:
            wx.CallLater(finishingDelay, finish)

    state.app = fslmain.FSLeyesApp()
    state.dummy = wx.Frame(None)
    state.panel = wx.Panel(state.dummy)
    state.sizer = wx.BoxSizer(wx.HORIZONTAL)
    state.sizer.Add(state.panel, flag=wx.EXPAND, proportion=1)
    state.dummy.SetSizer(state.sizer)

    if callAfterApp is not None:
        callAfterApp()

    state.dummy.SetSize((100, 100))
    state.dummy.Layout()
    state.dummy.Show()

    if not initialised[0]:

        # gl already initialised
        if fslplatform.glVersion is not None:
            wx.CallLater(startingDelay, init)
        else:
            wx.CallLater(startingDelay,
                         fslgl.getGLContext,
                         ready=init,
                         raiseErrors=True)
    else:
        wx.CallLater(startingDelay, run)

    with exitMainLoopOnError(state.app) as err:
        state.app.MainLoop()

    status.setTarget(None)
    if status._clearThread is not None:
        status._clearThread.die()
        status._clearThread.clear(0.01)
        status._clearThread.join()
        status._clearThread = None

    raised = state.raised
    result = state.result

    if err[0] is not None:
        raise err[0]

    time.sleep(1)

    if raised and propagateRaise:
        raise raised

    return result
Exemple #7
0
def makeDisplayContext(namespace, splash):
    """Creates the top-level *FSLeyes* :class:`.DisplayContext` and
    :class:`.OverlayList` .

    This function does the following:

     1. Creates the :class:`.OverlayList` and the top level
        :class:`.DisplayContext`.

     2. Loads and configures all of the overlays which were passed in on the
        command line.

    :arg namesace: Parsed command line arguments (see :func:`parseArgs`).

    :arg splash:   The :class:`.FSLeyesSplash` frame, created in :func:`init`.

    :returns: a tuple containing:
                - the :class:`.OverlayList`
                - the master :class:`.DisplayContext`
    """

    import fsleyes_widgets.utils.status as status
    import fsleyes.overlay as fsloverlay
    import fsleyes.parseargs as parseargs
    import fsleyes.displaycontext as displaycontext

    # Splash status update must be
    # performed on the main thread.
    def splashStatus(msg):
        wx.CallAfter(splash.SetStatus, msg)

    # Redirect status updates
    # to the splash frame
    status.setTarget(splashStatus)

    # Create the overlay list (only one of these
    # ever exists) and the master DisplayContext.
    # A new DisplayContext instance will be
    # created for every new view that is opened
    # in the FSLeyesFrame, but all child
    # DisplayContext instances will be linked to
    # this master one.
    overlayList = fsloverlay.OverlayList()
    displayCtx = displaycontext.DisplayContext(overlayList)

    # While the DisplayContext may refer to
    # multiple overlay groups, we are currently
    # using just one, allowing the user to specify
    # a set of overlays for which their display
    # properties are 'locked'.
    lockGroup = displaycontext.OverlayGroup(displayCtx, overlayList)
    displayCtx.overlayGroups.append(lockGroup)

    log.debug('Created overlay list and master DisplayContext ({})'.format(
        id(displayCtx)))

    # Load the images - the splash screen status will
    # be updated with the currently loading overlay name.
    #
    # The applyOverlayArgs function gets called before
    # the applySceneArgs function, so we'll manually
    # apply some important settings to the DC here so
    # they get used when any overlays are loaded.
    if namespace.bigmem is not None:
        displayCtx.loadInMemory = namespace.bigmem
    if namespace.autoDisplay is not None:
        displayCtx.autoDisplay = namespace.autoDisplay

    parseargs.applyOverlayArgs(namespace, overlayList, displayCtx)

    return overlayList, displayCtx