Skip to content

Commit

Permalink
adding text and events
Browse files Browse the repository at this point in the history
  • Loading branch information
Ducasse committed Aug 2, 2024
1 parent d718436 commit 19eae05
Show file tree
Hide file tree
Showing 3 changed files with 219 additions and 46 deletions.
20 changes: 20 additions & 0 deletions Chapters/bloc/events.md
Original file line number Diff line number Diff line change
Expand Up @@ -266,4 +266,24 @@ 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`.

```
| 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.
space := BlSpace new.space root addChildren: { elt1 . elt2 }. elt2
addEventHandlerOn: BlDropEvent
do: [ :evt | evt gestureSource inspect ].elt1
addEventHandlerOn: BlDragEndEvent
do: [ :evt | ]. space show.
```


Expand Down
84 changes: 84 additions & 0 deletions Chapters/bloc/text.md
Original file line number Diff line number Diff line change
Expand Up @@ -171,3 +171,87 @@ BlElement new
whose result is shown in Figure *@rect@*.

![Rectangle with numbers.](figures/rectangleWithNumbers.png width=60&label=rect)



### BlText vs. BlTextElement

You have 2 different levels to manage text in Bloc.
- `BlText` and its subclass `BlRopedText` create a text model where you can specify its attributes and style.
- `BlTextElement` and its subclasses will properly display the text inside a Bloc element.

A small example. You can notice that `BlText` background is different from `BlTextElement` background.

```smalltalk
| labelText label |
labelText := 'hello from bloc' asRopedText
background: Color orange ;
fontSize: 75;
fontName: 'Source Code Pro';
italic;
underline;
underlineColor: Color red;
vertical.
(labelText from: 1 to: 5) foreground: Color blue.
(labelText from: 7 to: 11) foreground: Color white.
(labelText from: 12 to: 15) foreground: Color red.
label := (BlTextElement text: labelText) position: 50 @ 10; background: Color yellow.
```

you can define the style of your text through BlTextAttributesStyler

````smalltalk
text := 'Hi John' asRopedText.
styler := BlTextAttributesStyler on: (text from: 3 to: 7).
styler
bold;
italic;
fontSize: 30;
fontName: 'Roboto';
monospace;
foreground: Color green.
styler style.
```
or using a fluent API
````smalltalk
text := 'Hi John' asRopedText.
(text from: 3 to: 7) stylerDo: [ :aStyler | aStyler bold italic foreground: Color red ].
````

As you may have noticed, this gives you a very fine-grained control over the style of your text.
You also need to re-specify attributes when your text changes.
If you want all your text to use the same attribute, you can then use `BlAttributedTextElement`.
You can then change your text, `BlAttributedTextElement` will reuse its attributes.


```smalltalk
text := 'Hi John' asRopedText.
element := BlAttributedTextElement new.
attributes := element attributesBuilder
foreground: Color green;
monospace;
bold;
italic;
fontSize: 30;
fontName: 'Roboto';
monospace.
label := (element text: text)
position: 50 @ 10;
background: Color yellow;
margin: (BlInsets all: 2);
padding: (BlInsets all: 2);
outskirts: BlOutskirts centered;
border: (BlBorder paint: Color red width: 2).
element text: 'hello world' asRopedText.
label.
```


161 changes: 115 additions & 46 deletions Chapters/toplo/skinningAWidget.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ The first thing that we should do is to make `ToNumberInputElement` inherit from
ToElement << #ToNumberInputElement
slots: { #plus . #minus . #inputValue . #value . #inputLabel };
tag: 'Input';
package: 'myBecherBloc'
package: 'Bloc-Book'
```

### Define a skin
Expand All @@ -33,11 +33,13 @@ We define a skin

```
ToRawSkin << #ToInputElementSkin
package: 'myBecherBloc'```
package: 'Bloc-Book'
```

We will now define action that should be done when the skin is installed.
We will now define the actions that should be done when the skin is installed.
Here for example we can change the border, background color and more.
Note that we can access the theme token properties using the message `valueOfTokenNamed:` or decide that
can simply use values specific to this skin.

```
ToInputElementSkin >> installLookEvent: anEvent
Expand All @@ -48,15 +50,16 @@ ToInputElementSkin >> installLookEvent: anEvent
e border: (BlBorder
paint: (e valueOfTokenNamed: #'color-border')
width: (e valueOfTokenNamed: #'line-width')).
e background: e backgroundPaint.
e background: Color red.
e geometry: (BlRoundedRectangleGeometry cornerRadius: 20).
e plus background: Color blue.
e minus background: Color red ]
```

In the `ToNumberInputElement` we define the method


Notice that two following forms are equivalent:
##### Remark
Notice that the two following forms are equivalent.
This is important if you want to maximize

```
anEvent elementDo: [ :e |
Expand All @@ -66,111 +69,177 @@ target := anEvent currentTarget.
target border: target valueOfTokenNamed: #'color-border-checkable’)
```

### Declaring the skin

The last step is to declare the skin to be used by the element.
To do so we define the method `newRawSkin` in the class `ToNumberInputElement`.

```
ToNumberInputElement >> newRawSkin
"Allow to create an instance of the widget skin"
^ ToInputElementSkin new
```


Update the following instance method.

```
ToNumberInputElement >> initialize
super initialize.
self size: self inputExtent.
self background: self backgroundPaint.
self layout: BlFrameLayout new.
self constraintsDo: [ :c |
c vertical fitContent.
c horizontal fitContent ].
self padding: (BlInsets all: 30).
self layout: BlLinearLayout horizontal.
self border: (BlBorder paint: Color pink).
self initializePlusButton.
self validateValueBlock: [ :v | v between: 1 and: 25 ].
self label: 'Input'.
self initializeMinusButton.
self initializeInputValue: 20.
self label: 'Input'.
self initializePlusButton
```

### Decorating a BlElement to get a ToElement
We can now open

```
BlNumberInputElement << #ToNumberInputElement traits: {TToElement}
ToNumberInputElement class >> openInputWithSkin

<script>
| space anInput |
space := BlSpace new.
space toTheme: ToRawSkin new.
anInput := self new position: 200 @ 200.
space root addChild: anInput.
space show.
^ anInput
```
### Define a theme that extends an existing one
Here we show that we can refine an existing theme.
```
ToNumberInputElement >> initialize
super initialize.
self initializeForToplo
ToRawTheme << #ToNewTheme
package: 'Bloc-Book'
```
??? we should check if the following is necessary
```
ToNumberInputElement >> onAddedToSceneGraph
ToNewTheme class >> defaultTokenProperties
"define here token properties of the widget theme"

super onAddedToSceneGraph.
self ensuredSkinManager requestInstallSkinIn: self.
self addEventHandler: ToSkinStateGenerator new
^ super defaultTokenProperties ,
{ (ToTokenProperty
name: #'background-color'
value: Color lightGreen) }
```
Now we are ready to open the
```
ToNumberInputElement class >> openInputWithSkin

<script>
| space anInput |
space := BlSpace new.
space toTheme: ToNewTheme new.
anInput := self new position: 200 @ 200.
space root addChild: anInput.
space show.
^ anInput
```
### Decorating a BlElement to get a ToElement
In the previous section,ent we said that the class has to inherit from `ToElement`,
this is not entirely true you can also use the trait `TToElement` in the class
either directly or in a subclass as in the following definition.
```
BlNumberInputElement << #ToNumberInputElement
traits: {TToElement};
package: 'Bloc-Book'
```
Since it does not make much sense to have both a non-skinnable widget and its skinnable
version (except in a tutorial) we believe that inheriting from `ToElement` will be the way to
define skinnable widget.
### Define a theme that extends an existing one

we also define a theme

When you use a trait you should also refine the initialize method to invoke the trait initialization.
```
ToRawTheme << #ToInputElementTheme
package: 'Mooflod'
ToNumberInputElement >> initialize
super initialize.
self initializeForToplo
```
SD: we should check if the following is necessary
```
ToInputElementTheme class >> defaultTokenProperties
"define here token properties of the widget theme"
ToNumberInputElement >> onAddedToSceneGraph

^ super defaultTokenProperties ,
{ (ToTokenProperty
name: #'background-color'
value: Color lightGreen) }
super onAddedToSceneGraph.
self ensuredSkinManager requestInstallSkinIn: self.
self addEventHandler: ToSkinStateGenerator new
```
```
ToNumberInputElement class >> openInputWithSkin <script> | space anInput | space := BlSpace new. space toTheme: ToInputElementTheme new. anInput := self new position: 200 @ 200. space root addChild: anInput. space show. ^ anInput
```
### Autonome theme
We should now how we can define a full new theme.
We will
- define a theme class
- define a skin class acting a root for the skins
- a specific skin for the widget
#### Defining a new theme
```
ToTheme << #ToMooflooTheme slots: {}; tag: 'Input'; package: 'myBecherBloc'
ToTheme << #ToNewTheme
tag: 'Input';
package: 'Bloc-Book'
```
```
ToMooflooThemenewSkinInstanceFor: anElement ^ anElement newMooflooSkin
ToNewTheme >> newSkinInstanceFor: anElement

^ anElement newNewThemeSkin
```
```
ToNumberInputElement class >> openInputWithSkin <script> | space anInput | space := BlSpace new. space toTheme: ToMooflooTheme new. anInput := self new position: 200 @ 200. space root addChild: anInput. space show. ^ anInput
ToNumberInputElement class >> openInputWithSkin

<script>
| space anInput |
space := BlSpace new.
space toTheme: ToNewTheme new.
anInput := self new position: 200 @ 200.
space root addChild: anInput.
space show.
^ anInput
```
```
BlElement >> newMooflooSkin ^ ToBasicMooflooSkin new
BlElement >> newNewThemeSkin

^ ToBasicMooflooSkin new
```
```
ToNumberInputElement >> newMooflooSkin ^ ToInputElementSkin new
ToNumberInputElement >> newNewThemeSkin

^ ToInputElementSkin new
```
### Using a stylesheet

0 comments on commit 19eae05

Please sign in to comment.