Learning how button model works

BrButtonModel BrWidgetModel << #BrButtonModel slots: { #action . #actionsWithModifiers }; tag: 'Button - Model'; package: 'Brick' is one of the most essential parts of the Brick widget library. It allows users to create clickable widgets and attach a custom action that will be executed on BlClickEvent BlMouseEvent << #BlClickEvent slots: {}; tag: 'Events'; package: 'Bloc' .

By default BrButtonModel BrWidgetModel << #BrButtonModel slots: { #action . #actionsWithModifiers }; tag: 'Button - Model'; package: 'Brick' has an empty action that does nothing:

Every button model creates a corresponding event handler that responds to BlClickEvent BlMouseEvent << #BlClickEvent slots: {}; tag: 'Events'; package: 'Bloc' :

The following example shows how to create a new button model and attach an action. In this particular case we set #clicked as an inner domain model to be able to assert that the action was indeed executed and also inform users about it:

buttonModelWithAction
	<gtExample>
	<return: #BrButtonModel>
	^ self default
		action: [ :aButtonElement :aButtonModel | 
			aButtonModel model: #clicked.
			self inform: 'clicked' ]
    

The instantiated button model can be attached to any visual BlElement Object << #BlElement traits: {TBlTransformable + TBlEventTarget + TBlDebug}; slots: { #spaceReference . #parent . #children . #bounds . #measuredBounds . #boundsCache . #eventDispatcher . #constraints . #layout . #transformation . #taskQueue . #errorHandler . #userData . #visuals . #flags . #theme }; tag: 'Core'; package: 'Bloc' as its view model. Once attached, the visual element becomes clickable, as the following example shows:

elementWithButtonModel
	<gtExample>
	<return: #BlElement>
	| anElement aButtonModel |
	aButtonModel := self buttonModelWithAction.

	anElement := BlElement new
			size: 60 @ 30;
			background: Color veryLightGray.

	self assertEventTarget: anElement hasNoEventHandlerOn: BlClickEvent.

	anElement viewModel: aButtonModel.

	self assertEventTarget: aButtonModel hasNoEventHandlerOn: BlClickEvent.
	self assertEventTarget: anElement hasEventHandlerOn: BlClickEvent.

	^ anElement
    

To test the behaviour of the button model we can simulate a click on the element with attached button model and make sure that the action was performed:

clickOnElementWithButtonModel
	<gtExample>
	<return: #BlElement>
	| anElement |
	anElement := self elementWithButtonModel.
	BlSpace simulateClickOn: anElement.

	self assert: anElement viewModel model equals: #clicked.

	^ anElement