UIBuilder.st
author ca
Mon, 05 Jan 1998 16:46:07 +0100
changeset 751 56a83a3b210c
parent 734 f1079f443a75
child 775 9d9995bf31a3
permissions -rw-r--r--
add isEditing; set to true if running UIPainter

"
 COPYRIGHT (c) 1995 by Claus Gittinger
              All Rights Reserved

 This software is furnished under a license and may be used
 only in accordance with the terms of that license and with the
 inclusion of the above copyright notice.   This software may not
 be provided or otherwise made available to, or used by, any
 other person.  No title to or ownership of the software is
 hereby transferred.
"

WindowBuilder subclass:#UIBuilder
	instanceVariableNames:'view currentMenuSelector spec specStack composite lastComponent
		compositeView menuBar isEditing'
	classVariableNames:'Verbose'
	poolDictionaries:''
	category:'Interface-Support-UI'
!

!UIBuilder class methodsFor:'documentation'!

copyright
"
 COPYRIGHT (c) 1995 by Claus Gittinger
              All Rights Reserved

 This software is furnished under a license and may be used
 only in accordance with the terms of that license and with the
 inclusion of the above copyright notice.   This software may not
 be provided or otherwise made available to, or used by, any
 other person.  No title to or ownership of the software is
 hereby transferred.
"
!

documentation
"
    this class will (eventually) allow parsing windowSpecs as
    created by ST-80's UIPainter, and thereby allow to run applications
    built with this tool.
    It also provides some rudimentary support for building interfaces
    programatically, by using #newComposite .. #add: .. #endComposite.
    This has been added for ST80-compatibility - we do not recommend using
    that for new ST/X programs.

    It was created to allow execution of PD applications which were
    written using that tool (and more and more are appearing ...).

    The class is not completed yet and certainly not bug free.
    Also, it is not guaranteed that all winSpecs are understood.

    Notice: 
        this class was implemented using protocol information
        from alpha testers, literature and by reading public domain code
        - it may not be complete or compatible to
        the corresponding ST-80 class. 
        If you encounter any incompatibilities, please forward a note 
        describing the incompatibility verbal (i.e. no code) to the ST/X team.

    [author:]
        Claus Gittinger
"
! !

!UIBuilder class methodsFor:'initialization'!

initialize
    Verbose := false    "/ debugging flag
! !

!UIBuilder methodsFor:'ST80 compatibility'!

wrapper
    "ST/X has no wrappers - return the view here"

    ^ view

    "Created: / 3.3.1997 / 18:28:31 / cg"
    "Modified: / 31.10.1997 / 18:42:52 / cg"
! !

!UIBuilder methodsFor:'accessing'!

isEditing
    "true if build from a GUI builder resource ( UIPainter, ... ); if true, no
     models or actions should be set (no application is running)
    "
    ^ isEditing ? false
!

isEditing:aState
    "true if build from a GUI builder resource ( UIPainter, ... ); if true, no
     models or actions should be set (no application is running)
    "
    isEditing := aState
!

menuAt:aKey
    "Find a binding for the menu named aKey, either in the bindings 
     or from the source"

    | menu |

    menu := self bindingAt:aKey.
    menu isNil ifTrue:[
        menu := self safelyPerform:#menuFor: with:aKey.
        menu isNil ifTrue:[
            menu := self safelyPerform:aKey
        ].
        menu := menu value.

        (application notNil and:[menu notNil]) ifTrue:[
            menu isArray ifTrue:[
                menu := Menu new fromLiteralArrayEncoding:menu.
                menu receiver:application.
                ^ menu
            ].
            menu findGuiResourcesIn:application
        ]
    ].
    ^ menu

    "Modified: / 30.10.1997 / 20:37:14 / cg"
!

menuAt:aSymbol put:someMenuOrHolder
    "add someMenuOrHolder as the binding for the menu named aSymbol to the bindings"

    ^ self aspectAt:aSymbol put:someMenuOrHolder

    "Modified: / 30.10.1997 / 20:32:51 / cg"
!

menuBar
    "return the value of the instance variable 'menuBar' (automatically generated)"

    ^ menuBar

    "Created: / 27.10.1997 / 16:30:12 / cg"
!

menuBar:something
    "set the value of the instance variable 'menuBar' (automatically generated)"

    menuBar := something.

    "Created: / 27.10.1997 / 16:30:13 / cg"
! !

!UIBuilder methodsFor:'building'!

buildFromSpec:aSpecOrSpecArray
    |m spec|

    window notNil ifTrue:[
        ^ self buildFromSpec:aSpecOrSpecArray in:window
    ].

    spec := UISpecification from:aSpecOrSpecArray.
    window := spec buildViewFor:self.

    ^ window

    "Modified: / 5.9.1995 / 21:43:29 / claus"
    "Modified: / 31.10.1997 / 18:41:14 / cg"
!

buildFromSpec:aSpecArray in:aView
    |m spec|

    spec := UISpecification from:aSpecArray.
    ^ spec buildViewFor:self in:aView.

    "Modified: 3.3.1997 / 18:44:02 / cg"
!

doFinalHookup

    "Created: 14.2.1997 / 14:52:27 / cg"
!

newSubBuilder
    |builder|

    builder := UIBuilder new.

    builder isEditing:isEditing.
    builder bindings:(self bindings).
    builder application:(self application).
  ^ builder
! !

!UIBuilder methodsFor:'building - programatically'!

add:aSpec
    |collectedComponents|

    composite notNil ifTrue:[
        (collectedComponents := composite collection) isNil ifTrue:[
            composite collection:(collectedComponents := OrderedCollection new).
        ].
        collectedComponents add:aSpec.
        view := aSpec buildViewWithLayoutFor:self in:compositeView.
    ] ifFalse:[
        spec isNil ifTrue:[
            spec := FullSpec new.
        ].

        (aSpec isMemberOf:WindowSpec) ifTrue:[
            spec window:aSpec
        ] ifFalse:[
            ((aSpec isMemberOf:ComponentSpec)
            or:[(aSpec isMemberOf:SpecCollection)]) ifTrue:[
                spec component:aSpec.

                window isNil ifTrue:[
                    window := windowView := StandardSystemView new.
                    window extent:300@300.
                ].
                aSpec buildViewWithLayoutFor:self in:window.
"/ builder window displayBox
                composite := aSpec.
                compositeView := window.
            ] ifFalse:[
                spec component isNil ifTrue:[
                    spec component:SpecCollection new.
                    spec component collection:OrderedCollection new.
                ].
                composite := spec component.
                window isNil ifTrue:[
                    window := windowView := StandardSystemView new.
                    window extent:300@300.
                ].
                compositeView := window.
                spec component collection add:aSpec.
                view := aSpec buildViewWithLayoutFor:self in:compositeView.
            ].
        ]
    ].

    lastComponent := view.
    ^ view

    "Modified: / 1.11.1997 / 02:48:38 / cg"
!

endComposite
    |entry finishedComposite finishedView|

    (specStack notNil and:[specStack notEmpty]) ifTrue:[
        finishedComposite := composite.
        finishedView := compositeView.  

        "/ pop
        entry := specStack removeLast.
        composite := entry key.
        compositeView := entry value.

        lastComponent := finishedView.
        ^ finishedComposite
    ].
    self halt.
    ^ composite

    "Created: / 3.3.1997 / 17:17:43 / cg"
    "Modified: / 30.10.1997 / 23:28:04 / cg"
!

endCompositeLayout:layout
    composite compositeSpec isNil ifTrue:[
        composite compositeSpec:(CompositeSpec new).
    ].
    composite compositeSpec layout:layout.
    compositeView layout:layout.
    self endComposite

    "Modified: / 30.10.1997 / 23:10:10 / cg"
!

endCompositeLayout:layout properties:props
    self endCompositeLayout:layout

    "Created: 3.3.1997 / 22:15:17 / cg"
!

newComposite
    |newComposite|

    "/ push the composite being built ...
    specStack isNil ifTrue:[
        specStack := OrderedCollection new
    ].
    specStack addLast:(composite->compositeView).

    "/ start creating a new one ...
    newComposite := CompositeSpecCollection new.
    newComposite compositeSpec:(CompositeSpec new).
    compositeView := self add:newComposite.
    composite := newComposite.
    ^ compositeView

    "Created: / 3.3.1997 / 17:15:36 / cg"
    "Modified: / 1.11.1997 / 02:48:44 / cg"
! !

!UIBuilder methodsFor:'initialization'!

setupWindowFor:aView
    |ext|

    window notNil ifTrue:[
        ext := window extent.

        ((window isMemberOf:View)
        or:[window isMemberOf:SimpleView]) ifTrue:[

windowView ~~ window ifTrue:[
    windowView isNil ifTrue:[
        self halt:'debug halt - should not happen'
    ]
].
            aView addSubView:window.
        ].
    ].

    window := aView.

    aView container isNil ifTrue:[
        spec notNil ifTrue:[
            spec window setupView:window for:self
        ]
    ].

    "Modified: 17.6.1997 / 18:03:54 / cg"
! !

!UIBuilder class methodsFor:'documentation'!

version
    ^ '$Header: /cvs/stx/stx/libview2/UIBuilder.st,v 1.30 1998-01-05 15:46:07 ca Exp $'
! !
UIBuilder initialize!