Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Going over examples2 #236

Merged
merged 3 commits into from
Apr 9, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions doc/ElementAddedToSceneGraph.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
## Understanding `BlElement>>#onAddedToSceneGraph`

As we know, `BlElement` and `BlSpace` play central roles in Bloc. When `BlElement` is added to a `BlSpace`, the space is referenced by the element with the help of `BlAttachedCachedSpaceReference`, which denotes that the space is attached to the element.


### Scene graph
We define a scene graph is a combination of a tree of elements and a space which contains those elements.

#### Attached element
An element is attached to the scene graph then and only then when that element or one of its parents is the root of a space. It is possible to test if an arbitrary element is attached to the scene graph by sending `BlElement>>#isAttachedToSceneGraph` message to that element. When an element is attached to the scene graph, `BlElement>>#space` returns a non-null instance of a `BlSpace` to which that element is added.

#### How to be notified when an element is attached to the scene graph?

There are two ways to be notified when an element is attached to the scene graph: an event `BlElementAddedToSceneGraphEvent` and a hook (template) method `BlElement>>#onAddedToSceneGraph`.
Please note, that when overriding `BlElement>>#onAddedToSceneGraph` it is mandatory to delegate the hook method to the super class, otherwise the children would not be notified.

#### When should I rely on the scene graph attachment hook?

There are very little cases when users should override `BlElement>>#onAddedToSceneGraph` or handle a corresponding event. This should only be used if the state or behavior of an element explicitly depends on the fact that it is a part of a graph scene. A good example of this would be subscribing to and unsubscribing from the `SystemAnnouncer`. Another example is cache handling, when an element is attached to the scene graph, that element can potentially pre-load something from an external source and then release that cached resource then an element is removed from the scene graph. In addition to the mentioned examples, some elements may decide to add an event handler to the space when attached to the scene graph and then remove that event handler when an element is removed from the scene graph.
As you can see, the use-cases for the `BlElement>>#onAddedToSceneGraph` are parent independent and purely depent on the binary condition: attached or not attached to the scene graph.

#### When to not rely on the scene graph attachment hook?

It is a mistake to rely on the attached to the scene graph event when the state of an element directly or indirectly depends on the state of its parents. Let's consider a font size and assume that the font size of a child depends on the font size of its parent. This situation may happen when the font size is defined in em units.
1em means that child should have the same font size as its parent, 0.5 means that the font size of a child is twice as small.
Everytime there is a change in the composition of the parents the font size should be recomputed. It should also be recomputed when the font size of any parent changes. What will happen when an element is transfered from one parent to the other within the same frame? It is very likely that the recomputation of the font size becomes inefficient and slow. A better solution would be to rely on `BlElementProperty` which can be propagated to children BlElementProperty>>#canPropagateToChildren.
36 changes: 36 additions & 0 deletions doc/ElementProperties.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
## Element property

When dealing with properties of a visual element we often find ourselves in a situation when some properties should be propagated to children or should be resolved in a local context (pt units), in a context of the direct parent (em units) or even in a global context of the whole scene graph (rem units). In some othercases, properties can be added, removed or changed multiple times per frame. Ideally, we would like to actually modify element's state at most once per frame. `BlElementProperty` helps us to do exactly that.

### Understanding properties with status

`BlElementProperty` is independent from a `BlElement`, which allows us to store properties separately or even share between multiple elements. While this being a useful property it does not facilitate the ability to track if a property is applied on a specific element. This is were `BlElementPropertyWithStatus` decorator comes into play. It wraps around element property and adds a status flag: applied, just added or to be removed.
The status flag is an elegant approach to the performance optimization problem. When switching element styles it is common that properties are removed and then added back (with the same or maybe a different value).
As an example let's consider the background of an element. Here is what roughly happens when the background is changed from black to white color:

1. Convert Color to `BlBackground`
2. Perform a comparison of the current `BlElement>>#background` with the new one and do nothing if they are equal.
3. Change the background instance variable value to the new one and request an element to redraw.

If for example the background is changed back from white to black within the same frame the element should perform the same 3 operations, so in total it would be 6 expensive step. Visually, however, nothing changed. By adding a status flag to the property we are able to minimize the amount of expensive modifications of the element's state.

### Accessing element properties

Each element knows a collection of properties currently applied on that element (BlElementCurrentProperties). They can be accessed by sending `BlElement>>#properties` to an element.
Consider the following element with a few properties that define its look:

`BlElementPropertyExplanation>>#elementWithMultipleProperties`

Sending `BlElement>>#properties` reveals what properties are currently applied: Check `BlElementPropertyExplanation>>#elementWithMultipleProperties`

### Adding and removing properties
An instance of `BlElementProperty` can be added to any arbitrary element by sending `BlElementCurrentProperties>>#addProperty:` and removed by sending `BlElementCurrentProperties>>#removeProperty:` to the collection of properties previously obtained with the help of `BlElement>>#properties`. From here Bloc will take care of the rest. Please note, that adding and removing properties does not have an immediate effect, all modifications done to the properties are batched and performed as part of the `BlSpaceFramePropertiesPhase`.

### Properties clean up after themselves

Each property knows how to apply itself on an element (`BlElementProperty>>#applyOnElement:`) and how to clean up after itself (`BlElementProperty>>#cleanUpOnElement:`). Both methods are optional and users do not have to override them, however, it is preferable to provide both implementations when applicable.
As an example let's take a BlElementBackgroundProperty which implements both methods:
`BlElementPropertyExamples>>#backgroundProperty`
Click on the buttons to the left from the rectangular element to see what happens when the background property is added and then removed from an element: once executed `BlElementPropertyExplanation>>#propertyCleanUp`.


27 changes: 27 additions & 0 deletions doc/MouseEvent.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
## About Mouse Events

### Mouse over/out and enter/leave events
Let us take a look at what happens when mouse moves between elements and what is the difference between two families of mouse events: enter/leave and over/out.

Quick comparison: hover elements that you obtain when executing
`BlMouseOverOutAndEnterLeaveEventTest>>#quickComparison`

#### `BlMouseEnterEvent` and `BlMouseLeaveEvent`

If you are looking for the simplest way to detect when a user hovers an element with the mouse use a combination of `BlMouseEnterEvent` and `BlMouseLeaveEvent`.
They trigger when the mouse pointer enters/leaves the element.

`BlMouseEnterEvent` and `BlMouseLeaveEvent` are sent directly (dispatched) to the element, ignoring any mouse transitions inside the element, therefore both mouse enter and leave events do not bubble. In the example below, notice how parent container does not receive mouse leave event when mouse transitions between children:
`BlMouseOverOutAndEnterLeaveEventTest>>#mouseEnterAndLeaveConsumed`

#### `BlMouseOverEvent` and `BlMouseOutEvent`

Similar to the mouse enter but a bit more advanced, `BlMouseOverEvent` occurs when a mouse pointer comes over an element, and `BlMouseOutEvent` – when it leaves:
Check `BlMouseOverOutAndEnterLeaveEventTest>>#basicMouseOverAndOut`

An important feature of mouseout – it triggers, when the pointer moves from an element to its descendant, e.g. from `parent` to `child`. It also means that mouse over/out events bubble.

In the example below, notice how parent container receives mouse out event when mouse transitions from it to deeper child elements:
`BlMouseOverOutAndEnterLeaveEventTest>>#mouseOverAndOutConsumed`


Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ BlCompositeBackgroundTest >> testAeApplyTo [

backgroundList := OrderedCollection with: (BlBackground paint: Color blue).
background := BlCompositeBackground withAll: backgroundList.
blElement := (BlElement new) background: background.
blElement := BlElement new background: background.
space root addChild: blElement.

space aeAsForm. "check no errors"
Expand Down
22 changes: 13 additions & 9 deletions src/Bloc-Animation-Tests/BlTransformationAnimationTest.class.st
Original file line number Diff line number Diff line change
Expand Up @@ -28,28 +28,32 @@ BlTransformationAnimationTest >> containerElement [

{ #category : #tests }
BlTransformationAnimationTest >> containerWithOneElement [
<sampleInstance>
^ self testContainerWithOneElement
]

{ #category : #tests }
BlTransformationAnimationTest >> linearTranslationAnimation [
<sampleInstance>
^ self testLinearTranslationAnimation
]

{ #category : #tests }
BlTransformationAnimationTest >> linearTranslationAnimationWithDelayAndLoop [
<sampleInstance>
^ self testLinearTranslationAnimationWithDelayAndLoop

]

{ #category : #tests }
BlTransformationAnimationTest >> linearTranslationAnimationWithDurationAndEasing [
<sampleInstance>
^ self testLinearTranslationAnimationWithDurationAndEasing
]

{ #category : #tests }
BlTransformationAnimationTest >> testAnimationElement [

<sampleInstance>
^ BlElement new
size: 50 @ 50;
background: Color veryLightGray;
Expand All @@ -58,7 +62,7 @@ BlTransformationAnimationTest >> testAnimationElement [

{ #category : #tests }
BlTransformationAnimationTest >> testContainerElement [

<sampleInstance>
^ BlElement new
size: 350 @ 350;
geometry: (BlRoundedRectangleGeometry cornerRadius: 5);
Expand All @@ -67,7 +71,7 @@ BlTransformationAnimationTest >> testContainerElement [

{ #category : #tests }
BlTransformationAnimationTest >> testContainerWithOneElement [

<sampleInstance>
| container element |
container := self containerElement.
element := self animationElement.
Expand All @@ -78,7 +82,7 @@ BlTransformationAnimationTest >> testContainerWithOneElement [

{ #category : #'smoke tests' }
BlTransformationAnimationTest >> testElementWithLinearTranslationAnimation [

<sampleInstance>
| container element animation |
animation := self linearTranslationAnimation.
element := self animationElement.
Expand All @@ -91,7 +95,7 @@ BlTransformationAnimationTest >> testElementWithLinearTranslationAnimation [

{ #category : #tests }
BlTransformationAnimationTest >> testElementWithLinearTranslationAnimationWithDelayAndLoop [

<sampleInstance>
| container animation |
animation := self linearTranslationAnimationWithDelayAndLoop.
container := self containerWithOneElement.
Expand All @@ -101,7 +105,7 @@ BlTransformationAnimationTest >> testElementWithLinearTranslationAnimationWithDe

{ #category : #tests }
BlTransformationAnimationTest >> testElementWithLinearTranslationAnimationWithDurationAndEasing [

<sampleInstance>
| container animation |
animation := self linearTranslationAnimationWithDurationAndEasing.
container := self containerWithOneElement.
Expand All @@ -111,7 +115,7 @@ BlTransformationAnimationTest >> testElementWithLinearTranslationAnimationWithDu

{ #category : #tests }
BlTransformationAnimationTest >> testLinearTranslationAnimation [

<sampleInstance>
| animation |
animation := BlTransformAnimation new.
animation transform
Expand All @@ -127,7 +131,7 @@ BlTransformationAnimationTest >> testLinearTranslationAnimation [

{ #category : #tests }
BlTransformationAnimationTest >> testLinearTranslationAnimationWithDelayAndLoop [

<sampleInstance>
| animation |
animation := BlTransformAnimation new.
animation transform
Expand All @@ -146,7 +150,7 @@ BlTransformationAnimationTest >> testLinearTranslationAnimationWithDelayAndLoop

{ #category : #tests }
BlTransformationAnimationTest >> testLinearTranslationAnimationWithDurationAndEasing [

<sampleInstance>
| animation |
animation := BlTransformAnimation new.
animation transform
Expand Down
2 changes: 1 addition & 1 deletion src/Bloc-DevTool/BlDevHalosEventListenerExamples.class.st
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ I exemplify {{gtClass:BlDevHalosEventListener}}.
"
Class {
#name : #BlDevHalosEventListenerExamples,
#superclass : #BlExamplesTest,
#superclass : #BlExampleTest,
#category : #'Bloc-DevTool-Examples'
}

Expand Down
26 changes: 0 additions & 26 deletions src/Bloc-Docs/BlElementOnAddedToSceneGraphExplanation.class.st

This file was deleted.

Loading