Learning how button model works

BrButtonModel BrWidgetModel subclass: #BrButtonModel instanceVariableNames: 'action' classVariableNames: '' package: 'Brick-Button - Model' 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 subclass: #BlClickEvent instanceVariableNames: '' classVariableNames: '' package: 'Bloc-Events' .

By default BrButtonModel BrWidgetModel subclass: #BrButtonModel instanceVariableNames: 'action' classVariableNames: '' package: 'Brick-Button - Model' has an empty action that does nothing:

Every button model creates a corresponding event handler that responds to BlClickEvent BlMouseEvent subclass: #BlClickEvent instanceVariableNames: '' classVariableNames: '' package: 'Bloc-Events' :

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>

	^ self default
		action: [ :aButtonElement :aButtonModel |
			aButtonModel model: #clicked.
			self inform: 'clicked' ]
    

The instantiated button model can be attached to any visual BlElement Object subclass: #BlElement uses: TBlTransformable + TBlEventTarget + TBlDebug instanceVariableNames: 'spaceReference parent children bounds measuredBounds boundsCache eventDispatcher constraints layout transformation taskQueue errorHandler userData visuals flags' classVariableNames: '' package: 'Bloc-Basic' as its view model. Once attached, the visual element becomes clickable, as the following example shows:

elementWithButtonModel
	<gtExample>
	| 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>
	| anElement |

	anElement := self elementWithButtonModel.
	BlSpace simulateClickOn: anElement.

	self assert: anElement viewModel model equals: #clicked.

	^ anElement