Navigation: ABC Library Reference > ToolbarClass >====== ToolbarClass Overview ====== | |
ToolbarClass and ToolbarTarget objects work together to reliably “convert” an event associated with a toolbar button into an appropriate event associated with a specific control or window.
ToolbarClass objects communicate with zero or more ToolbarTarget objects. Each ToolbarTarget object is associated with a specific entity, such as a browse list, relation tree,or update form. The ToolbarClass object forwards events and method calls to the active ToolbarTarget object. Only one target is active at a time.
This lets you use a single toolbar to drive a variety of targets, such as update forms, browse lists, relation tree lists, etc. A single toolbar can even drive multiple targets (two or more BrowseBoxes) in a single procedure.
ToolbarClass Concepts
Within an MDI application, the ToolbarClass and ToolbarTarget work together to reliably interpret and pass an event (EVENT:Accepted) associated with a toolbar button into an event associated with a specific control or window. For example, the end user CLICKS on a toolbar button (say the “Insert” button) on the MDI application frame. The frame procedure forwards the event to the active thread (POST(EVENT:Accepted,ACCEPTED(),SYSTEM{Prop:Active})). The active thread (procedure) manages a window that displays two LIST controls, and one of the LISTs has focus. This procedure has a ToolbarClass object plus a ToolbarTarget object for each LIST control. The ToolbarClass object takes the event (ToolbarClass.TakeEvent)1 and forwards the event to the active ToolbarTarget object (the target that represents the LIST with focus). The ToolbarTarget object takes the event (ToolbarListBoxClass.TakeEvent) and handles it by posting an appropriate event to a specific control or to the window, for example:
POST(EVENT:ACCEPTED,SELF.InsertButton) !insert a record
POST(EVENT:PageDown,SELF.Control) !scroll a LIST
POST(EVENT:Completed) !complete an update form
POST(EVENT:CloseWindow) !select a record
! 'etc.
If the procedure has a WindowManager object, the WindowManager object takes the event (WindowManager.TakeEvent) and forwards it to the ToolbarClass object (WindowManager.TakeAccepted).
ToolbarClass Relationship to Other Application Builder Classes
ToolbarTarget
The ToolbarClass object keeps a list of ToolbarTarget objects so it can forward events and method calls to a particular target. Each ToolbarTarget object is associated with a specific entity, such as a browse list, relation tree,or update form. At present, the ABC Library has three classes derived from the ToolbarTarget:
ToolbarListboxClass | BrowseClass toolbar target |
ToolbarReltreeClass | Reltree control toolbar target |
ToolbarUpdateClass | Form procedure toolbar target |
These ToolbarTarget objects implement the event handling specific to the associated entity. There may be zero or more ToolbarTarget objects within a procedure; however, only one is active at a time. The SetTarget method sets the active ToolbarTarget object.
BrowseClass and WindowManager
The WindowManager optionally uses the ToolbarClass, as does the BrowseClass. Therefore, if your program uses a WindowManager or BrowseClass object, it may also need the ToolbarClass. Much of this is automatic when you INCLUDE the WindowManager or BrowseClass headers (ABWINDOW.INC and ABBROWSE.INC) in your program's data section. See the Conceptual Example.
ToolbarClass ABC Template Implementation
The ABC procedure templates instantiate a ToolbarClass object called Toolbar within each procedure containing a template that asks for global toolbar control–that is, the BrowseBox template, the FormVCRControls template, and the RelationTree template.
The templates generate code to instantiate the ToolbarClass object and to register the ToolbarClass object with the WindowManager object. You may see code such as the following in your template-generated procedures.
Toolbar ToolbarClass !declare Toolbar object
CODE
!
ThisWindow.Init PROCEDURE
SELF.AddItem(Toolbar) !register Toolbar with WindowManager
BRW1.AddToolbarTarget(Toolbar) !register BrowseClass as target
Toolbar.AddTarget(REL1::Toolbar,?RelTree) !register RelTree as target
SELF.AddItem(ToolbarForm) !register update form as target
The WindowManager and BrowseClass are both programmed to use ToolbarClass objects. Therefore most of the interaction between these objects is encapsulated within the Application Builder Class code, and is only minimally reflected in the ABC Template generated code.
Toolbar Class Source Files
The ToolbarClass source code is installed by default to the Clarion \LIBSRC folder. The ToolbarClass source code and its respective components are contained in:
ABTOOLBA.INC | ToolbarClass declarations |
ABTOOLBA.CLW | ToolbarClass method definitions |
ToolbarClass Conceptual Example
The following example shows a typical sequence of statements to declare, instantiate, initialize, use, and terminate a ToolbarClass object and related ToolbarTarget objects.
This example uses the ToolbarClass to allow a global toolbar to drive two separate but related LISTs within a single MDI procedure. The primary LIST shows client information and the related LIST shows phone numbers for the selected client. The toolbar drives whichever list has focus.
The program POSTs toolbar events to the active MDI window using the SYSTEM{Prop:Active} property. Then the local ToolbarClass object calls on the active ToolbarTarget object to handle the event.
PROGRAM
INCLUDE('ABBROWSE.INC') !declare BrowseClass
INCLUDE('ABTOOLBA.INC') !declare Toolbar classes
INCLUDE('ABWINDOW.INC') !declare WindowManager
CODE
!program code
Main PROCEDURE !contains global toolbar
AppFrame APPLICATION('Toolbars'),AT(,,275,175),SYSTEM,MAX,RESIZE,IMM
MENUBAR
ITEM('Browse Customers'),USE(?BrowseCustomer)
END
TOOLBAR,AT(0,0,400,22) !must use ABTOOLBA.INC EQUATES:
BUTTON,AT(4,2),USE(?Top,Toolbar:Top),DISABLE,ICON('VCRFIRST.ICO'),FLAT
BUTTON,AT(16,2),USE(?PageUp,Toolbar:PageUp),DISABLE,ICON('VCRPRIOR.ICO'),FLAT
BUTTON,AT(28,2),USE(?Up,Toolbar:Up),DISABLE,ICON('VCRUP.ICO'),FLAT
BUTTON,AT(40,2),USE(?Down,Toolbar:Down),DISABLE,ICON('VCRDOWN.ICO'),FLAT
BUTTON,AT(52,2),USE(?PageDown,Toolbar:PageDown),DISABLE,ICON('VCRNEXT.ICO'),FLAT
BUTTON,AT(64,2),USE(?Bottom,Toolbar:Bottom),DISABLE,ICON('VCRLAST.ICO'),FLAT
END
END
Frame CLASS(WindowManager)
Init PROCEDURE(),BYTE,PROC,VIRTUAL
TakeAccepted PROCEDURE(),BYTE,PROC,VIRTUAL
END
Toolbar ToolbarClass !declare Toolbar object
CODE
Frame.Run()
Frame.Init PROCEDURE()
ReturnValue BYTE,AUTO
CODE
ReturnValue = PARENT.Init()
SELF.VCRRequest &= VCRRequest
SELF.Errors &= GlobalErrors
SELF.AddItem(Toolbar) !register Toolbar with WindowManager
OPEN(AppFrame)
SELF.Opened=True
SELF.SetAlerts()
RETURN ReturnValue
Frame.TakeAccepted PROCEDURE()
ReturnValue BYTE,AUTO
Looped BYTE
CODE
LOOP
IF Looped THEN RETURN Level:Notify ELSE Looped=1.
CASE ACCEPTED()
OF Toolbar:First TO Toolbar:Last !for EVENT:Accepted on toolbar
POST(EVENT:Accepted,ACCEPTED(),SYSTEM{Prop:Active}) !transfer it to active thread
CYCLE ! and stop
END
ReturnValue = PARENT.TakeAccepted()
IF ACCEPTED() = ?BrowseCustomer
START(BrowseCustomer,050000)
END
RETURN ReturnValue
END
BrowseCustomer PROCEDURE !contains local Toolbar and targets
CusView VIEW(Customer)
END
CusQ QUEUE
CUS:CUSTNO LIKE(CUS:CUSTNO)
CUS:NAME LIKE(CUS:NAME)
ViewPosition STRING(512)
END
PhView VIEW(Phones)
END
PhQ QUEUE
PH:NUMBER LIKE(PH:NUMBER)
PH:ID LIKE(PH:ID)
ViewPosition STRING(512)
END
CusWindow WINDOW('Browse Customers'),AT(,,246,131),IMM,SYSTEM,GRAY,MDI
LIST,AT(8,7,160,100),USE(?CusList),IMM,HVSCROLL,FROM(CusQ),|
FORMAT('51R(2)|M~CUSTNO~C(0)@n-14@80L(2)|M~NAME~@s30@')
BUTTON('&Insert'),AT(17,111,45,14),USE(?InsertCus),SKIP
BUTTON('&Change'),AT(66,111,45,14),USE(?ChangeCus),SKIP,DEFAULT
BUTTON('&Delete'),AT(115,111,45,14),USE(?DeleteCus),SKIP
LIST,AT(176,7,65,100),USE(?PhList),IMM,FROM(PhQ),FORMAT('80L~Phones~L(1)')
BUTTON('&Insert'),AT(187,41,42,12),USE(?InsertPh),HIDE
BUTTON('&Change'),AT(187,54,42,12),USE(?ChangePh),HIDE
BUTTON('&Delete'),AT(187,67,42,12),USE(?DeletePh),HIDE
END
ThisWindow CLASS(WindowManager) !declare ThisWindow object
Init PROCEDURE(),BYTE,PROC,VIRTUAL
Kill PROCEDURE(),BYTE,PROC,VIRTUAL
TakeSelected PROCEDURE(),BYTE,PROC,VIRTUAL
END
Toolbar ToolbarClass !declare Toolbar object to receive
! and process toolbar events from Main
CusBrowse CLASS(BrowseClass) !declare CusBrowse object
Q &CusQ
END
PhBrowse CLASS(BrowseClass) !declare PhBrowse object
Q &PhQ
END
CODE
ThisWindow.Run()
ThisWindow.Init PROCEDURE()
ReturnValue BYTE,AUTO
CODE
ReturnValue = PARENT.Init()
SELF.FirstField = ?CusList !CusList gets initial focus
SELF.VCRRequest &= VCRRequest
SELF.Errors &= GlobalErrors
SELF.AddItem(Toolbar) !register Toolbar with WindowManager
Relate:Customer.Open
CusBrowse.Init(?CusList,CusQ.ViewPosition,CusView,CusQ,Relate:Customer,SELF)
PhBrowse.Init(?PhList,PhQ.ViewPosition,PhView,PhQ,Relate:Phones,SELF)
OPEN(CusWindow)
SELF.Opened=True
CusBrowse.Q &= CusQ
CusBrowse.AddSortOrder(,CUS:BYNUMBER)
CusBrowse.AddField(CUS:CUSTNO,CusBrowse.Q.CUS:CUSTNO)
CusBrowse.AddField(CUS:NAME,CusBrowse.Q.CUS:NAME)
PhBrowse.Q &= PhQ
PhBrowse.AddSortOrder(,PH:IDKEY)
PhBrowse.AddRange(PH:ID,Relate:Phones,Relate:Customer)
PhBrowse.AddField(PH:NUMBER,PhBrowse.Q.PH:NUMBER)
PhBrowse.AddField(PH:ID,PhBrowse.Q.PH:ID)
CusBrowse.InsertControl=?InsertCus
CusBrowse.ChangeControl=?ChangeCus
CusBrowse.DeleteControl=?DeleteCus
CusBrowse.AddToolbarTarget(Toolbar) !Make CusBrowse a toolbar target
PhBrowse.InsertControl=?InsertPh
PhBrowse.ChangeControl=?ChangePh
PhBrowse.DeleteControl=?DeletePh
PhBrowse.AddToolbarTarget(Toolbar) !Make PhBrowse a toolbar target
SELF.SetAlerts()
RETURN ReturnValue
ThisWindow.Kill PROCEDURE()
ReturnValue BYTE,AUTO
CODE
ReturnValue = PARENT.Kill()
Relate:Customer.Close
RETURN ReturnValue
ThisWindow.TakeSelected PROCEDURE()
ReturnValue BYTE,AUTO
Looped BYTE
CODE
LOOP
IF Looped THEN RETURN Level:Notify ELSE Looped=1.
ReturnValue = PARENT.TakeSelected()
CASE FIELD()
OF ?CusList !if selected,
Toolbar.SetTarget(?CusList) ! make ?CusList the active target
OF ?PhList !if selected
IF RECORDS(PhBrowse.Q) > 1 !and contains more than one record,
Toolbar.SetTarget(?PhList) ! make ?PhList the active target
END
END
RETURN ReturnValue
END