Skip to content

Commit

Permalink
Merge pull request #1455 from Ducasse/enhNotificationCenter
Browse files Browse the repository at this point in the history
Enh notification center
estebanlm authored Oct 17, 2023
2 parents a529b1f + 0e02ff7 commit 64b06c1
Showing 7 changed files with 280 additions and 5 deletions.
22 changes: 17 additions & 5 deletions src/Spec2-Core/SpApplication.class.st
Original file line number Diff line number Diff line change
@@ -50,7 +50,8 @@ Class {
'properties',
'configuration',
'iconManager',
'iconProvider'
'iconProvider',
'notificationCenter'
],
#classVars : [
'DefaultApplication'
@@ -285,11 +286,22 @@ SpApplication >> newPresenter: aPresenterClass [
^ aPresenterClass newApplication: self
]

{ #category : 'ui - notifying' }
SpApplication >> notify: aSpecNotification [
"how notifications are handled depends on the backend"
{ #category : 'accessing' }
SpApplication >> notificationCenter [
"should be placed in initialize."
^ notificationCenter ifNil: [ notificationCenter := SpNotificationCenter new forApplication: self; yourself ]
]

{ #category : 'ui - dialogs' }
SpApplication >> notificationClass [

^ SpNotificationItem
]

{ #category : 'ui - dialogs' }
SpApplication >> notify: aString [

aSpecNotification dispatchTo: self backend
self notificationCenter add: (self notificationClass with: aString)
]

{ #category : 'accessing - properties' }
68 changes: 68 additions & 0 deletions src/Spec2-Core/SpNotificationCenter.class.st
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
"
I'm a simple object holding a limited list of notification items.
"
Class {
#name : #SpNotificationCenter,
#superclass : #Object,
#instVars : [
'items',
'limit',
'application'
],
#category : #'Spec2-Core-Notification'
}

{ #category : #adding }
SpNotificationCenter >> add: aSpNotificationItem [
items size > limit
ifTrue: [ items removeLast: self bulkSize ].
items addFirst: aSpNotificationItem.
self updateIfNecessary.
]

{ #category : #accessing }
SpNotificationCenter >> application [
^ application
]

{ #category : #adding }
SpNotificationCenter >> bulkSize [
"Returns the number of itesm that should be removed when the limit is reached.
Pay attention that the limit MUST always be larger than bulkSize"

^ 5
]

{ #category : #adding }
SpNotificationCenter >> forApplication: app [

application := app
]

{ #category : #initialization }
SpNotificationCenter >> initialize [

super initialize.
"Pay attention limit must not smaller than bulkSize because else
we will try to remove more elements than the number we have."
limit := 30.
items := OrderedCollection new.
]

{ #category : #accessing }
SpNotificationCenter >> items [
^ items
]

{ #category : #accessing }
SpNotificationCenter >> limit [
^ limit
]

{ #category : #adding }
SpNotificationCenter >> updateIfNecessary [

| notifs |
notifs := self application windows select: [ :each | each presenter class = SpNotificationCenterPresenter ].
notifs do: [ :each | each presenter updatePresenter ]
]
27 changes: 27 additions & 0 deletions src/Spec2-Core/SpNotificationItem.class.st
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
"
I'm a simple object representing a notification.
"
Class {
#name : #SpNotificationItem,
#superclass : #Object,
#instVars : [
'text'
],
#category : #'Spec2-Core-Notification'
}

{ #category : #'instance creation' }
SpNotificationItem class >> with: aString [

^ self new text: aString ; yourself
]

{ #category : #accessing }
SpNotificationItem >> text [
^ text
]

{ #category : #accessing }
SpNotificationItem >> text: aString [
text := aString
]
5 changes: 5 additions & 0 deletions src/Spec2-Core/SpPresenter.class.st
Original file line number Diff line number Diff line change
@@ -738,6 +738,11 @@ SpPresenter >> localeChanged [

]

{ #category : 'simple dialog helpers' }
SpPresenter >> notify: aString [
self application notify: aString
]

{ #category : 'private' }
SpPresenter >> okToChange [

90 changes: 90 additions & 0 deletions src/Spec2-Dialogs/SpNotificationCenterPresenter.class.st
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
Class {
#name : #SpNotificationCenterPresenter,
#superclass : #SpPresenterWithModel,
#instVars : [
'itemList',
'descriptionText',
'clearButton'
],
#category : #'Spec2-Dialogs'
}

{ #category : #examples }
SpNotificationCenterPresenter class >> example2 [

<example>
| app notificationPresenter |
app := SpApplication new.
notificationPresenter := self newApplication: app model: app notificationCenter.
notificationPresenter open.
^ app inspect
"1 to: 10 do: [ :each | app notify: each printString ]"
]

{ #category : #initialization }
SpNotificationCenterPresenter >> clearNotificationsAction [

itemList items: OrderedCollection new.
descriptionText text: ' No notification '
]

{ #category : #initialization }
SpNotificationCenterPresenter >> connectPresenters [

"Why this is not working
itemList whenSelectedItemChangedDo: [ :each | descriptionText text: each text]."

itemList whenSelectedDo: [ :each | each ifNotNil: [descriptionText text: each text]]

]

{ #category : #layout }
SpNotificationCenterPresenter >> defaultLayout [

| upperLayout lowerLayout |
upperLayout := SpBoxLayout newLeftToRight
addLast: clearButton;
yourself.
lowerLayout := SpPanedLayout newTopToBottom
positionOfSlider: 0.8;
add: itemList;
add: descriptionText;
yourself.
^ SpBoxLayout newTopToBottom
add: upperLayout expand: false;
add: lowerLayout;
yourself
]

{ #category : #initialization }
SpNotificationCenterPresenter >> initializePresenters [

itemList := self newList
display: [ :each | ' ' , each text contractTo: 20 ];
yourself.
descriptionText := self newText.
clearButton := self newButton
icon: (self iconNamed: #smallUpdate);
label: 'Clear notifications';
action: [ self clearNotificationsAction ];
yourself
]

{ #category : #initialization }
SpNotificationCenterPresenter >> initializeWindow: aWindowPresenter [

aWindowPresenter title: 'Notifications'
]

{ #category : #initialization }
SpNotificationCenterPresenter >> modelChanged [

itemList items: announcingObject value items.
itemList selectFirst
]

{ #category : #updating }
SpNotificationCenterPresenter >> updatePresenter [

self modelChanged
]
54 changes: 54 additions & 0 deletions src/Spec2-Tests/SpNotificationCenterTest.class.st
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
Class {
#name : 'SpNotificationCenterTest',
#superclass : 'TestCase',
#category : 'Spec2-Tests-Notifications',
#package : 'Spec2-Tests',
#tag : 'Notifications'
}

{ #category : 'tests' }
SpNotificationCenterTest >> testAddAnItemAddsIt [

| f center |
f := SpNotificationItem with: 'first'.
center := SpApplication new notificationCenter.
center add: f.
self assert: center items first text equals: 'first'
]

{ #category : 'tests' }
SpNotificationCenterTest >> testAddingOverTheLimitCutFirst [

| f center |
center := SpApplication new notificationCenter.
1 to: 35 do: [ :each |
f := SpNotificationItem with: each printString.
center add: f ] .

self assert: center items size equals: center limit
]

{ #category : 'tests' }
SpNotificationCenterTest >> testAddingOverTheLimitRemoveBuldElements [

| f center |
center := SpApplication new notificationCenter.
1 to: 32 do: [ :each |
f := SpNotificationItem with: each printString.
center add: f ] .

"when we added 31 we removed buld elements (5) and added 31 and 32 so we have 27 elements"
self assert: center items size equals: center limit - center bulkSize + (32 - center limit)
]

{ #category : 'tests' }
SpNotificationCenterTest >> testItemsAreOrderedLIFO [

| f center f2 |
f := SpNotificationItem with: 'first'.
center := SpApplication new notificationCenter.
center add: f.
f2 := SpNotificationItem with: 'second'.
center add: f2.
self assert: center items first text equals: 'second'
]
19 changes: 19 additions & 0 deletions src/Spec2-Tests/SpNotificationTest.class.st
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
Class {
#name : 'SpNotificationTest',
#superclass : 'TestCase',
#category : 'Spec2-Tests-Notifications',
#package : 'Spec2-Tests',
#tag : 'Notifications'
}

{ #category : 'tests' }
SpNotificationTest >> testNotificationIsKeptAround [

| pres app |
app := SpApplication new.
pres := SpPresenter newApplication: app.
pres notify: 'You should see this notification'.
self
assert: app notificationCenter items first text
equals: 'You should see this notification'
]

0 comments on commit 64b06c1

Please sign in to comment.