diff --git a/.gitignore b/.gitignore index 7181c34..6804441 100644 --- a/.gitignore +++ b/.gitignore @@ -16,11 +16,13 @@ gradle-app.setting # Addon maps *.addon.mm -version.properties *.mm.bak +# version.properties # ignore .jar files *.jar # ignore some folders ignoredByGitHub/ +delete/ + diff --git a/README-Tutorial-o-Matic-MDH.mm b/README-Tutorial-o-Matic-MDH.mm index e925ee6..dfbce35 100644 --- a/README-Tutorial-o-Matic-MDH.mm +++ b/README-Tutorial-o-Matic-MDH.mm @@ -3,14 +3,14 @@ - + - + @@ -20,7 +20,26 @@ - + +pre { + background-color: #e5e7ff; + border-left: 5px solid #ccc; + display: block; + padding: 8px; + margin: 5px; +} +code { + font-family: Consolas,"courier new"; + font-size: 11px; + color: #999; +} + +blockquote { + border-left: 5px solid #cccccc; + background-color: #eeeeee; + padding: 8px; +} + @@ -35,6 +54,27 @@ + + +pre { + background-color: #e5e7ff; + border-left: 5px solid #ccc; + display: block; + padding: 8px; + margin: 5px; +} +code { + font-family: Consolas,"courier new"; + font-size: 11px; + color: #999; +} + +blockquote { + border-left: 5px solid #cccccc; + background-color: #eeeeee; + padding: 8px; +} + @@ -63,7 +103,11 @@ - + + + + + @@ -118,8 +162,7 @@

- - + @@ -160,6 +203,7 @@ + @@ -174,16 +218,825 @@ = edofro.MarkDownHelper.MDH.list(node)

- - + + + + + + + +

+ = edofro.MarkDownHelper.MDH.webImageLink(node) +

+ +
+ + + + + + + + +

+ = edofro.MarkDownHelper.MDH.codeBlock(node) +

+ +
+ + + + + + +

+ import edofro.MarkDownHelper.MarkdownPreview +

+

+ +

+

+ new MarkdownPreview() +

+

+ +

+

+ def a = 5 +

+ +
+ + + + + + +

+ .groovy +

+ +
+
+
+ + =edofro.MarkDownHelper.MDH.plainTaskList(node) + + + + + + + + + + + + + + + + + + + +
+
+ + + + + + + + + + + + + + + + + +

+ = edofro.MarkDownHelper.MDH.document(node) +

+ +
+ + + + + + + + + + + + + + +

+ = edofro.MarkDownHelper.MDH.webLink(node) +

+ +
+ + + + + + + + +

+ = edofro.MarkDownHelper.MDH.webImageLink(node) +

+ +
+ + + + + + + + +

+ = edofro.MarkDownHelper.MDH.fileLink(node) +

+ +
+ + + + + + + + +

+ = edofro.MarkDownHelper.MDH.imageLink(node) +

+ +
+ + +
+ + + + + + + + + + + +

+ = edofro.MarkDownHelper.MDH.list(node) +

+ +
+ + + + + + + + + + + + + + + + +

+ 1. apples +

+

+ 1. bananas +

+

+ 1. oranges +

+

+ 1. lettuce +

+

+ 1. cucumber +

+

+ 1. tomatos +

+

+ 1. carrots +

+

+ +

+ +
+
+
+ + + + + + + + + + +

+ = edofro.MarkDownHelper.MDH.list(node) +

+ +
+ + + + + + + + + + + + + + + + + + + + + + +

+ = edofro.MarkDownHelper.MDH.list(node) +

+ +
+ + + + + + + +

+ = edofro.MarkDownHelper.MDH.webLink(node) +

+ +
+ + + + + + + + +

+ = edofro.MarkDownHelper.MDH.fileLink(node) +

+ +
+ + +
+ + + + + + + +

+ = edofro.MarkDownHelper.MDH.webImageLink(node) +

+ +
+ + + + + + + + +

+ = edofro.MarkDownHelper.MDH.imageLink(node) +

+ +
+ + +
+
+
+
+ + + + + + + + +

+ = edofro.MarkDownHelper.MDH.nestedTaskList(node) +

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + +

+ = edofro.MarkDownHelper.MDH.plainTaskList(node) +

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

+ = edofro.MarkDownHelper.MDH.table(node) +

+ +
+ + + + + + + + + + + + + + + + +

+ = edofro.MarkDownHelper.MDH.imageLink(node) +

+ +
+ + +
+ + + + + + + + + +

+ = edofro.MarkDownHelper.MDH.imageLink(node) +

+ +
+ + +
+ + + + + + + + + +

+ = edofro.MarkDownHelper.MDH.imageLink(node) +

+ +
+ + +
+ + + + + + + ![Bear.png](file:\C:\Users\Edo\Documents\GitHub\hello-world\resources\Animals%20Icons%20Set\Animals_png_small\mammals\Bear.png) + + + + + + + + + + + + +

+ = edofro.MarkDownHelper.MDH.codeBlock(node) +

+ +
+ + + + + + +

+ .groovy +

+ +
+ + + + + + +

+ // example code +

+

+ // the node's details must start with a dot and then the language of the code +

+

+ +

+

+ def text = node.text +

+

+ +

+

+ def msg = "the text of the selected node is ${text}" +

+

+ +

+

+ ui.informationMessage(msg.toString()) +

+ + +
+
+
+
+ + + + + + + +

+ = edofro.MarkDownHelper.MDH.textBlock(node) +

+ +
+ + + + + + +

+ The $1, the $2 and the $3 are from **$4** and can be found $5. +

+ +
+ + + + + + +

+ = edofro.MarkDownHelper.MDH.imageLink(node) +

+ +
+ + + + + + + + +

+ = edofro.MarkDownHelper.MDH.imageLink(node) +

+ +
+ + + + + + + + +

+ = edofro.MarkDownHelper.MDH.imageLink(node) +

+ +
+ + + + + + + + +

+ = edofro.MarkDownHelper.MDH.webLink(node) +

+ +
+ + + + + + + + +

+ = edofro.MarkDownHelper.MDH.webLink(node) +

+ +
+ + +
+
+
+ + + + + + + +

+ = edofro.MarkDownHelper.MDH.comment(node) +

+ +
+ + + + + + + +

+ = edofro.MarkDownHelper.MDH.textBlock(node) +

+ +
+ + + + + + +

+ The $3, the $1 and the $2 are from **$4** and can be found $5. +

+ +
+ + + + + + +

+ = edofro.MarkDownHelper.MDH.imageLink(node) +

+ +
+ + + + + + + + +

+ = edofro.MarkDownHelper.MDH.imageLink(node) +

+ +
+ + + + + + + + +

+ = edofro.MarkDownHelper.MDH.imageLink(node) +

+ +
+ + + + + + + + +

+ = edofro.MarkDownHelper.MDH.webLink(node) +

+ +
+ + + + + + + + +

+ = edofro.MarkDownHelper.MDH.webLink(node) +

+ +
+ + +
+
+ + + + + + +

+ = edofro.MarkDownHelper.MDH.table(node) +

+ +
+ + + + + + + + + + + + + + + + +

+ = edofro.MarkDownHelper.MDH.imageLink(node) +

+ +
+ + +
+ + + + + + + + + +

+ = edofro.MarkDownHelper.MDH.imageLink(node) +

+ +
+ + +
+ + + + + + + + + +

+ = edofro.MarkDownHelper.MDH.imageLink(node) +

+ +
+ + +
+
+
+
+ + + +
diff --git a/Tutorial-o-Matic/.gitignore b/Tutorial-o-Matic/.gitignore index e36dd13..e2a4a9f 100644 --- a/Tutorial-o-Matic/.gitignore +++ b/Tutorial-o-Matic/.gitignore @@ -16,8 +16,8 @@ gradle-app.setting # Addon maps *.addon.mm -version.properties *.mm.bak +# version.properties # ignore .jar files *.jar \ No newline at end of file diff --git a/Tutorial-o-Matic/Tutorial-o-Matic.mm b/Tutorial-o-Matic/Tutorial-o-Matic.mm index d64988d..8ae8619 100644 --- a/Tutorial-o-Matic/Tutorial-o-Matic.mm +++ b/Tutorial-o-Matic/Tutorial-o-Matic.mm @@ -1,14 +1,14 @@ - + - + - + @@ -44,7 +44,7 @@ - + @@ -163,15 +163,18 @@

- + - + - + + + + @@ -289,6 +292,9 @@ For each menu item with an icon add an attribute with the icon key (use develope + + + @@ -548,6 +554,9 @@ For each menu item with an icon add an attribute with the icon key (use develope

+ + + @@ -579,7 +588,7 @@ For each menu item with an icon add an attribute with the icon key (use develope - + @@ -590,10 +599,11 @@ For each menu item with an icon add an attribute with the icon key (use develope .groovy

- abre tutorial indicado en primer nodo hijo + opens tutorial defined in first child node

-
+ + diff --git a/Tutorial-o-Matic/build.gradle b/Tutorial-o-Matic/build.gradle index 338c73a..45f7bf1 100644 --- a/Tutorial-o-Matic/build.gradle +++ b/Tutorial-o-Matic/build.gradle @@ -1,10 +1,12 @@ +//Tutorial-o-Matic + apply plugin: 'groovy' targetCompatibility='1.8' libsDirName = "${rootDir}/lib" //clean.doFirst { delete "${rootDir}/lib" } // para eliminar todas las .jar -clean.doFirst { delete "${rootDir}/lib/Tutorial-o-Matic.jar" } //para eliminar sólo una de las .jar y que no me borrara markedj ni jsoup +clean.doFirst { delete "${rootDir}/lib/Tutorial-o-Matic.jar" } //para eliminar sólo una de las .jar y que no me borrara markedj ni jsoup repositories { mavenCentral() @@ -14,16 +16,16 @@ repositories { "C:/Program Files/Freeplane/core/org.freeplane.core/lib", "C:/Program Files/Freeplane/plugins/org.freeplane.plugin.script/lib", // "C:/Program Files/Freeplane/plugins/org.freeplane.plugin.markdown/lib", // para incluir markedj.jar - "${rootDir}/lib" //ahí puse markedj y jsoup + "${rootDir}/lib" //ahí puse markedj y jsoup ] - // Así para cuando Freeplane está en Portable Apps + // Así para cuando Freeplane está en Portable Apps // dirs: [ // "C:/PortableApps/FreeplanePortable/App/Freeplane", // "C:/PortableApps/FreeplanePortable/App/Freeplane/core/org.freeplane.core/lib", // "C:/PortableApps/FreeplanePortable/App/Freeplane/plugins/org.freeplane.plugin.script/lib", - // "${rootDir}/lib" //así lo usé en wikdshellext, porque ahí puse WikdShell.jar + // "${rootDir}/lib" //así lo usé en wikdshellext, porque ahí puse WikdShell.jar // ] } diff --git a/Tutorial-o-Matic/images/tutorialOMatic-icon.svg b/Tutorial-o-Matic/images/tutorialOMatic-icon.svg new file mode 100644 index 0000000..bb0d461 --- /dev/null +++ b/Tutorial-o-Matic/images/tutorialOMatic-icon.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/Tutorial-o-Matic/images/tutorialOMatic-screenshot-1.png b/Tutorial-o-Matic/images/tutorialOMatic-screenshot-1.png new file mode 100644 index 0000000..f0c6702 Binary files /dev/null and b/Tutorial-o-Matic/images/tutorialOMatic-screenshot-1.png differ diff --git a/Tutorial-o-Matic/images/tutorialOMatic.svg b/Tutorial-o-Matic/images/tutorialOMatic.svg new file mode 100644 index 0000000..f6f3629 --- /dev/null +++ b/Tutorial-o-Matic/images/tutorialOMatic.svg @@ -0,0 +1 @@ + diff --git a/Tutorial-o-Matic/scripts/ToMDemo.groovy b/Tutorial-o-Matic/scripts/ToMDemo.groovy index b1eedfe..fbd88fd 100644 --- a/Tutorial-o-Matic/scripts/ToMDemo.groovy +++ b/Tutorial-o-Matic/scripts/ToMDemo.groovy @@ -1,13 +1,16 @@ import edofro.tutorialomatic.ToM_ui as tomui import edofro.tutorialomatic.ToM as tom -//opens tutorial map -def sep = File.separator -def userDir = c.userDirectory.path -def mapFileName = "SimpleTutorialSample.mm" -def pathName = userDir + sep + "doc" + sep + "Tutorial-o-Matic" + sep + mapFileName -def tutMap = tom.getMapFromPath(pathName, false) //usar mapa indicado (pero oculto) +//region: opens tutorial map -tom.showTutorials( tutMap ) + def sep = File.separator + def userDir = c.userDirectory.path + def mapFileName = "SimpleTutorialSample.mm" + def pathName = userDir + sep + "doc" + sep + "Tutorial-o-Matic" + sep + mapFileName + def tutMap = tom.getMapFromPath(pathName, false) //usar mapa indicado (pero oculto) -return 'tutorial started' + tom.showTutorials( tutMap ) + + return 'tutorial started' + +//end: diff --git a/Tutorial-o-Matic/scripts/openDemoMap.groovy b/Tutorial-o-Matic/scripts/openDemoMap.groovy index 4b1235e..4347328 100644 --- a/Tutorial-o-Matic/scripts/openDemoMap.groovy +++ b/Tutorial-o-Matic/scripts/openDemoMap.groovy @@ -1,14 +1,22 @@ //opens demo map -def mapFile = "SimpleTutorialSample.mm" -def dir = c.userDirectory.path -def sep = File.separator -def helpFile = "Tutorial-o-Matic" + sep + mapFile -def pathName = dir + sep + "doc" + sep + helpFile +//region: defining path + def mapFile = "SimpleTutorialSample.mm" + def dir = c.userDirectory.path + def sep = File.separator + def helpFile = "Tutorial-o-Matic" + sep + mapFile + def pathName = dir + sep + "doc" + sep + helpFile +// end: +//region: opening mindmap file + if(exists(pathName)){ + c.mapLoader(pathName).withView().load() + } +//end: -if(exists(pathName)){ - c.mapLoader(pathName).withView().load() -} -def exists(String path){new File(path).isFile()} +//region: methods + + def exists(String path){new File(path).isFile()} + +//end: diff --git a/Tutorial-o-Matic/src/main/groovy/CustomComponentListener.groovy b/Tutorial-o-Matic/src/main/groovy/CustomComponentListener.groovy deleted file mode 100644 index 6b7cf6d..0000000 --- a/Tutorial-o-Matic/src/main/groovy/CustomComponentListener.groovy +++ /dev/null @@ -1,27 +0,0 @@ -package edofro.tutorialomatic - -//import edofro.tutorialomatic.TabPane -import edofro.tutorialomatic.ToM_ui as tomui - -import java.awt.event.* - - - -class CustomComponentListener implements ComponentListener { - public void componentResized(ComponentEvent e) { //https://docs.oracle.com/javase/8/docs/api/java/awt/event/ComponentEvent.html - def comp = e.component - //ToM_ui.resizeContentPanel(comp, tomui.maxContentPaneHeigth) - sleep(100) - ToM_ui.resizeContentPanel(comp, comp.height + 500) - // TabPane.repaint() - } - public void componentMoved(ComponentEvent e) { - // e.source.title = " moved. " - } - public void componentShown(ComponentEvent e) { - // e.source.title = " shown. " - } - public void componentHidden(ComponentEvent e) { - // e.getSource().title = " hidden. " - } -} \ No newline at end of file diff --git a/Tutorial-o-Matic/src/main/groovy/TabPane.groovy b/Tutorial-o-Matic/src/main/groovy/TabPane.groovy index 77586a8..4e80c67 100644 --- a/Tutorial-o-Matic/src/main/groovy/TabPane.groovy +++ b/Tutorial-o-Matic/src/main/groovy/TabPane.groovy @@ -4,8 +4,12 @@ import org.freeplane.core.ui.components.UITools as ui import org.freeplane.core.util.MenuUtils as menuUtils class TabPane{ +//region: properties def static tabPane = ui.freeplaneTabbedPanel +//end: + +//region: methods def static removeTab(String tabName, boolean hideTabPane = false){ def index = tabPane.indexOfTab(tabName) @@ -21,7 +25,7 @@ class TabPane{ return true } else return false } - + def static showTab(String tabName){ //if tabPanel is not showing --> show if(!tabPane.isShowing()) { @@ -33,7 +37,7 @@ class TabPane{ tabPane.previousTab = previousTab } else { tabPane.metaClass.previousTab = previousTab - } + } // look if tab exists def index = tabPane.indexOfTab(tabName) if (index>=0) { @@ -41,16 +45,16 @@ class TabPane{ return true } else return false } - + def static addTab(String tabName, componente){ tabPane.addTab(tabName, componente) } - + def static hasTab(String tabName){ def index = tabPane.indexOfTab(tabName) return ( index >= 0 ) } - + def static getTab(String tabName){ def index = tabPane.indexOfTab(tabName) if (index>=0) { @@ -59,9 +63,9 @@ class TabPane{ return null } } - + def static repaint(){ tabPane.repaint() } - +//end: } \ No newline at end of file diff --git a/Tutorial-o-Matic/src/main/groovy/ToM.groovy b/Tutorial-o-Matic/src/main/groovy/ToM.groovy index 248c532..54ee7f4 100644 --- a/Tutorial-o-Matic/src/main/groovy/ToM.groovy +++ b/Tutorial-o-Matic/src/main/groovy/ToM.groovy @@ -11,11 +11,14 @@ import org.freeplane.plugin.script.proxy.ScriptUtils class ToM{ - + // region: properties - + // this region has all the properties for the ToM class + + static final String version = '0.0.4' static final c = ScriptUtils.c() static final String tabName = 'Tutorial' + static final String idDictStorage = 'ToM_idDictionary' static final Map styles = [ tutorial : 'ToM-Tutorial' , @@ -32,13 +35,15 @@ class ToM{ select : 'ToM_select' , openMap : 'ToM_openMap' , openTutMap: 'ToM_openTutMap', + showNode : 'ToM_showNode' , ] - + static final exeHowIcons = ['emoji-1F507', 'emoji-2328', 'emoji-1F5B1'] - + // end: - + // region: getting tutorial components nodes + //The methods in this region get the nodes from the mindmap that contain the information needed to build the tutorial def static getNextTutNodes(n, boolean included = false){ def tutNodes = getTutNodes(getTutorialNode(n)) @@ -58,11 +63,14 @@ class ToM{ def static getNewPageNodes(nTutorial){ return nTutorial.find{it.style.name == styles.newPage} } - + // end: - + // region: loop fill contentPane + // this region contains the methods that loop over the "tutorial nodes" and builds a tutorial page + def static fillContentPane(myPanel, nextTutNodes, boolean doClear = true){ + def options = tomui.tomMarkedjOptions() def interruptLoop = false def startingNewPage = true if(doClear) myPanel.removeAll() @@ -70,7 +78,7 @@ class ToM{ for (tutNode in nextTutNodes){ switch(tutNode.style.name){ case styles.note: - addNotes(myPanel, tutNode.children) + addNotes(myPanel, tutNode.children, options) break case styles.nextPage: addNextPagePane(myPanel, tutNode, false) @@ -91,10 +99,10 @@ class ToM{ addTOCPane(myPanel, tutNode) break case styles.goto: - addGotoPane(myPanel, tutNode.children) + addGotoPane(myPanel, tutNode.children, nextTutNodes[0], options) break case styles.action: - addActionPane(myPanel, tutNode) + addActionPane(myPanel, tutNode, options) break case styles.groovy: addGroovyPane(myPanel, tutNode) @@ -106,11 +114,14 @@ class ToM{ addSelectPane(myPanel, tutNode) break case styles.openMap: - addOpenMapPane(myPanel, tutNode) + addOpenMapPane(myPanel, tutNode, options) break case styles.openTutMap: addInspectPane(myPanel, tutNode) break + case styles.showNode: + addShowNodePane(myPanel, tutNode) + break default: ui.informationMessage('node style not defined') break @@ -121,24 +132,25 @@ class ToM{ if(!interruptLoop) addNextPagePane(myPanel, nextTutNodes[-1], false, false) tomui.adjustHeight(myPanel, doClear) } - + def static fillPage(myP, nodo, included, doClear){ def nextNodes = getNextTutNodes(nodo, included) fillContentPane(myP, nextNodes, doClear) } - + // end: - - // region: components nodes to tutorial - - def static addNotes(myP, nodos){ + + // region: adding tutorial components nodes as contentPanes to tutorial tab + //methods that create the contentPanes used to build a tutorial page + + def static addNotes(myP, nodos, options){ nodos.each{n -> if(n.note) { - myP.add(tomui.createInstructionsPane(n), tomui.GBC) + myP.add(tomui.createInstructionsPane(n, options), tomui.GBC) } } } - + def static addPageTitle(myP, String texto){ def html = "

${texto}

" myP.add(tomui.createInstructionsPane(html), tomui.GBC) @@ -151,17 +163,17 @@ class ToM{ def static addNextPagePane(myP, lastNode, boolean included = false, boolean showNextButton = true){ def closeLabel = 'Stop tutorial' def closeToolTip = 'Click to stop the tutorial and close the tutorial tab' - def nextLabel = 'Next page' - def nextToolTip = 'Click to continue to the next page of the tutorial' - def bttnAction = showNextButton? { e -> fillPage(myP, lastNode, included, true) } : null + def nextLabel = showNextButton?'Next page':'Show tutorials' + def nextToolTip = showNextButton?'Click to continue to the next page of the tutorial':'Click to see the list of tutorials' + def bttnAction = showNextButton? { e -> fillPage(myP, lastNode, included, true) } : { e -> showTutorials(lastNode.mindMap) } def tocLabel = 'Table of Contents' def tocToolTip = 'Click to show the Table of Contents of the tutorial' def tocBttnAction = { e -> showTOC(myP,lastNode) } - - def nextButtonPanel = tomui.getNextButtonPanel(tabName, closeLabel, closeToolTip, nextLabel, nextToolTip , bttnAction, tocLabel, tocToolTip, tocBttnAction) + + def nextButtonPanel = tomui.createNextButtonPanel(tabName, closeLabel, closeToolTip, nextLabel, nextToolTip , bttnAction, tocLabel, tocToolTip, tocBttnAction) myP.add(nextButtonPanel, tomui.GBC) } - + def static addShowMenuItemPane(myP, nodos){ nodos.findAll{n -> toma.hasAction(n)}.each{nodo -> def infoAccion = toma.getActionInfoMap(nodo) @@ -184,8 +196,8 @@ class ToM{ if(! tomui.anyCompPending(myP) ) tomui.setNextPagePanelEnabled(myP, true) } } - - def buttonPanel = tomui.getButtonPanel(msgHtml,bttnText,bttnToolTip, bttnAction, true) + + def buttonPanel = tomui.createButtonPanel(msgHtml,bttnText,bttnToolTip, bttnAction, true) buttonPanel.metaClass.pending = false myP.add(buttonPanel, tomui.GBC) } else { @@ -193,80 +205,36 @@ class ToM{ myP.add(tomui.createInstructionsPane(textoHtml), tomui.GBC) } } - } - - def static showTOC(myP,nodo){ - myP.removeAll() - tomui.resizeContentPanel(myP,tomui.maxContentPaneHeigth) - addTOCPane(myP,nodo) - tomui.adjustHeight(myP, true) - } - - def static addTOCPane(myP,nodo){ - def titleNodes = getNewPageNodes(getTutorialNode(nodo)) - def pane = tomui.createEmptyGridBagPanel() - titleNodes.each{ tn -> - def title = tn.text - def bttnAction = { e -> fillPage(myP, tn, true, true) } - def button = tomui.createButton(title, bttnAction) - pane.add(button, tomui.GBC) - } - myP.add(pane, tomui.GBC) - } - - def static showTutorials(mapa){ - def myP = tomui.getContentPaneFromMyTab(tabName, true) - myP.removeAll() - tomui.resizeContentPanel(myP,tomui.maxContentPaneHeigth) - addTutorialsPane(myP, mapa) - tomui.adjustHeight(myP, true) } - def static addTutorialsPane(myP, mapa){ - def nodosTutoriales = mapa.root.find{it.style.name == styles.tutorial} - if ( nodosTutoriales.size() != 1 ){ - def pane = tomui.createEmptyGridBagPanel() - def pre = nodosTutoriales.size() == 0 ? "No t" : "T" - addPageTitle(myP, "${pre}utorials present in '${mapa.name}' map".toString()) - nodosTutoriales.each{ nT -> - def title = nT.text - def bttnAction = { e -> - def tutNodes = getTutNodes(nT) - if(tutNodes) { - fillContentPane(myP, tutNodes) - } else { - ui.informationMessage( "no tutorial components(nodes) found for tutorial '${nT.text}'".toString() ) - } - } - def button = tomui.createButton(title, bttnAction) - pane.add(button, tomui.GBC) - } - def stopButton = tomui.createButton('Exit tutorial', {tomui.closeTab(tabName)}) - pane.add(stopButton, tomui.GBC) - myP.add(pane, tomui.GBC) - } else { - def nT = nodosTutoriales[0] - def tutNodes = getTutNodes(nT) - if(tutNodes) { - fillContentPane(myP, tutNodes) - } else { - ui.informationMessage( "no tutorial components(nodes) found for tutorial '${nT.text}'".toString() ) - } - } - } - - def static addGotoPane(myP, nodos){ + def static addGotoPane(myP, nodos, backNode, options){ nodos.findAll{n -> n.link.node?true:false}.each{nodo -> - def targetNode = nodo.link.node - def msgHtml = nodo.note?tomui.getHtmlFromNote(nodo):null - def bttnText = nodo.text - def bttnToolTip = "Click to go to '${bttnText}' section" - def bttnAction = { e -> fillPage(myP, targetNode, true, true) } - def buttonPanel = tomui.getButtonPanel(msgHtml,bttnText,bttnToolTip, bttnAction, false) + def targetNode = nodo.link.node + def msgHtml = nodo.note?tomui.getHtmlFromNote(nodo, options):null + def bttnText = nodo.text + def bttnToolTip = "Click to go to '${bttnText}' section" + def bttnAction = { e -> gotoAction(myP, targetNode, backNode) } + def buttonPanel = tomui.createButtonPanel(msgHtml,bttnText,bttnToolTip, bttnAction, false) myP.add(buttonPanel, tomui.GBC) } } + def static gotoAction(myP,targetNode, backNode){ + myP.removeAll() + addReturnPane(myP, backNode) + fillPage(myP, targetNode, true, false) + addReturnPane(myP, backNode) + } + + def static addReturnPane(myP, backNode){ + def msgHtml = "Return to '${backNode.text}' page" + def bttnText = 'go back' + def bttnToolTip = "Click to go to '${backNode.text}' section" + def bttnAction = { e -> fillPage(myP, backNode, true, true)} + def buttonPanel = tomui.createButtonPanel(msgHtml,bttnText,bttnToolTip, bttnAction, false) + myP.add(buttonPanel, tomui.GBC) + } + def static addGroovyPane(myP, nodoT){ def enabled = !disableBttn(nodoT) nodoT.children.findAll{n -> WSE.isGroovyNode(n)}.each{nodo -> @@ -281,8 +249,8 @@ class ToM{ bttn.setEnabled(enabled) c.script(scrText, "groovy").executeOn(c.selected) } - - def buttonPanel = tomui.getButtonPanel(msgHtml,bttnText,bttnToolTip, bttnAction, false) + + def buttonPanel = tomui.createButtonPanel(msgHtml,bttnText,bttnToolTip, bttnAction, false) buttonPanel.metaClass.pending = false myP.add(buttonPanel, tomui.GBC) } else { @@ -291,22 +259,22 @@ class ToM{ } } } - - def static getGroovyHtml(nodo, script){ - def showScript = nodo.icons.icons.contains('emoji-1F50D') - uiMsg("showScript ${showScript}") - def html = showScript? tomui.getHtmlFromGroovyNode(nodo, script) : nodo.text - uiMsg("html ${html}") - return html - } - - def static addActionPane(myP, nodo){ + + def static getGroovyHtml(nodo, script){ + def showScript = nodo.icons.icons.contains('emoji-1F50D') + uiMsg("showScript ${showScript}") + def html = showScript? tomui.getHtmlFromGroovyNode(nodo, script) : nodo.text + uiMsg("html ${html}") + return html + } + + def static addActionPane(myP, nodo, options){ def infoAcciones = [] nodo.children.findAll{n -> toma.hasAction(n)}.each{n -> def infoAccion = toma.getActionInfoMap(n) - infoAcciones << infoAccion + infoAcciones << infoAccion } - def msgHtml = nodo.note?tomui.getHtmlFromNote(nodo):null + def msgHtml = nodo.note?tomui.getHtmlFromNote(nodo, options):null def bttnText = 'Execute' def bttnToolTip = "Click to execute the command on the selected nodes" def enabled = !disableBttn(nodo) @@ -317,25 +285,25 @@ class ToM{ toma.executeActions(infoAcciones, exeHow) } - def buttonPanel = ToM_ui.getButtonPanel(msgHtml,bttnText,bttnToolTip, bttnAction, false) + def buttonPanel = ToM_ui.createButtonPanel(msgHtml,bttnText,bttnToolTip, bttnAction, false) myP.add(buttonPanel, tomui.GBC) } - - def static exeActionsHow(nodo){ - def iconos = nodo.icons.icons - def iconitos = iconos.intersect(exeHowIcons) - if(iconitos){ - def index = exeHowIcons.indexOf(iconitos[0]) - return toma.ex.values()[index] - } else { - return toma.ex.showHotKeys - } - } - - def static disableBttn(nodo){ - def iconos = nodo.icons.icons - return iconos.contains('emoji-1F56F') - } + + def static exeActionsHow(nodo){ + def iconos = nodo.icons.icons + def iconitos = iconos.intersect(exeHowIcons) + if(iconitos){ + def index = exeHowIcons.indexOf(iconitos[0]) + return toma.ex.values()[index] + } else { + return toma.ex.showHotKeys + } + } + + def static disableBttn(nodo){ + def iconos = nodo.icons.icons + return iconos.contains('emoji-1F56F') + } def static addPastePane(myP, nodoSource){ def enabled = !disableBttn(nodoSource) @@ -352,11 +320,17 @@ class ToM{ } def idSource = ( nodoSource.findAll() - nodoSource )*.id def idTarget = ( nodoTarget.findAll() - existentesNodoTarget )*.id + //carga idDictionary desde mapa.storage + def mapa = nodoTarget.map + def idDictionary = getIdDictionary(mapa) + //actualiza idDictionary for (def i = 0; i < idSource.size() ; i++){ - myP.idDictionary[ idSource[i] ] = idTarget[i] + idDictionary[ idSource[i] ] = idTarget[i] } + //guarda idDictionary en mapa + setIdDictionary(mapa, idDictionary) } - def buttonPanel = tomui.getButtonPanel(msgHtml,bttnText,bttnToolTip, bttnAction, false) + def buttonPanel = tomui.createButtonPanel(msgHtml,bttnText,bttnToolTip, bttnAction, false) myP.add(buttonPanel, tomui.GBC) } @@ -368,6 +342,9 @@ class ToM{ def bttnAction = { e -> def bttn = e.source bttn.setEnabled(enabled) + //carga idDictionary desde mapa.storage + def mapa = c.selected.map + def idDictionary = getIdDictionary(mapa) def nodos = [] (nodo.findAll()- nodo).each{ n -> //get list of clones ids @@ -375,15 +352,15 @@ class ToM{ def clonesIds = n.getNodesSharingContent()*.id uiMsg("clonesIds $clonesIds") //intersect with list of dist.keySet - def keySet = myP.idDictionary.keySet() + def keySet = idDictionary.keySet() uiMsg("keySet $keySet") def sourceId = keySet.intersect(clonesIds) uiMsg("sourceId $sourceId") - //get Target id - def targetId = sourceId?myP.idDictionary[ sourceId[0] ]:null + //get Target id + def targetId = sourceId?idDictionary[ sourceId[0] ]:null uiMsg("targetId $targetId") //get node - def targetNode = targetId?c.selected.map.node(targetId):null + def targetNode = targetId?mapa.node(targetId):null uiMsg("targetNode $targetNode") //add node to nodes list if(targetNode) nodos += targetNode @@ -393,18 +370,38 @@ class ToM{ uiMsg("nodos $nodos") c.select(nodos) } - def buttonPanel = tomui.getButtonPanel(msgHtml,bttnText,bttnToolTip, bttnAction, false) + def buttonPanel = tomui.createButtonPanel(msgHtml,bttnText,bttnToolTip, bttnAction, false) myP.add(buttonPanel, tomui.GBC) } - def static addOpenMapPane(myP, tutNode){ + def static getIdDictionary(mapa){ + def dict = [:] + def textoDict = mapa.storage[idDictStorage] + if(textoDict){ + textoDict.toString().split(';').each{e -> + def (k,v) = e.split(':') + dict[k] = v + } + } + return dict + } + + def static setIdDictionary(mapa, dict){ + def texto = new StringBuilder() + dict.each{k,v -> + texto << "${k}:${v};" + } + mapa.storage[idDictStorage] = texto + } + + def static addOpenMapPane(myP, tutNode, options){ def sep = File.separator def nodoMapa = tutNode.children.find{it.text.endsWith('.mm')} def mapFileName = nodoMapa?.text def Dir = tutNode.map.file.parent def pathName = Dir + sep + mapFileName def enabled = !disableBttn(tutNode) - def msgHtml = tomui.getHtmlFromNote(nodoMapa)?:"Click to open '${mapFileName}'" + def msgHtml = tomui.getHtmlFromNote(nodoMapa, options)?:"Click to open '${mapFileName}'" def bttnText = "Open map '${mapFileName}'" def bttnToolTip = "Click to open '${mapFileName}'" def bttnAction = { e -> @@ -412,7 +409,7 @@ class ToM{ bttn.setEnabled(enabled) def mapa = getMapFromPath(pathName, true) //usar mapa indicado (pero oculto) } - def buttonPanel = tomui.getButtonPanel(msgHtml,bttnText,bttnToolTip, bttnAction, false) + def buttonPanel = tomui.createButtonPanel(msgHtml,bttnText,bttnToolTip, bttnAction, false) myP.add(buttonPanel, tomui.GBC) } @@ -427,14 +424,113 @@ class ToM{ pageNode.pathToRoot*.folded = false c.select(pageNode) } - def buttonPanel = tomui.getButtonPanel(msgHtml,bttnText,bttnToolTip, bttnAction, false) + def buttonPanel = tomui.createButtonPanel(msgHtml,bttnText,bttnToolTip, bttnAction, false) myP.add(buttonPanel, tomui.GBC) } + def static addShowNodePane(myP, nodo){ + def nodos = nodo.children.findAll{ n -> n.link && (n.link.node || (!n.link.node && !n.link.file && n.link.uri.scheme == 'file'))} + nodos.each{ n -> + def msgHtml = "Click to show ${n.text}" + def bttnText = "goto Node" + def bttnToolTip = "Click to show ${n.text}" + def bttnAction + if(n.link.node){ + bttnAction = { e -> + def tNode = n.link.node + def m = c.mapLoader(tNode.map.file).withView()//.selectNodeById(pageNodeId) + m.load() + tNode.pathToRoot*.folded = false + c.select(tNode) + c.centerOnNode(tNode) + } + } else { + bttnAction = { e -> + def path = n.link.uri.path.drop(1) + def id = n.link.uri.fragment + def m = c.mapLoader(path).withView()//.selectNodeById(pageNodeId) + m.load() + def tNode = m.mindMap.node(id) + tNode.pathToRoot*.folded = false + c.select(tNode) + c.centerOnNode(tNode) + } + } + def buttonPanel = tomui.createButtonPanel(msgHtml,bttnText,bttnToolTip, bttnAction, false) + myP.add(buttonPanel, tomui.GBC) + } + } + + def static addTOCPane(myP,nodo){ + def titleNodes = getNewPageNodes(getTutorialNode(nodo)) + def pane = tomui.createEmptyGridBagPanel() + titleNodes.each{ tn -> + def title = tn.text + def bttnAction = { e -> fillPage(myP, tn, true, true) } + def button = tomui.createButton(title, bttnAction) + pane.add(button, tomui.GBC) + } + myP.add(pane, tomui.GBC) + } + + def static addTutorialsPane(myP, mapa){ + def nodosTutoriales = mapa.root.find{it.style.name == styles.tutorial} + if ( nodosTutoriales.size() != 1 ){ + def pane = tomui.createEmptyGridBagPanel() + def pre = nodosTutoriales.size() == 0 ? "No t" : "T" + addPageTitle(myP, "${pre}utorials present in '${mapa.name}' map".toString()) + nodosTutoriales.each{ nT -> + def title = nT.text + def bttnAction = { e -> + def tutNodes = getTutNodes(nT) + if(tutNodes) { + fillContentPane(myP, tutNodes) + } else { + ui.informationMessage( "no tutorial components(nodes) found for tutorial '${nT.text}'".toString() ) + } + } + def button = tomui.createButton(title, bttnAction) + pane.add(button, tomui.GBC) + } + def stopButton = tomui.createButton('Exit tutorial', {tomui.closeTab(tabName)}) + pane.add(stopButton, tomui.GBC) + myP.add(pane, tomui.GBC) + } else { + def nT = nodosTutoriales[0] + def tutNodes = getTutNodes(nT) + if(tutNodes) { + fillContentPane(myP, tutNodes) + } else { + ui.informationMessage( "no tutorial components(nodes) found for tutorial '${nT.text}'".toString() ) + } + } + } + + // end: + + // region: showing other content in Tutorial Tab + //this region contains the methods that uses the tab to show other content leaving the Tutorial itself + + def static showTOC(myP,nodo){ + myP.removeAll() + tomui.resizeContentPanel(myP,tomui.maxContentPaneHeigth) + addTOCPane(myP,nodo) + tomui.adjustHeight(myP, true) + } + + def static showTutorials(mapa){ + def myP = tomui.getContentPaneFromMyTab(tabName, true) + myP.removeAll() + tomui.resizeContentPanel(myP,tomui.maxContentPaneHeigth) + addTutorialsPane(myP, mapa) + tomui.adjustHeight(myP, true) + } + // end: // region: Getting map + //this region contains the methods used to open mindmaps def static getMapFromPath(filePath, withView){ if(exists(filePath)){ @@ -447,9 +543,9 @@ class ToM{ def static exists(String path){new File(path).isFile()} // end: - + // region: help / debug - + def static uiMsg(texto){ //ui.informationMessage(texto.toString()) } diff --git a/Tutorial-o-Matic/src/main/groovy/ToM_actions.groovy b/Tutorial-o-Matic/src/main/groovy/ToM_actions.groovy index bf07f98..97e44d0 100644 --- a/Tutorial-o-Matic/src/main/groovy/ToM_actions.groovy +++ b/Tutorial-o-Matic/src/main/groovy/ToM_actions.groovy @@ -10,35 +10,34 @@ import org.freeplane.plugin.script.proxy.ScriptUtils class ToM_actions{ // region: definitions - + static final c = ScriptUtils.c() static final name = 'tutorialOMatic' static final actionInstruction1 = "addons.${name}.ActionInstruction1" static final actionInstruction2 = "addons.${name}.ActionInstruction2" - static final enum ex{ - muted, showHotKeys, showMenu - } + static final enum ex{ muted, showHotKeys, showMenu } static final int pausa = 400 - + static boolean waiting = false - - + + // end: definitions - - + + // ----------------- Methods ------------------------------------- - - // region: ------ execute actions ---------------------- - + + // region: execute actions + //methods to execute actions showing (or not) menu commands or hotkeys related to action + def static execute(String accion){ def acciones =[] + accion execute(acciones) } - + def static execute(java.util.ArrayList acciones){ menuUtils.executeMenuItems(acciones) } - + def static executeAction(infoAccion , how){ waiting = true def timer = new Timer() @@ -70,7 +69,7 @@ class ToM_actions{ } break } - } + } def static executeActions(infoAccions , how){ if(infoAccions){ @@ -96,11 +95,10 @@ class ToM_actions{ } } - - // end: - - // region: ----- getting label / keyStroke / toolTipText from menuEntry ------------------- + + // region: getting label / keyStroke / toolTipText from menuEntry + //getting info from menuEntry def static getKeyStroke(myMenuEntry){ def kS = myMenuEntry.keyStroke @@ -114,15 +112,16 @@ class ToM_actions{ def static getToolTip(mME){ mME.toolTipText } - + def static getMenuPath(path){ path[1..-2]*.label.join("'->'") } // end: - - // region: ----- getting instructions for action ---------------------------- - + + // region: getting information for action + // building a map [:] for each action with its information + def static getActionInfoMap(org.freeplane.plugin.script.proxy.NodeProxy nodo){ def accion = action(nodo) getActionInfoMap(accion) @@ -132,8 +131,8 @@ class ToM_actions{ def miPath = getMenuEntryPath(accion) if (!miPath) { return null } Map myAction = [:] - myAction - << [ action : accion ] + myAction + << [ action : accion ] << [ path : miPath ] << [ keyStroke : getKeyStroke(miPath[-1]) ] << [ label : getLabel(miPath[-1]) ] @@ -143,37 +142,40 @@ class ToM_actions{ def instr2 = myAction.keyStroke?textUtils.format(actionInstruction2, apos(myAction.keyStroke)):"" myAction << [ instructions : instr2?htmlUtils.join(instr1,"", instr2).replace('\n',''):instr1 ] return myAction - } + } def static apos(String texto){ return "\'" + texto + "\'" } - + // end: - - // region: ----- getting actions from nodes ---------------------- + + // region: getting actions from nodes + //getting actions from nodes + def static action(n){ return (n.link?.uri?.scheme == 'menuitem')?n.link.uri.schemeSpecificPart.drop(1):null } - + def static hasAction(n){ return (n.link?.uri?.scheme == 'menuitem') } - + // end: - - // region: ----- getting MenuEntryTree ------------------- - + + // region: getting MenuEntryTree + // getting MenuEntryTree + def static getMenuEntryPath(miAccion){ return getMenuEntryPath(getMenuEntryTree(), miAccion) } - + def static getMenuEntryTree(){ def menuName = "main_menu" // menuName = 'view' return menuUtils.createMenuEntryTree(menuName) } - + def static getMenuEntryPath(mTree, miAccion){ def path @@ -205,17 +207,18 @@ class ToM_actions{ // si no hay, devolver null return null } - + // end: - - // region: ----- displaying submenus -------------------- - + + // region: displaying submenus + //methods for displaying submenus from menubar + def static openMenus(accion, timeLapse){ timeLapse = timeLapse<25?25:timeLapse>3000?3000:timeLapse def menuPath = getMenuEntryPath(accion).drop(1)*.label def subMenu = ui.frame.JMenuBar.components.find{it.text == menuPath[0]} subMenu.armed = true - + def timer = new Timer() menuPath.drop(1).eachWithIndex{menuItem, i -> timer.runAfter(2 * (i + 1) * timeLapse) { @@ -263,11 +266,12 @@ class ToM_actions{ } return componentes } - + // end: - - // region: ----- working with nodes --------------------- - + + // region: working with nodes + //TODO: WIP simulateTextInputInNode + def static simulateTextInputInNode(nodo, texto, timeLapse, step){ //TODO: find a way that doesn't fire listener until the end def timer = new Timer() c.select(nodo) //TODO: what if nodo is not visible? @@ -281,15 +285,15 @@ class ToM_actions{ c.select(nodo) } } - + // end: - - // region: - + + // region: + // end: - - // region: - + + // region: + // end: - + } \ No newline at end of file diff --git a/Tutorial-o-Matic/src/main/groovy/ToM_ui.groovy b/Tutorial-o-Matic/src/main/groovy/ToM_ui.groovy index bb8e0b1..f399c8a 100644 --- a/Tutorial-o-Matic/src/main/groovy/ToM_ui.groovy +++ b/Tutorial-o-Matic/src/main/groovy/ToM_ui.groovy @@ -1,7 +1,8 @@ package edofro.tutorialomatic +//region: imports import edofro.tutorialomatic.TabPane -import edofro.tutorialomatic.CustomComponentListener +//import edofro.tutorialomatic.CustomComponentListener import java.util.Timer @@ -32,9 +33,12 @@ import org.freeplane.core.ui.components.UITools as ui // import org.freeplane.core.util.MenuUtils as menuUtils import io.github.gitbucket.markedj.Marked +import io.github.gitbucket.markedj.Options +//end: class ToM_ui{ + //region: definitions static final int minContentPaneWidth = 408 static final int maxContentPaneHeigth = 50000 static final String myPaneName = 'myContentPanel' @@ -55,7 +59,6 @@ class ToM_ui{ color: rgb(0, 80, 0); } """ - static SwingBuilder swing = new SwingBuilder() @@ -73,7 +76,10 @@ class ToM_ui{ ipadx : 0, // This field specifies the internal padding of the component, how much space to add to the minimum width of the component. The width of the component is at least its minimum width plus ipadx pixels. ipady : 0 // This field specifies the internal padding, that is, how much space to add to the minimum height of the component. The height of the component is at least its minimum height plus ipady pixels. ) - + //end: + + //region: Text Message in transparent dialog + def static showTextMessage(msg, lapseTime){ def win swing.edt{ @@ -103,7 +109,17 @@ class ToM_ui{ win.setVisible( true ) } - def static getHtmlFromNote(nodo){ + //end: + + //region: getting html + + def static tomMarkedjOptions(){ + Options options = new Options() + options.getWhitelist().addProtocols("img", "src", "http", "https", "file") + return options + } + + def static getHtmlFromNote(nodo, options){ if(!nodo.note) return null def noteType = nodo.noteContentType def html @@ -112,13 +128,13 @@ class ToM_ui{ html = nodo.plainNote.startsWith('=')?nodo.note.plain:nodo.note.html break case 'markdown': - //html = " ${Marked.marked(nodo.note.plain)} " + //html = " ${Marked.marked(nodo.note.plain, options))} " html = """ - ${Marked.marked(nodo.note.plain)} + ${Marked.marked(nodo.note.plain, options)} - """ + """ break default: html = "Node's note not recognized" @@ -126,7 +142,7 @@ class ToM_ui{ } return html } - + def static getHtmlFromGroovyNode(nodo, script){ def html = """ @@ -135,11 +151,15 @@ class ToM_ui{
${script}
""" - return html + return html } - def static createInstructionsPane(nodo){ - return createInstructionsPane(getHtmlFromNote(nodo)) + //end: + + //region: creating panes + + def static createInstructionsPane(nodo, options){ + return createInstructionsPane(getHtmlFromNote(nodo, options)) } def static createInstructionsPane(String html){ @@ -166,66 +186,32 @@ class ToM_ui{ return editor } - def static resizeContentPanel(comp, height){ - comp.parent.preferredSize = new Dimension(minContentPaneWidth, height) - } - - - def static adjustHeight(comp, boolean backToTop = false){ - if (backToTop) scrollContentPaneBackToTop(comp) - TabPane.repaint() - def timer = new Timer() - timer.runAfter(100) { - resizeContentPanel(comp, comp.height + 100) - if (backToTop) scrollContentPaneBackToTop(comp) - // TabPane.revalidate() <--- no funciona - TabPane.repaint() - } - } - - def static getButtonPanel(javax.swing.JComponent comp){ - return SU.getAncestorNamed(myButtonPanelName, comp) - } - - def static getTabContentPane(javax.swing.JComponent comp){ - return SU.getAncestorNamed(myPaneName, comp) - } - - def static getTabContentPane(String tabName){ - def contentPane - if( !TabPane.hasTab(tabName)) { - contentPane = swing.panel( - name: myPaneName, - layout: new GridBagLayout(), - // background: Color.gray - ){} - contentPane.addComponentListener(new CustomComponentListener()) - contentPane.metaClass.idDictionary = [:] - def panel = swing.panel( - layout: new GridBagLayout(), - preferredSize: new Dimension(minContentPaneWidth, maxContentPaneHeigth), - ){} - panel.add(contentPane,GBC) - def sp = swing.scrollPane(){} - sp.verticalScrollBar.unitIncrement = 16 //.getVerticalScrollBar().setUnitIncrement(16) - sp.viewport.add(panel) - TabPane.addTab(tabName, sp) - } else { - contentPane = TabPane.getTab(tabName)?.viewport.components[0].components.find{it.name == myPaneName} - } + def static createTabContentPane(String tabName){ + def contentPane = swing.panel( + name: myPaneName, + layout: new GridBagLayout(), + // background: Color.gray + ){} + def sp = createScrollPaneForContentPane(contentPane) + TabPane.addTab(tabName, sp) return contentPane } - - def static getContentPaneFromMyTab(String myTabName, boolean doClear){ - def cPane = ToM_ui.getTabContentPane(myTabName) - if(doClear) cPane.removeAll() //eliminar contenido existente en el panel - TabPane.showTab(myTabName) - ToM_ui.resizeContentPanel(cPane,maxContentPaneHeigth) - return cPane + + def static createScrollPaneForContentPane(contentPane){ + contentPane.addComponentListener(new CustomComponentListener()) + def panel = swing.panel( + layout: new GridBagLayout(), + preferredSize: new Dimension(minContentPaneWidth, maxContentPaneHeigth), + ){} + panel.add(contentPane,GBC) + def sp = swing.scrollPane(){} + sp.verticalScrollBar.unitIncrement = 16 //.getVerticalScrollBar().setUnitIncrement(16) + sp.viewport.add(panel) + return sp } // genera panel con botón - def static getButtonPanel(htmlMsg, buttonLabel, buttonToolTip, buttonAction, boolean isToggleButton = false){ + def static createButtonPanel(htmlMsg, buttonLabel, buttonToolTip, buttonAction, boolean isToggleButton = false){ def panel = swing.panel( border : new LineBorder(Color.gray, 1), name : myButtonPanelName, @@ -270,16 +256,16 @@ class ToM_ui{ } return panel } - + // genera panel close - next page //nextButtonAction == null --> no 'Next page' button - def static getNextButtonPanel(tabName, closeLabel, closeToolTip, nextLabel, nextToolTip, nextButtonAction, tocLabel = '', tocToolTip = '', tocButtonAction = null ){ + def static createNextButtonPanel(tabName, closeLabel, closeToolTip, nextLabel, nextToolTip, nextButtonAction, tocLabel = '', tocToolTip = '', tocButtonAction = null ){ def panel = swing.panel( //border : new LineBorder(Color.gray, 1), name : myNextPanelName, ) { borderLayout() - panel( + panel( border : new EmptyBorder(2, 10, 2, 10), // <------- éste constraints : NORTH ) { @@ -314,19 +300,93 @@ class ToM_ui{ return panel } - def static closeTab(tabName, boolean hideTabPane = false) { - TabPane.removeTab(tabName, hideTabPane) + def static createEmptyGridBagPanel(){ + return swing.panel( + layout: new GridBagLayout(), + border : new EmptyBorder(2, 10, 2, 0), //new LineBorder(Color.black, 1), + // background: Color.gray + ){} } + def static createButton(title, bttnAction){ + return swing.button( + label : title, + margin : new Insets(10,15,10,15), + actionPerformed : bttnAction, + ) + } + + + //end: + + //region: resizing panes + + def static resizeContentPanel(comp, height){ + comp.parent.preferredSize = new Dimension(minContentPaneWidth, height) + } + + def static adjustHeight(comp, boolean backToTop = false){ + if (backToTop) scrollContentPaneBackToTop(comp) + TabPane.repaint() + def timer = new Timer() + timer.runAfter(100) { + resizeContentPanel(comp, comp.height + 100) + if (backToTop) scrollContentPaneBackToTop(comp) + // TabPane.revalidate() <--- no funciona + TabPane.repaint() + } + } + + //end: + + //region: getting existing panes + + def static getButtonPanel(javax.swing.JComponent comp){ + return SU.getAncestorNamed(myButtonPanelName, comp) + } + + def static getTabContentPane(javax.swing.JComponent comp){ + return SU.getAncestorNamed(myPaneName, comp) + } + + def static getTabContentPane(String tabName){ + def contentPane + if( !TabPane.hasTab(tabName)) { + contentPane = createTabContentPane(tabName) + } else { + contentPane = TabPane.getTab(tabName)?.viewport.components[0].components.find{it.name == myPaneName} + } + return contentPane + } + + def static getContentPaneFromMyTab(String myTabName, boolean doClear){ + def cPane = ToM_ui.getTabContentPane(myTabName) + if(doClear) cPane.removeAll() //eliminar contenido existente en el panel + TabPane.showTab(myTabName) + ToM_ui.resizeContentPanel(cPane,maxContentPaneHeigth) + return cPane + } def static getNextButtonPanel(myP){ return myP.components.find{it.name == myNextPanelName} } - + + def static getScrollPaneViewport(comp){ + return SU.getAncestorOfClass(javax.swing.JViewport, comp) + } + + //end: + + //region: other methods + + def static closeTab(tabName, boolean hideTabPane = false) { + TabPane.removeTab(tabName, hideTabPane) + } + def static setNextPagePanelEnabled(JPanel myP, boolean isEnabled){ setPanelEnabled(getNextButtonPanel(myP), isEnabled) } - + def static setPanelEnabled(JPanel panel, boolean isEnabled) { panel.setEnabled(isEnabled) @@ -341,28 +401,35 @@ class ToM_ui{ def static anyCompPending(myP){ return myP.components.any{it.hasProperty('pending') && it.pending} } -// scrollPane - def static getScrollPaneViewport(comp){ - return SU.getAncestorOfClass(javax.swing.JViewport, comp) - } def static scrollContentPaneBackToTop(comp){ getScrollPaneViewport(comp).setViewPosition(new Point(0,0)) } + + //end: + + + //region: Listeners - def static createEmptyGridBagPanel(){ - return swing.panel( - layout: new GridBagLayout(), - border : new EmptyBorder(2, 10, 2, 0), //new LineBorder(Color.black, 1), - // background: Color.gray - ){} + // Listener for Tutorial Tab pane so it gets resized (enough length) each time its width gets modified + static class CustomComponentListener implements ComponentListener { + public void componentResized(ComponentEvent e) { //https://docs.oracle.com/javase/8/docs/api/java/awt/event/ComponentEvent.html + def comp = e.component + //ToM_ui.resizeContentPanel(comp, tomui.maxContentPaneHeigth) + sleep(100) + ToM_ui.resizeContentPanel(comp, comp.height + 500) + // TabPane.repaint() + } + public void componentMoved(ComponentEvent e) { + // e.source.title = " moved. " + } + public void componentShown(ComponentEvent e) { + // e.source.title = " shown. " + } + public void componentHidden(ComponentEvent e) { + // e.getSource().title = " hidden. " + } } - def static createButton(title, bttnAction){ - return swing.button( - label : title, - margin : new Insets(10,15,10,15), - actionPerformed : bttnAction, - ) - } + //end: } \ No newline at end of file diff --git a/Tutorial-o-Matic/version.properties b/Tutorial-o-Matic/version.properties index 0deb02d..6cb45ad 100644 --- a/Tutorial-o-Matic/version.properties +++ b/Tutorial-o-Matic/version.properties @@ -1,3 +1,4 @@ -version=v0.0.3 -downloadUrl=https://github.com/EdoFro/Freeplane_Tutorial_AddOn/releases/download/v0.0.3demo/Tutorial-o-Matic-v0.0.3.addon.mm -freeplaneVersionFrom=v1.9.9 +version=v0.0.4 +downloadUrl=https://github.com/EdoFro/Freeplane_Tutorial_AddOn/releases/download/v0.0.4/Tutorial-o-Matic-v0.0.4.addon.mm +freeplaneVersionFrom=v1.9.9 + diff --git a/Tutorial-o-Matic/zips/doc/Tutorial-o-Matic/SimpleTutorialSample.mm b/Tutorial-o-Matic/zips/doc/Tutorial-o-Matic/SimpleTutorialSample.mm index ef90280..00a2a80 100644 --- a/Tutorial-o-Matic/zips/doc/Tutorial-o-Matic/SimpleTutorialSample.mm +++ b/Tutorial-o-Matic/zips/doc/Tutorial-o-Matic/SimpleTutorialSample.mm @@ -1,7 +1,7 @@ - + @@ -14,12 +14,23 @@ - - + + - - + +pre { + background-color: rgb(230, 230, 230); + border: 1px solid rgb(0, 0, 0); + display: block; + padding: 10px; +} +code { + font-family: Consolas,"courier new"; + color: rgb(0, 80, 0); +} + + @@ -81,6 +92,10 @@ + + + + @@ -743,7 +758,7 @@
- + @@ -1183,6 +1198,29 @@ This example shows some actions applied without showing any message (muted): + + You can also jump to another tutorial's page. + + +To jump to the **'SimpleDemo's TOC page'** page click on the button bellow: + + + + + + + + + You can add buttons to jump to other nodes (in this or other mindmap) + + +Here is an example: + + + + + + @@ -2170,8 +2208,7 @@ This example shows some actions applied without showing any message (muted): muted icon indicates it should execute the command without showing menus or hotkeys

- - + @@ -2218,6 +2255,13 @@ This example shows some actions applied without showing any message (muted): + + You can also jump to another tutorial's page. + + +To jump to the **'SimpleDemo's TOC page'** page click on the button bellow: + +
@@ -2284,8 +2328,7 @@ candle indicates that executes only one time (then button gets disabled) magnifier icon indicates that the script code must be shown in the tutorial

- - +
@@ -2349,8 +2392,7 @@ candle indicates that executes only one time (then button gets disabled) magnifier icon indicates that the script code must be shown in the tutorial

- - +
@@ -2439,8 +2481,7 @@ candle indicates that executes only one time (then button gets disabled) to indicate which are the nodes you want to select just paste clones of them here as childs

- -
+