Grafoscopio/src/Grafoscopio/GrafoscopioDockingBar.class.st

610 lines
19 KiB
Smalltalk

"
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 : #GrafoscopioDockingBar,
#superclass : #DynamicComposableModel,
#instVars : [
'windowMainMenu',
'tree',
'nodeHeader',
'nodeBody'
],
#classVars : [
'dockingBar',
'recentNotebooks'
],
#classInstVars : [
'dockingBar',
'recentNotebooks'
],
#category : #'Grafoscopio-UI'
}
{ #category : #specs }
GrafoscopioDockingBar class >> defaultSpec [
<spec: #default>
^ SpecLayout composed
newColumn: [ :mainWindow |
mainWindow
newRow: [:menu |
menu add: #windowMainMenu
] height: 35;
newRow: [:outlineView |
outlineView
newColumn: [ :treePart |
treePart
newRow: [:tree | tree add: #tree];
addSplitter;
newRow: [:nodeHeader | nodeHeader add: #nodeHeader] height: 30
] right: 0.7;
addSplitter;
newColumn: [ :nodePart |
nodePart add: #nodeBody] left: 0.3.
].
];
yourself
]
{ #category : #updating }
GrafoscopioDockingBar class >> docDataManual [
"I define some metadata associated to the manual document.
Language is provided according to the ISO 639-1 code convention."
| docData |
docData := Dictionary
with: 'type' -> 'manual'
with: 'languageCode' -> 'ES_CO'
with: 'remoteRepo' -> 'http://mutabit.com/repos.fossil/grafoscopio/'
with: 'relativePath' -> 'Docs/Es/Manual/'
with: 'filename' -> 'manual-grafoscopio.ston'.
^ docData
]
{ #category : #updating }
GrafoscopioDockingBar class >> docDataTutorial [
"I define some metadata associated to the tutorial document.
Language is provided according to the ISO 639-1 code convention."
| docData |
docData := Dictionary
with: 'type' -> 'tutorial'
with: 'languageCode' -> 'ES_CO'
with: 'remoteRepo' -> 'http://mutabit.com/repos.fossil/grafoscopio/'
with: 'relativePath' -> 'Docs/Es/Tutoriales/'
with: 'filename' -> 'tutorial.ston'.
^ docData
]
{ #category : #accessing }
GrafoscopioDockingBar class >> dockingBar [
^ dockingBar
]
{ #category : #accessing }
GrafoscopioDockingBar class >> dockingBar: anObject [
dockingBar := anObject
]
{ #category : #examples }
GrafoscopioDockingBar class >> exampleBootstrapDynamicUI1 [
"Starting from an example UI from the Spec-Glamour, to customize towards the grafoscopio
UI and get some ideas"
|notebook leftUpperPanel leftPanel treeBrowser |
"Creating a notebook-tree with dummy data"
notebook := GrafoscopioNode new becomeDefaultTestTree.
"Defining the tree roots part"
leftUpperPanel := DynamicComposableModel new.
leftUpperPanel instantiateModels: #(tree TreeModel).
leftUpperPanel tree
roots: notebook children;
childrenBlock: [:node | node children ];
displayBlock: [:node | node title ].
leftUpperPanel layout: (SpecLayout composed
add: #tree;
yourself).
"to debug upto here uncomment the next line, and comment all other 'openWithSpec' ones"
"leftUpperPanel openWithSpec."
"Integrating the previous tree with the node header and creating the body according to
the tags on the node"
leftPanel := DynamicComposableModel new.
leftPanel assign: leftUpperPanel to: #roots.
leftPanel instantiateModels: #(header TextInputFieldModel).
treeBrowser := DynamicComposableModel new.
leftUpperPanel tree
whenSelectedItemChanged: [:node |
node
ifNil:[
leftPanel header text: ''.
treeBrowser instantiateModels: #(body TextModel).
Transcript show: 'Nada que mostrar', String cr]
ifNotNil: [
leftPanel header text: (leftUpperPanel tree selectedItem content header).
leftUpperPanel tree selectedItem content tags = 'código'
ifTrue: [
treeBrowser instantiateModels: #(body GlamourPresentationModel).
Transcript show: 'I am code', String cr.
Transcript show: treeBrowser body asString, String cr.
]
ifFalse: [
treeBrowser instantiateModels: #(body TextModel).
treeBrowser body text: (leftUpperPanel tree selectedItem content body).
Transcript show: 'I am NOT code', String cr.
Transcript show: treeBrowser body asString, String cr.
]
]
].
leftPanel layout:
(SpecLayout composed
newColumn: [:column |
column
add: #roots;
add: #header height: 35];
yourself).
"Integrating the previous tree with node body content"
treeBrowser assign: leftPanel to: #leftTree.
treeBrowser layout:
(SpecLayout composed
newRow: [:r | r add: #leftTree; add: #body ];
yourself
).
treeBrowser openWithSpec.
]
{ #category : #examples }
GrafoscopioDockingBar class >> exampleBootstrapDynamicUI2 [
"Starting from an example UI from the Spec-Glamour, to customize towards the grafoscopio
UI and get some ideas"
|notebook leftUpperPanel leftPanel treeBrowser |
"Creating a notebook-tree with dummy data"
notebook := GrafoscopioNode new becomeDefaultTestTree.
"Defining the tree roots part"
leftUpperPanel := DynamicComposableModel new.
leftUpperPanel instantiateModels: #(tree TreeModel).
leftUpperPanel tree
roots: notebook children;
childrenBlock: [:node | node children ];
displayBlock: [:node | node title ].
leftUpperPanel layout: (SpecLayout composed
add: #tree;
yourself).
"to debug upto here uncomment the next line, and comment all other 'openWithSpec' ones"
"leftUpperPanel openWithSpec."
"Integrating the previous tree with the node header and creating the body according to
the tags on the node"
leftPanel := DynamicComposableModel new.
leftPanel assign: leftUpperPanel to: #roots.
leftPanel instantiateModels: #(header TextInputFieldModel).
treeBrowser := DynamicComposableModel new.
leftUpperPanel tree
whenSelectedItemChanged: [:node |
node
ifNil:[
leftPanel header text: ''.
treeBrowser instantiateModels: #(body TextModel).
Transcript show: 'Nada que mostrar', String cr]
ifNotNil: [
leftPanel header text: (leftUpperPanel tree selectedItem content header).
leftUpperPanel tree selectedItem content tags = 'código'
ifTrue: [
treeBrowser instantiateModels: #(body GlamourPresentationModel).
treeBrowser assign: leftPanel to: #leftTree.
treeBrowser layout:
(SpecLayout composed
newRow: [:r | r add: #leftTree; add: #body ];
yourself
).
Transcript show: 'I am code', String cr.
Transcript show: treeBrowser body asString, String cr.
]
ifFalse: [
treeBrowser instantiateModels: #(body TextModel).
treeBrowser body text: (leftUpperPanel tree selectedItem content body).
treeBrowser assign: leftPanel to: #leftTree.
treeBrowser layout:
(SpecLayout composed
newRow: [:r | r add: #leftTree; add: #body ];
yourself
).
Transcript show: 'I am NOT code', String cr.
Transcript show: treeBrowser body asString, String cr.
]
]
].
leftPanel layout:
(SpecLayout composed
newColumn: [:column |
column
add: #roots;
add: #header height: 35];
yourself).
"Integrating the previous tree with node body content"
treeBrowser openWithSpec.
]
{ #category : #examples }
GrafoscopioDockingBar class >> exampleBootstrapUI [
"Starting from an example UI from the Spec-Glamour, to customize towards the grafoscopio
UI and get some ideas"
|ui lay notebook |
ui := DynamicComposableModel new.
ui title: 'new | Grafoscopio'.
ui instantiateModels: #(
tree TreeModel
header TextInputFieldModel
bodyWhenMarkup TextModel
bodyWhenCode GlamourPresentationModel).
notebook := GrafoscopioNode new becomeDefaultTestTree.
ui tree
roots: notebook children;
childrenBlock: [:node | node children];
displayBlock: [:node | node title ].
lay := SpecLayout composed
newRow: [:row |
row
newColumn: [:column |
column
newRow: #tree top: 0.2;
addHSplitter;
newRow: #header bottom: 0.8] right: 0.7;
addVSplitter;
newColumn: #bodyWhenCode];
yourself.
ui openWithSpecLayout: lay.
]
{ #category : #'class initialization' }
GrafoscopioDockingBar class >> initialize [
self start.
]
{ #category : #'graphical interface' }
GrafoscopioDockingBar 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' }
GrafoscopioDockingBar 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 top bar menu option:',
(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' }
GrafoscopioDockingBar 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' }
GrafoscopioDockingBar class >> open [
^ self new open
]
{ #category : #'graphical interface' }
GrafoscopioDockingBar class >> openFromRecentlyUsed [
"Opens a recent notebooks list"
| selection |
self recentNotebooks
ifNotEmpty: [
selection := UIManager default chooseFrom: recentNotebooks title: 'Choose a notebook'.
selection > 0
ifTrue: [ GrafoscopioNotebook new openFromFile: (recentNotebooks at: selection)]
ifFalse: [ self inform: 'No notebook selected!' ]
]
ifEmpty: [self messageNoRecentDocuments]
]
{ #category : #accessing }
GrafoscopioDockingBar class >> recentNotebooks [
^ recentNotebooks ifNil: [recentNotebooks := OrderedCollection new ]
]
{ #category : #accessing }
GrafoscopioDockingBar class >> recentNotebooks: anOrderedCollection [
recentNotebooks := anOrderedCollection
]
{ #category : #configuration }
GrafoscopioDockingBar class >> showSettings [
"Shows the settings in a Transcript. This should return a dictionary for better management of the settings. For the moment
is a quick a dirty hack"
Transcript show: fossil; cr.
Transcript show: pandoc
]
{ #category : #'graphical interface' }
GrafoscopioDockingBar class >> start [
"Creates a custom docking bar for grafoscopio on top, for shorcuts to the most used actions,
and as a fixed place for asking for help, external tools and grafoscopio updates and about"
| launchMenu helpMenu updateMenu |
launchMenu := MenuMorph new.
launchMenu
add: 'New notebook' target: (GrafoscopioNotebook new) selector: #openDefault;
add: 'Notebook from file...' target: (GrafoscopioNotebook new) selector: #openFromFileSelector;
add: 'Notebook from Internet...' target: (GrafoscopioNotebook new) selector: #openFromUrlUI;
add: 'Recent notebooks...' target: self selector: #openFromRecentlyUsed;
add: 'Example notebooks...' target: self selector: #messageNotImplementedYet;
add: 'Roassal visualizations gallery' target: (RTExampleBrowser new) selector: #open;
add: 'Playground' target: (Smalltalk tools) selector: #openWorkspace;
add: 'Transcript' target: (Smalltalk tools) selector: #openTranscript.
updateMenu := MenuMorph new.
updateMenu
add: 'Grafoscopio' target: self selector: #updateGrafoscopioUI;
add: 'Documentation' target: GrafoscopioDocumentation selector: #updateAllUI;
add: 'DataViz package' target: self selector: #updateDatavizUI;
add: 'Notebooks places' target: GrafoscopioDocumentation selector: #updateDocsPlaceUI;
"add: 'Database engine' target: ExternalApp selector: #installSQLite32BitsUI;
add: 'Pandoc path' target: ExternalApp selector: #configurePandoc;
add: 'Fossil path' target: ExternalApp selector: #configureFossil;"
add: 'All the system' target: self selector: #updateSystem.
helpMenu := MenuMorph new.
helpMenu
add: 'Tutorial (Spanish)' target: GrafoscopioDocumentation selector: #openTutorial;
add: 'Manual' target: GrafoscopioDocumentation selector: #openManual;
add: 'Manual (PDF)' target: GrafoscopioDocumentation selector: #openPDFManual;
add: 'Dataviz' target: (DatavizDocs new) selector: #openIntroNotebook;
add: 'Dev''s notes' target: GrafoscopioDocumentation selector: #openDevNotes;
add: 'About Grafoscopio' target: self selector: #messageAbout.
dockingBar := DockingBarMorph new.
dockingBar
add: 'Launch' subMenu: launchMenu;
add: 'Update' subMenu: updateMenu;
add: 'Help' subMenu: helpMenu.
dockingBar
adhereToTop;
openInWorld.
]
{ #category : #updating }
GrafoscopioDockingBar class >> updateDataviz [
"I update the Dataviz package with new versions of itself take from the source code
repository.
DataViz contains Data visualization helpers"
Gofer it
smalltalkhubUser: 'Offray' project: 'Dataviz';
configurationOf: 'Dataviz';
load.
self inform: 'Dataviz package update finished.'
]
{ #category : #updating }
GrafoscopioDockingBar 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 }
GrafoscopioDockingBar class >> updateGrafoscopio [
"Updates Grafoscopio with new versions of itself take from the source code repository and
the User Interface"
Gofer new
smalltalkhubUser: 'Offray' project: 'Grafoscopio';
package: 'Grafoscopio';
load.
self updateUI.
]
{ #category : #updating }
GrafoscopioDockingBar 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.
self inform: 'Grafoscopio update finished'
]
{ #category : #updating }
GrafoscopioDockingBar 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 }
GrafoscopioDockingBar class >> updateRecentNotebooksWith: aFileReference [
(self recentNotebooks includes: aFileReference)
ifFalse: [self recentNotebooks add: aFileReference].
]
{ #category : #updating }
GrafoscopioDockingBar class >> updateSystem [
| tmp1 tmp2 |
tmp1 := UIManager default
question: 'Do you wish to update all Grafoscopio and its co-dependencies ?'
title: 'Grafoscopio update'.
tmp1
ifNotNil: [ tmp1
ifTrue: [ tmp2 := self.
tmp2
updateGrafoscopio;
updateDataviz.
GrafoscopioDocumentation updateAll.
self inform: 'System update finished.' ]]
]
{ #category : #updating }
GrafoscopioDockingBar 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 ].
]