Skip to content

Commit

Permalink
initial version
Browse files Browse the repository at this point in the history
  • Loading branch information
haesleinhuepf committed Aug 17, 2019
0 parents commit 5e10bab
Show file tree
Hide file tree
Showing 10 changed files with 503 additions and 0 deletions.
2 changes: 2 additions & 0 deletions .gitignore
@@ -0,0 +1,2 @@
/.idea/
*.iml
16 changes: 16 additions & 0 deletions license.txt
@@ -0,0 +1,16 @@
Robert Haase, Max Planck Institute for Molecular Cell Biology
and Genetics, Dresden

Knowledge is free. Thus, the code and text in this repository is public domain. However:

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
147 changes: 147 additions & 0 deletions pom.xml
@@ -0,0 +1,147 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<parent>
<groupId>org.scijava</groupId>
<artifactId>pom-scijava</artifactId>
<version>27.0.1</version>
<relativePath />
</parent>

<groupId>net.haesleinhuepf</groupId>
<artifactId>extend-macro-autocomplete</artifactId>
<version>0.1.0</version>

<name>extend-macro-autocomplete</name>
<description>extend-macro-autocomplete</description>
<url>https://github.com/haesleinhuepf/extend-macro-autocompletion</url>
<inceptionYear>2019</inceptionYear>
<organization>
<name>MPI CBG</name>
<url>http://www.mpi-cbg.de</url>
</organization>
<licenses>
<license>
<name>public domain</name>
<distribution>repo</distribution>
</license>
</licenses>

<developers>
<developer>
<id>haesleinhuepf</id>
<name>Robert Haase</name>
<url>https://haesleinhuepf.net</url>
<organization>MPI CBG</organization>
<roles>
<role>founder</role>
<role>lead</role>
<role>developer</role>
<role>debugger</role>
<role>reviewer</role>
<role>support</role>
<role>maintainer</role>
</roles>
</developer>
</developers>
<contributors>
<contributor>
<name>none</name>
</contributor>
</contributors>

<mailingLists>
<mailingList>
<name>ImageSc Forum</name>
<archive>http://image.sc/</archive>
</mailingList>
</mailingLists>

<scm>
<connection>scm:git:git://github.com/haesleinhuepf/extend-macro-autocompletion</connection>
<developerConnection>scm:git:git@github.com/haesleinhuepf/extend-macro-autocompletion</developerConnection>
<tag>HEAD</tag>
<url>https://github.com/haesleinhuepf/extend-macro-autocompletion</url>
</scm>
<issueManagement>
<system>GitHub Issues</system>
<url>https://github.com/haesleinhuepf/extend-macro-autocompletion/issues</url>
</issueManagement>
<ciManagement>
<system>None</system>
</ciManagement>

<properties>
<package-name>net.haesleinhuepf</package-name>
<license.licenseName>bsd_3</license.licenseName>
<license.copyrightOwners>Robert Haase, MPI CBG</license.copyrightOwners>
<scijava.app.directory>C:/programs/fiji-win64/Fiji.app/</scijava.app.directory>
</properties>

<dependencies>
<!-- ImageJ dependencies -->
<dependency>
<groupId>net.imagej</groupId>
<artifactId>ij</artifactId>
</dependency>
<dependency>
<groupId>net.imagej</groupId>
<artifactId>imagej-legacy</artifactId>
</dependency>

<!-- SciJava dependencies -->
<dependency>
<groupId>org.scijava</groupId>
<artifactId>scijava-common</artifactId>
</dependency>
<dependency>
<groupId>org.scijava</groupId>
<artifactId>script-editor</artifactId>
</dependency>

<!-- Third party dependencies -->
<dependency>
<groupId>com.fifesoft</groupId>
<artifactId>languagesupport</artifactId>
</dependency>
<dependency>
<groupId>com.fifesoft</groupId>
<artifactId>rsyntaxtextarea</artifactId>
</dependency>
<dependency>
<groupId>com.fifesoft</groupId>
<artifactId>autocomplete</artifactId>
</dependency>

<!-- Test scope dependencies -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
</dependencies>

<repositories>
<repository>
<id>sonatype</id>
<url>http://oss.sonatype.org/content/groups/public</url>
</repository>
<repository>
<id>imagej.releases</id>
<url>
http://maven.imagej.net/content/repositories/releases
</url>
</repository>
<repository>
<id>imagej.snapshots</id>
<url>
http://maven.imagej.net/content/repositories/snapshots
</url>
</repository>
</repositories>

</project>
14 changes: 14 additions & 0 deletions readme.md
@@ -0,0 +1,14 @@
# ImageJ macro extensions and extending auto completion in Fijis script editor
Since we introduced auto-completion in Fijis script editor, some developers asked me
how they can make their tools discoverable by auto-completion users.
This article explains how to achieve this. I'm providing a [fully functional example](https://github.com/haesleinhuepf/extend-macro-autocompletion) as
this might be a better starting point for developers.

## Starting point a SciJava Fiji plugin
As a starting point we assume to have a [maven](https://maven.apache.org/) project with a
[pom.xml](http://github.com/haesleinhuepf/extend) file





@@ -0,0 +1,39 @@
package net.haesleinhuepf.fiji.macro;

import net.haesleinhuepf.fiji.plugins.MyPlugins;
import net.imagej.legacy.plugin.MacroExtensionAutoCompletionPlugin;
import org.fife.ui.autocomplete.BasicCompletion;
import org.fife.ui.autocomplete.CompletionProvider;
import org.scijava.plugin.Plugin;

import java.util.ArrayList;
import java.util.List;

/**
* MyMacroAutoCompletionExtension
*
* This class communicates with Fijis script editor. It hands over a list of potential commands
* which appear in the auto-completion pulldown.
*
* Author haesleinhuepf
* August 2019
*/
@Plugin(type = MacroExtensionAutoCompletionPlugin.class)
public class MyMacroAutoCompletionExtension implements MacroExtensionAutoCompletionPlugin {
@Override
public List<BasicCompletion> getCompletions(CompletionProvider completionProvider) {
ArrayList<BasicCompletion> completions = new ArrayList<BasicCompletion>();

MyMacroExtensionDescriptor[] pluginList = MyPlugins.list;

// go through plugins and provide an auto-complete entry for each
for (MyMacroExtensionDescriptor plugin : pluginList) {
String commandName = "Ext.MyLib_" + plugin.getClass().getSimpleName();
completions.add(new BasicCompletion(completionProvider, commandName, null, plugin.description()));
}



return completions;
}
}
@@ -0,0 +1,15 @@
package net.haesleinhuepf.fiji.macro;

/**
* This is a suggested interface all macro extending plugins should implement.
* Change it according to your needs.
*
* @author haesleinhuepf
* August 2019
*/
public interface MyMacroExtensionDescriptor {
void runFromMacro(Object[] parameters);
int[] parameterTypes();
String description();
String parameters();
}
68 changes: 68 additions & 0 deletions src/main/java/net/haesleinhuepf/fiji/macro/MyMacroExtensions.java
@@ -0,0 +1,68 @@
package net.haesleinhuepf.fiji.macro;

import ij.macro.Functions;
import ij.macro.ExtensionDescriptor;
import ij.macro.MacroExtension;
import net.haesleinhuepf.fiji.plugins.MyPlugins;
import org.scijava.command.Command;
import org.scijava.plugin.Plugin;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;

/**
* MyMacroExtensions
*
* This class communicates with ImageJs macro interpreter. It hands over a list of commands
* (of type ExtensionDescriptor) to the macro interpreter which will be accepted as valid
* commands. Furthermore, it's called when one of the commands is executed.
*
*
* @author haesleinhuepf
* August 2019
*/
@Plugin(type = Command.class, menuPath = "Plugins>My Macro Extensions")
public class MyMacroExtensions implements MacroExtension, Command {
@Override
public String handleExtension(String name, Object[] args) {
MyMacroExtensionDescriptor[] pluginList = MyPlugins.list;

// go through plugin list an check if we know the called plugin
for (MyMacroExtensionDescriptor plugin : pluginList) {
String command = MyPlugins.macroExtensionPrefix + plugin.getClass().getSimpleName();

// if name matches exactly
if (command.compareTo(name) == 0) {
// call the plugin
plugin.runFromMacro(args);
break;
}
}
return null;
}

@Override
public ExtensionDescriptor[] getExtensionFunctions() {
MyMacroExtensionDescriptor[] pluginList = MyPlugins.list;

ExtensionDescriptor[] result = new ExtensionDescriptor[pluginList.length];

int i = 0;
// formulate a list of ExtensionDescriptors describing all command this class can handle
for (MyMacroExtensionDescriptor plugin : pluginList) {
String call = MyPlugins.macroExtensionPrefix + plugin.getClass().getSimpleName() + "(" + plugin.parameters() + ")";
result[i] = new ExtensionDescriptor(call, plugin.parameterTypes(), this);
i++;
}

// hand over the list to ImageJs macro interpreter
return result;
}

@Override
public void run() {
// Activate this class as handler for macro extensions
Functions.registerExtensions(this);
}
}
88 changes: 88 additions & 0 deletions src/main/java/net/haesleinhuepf/fiji/plugins/MyPluginAdd.java
@@ -0,0 +1,88 @@
package net.haesleinhuepf.fiji.plugins;


import ij.ImagePlus;
import ij.WindowManager;
import ij.macro.MacroExtension;
import net.haesleinhuepf.fiji.macro.MyMacroExtensionDescriptor;
import org.scijava.command.Command;
import org.scijava.plugin.Parameter;
import org.scijava.plugin.Plugin;

/**
* A fancy plugin which adds a given number to all pixels of an image.
*
* @author haesleinhuepf
* August 2019
*/
@Plugin(type = Command.class, menuPath = "Plugins>My Plugin Add")
public class MyPluginAdd implements Command, MyMacroExtensionDescriptor {
/**
* This is the actual algorithm. It adds a number to any pixel of the image
*
* @param imp input image
* @param scalar number to add
*/
private void actualAlgorithm(ImagePlus imp, double scalar) {
imp.getProcessor().add(scalar);
}

// --------------------------------------------------------------------------------------
// these are implementations allowing MyMacroExtensions building autocompletion and
// calling the right command

// called by MyMacroExtensions in case the command is called from macro
@Override
public void runFromMacro(Object[] parameters) {
// We get an array of objects from the Macro interpeter.
// We need to convert/cast it to what we need
ImagePlus imp = WindowManager.getImage((String)parameters[0]);
double scalar = Double.parseDouble((String)parameters[1]);

// call the actual algorithm
actualAlgorithm(imp, scalar);
}

/**
* We need to define a list of parameter types
* @return int arry with parameter types as defined in the MacroExtension class.
*/
@Override
public int[] parameterTypes() {
return new int[] {MacroExtension.ARG_STRING, MacroExtension.ARG_NUMBER};
}

/**
* We should provide a user readable list of parameters
* @return list of parameters
*/
@Override
public String parameters() {
return "imageTitle, number";
}

/**
* We should define a description for users.
* @return algorithm/parameter description
*/
@Override
public String description() {
return "Hey folks, just enter an image and a number.\n\n :-)";
}


// --------------------------------------------------------------------------------------
// This is the definition of parameters to allow SciJava building a
// dialog for us in case the user clicks the menu
@Parameter
ImagePlus input;

@Parameter
Double scalar;

// called by SciJava on menu click
@Override
public void run() {
actualAlgorithm(input, scalar);
}
}

0 comments on commit 5e10bab

Please sign in to comment.