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

Removing voyage from the tutorial #10

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
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
80 changes: 51 additions & 29 deletions SmallTODO-Tutorial-1.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,21 +12,7 @@ It will look like Figure *@taskManager@*.


## Requirements

We will use Voyage to keep our small database, but since this will not be very big and we want to keep things simple, we will use an "in-memory" version of it. You can install it in your image executing:

```Smalltalk
Metacello new
repository: 'github://pharo-nosql/voyage';
baseline: 'Voyage';
load: 'memory tests'.
```

Then you can create the in-memory repository we are going to use during this tutorial.

```Smalltalk
VOMemoryRepository new enableSingleton.
```
Any additionnal tool is needed for this tutorial.

### A TODOTask class
Since this application will show and support the edition of a simple TODO list, we need to create a class that models the task. We are going to have the simplest approach possible for this example, but it is clear that it can be a lot more complex.
Expand All @@ -48,21 +34,46 @@ TODOTask >> done: aBoolean

TODOTask >> isDone
^ done

TODOTask class >> isVoyageRoot
^ true

TODOTask >> initialize

super initialize.
self done: false
```
How can we save the created tasks. Let `TODOTask class handles that`.
```smalltalk
TODOTask class
instanceVariableNames: 'tasks'

TODOTask class >> tasks
^ tasks ifNil: [ tasks := OrderedCollection new ]

TODOTask class >> new
|instance|
instance := super new.
self tasks add: instance.
^ instance
```

And let's create a couple of testing tasks:

```Smalltalk
TODOTask new title: 'Task One'; save.
TODOTask new title: 'Task Two'; save.
TODOTask tasks size. "0"

TODOTask new
title: 'Task One'.

TODOTask new
title: 'Task Two'.

TODOTask tasks size. "2"
```

Sometimes, we will need to clear the created tasks:
```Smalltalk
TODOTask class >> reset

tasks := OrderedCollection new.
```

## Creating your application
Expand Down Expand Up @@ -132,10 +143,11 @@ And now, we need to give our TODO list the tasks to display:
```Smalltalk
TODOListPresenter >> updatePresenter

todoListPresenter items: TODOTask selectAll asOrderedCollection
todoListPresenter items: TODOTask tasks asOrderedCollection
```

Note we send `asOrderedCollection` message to the list of tasks. This is because a table presenter receives an `OrderedCollection` as items, so we make sure we have the list as the presenter expects.
Note we send `asOrderedCollection` message to the list of tasks. This is because a table presenter receives an `OrderedCollection` as items, so we make sure we have the list as the presenter expects.
(But if you have followed carefully, `TODOTask class tasks` already returns an OrderedCollection. You can then avoid the message asOrderedCollection. We just want you to keep in mind that **a table presenter receives an `OrderedCollection` as items**).

## How does this look?

Expand Down Expand Up @@ -247,7 +259,8 @@ TODOTaskPresenter >> initializePresenters

```Smalltalk
TODOTaskPresenter >> updatePresenter
titlePresenter text: (aTask title ifNil: [ '' ])
titlePresenter
text: (task ifNil: [ '' ] ifNotNil: [task title])

```

Expand Down Expand Up @@ -278,14 +291,13 @@ Here, along with the already known `title:` and `initialExtent:` we added
- `addButton: 'Save' do: [ ... ]`. This will add buttons to our dialog window. And you need to define its behavior (the `accept` method).
- `addButton: 'Cancel' do: [ ... ]`. This is the same as the positive action, but here we do not want to do anything, that's why we just send `dialog close`.

How would be the `accept` method? Thanks to Voyage, very simple.
How would be the `accept` method ?

```Smalltalk
TODOTaskPresenter >> accept

self task
title: titlePresenter text;
save.
title: titlePresenter text.
```

**Tip:** You can try your dialog even if not yet integrated to your application by executing
Expand Down Expand Up @@ -319,7 +331,8 @@ TODOListPresenter >> initializePresenters
action: [ self addTask ];
yourself.

self layout: (SpBoxLayout newVertical
self layout: (SpBoxLayout newVertical
spacing: 5;
add: todoListPresenter;
add: (SpBoxLayout newHorizontal
addLast: addButton expand: false;
Expand Down Expand Up @@ -383,7 +396,7 @@ TODOListPresenter >> initializePresenters
yourself);
addColumn: (SpStringTableColumn
title: 'Title'
evaluated: [:task | task title);
evaluated: [:task | task title]);
contextMenu: self todoListContextMenu;
yourself.

Expand Down Expand Up @@ -442,9 +455,18 @@ TODOListPresenter >> removeSelectedTask
self updatePresenter
```

As you see, `editSelectedTask` is almost equal to `addTask` but instead of adding a new task, it takes the selected task in our table by sending `todoListPresenter selection selectedItem`.
As yogit u see, `editSelectedTask` is almost equal to `addTask` but instead of adding a new task, it takes the selected task in our table by sending `todoListPresenter selection selectedItem`.
Remove simply takes the selected item and send the `remove` message.

Now we need to make aTODOTask understand this last message.
```smalltalk
TODOTask >> remove
self class remove: self

TODOTask class >> tasks
tasks remove: aTODOTask
```

![First full version of the Task List Manager ](figures/figure4.png?width=80&label=fig4)

## Switching the backend to Gtk
Expand Down
2 changes: 1 addition & 1 deletion src/TODO/TODOApplication.class.st
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,5 @@ Class {
{ #category : #running }
TODOApplication >> start [

(self new: TODOListPresenter) openWithSpec
(TODOListPresenter newApplication: self) open
]
28 changes: 16 additions & 12 deletions src/TODO/TODOListPresenter.class.st
Original file line number Diff line number Diff line change
Expand Up @@ -7,36 +7,37 @@ Class {
#category : #TODO
}

{ #category : #actions }
{ #category : #initialization }
TODOListPresenter >> addTask [

(TODOTaskPresenter newApplication: self application)
task: TODOTask new;
openModalWithSpec.
openModal.
self updatePresenter
]

{ #category : #actions }
{ #category : #initialization }
TODOListPresenter >> editSelectedTask [

(TODOTaskPresenter newApplication: self application)
task: todoListPresenter selection selectedItem;
openModalWithSpec.
openModal.
self updatePresenter

]

{ #category : #initialization }
TODOListPresenter >> initializePresenters [
| addButton |

todoListPresenter := self newTable
addColumn: ((SpCheckBoxTableColumn evaluated: #isDone)
addColumn: ((SpCheckBoxTableColumn evaluated: [:task | task isDone])
width: 20;
onActivation: [ :task | task done: true ];
onDeactivation: [ :task | task done: false ];
yourself);
addColumn: (SpStringTableColumn title: 'Title' evaluated: #title);
addColumn: (SpStringTableColumn
title: 'Title'
evaluated: [:task | task title]);
contextMenu: self todoListContextMenu;
yourself.

Expand All @@ -63,7 +64,7 @@ TODOListPresenter >> initializeWindow: aWindowPresenter [
initialExtent: 500@500
]

{ #category : #actions }
{ #category : #initialization }
TODOListPresenter >> removeSelectedTask [

todoListPresenter selection selectedItem remove.
Expand All @@ -74,13 +75,16 @@ TODOListPresenter >> removeSelectedTask [
TODOListPresenter >> todoListContextMenu [

^ self newMenu
addItem: [ :item | item name: 'Edit...'; action: [ self editSelectedTask ] ];
addItem: [ :item | item name: 'Remove'; action: [ self removeSelectedTask ] ]

addItem: [ :item | item
name: 'Edit...';
action: [ self editSelectedTask ] ];
addItem: [ :item | item
name: 'Remove';
action: [ self removeSelectedTask ] ]
]

{ #category : #initialization }
TODOListPresenter >> updatePresenter [

todoListPresenter items: TODOTask selectAll asOrderedCollection
todoListPresenter items: TODOTask tasks asOrderedCollection
]
29 changes: 26 additions & 3 deletions src/TODO/TODOTask.class.st
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,28 @@ Class {
#category : #TODO
}

{ #category : #testing }
TODOTask class >> isVoyageRoot [
{ #category : #accessing }
TODOTask class >> new [
|instance|
instance := super new.
self tasks add: instance.
^ instance
]

^ true
{ #category : #removing }
TODOTask class >> remove: aTODOTask [
tasks remove: aTODOTask
]

{ #category : #accessing }
TODOTask class >> reset [
<script>
tasks := OrderedCollection new.
]

{ #category : #accessing }
TODOTask class >> tasks [
^ tasks ifNil: [ tasks := OrderedCollection new ]
]

{ #category : #accessing }
Expand All @@ -32,6 +50,11 @@ TODOTask >> isDone [
^ done
]

{ #category : #removing }
TODOTask >> remove [
self class remove: self
]

{ #category : #accessing }
TODOTask >> title [
^ title
Expand Down
25 changes: 15 additions & 10 deletions src/TODO/TODOTaskPresenter.class.st
Original file line number Diff line number Diff line change
Expand Up @@ -8,35 +8,34 @@ Class {
#category : #TODO
}

{ #category : #actions }
{ #category : #accessing }
TODOTaskPresenter >> accept [

self task
title: titlePresenter text;
save
title: titlePresenter text.
]

{ #category : #initialization }
TODOTaskPresenter >> initializeDialogWindow: aDialogWindowPresenter [
{ #category : #accessing }
TODOTaskPresenter >> initializeDialogWindow: aDialogWindowPresenter [

aDialogWindowPresenter
title: 'New task';
initialExtent: 350@120;
addButton: 'Accept' do: [ :dialog |
addButton: 'Accept' do: [ :dialog |
self accept.
dialog close ];
addButton: 'Cancel' do: [ :dialog |
dialog close ]
]

{ #category : #initialization }
{ #category : #accessing }
TODOTaskPresenter >> initializePresenters [

titlePresenter := self newTextInput.

self layout: (SpBoxLayout newVertical
add: titlePresenter expand: false;
yourself).
add: titlePresenter expand: false;
yourself).
]

{ #category : #accessing }
Expand All @@ -47,5 +46,11 @@ TODOTaskPresenter >> task [
{ #category : #accessing }
TODOTaskPresenter >> task: aTask [
task := aTask.
titlePresenter text: (aTask title ifNil: [ '' ])
self updatePresenter
]

{ #category : #accessing }
TODOTaskPresenter >> updatePresenter [
titlePresenter
text: (task ifNil: [ '' ] ifNotNil: [task title])
]