Skip to main content
Engineering LibreTexts

9.2: Presentation, Transmission and Ports

  • Page ID
    43709
  • \( \newcommand{\vecs}[1]{\overset { \scriptstyle \rightharpoonup} {\mathbf{#1}} } \) \( \newcommand{\vecd}[1]{\overset{-\!-\!\rightharpoonup}{\vphantom{a}\smash {#1}}} \)\(\newcommand{\id}{\mathrm{id}}\) \( \newcommand{\Span}{\mathrm{span}}\) \( \newcommand{\kernel}{\mathrm{null}\,}\) \( \newcommand{\range}{\mathrm{range}\,}\) \( \newcommand{\RealPart}{\mathrm{Re}}\) \( \newcommand{\ImaginaryPart}{\mathrm{Im}}\) \( \newcommand{\Argument}{\mathrm{Arg}}\) \( \newcommand{\norm}[1]{\| #1 \|}\) \( \newcommand{\inner}[2]{\langle #1, #2 \rangle}\) \( \newcommand{\Span}{\mathrm{span}}\) \(\newcommand{\id}{\mathrm{id}}\) \( \newcommand{\Span}{\mathrm{span}}\) \( \newcommand{\kernel}{\mathrm{null}\,}\) \( \newcommand{\range}{\mathrm{range}\,}\) \( \newcommand{\RealPart}{\mathrm{Re}}\) \( \newcommand{\ImaginaryPart}{\mathrm{Im}}\) \( \newcommand{\Argument}{\mathrm{Arg}}\) \( \newcommand{\norm}[1]{\| #1 \|}\) \( \newcommand{\inner}[2]{\langle #1, #2 \rangle}\) \( \newcommand{\Span}{\mathrm{span}}\)\(\newcommand{\AA}{\unicode[.8,0]{x212B}}\)

    This section gives a realistic example and details the Glamour framework.

    Running example

    In the following tutorial we will be creating a simple Smalltalk class navigator. Such navigators are used in many Smalltalk browsers and usually consist of four panes, which are abstractly depicted in figure Figure \(\PageIndex{1}\).

    The class navigator functions as follows: Pane 1 shows a list or a tree of packages, each package containing classes, which make up the organizational structure of the environment. When a package is selected, pane 2 shows a list of all classes in the selected package. When a class is selected, pane 3 shows all protocols (a construct to group methods also known as method categories) and all methods of the class are shown on pane 4. When a protocol is selected in pane 3, only the subset of methods that belong to that protocol are displayed on pane 4.

    Wirefram representation of the navigator.
    Figure \(\PageIndex{1}\): Wireframe representation of a Smalltalk class navigator.

    Starting the Browser

    We build the browser iteratively and gradually introduce new constructs of Glamour. To start with, we simply want to open a new browser on the list of packages. Because the example is going to involve more code than the previous file browser, we are going to implement the code browser in a dedicated class.

    The first step is then to create the class with some initial methods:

    Object subclass: #PBE2CodeNavigator
        instanceVariableNames: 'browser'
        classVariableNames: ''
        poolDictionaries: ''
        category: 'PBE2-CodeBrowser'
    
    PBE2CodeNavigator class>>open
        ^ self new open
    
    PBE2CodeNavigator>>open
        self buildBrowser.
        browser openOn: self organizer.
    
    PBE2CodeNavigator>>organizer
        ^ RPackageOrganizer default
    
    PBE2CodeNavigator>>buildBrowser
        browser := GLMTabulator new.
    

    Executing PBE2CodeNavigator open opens a new browser with the text “a RPackageOrganizer” and nothing else. Note that we now use the GLMTabulator class to create our browser. A GLMTabulator is an explicit browser that allows us to place panes in columns and rows.

    We now extend our browser with a new pane to display a list of packages.

    PBE2CodeNavigator>>buildBrowser
        browser := GLMTabulator new.
        browser
            column: #packages.
    
        browser transmit to: #packages; andShow: [:a | self packagesIn: a].
    
    PBE2CodeNavigator>>packagesIn: constructor
        constructor list
            display: [:organizer | organizer packageNames sorted];
            format: #asString
    

    Glamour browsers are composed in terms of panes and the flow of data between them. In our browser we currently have only one pane displaying packages. The flow of data is specified by means of transmissions. These are triggered when certain changes in the browser graphical user interface occur, such as an item selection in a list. We make our browser more useful by displaying classes contained in the selected package (see Figure \(\PageIndex{2}\)).

    PBE2CodeNavigator>>buildBrowser
        browser := GLMTabulator new.
        browser
            column: #packages;
            column: #classes.
    
        browser transmit to: #packages; andShow: [:a | self packagesIn: a].
        browser transmit from: #packages; to: #classes; andShow: [:a | self classesIn: a].
    
    PBE2CodeNavigator>>classesIn: constructor
        constructor list
            display: [:packageName | (self organizer packageNamed: packageName)
                definedClasses]
    

    The listing above shows almost all of the core language constructs of Glamour. Since we want to be able to reference the panes later, we give them the distinct names “packages” and “classes” and arrange them in columns using the column: keyword. Similarly, a row: keyword exists with which panes can be organized in rows.

    Two-pane browser.
    Figure \(\PageIndex{2}\): Two-pane browser. When a package is selected in the left pane, the contained classes are shown on the right pane.

    The transmit:, to: and from: keywords create a transmission—a directed connection that defines the flow of information from one pane to another. In this case, we create a link from the packages pane to the classes pane. The from: keyword signifies the origin of the transmission and to: the destination. If nothing more specific is stated, Glamour assumes that the origin refers to the selection of the specified pane. We show how to specify other aspects of the origin pane and how to use multiple origins below.

    Finally, the andShow: specifies what to display on the destination pane when the connection is activated or transmitted. In our example, we want to show a list of the classes that are contained in the selected package.

    The display: keyword simply stores the supplied block within the presentation. The blocks will only be evaluated later, when the presentation should be displayed on-screen. If no explicit display block is specified, Glamour attempts to display the object in some generic way. In the case of list presentations, this means that the displayString message is sent to the object to retrieve a standard string representation. As we have previously seen, format: is used to change this default behavior.

    Along with display:, it is possible to specify a when: condition to limit the applicability of the connection. By default, the only condition is that an item is in fact selected, i.e., that the display variable argument is not null.

    Another Presentation

    So far, packages are visually represented as a flat list. However, packages are naturally structured with the corresponding class category. To exploit this structure, we replace the list with a tree presentation for packages:

    PBE2CodeNavigator>>packagesIn: constructor
        constructor tree
            display: [ :organizer | (self rootPackagesOn: organizer) asSet sorted ];
            children: [ :rootPackage :organizer | (self childrenOf: rootPackage on: organizer)
                sorted ];
            format: #asString
    
    PBE2CodeNavigator>>classesIn: constructor
        constructor list
        when: [:packageName | self organizer includesPackageNamed: packageName ];
        display: [:packageName | (self organizer packageNamed: packageName)
            definedClasses]
    
    PBE2CodeNavigator>>childrenOf: rootPackage on: organizer
        ^ organizer packageNames select: [ :name | name beginsWith: rootPackage , '-' ]
    
    PBE2CodeNavigator>>rootPackagesOn: organizer
        ^ organizer packageNames collect: [ :string | string readStream upTo: $- ] 
    

    The tree presentation uses a children: argument that takes a selector or a block to specify how to retrieve the children of a given item in the tree. Since the children of each package are now selected by our tree presentation, we have to pass only the roots of the package hierarchy to the display: argument.

    At this point, we can also add Pane 3 to list the method categories (Figure \(\PageIndex{3}\)). The listing below introduces no new elements that we have not already discussed:

    PBE2CodeNavigator>>buildBrowser
        browser := GLMTabulator new.
        browser
            column: #packages;
            column: #classes;
            column: #categories.
    
        browser transmit to: #packages; andShow: [:a | self packagesIn: a].
        browser transmit from: #packages; to: #classes; andShow: [:a | self classesIn: a].
        browser transmit from: #classes; to: #categories; andShow: [:a | self categoriesIn: a].
    
    PBE2CodeNavigator>>categoriesIn: constructor
        constructor list
            display: [:class | class organization categories] 
    

    The browser resulting from the above changes is shown in figure Figure \(\PageIndex{3}\).

    Improved class navigator.
    Figure \(\PageIndex{3}\): Improved class navigator including a tree to display the packages and a list of method categories for the selected class.

    Multiple Origins

    Adding the list of methods as Pane 4 involves slightly more machinery. When a method category is selected we want to show only the methods that belong to that category. If no category is selected, all methods that belong to the current class are shown.

    This leads to our methods pane depending on the selection of two other panes, the class pane and the category pane. Multiple origins can be defined using multiple from: keywords as shown below.

    PBE2CodeNavigator>>buildBrowser
        browser := GLMTabulator new.
        browser
            column: #packages;
            column: #classes;
            column: #categories;
            column: #methods.
    
        browser transmit to: #packages; andShow: [:a | self packagesIn: a].
        browser transmit from: #packages; to: #classes; andShow: [:a | self classesIn: a].
        browser transmit from: #classes; to: #categories; andShow: [:a | self categoriesIn: a].
        browser transmit from: #classes; from: #categories; to: #methods;
            andShow: [:a | self methodsIn: a].
    
    PBE2CodeNavigator>>methodsIn: constructor
        constructor list
            display: [:class :category |
                (class organization listAtCategoryNamed: category) sorted].
        constructor list
            when: [:class :category | class notNil and: [category isNil]];
            display: [:class | class selectors sorted];
            allowNil 
    

    The listing shows a couple of new properties. First, the multiple origins are reflected in the number of arguments of the blocks that are used in the display: and when: clauses. Secondly, we are using more than one presentation—Glamour shows all presentations whose conditions match in the order that they were defined when the corresponding transmission is fired.

    In the first presentation, the condition matches when all arguments are defined (not null), this is the default for all presentations. The second condition matches only when the category is undefined and the class defined. When a presentation must be displayed even in the presence of an undefined origin, it is necessary to use allowNil as shown. We can therefore omit the category from the display block.

    The completed class navigator is displayed in Figure \(\PageIndex{4}\).

    Complete code navigator.
    Figure \(\PageIndex{4}\): Complete code navigator. If no method category is selected, all methods of the class are displayed. Otherwise, only the methods that belong to that category are shown.

    Ports

    When we stated that transmissions connect panes this was not entirely correct. More precisely, transmissions are connected to properties of panes called ports. Such ports consist of a name and a value which accommodates a particular aspect of state of the pane or its contained presentations. If the port is not explicitly specified by the user, Glamour uses the selection port by default. As a result, the following two statements are equivalent:

    browser transmit from: #packages; to: #classes; andShow: [:a | ...].
    browser transmit from: #packages port: #selection; to: #classes; andShow: [:a | ...]. 
    

    This page titled 9.2: Presentation, Transmission and Ports is shared under a CC BY-SA 3.0 license and was authored, remixed, and/or curated by Alexandre Bergel, Damien Cassou, Stéphane Ducasse, Jannik Laval (Square Bracket Associates) via source content that was edited to the style and standards of the LibreTexts platform; a detailed edit history is available upon request.