Many refactors. pharo 9 en windows is working really bad

This commit is contained in:
sbragagnolo 2020-05-10 22:38:20 +02:00
parent ae12fe9576
commit 9cf21cb38b
80 changed files with 7652 additions and 7550 deletions

View File

@ -1,28 +1,28 @@
"
I provide some convenience functionality to work with files.
"
Class {
#name : #FileUtils,
#superclass : #Object,
#category : #'Grafoscopio-Model'
}
{ #category : #utilities }
FileUtils class >> createFilesNamed: fileNames endingWith: fileExtension intoFolder: aFolder [
| createdFiles fullFileName existingFiles typedFileName |
createdFiles := OrderedCollection new.
existingFiles := OrderedCollection new.
fileNames do: [ :eachFile |
typedFileName := eachFile, fileExtension.
fullFileName := aFolder / typedFileName.
fullFileName exists
ifFalse: [
fullFileName ensureCreateFile.
createdFiles add: fullFileName basename ]
ifTrue: [existingFiles add: fullFileName basename ]].
^ (Dictionary new
at: 'created files' put: createdFiles;
at: 'existing files' put: existingFiles;
yourself)
]
"
I provide some convenience functionality to work with files.
"
Class {
#name : #FileUtils,
#superclass : #Object,
#category : #'Grafoscopio-Model'
}
{ #category : #utilities }
FileUtils class >> createFilesNamed: fileNames endingWith: fileExtension intoFolder: aFolder [
| createdFiles fullFileName existingFiles typedFileName |
createdFiles := OrderedCollection new.
existingFiles := OrderedCollection new.
fileNames do: [ :eachFile |
typedFileName := eachFile, fileExtension.
fullFileName := aFolder / typedFileName.
fullFileName exists
ifFalse: [
fullFileName ensureCreateFile.
createdFiles add: fullFileName basename ]
ifTrue: [existingFiles add: fullFileName basename ]].
^ (Dictionary new
at: 'created files' put: createdFiles;
at: 'existing files' put: existingFiles;
yourself)
]

View File

@ -1,139 +1,139 @@
"
Please comment me using the following template inspired by Class Responsibility Collaborator (CRC) design:
I'm FontAwesomeIcons, a custom selection of some icons in this font family used for the GUI of grafoscopio.
For the Responsibility part: Three sentences about my main responsibility, what I'm doing, what services do I offer.
For the Collaborators Part: State my main collaborators and one line about how I interact with them.
Public API and Key Messages
- message one
- message two
- what is the way to create instances is a plus.
One simple example is simply gorgeous.
Internal Representation and Key Implementation Points.
Instance Variables
icons: <Object>
Implementation Points
"
Class {
#name : #FontAwesomeIcons,
#superclass : #Object,
#instVars : [
'icons'
],
#classVars : [
'Current'
],
#category : #'Grafoscopio-UI'
}
{ #category : #'accessing - icons' }
FontAwesomeIcons >> copyIcon [
"Private - Generated method"
^Form fromBinaryStream: (Base64MimeConverter mimeDecodeToBytes: self copyIconContents readStream)
]
{ #category : #'private - contents' }
FontAwesomeIcons >> copyIconContents [
"Private - Method generated with the content of the file File @ /home/offray/Programas/Grafoscopio/Dev/Common/Icons/FontAwesome/Png/copy.png"
^ 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAA2UlEQVR4nJXQIU6DQRAF4K+F
4DAYVFHlBEgctQgScL0DCbp3wKNJOAIXQDcEC5iqQoNsA4KkiO6GJX92/p+XvGxm983bN8Mv
+rjFOnFYMNchbvCNSWooUTXopfMalxhjipfiLRucYg9bxf0zXCXBJP1yUkmwxhyviTN8wVsh
yHwsms/wiSUuivu8m3BBR1hglH5tGGxXGmGAO5zjIdBVE9xrjnb8nwQjHBb1ymaJfxAZ7NjM
HSIbHLQJIzxpzpoZYdim6WTQ7xayjmiJ7x1SLHrB4y72Www+fgBc9T/67LlhnQAAAABJRU5E
rkJggg=='
]
{ #category : #'accessing - icons' }
FontAwesomeIcons >> cutIcon [
"Private - Generated method"
^Form fromBinaryStream: (Base64MimeConverter mimeDecodeToBytes: self cutIconContents readStream)
]
{ #category : #'private - contents' }
FontAwesomeIcons >> cutIconContents [
"Private - Method generated with the content of the file File @ /home/offray/Programas/Grafoscopio/Dev/Common/Icons/FontAwesome/Png/cut.png"
^ 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABOUlEQVR4nNXSzyvlYRTH8Rcu
N5dmIt2FX4VpJktRUpKssB//wGSDUsrCahYzuykaGyk/YiFlb2VhYWVhYaUkKxsbTSYSYfE9
V3e+EQub+dRTz4/zvM85n+fhHXSNhxhX+IHSV+50IVNYbKAKn7EeoO8vXOyNmHFsolFMirWD
89TeFyxhEuXoxjI+ZPAVFZjHX+SRQz3uMINbTOMCoxEzinsYwlGRDw/4iX2s4VNUkcUvDD/X
Wwna0Y8WLGI7snSgGatx9o8KTn4MQB6VqA1ITuL4IP5E76dpyBQuUy0shGmHElPLI3YSs+HZ
k+4kb98QlewGMIsyfMMKOiO+B1toKgDmimC5yHqSqjIb2efRhrqAtGbQhxHJs41JXB9JAW7w
G9WYkHygY5zBQfR9jz0MpE16i2ok7v+HegQfqT9MAMiDKwAAAABJRU5ErkJggg=='
]
{ #category : #'accessing - icons' }
FontAwesomeIcons >> html5Icon [
"Private - Generated method"
^Form fromBinaryStream: (Base64MimeConverter mimeDecodeToBytes: self html5IconContents readStream)
]
{ #category : #'private - contents' }
FontAwesomeIcons >> html5IconContents [
"Private - Method generated with the content of the file File @ /home/offray/Programas/Grafoscopio/Dev/Common/Icons/FontAwesome/Png/html5.png"
^ 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAA+UlEQVR4nK3Tv0oDQRDH8c9J
BMFKJGIXBBtFwc7SUlDfwpewEewsbQQL8QHsA2lSiK2NCFr4Av4hjYigVSxuV/bWjRhxYJhl
9uY7v9m9rdR2ikm/tx7OoRUSO5gfA3AfFxMhPo9RDE85ICZ2Uf3gNzkgjhAVzIV4hJlC58Vc
cQ5oh7iJpb+MEBUsF+Snh/wNkI9QsqjuFe+jABu4xgDDxFcS+Ff30ggDrOEs6/6YKGgA8kOc
DfEQV+jgMoDb2bcNm0rkHqv/zOmwt4o93IX9kxIAXjTn/sBDlhviYBRgH7eFguhv6GI9LaoK
oA62sYUF9NWv70Jyff9mnwBsQJo0owsMAAAAAElFTkSuQmCC'
]
{ #category : #'accessing - icons' }
FontAwesomeIcons >> pasteIcon [
"Private - Generated method"
^Form fromBinaryStream: (Base64MimeConverter mimeDecodeToBytes: self pasteIconContents readStream)
]
{ #category : #'private - contents' }
FontAwesomeIcons >> pasteIconContents [
"Private - Method generated with the content of the file File @ /home/offray/Programas/Grafoscopio/Dev/Common/Icons/FontAwesome/Png/paste.png"
^ 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAqUlEQVR4nK3TTQrBQRzG8c/I
yk6SsrAilk5hYWfjWA6hXICycwtLByDJ2upvgZrG6+BbU7+3nnnmVxNQuDDC2j09LK5xB5u4
WY7iUpLH9ZcUGaedrZ4wznWQzh0wQfjWwRB9TF33lStwwABHzFG5WfvkCfsH/Vl4MBgToriC
ZpS3sMxxkNJGkbuDO/4isPtFoIwu6km9hdUvwg2cvP8bu/BMAVXU3ly0PQOGrUCXHk1emQAA
AABJRU5ErkJggg=='
]
{ #category : #'accessing - icons' }
FontAwesomeIcons >> tagIcon [
"Private - Generated method"
^Form fromBinaryStream: (Base64MimeConverter mimeDecodeToBytes: self tagIconContents readStream)
]
{ #category : #'private - contents' }
FontAwesomeIcons >> tagIconContents [
"Private - Method generated with the content of the file File @ /home/offray/Programas/Grafoscopio/Dev/Common/Icons/FontAwesome/Png/tag.png"
^ 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAmUlEQVR4nKXPMQ4BQRSA4U9D
oeIgKsdwAUfARSSiUTmExgUcYU8gGoVGpZFIGM0WG5mxM0zyMpni/zKPP0+nvleYNN4BZyxx
yIGedfQ5L8xygIA7RhjjUYoEXNFDH7fIT+ZtQMARpy/rJJFLIorNIgasC4Ao0sW+EJn+i2xi
q+QiFQYxIAepMEzFbUhWnEKK4iayxe6XOOu8ARtNbaMQ63x5AAAAAElFTkSuQmCC'
]
{ #category : #'accessing - icons' }
FontAwesomeIcons >> tagsIcon [
"Private - Generated method"
^Form fromBinaryStream: (self tagsIconContents base64Decoded readStream)
]
{ #category : #'private - contents' }
FontAwesomeIcons >> tagsIconContents [
"Private - Method generated with the content of the file File @ /home/offray/Programas/Grafoscopio/Dev/Common/Icons/FontAwesome/Png/tags.png"
^ 'iVBORw0KGgoAAAANSUhEUgAAABAAAAANCAYAAACgu+4kAAAABHNCSVQICAgIfAhkiAAAAAlw
SFlzAAAOxAAADsQBlSsOGwAAAXRJREFUKJGN0j1Mk1EYxfH/edRFSKijH4kTJBgTJ0cGTdxE
TKyUGAfFSQcKUl3taIjIh3EUTJzaAoORwUGdmUlMXB1ktSaQGNp7HOyrgG8jZ733+d1zc69G
y9NvsC6RRbZhIxQLtkdtX5DjSW1x5hM5CdBtxGnjLUQf6IzQDSfXWu30EvTF4fdjE49GugCA
Wa8vPLuIufO3CSePRnxspzQr+3UKGnlIdGoPlMqV84ihfasdpJX8XLCch0RnZz/SJlD+p2OG
tNNcHhLA57y7dUOwl/YiKk48vCLFuuDYfyGz1Urp8pHQJNK4SUXZZqz8+GqS1w6DGL/j29fr
OnX2O6b1+9XhsIixbyX0M8Sa8Ys/AEBpqjJsa7ULYtt3JTexGoZX5070PtgHANycnL4mYuUA
YsO4TTNwHWlpsNBzv1qtpjh4TGN+9q1JRcPuntr3Av8IXAeWs2HIfn5OSlOVYayntmeON3tr
O4XtD4KNwUJPJRsG+AVxqr+5c/rf8wAAAABJRU5ErkJggg=='
]
"
Please comment me using the following template inspired by Class Responsibility Collaborator (CRC) design:
I'm FontAwesomeIcons, a custom selection of some icons in this font family used for the GUI of grafoscopio.
For the Responsibility part: Three sentences about my main responsibility, what I'm doing, what services do I offer.
For the Collaborators Part: State my main collaborators and one line about how I interact with them.
Public API and Key Messages
- message one
- message two
- what is the way to create instances is a plus.
One simple example is simply gorgeous.
Internal Representation and Key Implementation Points.
Instance Variables
icons: <Object>
Implementation Points
"
Class {
#name : #FontAwesomeIcons,
#superclass : #Object,
#instVars : [
'icons'
],
#classVars : [
'Current'
],
#category : #'Grafoscopio-UI'
}
{ #category : #'accessing - icons' }
FontAwesomeIcons >> copyIcon [
"Private - Generated method"
^Form fromBinaryStream: (Base64MimeConverter mimeDecodeToBytes: self copyIconContents readStream)
]
{ #category : #'private - contents' }
FontAwesomeIcons >> copyIconContents [
"Private - Method generated with the content of the file File @ /home/offray/Programas/Grafoscopio/Dev/Common/Icons/FontAwesome/Png/copy.png"
^ 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAA2UlEQVR4nJXQIU6DQRAF4K+F
4DAYVFHlBEgctQgScL0DCbp3wKNJOAIXQDcEC5iqQoNsA4KkiO6GJX92/p+XvGxm983bN8Mv
+rjFOnFYMNchbvCNSWooUTXopfMalxhjipfiLRucYg9bxf0zXCXBJP1yUkmwxhyviTN8wVsh
yHwsms/wiSUuivu8m3BBR1hglH5tGGxXGmGAO5zjIdBVE9xrjnb8nwQjHBb1ymaJfxAZ7NjM
HSIbHLQJIzxpzpoZYdim6WTQ7xayjmiJ7x1SLHrB4y72Www+fgBc9T/67LlhnQAAAABJRU5E
rkJggg=='
]
{ #category : #'accessing - icons' }
FontAwesomeIcons >> cutIcon [
"Private - Generated method"
^Form fromBinaryStream: (Base64MimeConverter mimeDecodeToBytes: self cutIconContents readStream)
]
{ #category : #'private - contents' }
FontAwesomeIcons >> cutIconContents [
"Private - Method generated with the content of the file File @ /home/offray/Programas/Grafoscopio/Dev/Common/Icons/FontAwesome/Png/cut.png"
^ 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABOUlEQVR4nNXSzyvlYRTH8Rcu
N5dmIt2FX4VpJktRUpKssB//wGSDUsrCahYzuykaGyk/YiFlb2VhYWVhYaUkKxsbTSYSYfE9
V3e+EQub+dRTz4/zvM85n+fhHXSNhxhX+IHSV+50IVNYbKAKn7EeoO8vXOyNmHFsolFMirWD
89TeFyxhEuXoxjI+ZPAVFZjHX+SRQz3uMINbTOMCoxEzinsYwlGRDw/4iX2s4VNUkcUvDD/X
Wwna0Y8WLGI7snSgGatx9o8KTn4MQB6VqA1ITuL4IP5E76dpyBQuUy0shGmHElPLI3YSs+HZ
k+4kb98QlewGMIsyfMMKOiO+B1toKgDmimC5yHqSqjIb2efRhrqAtGbQhxHJs41JXB9JAW7w
G9WYkHygY5zBQfR9jz0MpE16i2ok7v+HegQfqT9MAMiDKwAAAABJRU5ErkJggg=='
]
{ #category : #'accessing - icons' }
FontAwesomeIcons >> html5Icon [
"Private - Generated method"
^Form fromBinaryStream: (Base64MimeConverter mimeDecodeToBytes: self html5IconContents readStream)
]
{ #category : #'private - contents' }
FontAwesomeIcons >> html5IconContents [
"Private - Method generated with the content of the file File @ /home/offray/Programas/Grafoscopio/Dev/Common/Icons/FontAwesome/Png/html5.png"
^ 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAA+UlEQVR4nK3Tv0oDQRDH8c9J
BMFKJGIXBBtFwc7SUlDfwpewEewsbQQL8QHsA2lSiK2NCFr4Av4hjYigVSxuV/bWjRhxYJhl
9uY7v9m9rdR2ikm/tx7OoRUSO5gfA3AfFxMhPo9RDE85ICZ2Uf3gNzkgjhAVzIV4hJlC58Vc
cQ5oh7iJpb+MEBUsF+Snh/wNkI9QsqjuFe+jABu4xgDDxFcS+Ff30ggDrOEs6/6YKGgA8kOc
DfEQV+jgMoDb2bcNm0rkHqv/zOmwt4o93IX9kxIAXjTn/sBDlhviYBRgH7eFguhv6GI9LaoK
oA62sYUF9NWv70Jyff9mnwBsQJo0owsMAAAAAElFTkSuQmCC'
]
{ #category : #'accessing - icons' }
FontAwesomeIcons >> pasteIcon [
"Private - Generated method"
^Form fromBinaryStream: (Base64MimeConverter mimeDecodeToBytes: self pasteIconContents readStream)
]
{ #category : #'private - contents' }
FontAwesomeIcons >> pasteIconContents [
"Private - Method generated with the content of the file File @ /home/offray/Programas/Grafoscopio/Dev/Common/Icons/FontAwesome/Png/paste.png"
^ 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAqUlEQVR4nK3TTQrBQRzG8c/I
yk6SsrAilk5hYWfjWA6hXICycwtLByDJ2upvgZrG6+BbU7+3nnnmVxNQuDDC2j09LK5xB5u4
WY7iUpLH9ZcUGaedrZ4wznWQzh0wQfjWwRB9TF33lStwwABHzFG5WfvkCfsH/Vl4MBgToriC
ZpS3sMxxkNJGkbuDO/4isPtFoIwu6km9hdUvwg2cvP8bu/BMAVXU3ly0PQOGrUCXHk1emQAA
AABJRU5ErkJggg=='
]
{ #category : #'accessing - icons' }
FontAwesomeIcons >> tagIcon [
"Private - Generated method"
^Form fromBinaryStream: (Base64MimeConverter mimeDecodeToBytes: self tagIconContents readStream)
]
{ #category : #'private - contents' }
FontAwesomeIcons >> tagIconContents [
"Private - Method generated with the content of the file File @ /home/offray/Programas/Grafoscopio/Dev/Common/Icons/FontAwesome/Png/tag.png"
^ 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAmUlEQVR4nKXPMQ4BQRSA4U9D
oeIgKsdwAUfARSSiUTmExgUcYU8gGoVGpZFIGM0WG5mxM0zyMpni/zKPP0+nvleYNN4BZyxx
yIGedfQ5L8xygIA7RhjjUYoEXNFDH7fIT+ZtQMARpy/rJJFLIorNIgasC4Ao0sW+EJn+i2xi
q+QiFQYxIAepMEzFbUhWnEKK4iayxe6XOOu8ARtNbaMQ63x5AAAAAElFTkSuQmCC'
]
{ #category : #'accessing - icons' }
FontAwesomeIcons >> tagsIcon [
"Private - Generated method"
^Form fromBinaryStream: (self tagsIconContents base64Decoded readStream)
]
{ #category : #'private - contents' }
FontAwesomeIcons >> tagsIconContents [
"Private - Method generated with the content of the file File @ /home/offray/Programas/Grafoscopio/Dev/Common/Icons/FontAwesome/Png/tags.png"
^ 'iVBORw0KGgoAAAANSUhEUgAAABAAAAANCAYAAACgu+4kAAAABHNCSVQICAgIfAhkiAAAAAlw
SFlzAAAOxAAADsQBlSsOGwAAAXRJREFUKJGN0j1Mk1EYxfH/edRFSKijH4kTJBgTJ0cGTdxE
TKyUGAfFSQcKUl3taIjIh3EUTJzaAoORwUGdmUlMXB1ktSaQGNp7HOyrgG8jZ733+d1zc69G
y9NvsC6RRbZhIxQLtkdtX5DjSW1x5hM5CdBtxGnjLUQf6IzQDSfXWu30EvTF4fdjE49GugCA
Wa8vPLuIufO3CSePRnxspzQr+3UKGnlIdGoPlMqV84ihfasdpJX8XLCch0RnZz/SJlD+p2OG
tNNcHhLA57y7dUOwl/YiKk48vCLFuuDYfyGz1Urp8pHQJNK4SUXZZqz8+GqS1w6DGL/j29fr
OnX2O6b1+9XhsIixbyX0M8Sa8Ys/AEBpqjJsa7ULYtt3JTexGoZX5070PtgHANycnL4mYuUA
YsO4TTNwHWlpsNBzv1qtpjh4TGN+9q1JRcPuntr3Av8IXAeWs2HIfn5OSlOVYayntmeON3tr
O4XtD4KNwUJPJRsG+AVxqr+5c/rf8wAAAABJRU5ErkJggg=='
]

View File

@ -1,13 +1,13 @@
Extension { #name : #FormCanvas }
{ #category : #'*Grafoscopio' }
FormCanvas >> gfcParagraph: para bounds: bounds color: c [
| scanner |
self setPaintColor: c.
scanner := (port clippedBy: (bounds translateBy: origin)) gfcDisplayScannerFor: para
foreground: c background: Color transparent
ignoreColorChanges: false.
para drawOn: (self copyClipRect: bounds) using: scanner at: origin + bounds topLeft.
]
Extension { #name : #FormCanvas }
{ #category : #'*Grafoscopio' }
FormCanvas >> gfcParagraph: para bounds: bounds color: c [
| scanner |
self setPaintColor: c.
scanner := (port clippedBy: (bounds translateBy: origin)) gfcDisplayScannerFor: para
foreground: c background: Color transparent
ignoreColorChanges: false.
para drawOn: (self copyClipRect: bounds) using: scanner at: origin + bounds topLeft.
]

View File

@ -1,351 +1,351 @@
"
I'm the Graphical User Interface for Grafoscopio environment.
My main responsability is to provide grafoscopio with a docking bar
with menu options for open, browse notebooks, update the system
and its components and the help menu.
"
Class {
#name : #GfUIHelpers,
#superclass : #DynamicComposablePresenter,
#instVars : [
'windowMainMenu',
'tree',
'nodeHeader',
'nodeBody'
],
#classVars : [
'dockingBar',
'recentNotebooks'
],
#classInstVars : [
'dockingBar',
'recentNotebooks',
'helpMenu'
],
#category : #'Grafoscopio-UI'
}
{ #category : #adding }
GfUIHelpers class >> addToHelpMenu: aGrafoscopioNotebook [
| metadata nbFile |
metadata := aGrafoscopioNotebook metadata.
nbFile := aGrafoscopioNotebook workingFile.
(metadata at: 'showOnHelp' ifAbsent: [ ^ self ])
ifTrue: [
self helpMenu submorphs
detect: [ :s | s contents = (metadata at: 'shortTitle') ]
ifFound: [
self inform:
'The notebook: ', String cr,
nbFile fullName, String cr,
' needs another shortTitle to be added to the docking bar Help Menu.' ]
ifNone: [
self helpMenu
add: (metadata at: 'shortTitle')
target: [ GrafoscopioNotebook open: nbFile ]
selector: #value ] ].
self updateUI
]
{ #category : #updating }
GfUIHelpers class >> installDataviz [
"I install the Dataviz package.
DataViz contains Data visualization helpers"
"self isDatavizInstalled ifTrue: [ ^ self ]."
Metacello new
smalltalkhubUser: 'Offray' project: 'Dataviz';
configuration: 'Dataviz';
load.
self inform: 'Dataviz package install finished.'
]
{ #category : #updating }
GfUIHelpers class >> installDatavizUI [
"I'm the User Interface for installing the Dataviz package for the first time."
| install |
install := (UIManager default
confirm:
'Dataviz is data visualization package, with several', String cr,
'Domain Specific Examples, like Panama Papers, Twitter Data Selfies.',
String cr, 'Do you want to install it?'
label: 'Install Dataviz package').
install ifFalse: [ ^ self ].
self installDataviz
]
{ #category : #updating }
GfUIHelpers class >> isDatavizInstalled [
^ (Metacello image
configuration: #('Dataviz');
list) isNotEmpty
]
{ #category : #'graphical interface' }
GfUIHelpers class >> messageAbout [
"I show the author(s), license, sponsors and main contributors to the project
and point to further documentation on the web"
LongMessageDialogWindow new
entryText:
'_.:| Grafoscopio |:._',
(String with: Character cr),
'(c) Copyright 2014-2017 by Offray Vladimir Luna Cárdenas',
(String with: Character cr),
'Covered under MIT license.',
(String with: Character cr),
(String with: Character cr),
'[ Sponsors ]',
(String with: Character cr),
'mutabiT | www.mutabit.com ',
(String with: Character cr),
'HiTec Lab, Fundación Universitaria Los Libertadores | www.ulibertadores.edu.co ',
(String with: Character cr),
(String with: Character cr),
'[ Thanks to ]',
(String with: Character cr),
'HackBo, Hackerspace Bogota | http://hackbo.co',
(String with: Character cr),
'// Regular workshops attendees \\
Rafael Medida, Iván Pulido, Camilo Hurtado',
(String with: Character cr),
'// Coffe talk (mostly about grafoscopio) \\
Yanneth Gil, Andrés Calderón, Luis Alejandro Bernal',
(String with: Character cr),
'// Pharo, Moose and Agile Visualization communities \\
Tudor Girba, Alexandre Bergel, Nicolai Hess, Peter Uhnák, Milton Mamani ',
(String with: Character cr),
'// Family support while writing, coding & travelling (among others!) \\
Divian Luna, Hilda Cárdenas',
(String with: Character cr),
(String with: Character cr),
'For further details and versions go to:',
(String with: Character cr),
(String with: Character cr),
'http://mutabit.com/grafoscopio';
title: 'About Grafoscopio';
open.
]
{ #category : #'graphical interface' }
GfUIHelpers class >> messageNoRecentDocuments [
"Shows that a feature is not implemeted and point to further documentation on the web"
UIManager default abort:
'Recent documents list is emtpy.',
(String with: Character cr),
'To fill it, open a document using the Grafoscopio menu option at the top bar:',
(String with: Character cr),
(String with: Character cr),
'"Launch > Notebook from file..."',
(String with: Character cr),
(String with: Character cr)
title: 'No recent documents'.
]
{ #category : #'graphical interface' }
GfUIHelpers class >> messageNotImplementedYet [
"Shows that a feature is not implemeted and point to further documentation on the web"
UIManager default abort:
'This functionality is not implemented yet!',
(String with: Character cr),
'For more information about future releases, please visit: ',
(String with: Character cr),
(String with: Character cr),
'http://mutabit.com/grafoscopio',
(String with: Character cr),
(String with: Character cr)
title: 'To be implemented'.
]
{ #category : #'graphical interface' }
GfUIHelpers class >> openFromRecentlyUsed [
"Opens a recent notebooks list"
| selection recentNotebooksReversed |
self recentNotebooks
ifNotEmpty: [
recentNotebooksReversed := recentNotebooks reversed.
selection := UIManager default
chooseFrom: recentNotebooksReversed title: 'Choose a notebook...'.
selection > 0
ifTrue: [ GrafoscopioNotebook new openFromFile: (recentNotebooksReversed at: selection)]
ifFalse: [ self inform: 'No notebook selected!' ]
]
ifEmpty: [self messageNoRecentDocuments]
]
{ #category : #accessing }
GfUIHelpers class >> recentNotebooks [
^ recentNotebooks ifNil: [recentNotebooks := OrderedCollection new ]
]
{ #category : #updating }
GfUIHelpers class >> updateDataviz [
"I update the Dataviz package with new versions of itself take from the source code
repository.
DataViz contains Data visualization helpers"
self isDatavizInstalled
ifFalse: [ self installDatavizUI ]
ifTrue: [
Gofer it
smalltalkhubUser: 'Offray' project: 'Dataviz';
configurationOf: 'Dataviz';
load.
self inform: 'Dataviz package update finished.'].
]
{ #category : #updating }
GfUIHelpers class >> updateDatavizUI [
"I'm the User Interface for updating the Dataviz package with new versions of itself
take from the source code repository"
| update |
update := (UIManager default
confirm:
'Dataviz is data visualization package, with several', String cr,
'Domain Specific Examples, like Panama Papers, Twitter Data Selfies.',
String cr, 'Do you want to update it?'
label: 'Update Dataviz package').
update ifFalse: [ ^ self ].
self updateDataviz
]
{ #category : #updating }
GfUIHelpers class >> updateGrafoscopio [
"Updates Grafoscopio with new versions of itself take from the source code repository and
reloads the User Interface"
Gofer new
smalltalkhubUser: 'Offray' project: 'Grafoscopio';
package: 'Grafoscopio';
load.
GrafoscopioUtils update.
]
{ #category : #updating }
GfUIHelpers class >> updateGrafoscopioUI [
"Updates Grafoscopio with new versions of itself take from the source code repository and
the User Interface"
| update |
update := (UIManager default
confirm: 'Do you wish to update Grafoscopio?'
label: 'Grafoscopio update').
update ifFalse: [ ^ self ].
self updateGrafoscopio.
GrafoscopioUtils update.
self updateUI.
self inform: 'Grafoscopio update finished'
]
{ #category : #updating }
GfUIHelpers class >> updatePrerrequisitesScript [
"Updates the system prerequisites with new versions of itself take from the source code repository"
"Visualization library (which also makes main menu loadable)"
Gofer it
smalltalkhubUser: 'ObjectProfile' project: 'Roassal2';
configurationOf: 'Roassal2';
loadStable.
"Support for the STON format used in file persistance for grafoscopio notebooks"
Gofer new
smalltalkhubUser: 'SvenVanCaekenberghe' project: 'STON';
configurationOf: 'Ston';
loadBleedingEdge.
"Moose and Roassal integration"
Gofer new
smalltalkhubUser: 'Moose' project: 'Glamour';
package: 'Glamour-Tools';
package: 'Glamour-Roassal2-Presentations';
load.
Gofer new
smalltalkhubUser: 'Moose' project: 'GToolkit';
package: 'GT-InspectorExtensions-CoreRoassal';
load.
"Fast Table support"
Gofer it
smalltalkhubUser: 'estebanlm' project: 'FastTable';
package: 'FastTable';
load.
"Integration with external tools"
Gofer new
smalltalkhubUser: 'Offray' project: 'Grafoscopio';
package: 'Grafoscopio-ExternalTools';
load.
"HTML scrapping"
Gofer new
smalltalkhubUser: 'PharoExtras' project: 'Soup';
configurationOf: 'Soup';
loadStable.
"SQLite support"
Gofer new
url: 'http://smalltalkhub.com/mc/PharoExtras/NBSQLite3/main';
package: 'NBSQLite3';
load.
Gofer new
url: 'http://smalltalkhub.com/mc/PharoExtras/NBSQLite3/main';
package: 'NBSQLite3-Examples';
load.
"Support for Operative System integration"
Gofer new
squeaksource: 'OSProcess';
package: 'OSProcess';
load.
Gofer new
squeaksource: 'CommandShell';
package: 'CommandShell-Piping';
load.
"Bibliographic support"
Gofer new
squeaksource: 'Citezen';
package: 'ConfigurationOfCitezen';
load.
]
{ #category : #updating }
GfUIHelpers class >> updateRecentNotebooksWith: aFileReference [
(self recentNotebooks includes: aFileReference)
ifFalse: [self recentNotebooks add: aFileReference].
]
{ #category : #updating }
GfUIHelpers class >> updateSystem [
| tmp1 |
tmp1 := UIManager default
question: 'Do you wish to update all Grafoscopio and its co-dependencies ?'
title: 'Grafoscopio update'.
tmp1
ifNotNil: [ tmp1
ifTrue: [
self
updateGrafoscopio;
updateDataviz.
GrafoscopioDocumentation updateAll.
self inform: 'System update finished.' ]]
]
{ #category : #updating }
GfUIHelpers class >> updateUI [
"I update the User Interface (UI) with new versions of the docking bar or logos where available.
I'm helpful while testing new functionality that should be expossed to the user via the UI"
self start.
(World submorphs select: [ :each | each class = DockingBarMorph ])
allButFirstDo: [ :bar | bar delete ].
]
"
I'm the Graphical User Interface for Grafoscopio environment.
My main responsability is to provide grafoscopio with a docking bar
with menu options for open, browse notebooks, update the system
and its components and the help menu.
"
Class {
#name : #GfUIHelpers,
#superclass : #DynamicComposablePresenter,
#instVars : [
'windowMainMenu',
'tree',
'nodeHeader',
'nodeBody'
],
#classVars : [
'dockingBar',
'recentNotebooks'
],
#classInstVars : [
'dockingBar',
'recentNotebooks',
'helpMenu'
],
#category : #'Grafoscopio-UI'
}
{ #category : #adding }
GfUIHelpers class >> addToHelpMenu: aGrafoscopioNotebook [
| metadata nbFile |
metadata := aGrafoscopioNotebook metadata.
nbFile := aGrafoscopioNotebook workingFile.
(metadata at: 'showOnHelp' ifAbsent: [ ^ self ])
ifTrue: [
self helpMenu submorphs
detect: [ :s | s contents = (metadata at: 'shortTitle') ]
ifFound: [
self inform:
'The notebook: ', String cr,
nbFile fullName, String cr,
' needs another shortTitle to be added to the docking bar Help Menu.' ]
ifNone: [
self helpMenu
add: (metadata at: 'shortTitle')
target: [ GrafoscopioNotebook open: nbFile ]
selector: #value ] ].
self updateUI
]
{ #category : #updating }
GfUIHelpers class >> installDataviz [
"I install the Dataviz package.
DataViz contains Data visualization helpers"
"self isDatavizInstalled ifTrue: [ ^ self ]."
Metacello new
smalltalkhubUser: 'Offray' project: 'Dataviz';
configuration: 'Dataviz';
load.
self inform: 'Dataviz package install finished.'
]
{ #category : #updating }
GfUIHelpers class >> installDatavizUI [
"I'm the User Interface for installing the Dataviz package for the first time."
| install |
install := (UIManager default
confirm:
'Dataviz is data visualization package, with several', String cr,
'Domain Specific Examples, like Panama Papers, Twitter Data Selfies.',
String cr, 'Do you want to install it?'
label: 'Install Dataviz package').
install ifFalse: [ ^ self ].
self installDataviz
]
{ #category : #updating }
GfUIHelpers class >> isDatavizInstalled [
^ (Metacello image
configuration: #('Dataviz');
list) isNotEmpty
]
{ #category : #'graphical interface' }
GfUIHelpers class >> messageAbout [
"I show the author(s), license, sponsors and main contributors to the project
and point to further documentation on the web"
LongMessageDialogWindow new
entryText:
'_.:| Grafoscopio |:._',
(String with: Character cr),
'(c) Copyright 2014-2017 by Offray Vladimir Luna Cárdenas',
(String with: Character cr),
'Covered under MIT license.',
(String with: Character cr),
(String with: Character cr),
'[ Sponsors ]',
(String with: Character cr),
'mutabiT | www.mutabit.com ',
(String with: Character cr),
'HiTec Lab, Fundación Universitaria Los Libertadores | www.ulibertadores.edu.co ',
(String with: Character cr),
(String with: Character cr),
'[ Thanks to ]',
(String with: Character cr),
'HackBo, Hackerspace Bogota | http://hackbo.co',
(String with: Character cr),
'// Regular workshops attendees \\
Rafael Medida, Iván Pulido, Camilo Hurtado',
(String with: Character cr),
'// Coffe talk (mostly about grafoscopio) \\
Yanneth Gil, Andrés Calderón, Luis Alejandro Bernal',
(String with: Character cr),
'// Pharo, Moose and Agile Visualization communities \\
Tudor Girba, Alexandre Bergel, Nicolai Hess, Peter Uhnák, Milton Mamani ',
(String with: Character cr),
'// Family support while writing, coding & travelling (among others!) \\
Divian Luna, Hilda Cárdenas',
(String with: Character cr),
(String with: Character cr),
'For further details and versions go to:',
(String with: Character cr),
(String with: Character cr),
'http://mutabit.com/grafoscopio';
title: 'About Grafoscopio';
open.
]
{ #category : #'graphical interface' }
GfUIHelpers class >> messageNoRecentDocuments [
"Shows that a feature is not implemeted and point to further documentation on the web"
UIManager default abort:
'Recent documents list is emtpy.',
(String with: Character cr),
'To fill it, open a document using the Grafoscopio menu option at the top bar:',
(String with: Character cr),
(String with: Character cr),
'"Launch > Notebook from file..."',
(String with: Character cr),
(String with: Character cr)
title: 'No recent documents'.
]
{ #category : #'graphical interface' }
GfUIHelpers class >> messageNotImplementedYet [
"Shows that a feature is not implemeted and point to further documentation on the web"
UIManager default abort:
'This functionality is not implemented yet!',
(String with: Character cr),
'For more information about future releases, please visit: ',
(String with: Character cr),
(String with: Character cr),
'http://mutabit.com/grafoscopio',
(String with: Character cr),
(String with: Character cr)
title: 'To be implemented'.
]
{ #category : #'graphical interface' }
GfUIHelpers class >> openFromRecentlyUsed [
"Opens a recent notebooks list"
| selection recentNotebooksReversed |
self recentNotebooks
ifNotEmpty: [
recentNotebooksReversed := recentNotebooks reversed.
selection := UIManager default
chooseFrom: recentNotebooksReversed title: 'Choose a notebook...'.
selection > 0
ifTrue: [ GrafoscopioNotebook new openFromFile: (recentNotebooksReversed at: selection)]
ifFalse: [ self inform: 'No notebook selected!' ]
]
ifEmpty: [self messageNoRecentDocuments]
]
{ #category : #accessing }
GfUIHelpers class >> recentNotebooks [
^ recentNotebooks ifNil: [recentNotebooks := OrderedCollection new ]
]
{ #category : #updating }
GfUIHelpers class >> updateDataviz [
"I update the Dataviz package with new versions of itself take from the source code
repository.
DataViz contains Data visualization helpers"
self isDatavizInstalled
ifFalse: [ self installDatavizUI ]
ifTrue: [
Gofer it
smalltalkhubUser: 'Offray' project: 'Dataviz';
configurationOf: 'Dataviz';
load.
self inform: 'Dataviz package update finished.'].
]
{ #category : #updating }
GfUIHelpers class >> updateDatavizUI [
"I'm the User Interface for updating the Dataviz package with new versions of itself
take from the source code repository"
| update |
update := (UIManager default
confirm:
'Dataviz is data visualization package, with several', String cr,
'Domain Specific Examples, like Panama Papers, Twitter Data Selfies.',
String cr, 'Do you want to update it?'
label: 'Update Dataviz package').
update ifFalse: [ ^ self ].
self updateDataviz
]
{ #category : #updating }
GfUIHelpers class >> updateGrafoscopio [
"Updates Grafoscopio with new versions of itself take from the source code repository and
reloads the User Interface"
Gofer new
smalltalkhubUser: 'Offray' project: 'Grafoscopio';
package: 'Grafoscopio';
load.
GrafoscopioUtils update.
]
{ #category : #updating }
GfUIHelpers class >> updateGrafoscopioUI [
"Updates Grafoscopio with new versions of itself take from the source code repository and
the User Interface"
| update |
update := (UIManager default
confirm: 'Do you wish to update Grafoscopio?'
label: 'Grafoscopio update').
update ifFalse: [ ^ self ].
self updateGrafoscopio.
GrafoscopioUtils update.
self updateUI.
self inform: 'Grafoscopio update finished'
]
{ #category : #updating }
GfUIHelpers class >> updatePrerrequisitesScript [
"Updates the system prerequisites with new versions of itself take from the source code repository"
"Visualization library (which also makes main menu loadable)"
Gofer it
smalltalkhubUser: 'ObjectProfile' project: 'Roassal2';
configurationOf: 'Roassal2';
loadStable.
"Support for the STON format used in file persistance for grafoscopio notebooks"
Gofer new
smalltalkhubUser: 'SvenVanCaekenberghe' project: 'STON';
configurationOf: 'Ston';
loadBleedingEdge.
"Moose and Roassal integration"
Gofer new
smalltalkhubUser: 'Moose' project: 'Glamour';
package: 'Glamour-Tools';
package: 'Glamour-Roassal2-Presentations';
load.
Gofer new
smalltalkhubUser: 'Moose' project: 'GToolkit';
package: 'GT-InspectorExtensions-CoreRoassal';
load.
"Fast Table support"
Gofer it
smalltalkhubUser: 'estebanlm' project: 'FastTable';
package: 'FastTable';
load.
"Integration with external tools"
Gofer new
smalltalkhubUser: 'Offray' project: 'Grafoscopio';
package: 'Grafoscopio-ExternalTools';
load.
"HTML scrapping"
Gofer new
smalltalkhubUser: 'PharoExtras' project: 'Soup';
configurationOf: 'Soup';
loadStable.
"SQLite support"
Gofer new
url: 'http://smalltalkhub.com/mc/PharoExtras/NBSQLite3/main';
package: 'NBSQLite3';
load.
Gofer new
url: 'http://smalltalkhub.com/mc/PharoExtras/NBSQLite3/main';
package: 'NBSQLite3-Examples';
load.
"Support for Operative System integration"
Gofer new
squeaksource: 'OSProcess';
package: 'OSProcess';
load.
Gofer new
squeaksource: 'CommandShell';
package: 'CommandShell-Piping';
load.
"Bibliographic support"
Gofer new
squeaksource: 'Citezen';
package: 'ConfigurationOfCitezen';
load.
]
{ #category : #updating }
GfUIHelpers class >> updateRecentNotebooksWith: aFileReference [
(self recentNotebooks includes: aFileReference)
ifFalse: [self recentNotebooks add: aFileReference].
]
{ #category : #updating }
GfUIHelpers class >> updateSystem [
| tmp1 |
tmp1 := UIManager default
question: 'Do you wish to update all Grafoscopio and its co-dependencies ?'
title: 'Grafoscopio update'.
tmp1
ifNotNil: [ tmp1
ifTrue: [
self
updateGrafoscopio;
updateDataviz.
GrafoscopioDocumentation updateAll.
self inform: 'System update finished.' ]]
]
{ #category : #updating }
GfUIHelpers class >> updateUI [
"I update the User Interface (UI) with new versions of the docking bar or logos where available.
I'm helpful while testing new functionality that should be expossed to the user via the UI"
self start.
(World submorphs select: [ :each | each class = DockingBarMorph ])
allButFirstDo: [ :bar | bar delete ].
]

View File

@ -1,165 +1,182 @@
"
I define the Grafoscopio main menu presented in the Pharo World.
"
Class {
#name : #GfWorldMenu,
#superclass : #Object,
#classInstVars : [
'recentNotebooks'
],
#category : #'Grafoscopio-UI'
}
{ #category : #'world menu' }
GfWorldMenu class >> helpMenuOn: aBuilder [
<worldMenu>
(aBuilder item: #GfManual)
label: 'Manual';
order: 1;
parent: #GfHelpAndDocs;
action: [ GrafoscopioNotebook open: GrafoscopioDocs manual ].
(aBuilder item: #GfManualPDF)
label: 'Manual (PDF)';
order: 2;
parent: #GfHelpAndDocs;
action: [ GrafoscopioDocs openPDFManual ].
(aBuilder item: #GfHelpDataviz)
label: 'Dataviz';
order: 3;
parent: #GfHelpAndDocs;
action: [ GrafoscopioNotebook open: DatavizDocs introNotebook ].
(aBuilder item: #GfHelpDevNotes)
label: 'Devs''s notes';
order: 4;
parent: #GfHelpAndDocs;
action: [ GrafoscopioNotebook open: GrafoscopioDocs devNotes ].
(aBuilder item: #GfHelpAbout)
label: 'About Grafoscopio';
order: 5;
parent: #GfHelpAndDocs;
action: [ GfUIHelpers messageAbout ].
]
{ #category : #'world menu' }
GfWorldMenu class >> launchCompatibilityMenuOn: aBuilder [
<worldMenu>
(aBuilder item: #'New notebook')
label: 'New notebook';
order: 1;
parent: #GfLaunchCompatibility;
action: [ GrafoscopioNotebook new openDefault ].
(aBuilder item: #'Notebook from file...')
label: 'Notebook from file...';
order: 2;
parent: #GfLaunchCompatibility;
action: [ GrafoscopioNotebook new openFromFileSelector ].
(aBuilder item: #'Notebook from the Internet...')
label: 'Notebook from the Internet...';
order: 3;
parent: #GfLaunchCompatibility;
action: [ GrafoscopioNotebook new openFromUrlUI ].
(aBuilder item: #recentNotebooks)
label: 'Recent notebooks...';
order: 4;
parent: #GfLaunchCompatibility;
action: [ GfUIHelpers openFromRecentlyUsed ]
]
{ #category : #'world menu' }
GfWorldMenu class >> launchMenuOn: aBuilder [
<worldMenu>
(aBuilder item: #'New notebook')
label: 'New notebook';
order: 1;
parent: #GfLaunch;
action: [ GrafoscopioNewNotebook new openDefault ].
(aBuilder item: #'Notebook from file...')
label: 'Notebook from file...';
order: 2;
parent: #GfLaunch;
action: [ GrafoscopioNewNotebook new openFromFileSelector ].
(aBuilder item: #GfLaunchOpenRecent)
label: 'Open recent...';
order: 2;
parent: #GfLaunch.
(aBuilder item: #'Notebook from the Internet...')
label: 'Notebook from the Internet...';
order: 3;
parent: #GfLaunch;
action: [ GrafoscopioNewNotebook new openFromUrlUI ].
(aBuilder item: #recentNotebooks)
label: 'Recent notebooks...';
order: 4;
parent: #GfLaunch;
action: [ GfUIHelpers openFromRecentlyUsed ]
]
{ #category : #'world menu' }
GfWorldMenu class >> mainMenuItemsOn: aBuilder [
"I add the main Grafoscopio menu to the Pharo World."
<worldMenu>
(aBuilder item: #Grafoscopio)
label: 'Grafoscopio';
order: 1;
with: [ (aBuilder
item: #GfLaunch;
label: 'Launch') target: self.
(aBuilder
item: #GfLaunchCompatibility;
label: 'Launch Compatibility') target: self.
(aBuilder
item: #GfUpdate;
label: 'Update') target: self.
(aBuilder
item: #GfHelpAndDocs;
label: 'Help & Docs') target: self ]
]
{ #category : #'world menu' }
GfWorldMenu class >> openRecentMenu: aBuilder [
<worldMenu>
GrafoscopioNotebook recents
do: [ :f |
(aBuilder item: #'Open', f basename )
label: 'Open ', f basename;
order: 1;
parent: #GfLaunchOpenRecent;
action: [ GrafoscopioNotebook open: f ] ]
]
{ #category : #'world menu' }
GfWorldMenu class >> updateMenuOn: aBuilder [
<worldMenu>
(aBuilder item: #GfUpdateGrafoscopio)
label: 'Grafoscopio';
order: 1;
parent: #GfUpdate;
action: [ GfUIHelpers updateGrafoscopioUI ].
(aBuilder item: #GfUpdateDocs)
label: 'Documentation';
order: 2;
parent: #GfUpdate;
action: [ GrafoscopioDocumentation updateAllUI ].
(aBuilder item: #GfUpdateDataviz)
label: 'DataViz package';
order: 3;
parent: #GfUpdate;
action: [ GfUIHelpers updateDatavizUI ].
(aBuilder item: #GfUpdateAll)
label: 'All the system';
order: 4;
parent: #GfUpdate;
action: [ GfUIHelpers updateSystem ].
]
{ #category : #updating }
GfWorldMenu class >> updateRecentNotebooksWith: aFileReference [
(self recentNotebooks includes: aFileReference)
ifFalse: [self recentNotebooks add: aFileReference].
]
"
I define the Grafoscopio main menu presented in the Pharo World.
"
Class {
#name : #GfWorldMenu,
#superclass : #Object,
#classInstVars : [
'recentNotebooks'
],
#category : #'Grafoscopio-UI'
}
{ #category : #'world menu' }
GfWorldMenu class >> getProjectExample [
| project unit |
project := GrafoscopioProject new.
unit := GrafoscopioUnitNode new.
unit name: 'Pillar-Example'.
unit
addChild: [ GrafoscopioPillarNode new
text: GrafoscopioPillarASText openExample;
yourself ]
ofClass: GrafoscopioPillarNode.
project document addChild: unit ofClass: GrafoscopioUnitNode.
^ project
]
{ #category : #'world menu' }
GfWorldMenu class >> getProjectFromFile [
| file |
file := UIManager default
chooseExistingFileReference: 'Choose a file'
extensions: #('ston')
path: FileLocator documents.
^ (STON fromStream: file readStream)
]
{ #category : #'world menu' }
GfWorldMenu class >> helpMenuOn: aBuilder [
<worldMenu>
(aBuilder item: #GfManual)
label: 'Manual';
order: 1;
parent: #GfHelpAndDocs;
action: [ GrafoscopioNotebook open: GrafoscopioDocs manual ].
(aBuilder item: #GfManualPDF)
label: 'Manual (PDF)';
order: 2;
parent: #GfHelpAndDocs;
action: [ GrafoscopioDocs openPDFManual ].
(aBuilder item: #GfHelpDataviz)
label: 'Dataviz';
order: 3;
parent: #GfHelpAndDocs;
action: [ GrafoscopioNotebook open: DatavizDocs introNotebook ].
(aBuilder item: #GfHelpDevNotes)
label: 'Devs''s notes';
order: 4;
parent: #GfHelpAndDocs;
action: [ GrafoscopioNotebook open: GrafoscopioDocs devNotes ].
(aBuilder item: #GfHelpAbout)
label: 'About Grafoscopio';
order: 5;
parent: #GfHelpAndDocs;
action: [ GfUIHelpers messageAbout ].
]
{ #category : #'world menu' }
GfWorldMenu class >> launchCompatibilityMenuOn: aBuilder [
<worldMenu>
(aBuilder item: #'New notebook')
label: 'New notebook';
order: 1;
parent: #GfLaunchCompatibility;
action: [ GrafoscopioNotebook new openDefault ].
(aBuilder item: #'Notebook from file...')
label: 'Notebook from file...';
order: 2;
parent: #GfLaunchCompatibility;
action: [ GrafoscopioNotebook new openFromFileSelector ].
(aBuilder item: #'Notebook from the Internet...')
label: 'Notebook from the Internet...';
order: 3;
parent: #GfLaunchCompatibility;
action: [ GrafoscopioNotebook new openFromUrlUI ].
(aBuilder item: #recentNotebooks)
label: 'Recent notebooks...';
order: 4;
parent: #GfLaunchCompatibility;
action: [ GfUIHelpers openFromRecentlyUsed ]
]
{ #category : #'world menu' }
GfWorldMenu class >> launchMenuOn: aBuilder [
<worldMenu>
(aBuilder item: #'New notebook')
label: 'New notebook';
order: 1;
parent: #GfLaunch;
action: [ (GrafoscopioTreeNotebook on: GrafoscopioProject new ) openWithSpec ].
(aBuilder item: #'New Notebook from example ')
label: 'Notebook from from example ';
order: 2;
parent: #GfLaunch;
action: [ (GrafoscopioTreeNotebook on: (self getProjectExample)) openWithSpec ].
(aBuilder item: #'Notebook from file...')
label: 'Notebook from file...';
order: 2;
parent: #GfLaunch;
action: [ (GrafoscopioTreeNotebook on: (self getProjectFromFile)) openWithSpec ].
(aBuilder item: #GfLaunchOpenRecent)
label: 'Open recent...';
order: 2;
parent: #GfLaunch.
(aBuilder item: #'Notebook from the Internet...')
label: 'Notebook from the Internet...';
order: 3;
parent: #GfLaunch;
action: [ GrafoscopioTreeNotebook new openFromUrlUI ].
(aBuilder item: #recentNotebooks)
label: 'Recent notebooks...';
order: 4;
parent: #GfLaunch;
action: [ GfUIHelpers openFromRecentlyUsed ]
]
{ #category : #'world menu' }
GfWorldMenu class >> mainMenuItemsOn: aBuilder [
"I add the main Grafoscopio menu to the Pharo World."
<worldMenu>
(aBuilder item: #Grafoscopio)
label: 'Grafoscopio';
order: 1;
with: [ (aBuilder
item: #GfLaunch;
label: 'Launch') target: self.
(aBuilder
item: #GfLaunchCompatibility;
label: 'Launch Compatibility') target: self.
(aBuilder
item: #GfUpdate;
label: 'Update') target: self.
(aBuilder
item: #GfHelpAndDocs;
label: 'Help & Docs') target: self ]
]
{ #category : #'world menu' }
GfWorldMenu class >> updateMenuOn: aBuilder [
<worldMenu>
(aBuilder item: #GfUpdateGrafoscopio)
label: 'Grafoscopio';
order: 1;
parent: #GfUpdate;
action: [ GfUIHelpers updateGrafoscopioUI ].
(aBuilder item: #GfUpdateDocs)
label: 'Documentation';
order: 2;
parent: #GfUpdate;
action: [ GrafoscopioDocumentation updateAllUI ].
(aBuilder item: #GfUpdateDataviz)
label: 'DataViz package';
order: 3;
parent: #GfUpdate;
action: [ GfUIHelpers updateDatavizUI ].
(aBuilder item: #GfUpdateAll)
label: 'All the system';
order: 4;
parent: #GfUpdate;
action: [ GfUIHelpers updateSystem ].
]
{ #category : #updating }
GfWorldMenu class >> updateRecentNotebooksWith: aFileReference [
(self recentNotebooks includes: aFileReference)
ifFalse: [self recentNotebooks add: aFileReference].
]

View File

@ -1,79 +1,79 @@
"
I am a Spec ComposableModel for all Glamour presentations (GLMPresentation subclasses.) By default I open a Playground because its creation contract is special.
Example uses :
""open a playground""
GlamourPresentationModel new openWithSpec.
""open a playground on 42""
|ui|
ui := GlamourPresentationModel new.
ui presentationClass: GTPlayground startOn: (GTPlayPage new saveContent: '42').
ui openWithSpec
""open an inspector on 42""
|ui|
ui := GlamourPresentationModel new.
ui presentationClass: GTInspector startOn: 42.
ui openWithSpec
"
Class {
#name : #GlamourPresentationModel,
#superclass : #SpPresenter,
#instVars : [
'presentation',
'glmPres'
],
#category : #'Grafoscopio-UI'
}
{ #category : #specs }
GlamourPresentationModel class >> defaultSpec [
<spec: #default>
^ SpBoxLayout newHorizontal
add: #presentation;
yourself
]
{ #category : #deprecation }
GlamourPresentationModel class >> isDeprecated [
^ true
]
{ #category : #accessing }
GlamourPresentationModel >> glmPres [
glmPres isNil ifTrue:[glmPres := GTPlayground new startOn: GTPlayPage new].
^glmPres
]
{ #category : #initialization }
GlamourPresentationModel >> initializeWidgets [
"Should actually do nothing at all.
This is because we cannot create the morph and later set the presentation.
So we will do all of this in the presentation: accessor.
"
self presentation.
]
{ #category : #accessing }
GlamourPresentationModel >> presentation [
presentation isNil ifTrue:[
| morph |
morph := GLMMorphicRenderer new render: self glmPres.
morph hResizing: #spaceFill.
morph vResizing: #spaceFill.
presentation := MorphicGenericAdapter morph: morph].
^ presentation
]
{ #category : #accessing }
GlamourPresentationModel >> presentation: anObject [
presentation := anObject
]
{ #category : #api }
GlamourPresentationModel >> presentationClass: aGLMCompositePresentation startOn: anObject [
glmPres := aGLMCompositePresentation new startOn: anObject
]
"
I am a Spec ComposableModel for all Glamour presentations (GLMPresentation subclasses.) By default I open a Playground because its creation contract is special.
Example uses :
""open a playground""
GlamourPresentationModel new openWithSpec.
""open a playground on 42""
|ui|
ui := GlamourPresentationModel new.
ui presentationClass: GTPlayground startOn: (GTPlayPage new saveContent: '42').
ui openWithSpec
""open an inspector on 42""
|ui|
ui := GlamourPresentationModel new.
ui presentationClass: GTInspector startOn: 42.
ui openWithSpec
"
Class {
#name : #GlamourPresentationModel,
#superclass : #SpPresenter,
#instVars : [
'presentation',
'glmPres'
],
#category : #'Grafoscopio-UI'
}
{ #category : #specs }
GlamourPresentationModel class >> defaultSpec [
<spec: #default>
^ SpBoxLayout newHorizontal
add: #presentation;
yourself
]
{ #category : #deprecation }
GlamourPresentationModel class >> isDeprecated [
^ true
]
{ #category : #accessing }
GlamourPresentationModel >> glmPres [
glmPres isNil ifTrue:[glmPres := GTPlayground new startOn: GTPlayPage new].
^glmPres
]
{ #category : #initialization }
GlamourPresentationModel >> initializeWidgets [
"Should actually do nothing at all.
This is because we cannot create the morph and later set the presentation.
So we will do all of this in the presentation: accessor.
"
self presentation.
]
{ #category : #accessing }
GlamourPresentationModel >> presentation [
presentation isNil ifTrue:[
| morph |
morph := GLMMorphicRenderer new render: self glmPres.
morph hResizing: #spaceFill.
morph vResizing: #spaceFill.
presentation := MorphicGenericAdapter morph: morph].
^ presentation
]
{ #category : #accessing }
GlamourPresentationModel >> presentation: anObject [
presentation := anObject
]
{ #category : #api }
GlamourPresentationModel >> presentationClass: aGLMCompositePresentation startOn: anObject [
glmPres := aGLMCompositePresentation new startOn: anObject
]

View File

@ -1,9 +1,9 @@
Extension { #name : #GrafPort }
{ #category : #'*Grafoscopio' }
GrafPort >> gfcDisplayScannerFor: para foreground: foreColor background: backColor ignoreColorChanges: shadowMode [
^ (GrafoscopioDisplayScanner new text: para text textStyle: para textStyle
foreground: foreColor background: backColor fillBlt: self
ignoreColorChanges: shadowMode)
setPort: self shallowCopy
]
Extension { #name : #GrafPort }
{ #category : #'*Grafoscopio' }
GrafPort >> gfcDisplayScannerFor: para foreground: foreColor background: backColor ignoreColorChanges: shadowMode [
^ (GrafoscopioDisplayScanner new text: para text textStyle: para textStyle
foreground: foreColor background: backColor fillBlt: self
ignoreColorChanges: shadowMode)
setPort: self shallowCopy
]

View File

@ -1,134 +1,134 @@
"
Just an abstract node.
"
Class {
#name : #GrafoscopioAbstractNode,
#superclass : #Object,
#instVars : [
'created',
'edited',
'tags',
'order',
'name'
],
#classInstVars : [
'clipboard'
],
#category : #'Grafoscopio-Model'
}
{ #category : #testing }
GrafoscopioAbstractNode class >> isAbstract [
^ self = GrafoscopioAbstractNode
]
{ #category : #testing }
GrafoscopioAbstractNode class >> isLeaf [
^ false
]
{ #category : #testing }
GrafoscopioAbstractNode class >> showInMenu [
^ false
]
{ #category : #accessing }
GrafoscopioAbstractNode >> addChild: aBlock ofClass: aClass [
self subclassResponsibility
]
{ #category : #accessing }
GrafoscopioAbstractNode >> addTag: aTag [
"Tags the recipient node with aTag (string). For the moment we will have only one tag.
In the future we will have several and there will be rules to know how tags interact with
each other"
self tags add: aTag
]
{ #category : #accessing }
GrafoscopioAbstractNode >> created [
^ created
]
{ #category : #accessing }
GrafoscopioAbstractNode >> created: aTimestamp [
"I tell when this object was created"
created := aTimestamp
]
{ #category : #accessing }
GrafoscopioAbstractNode >> edited [
^ edited
]
{ #category : #accessing }
GrafoscopioAbstractNode >> edited: aTimestamp [
"I store the last time when a node was edited.
Because nodes in the notebook have a autosave feature, I'm updated automatically when nodes are
edited from the GUI.
If I'm in the notebook root (i.e. node's level equals 0) I should store the last time the notebook
was saved on the hard drive."
edited := aTimestamp
]
{ #category : #accessing }
GrafoscopioAbstractNode >> initialize [
"I create a empty new node"
super initialize.
created := DateAndTime now.
edited := DateAndTime now
]
{ #category : #accessing }
GrafoscopioAbstractNode >> isLeaf [
^ self class isLeaf
]
{ #category : #'as yet unclassified' }
GrafoscopioAbstractNode >> moveDown [
self subclassResponsibility
]
{ #category : #accessing }
GrafoscopioAbstractNode >> name [
^ name
]
{ #category : #accessing }
GrafoscopioAbstractNode >> name: aName [
name := aName
]
{ #category : #'as yet unclassified' }
GrafoscopioAbstractNode >> order [
^ order ifNil: [ 0 ]
]
{ #category : #accessing }
GrafoscopioAbstractNode >> tagAs: aTag [
self
error:
'tags are not used as markers anymore. Use addTag: instead and ensure you are not relying on text/codigo etc.'
]
{ #category : #accessing }
GrafoscopioAbstractNode >> tags [
"I returns the receiver tags."
^ tags ifNil: [ tags := Set new ]
]
{ #category : #accessing }
GrafoscopioAbstractNode >> tags: aCollection [
tags := aCollection
]
{ #category : #'as yet unclassified' }
GrafoscopioAbstractNode >> updateStamp [
self edited: DateAndTime now
]
"
Just an abstract node.
"
Class {
#name : #GrafoscopioAbstractNode,
#superclass : #Object,
#instVars : [
'created',
'edited',
'tags',
'order',
'name'
],
#classInstVars : [
'clipboard'
],
#category : #'Grafoscopio-Model'
}
{ #category : #testing }
GrafoscopioAbstractNode class >> isAbstract [
^ self = GrafoscopioAbstractNode
]
{ #category : #testing }
GrafoscopioAbstractNode class >> isLeaf [
^ false
]
{ #category : #testing }
GrafoscopioAbstractNode class >> showInMenu [
^ false
]
{ #category : #accessing }
GrafoscopioAbstractNode >> addChild: aBlock ofClass: aClass [
self subclassResponsibility
]
{ #category : #accessing }
GrafoscopioAbstractNode >> addTag: aTag [
"Tags the recipient node with aTag (string). For the moment we will have only one tag.
In the future we will have several and there will be rules to know how tags interact with
each other"
self tags add: aTag
]
{ #category : #accessing }
GrafoscopioAbstractNode >> created [
^ created
]
{ #category : #accessing }
GrafoscopioAbstractNode >> created: aTimestamp [
"I tell when this object was created"
created := aTimestamp
]
{ #category : #accessing }
GrafoscopioAbstractNode >> edited [
^ edited
]
{ #category : #accessing }
GrafoscopioAbstractNode >> edited: aTimestamp [
"I store the last time when a node was edited.
Because nodes in the notebook have a autosave feature, I'm updated automatically when nodes are
edited from the GUI.
If I'm in the notebook root (i.e. node's level equals 0) I should store the last time the notebook
was saved on the hard drive."
edited := aTimestamp
]
{ #category : #accessing }
GrafoscopioAbstractNode >> initialize [
"I create a empty new node"
super initialize.
created := DateAndTime now.
edited := DateAndTime now
]
{ #category : #accessing }
GrafoscopioAbstractNode >> isLeaf [
^ self class isLeaf
]
{ #category : #'as yet unclassified' }
GrafoscopioAbstractNode >> moveDown [
self subclassResponsibility
]
{ #category : #accessing }
GrafoscopioAbstractNode >> name [
^ name
]
{ #category : #accessing }
GrafoscopioAbstractNode >> name: aName [
name := aName
]
{ #category : #'as yet unclassified' }
GrafoscopioAbstractNode >> order [
^ order ifNil: [ 0 ]
]
{ #category : #accessing }
GrafoscopioAbstractNode >> tagAs: aTag [
self
error:
'tags are not used as markers anymore. Use addTag: instead and ensure you are not relying on text/codigo etc.'
]
{ #category : #accessing }
GrafoscopioAbstractNode >> tags [
"I returns the receiver tags."
^ tags ifNil: [ tags := Set new ]
]
{ #category : #accessing }
GrafoscopioAbstractNode >> tags: aCollection [
tags := aCollection
]
{ #category : #'as yet unclassified' }
GrafoscopioAbstractNode >> updateStamp [
self edited: DateAndTime now
]

View File

@ -1,128 +1,128 @@
"
This abstract class works for defining the basic type required by Rubric
"
Class {
#name : #GrafoscopioAbstractText,
#superclass : #Object,
#category : #'Grafoscopio-Pillar'
}
{ #category : #'as yet unclassified' }
GrafoscopioAbstractText >> allRangesOfSubstring: aString [
^ { }
]
{ #category : #converting }
GrafoscopioAbstractText >> asText [
^ self
]
{ #category : #accessing }
GrafoscopioAbstractText >> at: anIndex [
^ self subclassResponsibility
]
{ #category : #accessing }
GrafoscopioAbstractText >> attributesAt: characterIndex [
"Answer the code for characters in the run beginning at characterIndex."
"NB: no senders any more (supplanted by #attributesAt:forStyle: but retained for the moment in order not to break user code that may exist somewhere that still calls this"
| attributes |
" self size = 0
ifTrue: [^ Array with: (TextFontChange new fontNumber: 1)]."
self size = 0 ifTrue: [ ^#()].
attributes := self runs at: characterIndex.
^ attributes
]
{ #category : #accessing }
GrafoscopioAbstractText >> attributesAt: anInteger forStyle: aTextStyle [
| attributes size |
size := self size.
(size = 0 or: [ size < anInteger ])
ifTrue: [ ^ Array
with: (TextFontChange new fontNumber: aTextStyle defaultFontIndex) ]. "null text tolerates access"
attributes := self runs at: anInteger.
^ attributes
]
{ #category : #copying }
GrafoscopioAbstractText >> copy [
^ self
]
{ #category : #copying }
GrafoscopioAbstractText >> copyFrom: start to: stop [
^ self subclassResponsibility
]
{ #category : #testing }
GrafoscopioAbstractText >> ifNotEmpty: isNotEmptyBlock ifEmpty: isEmptyBlock [
^ self isEmpty
ifTrue: [ isEmptyBlock value ]
ifFalse: [ isNotEmptyBlock value ]
]
{ #category : #testing }
GrafoscopioAbstractText >> isEmpty [
^ self size = 0
]
{ #category : #testing }
GrafoscopioAbstractText >> isText [
^ true
]
{ #category : #accessing }
GrafoscopioAbstractText >> last [
^ self at: self size
]
{ #category : #copying }
GrafoscopioAbstractText >> notEmpty [
^ self isEmpty not
]
{ #category : #removing }
GrafoscopioAbstractText >> removeAttribute: anAttr [
^ self removeAttribute: anAttr from: 1 to: self size
]
{ #category : #removing }
GrafoscopioAbstractText >> removeAttribute: att from: start to: stop [
self subclassResponsibility
]
{ #category : #editing }
GrafoscopioAbstractText >> replaceFrom: anInteger to: anInteger2 with: aCollection [
self subclassResponsibility
]
{ #category : #emphasis }
GrafoscopioAbstractText >> runLengthFor: characterIndex [
^ self runs runLengthFor: characterIndex
]
{ #category : #accessing }
GrafoscopioAbstractText >> runs [
self subclassResponsibility
]
{ #category : #accessing }
GrafoscopioAbstractText >> runs: anArray [
self subclassResponsibility "runs := RunArray new: self size withAll: anArray . "
]
{ #category : #accessing }
GrafoscopioAbstractText >> size [
^ self string size
]
{ #category : #accessing }
GrafoscopioAbstractText >> string [
^ self subclassResponsibility
]
{ #category : #accessing }
GrafoscopioAbstractText >> text: aParam [
self subclassResponsibility
]
"
This abstract class works for defining the basic type required by Rubric
"
Class {
#name : #GrafoscopioAbstractText,
#superclass : #Object,
#category : #'Grafoscopio-Pillar'
}
{ #category : #'as yet unclassified' }
GrafoscopioAbstractText >> allRangesOfSubstring: aString [
^ { }
]
{ #category : #converting }
GrafoscopioAbstractText >> asText [
^ self
]
{ #category : #accessing }
GrafoscopioAbstractText >> at: anIndex [
^ self subclassResponsibility
]
{ #category : #accessing }
GrafoscopioAbstractText >> attributesAt: characterIndex [
"Answer the code for characters in the run beginning at characterIndex."
"NB: no senders any more (supplanted by #attributesAt:forStyle: but retained for the moment in order not to break user code that may exist somewhere that still calls this"
| attributes |
" self size = 0
ifTrue: [^ Array with: (TextFontChange new fontNumber: 1)]."
self size = 0 ifTrue: [ ^#()].
attributes := self runs at: characterIndex.
^ attributes
]
{ #category : #accessing }
GrafoscopioAbstractText >> attributesAt: anInteger forStyle: aTextStyle [
| attributes size |
size := self size.
(size = 0 or: [ size < anInteger ])
ifTrue: [ ^ Array
with: (TextFontChange new fontNumber: aTextStyle defaultFontIndex) ]. "null text tolerates access"
attributes := self runs at: anInteger.
^ attributes
]
{ #category : #copying }
GrafoscopioAbstractText >> copy [
^ self
]
{ #category : #copying }
GrafoscopioAbstractText >> copyFrom: start to: stop [
^ self subclassResponsibility
]
{ #category : #testing }
GrafoscopioAbstractText >> ifNotEmpty: isNotEmptyBlock ifEmpty: isEmptyBlock [
^ self isEmpty
ifTrue: [ isEmptyBlock value ]
ifFalse: [ isNotEmptyBlock value ]
]
{ #category : #testing }
GrafoscopioAbstractText >> isEmpty [
^ self size = 0
]
{ #category : #testing }
GrafoscopioAbstractText >> isText [
^ true
]
{ #category : #accessing }
GrafoscopioAbstractText >> last [
^ self at: self size
]
{ #category : #copying }
GrafoscopioAbstractText >> notEmpty [
^ self isEmpty not
]
{ #category : #removing }
GrafoscopioAbstractText >> removeAttribute: anAttr [
^ self removeAttribute: anAttr from: 1 to: self size
]
{ #category : #removing }
GrafoscopioAbstractText >> removeAttribute: att from: start to: stop [
self subclassResponsibility
]
{ #category : #editing }
GrafoscopioAbstractText >> replaceFrom: anInteger to: anInteger2 with: aCollection [
self subclassResponsibility
]
{ #category : #emphasis }
GrafoscopioAbstractText >> runLengthFor: characterIndex [
^ self runs runLengthFor: characterIndex
]
{ #category : #accessing }
GrafoscopioAbstractText >> runs [
self subclassResponsibility
]
{ #category : #accessing }
GrafoscopioAbstractText >> runs: anArray [
self subclassResponsibility "runs := RunArray new: self size withAll: anArray . "
]
{ #category : #accessing }
GrafoscopioAbstractText >> size [
^ self string size
]
{ #category : #accessing }
GrafoscopioAbstractText >> string [
^ self subclassResponsibility
]
{ #category : #accessing }
GrafoscopioAbstractText >> text: aParam [
self subclassResponsibility
]

View File

@ -1,146 +1,160 @@
Class {
#name : #GrafoscopioAttributeBranchVisitor,
#superclass : #Object,
#instVars : [
'attributes',
'level',
'listLevel',
'index',
'text',
'styler'
],
#category : #'Grafoscopio-Pillar-Style'
}
{ #category : #accessing }
GrafoscopioAttributeBranchVisitor >> analyzeBranch: aBranch at: anIndex [
index := anIndex.
^ [ aBranch
inject: OrderedCollection new
into: [ :attrs :node |
node accept: self.
attrs addAll: (self attributesAt: node).
attrs ] ]
ensure: [ index := 0 ]
]
{ #category : #'as yet unclassified' }
GrafoscopioAttributeBranchVisitor >> attributes [
^ attributes
]
{ #category : #accessing }
GrafoscopioAttributeBranchVisitor >> attributesAt: aNode [
^ (attributes detect: [ :a | a first = aNode ]) second
]
{ #category : #'as yet unclassified' }
GrafoscopioAttributeBranchVisitor >> attributesAt: aNode ifAbsentPut: aBlock [
^ attributes
detect: [ :a | a first = aNode ]
ifFound: [ :a | a second ]
ifNone: [ | val |
val := aBlock value.
attributes
add:
{aNode.
val}.
val ]
]
{ #category : #'as yet unclassified' }
GrafoscopioAttributeBranchVisitor >> index: anIndex [
index := anIndex
]
{ #category : #'as yet unclassified' }
GrafoscopioAttributeBranchVisitor >> initialize [
attributes := OrderedCollection new.
styler := GrafoscopioPillarStyler defaultStyler.
]
{ #category : #'as yet unclassified' }
GrafoscopioAttributeBranchVisitor >> text: aGrafoscopioPillarASText [
text := aGrafoscopioPillarASText
]
{ #category : #'as yet unclassified' }
GrafoscopioAttributeBranchVisitor >> visitCodeblock: aPRCodeblock [
self
attributesAt: aPRCodeblock
ifAbsentPut: [ styler attributesForCodeBlock: aPRCodeblock at: index ]
]
{ #category : #'as yet unclassified' }
GrafoscopioAttributeBranchVisitor >> visitCommentedLine: aPRCommentedLine [
self attributesAt: aPRCommentedLine ifAbsentPut: [ styler default ]
]
{ #category : #'as yet unclassified' }
GrafoscopioAttributeBranchVisitor >> visitDocument: aPRDocument [
self attributesAt: aPRDocument ifAbsentPut: [ styler attributesForDocument: aPRDocument ]
]
{ #category : #'as yet unclassified' }
GrafoscopioAttributeBranchVisitor >> visitExternalLink: aPRExternalLink [
self
attributesAt: aPRExternalLink
ifAbsentPut: [ styler attributesForExternalLink: aPRExternalLink ]
]
{ #category : #'as yet unclassified' }
GrafoscopioAttributeBranchVisitor >> visitFigure: aPRFigure [
self attributesAt: aPRFigure ifAbsentPut: [ styler attributesForFigure: aPRFigure ]
]
{ #category : #'as yet unclassified' }
GrafoscopioAttributeBranchVisitor >> visitFormatText: aGrafoscopioFormatTextNode [
self attributesAt: aGrafoscopioFormatTextNode
ifAbsentPut: [ styler attributesForFormatText: aGrafoscopioFormatTextNode ]
]
{ #category : #'as yet unclassified' }
GrafoscopioAttributeBranchVisitor >> visitHeader: aPRHeader [
self
attributesAt: aPRHeader
ifAbsentPut: [ styler attributesForHeader: aPRHeader ]
]
{ #category : #'as yet unclassified' }
GrafoscopioAttributeBranchVisitor >> visitInternalLink: aPRInternalLink [
self
attributesAt: aPRInternalLink
ifAbsentPut: [ styler attributesForInternalLink: aPRInternalLink ]
]
{ #category : #'as yet unclassified' }
GrafoscopioAttributeBranchVisitor >> visitLineBreak: aPRLineBreak [
self attributesAt: aPRLineBreak
ifAbsentPut: [ styler attributesForLineBreak: aPRLineBreak ]
]
{ #category : #'as yet unclassified' }
GrafoscopioAttributeBranchVisitor >> visitListItem: aPRListItem [
self
attributesAt: aPRListItem
ifAbsentPut: [ styler attributesForListItem: aPRListItem at: index ]
]
{ #category : #'as yet unclassified' }
GrafoscopioAttributeBranchVisitor >> visitParagraph: aPRParagraph [
self
attributesAt: aPRParagraph
ifAbsentPut: [ styler attributesForParagraph: aPRParagraph ]
]
{ #category : #'as yet unclassified' }
GrafoscopioAttributeBranchVisitor >> visitText: aPRText [
self attributesAt: aPRText
ifAbsentPut: [ styler attributesForText: aPRText ]
]
{ #category : #'as yet unclassified' }
GrafoscopioAttributeBranchVisitor >> visitUnorderedList: aPRUnorderedList [
self attributesAt: aPRUnorderedList
ifAbsentPut: [ styler attributesForUnorderedList: aPRUnorderedList ]
]
Class {
#name : #GrafoscopioAttributeBranchVisitor,
#superclass : #Object,
#instVars : [
'attributes',
'level',
'listLevel',
'index',
'text',
'styler'
],
#category : #'Grafoscopio-Pillar-Style'
}
{ #category : #accessing }
GrafoscopioAttributeBranchVisitor >> analyzeBranch: aBranch at: anIndex [
index := anIndex.
^ [ aBranch
inject: OrderedCollection new
into: [ :attrs :node |
node accept: self.
attrs addAll: (self attributesAt: node).
attrs ] ]
ensure: [ index := 0 ]
]
{ #category : #'as yet unclassified' }
GrafoscopioAttributeBranchVisitor >> attributes [
^ attributes
]
{ #category : #accessing }
GrafoscopioAttributeBranchVisitor >> attributesAt: aNode [
^ (attributes detect: [ :a | a first = aNode ]) second
]
{ #category : #'as yet unclassified' }
GrafoscopioAttributeBranchVisitor >> attributesAt: aNode force: aBlock [
^ attributes
detect: [ :a | a first = aNode ]
ifFound: [ :a | a at:2 put: aBlock value ]
ifNone: [ | val |
val := aBlock value.
attributes
add:
{aNode.
val}.
val ]
]
{ #category : #'as yet unclassified' }
GrafoscopioAttributeBranchVisitor >> attributesAt: aNode ifAbsentPut: aBlock [
^ attributes
detect: [ :a | a first = aNode ]
ifFound: [ :a | a second ]
ifNone: [ | val |
val := aBlock value.
attributes
add:
{aNode.
val}.
val ]
]
{ #category : #'as yet unclassified' }
GrafoscopioAttributeBranchVisitor >> index: anIndex [
index := anIndex
]
{ #category : #'as yet unclassified' }
GrafoscopioAttributeBranchVisitor >> initialize [
attributes := OrderedCollection new.
styler := GrafoscopioPillarStyler defaultStyler.
]
{ #category : #'as yet unclassified' }
GrafoscopioAttributeBranchVisitor >> text: aGrafoscopioPillarASText [
text := aGrafoscopioPillarASText
]
{ #category : #'as yet unclassified' }
GrafoscopioAttributeBranchVisitor >> visitCodeblock: aPRCodeblock [
self
attributesAt: aPRCodeblock
ifAbsentPut: [ styler attributesForCodeBlock: aPRCodeblock at: index ]
]
{ #category : #'as yet unclassified' }
GrafoscopioAttributeBranchVisitor >> visitCommentedLine: aPRCommentedLine [
self attributesAt: aPRCommentedLine ifAbsentPut: [ styler default ]
]
{ #category : #'as yet unclassified' }
GrafoscopioAttributeBranchVisitor >> visitDocument: aPRDocument [
self attributesAt: aPRDocument ifAbsentPut: [ styler attributesForDocument: aPRDocument ]
]
{ #category : #'as yet unclassified' }
GrafoscopioAttributeBranchVisitor >> visitExternalLink: aPRExternalLink [
self
attributesAt: aPRExternalLink
ifAbsentPut: [ styler attributesForExternalLink: aPRExternalLink ]
]
{ #category : #'as yet unclassified' }
GrafoscopioAttributeBranchVisitor >> visitFigure: aPRFigure [
self attributesAt: aPRFigure ifAbsentPut: [ styler attributesForFigure: aPRFigure ]
]
{ #category : #'as yet unclassified' }
GrafoscopioAttributeBranchVisitor >> visitFormatText: aGrafoscopioFormatTextNode [
self attributesAt: aGrafoscopioFormatTextNode
ifAbsentPut: [ styler attributesForFormatText: aGrafoscopioFormatTextNode ]
]
{ #category : #'as yet unclassified' }
GrafoscopioAttributeBranchVisitor >> visitHeader: aPRHeader [
self
attributesAt: aPRHeader
ifAbsentPut: [ styler attributesForHeader: aPRHeader ]
]
{ #category : #'as yet unclassified' }
GrafoscopioAttributeBranchVisitor >> visitInternalLink: aPRInternalLink [
self
attributesAt: aPRInternalLink
ifAbsentPut: [ styler attributesForInternalLink: aPRInternalLink ]
]
{ #category : #'as yet unclassified' }
GrafoscopioAttributeBranchVisitor >> visitLineBreak: aPRLineBreak [
self attributesAt: aPRLineBreak
ifAbsentPut: [ styler attributesForLineBreak: aPRLineBreak ]
]
{ #category : #'as yet unclassified' }
GrafoscopioAttributeBranchVisitor >> visitListItem: aPRListItem [
self
attributesAt: aPRListItem
force: [ styler attributesForListItem: aPRListItem at: index ]
]
{ #category : #'as yet unclassified' }
GrafoscopioAttributeBranchVisitor >> visitParagraph: aPRParagraph [
self
attributesAt: aPRParagraph
ifAbsentPut: [ styler attributesForParagraph: aPRParagraph ]
]
{ #category : #'as yet unclassified' }
GrafoscopioAttributeBranchVisitor >> visitText: aPRText [
self attributesAt: aPRText
ifAbsentPut: [ styler attributesForText: aPRText ]
]
{ #category : #'as yet unclassified' }
GrafoscopioAttributeBranchVisitor >> visitUnorderedList: aPRUnorderedList [
self attributesAt: aPRUnorderedList
ifAbsentPut: [ styler attributesForUnorderedList: aPRUnorderedList ]
]

View File

@ -1,87 +1,87 @@
"
Branch node. this kind of node has no content
"
Class {
#name : #GrafoscopioBranchNode,
#superclass : #GrafoscopioLeafNode,
#instVars : [
'children'
],
#category : #'Grafoscopio-Model'
}
{ #category : #'instance creation' }
GrafoscopioBranchNode class >> isLeaf [
^ false
]
{ #category : #accessing }
GrafoscopioBranchNode >> acceptVisitor: aGrafoscopioVisitor [
aGrafoscopioVisitor visitBranchNode: self.
]
{ #category : #accessing }
GrafoscopioBranchNode >> acceptsChildsOfClass: aClass [
^ {GrafoscopioBranchNode.
GrafoscopioUnitNode} includes: aClass
]
{ #category : #accessing }
GrafoscopioBranchNode >> addAtBeginningChild: aBlock ofClass: aClass [
(self acceptsChildsOfClass: aClass)
ifTrue: [| child |
child := aBlock value.
child parent: self.
self children addFirst: child]
]
{ #category : #accessing }
GrafoscopioBranchNode >> addChild: aBlock ofClass: aClass [
(self acceptsChildsOfClass: aClass)
ifTrue: [ | child |
child := aBlock value.
child parent: self.
self children add: child ]
]
{ #category : #accessing }
GrafoscopioBranchNode >> children [
"Returns the receivers list of children"
^ children ifNil: [ children := OrderedCollection new ]
]
{ #category : #accessing }
GrafoscopioBranchNode >> children: aCollection [
"Sets the receivers children"
aCollection do: [:currentNode | currentNode parent: self ].
children := aCollection.
]
{ #category : #accessing }
GrafoscopioBranchNode >> isLeaf [
^ false
]
{ #category : #'as yet unclassified' }
GrafoscopioBranchNode >> moveDown: aNode [
| index |
"Moves the current node a place before in the children collection where is located"
index := children indexOf: aNode.
children swap: index with: (index + 1 min: children size)
]
{ #category : #'as yet unclassified' }
GrafoscopioBranchNode >> moveUp: aNode [
| index |
"Moves the current node a place before in the children collection where is located"
index := children indexOf: aNode.
children swap: index with: (index - 1 max: 1)
]
{ #category : #'as yet unclassified' }
GrafoscopioBranchNode >> remove: aGrafoscopioTextNode [
children remove: aGrafoscopioTextNode
]
"
Branch node. this kind of node has no content
"
Class {
#name : #GrafoscopioBranchNode,
#superclass : #GrafoscopioLeafNode,
#instVars : [
'children'
],
#category : #'Grafoscopio-Model'
}
{ #category : #'instance creation' }
GrafoscopioBranchNode class >> isLeaf [
^ false
]
{ #category : #accessing }
GrafoscopioBranchNode >> acceptVisitor: aGrafoscopioVisitor [
aGrafoscopioVisitor visitBranchNode: self.
]
{ #category : #accessing }
GrafoscopioBranchNode >> acceptsChildsOfClass: aClass [
^ {GrafoscopioBranchNode.
GrafoscopioUnitNode} includes: aClass
]
{ #category : #accessing }
GrafoscopioBranchNode >> addAtBeginningChild: aBlock ofClass: aClass [
(self acceptsChildsOfClass: aClass)
ifTrue: [| child |
child := aBlock value.
child parent: self.
self children addFirst: child]
]
{ #category : #accessing }
GrafoscopioBranchNode >> addChild: aBlock ofClass: aClass [
(self acceptsChildsOfClass: aClass)
ifTrue: [ | child |
child := aBlock value.
child parent: self.
self children add: child ]
]
{ #category : #accessing }
GrafoscopioBranchNode >> children [
"Returns the receivers list of children"
^ children ifNil: [ children := OrderedCollection new ]
]
{ #category : #accessing }
GrafoscopioBranchNode >> children: aCollection [
"Sets the receivers children"
aCollection do: [:currentNode | currentNode parent: self ].
children := aCollection.
]
{ #category : #accessing }
GrafoscopioBranchNode >> isLeaf [
^ false
]
{ #category : #'as yet unclassified' }
GrafoscopioBranchNode >> moveDown: aNode [
| index |
"Moves the current node a place before in the children collection where is located"
index := children indexOf: aNode.
children swap: index with: (index + 1 min: children size)
]
{ #category : #'as yet unclassified' }
GrafoscopioBranchNode >> moveUp: aNode [
| index |
"Moves the current node a place before in the children collection where is located"
index := children indexOf: aNode.
children swap: index with: (index - 1 max: 1)
]
{ #category : #'as yet unclassified' }
GrafoscopioBranchNode >> remove: aGrafoscopioTextNode [
children remove: aGrafoscopioTextNode
]

View File

@ -1,86 +1,86 @@
"
I'm just a prototype of how morphic buttons can be embedded
inside a Grafoscopio notebook UI via Spec.
I'm not used in the actual UI, but I'm more a remainder of directions
to explore.
"
Class {
#name : #GrafoscopioButtonModel,
#superclass : #ComposablePresenter,
#instVars : [
'button'
],
#category : #'Grafoscopio-UI'
}
{ #category : #specs }
GrafoscopioButtonModel class >> defaultSpec [
^ SpecLayout composed add: #button
]
{ #category : #accessing }
GrafoscopioButtonModel >> body [
^ self button
]
{ #category : #accessing }
GrafoscopioButtonModel >> button [
^ button
]
{ #category : #accessing }
GrafoscopioButtonModel >> button: anObject [
button := anObject
]
{ #category : #accessing }
GrafoscopioButtonModel >> cancel [
^ cancel
]
{ #category : #accessing }
GrafoscopioButtonModel >> cancel: anObject [
cancel := anObject
]
{ #category : #api }
GrafoscopioButtonModel >> content: anAssoc [
button label: anAssoc key.
button action: anAssoc value.
]
{ #category : #accessing }
GrafoscopioButtonModel >> find [
^ find
]
{ #category : #accessing }
GrafoscopioButtonModel >> find: anObject [
find := anObject
]
{ #category : #initalize }
GrafoscopioButtonModel >> initializeWidgets [
button := self newButton.
]
{ #category : #accessing }
GrafoscopioButtonModel >> ok [
^ ok
]
{ #category : #accessing }
GrafoscopioButtonModel >> ok: anObject [
ok := anObject
]
{ #category : #accessing }
GrafoscopioButtonModel >> replace [
^ replace
]
{ #category : #accessing }
GrafoscopioButtonModel >> replace: anObject [
replace := anObject
]
"
I'm just a prototype of how morphic buttons can be embedded
inside a Grafoscopio notebook UI via Spec.
I'm not used in the actual UI, but I'm more a remainder of directions
to explore.
"
Class {
#name : #GrafoscopioButtonModel,
#superclass : #ComposablePresenter,
#instVars : [
'button'
],
#category : #'Grafoscopio-UI'
}
{ #category : #specs }
GrafoscopioButtonModel class >> defaultSpec [
^ SpecLayout composed add: #button
]
{ #category : #accessing }
GrafoscopioButtonModel >> body [
^ self button
]
{ #category : #accessing }
GrafoscopioButtonModel >> button [
^ button
]
{ #category : #accessing }
GrafoscopioButtonModel >> button: anObject [
button := anObject
]
{ #category : #accessing }
GrafoscopioButtonModel >> cancel [
^ cancel
]
{ #category : #accessing }
GrafoscopioButtonModel >> cancel: anObject [
cancel := anObject
]
{ #category : #api }
GrafoscopioButtonModel >> content: anAssoc [
button label: anAssoc key.
button action: anAssoc value.
]
{ #category : #accessing }
GrafoscopioButtonModel >> find [
^ find
]
{ #category : #accessing }
GrafoscopioButtonModel >> find: anObject [
find := anObject
]
{ #category : #initalize }
GrafoscopioButtonModel >> initializeWidgets [
button := self newButton.
]
{ #category : #accessing }
GrafoscopioButtonModel >> ok [
^ ok
]
{ #category : #accessing }
GrafoscopioButtonModel >> ok: anObject [
ok := anObject
]
{ #category : #accessing }
GrafoscopioButtonModel >> replace [
^ replace
]
{ #category : #accessing }
GrafoscopioButtonModel >> replace: anObject [
replace := anObject
]

View File

@ -1,64 +1,64 @@
"
I represent a Pharo code node inside a Grafoscopio notebook as a
embedded interactive Playground.
"
Class {
#name : #GrafoscopioCodeModel,
#superclass : #ComposablePresenter,
#instVars : [
'body'
],
#category : #'Grafoscopio-UI'
}
{ #category : #specs }
GrafoscopioCodeModel class >> defaultSpec [
^ SpecLayout composed add: #body
]
{ #category : #accessing }
GrafoscopioCodeModel >> body [
^ body
]
{ #category : #accessing }
GrafoscopioCodeModel >> body: anObject [
body := anObject
]
{ #category : #API }
GrafoscopioCodeModel >> content: aGrafoscopioNodeContent [
body text: aGrafoscopioNodeContent
]
{ #category : #'as yet unclassified' }
GrafoscopioCodeModel >> extractHtmlImages [
"comment stating purpose of message"
|imgSoup imgHost imgList src|
imgList := Set new.
imgSoup := Soup fromString: self body.
(imgSoup findAllTags: 'img') do: [ :each|
src := (each attributeAt: 'src') asUrl.
(src host) ifNil: [src host: self links last asUrl removeLastPathSegment].
imgList add: src.
"imgList add: (each attributeAt: 'src') asUrl."
"OSProcess waitForCommand: 'wget ', (each attributeAt: 'src')."
"imgHost := self links last removeLastPathSegment."
"imgPath:= ((each attributeAt: 'src') asUrl). "
"ZnEasy getJpeg: (imgHost , imgPath) asUrl."
"OSProcess waitForCommand: ('mkdir ', imgPath)."
"Transcript show: ' wget ', imgPath , '/',(each attributeAt: 'src'). "
].
^imgList .
]
{ #category : #initialization }
GrafoscopioCodeModel >> initializeWidgets [
body := self newCode.
]
"
I represent a Pharo code node inside a Grafoscopio notebook as a
embedded interactive Playground.
"
Class {
#name : #GrafoscopioCodeModel,
#superclass : #ComposablePresenter,
#instVars : [
'body'
],
#category : #'Grafoscopio-UI'
}
{ #category : #specs }
GrafoscopioCodeModel class >> defaultSpec [
^ SpecLayout composed add: #body
]
{ #category : #accessing }
GrafoscopioCodeModel >> body [
^ body
]
{ #category : #accessing }
GrafoscopioCodeModel >> body: anObject [
body := anObject
]
{ #category : #API }
GrafoscopioCodeModel >> content: aGrafoscopioNodeContent [
body text: aGrafoscopioNodeContent
]
{ #category : #'as yet unclassified' }
GrafoscopioCodeModel >> extractHtmlImages [
"comment stating purpose of message"
|imgSoup imgHost imgList src|
imgList := Set new.
imgSoup := Soup fromString: self body.
(imgSoup findAllTags: 'img') do: [ :each|
src := (each attributeAt: 'src') asUrl.
(src host) ifNil: [src host: self links last asUrl removeLastPathSegment].
imgList add: src.
"imgList add: (each attributeAt: 'src') asUrl."
"OSProcess waitForCommand: 'wget ', (each attributeAt: 'src')."
"imgHost := self links last removeLastPathSegment."
"imgPath:= ((each attributeAt: 'src') asUrl). "
"ZnEasy getJpeg: (imgHost , imgPath) asUrl."
"OSProcess waitForCommand: ('mkdir ', imgPath)."
"Transcript show: ' wget ', imgPath , '/',(each attributeAt: 'src'). "
].
^imgList .
]
{ #category : #initialization }
GrafoscopioCodeModel >> initializeWidgets [
body := self newCode.
]

View File

@ -1,24 +0,0 @@
"
This kind of a leafNodes holds code text.
"
Class {
#name : #GrafoscopioCodeNode,
#superclass : #GrafoscopioTextNode,
#category : #'Grafoscopio-Model'
}
{ #category : #'as yet unclassified' }
GrafoscopioCodeNode class >> icon [
^ self iconNamed:#objects
]
{ #category : #'as yet unclassified' }
GrafoscopioCodeNode class >> nameForSelection [
^ 'New Code Node'
]
{ #category : #accessing }
GrafoscopioCodeNode >> acceptVisitor: aGrafoscopioVisitor [
aGrafoscopioVisitor visitCodeNode: self.
]

View File

@ -1,66 +1,66 @@
"
I define the documentation for the Grafoscopio package.
"
Class {
#name : #GrafoscopioDocs,
#superclass : #GrafoscopioDocumentation,
#category : #Grafoscopio
}
{ #category : #operation }
GrafoscopioDocs class >> devNotes [
"I'm just an alias to ease the operation. I need to know wich is the index of the notebook
I want to return, as defined on instance initialize method"
| docs |
docs := self newDefault.
^ (docs localPlace fullName, '/', (docs documents at: 5)) asFileReference.
]
{ #category : #initialization }
GrafoscopioDocs class >> initialize [
self update
]
{ #category : #operation }
GrafoscopioDocs class >> manual [
"I'm just an alias to ease the operation. I need to know wich is the index of the notebook
I want to open, as defined on method."
| docs |
docs := self newDefault.
^ (docs localPlace fullName, '/', (docs documents at: 2)) asFileReference.
]
{ #category : #operation }
GrafoscopioDocs class >> openPDFManual [
"I open the documentation in PDF format."
| pdfManual |
pdfManual := FileLocator imageDirectory asFileReference / 'Grafoscopio/Docs/En/Books/Manual/manual.pdf'.
WebBrowser openOn: pdfManual fullName.
]
{ #category : #operation }
GrafoscopioDocs class >> tutorial [
"I'm just an alias to ease the operation. I need to know wich is the index of the notebook
I want to return, as defined on instance initialize method"
| docs |
docs := self newDefault.
^ (docs localPlace fullName, '/', (docs documents at: 1)) asFileReference.
]
{ #category : #initialization }
GrafoscopioDocs >> initialize [
"I model the important documents that belong to the Grafoscopio documentation.
When more documents become more mature and usable, I will include them."
super initialize.
name := 'grafoscopio'.
repository := (FossilRepo new remote: 'http://mutabit.com/repos.fossil/grafoscopio').
localPlace := FileLocator workingDirectory asFileReference /'Grafoscopio'.
self
addDocument: 'Docs/Es/Tutoriales/tutorial.ston';
addDocument: 'Docs/En/Books/Manual/manual.ston';
addDocument: 'uv/Docs/En/Books/Manual/manual.pdf';
addDocument: 'Docs/En/Books/DataActivism/techniques-for-datactivism.ston';
addDocument: 'Docs/En/dev-notes.ston';
addDocument: 'Docs/En/Books/SpecIUFramework/spec-ui-framework.ston'.
]
"
I define the documentation for the Grafoscopio package.
"
Class {
#name : #GrafoscopioDocs,
#superclass : #GrafoscopioDocumentation,
#category : #Grafoscopio
}
{ #category : #operation }
GrafoscopioDocs class >> devNotes [
"I'm just an alias to ease the operation. I need to know wich is the index of the notebook
I want to return, as defined on instance initialize method"
| docs |
docs := self newDefault.
^ (docs localPlace fullName, '/', (docs documents at: 5)) asFileReference.
]
{ #category : #initialization }
GrafoscopioDocs class >> initialize [
self update
]
{ #category : #operation }
GrafoscopioDocs class >> manual [
"I'm just an alias to ease the operation. I need to know wich is the index of the notebook
I want to open, as defined on method."
| docs |
docs := self newDefault.
^ (docs localPlace fullName, '/', (docs documents at: 2)) asFileReference.
]
{ #category : #operation }
GrafoscopioDocs class >> openPDFManual [
"I open the documentation in PDF format."
| pdfManual |
pdfManual := FileLocator imageDirectory asFileReference / 'Grafoscopio/Docs/En/Books/Manual/manual.pdf'.
WebBrowser openOn: pdfManual fullName.
]
{ #category : #operation }
GrafoscopioDocs class >> tutorial [
"I'm just an alias to ease the operation. I need to know wich is the index of the notebook
I want to return, as defined on instance initialize method"
| docs |
docs := self newDefault.
^ (docs localPlace fullName, '/', (docs documents at: 1)) asFileReference.
]
{ #category : #initialization }
GrafoscopioDocs >> initialize [
"I model the important documents that belong to the Grafoscopio documentation.
When more documents become more mature and usable, I will include them."
super initialize.
name := 'grafoscopio'.
repository := (FossilRepo new remote: 'http://mutabit.com/repos.fossil/grafoscopio').
localPlace := FileLocator workingDirectory asFileReference /'Grafoscopio'.
self
addDocument: 'Docs/Es/Tutoriales/tutorial.ston';
addDocument: 'Docs/En/Books/Manual/manual.ston';
addDocument: 'uv/Docs/En/Books/Manual/manual.pdf';
addDocument: 'Docs/En/Books/DataActivism/techniques-for-datactivism.ston';
addDocument: 'Docs/En/dev-notes.ston';
addDocument: 'Docs/En/Books/SpecIUFramework/spec-ui-framework.ston'.
]

View File

@ -1,151 +0,0 @@
Class {
#name : #GrafoscopioDocumentEditionPerspective,
#superclass : #GrafoscopioPerspective,
#instVars : [
'tree',
'document'
],
#category : #'Grafoscopio-New-UI'
}
{ #category : #accessing }
GrafoscopioDocumentEditionPerspective class >> defaultSpec [
^ SpBoxLayout newVertical
add: #toolbar height: self toolbarHeight;
add:
(SpBoxLayout newHorizontal
add: #tree width: 100;
add: #viewport;
yourself) yourself
]
{ #category : #accessing }
GrafoscopioDocumentEditionPerspective class >> icon [
^ self iconNamed: #merge
]
{ #category : #'adding - convenience' }
GrafoscopioDocumentEditionPerspective >> addAtBeginningNewNodeOfClass: aClass [
self
addAtBeginningOf: (tree selectedItem ifNil: [ document ])
aNodeOfClass: aClass
]
{ #category : #'adding - base' }
GrafoscopioDocumentEditionPerspective >> addAtBeginningOf: aNode aNodeOfClass: aClass [
aNode
addAtBeginningChild: [ self instantiateNode: aClass ]
ofClass: aClass.
self modelChanged
]
{ #category : #'adding - convenience' }
GrafoscopioDocumentEditionPerspective >> addAtLastNewNodeOfClass: aClass [
self
addAtLastOf: (tree selectedItem ifNil: [ document ])
aNodeOfClass: aClass
]
{ #category : #'adding - base' }
GrafoscopioDocumentEditionPerspective >> addAtLastOf: aNode aNodeOfClass: aClass [
aNode
addChild: [ self instantiateNode: aClass ]
ofClass: aClass.
self modelChanged
]
{ #category : #'adding - convenience' }
GrafoscopioDocumentEditionPerspective >> addNewNodeAtBeginningOf: aNode [
self addAtBeginningOf: aNode aNodeOfClass: self chooseKindsOfNode
]
{ #category : #'adding - convenience' }
GrafoscopioDocumentEditionPerspective >> addNewNodeAtLastOf: aNode [
self addAtLastOf: aNode aNodeOfClass: self chooseKindsOfNode
]
{ #category : #'adding - convenience' }
GrafoscopioDocumentEditionPerspective >> addNewNodeOfClass: aClass [
^ self addAtLastNewNodeOfClass: aClass
]
{ #category : #initialization }
GrafoscopioDocumentEditionPerspective >> createDefaultViewportVisitor [
^ GrafoscopioViewportVisitor new
]
{ #category : #initialization }
GrafoscopioDocumentEditionPerspective >> createViewport [
^ self renderViewport: document
]
{ #category : #initialization }
GrafoscopioDocumentEditionPerspective >> informNodeHasChanged: aNode [
| path |
path := tree selection selectedPath.
tree roots: {document}.
tree selectPath: path.
]
{ #category : #initialization }
GrafoscopioDocumentEditionPerspective >> initializeWidgets [
super initializeWidgets.
tree := self newTreeTable.
tree
addColumn: (SpStringTableColumn evaluated: #name);
children: [ :node |
node isLeaf
ifTrue: [ {} ]
ifFalse: [ node children reject:[: a | a isLeaf ] ]].
tree activateOnDoubleClick.
tree whenSelectionChangedDo: [ : a | self renderViewport: a selectedItem ].
tree whenActivatedDo: [ : a | self tooglePresenterForEdition: a ].
]
{ #category : #'as yet unclassified' }
GrafoscopioDocumentEditionPerspective >> instantiateNode: aClass [
aClass class = GrafoscopioUnitNode species
ifTrue: [ | name |
name := UIManager default
request: 'Unit name'
initialAnswer: 'New unit'.
^ aClass new
name: name;
yourself ].
^ aClass new
]
{ #category : #initialization }
GrafoscopioDocumentEditionPerspective >> modelChanged [
| path |
viewport := self createViewport.
path := tree selection selectedPath.
tree roots: {document}.
tree selectPath: path.
self needRebuild: false.
self buildWithSpec
]
{ #category : #initialization }
GrafoscopioDocumentEditionPerspective >> renderViewport: aNode [
^ self createDefaultViewportVisitor createViewportFor: ( aNode ifNil: [ document ]) into: self
]
{ #category : #initialization }
GrafoscopioDocumentEditionPerspective >> setModelBeforeInitialization: aDomainObject [
super setModelBeforeInitialization: aDomainObject.
document := aDomainObject .
]
{ #category : #initialization }
GrafoscopioDocumentEditionPerspective >> tooglePresenterForEdition: anObect [
self halt.
]
{ #category : #initialization }
GrafoscopioDocumentEditionPerspective >> viewport [
^ viewport
]

View File

@ -0,0 +1,20 @@
Class {
#name : #GrafoscopioDocumentRichTextEditionPerspective,
#superclass : #GrafoscopioDocumentTextEditionPerspective,
#category : #'Grafoscopio-New-UI'
}
{ #category : #accessing }
GrafoscopioDocumentRichTextEditionPerspective class >> icon [
^ self iconNamed: #merge
]
{ #category : #initialization }
GrafoscopioDocumentRichTextEditionPerspective >> aboutToBeUninstalledFrom: aTreeNotebook [
]
{ #category : #initialization }
GrafoscopioDocumentRichTextEditionPerspective >> createDefaultViewportVisitor [
^ GrafoscopioViewportRichTextVisitor new
]

View File

@ -0,0 +1,189 @@
Class {
#name : #GrafoscopioDocumentTextEditionPerspective,
#superclass : #GrafoscopioPerspective,
#instVars : [
'tree',
'document',
'buildingVisitor'
],
#category : #'Grafoscopio-New-UI'
}
{ #category : #accessing }
GrafoscopioDocumentTextEditionPerspective class >> buildCommandsGroupWith: presenterInstance forRoot: rootCommandGroup [
rootCommandGroup
register: (self buildMenuBarGroupWith: presenterInstance)";
register: (self buildContextualMenuGroupWith: presenterInstance)"
]
{ #category : #accessing }
GrafoscopioDocumentTextEditionPerspective class >> buildContextualMenuGroupWith: presenterInstance [
^ (CmCommandGroup named: 'Context Menu') asSpecGroup
register: (self buildEditionGroupWith: presenterInstance);
register: (self buildAddingGroupWith: presenterInstance);
register: (self buildRemovingGroupWith: presenterInstance);
yourself
]
{ #category : #accessing }
GrafoscopioDocumentTextEditionPerspective class >> buildMenuBarGroupWith: presenterInstance [
^ (CmCommandGroup named: 'Context Menu') asSpecGroup
register:
(CmBlockCommand new
name: 'Inspect node';
block:
[ :context | context viewport selectedPage activePresenter inspectNode ];
asSpecCommand);
register:
(CmBlockCommand new
name: 'Inspect runs';
block:
[ :context | context viewport selectedPage activePresenter inspectRuns ];
asSpecCommand);
yourself
]
{ #category : #accessing }
GrafoscopioDocumentTextEditionPerspective class >> defaultSpec [
^ SpBoxLayout newVertical
add: #toolbar height: self toolbarHeight;
add:
(SpBoxLayout newHorizontal
add: #tree width: 100;
add: #viewport;
yourself) yourself
]
{ #category : #accessing }
GrafoscopioDocumentTextEditionPerspective class >> icon [
^ self iconNamed: #edit
]
{ #category : #'adding - convenience' }
GrafoscopioDocumentTextEditionPerspective >> aboutToBeUninstalledFrom: aTreeNotebook [
aTreeNotebook removePerspective: self
]
{ #category : #'adding - convenience' }
GrafoscopioDocumentTextEditionPerspective >> addAtLastNewNodeOfClass: aClass [
self
addAtLastOf: (tree selectedItem ifNil: [ document ])
aNodeOfClass: aClass
]
{ #category : #'adding - base' }
GrafoscopioDocumentTextEditionPerspective >> addAtLastOf: aNode aNodeOfClass: aClass [
aNode
addChild: [ self instantiateNode: aClass ]
ofClass: aClass.
self modelChanged
]
{ #category : #'adding - convenience' }
GrafoscopioDocumentTextEditionPerspective >> addNewNodeOfClass: aClass [
^ self addAtLastNewNodeOfClass: aClass
]
{ #category : #initialization }
GrafoscopioDocumentTextEditionPerspective >> buildingVisitor [
^ buildingVisitor
ifNil: [ buildingVisitor := self createDefaultViewportVisitor ]
]
{ #category : #initialization }
GrafoscopioDocumentTextEditionPerspective >> buildingVisitor: aVisitor [
buildingVisitor := aVisitor
]
{ #category : #initialization }
GrafoscopioDocumentTextEditionPerspective >> createDefaultViewportVisitor [
^ GrafoscopioViewportTextVisitor new
]
{ #category : #initialization }
GrafoscopioDocumentTextEditionPerspective >> createViewport [
^ self renderViewport: document
]
{ #category : #initialization }
GrafoscopioDocumentTextEditionPerspective >> informNodeHasChanged: aNode [
| path |
path := tree selection selectedPath.
tree roots: {document}.
tree selectPath: path.
]
{ #category : #initialization }
GrafoscopioDocumentTextEditionPerspective >> initializeWidgets [
super initializeWidgets.
tree := self newTreeTable.
tree
addColumn: (SpStringTableColumn evaluated: #name);
children: [ :node |
node isLeaf
ifTrue: [ {} ]
ifFalse: [ node children ] ].
tree activateOnDoubleClick.
tree
whenSelectionChangedDo: [ :a | self renderViewport: a selectedItem ].
tree whenActivatedDo: [ : a | self requestNewNameFor: a selectedItem ]
]
{ #category : #'as yet unclassified' }
GrafoscopioDocumentTextEditionPerspective >> instantiateNode: aClass [
| name |
name := UIManager default
request: 'Please, name the item'
initialAnswer: 'New item'.
^ aClass new
name: name;
yourself
]
{ #category : #initialization }
GrafoscopioDocumentTextEditionPerspective >> modelChanged [
| path |
path := tree selection selectedPath.
tree roots: {document}.
tree selectPath: path.
self needRebuild: false.
self buildWithSpec
]
{ #category : #initialization }
GrafoscopioDocumentTextEditionPerspective >> nameChanged [
| path |
path := tree selection selectedPath.
tree roots: {document}.
tree buildWithSpec.
tree selectPath: path
]
{ #category : #initialization }
GrafoscopioDocumentTextEditionPerspective >> renderViewport: aNode [
^ self buildingVisitor createViewportFor: ( aNode ifNil: [ document ]) into: self
]
{ #category : #initialization }
GrafoscopioDocumentTextEditionPerspective >> requestNewNameFor: aNode [
| name |
name := UIManager default
request: 'Please, name the node'
initialAnswer: aNode name asString.
name ifNotNil: [ aNode name: name ].
self buildingVisitor renamePageFor: aNode.
self nameChanged .
]
{ #category : #initialization }
GrafoscopioDocumentTextEditionPerspective >> setModelBeforeInitialization: aDomainObject [
super setModelBeforeInitialization: aDomainObject.
document := aDomainObject .
]
{ #category : #initialization }
GrafoscopioDocumentTextEditionPerspective >> viewport [
^ viewport
]

View File

@ -1,15 +1,15 @@
Class {
#name : #GrafoscopioExportPerspective,
#superclass : #GrafoscopioPerspective,
#category : #'Grafoscopio-New-UI'
}
{ #category : #accessing }
GrafoscopioExportPerspective class >> icon [
^ self iconNamed: #export
]
{ #category : #initialization }
GrafoscopioExportPerspective >> createViewport [
^ self newLabel
]
Class {
#name : #GrafoscopioExportPerspective,
#superclass : #GrafoscopioPerspective,
#category : #'Grafoscopio-New-UI'
}
{ #category : #accessing }
GrafoscopioExportPerspective class >> icon [
^ self iconNamed: #export
]
{ #category : #initialization }
GrafoscopioExportPerspective >> createViewport [
^ self newLabel
]

View File

@ -1,14 +1,14 @@
Class {
#name : #GrafoscopioFmtAnchorAsBody,
#superclass : #GrafoscopioFmtUrlAsBody,
#category : #'Grafoscopio-Pillar-TextFormat'
}
{ #category : #'target resize' }
GrafoscopioFmtAnchorAsBody >> beInstalledIn: anExternalLink [
anExternalLink children isEmpty ifFalse: [ ^ self ].
self
installTextNodeAtRightWithValue: anExternalLink anchor asString
in: anExternalLink
]
Class {
#name : #GrafoscopioFmtAnchorAsBody,
#superclass : #GrafoscopioFmtUrlAsBody,
#category : #'Grafoscopio-Pillar-TextFormat'
}
{ #category : #'target resize' }
GrafoscopioFmtAnchorAsBody >> beInstalledIn: anExternalLink [
anExternalLink children isEmpty ifFalse: [ ^ self ].
self
installTextNodeAtRightWithValue: anExternalLink anchor asString
in: anExternalLink
]

View File

@ -1,10 +1,11 @@
Class {
#name : #GrafoscopioFmtAnchorOnTheLeft,
#superclass : #GrafoscopioFormat,
#category : #'Grafoscopio-Pillar-TextFormat'
}
{ #category : #'target resize' }
GrafoscopioFmtAnchorOnTheLeft >> beInstalledIn: aNode [
self installTextNodeAtLeftWithValue: (Character value: 1) asString in: aNode
]
Class {
#name : #GrafoscopioFmtAnchorOnTheLeft,
#superclass : #GrafoscopioFormat,
#category : #'Grafoscopio-Pillar-TextFormat'
}
{ #category : #'target resize' }
GrafoscopioFmtAnchorOnTheLeft >> beInstalledIn: aNode [
self installTextNodeAtLeftWithValue: (Character value: 1) asString in: aNode
]

View File

@ -1,13 +1,13 @@
Class {
#name : #GrafoscopioFmtAnchorOnTheLeft2,
#superclass : #GrafoscopioFormat,
#category : #'Grafoscopio-Pillar-TextFormat'
}
{ #category : #'target resize' }
GrafoscopioFmtAnchorOnTheLeft2 >> beInstalledIn: aNode [
aNode language originalName = 'pharo-image'
ifTrue: [
aNode propertyAt: #text put: aNode text.
aNode text: (Character value: 1) asString ]
]
Class {
#name : #GrafoscopioFmtAnchorOnTheLeft2,
#superclass : #GrafoscopioFormat,
#category : #'Grafoscopio-Pillar-TextFormat'
}
{ #category : #'target resize' }
GrafoscopioFmtAnchorOnTheLeft2 >> beInstalledIn: aNode [
aNode language originalName = 'pharo-image'
ifTrue: [
aNode propertyAt: #text put: aNode text.
aNode text: (Character value: 1) asString ]
]

View File

@ -1,10 +1,11 @@
Class {
#name : #GrafoscopioFmtBeginningLinebreak,
#superclass : #GrafoscopioFormat,
#category : #'Grafoscopio-Pillar-TextFormat'
}
{ #category : #'target resize' }
GrafoscopioFmtBeginningLinebreak >> beInstalledIn: aNode [
self installTextNodeAtLeftWithValue: OSPlatform current lineEnding in: aNode
]
Class {
#name : #GrafoscopioFmtBeginningLinebreak,
#superclass : #GrafoscopioFormat,
#category : #'Grafoscopio-Pillar-TextFormat'
}
{ #category : #'target resize' }
GrafoscopioFmtBeginningLinebreak >> beInstalledIn: aNode [
" Should be using OSPlatform current lineEnding, but our text presenter does not support to have 2 character representation "
self installTextNodeAtLeftWithValue: String cr in: aNode
]

View File

@ -1,11 +1,12 @@
Class {
#name : #GrafoscopioFmtDoubleLinebreak,
#superclass : #GrafoscopioFormat,
#category : #'Grafoscopio-Pillar-TextFormat'
}
{ #category : #'target resize' }
GrafoscopioFmtDoubleLinebreak >> beInstalledIn: aNode [
self installTextNodeAtLeftWithValue: OSPlatform current lineEnding in: aNode.
self installTextNodeAtRightWithValue: OSPlatform current lineEnding in: aNode
]
Class {
#name : #GrafoscopioFmtDoubleLinebreak,
#superclass : #GrafoscopioFormat,
#category : #'Grafoscopio-Pillar-TextFormat'
}
{ #category : #'target resize' }
GrafoscopioFmtDoubleLinebreak >> beInstalledIn: aNode [
" Should be using OSPlatform current lineEnding, but our text presenter does not support to have 2 character representation "
self installTextNodeAtLeftWithValue: String cr in: aNode.
self installTextNodeAtRightWithValue: String cr in: aNode
]

View File

@ -1,15 +1,16 @@
Class {
#name : #GrafoscopioFmtEndingLinebreak,
#superclass : #GrafoscopioFormat,
#category : #'Grafoscopio-Pillar-TextFormat'
}
{ #category : #'target resize' }
GrafoscopioFmtEndingLinebreak >> beInstalledIn: aNode [
self installTextNodeAtRightWithValue: OSPlatform current lineEnding in: aNode
]
{ #category : #'target resize' }
GrafoscopioFmtEndingLinebreak >> value: aString [
^aString , OSPlatform current lineEnding
]
Class {
#name : #GrafoscopioFmtEndingLinebreak,
#superclass : #GrafoscopioFormat,
#category : #'Grafoscopio-Pillar-TextFormat'
}
{ #category : #'target resize' }
GrafoscopioFmtEndingLinebreak >> beInstalledIn: aNode [
" Should be using OSPlatform current lineEnding, but our text presenter does not support to have 2 character representation "
self installTextNodeAtRightWithValue: String cr in: aNode
]
{ #category : #'target resize' }
GrafoscopioFmtEndingLinebreak >> value: aString [
^aString , OSPlatform current lineEnding
]

View File

@ -1,12 +1,12 @@
Class {
#name : #GrafoscopioFmtEndingSpace,
#superclass : #GrafoscopioFormat,
#category : #'Grafoscopio-Pillar-TextFormat'
}
{ #category : #'target resize' }
GrafoscopioFmtEndingSpace >> beInstalledIn: aNode [
self
installTextNodeAtRightWithValue: String space
in: aNode
]
Class {
#name : #GrafoscopioFmtEndingSpace,
#superclass : #GrafoscopioFormat,
#category : #'Grafoscopio-Pillar-TextFormat'
}
{ #category : #'target resize' }
GrafoscopioFmtEndingSpace >> beInstalledIn: aNode [
self
installTextNodeAtRightWithValue: String space
in: aNode
]

View File

@ -1,14 +1,14 @@
Class {
#name : #GrafoscopioFmtUrlAsBody,
#superclass : #GrafoscopioFormat,
#category : #'Grafoscopio-Pillar-TextFormat'
}
{ #category : #'target resize' }
GrafoscopioFmtUrlAsBody >> beInstalledIn: anExternalLink [
anExternalLink children isEmpty ifFalse: [ ^ self ].
self
installTextNodeAtRightWithValue: anExternalLink reference asString
in: anExternalLink
]
Class {
#name : #GrafoscopioFmtUrlAsBody,
#superclass : #GrafoscopioFormat,
#category : #'Grafoscopio-Pillar-TextFormat'
}
{ #category : #'target resize' }
GrafoscopioFmtUrlAsBody >> beInstalledIn: anExternalLink [
anExternalLink children isEmpty ifFalse: [ ^ self ].
self
installTextNodeAtRightWithValue: anExternalLink reference asString
in: anExternalLink
]

View File

@ -1,41 +1,41 @@
Class {
#name : #GrafoscopioFormat,
#superclass : #Object,
#classInstVars : [
'instance'
],
#category : #'Grafoscopio-Pillar-TextFormat'
}
{ #category : #accessing }
GrafoscopioFormat class >> instance [
^ instance ifNil: [ instance := self new ]
]
{ #category : #'target resize' }
GrafoscopioFormat >> beInstalledIn: aNode [
self subclassResponsibility .
]
{ #category : #'target resize' }
GrafoscopioFormat >> installTextNodeAtLeftWithValue: aString in: aNode [
| newTextChild |
newTextChild := self newTextChildFor: aString in: aNode.
aNode children: {newTextChild} , aNode children
]
{ #category : #'target resize' }
GrafoscopioFormat >> installTextNodeAtRightWithValue: aString in: aNode [
| newTextChild |
newTextChild := self newTextChildFor: aString in: aNode.
aNode children: aNode children , {newTextChild}
]
{ #category : #'target resize' }
GrafoscopioFormat >> newTextChildFor: aString in: aNode [
^ GrafoscopioFormatTextNode new
text: aString;
parent: aNode;
yourself
]
Class {
#name : #GrafoscopioFormat,
#superclass : #Object,
#classInstVars : [
'instance'
],
#category : #'Grafoscopio-Pillar-TextFormat'
}
{ #category : #accessing }
GrafoscopioFormat class >> instance [
^ instance ifNil: [ instance := self new ]
]
{ #category : #'target resize' }
GrafoscopioFormat >> beInstalledIn: aNode [
self subclassResponsibility .
]
{ #category : #'target resize' }
GrafoscopioFormat >> installTextNodeAtLeftWithValue: aString in: aNode [
| newTextChild |
newTextChild := self newTextChildFor: aString in: aNode.
aNode children: {newTextChild} , aNode children
]
{ #category : #'target resize' }
GrafoscopioFormat >> installTextNodeAtRightWithValue: aString in: aNode [
| newTextChild |
newTextChild := self newTextChildFor: aString in: aNode.
aNode children: aNode children , {newTextChild}
]
{ #category : #'target resize' }
GrafoscopioFormat >> newTextChildFor: aString in: aNode [
^ GrafoscopioFormatTextNode new
text: aString;
parent: aNode;
yourself
]

View File

@ -1,16 +1,16 @@
Class {
#name : #GrafoscopioFormatTextNode,
#superclass : #PRText,
#category : #'Grafoscopio-Pillar-TextFormat'
}
{ #category : #visiting }
GrafoscopioFormatTextNode >> accept: aVisitor [
aVisitor visitFormatText: self
]
{ #category : #visiting }
GrafoscopioFormatTextNode >> printOn: aStream [
super printOn: aStream.
aStream nextPutAll: ' format text: '; print: self text
]
Class {
#name : #GrafoscopioFormatTextNode,
#superclass : #PRText,
#category : #'Grafoscopio-Pillar-TextFormat'
}
{ #category : #visiting }
GrafoscopioFormatTextNode >> accept: aVisitor [
aVisitor visitFormatText: self
]
{ #category : #visiting }
GrafoscopioFormatTextNode >> printOn: aStream [
super printOn: aStream.
aStream nextPutAll: ' format text: '; print: self text
]

View File

@ -1,65 +1,65 @@
"
Leaf node. Any content node is leaf
"
Class {
#name : #GrafoscopioLeafNode,
#superclass : #GrafoscopioAbstractNode,
#instVars : [
'parent'
],
#category : #'Grafoscopio-Model'
}
{ #category : #testing }
GrafoscopioLeafNode class >> isLeaf [
^ true
]
{ #category : #accessing }
GrafoscopioLeafNode >> acceptVisitor: aGrafoscopioVisitor [
aGrafoscopioVisitor visitLeafNode: self.
]
{ #category : #accessing }
GrafoscopioLeafNode >> addAtBeginningChild: aBlock ofClass: aClass [
self error: 'Leaf nodes are abstract. '
]
{ #category : #accessing }
GrafoscopioLeafNode >> addChild: aBlock ofClass: aClass [
self error: 'Leaf nodes are abstract. '
]
{ #category : #accessing }
GrafoscopioLeafNode >> level [
"Returns the level of the node. See the setter message for details"
^ parent ifNil: [ 0 ] ifNotNil: [ 1 + parent level ]
]
{ #category : #'as yet unclassified' }
GrafoscopioLeafNode >> moveDown [
parent moveDown: self.
]
{ #category : #'as yet unclassified' }
GrafoscopioLeafNode >> moveUp [
parent moveUp: self.
]
{ #category : #accessing }
GrafoscopioLeafNode >> parent [
"Returns the parent of the current node"
^ parent
]
{ #category : #accessing }
GrafoscopioLeafNode >> parent: aNode [
parent := aNode
]
{ #category : #'as yet unclassified' }
GrafoscopioLeafNode >> remove [
parent remove: self.
]
"
Leaf node. Any content node is leaf
"
Class {
#name : #GrafoscopioLeafNode,
#superclass : #GrafoscopioAbstractNode,
#instVars : [
'parent'
],
#category : #'Grafoscopio-Model'
}
{ #category : #testing }
GrafoscopioLeafNode class >> isLeaf [
^ true
]
{ #category : #accessing }
GrafoscopioLeafNode >> acceptVisitor: aGrafoscopioVisitor [
aGrafoscopioVisitor visitLeafNode: self.
]
{ #category : #accessing }
GrafoscopioLeafNode >> addAtBeginningChild: aBlock ofClass: aClass [
self error: 'Leaf nodes are abstract. '
]
{ #category : #accessing }
GrafoscopioLeafNode >> addChild: aBlock ofClass: aClass [
self error: 'Leaf nodes are abstract. '
]
{ #category : #accessing }
GrafoscopioLeafNode >> level [
"Returns the level of the node. See the setter message for details"
^ parent ifNil: [ 0 ] ifNotNil: [ 1 + parent level ]
]
{ #category : #'as yet unclassified' }
GrafoscopioLeafNode >> moveDown [
parent moveDown: self.
]
{ #category : #'as yet unclassified' }
GrafoscopioLeafNode >> moveUp [
parent moveUp: self.
]
{ #category : #accessing }
GrafoscopioLeafNode >> parent [
"Returns the parent of the current node"
^ parent
]
{ #category : #accessing }
GrafoscopioLeafNode >> parent: aNode [
parent := aNode
]
{ #category : #'as yet unclassified' }
GrafoscopioLeafNode >> remove [
parent remove: self.
]

View File

@ -1,51 +1,51 @@
"
I model the links of a GrafoscopioNode.
I'm responsable for showing the links and selecting them.
"
Class {
#name : #GrafoscopioLinksList,
#superclass : #ComposablePresenter,
#instVars : [
'links'
],
#category : #'Grafoscopio-UI'
}
{ #category : #specs }
GrafoscopioLinksList class >> defaultSpec [
^ SpLayout composed
add: #links;
yourself
]
{ #category : #accessing }
GrafoscopioLinksList >> content: aGrafoscopioNode [
links items: aGrafoscopioNode links
]
{ #category : #initialization }
GrafoscopioLinksList >> initializeWidgets [
links := self newList.
self focusOrder add: links
]
{ #category : #accessing }
GrafoscopioLinksList >> links [
^ links
]
{ #category : #accessing }
GrafoscopioLinksList >> links: anObject [
links := anObject
]
{ #category : #api }
GrafoscopioLinksList >> title [
^ 'Node links list'
]
{ #category : #'api-events' }
GrafoscopioLinksList >> whenSelectedItemChanged: aBlock [
links whenSelectedItemChanged: aBlock
]
"
I model the links of a GrafoscopioNode.
I'm responsable for showing the links and selecting them.
"
Class {
#name : #GrafoscopioLinksList,
#superclass : #ComposablePresenter,
#instVars : [
'links'
],
#category : #'Grafoscopio-UI'
}
{ #category : #specs }
GrafoscopioLinksList class >> defaultSpec [
^ SpLayout composed
add: #links;
yourself
]
{ #category : #accessing }
GrafoscopioLinksList >> content: aGrafoscopioNode [
links items: aGrafoscopioNode links
]
{ #category : #initialization }
GrafoscopioLinksList >> initializeWidgets [
links := self newList.
self focusOrder add: links
]
{ #category : #accessing }
GrafoscopioLinksList >> links [
^ links
]
{ #category : #accessing }
GrafoscopioLinksList >> links: anObject [
links := anObject
]
{ #category : #api }
GrafoscopioLinksList >> title [
^ 'Node links list'
]
{ #category : #'api-events' }
GrafoscopioLinksList >> whenSelectedItemChanged: aBlock [
links whenSelectedItemChanged: aBlock
]

View File

@ -1,105 +0,0 @@
Class {
#name : #GrafoscopioNewCodeModel,
#superclass : #GrafoscopioNewTextModel,
#instVars : [
'preview',
'previewButton'
],
#category : #'Grafoscopio-New-UI'
}
{ #category : #specs }
GrafoscopioNewCodeModel class >> defaultSpec [
^ SpBoxLayout newVertical
add: #body;
yourself
]
{ #category : #initialization }
GrafoscopioNewCodeModel >> content: aGrafoscopioNodeContent [
self layout: (self createLayoutFor: aGrafoscopioNodeContent).
body text: (aGrafoscopioNodeContent ifNil: [ '' ])
]
{ #category : #initialization }
GrafoscopioNewCodeModel >> createLayoutFor: aGrafoscopioNodeContent [
^ SpBoxLayout newVertical
add:
(SpBoxLayout newHorizontal
add:
(SpBoxLayout newVertical
add: #up;
add: #down;
add: #delete;
yourself)
width: 30;
add:
(SpBoxLayout newHorizontal
add: #body;
add: #previewButton width: 30;
add: #preview;
yourself);
yourself)
height: (self heightFor: aGrafoscopioNodeContent)
]
{ #category : #initialization }
GrafoscopioNewCodeModel >> editionLayoutFor: aGrafoscopioNodeContent [
^ SpBoxLayout newVertical
add:
(SpBoxLayout newHorizontal
add:
(SpBoxLayout newVertical
add: #up;
add: #down;
add: #delete;
yourself)
width: 30;
add:
(SpBoxLayout newHorizontal
add: #body;
add: #previewButton width: 30;
add: #preview;
yourself);
yourself)
height: (self heightFor: aGrafoscopioNodeContent)
]
{ #category : #initialization }
GrafoscopioNewCodeModel >> initializeWidgets [
super initializeWidgets.
previewButton := self newButton.
previewButton icon: (self iconNamed: #smallFind).
previewButton action: [ self previewCode ].
preview := self newLabel
]
{ #category : #initialization }
GrafoscopioNewCodeModel >> newTextComponent [
^ self newCode
whenTextChangedDo: [ model text: body text ];
autoAccept: true;
yourself
]
{ #category : #initialization }
GrafoscopioNewCodeModel >> normalLayoutFor: aGrafoscopioNodeContent [
^ SpBoxLayout newVertical
add:
(SpBoxLayout newHorizontal
add:
(SpBoxLayout newHorizontal
add: #body;
add: #previewButton width: 30;
add: #preview;
yourself);
yourself)
height: (self heightFor: aGrafoscopioNodeContent)
]
{ #category : #initialization }
GrafoscopioNewCodeModel >> previewCode [
[ preview label: (self class compiler evaluate: body text) asString ]
on: Error
do: [ :e | preview label: e asString]
]

View File

@ -1,83 +0,0 @@
Class {
#name : #GrafoscopioNewTextInputModel,
#superclass : #SpDynamicPresenter,
#instVars : [
'#body',
'#model => SpObservableSlot',
'#onModifyNodeLocationDo'
],
#category : #'Grafoscopio-New-UI'
}
{ #category : #specs }
GrafoscopioNewTextInputModel class >> defaultSpec [
^ SpBoxLayout newVertical
add: #body height: 300;
yourself
]
{ #category : #API }
GrafoscopioNewTextInputModel >> content: aGrafoscopioNodeContent [
self layout: (self createLayoutFor: aGrafoscopioNodeContent).
body text: (aGrafoscopioNodeContent ifNil: [ '' ])
]
{ #category : #API }
GrafoscopioNewTextInputModel >> createLayoutFor: aGrafoscopioNodeContent [
^ SpBoxLayout newVertical
add: #body
height: (self heightFor: aGrafoscopioNodeContent)
]
{ #category : #'as yet unclassified' }
GrafoscopioNewTextInputModel >> heightFor: aGrafoscopioNodeContent [
^ aGrafoscopioNodeContent
ifNil: [ 100 ]
ifNotNil: [ (aGrafoscopioNodeContent asString lines size * self class toolbarHeight) max: 100 ]
]
{ #category : #initialization }
GrafoscopioNewTextInputModel >> informModification [
onModifyNodeLocationDo
ifNotNil: [ onModifyNodeLocationDo cull: self ]
]
{ #category : #initialization }
GrafoscopioNewTextInputModel >> initialize [
super initialize.
]
{ #category : #initialization }
GrafoscopioNewTextInputModel >> initializePrivateAnnouncements [
super initializePrivateAnnouncements.
self property: #model whenChangedDo: [ self modelChanged ]
]
{ #category : #initialization }
GrafoscopioNewTextInputModel >> initializeWidgets [
body := self newTextComponent.
]
{ #category : #initialization }
GrafoscopioNewTextInputModel >> model: aModel [
model := aModel
]
{ #category : #initialization }
GrafoscopioNewTextInputModel >> modelChanged [
self content: model text.
]
{ #category : #initialization }
GrafoscopioNewTextInputModel >> newTextComponent [
^ self newTextInput whenTextChangedDo: [
model text: body text.
self informModification ];
yourself
]
{ #category : #initialization }
GrafoscopioNewTextInputModel >> onModifyNodeLocationDo: aBlock [
onModifyNodeLocationDo := aBlock
]

View File

@ -1,78 +1,77 @@
Class {
#name : #GrafoscopioNewTextModel,
#superclass : #GrafoscopioNewTextInputModel,
#instVars : [
'up',
'down',
'delete',
'editionMode',
'lastHeightUsed'
],
#category : #'Grafoscopio-New-UI'
}
{ #category : #initialization }
GrafoscopioNewTextModel >> createLayoutFor: aGrafoscopioNodeContent [
lastHeightUsed := (self heightFor: aGrafoscopioNodeContent).
^ editionMode
ifTrue: [ self editionLayoutFor: aGrafoscopioNodeContent ]
ifFalse: [ self normalLayoutFor: aGrafoscopioNodeContent ]
]
{ #category : #initialization }
GrafoscopioNewTextModel >> editionLayoutFor: aGrafoscopioNodeContent [
^ SpBoxLayout newVertical
add:
(SpBoxLayout newHorizontal
add:
(SpBoxLayout newVertical
add: #up;
add: #down;
add: #delete;
yourself)
width: 30;
add: #body;
yourself)
height: (self heightFor: aGrafoscopioNodeContent)
]
{ #category : #initialization }
GrafoscopioNewTextModel >> initializeWidgets [
super initializeWidgets .
editionMode := true.
up := self newButton icon: (self iconNamed: #up) ; color: Color transparent ; yourself .
down := self newButton icon: (self iconNamed: #down) ; color: Color transparent ; yourself .
delete := self newButton icon: (self iconNamed: #delete) ; color: Color transparent ; yourself .
up action: [ model moveUp. self informModification. ].
down action: [ model moveDown. self informModification.].
delete action: [ model remove .self informModification. ]
]
{ #category : #initialization }
GrafoscopioNewTextModel >> newTextComponent [
^ self newText
whenTextChangedDo: [ self textChanged ];
autoAccept: true;
yourself
]
{ #category : #initialization }
GrafoscopioNewTextModel >> normalLayoutFor: aGrafoscopioNodeContent [
^ SpBoxLayout newVertical
add: #body
height: (self heightFor: aGrafoscopioNodeContent)
]
{ #category : #initialization }
GrafoscopioNewTextModel >> textChanged [
model text: body text.
(lastHeightUsed - (self heightFor: model text )) abs
> (lastHeightUsed * 0.1)
ifTrue: [ self modelChanged ]
]
{ #category : #initialization }
GrafoscopioNewTextModel >> toogleEditionMode [
editionMode := editionMode not.
]
Class {
#name : #GrafoscopioNewTextModel,
#superclass : #SpPresenterWithModel,
#instVars : [
'body',
'onModifyNodeLocationDo'
],
#category : #'Grafoscopio-New-UI'
}
{ #category : #specs }
GrafoscopioNewTextModel class >> defaultSpec [
^ SpBoxLayout newVertical
add: #body;
yourself
]
{ #category : #'as yet unclassified' }
GrafoscopioNewTextModel >> body [
^ body
]
{ #category : #initialization }
GrafoscopioNewTextModel >> contextMenuFromCommandsGroup: aBlock [
^ body contextMenuFromCommandsGroup: aBlock
]
{ #category : #initialization }
GrafoscopioNewTextModel >> informModification [
onModifyNodeLocationDo
ifNotNil: [ onModifyNodeLocationDo cull: self ]
]
{ #category : #initialization }
GrafoscopioNewTextModel >> initialize [
super initialize.
]
{ #category : #initialization }
GrafoscopioNewTextModel >> initializeWidgets [
body := self newText.
body text: self model text.
body whenTextChangedDo: [ self informModification ]
]
{ #category : #initialization }
GrafoscopioNewTextModel >> inspectNRun [
body text
inspectRunAt:
(body selectionInterval
ifNil: [ body cursorPositionIndex ]
ifNotNil: [ :i | i first ])
]
{ #category : #initialization }
GrafoscopioNewTextModel >> inspectNode [
body text
inspectNodeAt:
(body selectionInterval
ifNil: [ body cursorPositionIndex ]
ifNotNil: [ :i | i first ])
]
{ #category : #'as yet unclassified' }
GrafoscopioNewTextModel >> inspectRuns [
^ self inspectNRun
]
{ #category : #initialization }
GrafoscopioNewTextModel >> modelChanged [
body text: self model text.
]
{ #category : #initialization }
GrafoscopioNewTextModel >> onModifyNodeLocationDo: aBlock [
onModifyNodeLocationDo := aBlock
]

File diff suppressed because it is too large Load Diff

View File

@ -1,171 +1,171 @@
"
I test the main functionality of the GrafoscopioNode class.
"
Class {
#name : #GrafoscopioNodeTest,
#superclass : #TestCase,
#category : #'Grafoscopio-Model'
}
{ #category : #tests }
GrafoscopioNodeTest >> dummyHtml [
| txt |
txt := '<html> <body> <img src="/web/files/pharo-logo-small.png">
<img src="https://pharo.org/web/files/pharo.png">
</body></html>'.
^ txt
]
{ #category : #tests }
GrafoscopioNodeTest >> newTestTree [
| node0 node1 node2 node3 node4 |
node0 := GrafoscopioTextNode new
created: DateAndTime now;
header: 'Arbol principal'.
node1 := GrafoscopioTextNode new
created: DateAndTime now;
header: 'Markup';
body: 'I am <b>just a node with markup</b>';
tagAs: 'text';
links: 'temp.md'.
node2 := GrafoscopioTextNode new
created: DateAndTime now ;
header: '%output Code';
tagAs: 'código';
body: '(ConfigurationOfGrafoscopio>>#version14:) sourceCode'.
node3 := GrafoscopioTextNode new
created: DateAndTime now ;
header: '%invisible';
tagAs: 'text';
body: '<i>Just testing</i>'.
node1 addNode: node3.
node4 := GrafoscopioTextNode new
created: DateAndTime now ;
header: 'Something';
tagAs: 'text';
body: '<h1>else</h1>'.
node1 addNode: node4.
node1 addNode: node2.
node0 addNode: node1.
^ node0
]
{ #category : #tests }
GrafoscopioNodeTest >> testAddingChildren [
| tree nnode orig |
tree := self newTestTree.
nnode := GrafoscopioTextNode new.
orig := tree children size.
tree addNode: nnode.
self assert: tree children size equals: orig + 1.
]
{ #category : #tests }
GrafoscopioNodeTest >> testDemoteNode [
| tree child1 child2 |
tree := GrafoscopioTextNode new.
child1 := GrafoscopioTextNode new.
child2 := GrafoscopioTextNode new.
tree
addNode: child1;
addNode: child2.
child2 demote.
self assert: child2 level equals: child1 level + 1
]
{ #category : #tests }
GrafoscopioNodeTest >> testFindAndReplace [
| tree |
tree := GrafoscopioTextNode new.
tree body: 'I''m only a test node.'.
tree find: 'only' andReplaceWith: 'JUST'.
self assert: (tree body findString: 'JUST') > 0.
]
{ #category : #tests }
GrafoscopioNodeTest >> testHasMarkdownSubtreesToExport [
"Because becomeDefaultTestTree contains at least one non empty 'links' object that
points to a relative path in the file system, ending in '.md' or '.markdown' the
result of this test is true.
Please see look #becomeDefaultTestTree message to see the details that makes this test true."
| tree |
tree := self newTestTree.
self assert: tree selectMarkupSubtreesToExport isNotEmpty equals: true.
]
{ #category : #tests }
GrafoscopioNodeTest >> testInitializeIsOk [
self shouldnt: [ GrafoscopioTextNode new ] raise: Error
]
{ #category : #tests }
GrafoscopioNodeTest >> testPromoteNode [
| tree child1 child2 |
tree := GrafoscopioTextNode new.
child1 := GrafoscopioTextNode new.
child2 := GrafoscopioTextNode new.
tree addNode: child1.
child1 addNode: child2.
child2 promote.
self assert: child2 level equals: child1 level
]
{ #category : #'tests-utility' }
GrafoscopioNodeTest >> testRemoveLeadingLineNumbersSized [
| copiedCode testNode |
copiedCode := '
1var tree = d3.layout.tree()
2 .sort(null)
3 .size([size.height, size.width - maxLabelLength*options.fontSize])
4 .children(function(d)
5 {
6 return (!d.contents || d.contents.length === 0) ? null : d.contents;
7 });
8
9var nodes = tree.nodes(treeData);
10var links = tree.links(nodes);
11 '.
testNode := GrafoscopioTextNode new
body: copiedCode.
testNode removeLeadingLineNumbersSized: 3.
self assert: testNode body equals: '
var tree = d3.layout.tree()
.sort(null)
.size([size.height, size.width - maxLabelLength*options.fontSize])
.children(function(d)
{
return (!d.contents || d.contents.length === 0) ? null : d.contents;
});
var nodes = tree.nodes(treeData);
var links = tree.links(nodes);
'
]
{ #category : #tests }
GrafoscopioNodeTest >> testRemovingChildren [
| tree orig |
tree := self newTestTree..
orig := tree children size.
orig > 0 ifTrue: [ tree removeNode: (tree children at: 1) ].
self assert: tree children size equals: orig - 1.
]
{ #category : #tests }
GrafoscopioNodeTest >> testSanitizedLink [
| node link |
link := 'docutopia://hackbo:hackbot'.
node := GrafoscopioTextNode new links: link.
self assert: (node sanitizeDefaultLink = 'https://docutopia.tupale.co/hackbo:hackbot') equals: true
]
"
I test the main functionality of the GrafoscopioNode class.
"
Class {
#name : #GrafoscopioNodeTest,
#superclass : #TestCase,
#category : #'Grafoscopio-Model'
}
{ #category : #tests }
GrafoscopioNodeTest >> dummyHtml [
| txt |
txt := '<html> <body> <img src="/web/files/pharo-logo-small.png">
<img src="https://pharo.org/web/files/pharo.png">
</body></html>'.
^ txt
]
{ #category : #tests }
GrafoscopioNodeTest >> newTestTree [
| node0 node1 node2 node3 node4 |
node0 := GrafoscopioTextNode new
created: DateAndTime now;
header: 'Arbol principal'.
node1 := GrafoscopioTextNode new
created: DateAndTime now;
header: 'Markup';
body: 'I am <b>just a node with markup</b>';
tagAs: 'text';
links: 'temp.md'.
node2 := GrafoscopioTextNode new
created: DateAndTime now ;
header: '%output Code';
tagAs: 'código';
body: '(ConfigurationOfGrafoscopio>>#version14:) sourceCode'.
node3 := GrafoscopioTextNode new
created: DateAndTime now ;
header: '%invisible';
tagAs: 'text';
body: '<i>Just testing</i>'.
node1 addNode: node3.
node4 := GrafoscopioTextNode new
created: DateAndTime now ;
header: 'Something';
tagAs: 'text';
body: '<h1>else</h1>'.
node1 addNode: node4.
node1 addNode: node2.
node0 addNode: node1.
^ node0
]
{ #category : #tests }
GrafoscopioNodeTest >> testAddingChildren [
| tree nnode orig |
tree := self newTestTree.
nnode := GrafoscopioTextNode new.
orig := tree children size.
tree addNode: nnode.
self assert: tree children size equals: orig + 1.
]
{ #category : #tests }
GrafoscopioNodeTest >> testDemoteNode [
| tree child1 child2 |
tree := GrafoscopioTextNode new.
child1 := GrafoscopioTextNode new.
child2 := GrafoscopioTextNode new.
tree
addNode: child1;
addNode: child2.
child2 demote.
self assert: child2 level equals: child1 level + 1
]
{ #category : #tests }
GrafoscopioNodeTest >> testFindAndReplace [
| tree |
tree := GrafoscopioTextNode new.
tree body: 'I''m only a test node.'.
tree find: 'only' andReplaceWith: 'JUST'.
self assert: (tree body findString: 'JUST') > 0.
]
{ #category : #tests }
GrafoscopioNodeTest >> testHasMarkdownSubtreesToExport [
"Because becomeDefaultTestTree contains at least one non empty 'links' object that
points to a relative path in the file system, ending in '.md' or '.markdown' the
result of this test is true.
Please see look #becomeDefaultTestTree message to see the details that makes this test true."
| tree |
tree := self newTestTree.
self assert: tree selectMarkupSubtreesToExport isNotEmpty equals: true.
]
{ #category : #tests }
GrafoscopioNodeTest >> testInitializeIsOk [
self shouldnt: [ GrafoscopioTextNode new ] raise: Error
]
{ #category : #tests }
GrafoscopioNodeTest >> testPromoteNode [
| tree child1 child2 |
tree := GrafoscopioTextNode new.
child1 := GrafoscopioTextNode new.
child2 := GrafoscopioTextNode new.
tree addNode: child1.
child1 addNode: child2.
child2 promote.
self assert: child2 level equals: child1 level
]
{ #category : #'tests-utility' }
GrafoscopioNodeTest >> testRemoveLeadingLineNumbersSized [
| copiedCode testNode |
copiedCode := '
1var tree = d3.layout.tree()
2 .sort(null)
3 .size([size.height, size.width - maxLabelLength*options.fontSize])
4 .children(function(d)
5 {
6 return (!d.contents || d.contents.length === 0) ? null : d.contents;
7 });
8
9var nodes = tree.nodes(treeData);
10var links = tree.links(nodes);
11 '.
testNode := GrafoscopioTextNode new
body: copiedCode.
testNode removeLeadingLineNumbersSized: 3.
self assert: testNode body equals: '
var tree = d3.layout.tree()
.sort(null)
.size([size.height, size.width - maxLabelLength*options.fontSize])
.children(function(d)
{
return (!d.contents || d.contents.length === 0) ? null : d.contents;
});
var nodes = tree.nodes(treeData);
var links = tree.links(nodes);
'
]
{ #category : #tests }
GrafoscopioNodeTest >> testRemovingChildren [
| tree orig |
tree := self newTestTree..
orig := tree children size.
orig > 0 ifTrue: [ tree removeNode: (tree children at: 1) ].
self assert: tree children size equals: orig - 1.
]
{ #category : #tests }
GrafoscopioNodeTest >> testSanitizedLink [
| node link |
link := 'docutopia://hackbo:hackbot'.
node := GrafoscopioTextNode new links: link.
self assert: (node sanitizeDefaultLink = 'https://docutopia.tupale.co/hackbo:hackbot') equals: true
]

File diff suppressed because it is too large Load Diff

View File

@ -1,8 +1,8 @@
"
I test the main functionality of the GrafoscopioNode class.
"
Class {
#name : #GrafoscopioNotebookTest,
#superclass : #TestCase,
#category : #'Grafoscopio-UI'
}
"
I test the main functionality of the GrafoscopioNode class.
"
Class {
#name : #GrafoscopioNotebookTest,
#superclass : #TestCase,
#category : #'Grafoscopio-UI'
}

View File

@ -1,196 +1,207 @@
Class {
#name : #GrafoscopioPerspective,
#superclass : #SpPresenterWithModel,
#instVars : [
'toolbar',
'viewport'
],
#category : #'Grafoscopio-New-UI'
}
{ #category : #'as yet unclassified' }
GrafoscopioPerspective class >> defaultPerspective [
^ GrafoscopioDocumentEditionPerspective
]
{ #category : #'as yet unclassified' }
GrafoscopioPerspective class >> defaultSpec [
^ SpBoxLayout newVertical
add: #toolbar height: self toolbarHeight;
add: #viewport;
yourself
]
{ #category : #'as yet unclassified' }
GrafoscopioPerspective class >> isAbstract [
^ self = GrafoscopioPerspective
]
{ #category : #'as yet unclassified' }
GrafoscopioPerspective class >> perspectives [
^ self allSubclasses select: [ : c | c isAbstract not ]
]
{ #category : #initialization }
GrafoscopioPerspective >> aboutToBeUninstalledFrom: aTreeNotebook [
]
{ #category : #initialization }
GrafoscopioPerspective >> addItemTo: aGroup [
aGroup
addItem: [ :item |
item
name: 'Dynamic';
icon: (self iconNamed: #delete);
action: [ aGroup menuItems remove: item.
self needRebuild: false.
self buildWithSpec ] ].
self needRebuild: false.
self buildWithSpec
]
{ #category : #initialization }
GrafoscopioPerspective >> addingMenu [
| menu |
menu := self newMenu.
self kindsOfNode
do: [ :n |
menu
addItem: [ :item |
item
name: n nameForSelection;
icon: n icon;
action: [ self addNewNodeOfClass: n ] ] ].
^ menu
]
{ #category : #'as yet unclassified' }
GrafoscopioPerspective >> chooseKindsOfNode [
| idx values |
values := self kindsOfNode.
idx := UIManager default
chooseFrom: values
lines: {}
title: 'What kind of node? '.
^ idx = 0
ifTrue: [ nil ]
ifFalse: [ values at: idx ]
]
{ #category : #initialization }
GrafoscopioPerspective >> createToolbar [
| aMenu |
aMenu := self newMenuBar
addGroup: [ :group |
group
addItem: [ :item |
item
name: 'File';
icon: (self iconNamed: #openIcon);
subMenu: self subMenu ].
group
addItem: [ :item |
item
name: nil;
description: 'Open file';
icon: (self iconNamed: #openIcon);
action: [ self inform: 'Open File' ] ].
group
addItem: [ :item |
item
name: nil;
description: 'Save File';
icon: (self iconNamed: #smallSaveIcon);
action: [ self inform: 'Save File' ] ].
group
addItem: [ :item |
item
name: nil;
description: 'Print file';
icon: (self iconNamed: #smallPrintIcon);
action: [ self inform: 'Print file' ] ] ];
addGroup: [ :group |
group
addItem: [ :item |
item
name: nil;
description: 'Undo';
icon: (self iconNamed: #smallUndoIcon);
action: [ self inform: 'Undo' ] ].
group
addItem: [ :item |
item
name: nil;
description: 'Redo';
icon: (self iconNamed: #smallRedoIcon);
action: [ self inform: 'Redo' ] ].
group
addItem: [ :item |
item
name: '';
icon: (self iconNamed: #add);
subMenu: self addingMenu ].
];
addGroup: [ :group |
group
addItem: [ :item |
item
name: nil;
description: 'Add menu item';
icon: (self iconNamed: #add);
action: [ self addItemTo: group ] ] ].
aMenu color: Color transparent.
^ aMenu
]
{ #category : #initialization }
GrafoscopioPerspective >> createViewport [
self subclassResponsibility
]
{ #category : #initialization }
GrafoscopioPerspective >> initializeWidgets [
super initializeWidgets.
toolbar := self createToolbar.
viewport := self createViewport
]
{ #category : #'as yet unclassified' }
GrafoscopioPerspective >> kindsOfNode [
^ GrafoscopioAbstractNode allSubclasses select: [ :c | c showInMenu ]
]
{ #category : #initialization }
GrafoscopioPerspective >> subMenu [
^ self newMenu
addItem: [ :item |
item
name: 'Open';
icon: (self iconNamed: #openIcon);
shortcut: $o meta;
action: [ self inform: 'Open' ] ];
addItem: [ :item |
item
name: 'Save';
icon: (self iconNamed: #smallSaveIcon);
shortcut: $s meta;
action: [ self inform: 'Save' ] ];
addItem: [ :item |
item
name: 'Print';
shortcut: $p meta;
icon: (self iconNamed: #smallPrintIcon);
action: [ self inform: 'Print' ] ];
addItem: [ :item |
item
name: 'Close';
shortcut: $c meta;
icon: (self iconNamed: #smallCancelIcon);
action: [ self inform: 'Kill' ] ];
yourself
]
{ #category : #'as yet unclassified' }
GrafoscopioPerspective >> updateModel: aModel [
]
Class {
#name : #GrafoscopioPerspective,
#superclass : #SpPresenterWithModel,
#instVars : [
'toolbar',
'viewport'
],
#category : #'Grafoscopio-New-UI'
}
{ #category : #'as yet unclassified' }
GrafoscopioPerspective class >> defaultPerspective [
^ GrafoscopioDocumentTextEditionPerspective
]
{ #category : #'as yet unclassified' }
GrafoscopioPerspective class >> defaultSpec [
^ SpBoxLayout newVertical
add: #toolbar height: self toolbarHeight;
add: #viewport;
yourself
]
{ #category : #'as yet unclassified' }
GrafoscopioPerspective class >> isAbstract [
^ self = GrafoscopioPerspective
]
{ #category : #'as yet unclassified' }
GrafoscopioPerspective class >> perspectives [
^ self allSubclasses select: [ : c | c isAbstract not ]
]
{ #category : #initialization }
GrafoscopioPerspective >> aboutToBeInstalled: aTreeNotebook [
]
{ #category : #initialization }
GrafoscopioPerspective >> aboutToBeUninstalledFrom: aTreeNotebook [
]
{ #category : #initialization }
GrafoscopioPerspective >> addItemTo: aGroup [
aGroup
addItem: [ :item |
item
name: 'Dynamic';
icon: (self iconNamed: #delete);
action: [ aGroup menuItems remove: item.
self needRebuild: false.
self buildWithSpec ] ].
self needRebuild: false.
self buildWithSpec
]
{ #category : #initialization }
GrafoscopioPerspective >> addingMenu [
| menu |
menu := self newMenu.
self kindsOfNode
do: [ :n |
menu
addItem: [ :item |
item
name: n nameForSelection;
icon: n icon;
action: [ self addNewNodeOfClass: n ] ] ].
^ menu
]
{ #category : #'as yet unclassified' }
GrafoscopioPerspective >> chooseKindsOfNode [
| idx values |
values := self kindsOfNode.
idx := UIManager default
chooseFrom: values
lines: {}
title: 'What kind of node? '.
^ idx = 0
ifTrue: [ nil ]
ifFalse: [ values at: idx ]
]
{ #category : #initialization }
GrafoscopioPerspective >> createToolbar [
| aMenu |
aMenu := self newMenuBar
addGroup: [ :group |
group
addItem: [ :item |
item
name: 'File';
icon: (self iconNamed: #openIcon);
subMenu: self subMenu ].
group
addItem: [ :item |
item
name: nil;
description: 'Open file';
icon: (self iconNamed: #openIcon);
action: [ self inform: 'Open File' ] ].
group
addItem: [ :item |
item
name: nil;
description: 'Save File';
icon: (self iconNamed: #smallSaveIcon);
action: [ self inform: 'Save File' ] ].
group
addItem: [ :item |
item
name: nil;
description: 'Print file';
icon: (self iconNamed: #smallPrintIcon);
action: [ self inform: 'Print file' ] ] ];
addGroup: [ :group |
group
addItem: [ :item |
item
name: nil;
description: 'Undo';
icon: (self iconNamed: #smallUndoIcon);
action: [ self inform: 'Undo' ] ].
group
addItem: [ :item |
item
name: nil;
description: 'Redo';
icon: (self iconNamed: #smallRedoIcon);
action: [ self inform: 'Redo' ] ].
group
addItem: [ :item |
item
name: '';
icon: (self iconNamed: #add);
subMenu: self addingMenu ].
];
addGroup: [ :group |
group
addItem: [ :item |
item
name: nil;
description: 'Add menu item';
icon: (self iconNamed: #add);
action: [ self addItemTo: group ] ] ].
aMenu color: Color transparent.
^ aMenu
]
{ #category : #initialization }
GrafoscopioPerspective >> createViewport [
self subclassResponsibility
]
{ #category : #initialization }
GrafoscopioPerspective >> initializeWidgets [
super initializeWidgets.
toolbar := self createToolbar.
viewport := self createViewport
]
{ #category : #'as yet unclassified' }
GrafoscopioPerspective >> kindsOfNode [
^ GrafoscopioAbstractNode allSubclasses select: [ :c | c showInMenu ]
]
{ #category : #initialization }
GrafoscopioPerspective >> subMenu [
^ self newMenu
addItem: [ :item |
item
name: 'Open';
icon: (self iconNamed: #openIcon);
shortcut: $o meta;
action: [ self inform: 'Open' ] ];
addItem: [ :item |
item
name: 'Save';
icon: (self iconNamed: #smallSaveIcon);
shortcut: $s meta;
action: [ self inform: 'Save' ] ];
addItem: [ :item |
item
name: 'Print';
shortcut: $p meta;
icon: (self iconNamed: #smallPrintIcon);
action: [ self inform: 'Print' ] ];
addItem: [ :item |
item
name: 'Close';
shortcut: $c meta;
icon: (self iconNamed: #smallCancelIcon);
action: [ self inform: 'Kill' ] ];
yourself
]
{ #category : #'as yet unclassified' }
GrafoscopioPerspective >> updateModel: aModel [
]
{ #category : #initialization }
GrafoscopioPerspective >> viewport: aViewport [
viewport := aViewport.
self buildWithSpec
]

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,80 @@
Class {
#name : #GrafoscopioPillarASTextNotebook,
#superclass : #SpPresenterWithModel,
#instVars : [
'sidebar',
'viewport',
'model',
'empty',
'perspectives'
],
#category : #'Grafoscopio-New-UI'
}
{ #category : #specs }
GrafoscopioPillarASTextNotebook class >> defaultSpec [
^ SpBoxLayout newHorizontal
add:
(SpBoxLayout newVertical
add: #empty height: self toolbarHeight;
add: #sidebar;
yourself)
width: 51;
add: #viewport;
yourself
]
{ #category : #'as yet unclassified' }
GrafoscopioPillarASTextNotebook >> basicInstallPerspective: aPerspective [
viewport ifNotNil: [ viewport aboutToBeUninstalledFrom: self ].
viewport := self perspectives
at: aPerspective
ifAbsentPut: [ self instantiate: aPerspective on: model document ].
]
{ #category : #initialization }
GrafoscopioPillarASTextNotebook >> createDefaultComponent [
^ self basicInstallPerspective: GrafoscopioPerspective defaultPerspective
]
{ #category : #initialization }
GrafoscopioPillarASTextNotebook >> initializeWidgets [
super initializeWidgets.
sidebar := self sidebar.
self createDefaultComponent.
empty := self newLabel.
]
{ #category : #initialization }
GrafoscopioPillarASTextNotebook >> installPerspective: aPerspective [
self basicInstallPerspective: aPerspective .
self modelChanged
]
{ #category : #initialization }
GrafoscopioPillarASTextNotebook >> modelChanged [
viewport modelChanged.
self needRebuild: false.
self buildWithSpec
]
{ #category : #initialization }
GrafoscopioPillarASTextNotebook >> perspectives [
^ perspectives ifNil: [ perspectives := Dictionary new ]
]
{ #category : #'as yet unclassified' }
GrafoscopioPillarASTextNotebook >> setModelBeforeInitialization: aDomainObject [
super setModelBeforeInitialization: aDomainObject.
model := aDomainObject
]
{ #category : #initialization }
GrafoscopioPillarASTextNotebook >> sidebar [
| bar |
bar := self instantiate: SpSidebar.
GrafoscopioPerspective perspectives
do:
[ :p | bar addAction: [ self installPerspective: p ] icon: p icon ].
^ bar
]

View File

@ -0,0 +1,205 @@
Class {
#name : #GrafoscopioPillarASTextStringAdapter,
#superclass : #ProtoObject,
#instVars : [
'text'
],
#category : #'Grafoscopio-Pillar'
}
{ #category : #'as yet unclassified' }
GrafoscopioPillarASTextStringAdapter >> allRangesOfSubstring: aSubstring [
^ Array streamContents: [:s | | start subSize |
start := 1.
subSize := aSubstring size.
[start isZero]
whileFalse: [ start := self findString: aSubstring startingAt: start.
start > 0
ifTrue: [s nextPut: (start to: start + subSize - 1).
start := start + subSize]]]
]
{ #category : #'as yet unclassified' }
GrafoscopioPillarASTextStringAdapter >> asString [
^ self
]
{ #category : #accessing }
GrafoscopioPillarASTextStringAdapter >> at: aNumber [
^ text at: aNumber
]
{ #category : #accessing }
GrafoscopioPillarASTextStringAdapter >> at: aNumber put: aChar [
self halt
]
{ #category : #'as yet unclassified' }
GrafoscopioPillarASTextStringAdapter >> copyFrom: one to: two [
^ text copyFrom: one to: two
]
{ #category : #'as yet unclassified' }
GrafoscopioPillarASTextStringAdapter >> findString: key startingAt: start [
^ self findString: key startingAt: start caseSensitive: true
]
{ #category : #'as yet unclassified' }
GrafoscopioPillarASTextStringAdapter >> findString: key startingAt: start caseSensitive: caseSensitive [
"Answer the index in this String at which the substring key first occurs,
at or beyond start. The match can be case-sensitive or not. If no match
is found, zero will be returned."
"IMPLEMENTATION NOTE: do not use CaseSensitiveOrder because it is broken for WideString
This is a temporary work around until Wide CaseSensitiveOrder search is fixed
Code should revert to:
caseSensitive
ifTrue: [^ self findSubstring: key in: self startingAt: start matchTable: CaseSensitiveOrder]
ifFalse: [^ self findSubstring: key in: self startingAt: start matchTable: CaseInsensitiveOrder]"
^ caseSensitive
ifTrue: [ WideString new
findSubstring: key
in: self
startingAt: start
matchTable: nil ]
ifFalse: [ WideString new
findSubstring: key
in: self
startingAt: start
matchTable: String newCaseInsensitiveOrder ]
]
{ #category : #'as yet unclassified' }
GrafoscopioPillarASTextStringAdapter >> ifEmpty: aBlock [
"Evaluate the given block, answering its value if the receiver is empty, otherwise answer the receiver."
"Note that the fact that this method returns its receiver in case the receiver is not empty allows one to write expressions like the following ones: self classifyMethodAs: (myProtocol ifEmpty: ['As yet unclassified'])"
^ self isEmpty
ifTrue: [ aBlock value ]
ifFalse: [ self ]
]
{ #category : #'as yet unclassified' }
GrafoscopioPillarASTextStringAdapter >> ifEmpty: emptyBlock ifNotEmpty: notEmptyBlock [
"Evaluate emptyBlock if I'm empty, notEmptyBlock otherwise"
"If the notEmptyBlock has an argument, eval with the receiver as its argument"
^ self isEmpty
ifTrue: [ emptyBlock value ]
ifFalse: [ notEmptyBlock cull: self ]
]
{ #category : #'as yet unclassified' }
GrafoscopioPillarASTextStringAdapter >> indexOf: aCharacter startingAt: anInteger ifAbsent: aBlockClosure [
| current index |
current := text detectAstNodeFor: anInteger.
index := current text
indexOf: aCharacter
startingAt: anInteger - current textStart + 1.
current := current next.
[ current isNotNil ]
whileTrue: [ index := current text indexOf: aCharacter.
index = 0
ifTrue: [ current := current next ]
ifFalse: [ ^ current textStart + index ] ].
^ aBlockClosure value
]
{ #category : #'as yet unclassified' }
GrafoscopioPillarASTextStringAdapter >> isByteString [
^ false
]
{ #category : #'as yet unclassified' }
GrafoscopioPillarASTextStringAdapter >> isEmpty [
^ text isEmpty
]
{ #category : #accessing }
GrafoscopioPillarASTextStringAdapter >> isReadOnlyObject [
"Answer if the receiver is read-only.
If the VM supports read-only objects it will not write to read-only objects.
An attempt to write to an instance variable of a read-only object will
cause the VM to send attemptToAssign:withIndex: to the read-only object.
An attempt to modify a read-only object in a primitive will cause the
primitive to fail with a #'no modification' error code."
<primitive: 163 error: ec>
^self class isImmediateClass
]
{ #category : #'as yet unclassified' }
GrafoscopioPillarASTextStringAdapter >> isString [
^ true
]
{ #category : #'as yet unclassified' }
GrafoscopioPillarASTextStringAdapter >> isWideString [
^ true
]
{ #category : #'as yet unclassified' }
GrafoscopioPillarASTextStringAdapter >> lastIndexOf: anElement startingAt: lastIndex ifAbsent: exceptionBlock [
"Answer the index of the last occurence of anElement within the
receiver. If the receiver does not contain anElement, answer the
result of evaluating the argument, exceptionBlock."
lastIndex to: 1 by: -1 do: [ :index |
(self at: index) = anElement
ifTrue: [ ^ index ] ].
^ exceptionBlock value
]
{ #category : #accessing }
GrafoscopioPillarASTextStringAdapter >> notEmpty [
^ text notEmpty
]
{ #category : #'as yet unclassified' }
GrafoscopioPillarASTextStringAdapter >> printOn: aStream [
aStream
nextPutAll: 'StringAdaptor(';
nextPutAll: self size asString;
nextPutAll: ')'
]
{ #category : #'as yet unclassified' }
GrafoscopioPillarASTextStringAdapter >> printString [
^ String streamContents: [ :str | self printOn: str ]
]
{ #category : #'as yet unclassified' }
GrafoscopioPillarASTextStringAdapter >> readStream [
^ ReadStream on: self
]
{ #category : #accessing }
GrafoscopioPillarASTextStringAdapter >> size [
^ text size
]
{ #category : #'as yet unclassified' }
GrafoscopioPillarASTextStringAdapter >> string [
^ text extractStringFrom: 1 to: self size
]
{ #category : #accessing }
GrafoscopioPillarASTextStringAdapter >> text: aGFPText [
text := aGFPText
]
{ #category : #'as yet unclassified' }
GrafoscopioPillarASTextStringAdapter >> trimBoth [
^ self
]
{ #category : #'as yet unclassified' }
GrafoscopioPillarASTextStringAdapter >> yourself [
^ self
]
{ #category : #'as yet unclassified' }
GrafoscopioPillarASTextStringAdapter >> ~= anOther [
^ (self == anOther) not
]

View File

@ -1,74 +0,0 @@
Class {
#name : #GrafoscopioPillarASTextStringDecorator,
#superclass : #Object,
#instVars : [
'text'
],
#category : #'Grafoscopio-Pillar'
}
{ #category : #accessing }
GrafoscopioPillarASTextStringDecorator >> at: aNumber [
^ text at: aNumber
]
{ #category : #accessing }
GrafoscopioPillarASTextStringDecorator >> at: aNumber put: aChar [
self halt
]
{ #category : #'as yet unclassified' }
GrafoscopioPillarASTextStringDecorator >> copyFrom: one to: two [
^ text copyFrom: one to: two
]
{ #category : #'as yet unclassified' }
GrafoscopioPillarASTextStringDecorator >> indexOf: aCharacter startingAt: anInteger ifAbsent: aBlockClosure [
| current index |
current := text detectAstNodeFor: anInteger.
index := current text
indexOf: aCharacter
startingAt: anInteger - current textStart + 1.
current := current next.
[ current isNotNil ]
whileTrue: [ index := current text indexOf: aCharacter.
index = 0
ifTrue: [ current := current next ]
ifFalse: [ ^ current textStart + index ] ].
^ aBlockClosure value
]
{ #category : #'as yet unclassified' }
GrafoscopioPillarASTextStringDecorator >> isByteString [
^ false
]
{ #category : #'as yet unclassified' }
GrafoscopioPillarASTextStringDecorator >> isEmpty [
^ text isEmpty
]
{ #category : #'as yet unclassified' }
GrafoscopioPillarASTextStringDecorator >> isWideString [
^ true
]
{ #category : #accessing }
GrafoscopioPillarASTextStringDecorator >> notEmpty [
^ text notEmpty
]
{ #category : #accessing }
GrafoscopioPillarASTextStringDecorator >> size [
^ text size
]
{ #category : #'as yet unclassified' }
GrafoscopioPillarASTextStringDecorator >> string [
self shouldBeImplemented.
]
{ #category : #accessing }
GrafoscopioPillarASTextStringDecorator >> text: aGFPText [
text := aGFPText
]

View File

@ -0,0 +1,69 @@
Class {
#name : #GrafoscopioPillarASTextStringProjectionAdapter,
#superclass : #GrafoscopioPillarASTextStringAdapter,
#instVars : [
'from',
'to',
'cached'
],
#category : #'Grafoscopio-Pillar'
}
{ #category : #'as yet unclassified' }
GrafoscopioPillarASTextStringProjectionAdapter >> asText [
^ self string asText
]
{ #category : #accessing }
GrafoscopioPillarASTextStringProjectionAdapter >> at: anInteger [
^ self cached at: anInteger
]
{ #category : #accessing }
GrafoscopioPillarASTextStringProjectionAdapter >> cached [
^ cached ifNil: [ cached := text extractStringFrom: from to: to ]
]
{ #category : #'as yet unclassified' }
GrafoscopioPillarASTextStringProjectionAdapter >> copyFrom: one to: two [
^ self class new
text: text;
from: from + one;
to: from + two;
yourself
]
{ #category : #'as yet unclassified' }
GrafoscopioPillarASTextStringProjectionAdapter >> from: anInteger [
from := anInteger
]
{ #category : #'as yet unclassified' }
GrafoscopioPillarASTextStringProjectionAdapter >> isEmpty [
^ to <= from
]
{ #category : #'as yet unclassified' }
GrafoscopioPillarASTextStringProjectionAdapter >> printOn: aStream [
aStream
nextPutAll: 'SubStringAdapter(';
nextPutAll: from asString;
nextPutAll: ':';
nextPutAll: to asString;
nextPutAll: ')'
]
{ #category : #accessing }
GrafoscopioPillarASTextStringProjectionAdapter >> size [
^ to - from
]
{ #category : #'as yet unclassified' }
GrafoscopioPillarASTextStringProjectionAdapter >> string [
^ text extractStringFrom: from to: to
]
{ #category : #'as yet unclassified' }
GrafoscopioPillarASTextStringProjectionAdapter >> to: anInteger [
to := anInteger
]

View File

@ -1,64 +0,0 @@
Class {
#name : #GrafoscopioPillarASTextStringProjectionDecorator,
#superclass : #GrafoscopioPillarASTextStringDecorator,
#instVars : [
'from',
'to',
'cached'
],
#category : #'Grafoscopio-Pillar'
}
{ #category : #'as yet unclassified' }
GrafoscopioPillarASTextStringProjectionDecorator >> allRangesOfSubstring: aString [
^ { }
]
{ #category : #'as yet unclassified' }
GrafoscopioPillarASTextStringProjectionDecorator >> asText [
^ self string asText
]
{ #category : #accessing }
GrafoscopioPillarASTextStringProjectionDecorator >> at: anInteger [
^ self cached at: anInteger
]
{ #category : #accessing }
GrafoscopioPillarASTextStringProjectionDecorator >> cached [
^ cached ifNil: [ cached := text extractStringFrom: from to: to ]
]
{ #category : #'as yet unclassified' }
GrafoscopioPillarASTextStringProjectionDecorator >> copyFrom: one to: two [
^ self class new
text: text;
from: from + one;
to: from + two;
yourself
]
{ #category : #'as yet unclassified' }
GrafoscopioPillarASTextStringProjectionDecorator >> from: anInteger [
from := anInteger
]
{ #category : #'as yet unclassified' }
GrafoscopioPillarASTextStringProjectionDecorator >> isEmpty [
^ from <= to
]
{ #category : #accessing }
GrafoscopioPillarASTextStringProjectionDecorator >> size [
^ to - from
]
{ #category : #'as yet unclassified' }
GrafoscopioPillarASTextStringProjectionDecorator >> string [
^ text extractStringFrom: from to: to
]
{ #category : #'as yet unclassified' }
GrafoscopioPillarASTextStringProjectionDecorator >> to: anInteger [
to := anInteger
]

View File

@ -0,0 +1,40 @@
Class {
#name : #GrafoscopioPillarNode,
#superclass : #GrafoscopioLeafNode,
#instVars : [
'ast',
'astText'
],
#category : #'Grafoscopio-Model'
}
{ #category : #testing }
GrafoscopioPillarNode class >> icon [
^ self iconNamed: #workspace
]
{ #category : #testing }
GrafoscopioPillarNode class >> nameForSelection [
^ 'New Pillar node'
]
{ #category : #testing }
GrafoscopioPillarNode class >> showInMenu [
^ true
]
{ #category : #accessing }
GrafoscopioPillarNode >> acceptVisitor: aGrafoscopioVisitor [
aGrafoscopioVisitor visitPillarNode: self.
]
{ #category : #accessing }
GrafoscopioPillarNode >> text [
^ astText
]
{ #category : #accessing }
GrafoscopioPillarNode >> text: anAst [
astText := anAst
]

View File

@ -1,80 +1,74 @@
Class {
#name : #GrafoscopioPillarRuns,
#superclass : #Object,
#instVars : [
'ast',
'lastBranch',
'lastAttributes',
'visitor'
],
#category : #'Grafoscopio-Pillar-Style'
}
{ #category : #accessing }
GrafoscopioPillarRuns >> ast: anAst [
ast := anAst.
visitor := GrafoscopioAttributeBranchVisitor new.
visitor text: ast
]
{ #category : #'basic api' }
GrafoscopioPillarRuns >> at: anIndex [
| newBranch |
anIndex > ast size
ifTrue: [ ^ Array empty ].
newBranch := ast detectFullBranchFor: anIndex.
newBranch = lastBranch
ifTrue: [ ^ lastAttributes ].
lastAttributes := self
calculateAttributesForBranch: newBranch
at: anIndex.
lastBranch := (newBranch
anySatisfy: [ :n | n isMemberOf: PRCodeblock ])
ifTrue: [ nil ]
ifFalse: [ newBranch ].
^ lastAttributes
]
{ #category : #'as yet unclassified' }
GrafoscopioPillarRuns >> calculateAttributesForBranch: aCollection at: anIndex [
^ visitor analyzeBranch: aCollection at: anIndex.
]
{ #category : #'basic api' }
GrafoscopioPillarRuns >> isEmpty [
^ ast isNil or: [ ast isEmpty ]
]
{ #category : #'as yet unclassified' }
GrafoscopioPillarRuns >> rangeOf: aTextURL startingAt: anInteger [
self assert: (aTextURL isKindOf: TextAction).
((self at: anInteger) contains: [ : a | (a isKindOf: TextAction)]) ifTrue: [
(ast extractStringFrom: anInteger to: (ast detectAstNodeFor: anInteger ) textStop) traceCr.
^ anInteger to: (ast detectAstNodeFor: anInteger ) textStop
].
^ 0 to: 0
]
{ #category : #'basic api' }
GrafoscopioPillarRuns >> reset [
lastAttributes := nil.
lastBranch := nil.
]
{ #category : #'as yet unclassified' }
GrafoscopioPillarRuns >> runLengthFor: anInteger [
| node |
anInteger > ast size
ifTrue: [ ^ 0 ].
node := ast detectAstNodeFor: anInteger.
^ (node isKindOf: PRCodeblock)
ifTrue: [ 1 ]
ifFalse: [ node textStop - anInteger ]
]
{ #category : #'as yet unclassified' }
GrafoscopioPillarRuns >> withStartStopAndValueDo: aBlockClosure [
thisContext sender asString traceCr.
'Should implement' traceCr.
]
Class {
#name : #GrafoscopioPillarRuns,
#superclass : #Object,
#instVars : [
'ast',
'lastBranch',
'lastAttributes',
'visitor'
],
#category : #'Grafoscopio-Pillar-Style'
}
{ #category : #accessing }
GrafoscopioPillarRuns >> ast: anAst [
ast := anAst.
visitor := GrafoscopioAttributeBranchVisitor new.
visitor text: ast
]
{ #category : #'basic api' }
GrafoscopioPillarRuns >> at: anIndex [
| newBranch |
anIndex > ast size
ifTrue: [ ^ Array empty ].
newBranch := ast detectFullBranchFor: anIndex.
"newBranch = lastBranch
ifTrue: [ ^ lastAttributes ]."
lastAttributes := self
calculateAttributesForBranch: newBranch
at: anIndex.
lastBranch := (newBranch
anySatisfy: [ :n | n isMemberOf: PRCodeblock ])
ifTrue: [ nil ]
ifFalse: [ newBranch ].
^ lastAttributes
]
{ #category : #'as yet unclassified' }
GrafoscopioPillarRuns >> calculateAttributesForBranch: aCollection at: anIndex [
^ visitor analyzeBranch: aCollection at: anIndex.
]
{ #category : #'basic api' }
GrafoscopioPillarRuns >> isEmpty [
^ ast isNil or: [ ast isEmpty ]
]
{ #category : #'as yet unclassified' }
GrafoscopioPillarRuns >> rangeOf: aTextURL startingAt: anInteger [
self assert: (aTextURL isKindOf: TextAction).
((self at: anInteger) contains: [ : a | (a isKindOf: TextAction)]) ifTrue: [
(ast extractStringFrom: anInteger to: (ast detectAstNodeFor: anInteger ) textStop) traceCr.
^ anInteger to: (ast detectAstNodeFor: anInteger ) textStop
].
^ 0 to: 0
]
{ #category : #'as yet unclassified' }
GrafoscopioPillarRuns >> runLengthFor: anInteger [
| node |
anInteger > ast size
ifTrue: [ ^ 0 ].
node := ast detectAstNodeFor: anInteger.
^ (node isKindOf: PRCodeblock)
ifTrue: [ 1 ]
ifFalse: [ node textStop - anInteger ]
]
{ #category : #'as yet unclassified' }
GrafoscopioPillarRuns >> withStartStopAndValueDo: aBlockClosure [
thisContext sender asString traceCr.
'Should implement' traceCr.
]

View File

@ -1,104 +1,104 @@
Class {
#name : #GrafoscopioPillarStyler,
#superclass : #Object,
#instVars : [
'pharoStyler'
],
#category : #'Grafoscopio-Pillar-Style'
}
{ #category : #accessing }
GrafoscopioPillarStyler class >> defaultStyler [
^ self new
]
{ #category : #'as yet unclassified' }
GrafoscopioPillarStyler >> attributesForCodeBlock: aPRCodeblock at: index [
aPRCodeblock language originalName = 'pharo-image'
ifTrue: [ ^ {(TextAnchor new
anchoredMorph: (self class compiler evaluate: (aPRCodeblock propertyAt: #text)))} ].
aPRCodeblock language originalName = 'pharo'
ifTrue: [ | runs |
runs := (self pharoStyler
privateStyle: aPRCodeblock text asText , '.') runs.
^ runs at: index - aPRCodeblock textStart ].
^{}
]
{ #category : #'as yet unclassified' }
GrafoscopioPillarStyler >> attributesForDocument: aDocument [
^ self default
]
{ #category : #'as yet unclassified' }
GrafoscopioPillarStyler >> attributesForExternalLink: aPRExternalLink [
^ {(TextColor new color: (Color fromHexString: '03A9F4')).
TextEmphasis underlined.
(TextAction new
actOnClickBlock: [ self inform: 'Should be going to ' , aPRExternalLink reference ])}
]
{ #category : #'as yet unclassified' }
GrafoscopioPillarStyler >> attributesForFigure: aPRFigure [
^ self default
]
{ #category : #'as yet unclassified' }
GrafoscopioPillarStyler >> attributesForFormatText: aGrafoscopioFormatTextNode [
^ self attributesForText: aGrafoscopioFormatTextNode
]
{ #category : #'as yet unclassified' }
GrafoscopioPillarStyler >> attributesForHeader: aPRHeader [
^ {(TextFontReference
toFont:
(LogicalFont
familyName: 'Source Code Pro'
pointSize: (20 - (aPRHeader level * 5) max: 10))) . TextEmphasis bold}
]
{ #category : #'as yet unclassified' }
GrafoscopioPillarStyler >> attributesForInternalLink: aPRInternalLink [
^ self attributesForExternalLink: aPRInternalLink
]
{ #category : #'as yet unclassified' }
GrafoscopioPillarStyler >> attributesForLineBreak: aPRLineBreak [
^ self default
]
{ #category : #'as yet unclassified' }
GrafoscopioPillarStyler >> attributesForListItem: aPRListItem at: index [
^ (aPRListItem text at: index - aPRListItem textStart + 1) = Character home
ifTrue: [ {(TextIndent tabs: aPRListItem level).
(TextAnchor new
anchoredMorph: (self iconNamed: #menuPin);
yourself)} ] ifFalse: [ { } ]
]
{ #category : #'as yet unclassified' }
GrafoscopioPillarStyler >> attributesForParagraph: aParagraph [
^ self default
]
{ #category : #'as yet unclassified' }
GrafoscopioPillarStyler >> attributesForText: aText [
^ self default
]
{ #category : #'as yet unclassified' }
GrafoscopioPillarStyler >> attributesForUnorderedList: aList [
^ self default
]
{ #category : #'as yet unclassified' }
GrafoscopioPillarStyler >> default [
^ Array empty
]
{ #category : #'as yet unclassified' }
GrafoscopioPillarStyler >> pharoStyler [
^ pharoStyler
ifNil: [ pharoStyler := SHRBTextStyler new isForWorkspace: true; yourself]
]
Class {
#name : #GrafoscopioPillarStyler,
#superclass : #Object,
#instVars : [
'pharoStyler'
],
#category : #'Grafoscopio-Pillar-Style'
}
{ #category : #accessing }
GrafoscopioPillarStyler class >> defaultStyler [
^ self new
]
{ #category : #'as yet unclassified' }
GrafoscopioPillarStyler >> attributesForCodeBlock: aPRCodeblock at: index [
aPRCodeblock language originalName = 'pharo-image'
ifTrue: [ ^ {(TextAnchor new
anchoredMorph: (self class compiler evaluate: (aPRCodeblock propertyAt: #text)))} ].
aPRCodeblock language originalName = 'pharo'
ifTrue: [ | runs |
runs := (self pharoStyler
privateStyle: aPRCodeblock text asText , '.') runs.
^ runs at: index - aPRCodeblock textStart ].
^{}
]
{ #category : #'as yet unclassified' }
GrafoscopioPillarStyler >> attributesForDocument: aDocument [
^ self default
]
{ #category : #'as yet unclassified' }
GrafoscopioPillarStyler >> attributesForExternalLink: aPRExternalLink [
^ {(TextColor new color: (Color fromHexString: '03A9F4')).
TextEmphasis underlined.
(TextAction new
actOnClickBlock: [ self inform: 'Should be going to ' , aPRExternalLink reference ])}
]
{ #category : #'as yet unclassified' }
GrafoscopioPillarStyler >> attributesForFigure: aPRFigure [
^ self default
]
{ #category : #'as yet unclassified' }
GrafoscopioPillarStyler >> attributesForFormatText: aGrafoscopioFormatTextNode [
^ self attributesForText: aGrafoscopioFormatTextNode
]
{ #category : #'as yet unclassified' }
GrafoscopioPillarStyler >> attributesForHeader: aPRHeader [
^ {(TextFontReference
toFont:
(LogicalFont
familyName: 'Source Code Pro'
pointSize: (20 - (aPRHeader level * 5) max: 10))) . TextEmphasis bold}
]
{ #category : #'as yet unclassified' }
GrafoscopioPillarStyler >> attributesForInternalLink: aPRInternalLink [
^ self attributesForExternalLink: aPRInternalLink
]
{ #category : #'as yet unclassified' }
GrafoscopioPillarStyler >> attributesForLineBreak: aPRLineBreak [
^ self default
]
{ #category : #'as yet unclassified' }
GrafoscopioPillarStyler >> attributesForListItem: aPRListItem at: index [
^ (aPRListItem text at: index - aPRListItem textStart + 1) = Character home
ifTrue: [ {(TextIndent tabs: aPRListItem parent level).
(TextAnchor new
anchoredMorph: (self iconNamed: #menuPin);
yourself)} ] ifFalse: [ { } ]
]
{ #category : #'as yet unclassified' }
GrafoscopioPillarStyler >> attributesForParagraph: aParagraph [
^ self default
]
{ #category : #'as yet unclassified' }
GrafoscopioPillarStyler >> attributesForText: aText [
^ self default
]
{ #category : #'as yet unclassified' }
GrafoscopioPillarStyler >> attributesForUnorderedList: aList [
^ self default
]
{ #category : #'as yet unclassified' }
GrafoscopioPillarStyler >> default [
^ Array empty
]
{ #category : #'as yet unclassified' }
GrafoscopioPillarStyler >> pharoStyler [
^ pharoStyler
ifNil: [ pharoStyler := SHRBTextStyler new isForWorkspace: true; yourself]
]

View File

@ -1,65 +1,65 @@
Class {
#name : #GrafoscopioPillarTextAnnotator,
#superclass : #PRVisitor,
#instVars : [
'texts',
'formatter',
'lastStop'
],
#category : #'Grafoscopio-Pillar'
}
{ #category : #'visiting-document' }
GrafoscopioPillarTextAnnotator >> formatter: aFormatter [
formatter := aFormatter
]
{ #category : #'visiting-document' }
GrafoscopioPillarTextAnnotator >> initialize [
super initialize.
texts := OrderedCollection new.
formatter := GrafoscopioTextFormatter default.
]
{ #category : #'visiting-document' }
GrafoscopioPillarTextAnnotator >> visitCodeblock: aTextObject [
self visitText: aTextObject
]
{ #category : #'visiting-document' }
GrafoscopioPillarTextAnnotator >> visitCommentedLine: aTextObject [
self visitText: aTextObject
]
{ #category : #'visiting-document' }
GrafoscopioPillarTextAnnotator >> visitDocument: aDoc [
lastStop := 1 .
aDoc accept: formatter.
super visitDocument: aDoc.
]
{ #category : #'as yet unclassified' }
GrafoscopioPillarTextAnnotator >> visitFormatText: aGrafoscopioFormatTextNode [
" for the annotator, a format text is a much as regular text"
self visitText: aGrafoscopioFormatTextNode
]
{ #category : #'visiting-document' }
GrafoscopioPillarTextAnnotator >> visitLineBreak: anObject [
^ self visitText: anObject
]
{ #category : #'visiting-document' }
GrafoscopioPillarTextAnnotator >> visitRaw: aTextObject [
self visitText: aTextObject
]
{ #category : #'visiting-document' }
GrafoscopioPillarTextAnnotator >> visitText: aTextObject [
texts ifNotEmpty: [ texts last next: aTextObject ].
texts add: aTextObject.
aTextObject propertyAt: #textStart put: lastStop.
lastStop := lastStop + aTextObject text size.
aTextObject propertyAt: #textStop put: lastStop .
]
Class {
#name : #GrafoscopioPillarTextAnnotator,
#superclass : #PRVisitor,
#instVars : [
'texts',
'formatter',
'lastStop'
],
#category : #'Grafoscopio-Pillar'
}
{ #category : #'visiting-document' }
GrafoscopioPillarTextAnnotator >> formatter: aFormatter [
formatter := aFormatter
]
{ #category : #'visiting-document' }
GrafoscopioPillarTextAnnotator >> initialize [
super initialize.
texts := OrderedCollection new.
formatter := GrafoscopioTextFormatter default.
]
{ #category : #'visiting-document' }
GrafoscopioPillarTextAnnotator >> visitCodeblock: aTextObject [
self visitText: aTextObject
]
{ #category : #'visiting-document' }
GrafoscopioPillarTextAnnotator >> visitCommentedLine: aTextObject [
self visitText: aTextObject
]
{ #category : #'visiting-document' }
GrafoscopioPillarTextAnnotator >> visitDocument: aDoc [
lastStop := 1 .
aDoc accept: formatter.
super visitDocument: aDoc.
]
{ #category : #'as yet unclassified' }
GrafoscopioPillarTextAnnotator >> visitFormatText: aGrafoscopioFormatTextNode [
" for the annotator, a format text is a much as regular text"
self visitText: aGrafoscopioFormatTextNode
]
{ #category : #'visiting-document' }
GrafoscopioPillarTextAnnotator >> visitLineBreak: anObject [
^ self visitText: anObject
]
{ #category : #'visiting-document' }
GrafoscopioPillarTextAnnotator >> visitRaw: aTextObject [
self visitText: aTextObject
]
{ #category : #'visiting-document' }
GrafoscopioPillarTextAnnotator >> visitText: aTextObject [
texts ifNotEmpty: [ texts last next: aTextObject ].
texts add: aTextObject.
aTextObject propertyAt: #textStart put: lastStop.
lastStop := lastStop + aTextObject text size.
aTextObject propertyAt: #textStop put: lastStop .
]

View File

@ -0,0 +1,37 @@
Class {
#name : #GrafoscopioPillarToTextDecorator,
#superclass : #Object,
#instVars : [
'pillarNode'
],
#category : #'Grafoscopio-Pillar'
}
{ #category : #'instance creation' }
GrafoscopioPillarToTextDecorator class >> on: aGFPillarNode [
^ self new
pillarNode: aGFPillarNode;
yourself
]
{ #category : #'as yet unclassified' }
GrafoscopioPillarToTextDecorator >> name [
^ pillarNode name
]
{ #category : #accessing }
GrafoscopioPillarToTextDecorator >> pillarNode: aNode [
pillarNode := aNode
]
{ #category : #accessing }
GrafoscopioPillarToTextDecorator >> text [
^ pillarNode text pillarText
]
{ #category : #accessing }
GrafoscopioPillarToTextDecorator >> text: aText [
| parsed |
parsed := PRPillarParser parse: aText.
^ pillarNode text ast: parsed
]

View File

@ -1,26 +1,31 @@
Class {
#name : #GrafoscopioProject,
#superclass : #Object,
#instVars : [
'document',
'dictionary'
],
#category : #'Grafoscopio-Model'
}
{ #category : #'as yet unclassified' }
GrafoscopioProject >> document [
^ document
]
{ #category : #initialization }
GrafoscopioProject >> initialize [
super initialize.
document := GrafoscopioRootNode new.
dictionary := GrafoscopioRootNode new
]
{ #category : #initialization }
GrafoscopioProject >> name: aName [
document name: aName
]
Class {
#name : #GrafoscopioProject,
#superclass : #Object,
#instVars : [
'document',
'dictionary'
],
#category : #'Grafoscopio-Model'
}
{ #category : #'as yet unclassified' }
GrafoscopioProject >> acceptVisitor: aGrafoscopioViewportTextVisitor [
aGrafoscopioViewportTextVisitor visitGrafoscopioProject: self
]
{ #category : #'as yet unclassified' }
GrafoscopioProject >> document [
^ document
]
{ #category : #initialization }
GrafoscopioProject >> initialize [
super initialize.
document := GrafoscopioRootNode new.
dictionary := GrafoscopioRootNode new
]
{ #category : #initialization }
GrafoscopioProject >> name: aName [
document name: aName
]

View File

@ -1,122 +1,122 @@
"
I'm a tool for finding and replacing text ocurrences in notebook
nodes.
"
Class {
#name : #GrafoscopioReplace,
#superclass : #ComposablePresenter,
#instVars : [
'find',
'replace',
'ok',
'cancel'
],
#category : #'Grafoscopio-UI'
}
{ #category : #specs }
GrafoscopioReplace class >> defaultSpec [
^ SpecLayout composed
newColumn: [ :column |
column
add: #find;
add: #replace;
newRow: [ :row | row add: #ok; add: #cancel ] height: self toolbarHeight ];
yourself
]
{ #category : #accessing }
GrafoscopioReplace >> cancel [
^ cancel
]
{ #category : #accessing }
GrafoscopioReplace >> cancel: anObject [
cancel := anObject
]
{ #category : #accessing }
GrafoscopioReplace >> find [
^ find
]
{ #category : #accessing }
GrafoscopioReplace >> find: anObject [
find := anObject
]
{ #category : #initialization }
GrafoscopioReplace >> initializePresenter [
"Here we need to deal with changes in the OK button to send messages about the
state of the 'find' and 'replace' variables or do nothing if 'Cancel' is pressed."
ok whenStateChangedDo: [
Transcript show: 'OK Clicked!' ]
]
{ #category : #initialization }
GrafoscopioReplace >> initializeWidgets [
find := self newTextInput
ghostText: 'Text to find...';
autoAccept: true.
replace := self newTextInput
ghostText: 'Text to replace...';
autoAccept: true.
ok := self newButton
label: 'OK';
state: false;
action: [
ok state: true.
self window close. ] .
cancel := self newButton
label: 'Cancel';
action: [
cancel state: true.
self window close ].
self focusOrder
add: find;
add: replace;
add: ok;
add: cancel.
self askOkToClose: true
]
{ #category : #accessing }
GrafoscopioReplace >> ok [
^ ok
]
{ #category : #accessing }
GrafoscopioReplace >> ok: anObject [
ok := anObject
]
{ #category : #private }
GrafoscopioReplace >> okToChange [
^ true
]
{ #category : #accessing }
GrafoscopioReplace >> replace [
^ replace
]
{ #category : #accessing }
GrafoscopioReplace >> replace: anObject [
replace := anObject
]
{ #category : #initialization }
GrafoscopioReplace >> returnValues [
self ok state
ifFalse: [ ^ self ]
ifTrue: [^ Dictionary new
at: 'find' put: find getText;
at: 'replace' put: replace getText;
yourself]
]
{ #category : #api }
GrafoscopioReplace >> title [
^ 'Find & Replace'
]
"
I'm a tool for finding and replacing text ocurrences in notebook
nodes.
"
Class {
#name : #GrafoscopioReplace,
#superclass : #ComposablePresenter,
#instVars : [
'find',
'replace',
'ok',
'cancel'
],
#category : #'Grafoscopio-UI'
}
{ #category : #specs }
GrafoscopioReplace class >> defaultSpec [
^ SpecLayout composed
newColumn: [ :column |
column
add: #find;
add: #replace;
newRow: [ :row | row add: #ok; add: #cancel ] height: self toolbarHeight ];
yourself
]
{ #category : #accessing }
GrafoscopioReplace >> cancel [
^ cancel
]
{ #category : #accessing }
GrafoscopioReplace >> cancel: anObject [
cancel := anObject
]
{ #category : #accessing }
GrafoscopioReplace >> find [
^ find
]
{ #category : #accessing }
GrafoscopioReplace >> find: anObject [
find := anObject
]
{ #category : #initialization }
GrafoscopioReplace >> initializePresenter [
"Here we need to deal with changes in the OK button to send messages about the
state of the 'find' and 'replace' variables or do nothing if 'Cancel' is pressed."
ok whenStateChangedDo: [
Transcript show: 'OK Clicked!' ]
]
{ #category : #initialization }
GrafoscopioReplace >> initializeWidgets [
find := self newTextInput
ghostText: 'Text to find...';
autoAccept: true.
replace := self newTextInput
ghostText: 'Text to replace...';
autoAccept: true.
ok := self newButton
label: 'OK';
state: false;
action: [
ok state: true.
self window close. ] .
cancel := self newButton
label: 'Cancel';
action: [
cancel state: true.
self window close ].
self focusOrder
add: find;
add: replace;
add: ok;
add: cancel.
self askOkToClose: true
]
{ #category : #accessing }
GrafoscopioReplace >> ok [
^ ok
]
{ #category : #accessing }
GrafoscopioReplace >> ok: anObject [
ok := anObject
]
{ #category : #private }
GrafoscopioReplace >> okToChange [
^ true
]
{ #category : #accessing }
GrafoscopioReplace >> replace [
^ replace
]
{ #category : #accessing }
GrafoscopioReplace >> replace: anObject [
replace := anObject
]
{ #category : #initialization }
GrafoscopioReplace >> returnValues [
self ok state
ifFalse: [ ^ self ]
ifTrue: [^ Dictionary new
at: 'find' put: find getText;
at: 'replace' put: replace getText;
yourself]
]
{ #category : #api }
GrafoscopioReplace >> title [
^ 'Find & Replace'
]

View File

@ -1,68 +1,68 @@
"
This is a root node. It represents a document.
"
Class {
#name : #GrafoscopioRootNode,
#superclass : #GrafoscopioAbstractNode,
#instVars : [
'children'
],
#category : #'Grafoscopio-Model'
}
{ #category : #accessing }
GrafoscopioRootNode >> acceptVisitor: aGrafoscopioVisitor [
aGrafoscopioVisitor visitRootNode: self.
]
{ #category : #accessing }
GrafoscopioRootNode >> acceptsChildsOfClass: aClass [
^ {GrafoscopioUnitNode} includes: aClass
]
{ #category : #accessing }
GrafoscopioRootNode >> addAtBeginningChild: aBlock ofClass: aClass [
(self acceptsChildsOfClass: aClass)
ifTrue: [ | child |
child := aBlock value.
child parent: self.
self children addFirst: child ]
]
{ #category : #accessing }
GrafoscopioRootNode >> addChild: aBlock ofClass: aClass [
(self acceptsChildsOfClass: aClass)
ifTrue: [ | child |
child := aBlock value.
child parent: self.
self children add: child ]
]
{ #category : #'as yet unclassified' }
GrafoscopioRootNode >> children [
^ children
]
{ #category : #accessing }
GrafoscopioRootNode >> initialize [
super initialize.
children := SortedCollection new
sortBlock: [ :a :b | a order < b order ];
yourself
]
{ #category : #accessing }
GrafoscopioRootNode >> level [
^ 1
]
{ #category : #accessing }
GrafoscopioRootNode >> text [
^ name
]
{ #category : #accessing }
GrafoscopioRootNode >> text: aText [
name := aText
]
"
This is a root node. It represents a document.
"
Class {
#name : #GrafoscopioRootNode,
#superclass : #GrafoscopioAbstractNode,
#instVars : [
'children'
],
#category : #'Grafoscopio-Model'
}
{ #category : #accessing }
GrafoscopioRootNode >> acceptVisitor: aGrafoscopioVisitor [
aGrafoscopioVisitor visitRootNode: self.
]
{ #category : #accessing }
GrafoscopioRootNode >> acceptsChildsOfClass: aClass [
^ {GrafoscopioUnitNode} includes: aClass
]
{ #category : #accessing }
GrafoscopioRootNode >> addAtBeginningChild: aBlock ofClass: aClass [
(self acceptsChildsOfClass: aClass)
ifTrue: [ | child |
child := aBlock value.
child parent: self.
self children addFirst: child ]
]
{ #category : #accessing }
GrafoscopioRootNode >> addChild: aBlock ofClass: aClass [
(self acceptsChildsOfClass: aClass)
ifTrue: [ | child |
child := aBlock value.
child parent: self.
self children add: child ]
]
{ #category : #'as yet unclassified' }
GrafoscopioRootNode >> children [
^ children
]
{ #category : #accessing }
GrafoscopioRootNode >> initialize [
super initialize.
children := SortedCollection new
sortBlock: [ :a :b | a order < b order ];
yourself
]
{ #category : #accessing }
GrafoscopioRootNode >> level [
^ 1
]
{ #category : #accessing }
GrafoscopioRootNode >> text [
^ name
]
{ #category : #accessing }
GrafoscopioRootNode >> text: aText [
name := aText
]

View File

@ -1,124 +1,124 @@
"
I am in charge of formatting a document in terms of text.
Our text model does not support break lines or tabbings as text attribute, but as text content. (By example, our header needs to have a line break before and after by default. This kind of things can be done in rubbric by adding the character cr. Still, our pillar AST does not have this breakline for the header, and we do not wan to add it, since it would affect the parsing. No, what we want is to be able to format and modify the text before returning it when being displayed, composed, scanned, etc. So for doing so we add the text formatter.
This text formatter contains a dictionary that allows the user to add as many as needed for each class.
This class provides as extention point:
#formatsFor: anObject > Returning a collection of formats for the given object (the default behaviour stores it by class).
#Redefine the specific visit methods for specific class behaviour.
)
"
Class {
#name : #GrafoscopioTextFormatter,
#superclass : #PRVisitor,
#instVars : [
'formats',
'stack'
],
#classInstVars : [
'default'
],
#category : #'Grafoscopio-Pillar-TextFormat'
}
{ #category : #accessing }
GrafoscopioTextFormatter class >> buildDefault [
| new |
new := self new.
new registerFormat: GrafoscopioFmtDoubleLinebreak instance forClass: PRHeader.
new registerFormat: GrafoscopioFmtAnchorOnTheLeft instance forClass: PRListItem.
new registerFormat: GrafoscopioFmtBeginningLinebreak instance forClass: PRListItem.
" new registerFormat: GrafoscopioFmtDoubleLinebreak instance forClass: PRCodeblock ."
new registerFormat: GrafoscopioFmtAnchorOnTheLeft2 instance forClass: PRCodeblock .
new registerFormat: GrafoscopioFmtEndingLinebreak instance forClass: PRParagraph .
new registerFormat: GrafoscopioFmtBeginningLinebreak instance forClass: PRList.
new registerFormat: GrafoscopioFmtUrlAsBody instance forClass: PRExternalLink .
new registerFormat: GrafoscopioFmtEndingSpace instance forClass: PRExternalLink.
new registerFormat: GrafoscopioFmtUrlAsBody instance forClass: PRMailLink.
new registerFormat: GrafoscopioFmtEndingSpace instance forClass: PRMailLink.
new registerFormat: GrafoscopioFmtAnchorAsBody instance forClass: PRInternalLink.
new registerFormat: GrafoscopioFmtEndingSpace instance forClass: PRInternalLink.
^ new
]
{ #category : #accessing }
GrafoscopioTextFormatter class >> buildEmpty [
| new |
new := self new.
^ new
]
{ #category : #accessing }
GrafoscopioTextFormatter class >> default [
^ self buildDefault
]
{ #category : #initialization }
GrafoscopioTextFormatter >> format: aNode [
(self formatsFor: aNode) do: [ :f | f beInstalledIn: aNode ]
]
{ #category : #initialization }
GrafoscopioTextFormatter >> formatsFor: aNode [
^ formats at: aNode ifAbsent: [ self formatsForClass: aNode class ]
]
{ #category : #initialization }
GrafoscopioTextFormatter >> formatsForClass: aNodeClass [
^ formats at: aNodeClass ifAbsent: [ Array empty ]
]
{ #category : #initialization }
GrafoscopioTextFormatter >> initialize [
super initialize .
formats := Dictionary new.
stack := Stack new.
]
{ #category : #initialization }
GrafoscopioTextFormatter >> registerFormat: aFormat for: aNode [
^ (formats at: aNode ifAbsentPut: [ OrderedCollection new ])
add: aFormat
]
{ #category : #initialization }
GrafoscopioTextFormatter >> registerFormat: aFormat forClass: aNodeClass [
^ self registerFormat: aFormat for: aNodeClass
]
{ #category : #initialization }
GrafoscopioTextFormatter >> visitDocument: aDocument [
self assert: stack isEmpty.
super visitDocument: aDocument.
self assert: stack isEmpty
]
{ #category : #initialization }
GrafoscopioTextFormatter >> visitDocumentGroup: aNode [
aNode parent: (stack ifNotEmpty: [stack first] ifEmpty:[ nil ]).
self format: aNode.
stack push: aNode.
super visitDocumentGroup: aNode.
stack pop
]
{ #category : #initialization }
GrafoscopioTextFormatter >> visitDocumentItem: anItem [
self format: anItem.
anItem parent: stack first.
]
{ #category : #initialization }
GrafoscopioTextFormatter >> visitEmptyParagraph: aParagraph [
stack top children last = aParagraph
ifTrue: [ stack top children: stack top children allButLast ].
]
{ #category : #'as yet unclassified' }
GrafoscopioTextFormatter >> visitFormatText: aGrafoscopioFormatTextNode [
" No way we format the formatted text. "
]
"
I am in charge of formatting a document in terms of text.
Our text model does not support break lines or tabbings as text attribute, but as text content. (By example, our header needs to have a line break before and after by default. This kind of things can be done in rubbric by adding the character cr. Still, our pillar AST does not have this breakline for the header, and we do not wan to add it, since it would affect the parsing. No, what we want is to be able to format and modify the text before returning it when being displayed, composed, scanned, etc. So for doing so we add the text formatter.
This text formatter contains a dictionary that allows the user to add as many as needed for each class.
This class provides as extention point:
#formatsFor: anObject > Returning a collection of formats for the given object (the default behaviour stores it by class).
#Redefine the specific visit methods for specific class behaviour.
)
"
Class {
#name : #GrafoscopioTextFormatter,
#superclass : #PRVisitor,
#instVars : [
'formats',
'stack'
],
#classInstVars : [
'default'
],
#category : #'Grafoscopio-Pillar-TextFormat'
}
{ #category : #accessing }
GrafoscopioTextFormatter class >> buildDefault [
| new |
new := self new.
new registerFormat: GrafoscopioFmtDoubleLinebreak instance forClass: PRHeader.
new registerFormat: GrafoscopioFmtAnchorOnTheLeft instance forClass: PRListItem.
new registerFormat: GrafoscopioFmtBeginningLinebreak instance forClass: PRListItem.
" new registerFormat: GrafoscopioFmtDoubleLinebreak instance forClass: PRCodeblock ."
new registerFormat: GrafoscopioFmtAnchorOnTheLeft2 instance forClass: PRCodeblock .
new registerFormat: GrafoscopioFmtEndingLinebreak instance forClass: PRParagraph .
new registerFormat: GrafoscopioFmtBeginningLinebreak instance forClass: PRList.
new registerFormat: GrafoscopioFmtUrlAsBody instance forClass: PRExternalLink .
new registerFormat: GrafoscopioFmtEndingSpace instance forClass: PRExternalLink.
new registerFormat: GrafoscopioFmtUrlAsBody instance forClass: PRMailLink.
new registerFormat: GrafoscopioFmtEndingSpace instance forClass: PRMailLink.
new registerFormat: GrafoscopioFmtAnchorAsBody instance forClass: PRInternalLink.
new registerFormat: GrafoscopioFmtEndingSpace instance forClass: PRInternalLink.
^ new
]
{ #category : #accessing }
GrafoscopioTextFormatter class >> buildEmpty [
| new |
new := self new.
^ new
]
{ #category : #accessing }
GrafoscopioTextFormatter class >> default [
^ self buildDefault
]
{ #category : #initialization }
GrafoscopioTextFormatter >> format: aNode [
(self formatsFor: aNode) do: [ :f | f beInstalledIn: aNode ]
]
{ #category : #initialization }
GrafoscopioTextFormatter >> formatsFor: aNode [
^ formats at: aNode ifAbsent: [ self formatsForClass: aNode class ]
]
{ #category : #initialization }
GrafoscopioTextFormatter >> formatsForClass: aNodeClass [
^ formats at: aNodeClass ifAbsent: [ Array empty ]
]
{ #category : #initialization }
GrafoscopioTextFormatter >> initialize [
super initialize .
formats := Dictionary new.
stack := Stack new.
]
{ #category : #initialization }
GrafoscopioTextFormatter >> registerFormat: aFormat for: aNode [
^ (formats at: aNode ifAbsentPut: [ OrderedCollection new ])
add: aFormat
]
{ #category : #initialization }
GrafoscopioTextFormatter >> registerFormat: aFormat forClass: aNodeClass [
^ self registerFormat: aFormat for: aNodeClass
]
{ #category : #initialization }
GrafoscopioTextFormatter >> visitDocument: aDocument [
self assert: stack isEmpty.
super visitDocument: aDocument.
self assert: stack isEmpty
]
{ #category : #initialization }
GrafoscopioTextFormatter >> visitDocumentGroup: aNode [
aNode parent: (stack ifNotEmpty: [stack first] ifEmpty:[ nil ]).
self format: aNode.
stack push: aNode.
super visitDocumentGroup: aNode.
stack pop
]
{ #category : #initialization }
GrafoscopioTextFormatter >> visitDocumentItem: anItem [
self format: anItem.
anItem parent: stack first.
]
{ #category : #initialization }
GrafoscopioTextFormatter >> visitEmptyParagraph: aParagraph [
stack top children last = aParagraph
ifTrue: [ stack top children: stack top children allButLast ].
]
{ #category : #'as yet unclassified' }
GrafoscopioTextFormatter >> visitFormatText: aGrafoscopioFormatTextNode [
" No way we format the formatted text. "
]

View File

@ -1,39 +1,39 @@
"
I represent a text node inside a Grafoscopio notebook.
Usually my content is markdown text.
"
Class {
#name : #GrafoscopioTextModel,
#superclass : #ComposablePresenter,
#instVars : [
'body'
],
#category : #'Grafoscopio-UI'
}
{ #category : #specs }
GrafoscopioTextModel class >> defaultSpec [
^ SpecLayout composed add: #body
]
{ #category : #accessing }
GrafoscopioTextModel >> body [
^ body
]
{ #category : #accessing }
GrafoscopioTextModel >> body: anObject [
body := anObject
]
{ #category : #API }
GrafoscopioTextModel >> content: aGrafoscopioNodeContent [
body text: aGrafoscopioNodeContent
]
{ #category : #initialization }
GrafoscopioTextModel >> initializeWidgets [
body := self newText.
body autoAccept: true.
]
"
I represent a text node inside a Grafoscopio notebook.
Usually my content is markdown text.
"
Class {
#name : #GrafoscopioTextModel,
#superclass : #ComposablePresenter,
#instVars : [
'body'
],
#category : #'Grafoscopio-UI'
}
{ #category : #specs }
GrafoscopioTextModel class >> defaultSpec [
^ SpecLayout composed add: #body
]
{ #category : #accessing }
GrafoscopioTextModel >> body [
^ body
]
{ #category : #accessing }
GrafoscopioTextModel >> body: anObject [
body := anObject
]
{ #category : #API }
GrafoscopioTextModel >> content: aGrafoscopioNodeContent [
body text: aGrafoscopioNodeContent
]
{ #category : #initialization }
GrafoscopioTextModel >> initializeWidgets [
body := self newText.
body autoAccept: true.
]

View File

@ -1,42 +1,42 @@
"
This kind of a leafNodes holds plain text.
"
Class {
#name : #GrafoscopioTextNode,
#superclass : #GrafoscopioLeafNode,
#instVars : [
'text'
],
#category : #'Grafoscopio-Model'
}
{ #category : #accessing }
GrafoscopioTextNode class >> icon [
^ self iconNamed: #workspace
]
{ #category : #'as yet unclassified' }
GrafoscopioTextNode class >> nameForSelection [
^ 'New text node'
]
{ #category : #'as yet unclassified' }
GrafoscopioTextNode class >> showInMenu [
^ true
]
{ #category : #accessing }
GrafoscopioTextNode >> acceptVisitor: aGrafoscopioVisitor [
aGrafoscopioVisitor visitTextNode: self.
]
{ #category : #'as yet unclassified' }
GrafoscopioTextNode >> text [
^ text
]
{ #category : #accessing }
GrafoscopioTextNode >> text: aString [
text := aString
]
"
This kind of a leafNodes holds plain text.
"
Class {
#name : #GrafoscopioTextNode,
#superclass : #GrafoscopioLeafNode,
#instVars : [
'text'
],
#category : #'Grafoscopio-Model'
}
{ #category : #accessing }
GrafoscopioTextNode class >> icon [
^ self iconNamed: #workspace
]
{ #category : #'as yet unclassified' }
GrafoscopioTextNode class >> nameForSelection [
^ 'New text node'
]
{ #category : #'as yet unclassified' }
GrafoscopioTextNode class >> showInMenu [
^ true
]
{ #category : #accessing }
GrafoscopioTextNode >> acceptVisitor: aGrafoscopioVisitor [
aGrafoscopioVisitor visitTextNode: self.
]
{ #category : #'as yet unclassified' }
GrafoscopioTextNode >> text [
^ text
]
{ #category : #accessing }
GrafoscopioTextNode >> text: aString [
text := aString
]

View File

@ -1,80 +1,86 @@
Class {
#name : #GrafoscopioTreeNotebook,
#superclass : #SpPresenterWithModel,
#instVars : [
'sidebar',
'viewport',
'model',
'empty',
'perspectives'
],
#category : #'Grafoscopio-New-UI'
}
{ #category : #specs }
GrafoscopioTreeNotebook class >> defaultSpec [
^ SpBoxLayout newHorizontal
add:
(SpBoxLayout newVertical
add: #empty height: self toolbarHeight;
add: #sidebar;
yourself)
width: 51;
add: #viewport;
yourself
]
{ #category : #'as yet unclassified' }
GrafoscopioTreeNotebook >> basicInstallPerspective: aPerspective [
viewport ifNotNil: [ viewport aboutToBeUninstalledFrom: self ].
viewport := self perspectives
at: aPerspective
ifAbsentPut: [ self instantiate: aPerspective on: model document ].
]
{ #category : #initialization }
GrafoscopioTreeNotebook >> createDefaultComponent [
^ self basicInstallPerspective: GrafoscopioPerspective defaultPerspective
]
{ #category : #initialization }
GrafoscopioTreeNotebook >> initializeWidgets [
super initializeWidgets.
sidebar := self sidebar.
self createDefaultComponent.
empty := self newLabel.
]
{ #category : #initialization }
GrafoscopioTreeNotebook >> installPerspective: aPerspective [
self basicInstallPerspective: aPerspective .
self modelChanged
]
{ #category : #initialization }
GrafoscopioTreeNotebook >> modelChanged [
viewport modelChanged.
self needRebuild: false.
self buildWithSpec
]
{ #category : #initialization }
GrafoscopioTreeNotebook >> perspectives [
^ perspectives ifNil: [ perspectives := Dictionary new ]
]
{ #category : #'as yet unclassified' }
GrafoscopioTreeNotebook >> setModelBeforeInitialization: aDomainObject [
super setModelBeforeInitialization: aDomainObject.
model := aDomainObject
]
{ #category : #initialization }
GrafoscopioTreeNotebook >> sidebar [
| bar |
bar := self instantiate: SpSidebar.
GrafoscopioPerspective perspectives
do:
[ :p | bar addAction: [ self installPerspective: p ] icon: p icon ].
^ bar
]
Class {
#name : #GrafoscopioTreeNotebook,
#superclass : #SpPresenterWithModel,
#instVars : [
'sidebar',
'viewport',
'model',
'empty',
'perspectives'
],
#category : #'Grafoscopio-New-UI'
}
{ #category : #specs }
GrafoscopioTreeNotebook class >> defaultSpec [
^ SpBoxLayout newHorizontal
add:
(SpBoxLayout newVertical
add: #empty height: self toolbarHeight;
add: #sidebar;
yourself)
width: 51;
add: #viewport;
yourself
]
{ #category : #'as yet unclassified' }
GrafoscopioTreeNotebook >> basicInstallPerspective: aPerspective [
viewport ifNotNil: [ viewport aboutToBeUninstalledFrom: self ].
viewport := self perspectives
at: aPerspective
ifAbsentPut: [ self instantiate: aPerspective on: model document ].
viewport aboutToBeInstalled: self.
]
{ #category : #initialization }
GrafoscopioTreeNotebook >> createDefaultComponent [
^ self basicInstallPerspective: GrafoscopioPerspective defaultPerspective
]
{ #category : #initialization }
GrafoscopioTreeNotebook >> initializeWidgets [
super initializeWidgets.
sidebar := self sidebar.
self createDefaultComponent.
empty := self newLabel.
]
{ #category : #initialization }
GrafoscopioTreeNotebook >> installPerspective: aPerspective [
self basicInstallPerspective: aPerspective .
self modelChanged
]
{ #category : #initialization }
GrafoscopioTreeNotebook >> modelChanged [
viewport modelChanged.
self needRebuild: false.
self buildWithSpec
]
{ #category : #initialization }
GrafoscopioTreeNotebook >> perspectives [
^ perspectives ifNil: [ perspectives := Dictionary new ]
]
{ #category : #'as yet unclassified' }
GrafoscopioTreeNotebook >> removePerspective: aPerspective [
perspectives removeKeyAtValue: aPerspective
]
{ #category : #'as yet unclassified' }
GrafoscopioTreeNotebook >> setModelBeforeInitialization: aDomainObject [
super setModelBeforeInitialization: aDomainObject.
model := aDomainObject
]
{ #category : #initialization }
GrafoscopioTreeNotebook >> sidebar [
| bar |
bar := self instantiate: SpSidebar.
GrafoscopioPerspective perspectives
do:
[ :p | bar addAction: [ self installPerspective: p ] icon: p icon ].
^ bar
]

View File

@ -1,41 +1,41 @@
Class {
#name : #GrafoscopioUnitNode,
#superclass : #GrafoscopioBranchNode,
#category : #'Grafoscopio-Model'
}
{ #category : #'instance creation' }
GrafoscopioUnitNode class >> icon [
^ self iconNamed: #smallHierarchyBrowser
]
{ #category : #'instance creation' }
GrafoscopioUnitNode class >> nameForSelection [
^ 'New unit'
]
{ #category : #'instance creation' }
GrafoscopioUnitNode class >> showInMenu [
^ true
]
{ #category : #accessing }
GrafoscopioUnitNode >> acceptVisitor: aGrafoscopioVisitor [
aGrafoscopioVisitor visitUnitNode: self.
]
{ #category : #accessing }
GrafoscopioUnitNode >> acceptsChildsOfClass: aClass [
^ aClass isLeaf or: [ aClass = self class ]
]
{ #category : #accessing }
GrafoscopioUnitNode >> text [
^ name
]
{ #category : #accessing }
GrafoscopioUnitNode >> text: aText [
name := aText
]
Class {
#name : #GrafoscopioUnitNode,
#superclass : #GrafoscopioBranchNode,
#category : #'Grafoscopio-Model'
}
{ #category : #'instance creation' }
GrafoscopioUnitNode class >> icon [
^ self iconNamed: #smallHierarchyBrowser
]
{ #category : #'instance creation' }
GrafoscopioUnitNode class >> nameForSelection [
^ 'New unit'
]
{ #category : #'instance creation' }
GrafoscopioUnitNode class >> showInMenu [
^ true
]
{ #category : #accessing }
GrafoscopioUnitNode >> acceptVisitor: aGrafoscopioVisitor [
aGrafoscopioVisitor visitUnitNode: self.
]
{ #category : #accessing }
GrafoscopioUnitNode >> acceptsChildsOfClass: aClass [
^ aClass isLeaf or: [ aClass = self class ]
]
{ #category : #accessing }
GrafoscopioUnitNode >> text [
^ name
]
{ #category : #accessing }
GrafoscopioUnitNode >> text: aText [
name := aText
]

View File

@ -1,97 +0,0 @@
"
URL Node downloads content for rendering.
"
Class {
#name : #GrafoscopioUrlNode,
#superclass : #GrafoscopioLeafNode,
#instVars : [
'link'
],
#category : #'Grafoscopio-Model'
}
{ #category : #'instance creation' }
GrafoscopioUrlNode class >> icon [
^ self iconNamed: #remote
]
{ #category : #'instance creation' }
GrafoscopioUrlNode class >> nameForSelection [
^ 'New URL Node'
]
{ #category : #'instance creation' }
GrafoscopioUrlNode class >> new [
^ super new
content;
yourself
]
{ #category : #'instance creation' }
GrafoscopioUrlNode class >> showInMenu [
^ true
]
{ #category : #'as yet unclassified' }
GrafoscopioUrlNode >> acceptVisitor: aGrafoscopioVisitor [
aGrafoscopioVisitor visitUrlNode: self.
]
{ #category : #'as yet unclassified' }
GrafoscopioUrlNode >> content [
^ (self url
ifNil: [ ' Invalid url ' ]
ifNotNil: [ :url | self fetchContent: url ])
]
{ #category : #'as yet unclassified' }
GrafoscopioUrlNode >> fetchContent: anUrl [
^ (ZnEasy get: anUrl) entity contents
]
{ #category : #'as yet unclassified' }
GrafoscopioUrlNode >> getUrl [
| url |
url := UIManager default
request: 'Please insert a url '
initialAnswer: 'http://'
title: 'URL Node'.
url ifNil: [ ^ nil ].
url := url asZnUrl.
(url host isEmptyOrNil
or: [ url scheme isEmptyOrNil or: [ url authority isEmptyOrNil ] ])
ifTrue: [ ^ nil ].
^ url
]
{ #category : #accessing }
GrafoscopioUrlNode >> link: aZnUrl [
link := aZnUrl
]
{ #category : #'as yet unclassified' }
GrafoscopioUrlNode >> openIn: aNotebook [
super openIn: aNotebook.
aNotebook links text: (link ifNil: 'Invalid url') asString
]
{ #category : #'as yet unclassified' }
GrafoscopioUrlNode >> shouldAskBeforeRemove [
^ false
]
{ #category : #content }
GrafoscopioUrlNode >> text [
^ self content
]
{ #category : #'as yet unclassified' }
GrafoscopioUrlNode >> text: aString [
]
{ #category : #'as yet unclassified' }
GrafoscopioUrlNode >> url [
^ link ifNil: [ link := self getUrl ]
]

View File

@ -0,0 +1,18 @@
Class {
#name : #GrafoscopioViewportRichTextVisitor,
#superclass : #GrafoscopioViewportTextVisitor,
#category : #'Grafoscopio-New-UI'
}
{ #category : #'as yet unclassified' }
GrafoscopioViewportRichTextVisitor >> visitPillarNode: aNode [
self
showPageFor: aNode
ifProviderDoestExistInstall: [ | text |
text := presenter instantiate: GrafoscopioNewTextModel on: aNode.
text
contextMenuFromCommandsGroup: [ presenter rootCommandsGroup / 'Context Menu' ].
text
onModifyNodeLocationDo: [ presenter informNodeHasChanged: aNode ].
text ]
]

View File

@ -0,0 +1,60 @@
Class {
#name : #GrafoscopioViewportTextVisitor,
#superclass : #GrafoscopioVisitor,
#instVars : [
'viewport',
'stack',
'presenter',
'pages'
],
#category : #'Grafoscopio-New-UI'
}
{ #category : #visiting }
GrafoscopioViewportTextVisitor >> createViewportFor: aDocumentNode into: aPresenter [
presenter := aPresenter.
aDocumentNode acceptVisitor: self.
^ viewport
]
{ #category : #visiting }
GrafoscopioViewportTextVisitor >> initialize [
super initialize.
pages := Dictionary new
]
{ #category : #'as yet unclassified' }
GrafoscopioViewportTextVisitor >> renamePageFor: aNode [
pages at: aNode ifPresent: [ : p | p title: aNode name ]
]
{ #category : #'as yet unclassified' }
GrafoscopioViewportTextVisitor >> showPageFor: aNode ifProviderDoestExistInstall: aBlock [
| page |
page := pages at: aNode ifAbsentPut: [ aBlock value ].
presenter viewport: page
]
{ #category : #'as yet unclassified' }
GrafoscopioViewportTextVisitor >> visitPillarNode: aGrafoscopioPillarNode [
self
showPageFor: aGrafoscopioPillarNode
ifProviderDoestExistInstall: [ | text |
text := presenter
instantiate: GrafoscopioNewTextModel
on: (GrafoscopioPillarToTextDecorator on: aGrafoscopioPillarNode).
text
onModifyNodeLocationDo: [ :model | model model text: model body text ].
text ]
]
{ #category : #visiting }
GrafoscopioViewportTextVisitor >> visitTextNode: aNode [
self
showPageFor: aNode
ifProviderDoestExistInstall: [ | text |
text := presenter instantiate: GrafoscopioNewTextModel on: aNode.
text
onModifyNodeLocationDo: [ :model | model model text: model body text ].
text ]
]

View File

@ -1,77 +0,0 @@
Class {
#name : #GrafoscopioViewportVisitor,
#superclass : #GrafoscopioVisitor,
#instVars : [
'viewport',
'stack',
'items',
'presenter'
],
#category : #'Grafoscopio-New-UI'
}
{ #category : #visiting }
GrafoscopioViewportVisitor >> createViewportFor: aDocumentNode into: aPresenter [
presenter := aPresenter.
items := OrderedCollection new.
aDocumentNode acceptVisitor: self.
viewport := aPresenter viewport
ifNil: [ aPresenter instantiate: SpComponentListPresenter ].
viewport items: items.
^ viewport
]
{ #category : #visiting }
GrafoscopioViewportVisitor >> visitCodeNode: aNode [
| code |
code := presenter instantiate: GrafoscopioNewCodeModel.
code onModifyNodeLocationDo: [ presenter informNodeHasChanged: aNode ].
code model: aNode.
items add: code.
]
{ #category : #visiting }
GrafoscopioViewportVisitor >> visitRootNode: aNode [
| text |
text := presenter instantiate: GrafoscopioNewTextInputModel.
text model: aNode.
text onModifyNodeLocationDo: [ presenter informNodeHasChanged: aNode ].
items add: text.
super visitRootNode: aNode.
]
{ #category : #visiting }
GrafoscopioViewportVisitor >> visitTextNode: aNode [
| text |
text := presenter instantiate: GrafoscopioNewTextModel.
text onModifyNodeLocationDo: [ presenter informNodeHasChanged: aNode ].
text model: aNode.
items add: text.
]
{ #category : #visiting }
GrafoscopioViewportVisitor >> visitUnitNode: aNode [
| text |
text := presenter instantiate: GrafoscopioNewTextInputModel.
text model: aNode.
text onModifyNodeLocationDo: [ presenter informNodeHasChanged: aNode ].
items add: text.
items add: (presenter newButton
label: ' Add node on the beginning ';
action: [ presenter addNewNodeAtBeginningOf: aNode ];
yourself).
super visitUnitNode: aNode.
items add: (presenter newButton
label: ' Add node on the end ';
action: [ presenter addNewNodeAtLastOf: aNode ];
yourself)
]
{ #category : #visiting }
GrafoscopioViewportVisitor >> visitUrlNode: aNode [
| text |
text := presenter instantiate: GrafoscopioNewTextInputModel.
text onModifyNodeLocationDo: [ presenter informNodeHasChanged: aNode ].
text model: aNode.
items add: text.
]

View File

@ -1,48 +1,44 @@
Class {
#name : #GrafoscopioVisitor,
#superclass : #Object,
#category : #'Grafoscopio-Model'
}
{ #category : #visiting }
GrafoscopioVisitor >> visitBranchNode: aNode [
self visitNode: aNode.
aNode children do: [ : c | c acceptVisitor: self ].
]
{ #category : #visiting }
GrafoscopioVisitor >> visitCodeNode: aNode [
self visitNode: aNode
]
{ #category : #visiting }
GrafoscopioVisitor >> visitLeafNode: aNode [
self visitNode: aNode
]
{ #category : #visiting }
GrafoscopioVisitor >> visitNode: aNode [
" nothing to do here"
]
{ #category : #visiting }
GrafoscopioVisitor >> visitRootNode: aNode [
self visitNode: aNode.
aNode children do: [ : c | c acceptVisitor: self ].
]
{ #category : #visiting }
GrafoscopioVisitor >> visitTextNode: aNode [
self visitNode: aNode
]
{ #category : #visiting }
GrafoscopioVisitor >> visitUnitNode: aNode [
self visitNode: aNode.
aNode children do: [ : c | c acceptVisitor: self ].
]
{ #category : #visiting }
GrafoscopioVisitor >> visitUrlNode: aNode [
self visitNode: aNode
]
Class {
#name : #GrafoscopioVisitor,
#superclass : #Object,
#category : #'Grafoscopio-Model'
}
{ #category : #visiting }
GrafoscopioVisitor >> visitBranchNode: aNode [
self visitNode: aNode.
aNode children do: [ : c | c acceptVisitor: self ].
]
{ #category : #'as yet unclassified' }
GrafoscopioVisitor >> visitGrafoscopioProject: aGrafoscopioProject [
self visitNode: aGrafoscopioProject .
aGrafoscopioProject document acceptVisitor: self.
]
{ #category : #visiting }
GrafoscopioVisitor >> visitLeafNode: aNode [
self visitNode: aNode
]
{ #category : #visiting }
GrafoscopioVisitor >> visitNode: aNode [
" nothing to do here"
]
{ #category : #visiting }
GrafoscopioVisitor >> visitRootNode: aNode [
self visitNode: aNode.
aNode children do: [ : c | c acceptVisitor: self ].
]
{ #category : #visiting }
GrafoscopioVisitor >> visitTextNode: aNode [
self visitNode: aNode
]
{ #category : #visiting }
GrafoscopioVisitor >> visitUnitNode: aNode [
self visitNode: aNode.
aNode children do: [ : c | c acceptVisitor: self ].
]

View File

@ -1,15 +1,15 @@
Class {
#name : #GrafoscopioZoaPediaPerspective,
#superclass : #GrafoscopioPerspective,
#category : #'Grafoscopio-New-UI'
}
{ #category : #accessing }
GrafoscopioZoaPediaPerspective class >> icon [
^ self iconNamed: #edit
]
{ #category : #initialization }
GrafoscopioZoaPediaPerspective >> createViewport [
^ self newLabel
]
Class {
#name : #GrafoscopioZoaPediaPerspective,
#superclass : #GrafoscopioPerspective,
#category : #'Grafoscopio-New-UI'
}
{ #category : #accessing }
GrafoscopioZoaPediaPerspective class >> icon [
^ self iconNamed: #edit
]
{ #category : #initialization }
GrafoscopioZoaPediaPerspective >> createViewport [
^ self newLabel
]

View File

@ -1,63 +1,63 @@
"
I store metadata for this package. These meta data are used by other tools such as the SmalllintManifestChecker and the critics Browser
"
Class {
#name : #ManifestGrafoscopio,
#superclass : #PackageManifest,
#category : #Grafoscopio
}
{ #category : #'code-critics' }
ManifestGrafoscopio class >> ruleRBAssignmentInIfTrueRuleV1FalsePositive [
^ #(#(#(#RGMethodDefinition #(#GrafoscopioTextNode #embedNodes #false)) #'2017-02-16T20:07:02.600781-05:00') #(#(#RGMethodDefinition #(#GrafoscopioNewNotebook #navigateRelativePathFor: #false)) #'2017-03-28T22:30:53.541042-05:00') )
]
{ #category : #'code-critics' }
ManifestGrafoscopio class >> ruleRBBadMessageRuleV1FalsePositive [
^ #(#(#(#RGMethodDefinition #(#'GrafoscopioDocumentation class' #openNotebookFrom:At: #true)) #'2017-04-05T18:01:21.892153-05:00') )
]
{ #category : #'code-critics' }
ManifestGrafoscopio class >> ruleRBBooleanPrecedenceRuleV1FalsePositive [
^ #(#(#(#RGMethodDefinition #(#'GrafoscopioNode class' #cleanTreeRootReferences #true)) #'2017-03-27T22:18:17.447627-05:00') )
]
{ #category : #'code-critics' }
ManifestGrafoscopio class >> ruleRBCascadedNextPutAllsRuleV1FalsePositive [
^ #(#(#(#RGMethodDefinition #(#GrafoscopioTextNode #metadataAsYamlIn: #false)) #'2017-04-20T19:01:59.286212-05:00') )
]
{ #category : #'code-critics' }
ManifestGrafoscopio class >> ruleRBClassNameInSelectorRuleV1FalsePositive [
^ #(#(#(#RGMethodDefinition #(#'Documentation class' #current #true)) #'2016-10-07T19:39:23.013722-05:00') )
]
{ #category : #'code-critics' }
ManifestGrafoscopio class >> ruleRBEqualsTrueRuleV1FalsePositive [
^ #(#(#(#RGMethodDefinition #(#'GrafoscopioDocumentation class' #listOutdated #true)) #'2016-10-09T10:16:31.841951-05:00') #(#(#RGMethodDefinition #(#'GrafoscopioDocumentation class' #listOutdatedDocsIn: #true)) #'2017-04-05T17:50:59.032741-05:00') )
]
{ #category : #'code-critics' }
ManifestGrafoscopio class >> ruleRBLongMethodsRuleV1FalsePositive [
^ #(#(#(#RGMethodDefinition #(#GrafoscopioNewNotebook #topBar #false)) #'2016-12-17T18:51:33.99062-05:00') #(#(#RGMethodDefinition #(#GrafoscopioNewNotebook #notebookSubMenu #false)) #'2017-02-02T11:43:53.106456-05:00') )
]
{ #category : #'code-critics' }
ManifestGrafoscopio class >> ruleRBSentNotImplementedRuleV1FalsePositive [
^ #(#(#(#RGMetaclassDefinition #(#'GrafoscopioGUI class' #GfUIHelpers)) #'2015-12-23T10:38:16.706667-05:00') #(#(#RGClassDefinition #(#GfUIHelpers)) #'2016-01-06T18:53:45.844051-05:00') #(#(#RGMethodDefinition #(#GrafoscopioNewNotebook #topBar #false)) #'2016-12-17T18:51:40.617924-05:00') )
]
{ #category : #'code-critics' }
ManifestGrafoscopio class >> ruleRBShouldntRaiseErrorRuleV1FalsePositive [
^ #(#(#(#RGMethodDefinition #(#GrafoscopioNodeTest #testInitializeIsOk #false)) #'2017-01-31T12:49:28.199769-05:00') )
]
{ #category : #'code-critics' }
ManifestGrafoscopio class >> ruleRBStringConcatenationRuleV1FalsePositive [
^ #(#(#(#RGMethodDefinition #(#'FileUtils class' #createFilesNamed:endingWith:intoFolder: #true)) #'2017-01-01T21:48:26.712639-05:00') )
]
{ #category : #'code-critics' }
ManifestGrafoscopio class >> ruleSmTMethodTestedRuleV1FalsePositive [
^ #(#(#(#RGClassDefinition #(#GrafoscopioTextNode)) #'2017-10-31T19:59:03.294735-05:00') )
]
"
I store metadata for this package. These meta data are used by other tools such as the SmalllintManifestChecker and the critics Browser
"
Class {
#name : #ManifestGrafoscopio,
#superclass : #PackageManifest,
#category : #Grafoscopio
}
{ #category : #'code-critics' }
ManifestGrafoscopio class >> ruleRBAssignmentInIfTrueRuleV1FalsePositive [
^ #(#(#(#RGMethodDefinition #(#GrafoscopioTextNode #embedNodes #false)) #'2017-02-16T20:07:02.600781-05:00') #(#(#RGMethodDefinition #(#GrafoscopioNewNotebook #navigateRelativePathFor: #false)) #'2017-03-28T22:30:53.541042-05:00') )
]
{ #category : #'code-critics' }
ManifestGrafoscopio class >> ruleRBBadMessageRuleV1FalsePositive [
^ #(#(#(#RGMethodDefinition #(#'GrafoscopioDocumentation class' #openNotebookFrom:At: #true)) #'2017-04-05T18:01:21.892153-05:00') )
]
{ #category : #'code-critics' }
ManifestGrafoscopio class >> ruleRBBooleanPrecedenceRuleV1FalsePositive [
^ #(#(#(#RGMethodDefinition #(#'GrafoscopioNode class' #cleanTreeRootReferences #true)) #'2017-03-27T22:18:17.447627-05:00') )
]
{ #category : #'code-critics' }
ManifestGrafoscopio class >> ruleRBCascadedNextPutAllsRuleV1FalsePositive [
^ #(#(#(#RGMethodDefinition #(#GrafoscopioTextNode #metadataAsYamlIn: #false)) #'2017-04-20T19:01:59.286212-05:00') )
]
{ #category : #'code-critics' }
ManifestGrafoscopio class >> ruleRBClassNameInSelectorRuleV1FalsePositive [
^ #(#(#(#RGMethodDefinition #(#'Documentation class' #current #true)) #'2016-10-07T19:39:23.013722-05:00') )
]
{ #category : #'code-critics' }
ManifestGrafoscopio class >> ruleRBEqualsTrueRuleV1FalsePositive [
^ #(#(#(#RGMethodDefinition #(#'GrafoscopioDocumentation class' #listOutdated #true)) #'2016-10-09T10:16:31.841951-05:00') #(#(#RGMethodDefinition #(#'GrafoscopioDocumentation class' #listOutdatedDocsIn: #true)) #'2017-04-05T17:50:59.032741-05:00') )
]
{ #category : #'code-critics' }
ManifestGrafoscopio class >> ruleRBLongMethodsRuleV1FalsePositive [
^ #(#(#(#RGMethodDefinition #(#GrafoscopioNewNotebook #topBar #false)) #'2016-12-17T18:51:33.99062-05:00') #(#(#RGMethodDefinition #(#GrafoscopioNewNotebook #notebookSubMenu #false)) #'2017-02-02T11:43:53.106456-05:00') )
]
{ #category : #'code-critics' }
ManifestGrafoscopio class >> ruleRBSentNotImplementedRuleV1FalsePositive [
^ #(#(#(#RGMetaclassDefinition #(#'GrafoscopioGUI class' #GfUIHelpers)) #'2015-12-23T10:38:16.706667-05:00') #(#(#RGClassDefinition #(#GfUIHelpers)) #'2016-01-06T18:53:45.844051-05:00') #(#(#RGMethodDefinition #(#GrafoscopioNewNotebook #topBar #false)) #'2016-12-17T18:51:40.617924-05:00') )
]
{ #category : #'code-critics' }
ManifestGrafoscopio class >> ruleRBShouldntRaiseErrorRuleV1FalsePositive [
^ #(#(#(#RGMethodDefinition #(#GrafoscopioNodeTest #testInitializeIsOk #false)) #'2017-01-31T12:49:28.199769-05:00') )
]
{ #category : #'code-critics' }
ManifestGrafoscopio class >> ruleRBStringConcatenationRuleV1FalsePositive [
^ #(#(#(#RGMethodDefinition #(#'FileUtils class' #createFilesNamed:endingWith:intoFolder: #true)) #'2017-01-01T21:48:26.712639-05:00') )
]
{ #category : #'code-critics' }
ManifestGrafoscopio class >> ruleSmTMethodTestedRuleV1FalsePositive [
^ #(#(#(#RGClassDefinition #(#GrafoscopioTextNode)) #'2017-10-31T19:59:03.294735-05:00') )
]

View File

@ -1,220 +1,220 @@
"
Please comment me using the following template inspired by Class Responsibility Collaborator (CRC) design:
I'm MendaIcons the provider of this icons on this environment.
My main responsibility is to support some menda icons insideCallback pharo environment, for that I convert and package png images to the pharo image.
For the Collaborators Part: State my main collaborators and one line about how I interact with them.
Public API and Key Messages
- message one
- message two
- what is the way to create instances is a plus.
One simple example is simply gorgeous.
Internal Representation and Key Implementation Points.
Implementation Points
"
Class {
#name : #MendaIcons,
#superclass : #Object,
#instVars : [
'icons'
],
#classVars : [
'Current'
],
#category : #'Grafoscopio-UI'
}
{ #category : #'instance creation' }
MendaIcons class >> current [
^ Current ifNil: [ Current := self new ]
]
{ #category : #'accessing - icons' }
MendaIcons >> arrowDownIcon [
"Private - Generated method"
^Form fromBinaryStream: (self arrowDownIconContents base64Decoded readStream)
]
{ #category : #'private - contents' }
MendaIcons >> arrowDownIconContents [
"Private - Method generated with the content of the file File @ /home/offray/Programas/Grafoscopio/Dev/Common/Icons/Menda/Png/arrowDown.png"
^ 'iVBORw0KGgoAAAANSUhEUgAAAA4AAAAICAYAAADJEc7MAAAABHNCSVQICAgIfAhkiAAAAAlw
SFlzAAAOxAAADsQBlSsOGwAAALJJREFUGJV9zjEKwkAUBND5i3ZaeJBAcgavIIjX2GwK8QbZ
/bmGjSDYaq5gE/Aa9hIyNkZkXf0w1fCGD5IIIexUNSOJf6nrOvfeb0lCXuBK8m6MWVprOyTO
e5+LSAtgDiA31tqO5EZEFsMwtE3TZDFS1WJEJNfOuZsBAOfc4RdW1YLkZURVVR0BQEi+l0MI
KxHZj2/3fT81xpxj9AVjLCITkrMYJWGEmUI/4Qd+lGV5SvVPkLiZ0qKAa5MAAAAASUVORK5C
YII='
]
{ #category : #'accessing - icons' }
MendaIcons >> arrowLeftIcon [
"Private - Generated method"
^Form fromBinaryStream: (self arrowLeftIconContents base64Decoded readStream)
]
{ #category : #'private - contents' }
MendaIcons >> arrowLeftIconContents [
"Private - Method generated with the content of the file File @ /home/offray/Programas/Grafoscopio/Dev/Common/Icons/Menda/Png/arrowLeft.png"
^ 'iVBORw0KGgoAAAANSUhEUgAAAAgAAAAOCAYAAAASVl2WAAAABHNCSVQICAgIfAhkiAAAAAlw
SFlzAAAOxAAADsQBlSsOGwAAAK1JREFUGJV9kcFpAmEQhb835rpo2giYHsSLBQhiH3NLCf/+
20XIRexAy7CLkAKEfZ42xNXswJy+j4H3Bts821rr0jayzXhqrTvbn8DHgzBASd+2VzEFM/MS
UxAgpiDArGmafyFA2L5KMjCz/TJOFJl5tL0H5hFxLqW83wkAmXkYJEmnv9JvikGStJB06rpu
CTw22bbtVtKX7Z+IWN8VNbr02vf95umjbFNKebPNDbaypHslWRyiAAAAAElFTkSuQmCC'
]
{ #category : #'accessing - icons' }
MendaIcons >> arrowRightIcon [
"Private - Generated method"
^Form fromBinaryStream: (self arrowRightIconContents base64Decoded readStream)
]
{ #category : #'private - contents' }
MendaIcons >> arrowRightIconContents [
"Private - Method generated with the content of the file File @ /home/offray/Programas/Grafoscopio/Dev/Common/Icons/Menda/Png/arrowRight.png"
^ 'iVBORw0KGgoAAAANSUhEUgAAAAgAAAAOCAYAAAASVl2WAAAABHNCSVQICAgIfAhkiAAAAAlw
SFlzAAAOxAAADsQBlSsOGwAAAMVJREFUGJV9kTFqw0AQRf/M2pWsQK4RMDit2lTpDSbXkFCV
I6xW13AZcK20ukAgOYb7IPTSxMFWLH8YGHgPZpgRoJTSGtC1Cnmev0ra933/VRTFpyZxMzsA
RzPbN02z/SeUZfnh7k9zkkvSLclPzZxkwMXMtm3X4zi+m9k98OKaZBiGpZktAMzs+0JIKT2G
EDpgBeyqqjosziHQSVoBu7qu3/6WjDFufmF+DiUpZFm2cfdO0t0Uni75DFyFkiRAMcaHuWf9
APv6mfGc3+HbAAAAAElFTkSuQmCC'
]
{ #category : #'accessing - icons' }
MendaIcons >> arrowUpIcon [
"Private - Generated method"
^Form fromBinaryStream: (self arrowUpIconContents base64Decoded readStream)
]
{ #category : #'private - contents' }
MendaIcons >> arrowUpIconContents [
"Private - Method generated with the content of the file File @ /home/offray/Programas/Grafoscopio/Dev/Common/Icons/Menda/Png/arrowUp.png"
^ 'iVBORw0KGgoAAAANSUhEUgAAAA4AAAAICAYAAADJEc7MAAAABHNCSVQICAgIfAhkiAAAAAlw
SFlzAAAOxAAADsQBlSsOGwAAAJRJREFUGJWNy8EJQjEQBNCdVGAdwtca/LYg2EdIsIjNliHi
xQ6sQfRgF4L/LOx4EnJIPg7MaeaBpLRiZnuSn5TSpbWHGXQEcC6l7P6CFXqJyATg1MKhh0hu
AGx7OPRQSukZY7y7+9jCoYd+h5zzw91Hku8aw8wGd7+1UB1VXQG4AliQXAtJUdWDqi5JylzN
bFDVTFK+Zz+PhDBK0j8AAAAASUVORK5CYII='
]
{ #category : #'gt-inspector' }
MendaIcons >> gtInspectorIconsIn: composite [
<gtInspectorPresentationOrder: 40>
composite list
title: 'Icons';
display: [
self iconSelectors asSortedCollection
collect: [ :each | each -> (self perform: each) ] ];
icon: [ :each | each value ];
format: [ :each | each key ]
]
{ #category : #initialization }
MendaIcons >> iconSelectors [
^ self class selectors select: [ :each | '*Icon' match: each asString ]
]
{ #category : #initialization }
MendaIcons >> initialize [
super initialize.
self initializeIcons
]
{ #category : #initialization }
MendaIcons >> initializeIcons [
icons := LRUCache new
maximumWeight: 64;
factory: [ :key | self perform: key ];
yourself
]
{ #category : #'accessing - icons' }
MendaIcons >> minusIcon [
"Private - Generated method"
^Form fromBinaryStream: (self minusIconContents base64Decoded readStream)
]
{ #category : #'private - contents' }
MendaIcons >> minusIconContents [
"Private - Method generated with the content of the file File @ /home/offray/Programas/Grafoscopio/Dev/Common/Icons/Menda/Png/minus.png"
^ 'iVBORw0KGgoAAAANSUhEUgAAAA4AAAADCAYAAACj1j4PAAAABHNCSVQICAgIfAhkiAAAAAlw
SFlzAAAOxAAADsQBlSsOGwAAADhJREFUCJlj7O7uDmNgYEhjIAEwMTFNZ2FkZJRjYGBwJkXj
379/t7D8////AQMDw05SNDIwMDwEANK6DIovD6CyAAAAAElFTkSuQmCC'
]
{ #category : #'accessing - icons' }
MendaIcons >> plusIcon [
"Private - Generated method"
^Form fromBinaryStream: (self plusIconContents base64Decoded readStream)
]
{ #category : #'private - contents' }
MendaIcons >> plusIconContents [
"Private - Method generated with the content of the file File @ /home/offray/Programas/Grafoscopio/Dev/Common/Icons/Menda/Png/plus.png"
^ 'iVBORw0KGgoAAAANSUhEUgAAAA4AAAAOCAYAAAAfSC3RAAAABHNCSVQICAgIfAhkiAAAAAlw
SFlzAAAOxAAADsQBlSsOGwAAAKVJREFUKJHVkjEOgkAQRd9suIFcxUhvZeJpCA2FhoJ2uYyN
nEE9CZ5hP4WQkHVJjIWJv5r5839m83dMEjG6ritCCO3U1lVV3WJN9uYCJOVmtgcws01K41Lk
J/i90bz3haQ84rfAeaob4LEcShqyEEI7B7GCJsH1Xz81A+o4ckm7eZOZnYD7cu6ce1rqALz3
R+AyGQ9lWV5jzR/949qtDkAPryBSmhE5/jJyCd+z1gAAAABJRU5ErkJggg=='
]
{ #category : #'accessing - icons' }
MendaIcons >> smalltalkCodeIcon [
"Private - Generated method"
^Form fromBinaryStream: (self smalltalkCodeIconContents base64Decoded readStream)
]
{ #category : #'private - contents' }
MendaIcons >> smalltalkCodeIconContents [
"Private - Method generated with the content of the file File @ /home/offray/Programas/Grafoscopio/Dev/Common/Icons/Menda/Png/smalltalkCode.png"
^ 'iVBORw0KGgoAAAANSUhEUgAAAA4AAAAOCAYAAAAfSC3RAAAABHNCSVQICAgIfAhkiAAAAAlw
SFlzAAAOxAAADsQBlSsOGwAAAQhJREFUKJHtkrFOw0AQRGfOJ1FdkSB6pLgN+QAaJCQkfsS1
ZbcUDm18EvK/UOQPEA1ROiy+gDQBdxz20BwSsiho0jHV7urN7BbLuq4fJc0kbUn2xpiboige
6rq+JdmXZblcrVbnJJeSLMk5ydZKmpGckrwAAEl3AEDyTNInABhjTgBckkRkUkNyG5vTJEkm
zrk1RnLO3SdJMhmGIY2hGyupJwlr7Vue5/uxCQCyLAsA9t57G5f05jfwL/o3HsJo4xshhHDs
vbdd171XVfXxE2qa5iiE4ABMv32G5BwAjDEvAHbOuatxegjhGsAOwHMcLSzJVlJKciOpjwAA
PAHoY/0qaR2vW0hqvwBnzXKb8TsomwAAAABJRU5ErkJggg=='
]
{ #category : #'accessing - icons' }
MendaIcons >> tagAddIcon [
"Private - Generated method"
^Form fromBinaryStream: (self tagAddIconContents base64Decoded readStream)
]
{ #category : #'private - contents' }
MendaIcons >> tagAddIconContents [
"Private - Method generated with the content of the file File @ /home/offray/Programas/Grafoscopio/Dev/Common/Icons/Menda/Png/tagAdd.png"
^ 'iVBORw0KGgoAAAANSUhEUgAAAA4AAAAOCAYAAAAfSC3RAAAABHNCSVQICAgIfAhkiAAAAAlw
SFlzAAAOxAAADsQBlSsOGwAAATFJREFUKJF90DFPAjEcBfD3GuByGg1qiH4FRyOrDhjipl9B
HR25+whu0NldJ0dmHJ2c1U0HY6KigKLJwYE8F8GjAf5Jk+bf/tq+slwunwDIwymSNgiCmtsf
lgGQJ7nrDklVa21xFgQASGpKOpXU/bvRn4VNYn4RhuExgKvEc6fiJDyqVCqXAApO1onYJDZ4
JHdI0j19EjYkraRoUo71zXcsZOOJmJJgrS1KqpL0k3B77xG31zk0Xv7bkiKS+5QEAGM4X3hG
OvODldUOvj4yiLsG9zfLqD/NAcBA0sEIJvFSrusbI2xsveLhLovPhofvdhpxJzUgeVgqlc6S
v4ogCGok91tvXtSs++j1DNotD826P4ZGGd0a3jy/2PPjKIV+34yhqdDJ7LloJkzgtTAMz921
X92gun92K18+AAAAAElFTkSuQmCC'
]
{ #category : #'accessing - icons' }
MendaIcons >> tagMinusIcon [
"Private - Generated method"
^Form fromBinaryStream: (self tagMinusIconContents base64Decoded readStream)
]
{ #category : #'private - contents' }
MendaIcons >> tagMinusIconContents [
"Private - Method generated with the content of the file File @ /home/offray/Programas/Grafoscopio/Dev/Common/Icons/Menda/Png/tagMinus.png"
^ 'iVBORw0KGgoAAAANSUhEUgAAAA4AAAAOCAYAAAAfSC3RAAAABHNCSVQICAgIfAhkiAAAAAlw
SFlzAAAOxAAADsQBlSsOGwAAAPhJREFUKJGF0bFKQzEUBuD/D9Zy3RQKPsh9gkpx7Cuoo+NN
HqHbvZm76+TYuY4+gqubIDg4iFBbaP8u9ZIcrrcHAiHJl5NzwrquZwBKmCAZvfdLu/4XDkBJ
8toOSYsY46QPAgAkfUmaS1ofMhZ92CXzpxDCPYCX5Ln/4hTeNU3zDGBsau3ELjkwJHlFkvb2
LuxIRkmrrjr6MCUhxjiRtCBZHLtA0orklJIAIMPl+AOD020G3l4v8Pl+BgA7STctTPH5aF04
pwz+fA+w+T3ZkbytquohgzazeWWLgPw7AADe+yXJqWlYhtrmdEWSeWhRL0zwZQjh0e7tAVcM
m6R0vbZ+AAAAAElFTkSuQmCC'
]
"
Please comment me using the following template inspired by Class Responsibility Collaborator (CRC) design:
I'm MendaIcons the provider of this icons on this environment.
My main responsibility is to support some menda icons insideCallback pharo environment, for that I convert and package png images to the pharo image.
For the Collaborators Part: State my main collaborators and one line about how I interact with them.
Public API and Key Messages
- message one
- message two
- what is the way to create instances is a plus.
One simple example is simply gorgeous.
Internal Representation and Key Implementation Points.
Implementation Points
"
Class {
#name : #MendaIcons,
#superclass : #Object,
#instVars : [
'icons'
],
#classVars : [
'Current'
],
#category : #'Grafoscopio-UI'
}
{ #category : #'instance creation' }
MendaIcons class >> current [
^ Current ifNil: [ Current := self new ]
]
{ #category : #'accessing - icons' }
MendaIcons >> arrowDownIcon [
"Private - Generated method"
^Form fromBinaryStream: (self arrowDownIconContents base64Decoded readStream)
]
{ #category : #'private - contents' }
MendaIcons >> arrowDownIconContents [
"Private - Method generated with the content of the file File @ /home/offray/Programas/Grafoscopio/Dev/Common/Icons/Menda/Png/arrowDown.png"
^ 'iVBORw0KGgoAAAANSUhEUgAAAA4AAAAICAYAAADJEc7MAAAABHNCSVQICAgIfAhkiAAAAAlw
SFlzAAAOxAAADsQBlSsOGwAAALJJREFUGJV9zjEKwkAUBND5i3ZaeJBAcgavIIjX2GwK8QbZ
/bmGjSDYaq5gE/Aa9hIyNkZkXf0w1fCGD5IIIexUNSOJf6nrOvfeb0lCXuBK8m6MWVprOyTO
e5+LSAtgDiA31tqO5EZEFsMwtE3TZDFS1WJEJNfOuZsBAOfc4RdW1YLkZURVVR0BQEi+l0MI
KxHZj2/3fT81xpxj9AVjLCITkrMYJWGEmUI/4Qd+lGV5SvVPkLiZ0qKAa5MAAAAASUVORK5C
YII='
]
{ #category : #'accessing - icons' }
MendaIcons >> arrowLeftIcon [
"Private - Generated method"
^Form fromBinaryStream: (self arrowLeftIconContents base64Decoded readStream)
]
{ #category : #'private - contents' }
MendaIcons >> arrowLeftIconContents [
"Private - Method generated with the content of the file File @ /home/offray/Programas/Grafoscopio/Dev/Common/Icons/Menda/Png/arrowLeft.png"
^ 'iVBORw0KGgoAAAANSUhEUgAAAAgAAAAOCAYAAAASVl2WAAAABHNCSVQICAgIfAhkiAAAAAlw
SFlzAAAOxAAADsQBlSsOGwAAAK1JREFUGJV9kcFpAmEQhb835rpo2giYHsSLBQhiH3NLCf/+
20XIRexAy7CLkAKEfZ42xNXswJy+j4H3Bts821rr0jayzXhqrTvbn8DHgzBASd+2VzEFM/MS
UxAgpiDArGmafyFA2L5KMjCz/TJOFJl5tL0H5hFxLqW83wkAmXkYJEmnv9JvikGStJB06rpu
CTw22bbtVtKX7Z+IWN8VNbr02vf95umjbFNKebPNDbaypHslWRyiAAAAAElFTkSuQmCC'
]
{ #category : #'accessing - icons' }
MendaIcons >> arrowRightIcon [
"Private - Generated method"
^Form fromBinaryStream: (self arrowRightIconContents base64Decoded readStream)
]
{ #category : #'private - contents' }
MendaIcons >> arrowRightIconContents [
"Private - Method generated with the content of the file File @ /home/offray/Programas/Grafoscopio/Dev/Common/Icons/Menda/Png/arrowRight.png"
^ 'iVBORw0KGgoAAAANSUhEUgAAAAgAAAAOCAYAAAASVl2WAAAABHNCSVQICAgIfAhkiAAAAAlw
SFlzAAAOxAAADsQBlSsOGwAAAMVJREFUGJV9kTFqw0AQRf/M2pWsQK4RMDit2lTpDSbXkFCV
I6xW13AZcK20ukAgOYb7IPTSxMFWLH8YGHgPZpgRoJTSGtC1Cnmev0ra933/VRTFpyZxMzsA
RzPbN02z/SeUZfnh7k9zkkvSLclPzZxkwMXMtm3X4zi+m9k98OKaZBiGpZktAMzs+0JIKT2G
EDpgBeyqqjosziHQSVoBu7qu3/6WjDFufmF+DiUpZFm2cfdO0t0Uni75DFyFkiRAMcaHuWf9
APv6mfGc3+HbAAAAAElFTkSuQmCC'
]
{ #category : #'accessing - icons' }
MendaIcons >> arrowUpIcon [
"Private - Generated method"
^Form fromBinaryStream: (self arrowUpIconContents base64Decoded readStream)
]
{ #category : #'private - contents' }
MendaIcons >> arrowUpIconContents [
"Private - Method generated with the content of the file File @ /home/offray/Programas/Grafoscopio/Dev/Common/Icons/Menda/Png/arrowUp.png"
^ 'iVBORw0KGgoAAAANSUhEUgAAAA4AAAAICAYAAADJEc7MAAAABHNCSVQICAgIfAhkiAAAAAlw
SFlzAAAOxAAADsQBlSsOGwAAAJRJREFUGJWNy8EJQjEQBNCdVGAdwtca/LYg2EdIsIjNliHi
xQ6sQfRgF4L/LOx4EnJIPg7MaeaBpLRiZnuSn5TSpbWHGXQEcC6l7P6CFXqJyATg1MKhh0hu
AGx7OPRQSukZY7y7+9jCoYd+h5zzw91Hku8aw8wGd7+1UB1VXQG4AliQXAtJUdWDqi5JylzN
bFDVTFK+Zz+PhDBK0j8AAAAASUVORK5CYII='
]
{ #category : #'gt-inspector' }
MendaIcons >> gtInspectorIconsIn: composite [
<gtInspectorPresentationOrder: 40>
composite list
title: 'Icons';
display: [
self iconSelectors asSortedCollection
collect: [ :each | each -> (self perform: each) ] ];
icon: [ :each | each value ];
format: [ :each | each key ]
]
{ #category : #initialization }
MendaIcons >> iconSelectors [
^ self class selectors select: [ :each | '*Icon' match: each asString ]
]
{ #category : #initialization }
MendaIcons >> initialize [
super initialize.
self initializeIcons
]
{ #category : #initialization }
MendaIcons >> initializeIcons [
icons := LRUCache new
maximumWeight: 64;
factory: [ :key | self perform: key ];
yourself
]
{ #category : #'accessing - icons' }
MendaIcons >> minusIcon [
"Private - Generated method"
^Form fromBinaryStream: (self minusIconContents base64Decoded readStream)
]
{ #category : #'private - contents' }
MendaIcons >> minusIconContents [
"Private - Method generated with the content of the file File @ /home/offray/Programas/Grafoscopio/Dev/Common/Icons/Menda/Png/minus.png"
^ 'iVBORw0KGgoAAAANSUhEUgAAAA4AAAADCAYAAACj1j4PAAAABHNCSVQICAgIfAhkiAAAAAlw
SFlzAAAOxAAADsQBlSsOGwAAADhJREFUCJlj7O7uDmNgYEhjIAEwMTFNZ2FkZJRjYGBwJkXj
379/t7D8////AQMDw05SNDIwMDwEANK6DIovD6CyAAAAAElFTkSuQmCC'
]
{ #category : #'accessing - icons' }
MendaIcons >> plusIcon [
"Private - Generated method"
^Form fromBinaryStream: (self plusIconContents base64Decoded readStream)
]
{ #category : #'private - contents' }
MendaIcons >> plusIconContents [
"Private - Method generated with the content of the file File @ /home/offray/Programas/Grafoscopio/Dev/Common/Icons/Menda/Png/plus.png"
^ 'iVBORw0KGgoAAAANSUhEUgAAAA4AAAAOCAYAAAAfSC3RAAAABHNCSVQICAgIfAhkiAAAAAlw
SFlzAAAOxAAADsQBlSsOGwAAAKVJREFUKJHVkjEOgkAQRd9suIFcxUhvZeJpCA2FhoJ2uYyN
nEE9CZ5hP4WQkHVJjIWJv5r5839m83dMEjG6ritCCO3U1lVV3WJN9uYCJOVmtgcws01K41Lk
J/i90bz3haQ84rfAeaob4LEcShqyEEI7B7GCJsH1Xz81A+o4ckm7eZOZnYD7cu6ce1rqALz3
R+AyGQ9lWV5jzR/949qtDkAPryBSmhE5/jJyCd+z1gAAAABJRU5ErkJggg=='
]
{ #category : #'accessing - icons' }
MendaIcons >> smalltalkCodeIcon [
"Private - Generated method"
^Form fromBinaryStream: (self smalltalkCodeIconContents base64Decoded readStream)
]
{ #category : #'private - contents' }
MendaIcons >> smalltalkCodeIconContents [
"Private - Method generated with the content of the file File @ /home/offray/Programas/Grafoscopio/Dev/Common/Icons/Menda/Png/smalltalkCode.png"
^ 'iVBORw0KGgoAAAANSUhEUgAAAA4AAAAOCAYAAAAfSC3RAAAABHNCSVQICAgIfAhkiAAAAAlw
SFlzAAAOxAAADsQBlSsOGwAAAQhJREFUKJHtkrFOw0AQRGfOJ1FdkSB6pLgN+QAaJCQkfsS1
ZbcUDm18EvK/UOQPEA1ROiy+gDQBdxz20BwSsiho0jHV7urN7BbLuq4fJc0kbUn2xpiboige
6rq+JdmXZblcrVbnJJeSLMk5ydZKmpGckrwAAEl3AEDyTNInABhjTgBckkRkUkNyG5vTJEkm
zrk1RnLO3SdJMhmGIY2hGyupJwlr7Vue5/uxCQCyLAsA9t57G5f05jfwL/o3HsJo4xshhHDs
vbdd171XVfXxE2qa5iiE4ABMv32G5BwAjDEvAHbOuatxegjhGsAOwHMcLSzJVlJKciOpjwAA
PAHoY/0qaR2vW0hqvwBnzXKb8TsomwAAAABJRU5ErkJggg=='
]
{ #category : #'accessing - icons' }
MendaIcons >> tagAddIcon [
"Private - Generated method"
^Form fromBinaryStream: (self tagAddIconContents base64Decoded readStream)
]
{ #category : #'private - contents' }
MendaIcons >> tagAddIconContents [
"Private - Method generated with the content of the file File @ /home/offray/Programas/Grafoscopio/Dev/Common/Icons/Menda/Png/tagAdd.png"
^ 'iVBORw0KGgoAAAANSUhEUgAAAA4AAAAOCAYAAAAfSC3RAAAABHNCSVQICAgIfAhkiAAAAAlw
SFlzAAAOxAAADsQBlSsOGwAAATFJREFUKJF90DFPAjEcBfD3GuByGg1qiH4FRyOrDhjipl9B
HR25+whu0NldJ0dmHJ2c1U0HY6KigKLJwYE8F8GjAf5Jk+bf/tq+slwunwDIwymSNgiCmtsf
lgGQJ7nrDklVa21xFgQASGpKOpXU/bvRn4VNYn4RhuExgKvEc6fiJDyqVCqXAApO1onYJDZ4
JHdI0j19EjYkraRoUo71zXcsZOOJmJJgrS1KqpL0k3B77xG31zk0Xv7bkiKS+5QEAGM4X3hG
OvODldUOvj4yiLsG9zfLqD/NAcBA0sEIJvFSrusbI2xsveLhLovPhofvdhpxJzUgeVgqlc6S
v4ogCGok91tvXtSs++j1DNotD826P4ZGGd0a3jy/2PPjKIV+34yhqdDJ7LloJkzgtTAMz921
X92gun92K18+AAAAAElFTkSuQmCC'
]
{ #category : #'accessing - icons' }
MendaIcons >> tagMinusIcon [
"Private - Generated method"
^Form fromBinaryStream: (self tagMinusIconContents base64Decoded readStream)
]
{ #category : #'private - contents' }
MendaIcons >> tagMinusIconContents [
"Private - Method generated with the content of the file File @ /home/offray/Programas/Grafoscopio/Dev/Common/Icons/Menda/Png/tagMinus.png"
^ 'iVBORw0KGgoAAAANSUhEUgAAAA4AAAAOCAYAAAAfSC3RAAAABHNCSVQICAgIfAhkiAAAAAlw
SFlzAAAOxAAADsQBlSsOGwAAAPhJREFUKJGF0bFKQzEUBuD/D9Zy3RQKPsh9gkpx7Cuoo+NN
HqHbvZm76+TYuY4+gqubIDg4iFBbaP8u9ZIcrrcHAiHJl5NzwrquZwBKmCAZvfdLu/4XDkBJ
8toOSYsY46QPAgAkfUmaS1ofMhZ92CXzpxDCPYCX5Ln/4hTeNU3zDGBsau3ELjkwJHlFkvb2
LuxIRkmrrjr6MCUhxjiRtCBZHLtA0orklJIAIMPl+AOD020G3l4v8Pl+BgA7STctTPH5aF04
pwz+fA+w+T3ZkbytquohgzazeWWLgPw7AADe+yXJqWlYhtrmdEWSeWhRL0zwZQjh0e7tAVcM
m6R0vbZ+AAAAAElFTkSuQmCC'
]

View File

@ -1,185 +1,185 @@
"
I provide support for minmapping Freemind import and d3js export.
In the future I'll plan to support exporting from Grafoscopio notebooks
to javascript enabled web presentations.
"
Class {
#name : #MindMap,
#superclass : #Object,
#category : #'Grafoscopio-Model'
}
{ #category : #'as yet unclassified' }
MindMap class >> d3CSS [
"I define the nodes geometrical form, their text and the links between them."
^ ' .node circle {
fill: #fff;
stroke: steelblue;
stroke-width: 3px;
}
.node text { font: 12px sans-serif; }
.link {
fill: none;
stroke: #ccc;
stroke-width: 2px;
}'
]
{ #category : #'as yet unclassified' }
MindMap class >> d3SVGAppender [
"I append the SVG working area to the body of our web page and create a group elements
(<g>) that will contain the SVG objects (the nodes, text and links)"
^'var svg = d3.select("body").append("svg")
.attr("width", width + margin.right + margin.left)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");'
]
{ #category : #'as yet unclassified' }
MindMap class >> d3TreeDemoData [
"I'm demo data for the tutorial contain at: https://blog.pixelingene.com/2011/07/building-a-tree-diagram-in-d3-js/"
^ 'var treeData = {
name: "/",
contents: [
{
name: "Applications",
contents: [
{ name: "Mail.app" },
{ name: "iPhoto.app" },
{ name: "Keynote.app" },
{ name: "iTunes.app" },
{ name: "XCode.app" },
{ name: "Numbers.app" },
{ name: "Pages.app" }
]
},
{
name: "System",
contents: []
},
{
name: "Library",
contents: [
{
name: "Application Support",
contents: [
{ name: "Adobe" },
{ name: "Apple" },
{ name: "Google" },
{ name: "Microsoft" }
]
},
{
name: "Languages",
contents: [
{ name: "Ruby" },
{ name: "Python" },
{ name: "Javascript" },
{ name: "C#" }
]
},
{
name: "Developer",
contents: [
{ name: "4.2" },
{ name: "4.3" },
{ name: "5.0" },
{ name: "Documentation" }
]
}
]
},
{
name: "opt",
contents: []
},
{
name: "Users",
contents: [
{ name: "pavanpodila" },
{ name: "admin" },
{ name: "test-user" }
]
}
]
};'
]
{ #category : #'as yet unclassified' }
MindMap class >> d3TreeDiagramProperties [
^ 'var margin = {top: 20, right: 120, bottom: 20, left: 120},
width = 960 - margin.right - margin.left,
height = 500 - margin.top - margin.bottom;
var i = 0;
var tree = d3.layout.tree()
.size([height, width]);'
]
{ #category : #'as yet unclassified' }
MindMap class >> d3TreeLinksDrawerFunction [
^ 'var diagonal = d3.svg.diagonal()
.projection(function(d) { return [d.y, d.x]; });'
]
{ #category : #'as yet unclassified' }
MindMap class >> d3TreeRootDefinition [
"For an excellent explanation on whi this, look at:
http://www.d3noob.org/2014/01/tree-diagrams-in-d3js_11.html"
^ 'root = treeData[0];'
]
{ #category : #'as yet unclassified' }
MindMap class >> d3TreeUpdater [
^ 'function update (source) {
// Compute the new tree layout.
var nodes = tree.nodes(root).reverse(),
links = tree.links(nodes);
// Normalize for fixed-depth.
nodes.forEach(function(d) { d.y = d.depth * 180 });
// Declare the nodes
var node = svg.selectAll("g.node")
.data(nodes, function(d) { return d.id || (d.id = ++i); });
// Enter the nodes.
var nodeEnter = node.enter().append("g")
.attr("class", "node")
.attr("transform", function(d) {
return "translate(" + d.y + "," + d.x + ")";});
nodeEnter.append("circle")
.attr("r",10)
.style("fill", "#fff");
nodeEnter.append("text")
.attr("x", function (d) {
return d.children || d._children ? -13 : 13; })
.attr("dy", ".35em")
.attr("text-anchor", function(d) {
return d.children || d._children ? "end" : "start"; })
.text(function(d) { return d.name; })
.style ("fill-opacity", 1);
// Declare the links
var link = svg.selectAll("path.link")
.data(links, function(d) { return d.targed.id });
// Enter the links.
link.enter().insert("path","g")
.attr("class", "link")
.attr("d", diagonal);
}'
]
{ #category : #'as yet unclassified' }
MindMap class >> d3TreeUpdaterCaller [
^ 'update(root)'
]
"
I provide support for minmapping Freemind import and d3js export.
In the future I'll plan to support exporting from Grafoscopio notebooks
to javascript enabled web presentations.
"
Class {
#name : #MindMap,
#superclass : #Object,
#category : #'Grafoscopio-Model'
}
{ #category : #'as yet unclassified' }
MindMap class >> d3CSS [
"I define the nodes geometrical form, their text and the links between them."
^ ' .node circle {
fill: #fff;
stroke: steelblue;
stroke-width: 3px;
}
.node text { font: 12px sans-serif; }
.link {
fill: none;
stroke: #ccc;
stroke-width: 2px;
}'
]
{ #category : #'as yet unclassified' }
MindMap class >> d3SVGAppender [
"I append the SVG working area to the body of our web page and create a group elements
(<g>) that will contain the SVG objects (the nodes, text and links)"
^'var svg = d3.select("body").append("svg")
.attr("width", width + margin.right + margin.left)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");'
]
{ #category : #'as yet unclassified' }
MindMap class >> d3TreeDemoData [
"I'm demo data for the tutorial contain at: https://blog.pixelingene.com/2011/07/building-a-tree-diagram-in-d3-js/"
^ 'var treeData = {
name: "/",
contents: [
{
name: "Applications",
contents: [
{ name: "Mail.app" },
{ name: "iPhoto.app" },
{ name: "Keynote.app" },
{ name: "iTunes.app" },
{ name: "XCode.app" },
{ name: "Numbers.app" },
{ name: "Pages.app" }
]
},
{
name: "System",
contents: []
},
{
name: "Library",
contents: [
{
name: "Application Support",
contents: [
{ name: "Adobe" },
{ name: "Apple" },
{ name: "Google" },
{ name: "Microsoft" }
]
},
{
name: "Languages",
contents: [
{ name: "Ruby" },
{ name: "Python" },
{ name: "Javascript" },
{ name: "C#" }
]
},
{
name: "Developer",
contents: [
{ name: "4.2" },
{ name: "4.3" },
{ name: "5.0" },
{ name: "Documentation" }
]
}
]
},
{
name: "opt",
contents: []
},
{
name: "Users",
contents: [
{ name: "pavanpodila" },
{ name: "admin" },
{ name: "test-user" }
]
}
]
};'
]
{ #category : #'as yet unclassified' }
MindMap class >> d3TreeDiagramProperties [
^ 'var margin = {top: 20, right: 120, bottom: 20, left: 120},
width = 960 - margin.right - margin.left,
height = 500 - margin.top - margin.bottom;
var i = 0;
var tree = d3.layout.tree()
.size([height, width]);'
]
{ #category : #'as yet unclassified' }
MindMap class >> d3TreeLinksDrawerFunction [
^ 'var diagonal = d3.svg.diagonal()
.projection(function(d) { return [d.y, d.x]; });'
]
{ #category : #'as yet unclassified' }
MindMap class >> d3TreeRootDefinition [
"For an excellent explanation on whi this, look at:
http://www.d3noob.org/2014/01/tree-diagrams-in-d3js_11.html"
^ 'root = treeData[0];'
]
{ #category : #'as yet unclassified' }
MindMap class >> d3TreeUpdater [
^ 'function update (source) {
// Compute the new tree layout.
var nodes = tree.nodes(root).reverse(),
links = tree.links(nodes);
// Normalize for fixed-depth.
nodes.forEach(function(d) { d.y = d.depth * 180 });
// Declare the nodes
var node = svg.selectAll("g.node")
.data(nodes, function(d) { return d.id || (d.id = ++i); });
// Enter the nodes.
var nodeEnter = node.enter().append("g")
.attr("class", "node")
.attr("transform", function(d) {
return "translate(" + d.y + "," + d.x + ")";});
nodeEnter.append("circle")
.attr("r",10)
.style("fill", "#fff");
nodeEnter.append("text")
.attr("x", function (d) {
return d.children || d._children ? -13 : 13; })
.attr("dy", ".35em")
.attr("text-anchor", function(d) {
return d.children || d._children ? "end" : "start"; })
.text(function(d) { return d.name; })
.style ("fill-opacity", 1);
// Declare the links
var link = svg.selectAll("path.link")
.data(links, function(d) { return d.targed.id });
// Enter the links.
link.enter().insert("path","g")
.attr("class", "link")
.attr("d", diagonal);
}'
]
{ #category : #'as yet unclassified' }
MindMap class >> d3TreeUpdaterCaller [
^ 'update(root)'
]

View File

@ -1,13 +1,13 @@
Extension { #name : #PRCodeblock }
{ #category : #'*Grafoscopio' }
PRCodeblock >> children [
^ self
propertyAt: #children
ifAbsentPut: [ { PRText new text: text; parent: self ;yourself } asOrderedCollection ]
]
{ #category : #'*Grafoscopio' }
PRCodeblock >> children: aCollection [
self propertyAt:#children put: aCollection.
]
Extension { #name : #PRCodeblock }
{ #category : #'*Grafoscopio' }
PRCodeblock >> children [
^ self
propertyAt: #children
ifAbsentPut: [ { PRText new text: text; parent: self ;yourself } asOrderedCollection ]
]
{ #category : #'*Grafoscopio' }
PRCodeblock >> children: aCollection [
self propertyAt:#children put: aCollection.
]

View File

@ -1,8 +1,8 @@
Extension { #name : #PRDocumentGroup }
{ #category : #'*Grafoscopio' }
PRDocumentGroup >> children: anArrayOfChildren [
"Answer the children of the receiver."
children := anArrayOfChildren asArray
]
Extension { #name : #PRDocumentGroup }
{ #category : #'*Grafoscopio' }
PRDocumentGroup >> children: anArrayOfChildren [
"Answer the children of the receiver."
children := anArrayOfChildren asArray
]

View File

@ -1,63 +1,63 @@
Extension { #name : #PRDocumentItem }
{ #category : #'*Grafoscopio' }
PRDocumentItem >> formats [
| ancestors |
ancestors := (self parent ifNil: [ {} ] ifNotNil: [ self parent formats ]).
^ ancestors , (self propertyAt: #gfpFormat ifAbsent: [ Array empty ])
]
{ #category : #'*Grafoscopio' }
PRDocumentItem >> installFormat: aFormat [
(self propertyAt: #gfpFormat ifAbsentPut: [ OrderedCollection new ]) add: aFormat.
]
{ #category : #'*Grafoscopio' }
PRDocumentItem >> isLineBreak [
^ false
]
{ #category : #'*Grafoscopio' }
PRDocumentItem >> isTextOrLineBreak [
^ false
]
{ #category : #'*Grafoscopio' }
PRDocumentItem >> markAsDirty [
self parent ifNotNil: [ :p | p markAsDirty ].
properties removeKey: #textStart ifAbsent: [ ].
properties removeKey: #textStop ifAbsent: [ ]
]
{ #category : #'*Grafoscopio' }
PRDocumentItem >> parent [
^ self propertyAt: #parent ifAbsent: [ nil ]
]
{ #category : #'*Grafoscopio' }
PRDocumentItem >> parent: aParent [
self propertyAt: #parent put: aParent
]
{ #category : #'*Grafoscopio' }
PRDocumentItem >> textSize [
^ self textStop - self textStart
]
{ #category : #'*Grafoscopio' }
PRDocumentItem >> textStart [
^ self
propertyAt: #textStart
ifAbsentPut: [ self hasChildren
ifTrue: [ self children first textStart ]
ifFalse: [ 0 ] ]
]
{ #category : #'*Grafoscopio' }
PRDocumentItem >> textStop [
^ self
propertyAt: #textStop
ifAbsentPut: [ self hasChildren
ifTrue: [ self children last textStop ]
ifFalse: [ 0 ] ]
]
Extension { #name : #PRDocumentItem }
{ #category : #'*Grafoscopio' }
PRDocumentItem >> formats [
| ancestors |
ancestors := (self parent ifNil: [ {} ] ifNotNil: [ self parent formats ]).
^ ancestors , (self propertyAt: #gfpFormat ifAbsent: [ Array empty ])
]
{ #category : #'*Grafoscopio' }
PRDocumentItem >> installFormat: aFormat [
(self propertyAt: #gfpFormat ifAbsentPut: [ OrderedCollection new ]) add: aFormat.
]
{ #category : #'*Grafoscopio' }
PRDocumentItem >> isLineBreak [
^ false
]
{ #category : #'*Grafoscopio' }
PRDocumentItem >> isTextOrLineBreak [
^ false
]
{ #category : #'*Grafoscopio' }
PRDocumentItem >> markAsDirty [
self parent ifNotNil: [ :p | p markAsDirty ].
properties removeKey: #textStart ifAbsent: [ ].
properties removeKey: #textStop ifAbsent: [ ]
]
{ #category : #'*Grafoscopio' }
PRDocumentItem >> parent [
^ self propertyAt: #parent ifAbsent: [ nil ]
]
{ #category : #'*Grafoscopio' }
PRDocumentItem >> parent: aParent [
self propertyAt: #parent put: aParent
]
{ #category : #'*Grafoscopio' }
PRDocumentItem >> textSize [
^ self textStop - self textStart
]
{ #category : #'*Grafoscopio' }
PRDocumentItem >> textStart [
^ self
propertyAt: #textStart
ifAbsentPut: [ self hasChildren
ifTrue: [ self children first textStart ]
ifFalse: [ 0 ] ]
]
{ #category : #'*Grafoscopio' }
PRDocumentItem >> textStop [
^ self
propertyAt: #textStop
ifAbsentPut: [ self hasChildren
ifTrue: [ self children last textStop ]
ifFalse: [ 0 ] ]
]

View File

@ -1,70 +1,70 @@
Extension { #name : #PRLineBreak }
{ #category : #'*Grafoscopio' }
PRLineBreak >> formattedText [
^ OSPlatform current lineEnding
]
{ #category : #'*Grafoscopio' }
PRLineBreak >> isLineBreak [
^ true
]
{ #category : #'*Grafoscopio' }
PRLineBreak >> isTextOrLineBreak [
^ true
]
{ #category : #'*Grafoscopio' }
PRLineBreak >> markAsDirty [
self parent ifNotNil: [ :p | p markAsDirty ]
]
{ #category : #'*Grafoscopio' }
PRLineBreak >> next [
^ self propertyAt: #next ifAbsent: [ nil ]
]
{ #category : #'*Grafoscopio' }
PRLineBreak >> next: aText [
self propertyAt: #next put: aText
]
{ #category : #'*Grafoscopio' }
PRLineBreak >> text [
^ OSPlatform current lineEnding
]
{ #category : #'*Grafoscopio' }
PRLineBreak >> text: aString [
self shouldBeImplemented.
]
{ #category : #'*Grafoscopio' }
PRLineBreak >> textSize [
^ self text size
]
{ #category : #'*Grafoscopio' }
PRLineBreak >> textStart [
^ self propertyAt: #textStart
]
{ #category : #'*Grafoscopio' }
PRLineBreak >> textStart: aValue [
^ self
propertyAt: #textStart
put: aValue
]
{ #category : #'*Grafoscopio' }
PRLineBreak >> textStop [
^ self propertyAt: #textStop
]
{ #category : #'*Grafoscopio' }
PRLineBreak >> textStop: aValue [
^ self
propertyAt: #textStop
put: aValue
]
Extension { #name : #PRLineBreak }
{ #category : #'*Grafoscopio' }
PRLineBreak >> formattedText [
^ OSPlatform current lineEnding
]
{ #category : #'*Grafoscopio' }
PRLineBreak >> isLineBreak [
^ true
]
{ #category : #'*Grafoscopio' }
PRLineBreak >> isTextOrLineBreak [
^ true
]
{ #category : #'*Grafoscopio' }
PRLineBreak >> markAsDirty [
self parent ifNotNil: [ :p | p markAsDirty ]
]
{ #category : #'*Grafoscopio' }
PRLineBreak >> next [
^ self propertyAt: #next ifAbsent: [ nil ]
]
{ #category : #'*Grafoscopio' }
PRLineBreak >> next: aText [
self propertyAt: #next put: aText
]
{ #category : #'*Grafoscopio' }
PRLineBreak >> text [
^ OSPlatform current lineEnding
]
{ #category : #'*Grafoscopio' }
PRLineBreak >> text: aString [
self shouldBeImplemented.
]
{ #category : #'*Grafoscopio' }
PRLineBreak >> textSize [
^ 1
]
{ #category : #'*Grafoscopio' }
PRLineBreak >> textStart [
^ self propertyAt: #textStart
]
{ #category : #'*Grafoscopio' }
PRLineBreak >> textStart: aValue [
^ self
propertyAt: #textStart
put: aValue
]
{ #category : #'*Grafoscopio' }
PRLineBreak >> textStop [
^ self propertyAt: #textStop
]
{ #category : #'*Grafoscopio' }
PRLineBreak >> textStop: aValue [
^ self
propertyAt: #textStop
put: aValue
]

View File

@ -1,16 +1,16 @@
Extension { #name : #PRList }
{ #category : #'*Grafoscopio' }
PRList >> level [
| current level |
current := self.
level := 0.
[ current notNil ]
whileTrue: [
(current isKindOf: PRList) ifTrue: [
level := level + 1.
].
current := current parent
].
^ level
]
Extension { #name : #PRList }
{ #category : #'*Grafoscopio' }
PRList >> level [
| current level |
current := self.
level := 0.
[ current notNil ]
whileTrue: [
(current isKindOf: PRList) ifTrue: [
level := level + 1.
].
current := current parent
].
^ level
]

View File

@ -1,6 +1,6 @@
Extension { #name : #PRPillarWriter }
{ #category : #'*Grafoscopio' }
PRPillarWriter >> visitFormatText: aGrafoscopioFormatTextNode [
" Do nothing "
]
Extension { #name : #PRPillarWriter }
{ #category : #'*Grafoscopio' }
PRPillarWriter >> visitFormatText: aGrafoscopioFormatTextNode [
" Do nothing "
]

View File

@ -1,45 +1,45 @@
Extension { #name : #PRText }
{ #category : #'*Grafoscopio' }
PRText >> isTextOrLineBreak [
^ true
]
{ #category : #'*Grafoscopio' }
PRText >> markAsDirty [
self parent ifNotNil: [ :p | p markAsDirty ]
]
{ #category : #'*Grafoscopio' }
PRText >> next [
^ self propertyAt: #next ifAbsent: [ nil ]
]
{ #category : #'*Grafoscopio' }
PRText >> next: aText [
self propertyAt: #next put: aText.
]
{ #category : #'*Grafoscopio' }
PRText >> textStart [
^ self propertyAt: #textStart
]
{ #category : #'*Grafoscopio' }
PRText >> textStart: aValue [
^ self
propertyAt: #textStart
put: aValue
]
{ #category : #'*Grafoscopio' }
PRText >> textStop [
^ self propertyAt: #textStop
]
{ #category : #'*Grafoscopio' }
PRText >> textStop: aValue [
^ self
propertyAt: #textStop
put: aValue
]
Extension { #name : #PRText }
{ #category : #'*Grafoscopio' }
PRText >> isTextOrLineBreak [
^ true
]
{ #category : #'*Grafoscopio' }
PRText >> markAsDirty [
self parent ifNotNil: [ :p | p markAsDirty ]
]
{ #category : #'*Grafoscopio' }
PRText >> next [
^ self propertyAt: #next ifAbsent: [ nil ]
]
{ #category : #'*Grafoscopio' }
PRText >> next: aText [
self propertyAt: #next put: aText.
]
{ #category : #'*Grafoscopio' }
PRText >> textStart [
^ self propertyAt: #textStart
]
{ #category : #'*Grafoscopio' }
PRText >> textStart: aValue [
^ self
propertyAt: #textStart
put: aValue
]
{ #category : #'*Grafoscopio' }
PRText >> textStop [
^ self propertyAt: #textStop
]
{ #category : #'*Grafoscopio' }
PRText >> textStop: aValue [
^ self
propertyAt: #textStop
put: aValue
]

View File

@ -1,44 +1,44 @@
Class {
#name : #SpSidebar,
#superclass : #SpPresenter,
#instVars : [
'container'
],
#category : #'Grafoscopio-New-UI'
}
{ #category : #specs }
SpSidebar class >> defaultSpec [
^ SpBoxLayout newHorizontal
add: #container ;
yourself
]
{ #category : #initialization }
SpSidebar >> addAction: aBlock icon: anIcon [
container
addPresenter:
(self createDefaultPresenter
parent: self;
action: [ :state |
container unselectAll.
aBlock cull: state ];
icon: anIcon;
yourself)
]
{ #category : #'as yet unclassified' }
SpSidebar >> buttons [
^ container items
]
{ #category : #initialization }
SpSidebar >> createDefaultPresenter [
^ self instantiate: SpSquareButton.
]
{ #category : #initialization }
SpSidebar >> initializeWidgets [
super initializeWidgets.
container := self instantiate: SpComponentListPresenter.
]
Class {
#name : #SpSidebar,
#superclass : #SpPresenter,
#instVars : [
'container'
],
#category : #'Grafoscopio-New-UI'
}
{ #category : #specs }
SpSidebar class >> defaultSpec [
^ SpBoxLayout newHorizontal
add: #container ;
yourself
]
{ #category : #initialization }
SpSidebar >> addAction: aBlock icon: anIcon [
container
addPresenter:
(self createDefaultPresenter
parent: self;
action: [ :state |
container unselectAll.
aBlock cull: state ];
icon: anIcon;
yourself)
]
{ #category : #'as yet unclassified' }
SpSidebar >> buttons [
^ container items
]
{ #category : #initialization }
SpSidebar >> createDefaultPresenter [
^ self instantiate: SpSquareButton.
]
{ #category : #initialization }
SpSidebar >> initializeWidgets [
super initializeWidgets.
container := self instantiate: SpComponentListPresenter.
]

View File

@ -1,52 +1,52 @@
Class {
#name : #SpSquareButton,
#superclass : #SpPresenter,
#instVars : [
'button',
'parent'
],
#category : #'Grafoscopio-New-UI'
}
{ #category : #specs }
SpSquareButton class >> defaultSpec [
^ SpBoxLayout newVertical
add: (SpBoxLayout newHorizontal add: #button width: 50; yourself) height: 50;
yourself
]
{ #category : #initialization }
SpSquareButton >> action: anAction [
button
action: [ :state |
state
ifTrue: [ parent buttons
reject: [ :b | b = self ]
thenDo: [ :b | b toggleOff ].
anAction cull: state ]
ifFalse: [ ] ]
]
{ #category : #initialization }
SpSquareButton >> icon: icon [
button icon: icon
]
{ #category : #initialization }
SpSquareButton >> initializeWidgets [
super initializeWidgets.
button := self newToggleButton
extent: 90 @ 50;
color: Color transparent;
yourself
]
{ #category : #'as yet unclassified' }
SpSquareButton >> parent: aSpSidebar [
parent := aSpSidebar
]
{ #category : #initialization }
SpSquareButton >> toggleOff [
button state: false.
]
Class {
#name : #SpSquareButton,
#superclass : #SpPresenter,
#instVars : [
'button',
'parent'
],
#category : #'Grafoscopio-New-UI'
}
{ #category : #specs }
SpSquareButton class >> defaultSpec [
^ SpBoxLayout newVertical
add: (SpBoxLayout newHorizontal add: #button width: 50; yourself) height: 50;
yourself
]
{ #category : #initialization }
SpSquareButton >> action: anAction [
button
action: [ :state |
state
ifTrue: [ parent buttons
reject: [ :b | b = self ]
thenDo: [ :b | b toggleOff ].
anAction cull: state ]
ifFalse: [ ] ]
]
{ #category : #initialization }
SpSquareButton >> icon: icon [
button icon: icon
]
{ #category : #initialization }
SpSquareButton >> initializeWidgets [
super initializeWidgets.
button := self newToggleButton
extent: 90 @ 50;
color: Color transparent;
yourself
]
{ #category : #'as yet unclassified' }
SpSquareButton >> parent: aSpSidebar [
parent := aSpSidebar
]
{ #category : #initialization }
SpSquareButton >> toggleOff [
button state: false.
]

View File

@ -1,6 +1,6 @@
Extension { #name : #Text }
{ #category : #'*Grafoscopio' }
Text >> allSegmentsOfLinesDo: aBlockClosure [
]
Extension { #name : #Text }
{ #category : #'*Grafoscopio' }
Text >> allSegmentsOfLinesDo: aBlockClosure [
]

View File

@ -1,9 +1,9 @@
Extension { #name : #TextPresenter }
{ #category : #'*Grafoscopio' }
TextPresenter >> beForGrafoscopio [
self
isCodeCompletionAllowed: true;
menuHolder: [ self getMenu ];
isForSmalltalkCode: true
]
Extension { #name : #TextPresenter }
{ #category : #'*Grafoscopio' }
TextPresenter >> beForGrafoscopio [
self
isCodeCompletionAllowed: true;
menuHolder: [ self getMenu ];
isForSmalltalkCode: true
]

View File

@ -1,17 +1,17 @@
Extension { #name : #TreePresenter }
{ #category : #'*Grafoscopio' }
TreePresenter >> selectedIndex [
^ selectedItem value
ifNil: [ 1 min: rootsHolder value size ]
ifNotNil: [ rootsHolder value indexOf: selectedItem value ]
]
{ #category : #'*Grafoscopio' }
TreePresenter >> selectedIndex: anInteger [
anInteger = 0
ifTrue: [ self resetSelection.
self highlightedItem: nil ]
ifFalse: [ self selectedItem: (rootsHolder value at: anInteger).
self highlightedItem: (rootsHolder value at: anInteger) ]
]
Extension { #name : #TreePresenter }
{ #category : #'*Grafoscopio' }
TreePresenter >> selectedIndex [
^ selectedItem value
ifNil: [ 1 min: rootsHolder value size ]
ifNotNil: [ rootsHolder value indexOf: selectedItem value ]
]
{ #category : #'*Grafoscopio' }
TreePresenter >> selectedIndex: anInteger [
anInteger = 0
ifTrue: [ self resetSelection.
self highlightedItem: nil ]
ifFalse: [ self selectedItem: (rootsHolder value at: anInteger).
self highlightedItem: (rootsHolder value at: anInteger) ]
]

View File

@ -1 +1 @@
Package { #name : #Grafoscopio }
Package { #name : #Grafoscopio }