Learning how button model works

BrButtonModel BrWidgetModel subclass: #BrButtonModel instanceVariableNames: 'action actionsWithModifiers' 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 actionsWithModifiers' 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>
	<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 subclass: #BlElement uses: TBlTransformable + TBlEventTarget + TBlDebug instanceVariableNames: 'spaceReference parent children bounds measuredBounds boundsCache eventDispatcher constraints layout transformation taskQueue errorHandler userData visuals flags theme' classVariableNames: '' package: 'Bloc-Core' 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