Doing silly proof some UI stuff (as removing nodes, adding nodes etc) specially for me :D

This commit is contained in:
Santiago Bragagnolo 2020-02-20 12:03:33 +00:00 committed by Offray Luna
parent 1cc945c086
commit 4118724ab4
5 changed files with 138 additions and 173 deletions

View File

@ -0,0 +1,21 @@
Class {
#name : #GrafoscopioAbstractNode,
#superclass : #Object,
#instVars : [
'header',
'created',
'edited',
'selected',
'key',
'icon',
'body',
'tags',
'children',
'parent',
'node',
'nodesInPreorder',
'links',
'output'
],
#category : #'Grafoscopio-Model'
}

View File

@ -12,11 +12,10 @@ Class {
#name : #GrafoscopioNode,
#superclass : #Object,
#instVars : [
'id',
'header',
'headers',
'created',
'edited',
'selected',
'key',
'icon',
'body',
@ -24,9 +23,7 @@ Class {
'children',
'parent',
'node',
'nodesInPreorder',
'links',
'output'
'links'
],
#classInstVars : [
'clipboard'
@ -102,15 +99,19 @@ GrafoscopioNode >> addNode: aNode [
{ #category : #'add/remove nodes' }
GrafoscopioNode >> addNodeAfterMe [
"Adds a generic node after the given node so they become slibings of the same parent"
| genericNode |
genericNode := self class new
created: DateAndTime now printString;
header: 'newNode';
body: ''.
self parent children add: genericNode after: self.
genericNode parent: self parent.
self parent
ifNil: [
self children add: genericNode.
genericNode parent: self ]
ifNotNil: [ self parent children add: genericNode after: self.
genericNode parent: self parent ].
^ genericNode
]
{ #category : #accessing }
@ -203,6 +204,16 @@ GrafoscopioNode >> asStonFromRoot [
]
{ #category : #exporting }
GrafoscopioNode >> asTreeNodePresenter [
node := TreeNodePresenter new.
node
hasChildren: [ self children isNotEmpty ];
children: [ self children collect: [ :subNode | subNode asTreeNodePresenter ] ];
content: self.
^ node
]
{ #category : #accessing }
GrafoscopioNode >> body [
"Returns the receivers body"
@ -235,9 +246,15 @@ GrafoscopioNode >> bodyAsMarkdownInto: aStream [
self embeddedNodes ifNotNil: [ aStream nextPutAll: (self embedNodes contents asString withInternetLineEndings); crlf; crlf].
]
{ #category : #exporting }
GrafoscopioNode >> calculateLevel [
^ parent ifNil: [ 0 ] ifNotNil: [ 1 + parent calculateLevel ]
{ #category : #'add/remove nodes' }
GrafoscopioNode >> buildPreorderCollection: aCollection [
"Stores the current node in a collection and recursively stores its children"
aCollection add: self.
(self children isNotEmpty) & ((self header findString: '#invisible')=1) not
ifTrue: [ (self children) do: [ :eachNode | eachNode buildPreorderCollection: aCollection]].
]
{ #category : #operation }
@ -279,19 +296,9 @@ GrafoscopioNode >> children: aCollection [
children := aCollection.
]
{ #category : #accessing }
{ #category : #'as yet unclassified' }
GrafoscopioNode >> content [
"Returns the receivers body"
^ self body
]
{ #category : #accessing }
GrafoscopioNode >> content: anObject [
"Sets the receivers body to the given object"
body := anObject
^ body
]
{ #category : #'add/remove nodes' }
@ -406,13 +413,6 @@ GrafoscopioNode >> embeddedNodes [
^ self children select: [:each | each headerStartsWith: '%embed']
]
{ #category : #accessing }
GrafoscopioNode >> expanded: aBoolean [
"I tell if the node is expanded from the UI, showing my children.
Several nodes can be expanded in a single document."
selected := aBoolean
]
{ #category : #exporting }
GrafoscopioNode >> exportCodeBlockTo: aStream [
"I convert the content of a node taged as 'código' (code) as pandoc markdown and put it
@ -553,7 +553,7 @@ GrafoscopioNode >> headerStartsWith: aString [
{ #category : #accessing }
GrafoscopioNode >> headers [
"I returns the headers of the receiver children"
^ headers := self children collect: [:currentNode | currentNode header ]
^ self children collect: [:currentNode | currentNode header ]
]
{ #category : #operation }
@ -639,7 +639,10 @@ GrafoscopioNode >> initialize [
self
header: 'newHeader';
tagAs: 'text';
body: ''
body: ''.
id := UUID new.
created := DateAndTime now.
edited := DateAndTime now
]
{ #category : #accessing }
@ -713,14 +716,14 @@ GrafoscopioNode >> lastLink [
{ #category : #accessing }
GrafoscopioNode >> lastNetLink [
^ self links detect: [ :l | l asZnUrl isURL ]
^ self links detect: [ :l | l asZnUrl ]
]
{ #category : #accessing }
GrafoscopioNode >> level [
"Returns the level of the node. See the setter message for details"
^ self calculateLevel
^ parent ifNil: [ 0 ] ifNotNil: [ 1 + parent level ]
]
{ #category : #accessing }
@ -838,29 +841,33 @@ GrafoscopioNode >> metadataAsYamlIn: markdownStream [
]
{ #category : #movement }
GrafoscopioNode >> moveAfter [
GrafoscopioNode >> moveDown [
"Moves the current node a place before in the children collection where is located"
| collection index successor |
collection := self parent children.
index := collection indexOf: self.
(index between: 1 and: collection size - 1)
ifTrue: [
successor := collection after: self.
collection at: index + 1 put: self.
collection at: index put: successor]
self parent moveDown: self
]
{ #category : #movement }
GrafoscopioNode >> moveBefore [
GrafoscopioNode >> moveDown: aNode [
| index |
"Moves the current node a place before in the children collection where is located"
| collection index predecessor |
collection := self parent children.
index := collection indexOf: self.
(index between: 2 and: collection size)
ifTrue: [
predecessor := collection before: self.
collection at: index -1 put: self.
collection at: index put: predecessor]
index := children indexOf: aNode.
children swap: index with: (index + 1 min: children size)
]
{ #category : #movement }
GrafoscopioNode >> moveUp [
"Moves the current node a place before in the children collection where is located"
self parent moveUp: self
]
{ #category : #movement }
GrafoscopioNode >> 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 : #'instance creation' }
@ -883,11 +890,6 @@ GrafoscopioNode >> output [
evaluate
]
{ #category : #accessing }
GrafoscopioNode >> output: anObject [
output := anObject
]
{ #category : #utility }
GrafoscopioNode >> pandocOptions [
self metadata ifNil: [ ^ nil ].
@ -946,24 +948,10 @@ GrafoscopioNode >> pasteFromClipboard [
{ #category : #operation }
GrafoscopioNode >> preorderTraversal [
| nodesInPreorder |
nodesInPreorder := OrderedCollection new.
self visitedGoTo: nodesInPreorder.
^ nodesInPreorder.
]
{ #category : #'as yet unclassified' }
GrafoscopioNode >> preorderTraversalIndex [
"I tell which place I occupy in the tree children (without counting the root)."
| root |
root := self root.
root preorderTraversalRootChildren doWithIndex: [ :currentNode :index |
currentNode = self ifTrue: [^ index] ].
]
{ #category : #'as yet unclassified' }
GrafoscopioNode >> preorderTraversalRootChildren [
^ self root preorderTraversal allButFirst
self buildPreorderCollection: nodesInPreorder.
^ nodesInPreorder
]
{ #category : #movement }
@ -1061,18 +1049,6 @@ GrafoscopioNode >> selectMarkupSubtreesToExport [
^ (self root preorderTraversal) select: [ :each | each linksToMarkupFile ].
]
{ #category : #accessing }
GrafoscopioNode >> selected [
^ selected
]
{ #category : #accessing }
GrafoscopioNode >> selected: aBoolean [
"I tell if the node is selected from the UI.
Once other node is selected my value becomes false."
selected := aBoolean
]
{ #category : #accessing }
GrafoscopioNode >> specModelClass [
@ -1163,19 +1139,6 @@ GrafoscopioNode >> toggleCodeText [
ifTrue: [ ^ self tags replaceAll: 'código' with: 'text' ].
]
{ #category : #accessing }
GrafoscopioNode >> toggleSelected [
"I made the receiver the current selected node and deselect all other nodes."
| root previousSelection |
self isSelected ifTrue: [ ^ self ].
root := self root.
previousSelection := self preorderTraversalRootChildren at: (self detectSelectionIndex).
previousSelection selected: false.
self selected: true.
^ self.
]
{ #category : #operation }
GrafoscopioNode >> unsavedNodes [
"I collect all nodes that have changed after the last saving"
@ -1195,8 +1158,7 @@ GrafoscopioNode >> updateEditionTimestamp [
{ #category : #importing }
GrafoscopioNode >> uploadBodyFrom: fileLocator filteredFor: selectedLink [
(self linksFilters contains: selectedLink)
ifFalse: [ self body: fileLocator contents ]
self body: fileLocator contents
]
{ #category : #operation }
@ -1206,17 +1168,6 @@ GrafoscopioNode >> visitLastLink [
[WebBrowser openOn: self lastLink] fork
]
{ #category : #'add/remove nodes' }
GrafoscopioNode >> visitedGoTo: aCollection [
"Stores the current node in a collection and recursively stores its children"
aCollection add: self.
(self children isNotEmpty) & ((self header findString: '#invisible')=1) not
ifTrue: [ (self children) do: [ :eachNode | eachNode visitedGoTo: aCollection]].
]
{ #category : #'as yet unclassified' }
GrafoscopioNode >> wrapBodyLines [
"I convert the node body from HTML format to Pandoc's Markdown."

View File

@ -103,17 +103,6 @@ GrafoscopioNodeTest >> testInitializeIsOk [
self shouldnt: [ GrafoscopioNode new ] raise: Error
]
{ #category : #tests }
GrafoscopioNodeTest >> testNodeSelection [
| tree child1 |
tree := self newTestTree..
child1 := tree preorderTraversalRootChildren at: 1.
child1 selected: true.
self assert: tree detectSelectionIndex equals: 1
]
{ #category : #tests }
GrafoscopioNodeTest >> testPromoteNode [
| tree child1 child2 |
@ -180,16 +169,3 @@ GrafoscopioNodeTest >> testSanitizedLink [
self assert: (node sanitizeDefaultLink = 'https://docutopia.tupale.co/hackbo:hackbot') equals: true
]
{ #category : #tests }
GrafoscopioNodeTest >> testToggleNodeSelection [
"I verify that a selected node can be unchosen once a new selection has been done."
| tree testNode1 testNode2 |
tree := self newTestTree..
testNode1 := (tree preorderTraversalRootChildren at: 1) selected: true.
self assert: tree detectSelectionIndex equals: testNode1 preorderTraversalIndex.
testNode2 := (tree preorderTraversalRootChildren at: 2).
testNode2 toggleSelected.
self assert: tree detectSelectionIndex equals: testNode2 preorderTraversalIndex
]

View File

@ -87,7 +87,7 @@ GrafoscopioNotebook >> addCommandFrom: dictionary into: stream [
{ #category : #'editing nodes' }
GrafoscopioNotebook >> addNode [
self currentNodeContent addNodeAfterMe.
self currentNode addNodeAfterMe.
self notebookContent: notebook.
]
@ -148,6 +148,11 @@ GrafoscopioNotebook >> checksumForRootSubtree [
^ GrafoscopioUtils checksumFor: self workingFile
]
{ #category : #'as yet unclassified' }
GrafoscopioNotebook >> content [
self shouldBeImplemented.
]
{ #category : #'editing nodes' }
GrafoscopioNotebook >> copyNodeToClipboard [
tree highlightedItem content copyToClipboard.
@ -160,22 +165,25 @@ GrafoscopioNotebook >> createNewExample [
node0 := GrafoscopioNode new
created: DateAndTime now printString;
header: 'Arbol principal';
tagAs: 'código'.
tagAs: 'código';
yourself.
node1 := GrafoscopioNode new
created: DateAndTime now printString;
header: 'Node 1';
body: '';
tagAs: 'text'.
tagAs: 'text';
yourself.
node0 addNode: node1.
^ node0
]
{ #category : #operation }
GrafoscopioNotebook >> currentNode [
| currentNode |
currentNode := tree highlightedItem.
currentNode ifNil: [ ^ self ].
^ currentNode
^ tree highlightedItem
ifNil: [ notebook children
ifEmpty: [ notebook root ]
ifNotEmpty: [ notebook children first ] ]
ifNotNil: [ :v | v content ]
]
{ #category : #operation }
@ -568,7 +576,7 @@ GrafoscopioNotebook >> linksList [
{ #category : #utilities }
GrafoscopioNotebook >> listImagesUI [
ListModel new
ListPresenter new
title: 'Images files list';
items: self imagesList ;
openWithSpec
@ -613,18 +621,18 @@ GrafoscopioNotebook >> metadata [
]
{ #category : #'editing nodes' }
GrafoscopioNotebook >> moveNodeAfter [
GrafoscopioNotebook >> moveSelectedNodeDown [
| editedNode |
editedNode := tree selectedItem content.
editedNode moveAfter.
editedNode moveDown.
self notebookContent: notebook
]
{ #category : #'editing nodes' }
GrafoscopioNotebook >> moveNodeBefore [
GrafoscopioNotebook >> moveSelectedNodeUp [
| editedNode |
editedNode := tree highlightedItem content.
editedNode moveBefore.
editedNode moveUp.
self notebookContent: notebook
]
@ -664,16 +672,9 @@ GrafoscopioNotebook >> notebook: anObject [
{ #category : #api }
GrafoscopioNotebook >> notebookContent: aTree [
| nodeBlock |
nodeBlock:= [:gfcNode | |node|
node := TreeNodeModel new.
node
hasChildren: [ gfcNode children isNotEmpty ];
children: [ gfcNode children collect: [:subNode | nodeBlock value: subNode ]];
content: gfcNode].
tree roots: (aTree children collect:[ :gfcNode | nodeBlock value: gfcNode])
tree
roots: (aTree children collect: [ :gfcNode | gfcNode asTreeNodePresenter ]).
tree selectedIndex: (tree selectedIndex min: aTree children size)
]
{ #category : #initialization }
@ -916,14 +917,14 @@ GrafoscopioNotebook >> promoteNode [
{ #category : #'editing nodes' }
GrafoscopioNotebook >> removeNode [
| contentToDelete parentContent newSelectedContent children |
tree selectedItem
ifNil: [ ^ self inform: 'No node available or properly selected ' ].
contentToDelete := tree selectedItem content.
parentContent := contentToDelete parent.
children := parentContent children.
children size > 1
ifTrue: [
children last = contentToDelete
ifTrue: [ newSelectedContent := children at: (children size - 1) ]
]
ifTrue: [ children last = contentToDelete
ifTrue: [ newSelectedContent := children at: children size - 1 ] ]
ifFalse: [ newSelectedContent := parentContent ].
contentToDelete parent removeNode: contentToDelete.
self notebookContent: notebook
@ -1008,7 +1009,7 @@ GrafoscopioNotebook >> toggleCodeNode [
{ #category : #initialization }
GrafoscopioNotebook >> topBar [
^ MenuModel new
^ MenuPresenter new
addGroup: [ :group |
group
addItem: [ :item |
@ -1086,14 +1087,14 @@ GrafoscopioNotebook >> topBar [
name: nil;
description: 'Move node up';
icon: MendaIcons new arrowUpIcon;
action: [ self moveNodeBefore ] ].
action: [ self moveSelectedNodeUp ] ].
group
addItem: [ :item |
item
name: nil;
description: 'Move node down';
icon: MendaIcons new arrowDownIcon;
action: [ self moveNodeAfter ] ].
action: [ self moveSelectedNodeDown ] ].
group
addItem: [ :item |
item
@ -1207,7 +1208,6 @@ GrafoscopioNotebook >> updateBodyFor: aNodeContainer [
tree needRebuild: false.
body needRebuild: true.
aNode := aNodeContainer content.
aNode toggleSelected.
header text: aNode header.
body := self instantiate: aNode specModelClass new.
body content: aNode body.

View File

@ -0,0 +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) ]
]