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

This commit is contained in:
SantiagoBragagnolo 2020-02-20 12:03:33 +00:00
parent 9c7fb747f6
commit 23e763cd9c
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, #name : #GrafoscopioNode,
#superclass : #Object, #superclass : #Object,
#instVars : [ #instVars : [
'id',
'header', 'header',
'headers',
'created', 'created',
'edited', 'edited',
'selected',
'key', 'key',
'icon', 'icon',
'body', 'body',
@ -24,9 +23,7 @@ Class {
'children', 'children',
'parent', 'parent',
'node', 'node',
'nodesInPreorder', 'links'
'links',
'output'
], ],
#classInstVars : [ #classInstVars : [
'clipboard' 'clipboard'
@ -102,15 +99,19 @@ GrafoscopioNode >> addNode: aNode [
{ #category : #'add/remove nodes' } { #category : #'add/remove nodes' }
GrafoscopioNode >> addNodeAfterMe [ GrafoscopioNode >> addNodeAfterMe [
"Adds a generic node after the given node so they become slibings of the same parent" "Adds a generic node after the given node so they become slibings of the same parent"
| genericNode | | genericNode |
genericNode := self class new genericNode := self class new
created: DateAndTime now printString; created: DateAndTime now printString;
header: 'newNode'; header: 'newNode';
body: ''. body: ''.
self parent children add: genericNode after: self. self parent
genericNode parent: self parent. ifNil: [
self children add: genericNode.
genericNode parent: self ]
ifNotNil: [ self parent children add: genericNode after: self.
genericNode parent: self parent ].
^ genericNode ^ genericNode
] ]
{ #category : #accessing } { #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 } { #category : #accessing }
GrafoscopioNode >> body [ GrafoscopioNode >> body [
"Returns the receivers body" "Returns the receivers body"
@ -235,9 +246,15 @@ GrafoscopioNode >> bodyAsMarkdownInto: aStream [
self embeddedNodes ifNotNil: [ aStream nextPutAll: (self embedNodes contents asString withInternetLineEndings); crlf; crlf]. self embeddedNodes ifNotNil: [ aStream nextPutAll: (self embedNodes contents asString withInternetLineEndings); crlf; crlf].
] ]
{ #category : #exporting } { #category : #'add/remove nodes' }
GrafoscopioNode >> calculateLevel [ GrafoscopioNode >> buildPreorderCollection: aCollection [
^ parent ifNil: [ 0 ] ifNotNil: [ 1 + parent calculateLevel ] "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 } { #category : #operation }
@ -279,19 +296,9 @@ GrafoscopioNode >> children: aCollection [
children := aCollection. children := aCollection.
] ]
{ #category : #accessing } { #category : #'as yet unclassified' }
GrafoscopioNode >> content [ GrafoscopioNode >> content [
"Returns the receivers body" ^ body
^ self body
]
{ #category : #accessing }
GrafoscopioNode >> content: anObject [
"Sets the receivers body to the given object"
body := anObject
] ]
{ #category : #'add/remove nodes' } { #category : #'add/remove nodes' }
@ -406,13 +413,6 @@ GrafoscopioNode >> embeddedNodes [
^ self children select: [:each | each headerStartsWith: '%embed'] ^ 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 } { #category : #exporting }
GrafoscopioNode >> exportCodeBlockTo: aStream [ GrafoscopioNode >> exportCodeBlockTo: aStream [
"I convert the content of a node taged as 'código' (code) as pandoc markdown and put it "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 } { #category : #accessing }
GrafoscopioNode >> headers [ GrafoscopioNode >> headers [
"I returns the headers of the receiver children" "I returns the headers of the receiver children"
^ headers := self children collect: [:currentNode | currentNode header ] ^ self children collect: [:currentNode | currentNode header ]
] ]
{ #category : #operation } { #category : #operation }
@ -639,7 +639,10 @@ GrafoscopioNode >> initialize [
self self
header: 'newHeader'; header: 'newHeader';
tagAs: 'text'; tagAs: 'text';
body: '' body: ''.
id := UUID new.
created := DateAndTime now.
edited := DateAndTime now
] ]
{ #category : #accessing } { #category : #accessing }
@ -713,14 +716,14 @@ GrafoscopioNode >> lastLink [
{ #category : #accessing } { #category : #accessing }
GrafoscopioNode >> lastNetLink [ GrafoscopioNode >> lastNetLink [
^ self links detect: [ :l | l asZnUrl isURL ] ^ self links detect: [ :l | l asZnUrl ]
] ]
{ #category : #accessing } { #category : #accessing }
GrafoscopioNode >> level [ GrafoscopioNode >> level [
"Returns the level of the node. See the setter message for details" "Returns the level of the node. See the setter message for details"
^ self calculateLevel ^ parent ifNil: [ 0 ] ifNotNil: [ 1 + parent level ]
] ]
{ #category : #accessing } { #category : #accessing }
@ -838,29 +841,33 @@ GrafoscopioNode >> metadataAsYamlIn: markdownStream [
] ]
{ #category : #movement } { #category : #movement }
GrafoscopioNode >> moveAfter [ GrafoscopioNode >> moveDown [
"Moves the current node a place before in the children collection where is located" "Moves the current node a place before in the children collection where is located"
| collection index successor |
collection := self parent children. self parent moveDown: self
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]
] ]
{ #category : #movement } { #category : #movement }
GrafoscopioNode >> moveBefore [ GrafoscopioNode >> moveDown: aNode [
| index |
"Moves the current node a place before in the children collection where is located" "Moves the current node a place before in the children collection where is located"
| collection index predecessor | index := children indexOf: aNode.
collection := self parent children. children swap: index with: (index + 1 min: children size)
index := collection indexOf: self. ]
(index between: 2 and: collection size)
ifTrue: [ { #category : #movement }
predecessor := collection before: self. GrafoscopioNode >> moveUp [
collection at: index -1 put: self. "Moves the current node a place before in the children collection where is located"
collection at: index put: predecessor]
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' } { #category : #'instance creation' }
@ -883,11 +890,6 @@ GrafoscopioNode >> output [
evaluate evaluate
] ]
{ #category : #accessing }
GrafoscopioNode >> output: anObject [
output := anObject
]
{ #category : #utility } { #category : #utility }
GrafoscopioNode >> pandocOptions [ GrafoscopioNode >> pandocOptions [
self metadata ifNil: [ ^ nil ]. self metadata ifNil: [ ^ nil ].
@ -946,24 +948,10 @@ GrafoscopioNode >> pasteFromClipboard [
{ #category : #operation } { #category : #operation }
GrafoscopioNode >> preorderTraversal [ GrafoscopioNode >> preorderTraversal [
| nodesInPreorder |
nodesInPreorder := OrderedCollection new. nodesInPreorder := OrderedCollection new.
self visitedGoTo: nodesInPreorder. self buildPreorderCollection: nodesInPreorder.
^ 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
] ]
{ #category : #movement } { #category : #movement }
@ -1061,18 +1049,6 @@ GrafoscopioNode >> selectMarkupSubtreesToExport [
^ (self root preorderTraversal) select: [ :each | each linksToMarkupFile ]. ^ (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 } { #category : #accessing }
GrafoscopioNode >> specModelClass [ GrafoscopioNode >> specModelClass [
@ -1163,19 +1139,6 @@ GrafoscopioNode >> toggleCodeText [
ifTrue: [ ^ self tags replaceAll: 'código' with: 'text' ]. 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 } { #category : #operation }
GrafoscopioNode >> unsavedNodes [ GrafoscopioNode >> unsavedNodes [
"I collect all nodes that have changed after the last saving" "I collect all nodes that have changed after the last saving"
@ -1195,8 +1158,7 @@ GrafoscopioNode >> updateEditionTimestamp [
{ #category : #importing } { #category : #importing }
GrafoscopioNode >> uploadBodyFrom: fileLocator filteredFor: selectedLink [ GrafoscopioNode >> uploadBodyFrom: fileLocator filteredFor: selectedLink [
(self linksFilters contains: selectedLink) self body: fileLocator contents
ifFalse: [ self body: fileLocator contents ]
] ]
{ #category : #operation } { #category : #operation }
@ -1206,17 +1168,6 @@ GrafoscopioNode >> visitLastLink [
[WebBrowser openOn: self lastLink] fork [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' } { #category : #'as yet unclassified' }
GrafoscopioNode >> wrapBodyLines [ GrafoscopioNode >> wrapBodyLines [
"I convert the node body from HTML format to Pandoc's Markdown." "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 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 } { #category : #tests }
GrafoscopioNodeTest >> testPromoteNode [ GrafoscopioNodeTest >> testPromoteNode [
| tree child1 child2 | | tree child1 child2 |
@ -180,16 +169,3 @@ GrafoscopioNodeTest >> testSanitizedLink [
self assert: (node sanitizeDefaultLink = 'https://docutopia.tupale.co/hackbo:hackbot') equals: true 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' } { #category : #'editing nodes' }
GrafoscopioNotebook >> addNode [ GrafoscopioNotebook >> addNode [
self currentNodeContent addNodeAfterMe. self currentNode addNodeAfterMe.
self notebookContent: notebook. self notebookContent: notebook.
] ]
@ -148,6 +148,11 @@ GrafoscopioNotebook >> checksumForRootSubtree [
^ GrafoscopioUtils checksumFor: self workingFile ^ GrafoscopioUtils checksumFor: self workingFile
] ]
{ #category : #'as yet unclassified' }
GrafoscopioNotebook >> content [
self shouldBeImplemented.
]
{ #category : #'editing nodes' } { #category : #'editing nodes' }
GrafoscopioNotebook >> copyNodeToClipboard [ GrafoscopioNotebook >> copyNodeToClipboard [
tree highlightedItem content copyToClipboard. tree highlightedItem content copyToClipboard.
@ -160,22 +165,25 @@ GrafoscopioNotebook >> createNewExample [
node0 := GrafoscopioNode new node0 := GrafoscopioNode new
created: DateAndTime now printString; created: DateAndTime now printString;
header: 'Arbol principal'; header: 'Arbol principal';
tagAs: 'código'. tagAs: 'código';
yourself.
node1 := GrafoscopioNode new node1 := GrafoscopioNode new
created: DateAndTime now printString; created: DateAndTime now printString;
header: 'Node 1'; header: 'Node 1';
body: ''; body: '';
tagAs: 'text'. tagAs: 'text';
yourself.
node0 addNode: node1. node0 addNode: node1.
^ node0 ^ node0
] ]
{ #category : #operation } { #category : #operation }
GrafoscopioNotebook >> currentNode [ GrafoscopioNotebook >> currentNode [
| currentNode | ^ tree highlightedItem
currentNode := tree highlightedItem. ifNil: [ notebook children
currentNode ifNil: [ ^ self ]. ifEmpty: [ notebook root ]
^ currentNode ifNotEmpty: [ notebook children first ] ]
ifNotNil: [ :v | v content ]
] ]
{ #category : #operation } { #category : #operation }
@ -457,7 +465,7 @@ GrafoscopioNotebook >> imagesList [
{ #category : #accessing } { #category : #accessing }
GrafoscopioNotebook >> imagesList: anObject [ GrafoscopioNotebook >> imagesList: anObject [
self halt. self halt.
imagesList := anObject imagesList := anObject
] ]
@ -568,7 +576,7 @@ GrafoscopioNotebook >> linksList [
{ #category : #utilities } { #category : #utilities }
GrafoscopioNotebook >> listImagesUI [ GrafoscopioNotebook >> listImagesUI [
ListModel new ListPresenter new
title: 'Images files list'; title: 'Images files list';
items: self imagesList ; items: self imagesList ;
openWithSpec openWithSpec
@ -613,18 +621,18 @@ GrafoscopioNotebook >> metadata [
] ]
{ #category : #'editing nodes' } { #category : #'editing nodes' }
GrafoscopioNotebook >> moveNodeAfter [ GrafoscopioNotebook >> moveSelectedNodeDown [
| editedNode | | editedNode |
editedNode := tree selectedItem content. editedNode := tree selectedItem content.
editedNode moveAfter. editedNode moveDown.
self notebookContent: notebook self notebookContent: notebook
] ]
{ #category : #'editing nodes' } { #category : #'editing nodes' }
GrafoscopioNotebook >> moveNodeBefore [ GrafoscopioNotebook >> moveSelectedNodeUp [
| editedNode | | editedNode |
editedNode := tree highlightedItem content. editedNode := tree highlightedItem content.
editedNode moveBefore. editedNode moveUp.
self notebookContent: notebook self notebookContent: notebook
] ]
@ -664,16 +672,9 @@ GrafoscopioNotebook >> notebook: anObject [
{ #category : #api } { #category : #api }
GrafoscopioNotebook >> notebookContent: aTree [ GrafoscopioNotebook >> notebookContent: aTree [
tree
| nodeBlock | roots: (aTree children collect: [ :gfcNode | gfcNode asTreeNodePresenter ]).
nodeBlock:= [:gfcNode | |node| tree selectedIndex: (tree selectedIndex min: aTree children size)
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])
] ]
{ #category : #initialization } { #category : #initialization }
@ -916,14 +917,14 @@ GrafoscopioNotebook >> promoteNode [
{ #category : #'editing nodes' } { #category : #'editing nodes' }
GrafoscopioNotebook >> removeNode [ GrafoscopioNotebook >> removeNode [
| contentToDelete parentContent newSelectedContent children | | contentToDelete parentContent newSelectedContent children |
tree selectedItem
ifNil: [ ^ self inform: 'No node available or properly selected ' ].
contentToDelete := tree selectedItem content. contentToDelete := tree selectedItem content.
parentContent := contentToDelete parent. parentContent := contentToDelete parent.
children := parentContent children. children := parentContent children.
children size > 1 children size > 1
ifTrue: [ ifTrue: [ children last = contentToDelete
children last = contentToDelete ifTrue: [ newSelectedContent := children at: children size - 1 ] ]
ifTrue: [ newSelectedContent := children at: (children size - 1) ]
]
ifFalse: [ newSelectedContent := parentContent ]. ifFalse: [ newSelectedContent := parentContent ].
contentToDelete parent removeNode: contentToDelete. contentToDelete parent removeNode: contentToDelete.
self notebookContent: notebook self notebookContent: notebook
@ -1008,7 +1009,7 @@ GrafoscopioNotebook >> toggleCodeNode [
{ #category : #initialization } { #category : #initialization }
GrafoscopioNotebook >> topBar [ GrafoscopioNotebook >> topBar [
^ MenuModel new ^ MenuPresenter new
addGroup: [ :group | addGroup: [ :group |
group group
addItem: [ :item | addItem: [ :item |
@ -1086,14 +1087,14 @@ GrafoscopioNotebook >> topBar [
name: nil; name: nil;
description: 'Move node up'; description: 'Move node up';
icon: MendaIcons new arrowUpIcon; icon: MendaIcons new arrowUpIcon;
action: [ self moveNodeBefore ] ]. action: [ self moveSelectedNodeUp ] ].
group group
addItem: [ :item | addItem: [ :item |
item item
name: nil; name: nil;
description: 'Move node down'; description: 'Move node down';
icon: MendaIcons new arrowDownIcon; icon: MendaIcons new arrowDownIcon;
action: [ self moveNodeAfter ] ]. action: [ self moveSelectedNodeDown ] ].
group group
addItem: [ :item | addItem: [ :item |
item item
@ -1207,7 +1208,6 @@ GrafoscopioNotebook >> updateBodyFor: aNodeContainer [
tree needRebuild: false. tree needRebuild: false.
body needRebuild: true. body needRebuild: true.
aNode := aNodeContainer content. aNode := aNodeContainer content.
aNode toggleSelected.
header text: aNode header. header text: aNode header.
body := self instantiate: aNode specModelClass new. body := self instantiate: aNode specModelClass new.
body content: aNode body. 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) ]
]