Skip to content

Commit

Permalink
Merge pull request #873 from hernanmd/add_search_feature
Browse files Browse the repository at this point in the history
Add search feature
  • Loading branch information
jecisc authored Nov 7, 2024
2 parents e021b79 + b2e57fa commit f16af73
Show file tree
Hide file tree
Showing 9 changed files with 413 additions and 324 deletions.
38 changes: 32 additions & 6 deletions src/NewTools-SettingsBrowser/StSettingNode.class.st
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ Class {
'declaration',
'pragma',
'parentName',
'model'
'model',
'matchBlock'
],
#category : 'NewTools-SettingsBrowser-Model',
#package : 'NewTools-SettingsBrowser',
Expand Down Expand Up @@ -103,6 +104,12 @@ StSettingNode >> hasChildren [
^ self allChildren notEmpty
]

{ #category : 'testing' }
StSettingNode >> hasParent [

^ parentName notNil
]

{ #category : 'accessing' }
StSettingNode >> item [

Expand All @@ -121,11 +128,30 @@ StSettingNode >> label: aString [
declaration label: aString.
]

{ #category : 'testing' }
StSettingNode >> matches: aString [
"Answer <true> if aString matches any of the receiver's descriptors"

^ self label asLowercase beginsWithAnyOf: self descriptors
{ #category : 'accessing' }
StSettingNode >> matchBlock [

^ matchBlock
ifNil: [
matchBlock := [ : node : pattern |
node label substrings anySatisfy: [ : substr |
substr asLowercase beginsWith: pattern asLowercase ] ] ]
]

{ #category : 'enumerating' }
StSettingNode >> matches: aString [
"Recursive search the receiver for aString in its label"

| result |
result := OrderedCollection new.
self allChildren do: [ :node |
(self matchBlock value: node value: aString) ifTrue: [
result add: node ].

node hasChildren ifTrue: [
result addAll: (node matches: aString) ] ].

^ result
]

{ #category : 'accessing' }
Expand Down
11 changes: 0 additions & 11 deletions src/NewTools-SettingsBrowser/StSettingTreeBuilder.class.st
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,3 @@ StSettingTreeBuilder >> nodeClass [

^ StSettingNode
]

{ #category : 'private - tree building' }
StSettingTreeBuilder >> nodeClass: aClass name: aSymbol [
| node |
node := self nodeClass with: aClass new.
node item name: aSymbol.
node pragma: currentPragma.
node parentName: (currentParent ifNotNil: [currentParent name]).
self nodeList add: node.
^ (SettingNodeBuilder new) node: node; builder: self; yourself
]
18 changes: 18 additions & 0 deletions src/NewTools-SettingsBrowser/StSettingsAbstractPresenter.class.st
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,24 @@ Class {
#tag : 'UI'
}

{ #category : 'callbacks' }
StSettingsAbstractPresenter >> newNodePresenterFrom: aSettingNode level: anInteger [

| nodePresenter |

nodePresenter := self
instantiate: aSettingNode presenterClass
on: aSettingNode.
nodePresenter sectionTitleStyle: self sectionTitleString , anInteger asString.
^ nodePresenter
]

{ #category : 'callbacks' }
StSettingsAbstractPresenter >> sectionTitleString [

^ 'sectionTitleL'
]

{ #category : 'accessing' }
StSettingsAbstractPresenter >> settingsTree [
"Answer the receiver's <StSettingsTree>, the settings model"
Expand Down
297 changes: 297 additions & 0 deletions src/NewTools-SettingsBrowser/StSettingsDetailsPresenter.class.st
Original file line number Diff line number Diff line change
@@ -0,0 +1,297 @@
"
It represents a setting category page with setting sections and settings. The page was selected from `StSettingsCategoriesPresenter` and it matches a `StSettingsCategoryItemPresenter`.
"
Class {
#name : 'StSettingsDetailsPresenter',
#superclass : 'StSettingsAbstractPresenter',
#instVars : [
'pageTitle',
'settingDocPresenter',
'settingDocLabel',
'notebook',
'settingTree'
],
#category : 'NewTools-SettingsBrowser-UI',
#package : 'NewTools-SettingsBrowser',
#tag : 'UI'
}

{ #category : 'private' }
StSettingsDetailsPresenter >> activePage [

| selectedPage |

selectedPage := notebook selectedPage.
selectedPage activePresenter
ifNil: [ selectedPage retrievePresenter ].
^ selectedPage activePresenter
]

{ #category : 'callbacks - tabs' }
StSettingsDetailsPresenter >> addDefaultGeneralTabFrom: aStSettingNode [
"Private - Add General Settings default"

| generalSettingNode |

generalSettingNode := self newSettingNode.
generalSettingNode item name: self generalTitle.
generalSettingNode parentName: aStSettingNode name.
notebook addPage: (SpNotebookPage new
icon: (self iconNamed: #smallQuestion);
presenterProvider: [ StSettingsNotebookPageContentPresenter on: generalSettingNode ];
title: self generalTitle;
yourself).
]

{ #category : 'callbacks - tabs' }
StSettingsDetailsPresenter >> addHeaderForSettingsWithoutParent: aSpNotebookPage [
"Private - We add a 'General' header (2nd level) for those nodes without parent other than the root"

| generalSettingNode generalNodePresenter |

generalSettingNode := self newGeneralSetting: aSpNotebookPage.
generalNodePresenter := self
newSectionNodePresenterFrom: generalSettingNode
level: 2.
self activePage
add: generalNodePresenter
expand: false
]

{ #category : 'callbacks - tabs' }
StSettingsDetailsPresenter >> addSearchResultTabFrom: resultStSettingNodes [
"Private - Add a tab with search results from resultStSettingNodes in the receiver's notebook"

| rootSearchResultNode rsSettingNodes rsRootResultNode |

notebook hasPages ifTrue: [ notebook removeAll ].

rsSettingNodes := resultStSettingNodes copy asOrderedCollection.
"Create a new settings tree with the results"
rsRootResultNode := StSettingsTree new nodeList: rsSettingNodes; yourself.
"Create a new parent node "
rootSearchResultNode := self newSettingNode
parentName: 'Results';
model: rsRootResultNode;
yourself.

"Set the model of each result node"
rsSettingNodes do: [ : snc |
snc
parentName: rootSearchResultNode name;
model: rsRootResultNode ].

notebook addPage: (self newResultPageOn: rootSearchResultNode).
self selectFirstPage.


]

{ #category : 'callbacks - tabs' }
StSettingsDetailsPresenter >> addTabsFrom: aStSettingNode [

aStSettingNode allChildren do: [ :aSettingNode |
| nodePresenter |
(nodePresenter := self
instantiate: aSettingNode presenterClass
on: aSettingNode) hasChildren
ifTrue: [
nodePresenter sectionTitleStyle: self sectionTitleString.
notebook addPage: (SpNotebookPage new
icon: (self iconNamed: #smallQuestion);
presenterProvider: [ StSettingsNotebookPageContentPresenter on: aSettingNode ];
title: aSettingNode label;
yourself) ] ]
]

{ #category : 'initialization' }
StSettingsDetailsPresenter >> defaultInputPort [

^ SpModelPort newPresenter: self

]

{ #category : 'layout' }
StSettingsDetailsPresenter >> defaultLayout [

^ SpBoxLayout newTopToBottom
add: pageTitle expand: false;
add: (SpPanedLayout newVertical
positionOfSlider: 0.85;
add: notebook;
add: (SpBoxLayout newTopToBottom
spacing: 5;
add: settingDocLabel expand: false;
add: settingDocPresenter;
yourself);
yourself);
yourself
]

{ #category : 'callbacks - tabs' }
StSettingsDetailsPresenter >> generalTitle [

^ 'General'
]

{ #category : 'initialization' }
StSettingsDetailsPresenter >> initializePresenters [

pageTitle := self newLabel.
notebook := self newNotebook
whenSelectedPageChangedDo: [ :presenter | self updateSelectedPage: presenter ];
yourself.
settingDocLabel := self newLabel
addStyle: 'settingDocTitle';
yourself.
settingDocPresenter := self newText
]

{ #category : 'callbacks - tabs' }
StSettingsDetailsPresenter >> newGeneralSetting: aSpNotebookPage [

| currentParent generalSettingNode |

currentParent := aSpNotebookPage activePresenter parentNode.
generalSettingNode := StSettingNode with: PragmaSetting new.
generalSettingNode item name: self generalTitle.
generalSettingNode parentName: (currentParent ifNotNil: [ currentParent name ]).
^ generalSettingNode
]

{ #category : 'TOREMOVE' }
StSettingsDetailsPresenter >> newResultPageOn: aStSettingNode [

^ SpNotebookPage new
icon: (self iconNamed: #smallQuestion);
presenterProvider: [ self instantiate: StSettingsNotebookPageContentPresenter on: aStSettingNode ];
beCloseable;
title: self resultsTitle;
yourself
]

{ #category : 'callbacks' }
StSettingsDetailsPresenter >> newSectionNodePresenterFrom: aSettingNode level: anInteger [
"Private - This is a temporary method until finding a proper solution for 'hand-wired' sections, since some settings declarations are not grouped"

| nodePresenter |
nodePresenter := self
instantiate: StSettingSectionPresenter
on: aSettingNode.
nodePresenter sectionTitleStyle: self sectionTitleString , anInteger asString.
^ nodePresenter
]

{ #category : 'callbacks - tabs' }
StSettingsDetailsPresenter >> newSettingNode [

^ StSettingNode with: PragmaSetting new.
]

{ #category : 'initialization' }
StSettingsDetailsPresenter >> notebook [

^ notebook

]

{ #category : 'callbacks - tabs' }
StSettingsDetailsPresenter >> resultsTitle [

^ 'Results'
]

{ #category : 'callbacks' }
StSettingsDetailsPresenter >> selectFirstPage [

self notebook selectPageIndex: 1.
self updateSelectedPage: self notebook selectedPage.
]

{ #category : 'accessing - model' }
StSettingsDetailsPresenter >> setModel: aNode [
"Private - Set the receiver's content iterating recursively starting from aNode"

settingTree := aNode model childrenOf: aNode.
pageTitle
label: aNode label;
addStyle: 'pageTitle'.
notebook removeAll.
self updatePages: aNode.

]

{ #category : 'callbacks - tabs' }
StSettingsDetailsPresenter >> updatePages: aStSettingNode [
"Private - Recursively iterate aStSettingNode children using anInteger as 'level' indicator for title styling purposes"

self addDefaultGeneralTabFrom: aStSettingNode.
self addTabsFrom: aStSettingNode.
]

{ #category : 'callbacks' }
StSettingsDetailsPresenter >> updatePresenterGeneralNodes: aCollection [

| nodePresenter |
aCollection do: [ :settingNode |
nodePresenter := self newNodePresenterFrom: settingNode level: 2.
"Here the owner of each node presenter will be updated to a StSettingsNotebookPageContentPresenter"
self activePage add: nodePresenter expand: false ]
]

{ #category : 'callbacks' }
StSettingsDetailsPresenter >> updatePresenterTree: aStSettingNode level: anInteger [
"Private - Recursively iterate aStSettingNode children using anInteger as 'level' indicator for title styling purposes"

aStSettingNode allChildren do: [ :aSettingNode |
| nodePresenter |
nodePresenter := self
newNodePresenterFrom: aSettingNode
level: anInteger.
"The activePage here should be a StSettingsNotebookPageContentPresenter"
self activePage add: nodePresenter expand: false.
self updatePresenterTree: aSettingNode level: anInteger + 1 ].


]

{ #category : 'callbacks - tabs' }
StSettingsDetailsPresenter >> updateSelectedPage: aSpNotebookPage [
"Private - Update the receiver's notebook with aSpNotebookPage. The first time the notebook is opened, a #selectedPage event is triggered and aSpNotebookPage will be nil"

aSpNotebookPage ifNotNil: [
aSpNotebookPage activePresenter ifNotNil: [ : activePresenter | activePresenter removeAll ].
self updateSelectedSpecialCases: aSpNotebookPage.
self updateSelectedPageTree: aSpNotebookPage ]
]

{ #category : 'private' }
StSettingsDetailsPresenter >> updateSelectedPageTree: aSpNotebookPage [

| updatedPage |

updatedPage := aSpNotebookPage activePresenter
ifNil: [ aSpNotebookPage retrievePresenter ]
ifNotNil: [ aSpNotebookPage activePresenter ].

self updatePresenterTree: updatedPage parentNode level: 2
]

{ #category : 'callbacks - tabs' }
StSettingsDetailsPresenter >> updateSelectedSpecialCases: aSpNotebookPage [
"Do not add a 'General' header if we are already in the General tab"

aSpNotebookPage title = self resultsTitle
ifFalse: [
aSpNotebookPage title = self generalTitle
ifFalse: [ self addHeaderForSettingsWithoutParent: aSpNotebookPage ]
ifTrue: [ self updatePresenterGeneralNodes: (settingTree reject: [ : node | node hasChildren ]) ] ]
]

{ #category : 'callbacks' }
StSettingsDetailsPresenter >> updateSetting: labelString helpText: settingHelpString [

settingDocLabel label: labelString.
settingDocPresenter text: settingHelpString.
]
Loading

0 comments on commit f16af73

Please sign in to comment.