# Display

This module implements a simple visual display system modeled on Oberon.

Refer to Chapter 4 of the Project Oberon book for more information.

There is a Display object that manages a pygame surface and N vertical tracks each of which manages zero or more viewers.

class `joy.vui.display.``Display`(screen, lookup, *track_ratios)

  Manage tracks and viewers on a screen (Pygame surface.)

  The size and number of tracks are defined by passing in at least two ratios, e.g. Display(screen, 1, 4, 4) would create three tracks, one small one on the left and two larger ones of the same size, each four times wider than the left one.

  All tracks take up the whole height of the display screen. Tracks manage zero or more Viewers. When you “grow” a viewer a new track is created that overlays or hides one or two existing tracks, and when the last viewer in an overlay track is closed the track closes too and reveals the hidden tracks (and their viewers, if any.)

  In order to facilitate command underlining while mouse dragging the lookup parameter must be a function that accepts a string and returns a Boolean indicating whether that string is a valid Joy function name. Typically you pass in the __contains__ method of the Joy dict. This is a case of breaking “loose coupling” to gain efficiency, as otherwise we would have to e.g. send some sort of lookup message to the World context object, going through the whole Display.broadcast() machinery, etc. Not something you want to do on each MOUSEMOTION event.

  `at`(x, y)

    Return the viewer (which can be a Track) at the x, y location, along with the relative-to-viewer-surface x and y coordinates. If there is no viewer at the location the Track will be returned instead.

  `broadcast`(message)

    Broadcast a message to all viewers (except the sender) and all registered handlers.

  `change_viewer`(viewer, y, relative=False)

    Adjust the top of the viewer to a new y within the boundaries of its neighbors.

    If relative is False new_y should be in screen coords, else new_y should be relative to the top of the viewer.

  `close_viewer`(viewer)

    Close the viewer.

  `dispatch_event`(event)

    Display event handling.

  `done_resizing`()

    Helper method called directly by `MenuViewer.mouse_up()` to (hackily) update the display when done resizing a viewer.

  `focus`(viewer)

    Set system focus to a given viewer (or no viewer if a track.)

  `grow_viewer`(viewer)

    Cause the viewer to take up its whole track or, if it does already, take up another track, up to the whole screen.

    This is the inverse of closing a viewer. “Growing” a viewer actually creates a new copy and a new track to hold it. The old tracks and viewers are retained, and they get restored when the covering track closes, which happens automatically when the last viewer in the covering track is closed.

  `init_text`(pt, x, y, filename)

    Open and return a `TextViewer` on a given file (which must be present in the `JOYHOME` directory.)

  `iter_viewers`()

    Iterate through all viewers yielding (viewer, x, y) three-tuples. The x and y coordinates are screen pixels of the top-left corner of the viewer.

  `open_viewer`(x, y, class_)

    Open a viewer of class_ at the x, y location on the display, return the viewer.

  `redraw`()

    Redraw all tracks (which will redraw all viewers.)

class `joy.vui.display.``Track`(surface)

  Manage a vertical strip of the display, and the viewers on it.

  `broadcast`(message)

    Broadcast a message to all viewers on this track (except the sender.)

  `change_viewer`(viewer, new_y, relative=False)

    Adjust the top of the viewer to a new y within the boundaries of its neighbors.

    If relative is False new_y should be in screen coords, else new_y should be relative to the top of the viewer.

  `close_viewer`(viewer)

    Close the viewer, reuse the freed space.

  `draw`(rect=None)

    Draw the track onto its surface, clearing all content.

    If rect is passed only draw to that area. This supports e.g. closing a viewer that then exposes part of the track.

  `open_viewer`(y, class_)

    Open and return a viewer of class at y.

  `redraw`()

    Redraw the track and all of its viewers.

  `split`(y)

    Split the Track at the y coordinate and return the height available for a new viewer. Tracks manage a vertical strip of the display screen so they don’t resize their surface when split.

  `viewer_at`(y)

    Return the viewer at y along with the viewer-relative y coordinate, if there’s no viewer at y return this track and y.