WinBuilder.st
author ca
Mon, 03 Mar 1997 11:14:14 +0100
changeset 473 9ef922391c70
parent 467 8fb5fa11956c
child 475 fd94f2bc8b9e
permissions -rw-r--r--
nil aspect

"
 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.
"

Object subclass:#WindowBuilder
	instanceVariableNames:'window application bindings focusSequence namedComponents
		componentCreationHook applicationClass'
	classVariableNames:''
	poolDictionaries:''
	category:'Interface-Support-UI'
!

!WindowBuilder 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
"
    a no-op class, for systems which do not use the UIBuilder.
    Concrete subclasses know how to create a view (with components) from
    some interface spec. Currently, an experimantal version of UIBuilder exists,
    and more may be added in the future (for example, to parse different UI
    specs - thinking of motifs UIL specs etc).

    [author:]
        Claus Gittinger
"
! !

!WindowBuilder methodsFor:'accessing'!

addBindings:moreBindings
    "used with subDialogs, which provide local bindings.
     All bindings from moreBindings overwrite any local bindings."

    moreBindings notNil ifTrue:[
        moreBindings keysAndValuesDo:[:aKey :aValue |
            bindings at:aKey put:aValue
        ]
    ]

    "Created: 28.2.1997 / 14:14:33 / cg"
!

application
    "return the application (an ApplicationModel),
     for which the view is built.
     This one is supposed to provide the aspects, menus etc."

    ^ application

    "Modified: 17.1.1997 / 19:04:40 / cg"
!

application:anApplicationModel
    "set the application (an ApplicationModel),
     for which the view is built.
     This one is supposed to provide the aspects, menus etc."

    application := anApplicationModel

    "Modified: 17.1.1997 / 19:04:47 / cg"
!

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

    applicationClass := something.!

aspectAt:aSymbol
    |b|

    aSymbol notNil ifTrue:[
        bindings notNil ifTrue:[
            b := bindings at:aSymbol ifAbsent:nil.
            b notNil ifTrue:[^ b].
        ].

        application notNil ifTrue:[
            Object messageNotUnderstoodSignal catch:[
                ^ application aspectFor:aSymbol
            ]
        ]
    ].
    ^ nil

    "Modified: 17.1.1997 / 19:28:32 / cg"
!

aspectAt:aSymbol put:aModel
    bindings isNil ifTrue:[
        bindings := IdentityDictionary new
    ].
    ^ bindings at:aSymbol put:aModel

    "Modified: 17.1.1997 / 19:28:37 / cg"
!

bindingAt:aSymbol
    bindings notNil ifTrue:[
        ^ bindings at:aSymbol ifAbsent:nil.
    ].
    ^ nil
!

bindings
    ^ bindings
!

bindings:aDictionary
    bindings := aDictionary
!

componentAt:name
    namedComponents isNil ifTrue:[^ nil].
    ^ namedComponents at:name asSymbol ifAbsent:nil
!

componentAt:name put:aComponent
    namedComponents isNil ifTrue:[
        namedComponents := IdentityDictionary new.
    ].
    namedComponents at:name asSymbol put:aComponent
!

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

    componentCreationHook := something.!

focusSequence 
    ^ focusSequence
!

namedComponents
    ^ namedComponents
!

source
    "same as #application, for ST-80 compatibility"

    ^ application

    "Created: 17.1.1997 / 19:03:51 / cg"
!

source:anApplicationModel
    "same as #application:, for ST-80 compatibility"

    application := anApplicationModel

    "Modified: 17.1.1997 / 19:03:57 / cg"
!

window
    "return the top window (view), for which an interface
     is (being) built"

    ^ window

    "Modified: 17.1.1997 / 19:30:00 / cg"
!

window:aView
    "set the top window (view), for which an interface
     is (being) built"

    window := aView

    "Modified: 17.1.1997 / 19:30:22 / cg"
!

windowGroup
self halt.
    ^ window windowGroup

    "Modified: 17.1.1997 / 19:30:26 / cg"
! !

!WindowBuilder methodsFor:'building'!

buildFromSpec:aSpec
    ^ self subclassResponsibility
!

makeTabable:aComponent
    focusSequence isNil ifTrue:[
        focusSequence := OrderedCollection new.
    ].
    focusSequence add:aComponent
! !

!WindowBuilder methodsFor:'spec creation aspect fetch'!

actionFor:aKey
    "return an action for aKey. This is invoked during window building
     (by the builder) to ask for an ActionButtons actionBlock.
     Here, first the local bindings are searched, then the application and
     finally the applications class is asked for a corresponding action.
     The returned object is typically a block."

    |b|

    bindings notNil ifTrue:[
        b := bindings at:aKey ifAbsent:nil.
        b notNil ifTrue:[^ b].
    ].

    application notNil ifTrue:[
        Object messageNotUnderstoodSignal catch:[
            ^ application actionFor:aKey
        ]
    ].
    applicationClass notNil ifTrue:[
        (applicationClass respondsTo:#actionFor:) ifTrue:[
            ^ applicationClass actionFor:aKey
        ]
    ].
    ^ []

    "Created: 17.1.1997 / 21:08:22 / cg"
!

aspectFor:aKey
    "return a model for aKey. This is invoked during window building
     (by the builder) to ask for an Editfields, a Toggles etc. model.
     Here, first the local bindings are searched, then the application and
     finally the applications class is asked for a corresponding action.
     The returned object is typically a valueHolder."

    |b|

    bindings notNil ifTrue:[
        b := bindings at:aKey ifAbsent:nil.
        b notNil ifTrue:[^ b].
    ].

    application notNil ifTrue:[
        Object messageNotUnderstoodSignal catch:[
            ^ application aspectFor:aKey
        ]
    ].
    applicationClass notNil ifTrue:[
        (applicationClass respondsTo:#aspectFor:) ifTrue:[
            ^ applicationClass aspectFor:aKey
        ]
    ].
    ^ self aspectAt:aKey

    "Created: 17.1.1997 / 21:06:16 / cg"
!

componentFor:aKey
    "return a component for aKey. This is invoked during window building
     (by the builder) to ask for an ArbitraryComponents view.
     Here, first the local bindings are searched, then the application and
     finally the applications class is asked for a corresponding action.
     The returned object is typically a view."

    |cls|

    application notNil ifTrue:[
        Object messageNotUnderstoodSignal catch:[
            ^ application componentFor:aKey
        ]
    ].
    applicationClass notNil ifTrue:[
        (applicationClass respondsTo:#componentFor:) ifTrue:[
            ^ applicationClass componentFor:aKey
        ]
    ].
    ^ self aspectAt:aKey

!

labelFor:aKey
    "return a label for aKey. This is invoked during window building
     (by the builder) to ask for a ???'s label.
     Here, first the local bindings are searched, then the application and
     finally the applications class is asked for a corresponding action.
     The returned object is typically a string."

    |cls|

    application notNil ifTrue:[
        Object messageNotUnderstoodSignal catch:[
            ^ application labelFor:aKey
        ]
    ].
    applicationClass notNil ifTrue:[
        (applicationClass respondsTo:#labelFor:) ifTrue:[
            ^ applicationClass labelFor:aKey
        ]
    ].
    ^ self aspectAt:aKey

!

listFor:aKey
    "return a list for aKey. This is invoked during window building
     (by the builder) to ask for a ???'s label.
     Here, first the local bindings are searched, then the application and
     finally the applications class is asked for a corresponding action.
     The returned object is typically a list."

    application notNil ifTrue:[
        Object messageNotUnderstoodSignal catch:[
            ^ application listFor:aKey
        ]
    ].
    applicationClass notNil ifTrue:[
        (applicationClass respondsTo:#listFor:) ifTrue:[
            ^ applicationClass listFor:aKey
        ]
    ].
    ^ self aspectAt:aKey

    "Created: 17.1.1997 / 21:08:45 / cg"
! !

!WindowBuilder methodsFor:'spec creation callbacks'!

createdComponent:aView forSpec:spec
    componentCreationHook notNil ifTrue:[
        componentCreationHook value:aView value:spec value:self
    ]

    "Modified: 5.9.1995 / 21:42:54 / claus"
! !

!WindowBuilder methodsFor:'startup'!

closeRequest
    window destroy

    "Modified: 17.1.1997 / 19:30:32 / cg"
!

open
    "open my topView, as previously created"

    self 
        openWithExtent:nil
        andType:(application defaultWindowType)

    "Modified: 17.1.1997 / 19:59:22 / cg"
!

openAt:aPoint
    "open my topView at some location"

    self 
        openAt:aPoint 
        withExtent:nil  
        andType:(application defaultWindowType)

    "Created: 14.2.1997 / 20:21:57 / cg"
    "Modified: 28.2.1997 / 22:50:29 / cg"
!

openAt:origin withExtent:ext andType:type
    "open my window, as previously created, optionally defining the
     windows origin and/or extent. 
     The type argument may be #dialog or #normal, and specifies if the view 
     should be opened as a modal view, blocking interaction to the currently 
     active view, or as a normal view."

    origin notNil ifTrue:[
        window origin:origin
    ].
    ext notNil ifTrue:[
        window extent:ext
    ].

    type == #dialog ifTrue:[
        window fixSize.
        window fixPosition:(window device pointerPosition - window positionOffset).
        window openModal.
        ^ self
    ].

    type == #normal ifTrue:[
        window open.
        ^ self
    ].

    type == #popUp ifTrue:[
        window fixPosition:(window device pointerPosition).
        window openAsPopUp.
        ^ self
    ].

    "
     if ST-80 supports more types - these may be added later
    "
    self halt:'unimplemented'

    "Created: 14.2.1997 / 20:22:24 / cg"
    "Modified: 28.2.1997 / 22:56:52 / cg"
!

openDialog
    "open my topView, as previously created as a modal view,
     blocking interaction to the currently active view."

    self 
        openWithExtent:nil 
        andType:#dialog

    "Modified: 17.1.1997 / 19:59:29 / cg"
!

openDialogAt:aPoint withExtent:ext
    "open my topView, as previously created as a modal view,
     blocking interaction to the currently active view."

    self 
        openAt:aPoint withExtent:ext 
        andType:#dialog

    "Modified: 17.1.1997 / 19:59:36 / cg"
    "Created: 14.2.1997 / 20:24:19 / cg"
!

openDialogWithExtent:ext
    "open my topView, as previously created as a modal view,
     blocking interaction to the currently active view."

    self 
        openWithExtent:ext 
        andType:#dialog

    "Modified: 17.1.1997 / 19:59:36 / cg"
!

openPopUpAt:aPoint
    "open my topView, as previously created as a popUp view,
     blocking interaction to the currently active view."

    self 
        openAt:aPoint withExtent:nil 
        andType:#popUp

    "Modified: 17.1.1997 / 19:59:29 / cg"
    "Created: 14.2.1997 / 20:24:38 / cg"
!

openPopUpIn:aRectangle
    "open my topView, as previously created as a popUp view,
     blocking interaction to the currently active view."

    self 
        openWithExtent:nil 
        andType:#popUp

    "Modified: 17.1.1997 / 19:59:29 / cg"
    "Created: 17.1.1997 / 20:01:24 / cg"
!

openWithExtent:aPoint
    "open my topView, as previously created, but override
     the extent."

    self 
        openWithExtent:aPoint 
        andType:(application defaultWindowType)

    "Modified: 17.1.1997 / 19:58:48 / cg"
!

openWithExtent:ext andType:type
    "open my window, as previously created. The type argument
     may be #dialog or #normal, and specifies if the view should
     be opened as a modal view, blocking interaction to the currently 
     active view, or as a normal view."

    ^ self openAt:nil withExtent:ext andType:type

    "Modified: 14.2.1997 / 20:22:47 / cg"
! !

!WindowBuilder class methodsFor:'documentation'!

version
    ^ '$Header: /cvs/stx/stx/libview2/Attic/WinBuilder.st,v 1.29 1997-03-03 10:14:14 ca Exp $'
! !