Skip to content

Commit

Permalink
add more content to event handling + small tip in transformDo:
Browse files Browse the repository at this point in the history
  • Loading branch information
rvillemeur committed Oct 16, 2024
1 parent 1c8c4ef commit 4f55611
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 45 deletions.
4 changes: 4 additions & 0 deletions Chapters/bloc/element.md
Original file line number Diff line number Diff line change
Expand Up @@ -342,6 +342,10 @@ element transformDo: [ :b | b scaleBy: 0.2; translateBy: -25 @ -15 ];
```
The following script produces *@fig:transform@*.

it sets the scale to 0.2 and translate by -25@15, it doesn't scale it by 0.2.
each time you execute it. If you want to append try: `builder inherit scaleBy: 0.2`.
`transformDo:` creates a new transformation from the commands in the block closure

```smalltalk
aContainer := BlElement new
layout: BlFrameLayout new;
Expand Down
112 changes: 67 additions & 45 deletions Chapters/bloc/events.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,26 @@
## Event handling

In graphical applications, whenever a user interacts with the application (BlElements),
an event is said to have been occurred. For example, clicking on a button, moving
the mouse, entering a character through keyboard, selecting an item from list, etc.
are the activities that causes an event to happen.

Bloc provides support to handle a wide varieties of events. The class named *BlEvent* is the base class for an event. An instance of any of its subclass is an event. Some of them are are listed below.

- **Mouse Event** − This is an input event that occurs when a mouse is clicked. It includes actions like mouse clicked, mouse pressed, mouse released, mouse moved, etc.

- **Key Event** − This is an input event that indicates the key stroke occurred on an element. Those events includes actions like key pressed, key released and key typed.

- **Drag Event** − This occurs when an Element is dragged by mouse. It includes actions like drag entered, drag dropped, drag entered target, drag exited target, drag over, etc.

Event Handling is the mechanism that controls the event and decides what should happen, if an event occurs. This mechanism has the code which is known as an event handler that is executed when an event occurs.

Bloc provides handlers and filters to handle events. Every event has:

- Target − The element on which an event occurred.
- Source - Used in drag&drop to identify the source element.
- Type − Type of the occurred event

### Event handling

```smalltalk
Expand Down Expand Up @@ -27,6 +48,18 @@ deco addEventHandler: (BlEventHandler

### About event bubbling

#### Event Capturing Phase
This event travels to all elements in the dispatch chain (from top to bottom), starting from *BlSpace*. If any of these element has a handler for this event, it will be executed, until it reach the target element which can process it.

#### Event Bubbling Phase
In the event bubbling phase, the event is travelled from the target element to BlSpace (bottom to top). If any of the element in the event dispatch chain has a handler registered for the event, it will be executed. When the event reaches the BlSpace element the process will be completed.

#### Event Handlers
Event handlers are those which contains application logic to process an event. An element can register more than one handler.

You can stop the event propagation in an event handler by adding
`anEvent consumed: true.`

We should check `example_mouseEvent_descending_bubbling`

![event propagation](figures/EventPropagation.png)
Expand Down Expand Up @@ -276,55 +309,44 @@ BlShortcutWithAction new

### Drag and Drop

The drop event should be applied to the element that will receive the dragged content.
`Elt1` uses the dragEnd to know when the drag has ended.
`Elt2` uses the dropEvent to know when something try to be dropped on it.
If you drop `elt1` on `elt2`, `elt2` opens an inspector on `elt1`.
Full drag&drop example

```
| elt1 elt2 space |
elt1 := BlElement new
background: Color lightBlue;
position: 100 asPoint;
addEventHandler: BlPullHandler new disallowOutOfBounds;
id: #elt1;
yourself.
elt2 := BlElement new
background: Color red;
size: 100 asPoint;
position: 200 asPoint;
id: #elt2;
yourself.
| source1 source2 target space offset |
space := BlSpace new.
space root addChildren: { elt1 . elt2 }.
elt2
addEventHandlerOn: BlDropEvent
do: [ :evt | evt gestureSource inspect ].
elt1
addEventHandlerOn: BlDragEndEvent
do: [ :evt | ].
space show.
```


### Manually drag and drop

source1 := BlElement new size: 100 @ 100; background: Color red; border: (BlBorder paint: Color gray width: 2); position: 0@0.
source2 := BlElement new size: 100 @ 100; background: Color purple; border: (BlBorder paint: Color gray width: 2); position: 150@0.
target := BlElement new size: 100 @ 100; background: Color blue; border: (BlBorder paint: Color gray width: 2); position: 500 @ 500.
space root addChildren: { source1. source2. target. }.
source1 addEventHandlerOn: BlDragStartEvent do: [ :event | event consumed: true. self inform: 'source1 BlStartDragEvent'.
offset := event position - source1 position.
source1 removeFromParent.].
source1 addEventHandlerOn: BlDragEndEvent do: [ :event | event consumed: true. self inform: 'source1 BlDragEndEvent'. ].
source1 addEventHandlerOn: BlDragEvent do: [ :event | event consumed: true. "self inform: 'source1 BlDragEvent'."
source1 position: event position - offset.
source1 hasParent ifFalse: [space root addChild: source1].
source1 preventMeAndChildrenMouseEvents ].
source2 addEventHandlerOn: BlDragStartEvent do: [ :event | event consumed: true. self inform: 'source2 BlStartDragEvent'.
offset := event position - source2 position.
source2 removeFromParent.].
source2 addEventHandlerOn: BlDragEndEvent do: [ :event | event consumed: true. self inform: 'source2 BlDragEndEvent'. ].
source2 addEventHandlerOn: BlDragEvent do: [ :event | event consumed: true. "self inform: 'source BlDragEvent'."
source2 position: event position - offset.
source2 hasParent ifFalse: [space root addChild: source2].
source2 preventMeAndChildrenMouseEvents ].
target addEventHandlerOn: BlDropEvent do: [ :event | event consumed: true. self inform: 'target BlDropEvent'.
event gestureSource background paint color = (Color red)
ifTrue: [ self inform: 'drop accepted' ]
ifFalse: [ self inform: 'drop rejected'. event gestureSource position: 100 @ 400; allowMeAndChildrenMouseEvents] ].
target addEventHandlerOn: BlDragEnterEvent do: [ :event | event consumed: true. self inform: 'target BlDragEnterEvent' ].
target addEventHandlerOn: BlDragLeaveEvent do: [ :event | event consumed: true. self inform: 'target BlDragLeaveEvent' ].
space show
```
elt := BlElement new background: Color red; size: 200 asPoint.
offset := 0.
elt addEventHandlerOn: BlDragStartEvent do: [ :e | e consume.
offset := e position - elt position].
elt addEventHandlerOn: BlDragEvent do: [ :e | elt position: e position - offset ].
elt openInSpace.
```



### BlPullHandler

Expand Down

0 comments on commit 4f55611

Please sign in to comment.