WindowGroup.st
author claus
Sun, 09 Jan 1994 22:54:12 +0100
changeset 26 ac9f66dc8f53
parent 23 4a7e02de7b72
child 28 3879ff2138f1
permissions -rw-r--r--
*** empty log message ***

"
 COPYRIGHT (c) 1993 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:#WindowGroup
         instanceVariableNames:'views topViews myProcess mySensor'
         classVariableNames:'ActiveGroup'
         poolDictionaries:''
         category:'Interface-Support'
!

!WindowGroup class methodsFor:'instance creation'!

new
    "create and return a new WindowGroup object"

    ^ self basicNew initialize
! !

!WindowGroup class methodsFor:'accessing'!

activeGroup
    "return the currently active windowGroup"

    ^ ActiveGroup
! !

!WindowGroup methodsFor:'accessing'!

sensor
    "return the windowGroups sensor"

    ^ mySensor
!

addView:aView
    "add aView to the windowGroup"

    views isNil ifTrue:[
        views := OrderedCollection new.
    ].
    views add:aView
!

removeView:aView
    "remove aView from the windowGroup;
     if this was the last view in this group, 
     also shut down the corresponding process"

    views notNil ifTrue:[
        views remove:aView ifAbsent:[].
        views isEmpty ifTrue:[
            views := nil
        ]
    ].
    topViews notNil ifTrue:[
        topViews remove:aView ifAbsent:[].
        topViews isEmpty ifTrue:[
            topViews := nil
        ]
    ].

    (views isNil and:[topViews isNil]) ifTrue:[
        views := nil.
        topViews := nil.
        myProcess notNil ifTrue:[
            myProcess terminate.
            myProcess := nil
        ]
    ].
    mySensor eventSemaphore signal
!

views
    "return the views accociated to this windowGroup"

    ^ views
!

process 
    "return the windowGroups process"

    ^ myProcess
!

sensor:aSensor
    "set the windowGroups sensor"

    mySensor := aSensor
!

addTopView:aView
    topViews isNil ifTrue:[
        topViews := OrderedCollection new.
    ].
    topViews add:aView
! !

!WindowGroup methodsFor:'event handling'!

processEvent
    "process a single event from either the damage- or user input queues"

    |damage event view rect|

    ActiveGroup := self.
    [mySensor hasDamage] whileTrue:[
        damage := mySensor nextDamage.
        view := damage at:1.
        rect := damage at:2.
        view exposeX:rect left y:rect top width:rect width height:rect height
    ].
    [mySensor hasEvents] whileTrue:[
        event := mySensor nextEvent.
        event sendEvent
    ]
!

eventLoop
    "loop executed by windowGroup process;
     wait-for and process events forever"

   self eventLoopWhile:[true]
!

eventLoopWhile:aBlock
    "wait-for and process events while aBlock evaluates to true."

   aBlock whileTrue:[
        mySensor eventSemaphore wait.
        self processEvent
   ]
! !

!WindowGroup methodsFor:'activation / deactivation'!

startup
    "startup the window-group;
     this creates a new window group process, which
     does the event processing."

    |nm|

    myProcess isNil ifTrue:[
        myProcess := [
            self eventLoop
        ] forkAt:Processor userSchedulingPriority.

        (topViews notNil and:[topViews isEmpty not]) ifTrue:[
            "give the handler process a user friendly name"
            nm := topViews first iconLabel.
            nm isNil ifTrue:[
                nm := topViews first name.
                nm isNil ifTrue:[
                    nm := topViews first label.
                ]
            ].
            myProcess name:(topViews first name)
        ] ifFalse:[
            myProcess name:'window handler'.
        ].

        "when the process dies, we have to close-down
         the views as well"
        myProcess exitAction:[self closeDownViews]
    ]
!

closeDownViews
    "destroy all views associated to this window group"

    topViews notNil ifTrue:[
        topViews do:[:aTopView | aTopView destroy]
    ].
    views := nil.
    topViews := nil.
!

shutdown
    "shutdow the window group; close all views and
     terminate process"

    self closeDownViews.
    myProcess notNil ifTrue:[
        myProcess terminate.
        myProcess := nil
    ]
! !

!WindowGroup methodsFor:'initialization'!

reinitialize
    "throw away old (zombie) process"
    myProcess := nil.

    "throw away old events"
    self initialize
!

initialize
    "setup the windowgroup, by creating a new sensor
     and an event semaphore"

    mySensor := WindowSensor new.
    mySensor eventSemaphore:Semaphore new
! !

!WindowGroup methodsFor:'printing'!

printString
    "return a printed representation;
     just for more user friendlyness, add name of process."

    myProcess isNil ifTrue:[^ super printString].
    ^ 'WindowGroup(' , myProcess nameOrId , ')'
! !