├── .gitignore ├── .idea ├── misc.xml ├── modules.xml ├── runConfigurations.xml └── vcs.xml ├── COPYING ├── LICENSE.CECILL-C ├── LICENSE.LGPL ├── README.md ├── app ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ └── main │ ├── AndroidManifest.xml │ ├── java │ └── org │ │ └── graphstream │ │ └── ui │ │ ├── android │ │ ├── AndroidFullGraphRenderer.java │ │ ├── Backend.java │ │ ├── BackendJ2D.java │ │ ├── renderer │ │ │ ├── AreaSkeleton.java │ │ │ ├── ConnectorSkeleton.java │ │ │ ├── EdgeRenderer.java │ │ │ ├── GraphBackgroundRenderer.java │ │ │ ├── NodeRenderer.java │ │ │ ├── SelectionRenderer.java │ │ │ ├── Skeleton.java │ │ │ ├── SpriteRenderer.java │ │ │ ├── StyleRenderer.java │ │ │ └── shape │ │ │ │ ├── AreaOnConnector.java │ │ │ │ ├── Connector.java │ │ │ │ ├── Decorable.java │ │ │ │ ├── Orientable.java │ │ │ │ ├── Shape.java │ │ │ │ └── android │ │ │ │ ├── Area.java │ │ │ │ ├── IconAndText.java │ │ │ │ ├── ShapeDecor.java │ │ │ │ ├── ShapePaint.java │ │ │ │ ├── ShapeStroke.java │ │ │ │ ├── ShowCubics.java │ │ │ │ ├── advancedShapes │ │ │ │ ├── AngleShape.java │ │ │ │ ├── BlobShape.java │ │ │ │ ├── CubicCurveShape.java │ │ │ │ ├── FreePlaneEdgeShape.java │ │ │ │ ├── HorizontalSquareEdgeShape.java │ │ │ │ ├── LSquareEdgeShape.java │ │ │ │ └── PieChartShape.java │ │ │ │ ├── arrowShapes │ │ │ │ ├── ArrowOnEdge.java │ │ │ │ ├── CircleOnEdge.java │ │ │ │ ├── DiamondOnEdge.java │ │ │ │ └── ImageOnEdge.java │ │ │ │ ├── baseShapes │ │ │ │ ├── AreaConnectorShape.java │ │ │ │ ├── AreaOnConnectorShape.java │ │ │ │ ├── AreaShape.java │ │ │ │ ├── ConnectorShape.java │ │ │ │ ├── Form.java │ │ │ │ ├── LineConnectorShape.java │ │ │ │ ├── LineShape.java │ │ │ │ ├── OrientableRectangularAreaShape.java │ │ │ │ ├── PolygonalShape.java │ │ │ │ ├── PolylineEdgeShape.java │ │ │ │ └── RectangularAreaShape.java │ │ │ │ ├── basicShapes │ │ │ │ ├── CircleShape.java │ │ │ │ ├── CrossShape.java │ │ │ │ ├── DiamondShape.java │ │ │ │ ├── FreePlaneNodeShape.java │ │ │ │ ├── PolygonShape.java │ │ │ │ ├── RoundedSquareShape.java │ │ │ │ ├── SquareShape.java │ │ │ │ └── TriangleShape.java │ │ │ │ ├── shapePart │ │ │ │ ├── Fillable.java │ │ │ │ ├── FillableLine.java │ │ │ │ ├── FillableMulticolored.java │ │ │ │ ├── Shadowable.java │ │ │ │ ├── ShadowableLine.java │ │ │ │ ├── Strokable.java │ │ │ │ └── StrokableLine.java │ │ │ │ └── spriteShapes │ │ │ │ ├── OrientableSquareShape.java │ │ │ │ ├── ShapeStroke.java │ │ │ │ ├── SpriteArrowShape.java │ │ │ │ └── SpriteFlowShape.java │ │ └── util │ │ │ ├── AttributeUtils.java │ │ │ ├── Background.java │ │ │ ├── ColorManager.java │ │ │ ├── CubicCurve.java │ │ │ ├── Display.java │ │ │ ├── EdgePoints.java │ │ │ ├── FPSLogger.java │ │ │ ├── Font.java │ │ │ ├── FontCache.java │ │ │ ├── ImageCache.java │ │ │ ├── Selection.java │ │ │ ├── ShapeUtil.java │ │ │ └── Stroke.java │ │ └── android_viewer │ │ ├── AndroidViewer.java │ │ ├── DefaultView.java │ │ ├── ViewPanel.java │ │ └── util │ │ ├── CubicCurve.java │ │ ├── DefaultFragment.java │ │ ├── DefaultMouseManager.java │ │ └── GradientFactory.java │ └── res │ ├── drawable-v24 │ └── ic_launcher_foreground.xml │ ├── drawable │ └── ic_launcher_background.xml │ ├── layout │ └── fragment_default.xml │ ├── mipmap-anydpi-v26 │ ├── ic_launcher.xml │ └── ic_launcher_round.xml │ ├── mipmap-hdpi │ ├── ic_launcher.png │ └── ic_launcher_round.png │ ├── mipmap-mdpi │ ├── ic_launcher.png │ └── ic_launcher_round.png │ ├── mipmap-xhdpi │ ├── ic_launcher.png │ └── ic_launcher_round.png │ ├── mipmap-xxhdpi │ ├── ic_launcher.png │ └── ic_launcher_round.png │ ├── mipmap-xxxhdpi │ ├── ic_launcher.png │ └── ic_launcher_round.png │ └── values │ ├── colors.xml │ ├── strings.xml │ └── styles.xml ├── build.gradle ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── scripts └── publish-mavencentral.gradle └── settings.gradle /.gitignore: -------------------------------------------------------------------------------- 1 | # Built application files 2 | *.apk 3 | *.ap_ 4 | 5 | # Files for the ART/Dalvik VM 6 | *.dex 7 | 8 | # Java class files 9 | *.class 10 | 11 | # Generated files 12 | bin/ 13 | gen/ 14 | out/ 15 | 16 | # Gradle files 17 | .gradle/ 18 | build/ 19 | 20 | # Local configuration file (sdk path, etc) 21 | local.properties 22 | 23 | # Proguard folder generated by Eclipse 24 | proguard/ 25 | 26 | # Log Files 27 | *.log 28 | 29 | # Android Studio Navigation editor temp files 30 | .navigation/ 31 | 32 | # Android Studio captures folder 33 | captures/ 34 | 35 | # Intellij 36 | *.iml 37 | .idea/workspace.xml 38 | .idea/tasks.xml 39 | .idea/gradle.xml 40 | .idea/dictionaries 41 | .idea/libraries 42 | 43 | # Keystore files 44 | *.jks 45 | 46 | # External native build folder generated in Android Studio 2.2 and later 47 | .externalNativeBuild 48 | 49 | # Google Services (e.g. APIs or Firebase) 50 | google-services.json 51 | 52 | # Freeline 53 | freeline.py 54 | freeline/ 55 | freeline_project_description.json 56 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 16 | 26 | 27 | 28 | 29 | 30 | 31 | 33 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /.idea/runConfigurations.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 11 | 12 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /COPYING: -------------------------------------------------------------------------------- 1 | GraphStream is a library whose purpose is to handle static or dynamic 2 | graph, create them from scratch, file or any source and display them. 3 | 4 | This program is free software distributed under the terms of two licenses, the 5 | CeCILL-C license that fits European law, and the GNU Lesser General Public 6 | License. You can use, modify and/ or redistribute the software under the terms 7 | of the CeCILL-C license as circulated by CEA, CNRS and INRIA at the following 8 | URL or under the terms of the GNU LGPL as published by 9 | the Free Software Foundation, either version 3 of the License, or (at your 10 | option) any later version. 11 | 12 | This program is distributed in the hope that it will be useful, but WITHOUT ANY 13 | WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A 14 | PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. 15 | 16 | You should have received a copy of the GNU Lesser General Public License 17 | along with this program. If not, see . 18 | 19 | The fact that you are presently reading this means that you have had 20 | knowledge of the CeCILL-C and LGPL licenses and that you accept their terms. 21 | -------------------------------------------------------------------------------- /LICENSE.CECILL-C: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/graphstream/gs-ui-android/232eb7ffffdc7053173b002489dcccec8226ac43/LICENSE.CECILL-C -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # GraphStream -- Android Viewer 2 | 3 | The GraphStream project is a java library that provides an API to model, analyze and visualize graphs and dynamic graphs. 4 | 5 | This module contains a Android implementation of the GraphStream Viewer. 6 | 7 | Check out the Website for more information. 8 | 9 | ## UI 10 | 11 | This renderer supports almost all of the CSS properties defined in the [GraphStream CSS Reference](http://graphstream-project.org/doc/Tutorials/GraphStream-CSS-Reference_1.0/), however it is still a work in progress. This viewer is intended only at 2D visualization actually. 12 | 13 | We are interested in any suggestion to improve this renderer, and your use cases could be of great help for us in developing this project. If you like and use this project, this could be a good contribution. 14 | 15 | ## Install UI 16 | 17 | `gs-ui-android` is a plugin to the `gs-core` main project. 18 | 19 | The release comes with a pre-packaged aar file named `gs-ui-android.aar` that contains the GraphStream viewer classes. It depends on the root project `gs-core`. 20 | 21 | For using Graphstream, your project must run with java 8 22 | 23 | Add the .aar in your project following these instructions : https://developer.android.com/studio/projects/android-library.html#AddDependency 24 | 25 | You can download GraphStream on the github releases pages: 26 | 27 | - [gs-core](https://github.com/graphstream/gs-core/releases) 28 | - [gs-ui-android](https://github.com/graphstream/gs-ui-android/releases) 29 | 30 | 31 | Gradle users, you may include `gs-core` and `gs-ui-android` as a dependency to your project using . 32 | Simply add the `jitpack` repository to the `pom.xml`: 33 | 34 | ``` 35 | allprojects { 36 | repositories { 37 | maven { url 'https://jitpack.io' } 38 | } 39 | } 40 | ``` 41 | 42 | then, add the `gs-core` and `gs-ui-android` to your dependencies: 43 | 44 | ```xml 45 | dependencies { 46 | api 'com.github.graphstream:gs-ui-android:2.0' 47 | api 'com.github.graphstream:gs-core:2.0' 48 | } 49 | ``` 50 | 51 | You can use any version of `gs-core` and `gs-ui-android` you need, provided they are the same. Simply specify the desired version in the `` tag. The version can be a git tag name (e.g. `2.0`), a commit number, or a branch name followed by `-SNAPSHOT` (e.g. `dev-SNAPSHOT`). More details on the [possible versions on jitpack](https://jitpack.io/#graphstream/gs-core). 52 | 53 | ## Configure UI 54 | 55 | For the convenience of the users, a default Android Fragment (`org.graphstream.ui.android_viewer.util.DefaultFragment`) is provided. The Fragment can be used like so: 56 | 57 | ```java 58 | public void display(Bundle savedInstanceState, Graph graph, boolean autoLayout) { 59 | if (savedInstanceState == null) { 60 | FragmentManager fm = getSupportFragmentManager(); 61 | 62 | // find fragment or create him 63 | fragment = (DefaultFragment) fm.findFragmentByTag("fragment_tag"); 64 | if (null == fragment) { 65 | fragment = new DefaultFragment(); 66 | fragment.init(graph, autoLayout); 67 | } 68 | 69 | // Add the fragment in the layout and commit 70 | FragmentTransaction ft = fm.beginTransaction() ; 71 | ft.add(CONTENT_VIEW_ID, fragment).commit(); 72 | } 73 | } 74 | ``` 75 | 76 | ## Help 77 | 78 | You may check the documentation on the [website](http://graphstream-project.org). You may also share your questions on the mailing list at http://sympa.litislab.fr/sympa/subscribe/graphstream-users 79 | 80 | ## License 81 | 82 | See the COPYING file. 83 | 84 | ## Compilation notes 85 | 86 | - Java 1.8 is needed. 87 | - The `JAVA_HOME` variable should be set. 88 | -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.library' 2 | apply plugin: 'com.github.dcendents.android-maven' 3 | 4 | group='org.graphstream' 5 | 6 | android { 7 | compileSdkVersion 26 8 | defaultConfig { 9 | minSdkVersion 24 10 | targetSdkVersion 26 11 | versionCode 2 12 | versionName "2.0" 13 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" 14 | } 15 | buildTypes { 16 | release { 17 | minifyEnabled false 18 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 19 | } 20 | } 21 | compileOptions { 22 | sourceCompatibility JavaVersion.VERSION_1_8 23 | targetCompatibility JavaVersion.VERSION_1_8 24 | } 25 | productFlavors { 26 | } 27 | 28 | lintOptions { 29 | abortOnError false 30 | } 31 | } 32 | 33 | dependencies { 34 | api 'org.graphstream:gs-core:2.0' 35 | implementation 'com.android.support:appcompat-v7:26.1.0' 36 | implementation 'com.android.support.constraint:constraint-layout:1.0.2' 37 | testImplementation 'junit:junit:4.12' 38 | androidTestImplementation 'com.android.support.test:runner:1.0.1' 39 | androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.1' 40 | } 41 | 42 | ext { 43 | PUBLISH_GROUP_ID = 'org.graphstream' 44 | PUBLISH_ARTIFACT_ID = 'gs-ui-android' 45 | PUBLISH_VERSION = android.defaultConfig.versionName 46 | } 47 | 48 | apply from: "${rootProject.projectDir}/scripts/publish-mavencentral.gradle" 49 | -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile 22 | -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 10 | -------------------------------------------------------------------------------- /app/src/main/java/org/graphstream/ui/android/Backend.java: -------------------------------------------------------------------------------- 1 | package org.graphstream.ui.android; 2 | 3 | 4 | import android.graphics.Canvas; 5 | import android.graphics.Matrix; 6 | import android.graphics.Paint; 7 | import android.view.SurfaceView; 8 | 9 | import org.graphstream.ui.android.renderer.GraphBackgroundRenderer; 10 | import org.graphstream.ui.android.renderer.shape.Shape; 11 | import org.graphstream.ui.graphicGraph.StyleGroup; 12 | 13 | public interface Backend extends org.graphstream.ui.view.camera.Backend { 14 | 15 | /** 16 | * Called before any prior use of this back-end. 17 | */ 18 | void open(SurfaceView drawingSurface); 19 | 20 | /** 21 | * Called after finished using this object. 22 | */ 23 | void close(); 24 | 25 | /** 26 | * Setup the back-end for a new rendering session. 27 | */ 28 | void prepareNewFrame(Canvas g2); 29 | 30 | /** 31 | * The Java2D graphics. 32 | */ 33 | Canvas graphics2D(); 34 | 35 | /** 36 | * The brush for Canvas 37 | */ 38 | Paint getPaint(); 39 | 40 | Shape chooseNodeShape(Shape oldShape, StyleGroup group); 41 | 42 | Shape chooseEdgeShape(Shape oldShape, StyleGroup group); 43 | 44 | Shape chooseEdgeArrowShape(Shape oldShape, StyleGroup group); 45 | 46 | Shape chooseSpriteShape(Shape oldShape, StyleGroup group); 47 | 48 | GraphBackgroundRenderer chooseGraphBackgroundRenderer(); 49 | 50 | /** 51 | * The drawing surface. 52 | * The drawing surface may be different than the one passed as 53 | * argument to open(), the back-end is free to create a new surface 54 | * as it sees fit. 55 | */ 56 | SurfaceView drawingSurface(); 57 | 58 | /** 59 | * Access to currentTransform 60 | */ 61 | Matrix getMatrix(); 62 | 63 | Matrix getMatrixSurface(); 64 | 65 | void setMatrix(Matrix m) ; 66 | } 67 | -------------------------------------------------------------------------------- /app/src/main/java/org/graphstream/ui/android/renderer/AreaSkeleton.java: -------------------------------------------------------------------------------- 1 | package org.graphstream.ui.android.renderer; 2 | 3 | import org.graphstream.ui.geom.Point2; 4 | 5 | /** Skeleton for nodes and sprites. */ 6 | public class AreaSkeleton extends Skeleton implements org.graphstream.ui.view.camera.AreaSkeleton { 7 | public Point2 theCenter = new Point2(0, 0); 8 | public Point2 theSize = new Point2(0, 0); 9 | 10 | @Override 11 | public Point2 theSize() { 12 | // TODO Auto-generated method stub 13 | return theSize; 14 | } 15 | @Override 16 | public Point2 theCenter() { 17 | // TODO Auto-generated method stub 18 | return theCenter; 19 | } 20 | } -------------------------------------------------------------------------------- /app/src/main/java/org/graphstream/ui/android/renderer/EdgeRenderer.java: -------------------------------------------------------------------------------- 1 | package org.graphstream.ui.android.renderer; 2 | 3 | import org.graphstream.ui.graphicGraph.GraphicEdge; 4 | import org.graphstream.ui.graphicGraph.GraphicElement; 5 | import org.graphstream.ui.graphicGraph.StyleGroup; 6 | import org.graphstream.ui.android.Backend; 7 | import org.graphstream.ui.view.camera.DefaultCamera2D; 8 | import org.graphstream.ui.android.AndroidFullGraphRenderer; 9 | import org.graphstream.ui.android.renderer.shape.Connector; 10 | import org.graphstream.ui.android.renderer.shape.Shape; 11 | import org.graphstream.ui.android.renderer.shape.android.baseShapes.AreaOnConnectorShape; 12 | 13 | public class EdgeRenderer extends StyleRenderer { 14 | private Shape shape = null; 15 | AreaOnConnectorShape arrow = null; 16 | 17 | public EdgeRenderer(StyleGroup styleGroup) { 18 | super(styleGroup); 19 | } 20 | 21 | public EdgeRenderer(StyleGroup styleGroup, AndroidFullGraphRenderer mainRenderer) { 22 | super(styleGroup); 23 | } 24 | 25 | @Override 26 | public void setupRenderingPass(Backend bck, DefaultCamera2D camera, boolean forShadow) { 27 | shape = bck.chooseEdgeShape(shape, group); 28 | arrow = (AreaOnConnectorShape)bck.chooseEdgeArrowShape(arrow, group); 29 | } 30 | 31 | @Override 32 | public void pushStyle(Backend bck, DefaultCamera2D camera, boolean forShadow) { 33 | shape.configureForGroup(bck, group, camera); 34 | 35 | if(arrow != null) { 36 | arrow.configureForGroup(bck, group, camera); 37 | } 38 | } 39 | 40 | @Override 41 | public void pushDynStyle(Backend bck, DefaultCamera2D camera, GraphicElement element) {} 42 | 43 | @Override 44 | public void renderElement(Backend bck, DefaultCamera2D camera, GraphicElement element) { 45 | GraphicEdge edge = (GraphicEdge)element; 46 | ConnectorSkeleton skel = getOrSetConnectorSkeleton(element); 47 | shape.configureForElement(bck, element, skel, camera); 48 | shape.render(bck, camera, element, skel); 49 | 50 | if(edge.isDirected() && (arrow != null)) { 51 | arrow.theConnectorYoureAttachedTo((Connector)shape /* !!!! Test this TODO ensure this !!! */); 52 | arrow.configureForElement(bck, element, skel, camera); 53 | arrow.render(bck, camera, element, skel); 54 | } 55 | } 56 | 57 | @Override 58 | public void renderShadow(Backend bck, DefaultCamera2D camera, GraphicElement element) { 59 | GraphicEdge edge = (GraphicEdge)element; 60 | ConnectorSkeleton skel = getOrSetConnectorSkeleton(element); 61 | 62 | shape.configureForElement(bck, element, skel, camera); 63 | shape.renderShadow(bck, camera, element, skel); 64 | 65 | if(edge.isDirected() && (arrow != null)) { 66 | arrow.theConnectorYoureAttachedTo((Connector)shape /* !!!! Test this TODO ensure this !!! */); 67 | arrow.configureForElement(bck, element, skel, camera); 68 | arrow.renderShadow(bck, camera, element, skel); 69 | } 70 | } 71 | 72 | /** Retrieve the shared edge informations stored on the given edge element. 73 | * If such information is not yet present, add it to the element. 74 | * @param element The element to look for. 75 | * @return The edge information. 76 | * @throws RuntimeException if the element is not an edge. */ 77 | protected ConnectorSkeleton getOrSetConnectorSkeleton(GraphicElement element) { 78 | if(element instanceof GraphicEdge) { 79 | ConnectorSkeleton info = (ConnectorSkeleton)element.getAttribute(Skeleton.attributeName) ; 80 | 81 | if(info == null) { 82 | info = new ConnectorSkeleton(); 83 | element.setAttribute(Skeleton.attributeName, info); 84 | } 85 | 86 | return info; 87 | } 88 | else { 89 | throw new RuntimeException("Trying to get EdgeInfo on non-edge..."); 90 | } 91 | } 92 | 93 | @Override 94 | public void elementInvisible(Backend bck, DefaultCamera2D camera, GraphicElement element) {} 95 | 96 | @Override 97 | public void endRenderingPass(Backend bck, DefaultCamera2D camera, boolean forShadow) {} 98 | } 99 | -------------------------------------------------------------------------------- /app/src/main/java/org/graphstream/ui/android/renderer/NodeRenderer.java: -------------------------------------------------------------------------------- 1 | package org.graphstream.ui.android.renderer; 2 | 3 | import org.graphstream.ui.android.AndroidFullGraphRenderer; 4 | import org.graphstream.ui.android.Backend; 5 | import org.graphstream.ui.android.renderer.shape.Shape; 6 | import org.graphstream.ui.graphicGraph.GraphicElement; 7 | import org.graphstream.ui.graphicGraph.GraphicNode; 8 | import org.graphstream.ui.graphicGraph.StyleGroup; 9 | import org.graphstream.ui.view.camera.DefaultCamera2D; 10 | 11 | public class NodeRenderer extends StyleRenderer { 12 | 13 | private Shape shape = null; 14 | 15 | public NodeRenderer(StyleGroup style) { 16 | super(style); 17 | } 18 | 19 | public static StyleRenderer apply(StyleGroup style, AndroidFullGraphRenderer renderer) { 20 | return new NodeRenderer(style); 21 | } 22 | 23 | @Override 24 | public void setupRenderingPass(Backend bck, DefaultCamera2D camera, boolean forShadow) { 25 | shape = bck.chooseNodeShape(shape, group); 26 | } 27 | 28 | @Override 29 | public void pushStyle(Backend bck, DefaultCamera2D camera, boolean forShadow) { 30 | shape.configureForGroup(bck, group, camera); 31 | } 32 | 33 | @Override 34 | public void pushDynStyle(Backend bck, DefaultCamera2D camera, GraphicElement element) {} 35 | 36 | @Override 37 | public void renderElement(Backend bck, DefaultCamera2D camera, GraphicElement element) { 38 | AreaSkeleton skel = getOrSetAreaSkeleton(element); 39 | shape.configureForElement(bck, element, skel, camera); 40 | shape.render(bck, camera, element, skel); 41 | } 42 | 43 | @Override 44 | public void renderShadow(Backend bck, DefaultCamera2D camera, GraphicElement element) { 45 | AreaSkeleton skel = getOrSetAreaSkeleton(element); 46 | shape.configureForElement(bck, element, skel, camera); 47 | shape.renderShadow(bck, camera, element, skel); 48 | } 49 | 50 | @Override 51 | public void elementInvisible(Backend bck, DefaultCamera2D camera, GraphicElement element) {} 52 | 53 | /** Retrieve the area shared informations stored on the given node element. 54 | * If such information is not yet present, add it to the element. 55 | * @param element The element to look for. 56 | * @return The node information. 57 | * @throws RuntimeException if the element is not a node. */ 58 | private AreaSkeleton getOrSetAreaSkeleton(GraphicElement element) { 59 | if(element instanceof GraphicNode) { 60 | AreaSkeleton skel =(AreaSkeleton) element.getAttribute(Skeleton.attributeName); 61 | 62 | if(skel == null) { 63 | skel = new AreaSkeleton(); 64 | element.setAttribute(Skeleton.attributeName, skel); 65 | } 66 | 67 | return skel; 68 | } 69 | else { 70 | throw new RuntimeException("Trying to get AreaSkeleton on non-area (node or sprite) ..."); 71 | } 72 | } 73 | 74 | @Override 75 | public void endRenderingPass(Backend bck, DefaultCamera2D camera, boolean forShadow) { 76 | // TODO Auto-generated method stub 77 | 78 | } 79 | 80 | } 81 | -------------------------------------------------------------------------------- /app/src/main/java/org/graphstream/ui/android/renderer/SelectionRenderer.java: -------------------------------------------------------------------------------- 1 | package org.graphstream.ui.android.renderer; 2 | 3 | import android.graphics.Canvas; 4 | import android.graphics.Color; 5 | import android.graphics.Paint; 6 | 7 | import org.graphstream.ui.android.Backend; 8 | import org.graphstream.ui.android.renderer.shape.android.baseShapes.Form; 9 | import org.graphstream.ui.android.util.ColorManager; 10 | import org.graphstream.ui.android.util.Selection; 11 | import org.graphstream.ui.android.util.Stroke; 12 | import org.graphstream.ui.graphicGraph.GraphicGraph; 13 | import org.graphstream.ui.view.camera.DefaultCamera2D; 14 | 15 | public class SelectionRenderer { 16 | 17 | private Selection selection; 18 | 19 | protected Form.Rectangle2D shape = new Form.Rectangle2D(); 20 | 21 | protected int linesColorQ = Color.argb( 64,0, 0, 0 ); 22 | protected int fillColor = Color.argb( 32, 50, 50, 200); 23 | 24 | public SelectionRenderer(Selection selection, GraphicGraph graph) { 25 | this.selection = selection ; 26 | } 27 | 28 | public void render(Backend bck, DefaultCamera2D camera, int panelWidth, int panelHeight) { 29 | // XXX 30 | // TODO make this an abstract class whose implementation are create by the back-end 31 | // XXX 32 | if(selection.isActive() && selection.x1() != selection.x2() && selection.y1() != selection.y2()) { 33 | Canvas g = bck.graphics2D(); 34 | Paint p = new Paint(); 35 | 36 | float x1 = selection.x1(); 37 | float y1 = selection.y1(); 38 | float x2 = selection.x2(); 39 | float y2 = selection.y2(); 40 | float t = 0.0f; 41 | 42 | if(x1 > x2) { t = x1; x1 = x2; x2 = t; } 43 | if(y1 > y2) { t = y1; y1 = y2; y2 = t; } 44 | 45 | //int color = p.getColor(); 46 | p.setColor(linesColorQ); 47 | 48 | //float width = p.getStrokeWidth(); 49 | p.setStrokeWidth(4); 50 | 51 | shape.setFrame(x1, y1, x2-x1, y2-y1); 52 | 53 | p.setColor(fillColor); 54 | shape.drawByPoints(bck.drawingSurface(), g, p, false); 55 | 56 | p.setColor(linesColorQ); 57 | shape.drawByPoints(bck.drawingSurface(), g, p, true); 58 | 59 | //p.setColor(color); 60 | //p.setStrokeWidth(width); 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /app/src/main/java/org/graphstream/ui/android/renderer/Skeleton.java: -------------------------------------------------------------------------------- 1 | package org.graphstream.ui.android.renderer; 2 | 3 | import org.graphstream.ui.android.renderer.shape.android.IconAndText; 4 | 5 | /** Elements of rendering that, contrary to the shapes, are specific to the element, not the style 6 | * group and define the basic geometry of the shape. */ 7 | public abstract class Skeleton implements org.graphstream.ui.view.camera.Skeleton { 8 | public IconAndText iconAndText = null ; 9 | 10 | public enum EdgeShapeKind { 11 | LINE, 12 | CURVE, 13 | POLYLINE 14 | } 15 | 16 | public class Triplet { 17 | public final X i; 18 | public final Y sum; 19 | public final Z ps; 20 | 21 | public Triplet(X i, Y sum, Z ps) { 22 | this.i = i; 23 | this.sum = sum; 24 | this.ps = ps; 25 | } 26 | } 27 | } -------------------------------------------------------------------------------- /app/src/main/java/org/graphstream/ui/android/renderer/SpriteRenderer.java: -------------------------------------------------------------------------------- 1 | package org.graphstream.ui.android.renderer; 2 | 3 | import org.graphstream.ui.geom.Point3; 4 | import org.graphstream.ui.graphicGraph.GraphicElement; 5 | import org.graphstream.ui.graphicGraph.GraphicSprite; 6 | import org.graphstream.ui.graphicGraph.StyleGroup; 7 | import org.graphstream.ui.graphicGraph.stylesheet.StyleConstants; 8 | import org.graphstream.ui.android.Backend; 9 | import org.graphstream.ui.view.camera.DefaultCamera2D; 10 | import org.graphstream.ui.android.AndroidFullGraphRenderer; 11 | import org.graphstream.ui.android.renderer.shape.Shape; 12 | 13 | public class SpriteRenderer extends StyleRenderer { 14 | 15 | private Shape shape = null; 16 | 17 | public SpriteRenderer(StyleGroup style) { 18 | super(style); 19 | } 20 | 21 | public static StyleRenderer apply(StyleGroup style, AndroidFullGraphRenderer renderer) { 22 | return new SpriteRenderer( style ); 23 | } 24 | 25 | @Override 26 | public void setupRenderingPass(Backend bck, DefaultCamera2D camera, boolean forShadow) { 27 | shape = bck.chooseSpriteShape(shape, group); 28 | } 29 | 30 | @Override 31 | public void pushStyle(Backend bck, DefaultCamera2D camera, boolean forShadow) { 32 | shape.configureForGroup(bck, group, camera); 33 | } 34 | 35 | @Override 36 | public void pushDynStyle(Backend bck, DefaultCamera2D camera, GraphicElement element) {} 37 | 38 | @Override 39 | public void renderElement(Backend bck, DefaultCamera2D camera, GraphicElement element) { 40 | GraphicSprite sprite = (GraphicSprite)element; 41 | AreaSkeleton skel = getOrSetAreaSkeleton(element); 42 | 43 | shape.configureForElement(bck, element, skel, camera); 44 | shape.render(bck, camera, element, skel); 45 | } 46 | 47 | @Override 48 | public void renderShadow(Backend bck, DefaultCamera2D camera, GraphicElement element) { 49 | GraphicSprite sprite = (GraphicSprite)element; 50 | Point3 pos = camera.getSpritePosition(sprite, new Point3(), StyleConstants.Units.GU); 51 | AreaSkeleton skel = getOrSetAreaSkeleton(element); 52 | 53 | shape.configureForElement(bck, element, skel, camera); 54 | shape.renderShadow(bck, camera, element, skel); 55 | } 56 | 57 | @Override 58 | public void elementInvisible(Backend bck, DefaultCamera2D camera, GraphicElement element) {} 59 | 60 | private AreaSkeleton getOrSetAreaSkeleton(GraphicElement element) { 61 | if(element instanceof GraphicSprite) { 62 | AreaSkeleton info = (AreaSkeleton)element.getAttribute(Skeleton.attributeName); 63 | 64 | if(info == null) { 65 | info = new AreaSkeleton(); 66 | element.setAttribute(Skeleton.attributeName, info); 67 | } 68 | 69 | return info; 70 | } 71 | else { 72 | throw new RuntimeException("Trying to get NodeInfo on non-node ..."); 73 | } 74 | } 75 | 76 | @Override 77 | public void endRenderingPass(Backend bck, DefaultCamera2D camera, boolean forShadow) { 78 | // TODO Auto-generated method stub 79 | 80 | } 81 | 82 | 83 | 84 | } 85 | -------------------------------------------------------------------------------- /app/src/main/java/org/graphstream/ui/android/renderer/shape/AreaOnConnector.java: -------------------------------------------------------------------------------- 1 | package org.graphstream.ui.android.renderer.shape; 2 | 3 | import org.graphstream.ui.graphicGraph.GraphicEdge; 4 | import org.graphstream.ui.graphicGraph.stylesheet.Style; 5 | import org.graphstream.ui.view.camera.DefaultCamera2D; 6 | import org.graphstream.ui.android.renderer.shape.android.Area; 7 | 8 | /** Some areas are attached to a connector (sprites). */ 9 | public class AreaOnConnector extends Area { 10 | /** The connector we are attached to. */ 11 | protected Connector theConnector = null; 12 | 13 | /** The edge represented by the connector.. */ 14 | protected GraphicEdge theEdge = null; 15 | 16 | /** XXX must call this method explicitly in the renderer !!! bad !!! XXX */ 17 | public void theConnectorYoureAttachedTo(Connector connector) { theConnector = connector; } 18 | 19 | protected void configureAreaOnConnectorForGroup(Style style, DefaultCamera2D camera) { 20 | sizeForEdgeArrow(style, camera); 21 | } 22 | 23 | protected void configureAreaOnConnectorForElement(GraphicEdge edge, Style style, DefaultCamera2D camera) { 24 | connector(edge); 25 | theCenter.set(edge.to.getX(), edge.to.getY()); 26 | } 27 | 28 | private void connector(GraphicEdge edge) { theEdge = edge ; } 29 | 30 | private void sizeForEdgeArrow(Style style, DefaultCamera2D camera) { 31 | double w = camera.getMetrics().lengthToGu(style.getArrowSize(), 0); 32 | double h = w ; 33 | if(style.getArrowSize().size() > 1) 34 | h = camera.getMetrics().lengthToGu(style.getArrowSize(), 1) ; 35 | 36 | theSize.set(w, h); 37 | } 38 | 39 | } -------------------------------------------------------------------------------- /app/src/main/java/org/graphstream/ui/android/renderer/shape/Decorable.java: -------------------------------------------------------------------------------- 1 | package org.graphstream.ui.android.renderer.shape; 2 | 3 | import android.graphics.RectF; 4 | 5 | import org.graphstream.ui.graphicGraph.GraphicEdge; 6 | import org.graphstream.ui.graphicGraph.GraphicElement; 7 | import org.graphstream.ui.graphicGraph.StyleGroup; 8 | import org.graphstream.ui.graphicGraph.stylesheet.Style; 9 | import org.graphstream.ui.android.Backend; 10 | import org.graphstream.ui.view.camera.DefaultCamera2D; 11 | import org.graphstream.ui.android.renderer.Skeleton; 12 | import org.graphstream.ui.android.renderer.shape.android.IconAndText; 13 | import org.graphstream.ui.android.renderer.shape.android.ShapeDecor; 14 | import org.graphstream.ui.android.renderer.shape.android.baseShapes.Form; 15 | 16 | /** Trait for shapes that can be decorated by an icon and/or a text. */ 17 | public class Decorable extends HasSkel { 18 | /** The string of text of the contents. */ 19 | public String text = null; 20 | 21 | /** The text and icon. */ 22 | public ShapeDecor theDecor = null ; 23 | 24 | /** Paint the decorations (text and icon). */ 25 | public void decorArea(Backend backend, DefaultCamera2D camera, IconAndText iconAndText, GraphicElement element, Form shape ) { 26 | boolean visible = true ; 27 | if( element != null ) visible = camera.isTextVisible( element ); 28 | if( theDecor != null && visible ) { 29 | RectF bounds = shape.getBounds(); 30 | theDecor.renderInside(backend, camera, iconAndText, bounds.left, bounds.top, bounds.right, bounds.bottom ); 31 | } 32 | } 33 | 34 | public void decorConnector(Backend backend, DefaultCamera2D camera, IconAndText iconAndText, GraphicElement element, Form shape ) { 35 | boolean visible = true ; 36 | if( element != null ) visible = camera.isTextVisible( element ); 37 | if( theDecor != null && visible ) { 38 | if ( element instanceof GraphicEdge ) { 39 | GraphicEdge edge = (GraphicEdge)element; 40 | if((skel != null) && (skel.isCurve())) { 41 | theDecor.renderAlong(backend, camera, iconAndText, skel); 42 | } 43 | else { 44 | theDecor.renderAlong(backend, camera, iconAndText, edge.from.x, edge.from.y, edge.to.x, edge.to.y); 45 | } 46 | } 47 | else { 48 | RectF bounds = shape.getBounds(); 49 | theDecor.renderAlong(backend, camera, iconAndText, bounds.left, bounds.top, bounds.right, bounds.bottom ); 50 | } 51 | } 52 | } 53 | 54 | /** Configure all the static parts needed to decor the shape. */ 55 | public void configureDecorableForGroup( Style style, DefaultCamera2D camera) { 56 | /*if( theDecor == null )*/ theDecor = ShapeDecor.apply( style ); 57 | } 58 | /** Setup the parts of the decor specific to each element. */ 59 | public void configureDecorableForElement(Backend backend, DefaultCamera2D camera, GraphicElement element, Skeleton skel) { 60 | text = element.label; 61 | if( skel != null ) { 62 | StyleGroup style = element.getStyle(); 63 | skel.iconAndText = IconAndText.apply( style, camera, element ); 64 | if( style.getIcon() != null && style.getIcon().equals( "dynamic" ) && element.hasAttribute( "ui.icon" ) ) { 65 | String url = element.getLabel("ui.icon").toString(); 66 | skel.iconAndText.setIcon(backend, url); 67 | } 68 | skel.iconAndText.setText(backend, element.label); 69 | } 70 | } 71 | } -------------------------------------------------------------------------------- /app/src/main/java/org/graphstream/ui/android/renderer/shape/Orientable.java: -------------------------------------------------------------------------------- 1 | package org.graphstream.ui.android.renderer.shape; 2 | 3 | import org.graphstream.ui.geom.Point3; 4 | import org.graphstream.ui.geom.Vector2; 5 | import org.graphstream.ui.graphicGraph.GraphicEdge; 6 | import org.graphstream.ui.graphicGraph.GraphicNode; 7 | import org.graphstream.ui.graphicGraph.GraphicSprite; 8 | import org.graphstream.ui.graphicGraph.stylesheet.Style; 9 | import org.graphstream.ui.graphicGraph.stylesheet.StyleConstants.SpriteOrientation; 10 | import org.graphstream.ui.view.camera.DefaultCamera2D; 11 | import org.graphstream.ui.android.renderer.ConnectorSkeleton; 12 | import org.graphstream.ui.android.renderer.Skeleton; 13 | 14 | /** Trait for all shapes that points at a direction. */ 15 | public class Orientable { 16 | /** The shape orientation. */ 17 | SpriteOrientation orientation = null ; 18 | 19 | /** The shape target. */ 20 | public Point3 target = new Point3(); 21 | 22 | /** Configure the orientation mode for the group according to the style. */ 23 | public void configureOrientableForGroup(Style style, DefaultCamera2D camera) { orientation = style.getSpriteOrientation(); } 24 | 25 | /** Compute the orientation vector for the given element according to the orientation mode. */ 26 | public void configureOrientableForElement(DefaultCamera2D camera, GraphicSprite sprite) { 27 | if ( sprite.getAttachment() instanceof GraphicNode ) { 28 | switch (sprite.getStyle().getSpriteOrientation()) { 29 | case NONE: 30 | target.set(0, 0); 31 | break; 32 | case FROM: 33 | target.set(((GraphicNode)sprite.getAttachment()).getX(), ((GraphicNode)sprite.getAttachment()).getY()); 34 | break; 35 | case TO: 36 | target.set(((GraphicNode)sprite.getAttachment()).getX(), ((GraphicNode)sprite.getAttachment()).getY()); 37 | break; 38 | case PROJECTION: 39 | target.set(((GraphicNode)sprite.getAttachment()).getX(), ((GraphicNode)sprite.getAttachment()).getY()); 40 | break; 41 | default: 42 | break; 43 | } 44 | } 45 | else if ( sprite.getAttachment() instanceof GraphicEdge ) { 46 | switch (sprite.getStyle().getSpriteOrientation()) { 47 | case NONE: 48 | target.set(0, 0); 49 | break; 50 | case FROM: 51 | target.set(((GraphicEdge)sprite.getAttachment()).from.getX(), ((GraphicEdge)sprite.getAttachment()).from.getY()); 52 | break; 53 | case TO: 54 | target.set(((GraphicEdge)sprite.getAttachment()).to.getX(), ((GraphicEdge)sprite.getAttachment()).to.getY()); 55 | break; 56 | case PROJECTION: 57 | ConnectorSkeleton ei = (ConnectorSkeleton)((GraphicEdge)sprite.getAttachment()).getAttribute(Skeleton.attributeName) ; 58 | if(ei != null) 59 | ei.pointOnShape(sprite.getX(), target) ; 60 | else 61 | setTargetOnLineEdge(camera, sprite, (GraphicEdge)sprite.getAttachment()) ; 62 | break; 63 | default: 64 | break; 65 | } 66 | } 67 | else { 68 | orientation = SpriteOrientation.NONE ; 69 | } 70 | } 71 | 72 | private void setTargetOnLineEdge(DefaultCamera2D camera, GraphicSprite sprite, GraphicEdge ge) { 73 | Vector2 dir = new Vector2(ge.to.getX()-ge.from.getX(), ge.to.getY()-ge.from.getY()); 74 | dir.scalarMult(sprite.getX()); 75 | target.set(ge.from.getX() + dir.x(), ge.from.getY() + dir.y()); 76 | } 77 | } -------------------------------------------------------------------------------- /app/src/main/java/org/graphstream/ui/android/renderer/shape/Shape.java: -------------------------------------------------------------------------------- 1 | package org.graphstream.ui.android.renderer.shape; 2 | 3 | import org.graphstream.ui.android.Backend; 4 | import org.graphstream.ui.android.renderer.Skeleton; 5 | import org.graphstream.ui.graphicGraph.GraphicElement; 6 | import org.graphstream.ui.graphicGraph.stylesheet.Style; 7 | import org.graphstream.ui.view.camera.DefaultCamera2D; 8 | 9 | public interface Shape { 10 | /** Configure as much as possible the graphics before painting several version of this shape 11 | * at different positions. 12 | * @param backend The rendering back-end. 13 | * @param style The style for the group. 14 | * @param camera the view parameters. */ 15 | void configureForGroup(Backend backend, Style style, DefaultCamera2D camera) ; 16 | 17 | /** Configure all the dynamic and per element settings. 18 | * Some configurations can only be done before painting the element, since they change for 19 | * each element. 20 | * @param backend The rendering back-end. 21 | * @param element The specific element to render. 22 | * @param skeleton The element geometry and information. 23 | * @param camera the view parameters. */ 24 | void configureForElement(Backend backend, GraphicElement element, Skeleton skeleton, DefaultCamera2D camera); 25 | 26 | /** Must create the shape from informations given earlier, that is, resize it if needed and 27 | * position it, and do all the things that are specific to each element, and cannot be done 28 | * for the group of elements. 29 | * This method is made to be called inside the render() method, hence it is protected. 30 | * @param backend The rendering back-end. 31 | * @param camera the view parameters. */ 32 | void make(Backend backend, DefaultCamera2D camera); 33 | 34 | /** Same as {@link #make(Camera)} for the shadow shape. The shadow shape may be moved and 35 | * resized compared to the original shape. This method is made to be called inside the 36 | * renderShadow() method, hence it is protected. */ 37 | void makeShadow(Backend backend, DefaultCamera2D camera); 38 | 39 | /** Render the shape for the given element. 40 | * @param backend The rendering back-end. 41 | * @param camera The view parameters. 42 | * @param element The element to render. 43 | * @param skeleton The element geometry and information. */ 44 | void render(Backend bck, DefaultCamera2D camera, GraphicElement element, Skeleton skeleton); 45 | 46 | /** Render the shape shadow for the given element. The shadow is rendered in a different pass 47 | * than usual rendering, therefore it is a separate method. */ 48 | void renderShadow(Backend bck, DefaultCamera2D camera, GraphicElement element, Skeleton skeleton); 49 | } 50 | -------------------------------------------------------------------------------- /app/src/main/java/org/graphstream/ui/android/renderer/shape/android/Area.java: -------------------------------------------------------------------------------- 1 | package org.graphstream.ui.android.renderer.shape.android; 2 | 3 | import org.graphstream.ui.geom.Point2; 4 | import org.graphstream.ui.geom.Point3; 5 | import org.graphstream.ui.graphicGraph.GraphicElement; 6 | import org.graphstream.ui.graphicGraph.stylesheet.Style; 7 | import org.graphstream.ui.graphicGraph.stylesheet.StyleConstants; 8 | import org.graphstream.ui.android.Backend; 9 | import org.graphstream.ui.view.camera.DefaultCamera2D; 10 | import org.graphstream.ui.android.renderer.AreaSkeleton; 11 | 12 | /** Trait for elements painted inside an area (most nodes and sprites). 13 | * 14 | * This trait manages the size of the area (the size is rectangular, although the area may not 15 | * be), its position, and the automatic fit to the contents, if needed. 16 | * 17 | * As this trait computes the position and size of the shape, it should 18 | * probably be configured first when assembling the configureForGroup 19 | * and configureForElement methods. */ 20 | public class Area { 21 | /** The shape position. */ 22 | public Point2 theCenter = new Point2(); 23 | 24 | /** The shape size. */ 25 | public Point2 theSize = new Point2(); 26 | 27 | /** Fit the shape size to its contents? */ 28 | protected boolean fit = false; 29 | 30 | public void configureAreaForGroup(Style style, DefaultCamera2D camera) { 31 | sizeForGroup(style, camera); 32 | } 33 | 34 | /** Select the general size and position of the shape. 35 | * This is done according to: 36 | * - The style, 37 | * - Eventually the element specific size attribute, 38 | * - Eventually the element contents (decor). */ 39 | public void configureAreaForElement(Backend backend, DefaultCamera2D camera, AreaSkeleton skel, GraphicElement element, ShapeDecor decor) { 40 | Point3 pos = camera.getNodeOrSpritePositionGU(element, null); 41 | 42 | if(fit) { 43 | Tuple decorSize = decor.size(backend, camera, skel.iconAndText); 44 | if(decorSize.val1 == 0 || decorSize.val2 == 0) 45 | sizeForElement(element.getStyle(), camera, element); 46 | positionAndFit(camera, skel, element, pos.x, pos.y, decorSize.val1, decorSize.val2); 47 | } 48 | else { 49 | sizeForElement(element.getStyle(), camera, element); 50 | positionAndFit(camera, skel, element, pos.x, pos.y, 0, 0); 51 | } 52 | } 53 | 54 | /** Set the general size of the area according to the style. 55 | * Also look if the style SizeMode says if the element must fit to its contents. 56 | * If so, the configureAreaForElement() method will recompute the size for each 57 | * element according to the contents (shape decoration). */ 58 | private void sizeForGroup(Style style, DefaultCamera2D camera) { 59 | double w = camera.getMetrics().lengthToGu( style.getSize(), 0 ); 60 | double h = w; 61 | if( style.getSize().size() > 1 ) 62 | h = camera.getMetrics().lengthToGu( style.getSize(), 1 ); 63 | 64 | 65 | theSize.set(w, h); 66 | fit = (style.getSizeMode() == StyleConstants.SizeMode.FIT); 67 | } 68 | 69 | /** Try to compute the size of this area according to the given element. */ 70 | private void sizeForElement(Style style, DefaultCamera2D camera, GraphicElement element) { 71 | double w = camera.getMetrics().lengthToGu(style.getSize(), 0); 72 | double h = w ; 73 | if(style.getSize().size() > 1) 74 | h = camera.getMetrics().lengthToGu(style.getSize(), 1) ; 75 | 76 | if(style.getSizeMode() == StyleConstants.SizeMode.DYN_SIZE) { 77 | Object s = element.getAttribute("ui.size"); 78 | 79 | if(s != null) { 80 | w = camera.getMetrics().lengthToGu(StyleConstants.convertValue(s)); 81 | h = w; 82 | } 83 | } 84 | 85 | theSize.set(w, h); 86 | } 87 | 88 | /** Assign a position to the shape according to the element, set the size of the element, 89 | * and update the skeleton of the element. */ 90 | private void positionAndFit(DefaultCamera2D camera, AreaSkeleton skel, GraphicElement element, double x, double y, double contentOverallWidth, double contentOverallHeight) { 91 | if(skel != null) { 92 | if(contentOverallWidth > 0 && contentOverallHeight > 0) 93 | theSize.set(contentOverallWidth, contentOverallHeight); 94 | 95 | skel.theSize.copy(theSize); 96 | skel.theCenter.copy(theCenter); 97 | } 98 | 99 | theCenter.set(x, y); 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /app/src/main/java/org/graphstream/ui/android/renderer/shape/android/ShapeStroke.java: -------------------------------------------------------------------------------- 1 | package org.graphstream.ui.android.renderer.shape.android; 2 | 3 | import android.graphics.Canvas; 4 | import android.graphics.Paint; 5 | 6 | import org.graphstream.ui.graphicGraph.stylesheet.Style; 7 | import org.graphstream.ui.android.renderer.shape.android.baseShapes.Form; 8 | import org.graphstream.ui.android.renderer.shape.android.baseShapes.Form.Ellipse2D; 9 | import org.graphstream.ui.android.renderer.shape.android.baseShapes.Form.Rectangle2D; 10 | import org.graphstream.ui.android.util.ColorManager; 11 | import org.graphstream.ui.android.util.Stroke; 12 | 13 | public abstract class ShapeStroke { 14 | public abstract Stroke stroke(float width, Form shape, int fillColor) ; 15 | 16 | public static ShapeStroke strokeForArea(Style style) { 17 | switch (style.getStrokeMode()) { 18 | case PLAIN: return new PlainShapeStroke(); 19 | case DOTS: return new DotsShapeStroke(); 20 | case DASHES: return new DashesShapeStroke(); 21 | case DOUBLE: return new DoubleShapeStroke(); 22 | default: return null ; 23 | } 24 | } 25 | 26 | public static ShapeStroke strokeForConnectorFill(Style style) { 27 | switch (style.getFillMode()) { 28 | case PLAIN: return new PlainShapeStroke(); 29 | case DYN_PLAIN: return new PlainShapeStroke(); 30 | case NONE: return null ; // Gracefully handled by the drawing part. 31 | default: return new PlainShapeStroke() ; 32 | } 33 | } 34 | 35 | public ShapeStroke strokeForConnectorStroke(Style style) { 36 | return strokeForArea(style); 37 | } 38 | 39 | public static int strokeColor(Style style) { 40 | if( style.getStrokeMode() != org.graphstream.ui.graphicGraph.stylesheet.StyleConstants.StrokeMode.NONE ) { 41 | return ColorManager.getStrokeColor(style, 0); 42 | } 43 | else { 44 | return -1; 45 | } 46 | } 47 | } 48 | 49 | class PlainShapeStroke extends ShapeStroke { 50 | private float oldWidth = 0.0f ; 51 | private Stroke oldStroke = null ; 52 | 53 | @Override 54 | public Stroke stroke(float width, Form shape, int fillColor) { 55 | return stroke(width); 56 | } 57 | 58 | public Stroke stroke(float width) { 59 | if( width == oldWidth ) { 60 | if( oldStroke == null ) 61 | oldStroke = new Stroke( width ); 62 | return oldStroke; 63 | } 64 | else { 65 | oldWidth = width; 66 | oldStroke = new Stroke( width ); 67 | return oldStroke; 68 | } 69 | } 70 | } 71 | 72 | class DotsShapeStroke extends ShapeStroke { 73 | private float oldWidth = 0.0f ; 74 | private Stroke oldStroke = null ; 75 | 76 | @Override 77 | public Stroke stroke(float width, Form shape, int fillColor) { 78 | return stroke(width); 79 | } 80 | 81 | public Stroke stroke(float width) { 82 | if( width == oldWidth ) { 83 | if( oldStroke == null ) { 84 | oldStroke = new Stroke( width, width, Paint.Cap.BUTT); 85 | } 86 | return oldStroke; 87 | } else { 88 | oldWidth = width; 89 | oldStroke = new Stroke( width, width, Paint.Cap.BUTT); 90 | return oldStroke; 91 | } 92 | } 93 | } 94 | 95 | class DashesShapeStroke extends ShapeStroke { 96 | private float oldWidth = 0.0f ; 97 | private Stroke oldStroke = null ; 98 | 99 | @Override 100 | public Stroke stroke(float width, Form shape, int fillColor) { 101 | return stroke(width); 102 | } 103 | 104 | public Stroke stroke(float width) { 105 | if( width == oldWidth ) { 106 | if( oldStroke == null ){ 107 | oldStroke = new Stroke( width, (3*width), Paint.Cap.BUTT); 108 | } 109 | return oldStroke ; 110 | } else { 111 | oldWidth = width ; 112 | oldStroke = new Stroke( width, (3*width), Paint.Cap.BUTT); 113 | return oldStroke ; 114 | } 115 | } 116 | } 117 | 118 | class DoubleShapeStroke extends ShapeStroke { 119 | 120 | @Override 121 | public Stroke stroke(float width, Form shape, int fillColor) { 122 | return new CompositeStroke( new Stroke(width*3), new Stroke(width), width, shape, fillColor); 123 | } 124 | 125 | class CompositeStroke extends Stroke { 126 | private Stroke stroke1 ; 127 | private Stroke stroke2 ; 128 | private Form form ; 129 | private int fillColor ; 130 | 131 | public CompositeStroke(Stroke stroke1, Stroke stroke2, float w, Form form, int fillColor) { 132 | super(w); 133 | this.stroke1 = stroke1 ; 134 | this.stroke2 = stroke2 ; 135 | this.form = form ; 136 | this.fillColor = fillColor ; 137 | } 138 | 139 | @Override 140 | public void changeStrokeProperties(Canvas g, Paint p) { 141 | // if form is null ==> debug in FillableLine 142 | 143 | if (form.getIdForm().equals("Rect")) { 144 | ((Rectangle2D)form).setDoubleStroke(stroke1, stroke2, fillColor); 145 | } 146 | else if (form.getIdForm().equals("Path")) { 147 | System.err.println("DoubleStroke for Path not implemented yet"); 148 | stroke2.changeStrokeProperties(g, p); 149 | } 150 | else if (form.getIdForm().equals("CubicCurve")) { 151 | System.err.println("DoubleStroke for CubicCurve not implemented yet"); 152 | stroke2.changeStrokeProperties(g, p); 153 | } 154 | else if (form.getIdForm().equals("Line")) { 155 | float[][] path = (float[][]) form.getPath(); 156 | float x1 = path[0][0]; 157 | float y1 = path[0][1]; 158 | float x2 = path[1][0]; 159 | float y2 = path[1][1]; 160 | 161 | stroke2.changeStrokeProperties(g, p); 162 | double angle = Math.toDegrees(Math.atan2(y2-y1, x2-x1) - Math.atan2(1, 1)); 163 | if ( angle >= 90 || angle <= -180 || (angle >= -90 && angle < 0)) { 164 | y1 += width*3 ; 165 | y2 += width*3 ; 166 | } 167 | else { 168 | x1 += width*3 ; 169 | x2 += width*3 ; 170 | } 171 | p.setStyle(Paint.Style.STROKE); 172 | g.drawLine(x1, y1, x2, y2, p); 173 | } 174 | else if (form.getIdForm().equals("Ellipse")) { 175 | ((Ellipse2D)form).setDoubleStroke(stroke1, stroke2, fillColor); 176 | } 177 | } 178 | } 179 | } 180 | 181 | -------------------------------------------------------------------------------- /app/src/main/java/org/graphstream/ui/android/renderer/shape/android/ShowCubics.java: -------------------------------------------------------------------------------- 1 | package org.graphstream.ui.android.renderer.shape.android; 2 | 3 | import android.graphics.Canvas; 4 | import android.graphics.Color; 5 | import android.graphics.Paint; 6 | 7 | import org.graphstream.ui.android.util.ColorManager; 8 | import org.graphstream.ui.geom.Point3; 9 | import org.graphstream.ui.android.renderer.ConnectorSkeleton; 10 | import org.graphstream.ui.view.camera.Camera; 11 | 12 | /** Utility trait to display cubics Bézier curves control polygons. */ 13 | public class ShowCubics { 14 | public boolean showControlPolygon = false ; 15 | 16 | /** Show the control polygons. */ 17 | public void showCtrlPoints(Canvas g, Paint p, Camera camera, ConnectorSkeleton skel) { 18 | if (showControlPolygon && skel.isCurve()) { 19 | Point3 from = skel.from(); 20 | Point3 ctrl1 = skel.apply(1); 21 | Point3 ctrl2 = skel.apply(2); 22 | Point3 to = skel.to(); 23 | 24 | int color = p.getColor(); 25 | float stroke = p.getStrokeWidth(); 26 | 27 | double px6 = camera.getMetrics().px1 * 6; 28 | double px3 = camera.getMetrics().px1 * 3; 29 | 30 | p.setColor(Color.RED); 31 | p.setStyle(Paint.Style.FILL); 32 | g.drawOval((float)(from.x - px3), (float)(from.y - px3), (float)px6, (float)px6, p); 33 | 34 | if (ctrl1 != null) { 35 | g.drawOval((float)(ctrl1.x - px3), (float)(ctrl1.y - px3), (float)px6, (float)px6, p); 36 | 37 | g.drawOval((float)(ctrl2.x - px3), (float)(ctrl2.y - px3), (float)px6, (float)px6, p); 38 | 39 | p.setStyle(Paint.Style.STROKE); 40 | p.setStrokeWidth((float)camera.getMetrics().px1); 41 | g.drawLine((float)ctrl1.x, (float)ctrl1.y, (float)ctrl2.x, (float)ctrl2.y, p); 42 | 43 | g.drawLine((float)from.x, (float)from.y, (float)ctrl1.x, (float)ctrl1.y, p); 44 | 45 | g.drawLine((float)ctrl2.x, (float)ctrl2.y, (float)to.x, (float)to.y, p); 46 | } 47 | 48 | p.setStyle(Paint.Style.FILL); 49 | g.drawOval((float)(to.x - px3), (float)(to.y - px3), (float)px6, (float)px6, p); 50 | 51 | p.setColor(color); 52 | p.setStrokeWidth(stroke); 53 | } 54 | } 55 | } -------------------------------------------------------------------------------- /app/src/main/java/org/graphstream/ui/android/renderer/shape/android/advancedShapes/CubicCurveShape.java: -------------------------------------------------------------------------------- 1 | package org.graphstream.ui.android.renderer.shape.android.advancedShapes; 2 | 3 | import android.graphics.Canvas; 4 | import android.graphics.Paint; 5 | 6 | import org.graphstream.ui.geom.Vector2; 7 | import org.graphstream.ui.graphicGraph.GraphicElement; 8 | import org.graphstream.ui.android.Backend; 9 | import org.graphstream.ui.view.camera.DefaultCamera2D; 10 | import org.graphstream.ui.android.renderer.Skeleton; 11 | import org.graphstream.ui.android.renderer.shape.android.ShowCubics; 12 | import org.graphstream.ui.android.renderer.shape.android.baseShapes.LineConnectorShape; 13 | import org.graphstream.ui.android.renderer.shape.android.baseShapes.Form.Path2D; 14 | 15 | public class CubicCurveShape extends LineConnectorShape { 16 | ShowCubics showCubics ; 17 | Path2D theShape = new Path2D(0, false); 18 | 19 | public CubicCurveShape() { 20 | this.showCubics = new ShowCubics() ; 21 | } 22 | 23 | @Override 24 | public void make(Backend backend, DefaultCamera2D camera) { 25 | make(camera, 0, 0, 0, 0); 26 | } 27 | 28 | private void make(DefaultCamera2D camera, double sox, double soy, double swx, double swy) { 29 | if (skel.multi() > 1 || skel.isLoop()) // is a loop or a multi edge 30 | makeMultiOrLoop(camera, sox, soy, swx, swy); 31 | else if(skel.isPoly() && skel.size() == 4) 32 | makeFromPoints(camera, sox, soy, swx, swy); // has points positions 33 | else 34 | makeSingle(camera, sox, soy, swx, swy); // is a single edge. 35 | } 36 | 37 | private void makeMultiOrLoop(DefaultCamera2D camera, double sox, double soy, double swx, double swy) { 38 | if (skel.isLoop()) 39 | makeLoop(camera, sox, soy, swx, swy); 40 | else 41 | makeMulti(camera, sox, soy, swx, swy); 42 | } 43 | 44 | private void makeLoop(DefaultCamera2D camera, double sox, double soy, double swx, double swy) { 45 | double fromx = skel.apply(0).x + sox; 46 | double fromy = skel.apply(0).y + soy; 47 | double tox = skel.apply(3).x + sox; 48 | double toy = skel.apply(3).y + soy; 49 | double c1x = skel.apply(1).x + sox; 50 | double c1y = skel.apply(1).y + soy; 51 | double c2x = skel.apply(2).x + sox; 52 | double c2y = skel.apply(2).y + soy; 53 | 54 | theShape = new Path2D(5, false); 55 | theShape.moveTo(fromx, fromy); 56 | theShape.curveTo(c1x, c1y, c2x, c2y, tox, toy); 57 | } 58 | 59 | private void makeMulti(DefaultCamera2D camera, double sox, double soy, double swx, double swy) { 60 | double fromx = skel.apply(0).x + sox; 61 | double fromy = skel.apply(0).y + soy; 62 | double tox = skel.apply(3).x + sox; 63 | double toy = skel.apply(3).y + soy; 64 | double c1x = skel.apply(1).x + sox; 65 | double c1y = skel.apply(1).y + soy; 66 | double c2x = skel.apply(2).x + sox; 67 | double c2y = skel.apply(2).y + soy; 68 | 69 | theShape = new Path2D(5, false); 70 | theShape.moveTo(fromx, fromy); 71 | theShape.curveTo(c1x, c1y, c2x, c2y, tox, toy); 72 | } 73 | 74 | private void makeFromPoints(DefaultCamera2D camera, double sox, double soy, double swx, double swy) { 75 | double fromx = skel.from().x + sox; 76 | double fromy = skel.from().y + soy; 77 | double tox = skel.to().x + sox; 78 | double toy = skel.to().y + soy; 79 | double c1x = skel.apply(1).x + sox; 80 | double c1y = skel.apply(1).y + soy; 81 | double c2x = skel.apply(2).x + sox; 82 | double c2y = skel.apply(2).y + soy; 83 | 84 | theShape = new Path2D(5, false); 85 | theShape.moveTo(fromx, fromy); 86 | theShape.curveTo(c1x, c1y, c2x, c2y, tox, toy); 87 | 88 | if (sox == 0 && soy == 0) { // Inform the system this is a curve, not a polyline. 89 | skel.setCurve( 90 | fromx, fromy, 0, 91 | c1x, c1y, 0, 92 | c2x, c2y, 0, 93 | tox, toy, 0); 94 | } 95 | } 96 | 97 | private void makeSingle(DefaultCamera2D camera, double sox, double soy, double swx, double swy) { 98 | double fromx = skel.from().x + sox; 99 | double fromy = skel.from().y + soy; 100 | double tox = skel.to().x + sox; 101 | double toy = skel.to().y + soy; 102 | Vector2 mainDir = new Vector2(skel.from(), skel.to()); 103 | double length = mainDir.length(); 104 | double angle = mainDir.y() / length; 105 | double c1x = 0.0; 106 | double c1y = 0.0; 107 | double c2x = 0.0; 108 | double c2y = 0.0; 109 | 110 | if (angle > 0.707107f || angle < -0.707107f) { 111 | // North or south. 112 | c1x = fromx + mainDir.x() / 2; 113 | c2x = c1x; 114 | c1y = fromy; 115 | c2y = toy; 116 | } 117 | else { 118 | // East or west. 119 | c1x = fromx; 120 | c2x = tox; 121 | c1y = fromy + mainDir.y() / 2; 122 | c2y = c1y; 123 | } 124 | 125 | theShape = new Path2D(5, false); 126 | theShape.moveTo(fromx, fromy); 127 | theShape.curveTo(c1x, c1y, c2x, c2y, tox, toy); 128 | 129 | // Set the connector as a curve. 130 | 131 | if (sox == 0 && soy == 0) { 132 | skel.setCurve( 133 | fromx, fromy, 0, 134 | c1x, c1y, 0, 135 | c2x, c2y, 0, 136 | tox, toy, 0); 137 | } 138 | } 139 | 140 | @Override 141 | public void makeShadow(Backend backend, DefaultCamera2D camera) { 142 | if (skel.isCurve()) 143 | makeMultiOrLoop(camera, shadowableLine.theShadowOff.x, shadowableLine.theShadowOff.y, shadowableLine.theShadowWidth, shadowableLine.theShadowWidth); 144 | else 145 | makeSingle(camera, shadowableLine.theShadowOff.x, shadowableLine.theShadowOff.y, shadowableLine.theShadowWidth, shadowableLine.theShadowWidth); 146 | } 147 | 148 | @Override 149 | public void render(Backend bck, DefaultCamera2D camera, GraphicElement element, Skeleton skeleton) { 150 | Canvas g = bck.graphics2D(); 151 | Paint p = bck.getPaint(); 152 | make(bck, camera); 153 | strokableLine.stroke(bck.drawingSurface(), g, p, theShape); 154 | fillableLine.fill(bck.drawingSurface(), g, p, theSize, theShape); 155 | decorable.decorConnector(bck, camera, skel.iconAndText, element, theShape); 156 | // showControlPolygon = true 157 | // if( showControlPolygon ) { 158 | // val c = g.getColor(); 159 | // val s = g.getStroke(); 160 | // g.setStroke( new java.awt.BasicStroke( camera.metrics.px1 ) ) 161 | // g.setColor( Color.red ); 162 | // g.draw( theShape ); 163 | // g.setStroke( s ); 164 | // g.setColor( c ); 165 | // showCtrlPoints( g, camera ) 166 | // } 167 | } 168 | 169 | @Override 170 | public void renderShadow(Backend bck, DefaultCamera2D camera, GraphicElement element, Skeleton skeleton) { 171 | makeShadow(bck, camera); 172 | shadowableLine.cast(bck.drawingSurface(), bck.graphics2D(), bck.getPaint(), theShape); 173 | } 174 | } -------------------------------------------------------------------------------- /app/src/main/java/org/graphstream/ui/android/renderer/shape/android/advancedShapes/FreePlaneEdgeShape.java: -------------------------------------------------------------------------------- 1 | package org.graphstream.ui.android.renderer.shape.android.advancedShapes; 2 | 3 | import android.graphics.Canvas; 4 | import android.graphics.Paint; 5 | 6 | import java.util.logging.Level; 7 | import java.util.logging.Logger; 8 | 9 | import org.graphstream.ui.graphicGraph.GraphicElement; 10 | import org.graphstream.ui.android.Backend; 11 | import org.graphstream.ui.view.camera.DefaultCamera2D; 12 | import org.graphstream.ui.android.renderer.Skeleton; 13 | import org.graphstream.ui.android.renderer.shape.android.baseShapes.LineConnectorShape; 14 | import org.graphstream.ui.android.renderer.shape.android.baseShapes.Form.Path2D; 15 | 16 | public class FreePlaneEdgeShape extends LineConnectorShape { 17 | Path2D theShape = new Path2D(0, false); 18 | 19 | @Override 20 | public void make(Backend backend, DefaultCamera2D camera) { 21 | make(camera, 0, 0, 0, 0); 22 | } 23 | 24 | private void make(DefaultCamera2D camera, double sox, double soy, double swx, double swy) { 25 | if (skel.multi() > 1 || skel.isLoop()) // is a loop or a multi edge 26 | makeMultiOrLoop(camera, sox, soy, swx, swy); 27 | else 28 | makeSingle(camera, sox, soy, swx, swy); // is a single edge. 29 | } 30 | 31 | private void makeMultiOrLoop(DefaultCamera2D camera, double sox, double soy, double swx, double swy) { 32 | if (skel.isLoop()) 33 | makeLoop(camera, sox, soy, swx, swy); 34 | else 35 | makeMulti(camera, sox, soy, swx, swy); 36 | } 37 | 38 | private void makeLoop(DefaultCamera2D camera, double sox, double soy, double swx, double swy) { 39 | double fromx = skel.apply(0).x + sox; 40 | double fromy = skel.apply(0).y + soy; 41 | double tox = skel.apply(3).x + sox; 42 | double toy = skel.apply(3).y + soy; 43 | double c1x = skel.apply(1).x + sox; 44 | double c1y = skel.apply(1).y + soy; 45 | double c2x = skel.apply(2).x + sox; 46 | double c2y = skel.apply(2).y + soy; 47 | 48 | theShape = new Path2D(5, false); 49 | theShape.moveTo(fromx, fromy); 50 | theShape.curveTo(c1x, c1y, c2x, c2y, tox, toy); 51 | } 52 | 53 | private void makeMulti(DefaultCamera2D camera, double sox, double soy, double swx, double swy) { 54 | double fromx = skel.apply(0).x + sox; 55 | double fromy = skel.apply(0).y + soy; 56 | double tox = skel.apply(3).x + sox; 57 | double toy = skel.apply(3).y + soy; 58 | double c1x = skel.apply(1).x + sox; 59 | double c1y = skel.apply(1).y + soy; 60 | double c2x = skel.apply(2).x + sox; 61 | double c2y = skel.apply(2).y + soy; 62 | 63 | theShape = new Path2D(5, false); 64 | theShape.moveTo(fromx, fromy); 65 | theShape.curveTo(c1x, c1y, c2x, c2y, tox, toy); 66 | } 67 | 68 | private void makeSingle(DefaultCamera2D camera, double sox, double soy, double swx, double swy) { 69 | try { 70 | double fromx = skel.from().x + sox; 71 | double fromy = skel.from().y + soy - theSourceSize.y / 2; 72 | double tox = skel.to().x + sox; 73 | double toy = skel.to().y + soy - theTargetSize.y / 2; 74 | double length = Math.abs(skel.to().x - skel.from().x); 75 | double c1x = 0.0; 76 | double c1y = 0.0; 77 | double c2x = 0.0; 78 | double c2y = 0.0; 79 | 80 | if (skel.from().x < skel.to().x) { 81 | // At right. 82 | fromx += theSourceSize.x / 2; 83 | tox -= theTargetSize.x / 2; 84 | c1x = fromx + length / 3; 85 | c2x = tox - length / 3; 86 | c1y = fromy; 87 | c2y = toy; 88 | } else { 89 | // At left. 90 | fromx -= theSourceSize.x / 2; 91 | tox += theTargetSize.x / 2; 92 | c1x = fromx - length / 3; 93 | c2x = tox + length / 3; 94 | c1y = fromy; 95 | c2y = toy; 96 | } 97 | 98 | theShape = new Path2D(5, false); 99 | theShape.moveTo(fromx, fromy); 100 | theShape.curveTo(c1x, c1y, c2x, c2y, tox, toy); 101 | 102 | // Set the connector as a curve. 103 | if (sox == 0 && soy == 0) { 104 | skel.setCurve( 105 | fromx, fromy, 0, 106 | c1x, c1y, 0, 107 | c2x, c2y, 0, 108 | tox, toy, 0); 109 | } 110 | } 111 | catch(Exception e) { 112 | Logger.getLogger(this.getClass().getSimpleName()).log(Level.WARNING, "FOUND!", e); 113 | } 114 | } 115 | 116 | @Override 117 | public void makeShadow(Backend backend, DefaultCamera2D camera) { 118 | if (skel.isCurve()) 119 | makeMultiOrLoop(camera, shadowableLine.theShadowOff.x, shadowableLine.theShadowOff.y, shadowableLine.theShadowWidth, shadowableLine.theShadowWidth); 120 | else 121 | makeSingle(camera, shadowableLine.theShadowOff.x, shadowableLine.theShadowOff.y, shadowableLine.theShadowWidth, shadowableLine.theShadowWidth); 122 | } 123 | 124 | @Override 125 | public void render(Backend bck, DefaultCamera2D camera, GraphicElement element, Skeleton skeleton) { 126 | Canvas g = bck.graphics2D(); 127 | Paint p = bck.getPaint(); 128 | 129 | make(bck, camera); 130 | strokableLine.stroke(bck.drawingSurface(), g, p, theShape); 131 | fillableLine.fill(bck.drawingSurface(), g, p, theSize, theShape); 132 | decorable.decorConnector(bck, camera, skel.iconAndText, element, theShape); 133 | } 134 | 135 | @Override 136 | public void renderShadow(Backend bck, DefaultCamera2D camera, GraphicElement element, Skeleton skeleton) { 137 | makeShadow(bck, camera); 138 | shadowableLine.cast(bck.drawingSurface(), bck.graphics2D(), bck.getPaint(), theShape); 139 | } 140 | } 141 | -------------------------------------------------------------------------------- /app/src/main/java/org/graphstream/ui/android/renderer/shape/android/advancedShapes/LSquareEdgeShape.java: -------------------------------------------------------------------------------- 1 | package org.graphstream.ui.android.renderer.shape.android.advancedShapes; 2 | 3 | import android.graphics.Canvas; 4 | import android.graphics.Paint; 5 | 6 | import org.graphstream.ui.geom.Point3; 7 | import org.graphstream.ui.geom.Vector2; 8 | import org.graphstream.ui.graphicGraph.GraphicElement; 9 | import org.graphstream.ui.android.Backend; 10 | import org.graphstream.ui.view.camera.DefaultCamera2D; 11 | import org.graphstream.ui.android.renderer.Skeleton; 12 | import org.graphstream.ui.android.renderer.shape.android.baseShapes.LineConnectorShape; 13 | import org.graphstream.ui.android.renderer.shape.android.baseShapes.Form.Path2D; 14 | 15 | public class LSquareEdgeShape extends LineConnectorShape { 16 | Path2D theShape = new Path2D(0, false); 17 | 18 | @Override 19 | public void make(Backend backend, DefaultCamera2D camera) { 20 | make(camera, 0, 0, 0, 0); 21 | } 22 | 23 | private void make(DefaultCamera2D camera, double sox, double soy, double swx, double swy) { 24 | if (skel.multi() > 1 || skel.isLoop()) // is a loop or a multi edge 25 | makeMultiOrLoop(camera, sox, soy, swx, swy); 26 | else 27 | makeSingle(camera, sox, soy, swx, swy); // is a single edge. 28 | } 29 | 30 | private void makeMultiOrLoop(DefaultCamera2D camera, double sox, double soy, double swx, double swy) { 31 | if (skel.isLoop()) 32 | makeLoop(camera, sox, soy, swx, swy); 33 | else 34 | makeMulti(camera, sox, soy, swx, swy); 35 | } 36 | 37 | private void makeLoop(DefaultCamera2D camera, double sox, double soy, double swx, double swy) { 38 | double fromx = skel.apply(0).x + sox; 39 | double fromy = skel.apply(0).y + soy; 40 | double tox = skel.apply(3).x + sox; 41 | double toy = skel.apply(3).y + soy; 42 | double c1x = skel.apply(1).x + sox; 43 | double c1y = skel.apply(1).y + soy; 44 | double c2x = skel.apply(2).x + sox; 45 | double c2y = skel.apply(2).y + soy; 46 | 47 | theShape = new Path2D(5, false); 48 | theShape.moveTo(fromx, fromy); 49 | theShape.curveTo(c1x, c1y, c2x, c2y, tox, toy); 50 | } 51 | 52 | private void makeMulti(DefaultCamera2D camera, double sox, double soy, double swx, double swy) { 53 | double fromx = skel.apply(0).x + sox; 54 | double fromy = skel.apply(0).y + soy; 55 | double tox = skel.apply(3).x + sox; 56 | double toy = skel.apply(3).y + soy; 57 | double c1x = skel.apply(1).x + sox; 58 | double c1y = skel.apply(1).y + soy; 59 | double c2x = skel.apply(2).x + sox; 60 | double c2y = skel.apply(2).y + soy; 61 | 62 | theShape = new Path2D(5, false); 63 | theShape.moveTo(fromx, fromy); 64 | theShape.curveTo(c1x, c1y, c2x, c2y, tox, toy); 65 | } 66 | 67 | private void makeSingle(DefaultCamera2D camera, double sox, double soy, double swx, double swy) { 68 | Point3 from = new Point3(skel.from().x + sox, skel.from().y + soy, 0); 69 | Point3 to = new Point3(skel.to().x + sox, skel.to().y + soy, 0); 70 | Vector2 mainDir = new Vector2(from, to); 71 | double length = mainDir.length(); 72 | double angle = mainDir.y() / length; 73 | Point3 inter = null; 74 | 75 | if (angle > 0.707107f || angle < -0.707107f) { 76 | // North or south. 77 | inter = new Point3(from.x, to.y, 0); 78 | } 79 | else { 80 | // East or west. 81 | inter = new Point3(to.x, from.y, 0); 82 | } 83 | 84 | if (sox == 0 && soy == 0) { 85 | Point3[] pts = {from, inter, to}; 86 | skel.setPoly(pts); 87 | } 88 | 89 | theShape = new Path2D(5, false); 90 | theShape.moveTo(from.x, from.y); 91 | theShape.lineTo(inter.x, inter.y); 92 | theShape.lineTo(to.x, to.y); 93 | } 94 | 95 | @Override 96 | public void makeShadow(Backend backend, DefaultCamera2D camera) { 97 | if (skel.isCurve()) 98 | makeMultiOrLoop(camera, shadowableLine.theShadowOff.x, shadowableLine.theShadowOff.y, shadowableLine.theShadowWidth, shadowableLine.theShadowWidth); 99 | else 100 | makeSingle(camera, shadowableLine.theShadowOff.x, shadowableLine.theShadowOff.y, shadowableLine.theShadowWidth, shadowableLine.theShadowWidth); 101 | } 102 | 103 | @Override 104 | public void render(Backend bck, DefaultCamera2D camera, GraphicElement element, Skeleton skeleton) { 105 | Canvas g = bck.graphics2D(); 106 | Paint p = bck.getPaint(); 107 | make(bck, camera); 108 | strokableLine.stroke(bck.drawingSurface(), g, p, theShape); 109 | fillableLine.fill(bck.drawingSurface(), g, p, theSize, theShape); 110 | decorable.decorConnector(bck, camera, skel.iconAndText, element, theShape); 111 | } 112 | 113 | @Override 114 | public void renderShadow(Backend bck, DefaultCamera2D camera, GraphicElement element, Skeleton skeleton) { 115 | makeShadow(bck, camera); 116 | shadowableLine.cast(bck.drawingSurface(), bck.graphics2D(), bck.getPaint(), theShape); 117 | } 118 | } 119 | -------------------------------------------------------------------------------- /app/src/main/java/org/graphstream/ui/android/renderer/shape/android/advancedShapes/PieChartShape.java: -------------------------------------------------------------------------------- 1 | package org.graphstream.ui.android.renderer.shape.android.advancedShapes; 2 | 3 | import android.graphics.Canvas; 4 | import android.graphics.Color; 5 | import android.graphics.Paint; 6 | import android.util.Log; 7 | import android.view.SurfaceView; 8 | 9 | import java.util.logging.Logger; 10 | 11 | import org.graphstream.ui.android.util.ColorManager; 12 | import org.graphstream.ui.graphicGraph.GraphicElement; 13 | import org.graphstream.ui.graphicGraph.stylesheet.Style; 14 | import org.graphstream.ui.android.Backend; 15 | import org.graphstream.ui.view.camera.DefaultCamera2D; 16 | import org.graphstream.ui.android.renderer.AreaSkeleton; 17 | import org.graphstream.ui.android.renderer.Skeleton; 18 | import org.graphstream.ui.android.renderer.shape.Decorable; 19 | import org.graphstream.ui.android.renderer.shape.Shape; 20 | import org.graphstream.ui.android.renderer.shape.android.Area; 21 | import org.graphstream.ui.android.renderer.shape.android.baseShapes.Form.Arc2D; 22 | import org.graphstream.ui.android.renderer.shape.android.baseShapes.Form.Ellipse2D; 23 | import org.graphstream.ui.android.renderer.shape.android.shapePart.FillableMulticolored; 24 | import org.graphstream.ui.android.renderer.shape.android.shapePart.Shadowable; 25 | import org.graphstream.ui.android.renderer.shape.android.shapePart.Strokable; 26 | import org.graphstream.ui.android.util.AttributeUtils; 27 | 28 | public class PieChartShape extends FillableMulticolored implements Shape, AttributeUtils { 29 | int[] colors = {Color.RED, Color.GREEN, Color.BLUE, Color.YELLOW, Color.MAGENTA, 30 | Color.CYAN, Color.rgb(255, 165, 0) /*ORANGE*/, Color.rgb(255, 105, 180)/*Color.PINK*/}; 31 | 32 | Strokable strokabe ; 33 | Shadowable shadowable ; 34 | Decorable decorable ; 35 | Area area ; 36 | 37 | Ellipse2D theShape = new Ellipse2D(); 38 | double[] theValues = null ; 39 | Object valuesRef = null ; 40 | 41 | public PieChartShape() { 42 | strokabe = new Strokable(); 43 | shadowable = new Shadowable(); 44 | decorable = new Decorable(); 45 | area = new Area(); 46 | } 47 | 48 | @Override 49 | public void configureForGroup(Backend backend, Style style, DefaultCamera2D camera) { 50 | area.configureAreaForGroup(style, camera); 51 | configureFillableMultiColoredForGroup(style, camera); 52 | strokabe.configureStrokableForGroup(style, camera); 53 | shadowable.configureShadowableForGroup(style, camera); 54 | decorable.configureDecorableForGroup(style, camera); 55 | } 56 | @Override 57 | public void configureForElement(Backend bck, GraphicElement element, Skeleton skel, 58 | DefaultCamera2D camera) { 59 | decorable.configureDecorableForElement(bck, camera, element, skel); 60 | area.configureAreaForElement(bck, camera, (AreaSkeleton)skel, element, decorable.theDecor); 61 | } 62 | @Override 63 | public void make(Backend backend, DefaultCamera2D camera) { 64 | theShape.setFrameFromCenter(area.theCenter.x, area.theCenter.y, area.theCenter.x + area.theSize.x / 2, area.theCenter.y + area.theSize.y / 2); 65 | } 66 | 67 | @Override 68 | public void makeShadow(Backend backend, DefaultCamera2D camera) { 69 | theShape.setFrameFromCenter(area.theCenter.x + shadowable.theShadowOff.x, area.theCenter.y + shadowable.theShadowOff.y, 70 | area.theCenter.x + (area.theSize.x + shadowable.theShadowWidth.x) / 2, area.theCenter.y + (area.theSize.y + shadowable.theShadowWidth.y) / 2); 71 | } 72 | @Override 73 | public void render(Backend bck, DefaultCamera2D camera, GraphicElement element, Skeleton skel) { 74 | Canvas g = bck.graphics2D(); 75 | Paint p = bck.getPaint(); 76 | make(bck, camera); 77 | checkValues(element); 78 | fillPies(bck.drawingSurface(), g, p, element); 79 | //fill(g, theSize, theShape) 80 | strokabe.stroke(bck.drawingSurface(), g, p, theShape); 81 | decorable.decorArea(bck, camera, skel.iconAndText, element, theShape); 82 | } 83 | 84 | private void fillPies(SurfaceView view, Canvas g, Paint p, GraphicElement element) { 85 | if (theValues != null) { 86 | // we assume the pies values sum up to one. And we wont check it, its a mater of speed ;-). 87 | Arc2D arc = new Arc2D(); 88 | double beg = 0.0; 89 | double end = 0.0; 90 | double col = 0; 91 | double sum = 0.0; 92 | 93 | for( int i = 0 ; i < theValues.length ; i++ ) { 94 | double value = theValues[i]; 95 | end = beg + value; 96 | arc.setArcByCenter(area.theCenter.x, area.theCenter.y, area.theSize.x / 2, beg * 360, value * 360); 97 | 98 | p.setColor(fillColors[(int) (col % fillColors.length)]); 99 | 100 | arc.drawByPoints(view, g, p, false); 101 | beg = end; 102 | sum += value; 103 | col += 1; 104 | } 105 | 106 | if (sum > 1.01f) 107 | Log.e("Error", "[Sprite "+element.getId()+"] The sum of values for ui.pie-value should eval to 1 at max (actually "+sum+")."); 108 | } 109 | else { 110 | // Draw a red empty circle to indicate "no value". 111 | 112 | p.setColor(Color.RED); 113 | 114 | theShape.drawByPoints(view, g, p,false); 115 | } 116 | } 117 | 118 | private void checkValues(GraphicElement element) { 119 | Object pieValues = element.getAttribute("ui.pie-values"); 120 | 121 | if (pieValues != null) { 122 | // Object oldRef = valuesRef; 123 | valuesRef = pieValues; 124 | // We use valueRef to avoid 125 | // recreating the values array for nothing. 126 | //if ((theValues == null) || (oldRef ne valuesRef)) { // Cannot do this : the array reference can be the same and the values changed. 127 | theValues = getDoubles(valuesRef); 128 | //} 129 | } 130 | } 131 | 132 | @Override 133 | public void renderShadow(Backend bck, DefaultCamera2D camera, GraphicElement element, Skeleton skeleton) { 134 | makeShadow(bck, camera); 135 | shadowable.cast(bck.drawingSurface(), bck.graphics2D(), bck.getPaint(), theShape); 136 | } 137 | } -------------------------------------------------------------------------------- /app/src/main/java/org/graphstream/ui/android/renderer/shape/android/arrowShapes/ArrowOnEdge.java: -------------------------------------------------------------------------------- 1 | package org.graphstream.ui.android.renderer.shape.android.arrowShapes; 2 | 3 | import android.graphics.Canvas; 4 | import android.graphics.Paint; 5 | 6 | import org.graphstream.ui.geom.Point2; 7 | import org.graphstream.ui.geom.Point3; 8 | import org.graphstream.ui.geom.Vector2; 9 | import org.graphstream.ui.graphicGraph.GraphicElement; 10 | import org.graphstream.ui.graphicGraph.stylesheet.Style; 11 | import org.graphstream.ui.android.Backend; 12 | import org.graphstream.ui.view.camera.DefaultCamera2D; 13 | import org.graphstream.ui.android.renderer.ConnectorSkeleton; 14 | import org.graphstream.ui.android.renderer.Skeleton; 15 | import org.graphstream.ui.android.renderer.shape.android.baseShapes.AreaOnConnectorShape; 16 | import org.graphstream.ui.android.renderer.shape.android.baseShapes.Form.Path2D; 17 | import org.graphstream.ui.android.util.AttributeUtils.Tuple; 18 | import org.graphstream.ui.android.util.CubicCurve; 19 | import org.graphstream.ui.android.util.ShapeUtil; 20 | 21 | public class ArrowOnEdge extends AreaOnConnectorShape { 22 | Path2D theShape = new Path2D(0, true); 23 | 24 | @Override 25 | public void make(Backend backend, DefaultCamera2D camera) { 26 | make( false, camera ); 27 | } 28 | 29 | @Override 30 | public void makeShadow(Backend backend, DefaultCamera2D camera) { 31 | make( true, camera ); 32 | } 33 | 34 | private void make(boolean forShadow, DefaultCamera2D camera) { 35 | if(theConnector.skel.isCurve()) 36 | makeOnCurve(forShadow, camera); 37 | else 38 | makeOnLine(forShadow, camera); 39 | } 40 | 41 | private void makeOnCurve(boolean forShadow, DefaultCamera2D camera) { 42 | 43 | Tuple tuple = CubicCurve.approxIntersectionPointOnCurve( theEdge, theConnector, camera ); 44 | Point2 p1 = tuple.x ; 45 | double t = tuple.y ; 46 | 47 | Style style = theEdge.getStyle(); 48 | 49 | Point3 p2 = CubicCurve.eval( theConnector.fromPos(), theConnector.byPos1(), theConnector.byPos2(), theConnector.toPos(), t-0.05f ); 50 | Vector2 dir = new Vector2( p1.x - p2.x, p1.y - p2.y ); // XXX The choice of the number above (0.05f) is problematic 51 | dir.normalize(); // Clearly it should be chosen according to the length 52 | dir.scalarMult( theSize.x ); // of the arrow compared to the length of the curve, however 53 | Vector2 per = new Vector2( dir.y(), -dir.x() ); // computing the curve length (see CubicCurve) is costly. XXX 54 | per.normalize(); 55 | per.scalarMult( theSize.y ); 56 | 57 | // Create a polygon. 58 | 59 | theShape = new Path2D(5, true); 60 | theShape.moveTo( p1.x , p1.y ); 61 | theShape.lineTo( p1.x - dir.x() + per.x(), p1.y - dir.y() + per.y() ); 62 | theShape.lineTo( p1.x - dir.x() - per.x(), p1.y - dir.y() - per.y() ); 63 | theShape.closePath(); 64 | } 65 | 66 | private void makeOnLine(boolean forShadow, DefaultCamera2D camera) { 67 | ConnectorSkeleton skel = theConnector.skel; 68 | double off = 0; 69 | Vector2 theDirection ; 70 | if(skel.isPoly()) { 71 | off = ShapeUtil.evalTargetRadius2D( skel.apply(skel.size()-2), skel.to(), theEdge.to, camera ); 72 | theDirection = new Vector2( 73 | skel.to().x - skel.apply(skel.size()-2).x, 74 | skel.to().y - skel.apply(skel.size()-2).y ); 75 | } 76 | else { 77 | off = ShapeUtil.evalTargetRadius2D( skel.from(), skel.to(), theEdge.to, camera ); 78 | theDirection = new Vector2( 79 | skel.to().x - skel.from().x, 80 | skel.to().y - skel.from().y ); 81 | } 82 | 83 | theDirection.normalize(); 84 | 85 | double x = theCenter.x - ( theDirection.x() * off ); 86 | double y = theCenter.y - ( theDirection.y() * off ); 87 | Vector2 perp = new Vector2( theDirection.y(), -theDirection.x() ); 88 | 89 | perp.normalize(); 90 | theDirection.scalarMult( theSize.x ); 91 | perp.scalarMult( theSize.y ); 92 | 93 | if( forShadow ) { 94 | x += shadowable.theShadowOff.x; 95 | y += shadowable.theShadowOff.y; 96 | } 97 | 98 | // Create a polygon. 99 | 100 | theShape = new Path2D(5, true); 101 | theShape.moveTo( x , y ); 102 | theShape.lineTo( x - theDirection.x() + perp.x(), y - theDirection.y() + perp.y() ); 103 | theShape.lineTo( x - theDirection.x() - perp.x(), y - theDirection.y() - perp.y() ); 104 | theShape.closePath(); 105 | } 106 | 107 | @Override 108 | public void render(Backend bck, DefaultCamera2D camera, GraphicElement element, Skeleton skeleton) { 109 | Canvas g = bck.graphics2D(); 110 | Paint p = bck.getPaint(); 111 | make( false, camera ); 112 | strokable.stroke(bck.drawingSurface(), g, p, theShape ); 113 | fillable.fill(bck.drawingSurface(), g, p, theShape, camera ); 114 | } 115 | 116 | @Override 117 | public void renderShadow(Backend bck, DefaultCamera2D camera, GraphicElement element, Skeleton skeleton) { 118 | make( true, camera ); 119 | shadowable.cast(bck.drawingSurface(), bck.graphics2D(), bck.getPaint(), theShape ); 120 | } 121 | } 122 | -------------------------------------------------------------------------------- /app/src/main/java/org/graphstream/ui/android/renderer/shape/android/arrowShapes/CircleOnEdge.java: -------------------------------------------------------------------------------- 1 | package org.graphstream.ui.android.renderer.shape.android.arrowShapes; 2 | 3 | import android.graphics.Canvas; 4 | import android.graphics.Paint; 5 | 6 | import org.graphstream.ui.geom.Point2; 7 | import org.graphstream.ui.geom.Point3; 8 | import org.graphstream.ui.geom.Vector2; 9 | import org.graphstream.ui.graphicGraph.GraphicElement; 10 | import org.graphstream.ui.graphicGraph.stylesheet.Style; 11 | import org.graphstream.ui.android.Backend; 12 | import org.graphstream.ui.view.camera.DefaultCamera2D; 13 | import org.graphstream.ui.android.renderer.Skeleton; 14 | import org.graphstream.ui.android.renderer.shape.Connector; 15 | import org.graphstream.ui.android.renderer.shape.android.baseShapes.AreaOnConnectorShape; 16 | import org.graphstream.ui.android.renderer.shape.android.baseShapes.Form.Ellipse2D; 17 | import org.graphstream.ui.android.util.CubicCurve; 18 | import org.graphstream.ui.android.util.ShapeUtil; 19 | import org.graphstream.ui.android.util.AttributeUtils.Tuple; 20 | 21 | public class CircleOnEdge extends AreaOnConnectorShape { 22 | Ellipse2D theShape = new Ellipse2D(); 23 | 24 | @Override 25 | public void make(Backend backend, DefaultCamera2D camera) { 26 | make( false, camera ); 27 | } 28 | 29 | @Override 30 | public void makeShadow(Backend backend, DefaultCamera2D camera) { 31 | make( true, camera ); 32 | } 33 | 34 | private void make(boolean forShadow, DefaultCamera2D camera) { 35 | if( theConnector.skel.isCurve() ) 36 | makeOnCurve( forShadow, camera ); 37 | else 38 | makeOnLine( forShadow, camera ); 39 | } 40 | 41 | private void makeOnCurve(boolean forShadow, DefaultCamera2D camera) { 42 | Tuple tuple = CubicCurve.approxIntersectionPointOnCurve( theEdge, theConnector, camera ); 43 | Point2 p1 = tuple.x ; 44 | double t = tuple.y ; 45 | 46 | Style style = theEdge.getStyle(); 47 | 48 | Point3 p2 = CubicCurve.eval( theConnector.fromPos(), theConnector.byPos1(), theConnector.byPos2(), theConnector.toPos(), t-0.1f ); 49 | Vector2 dir = new Vector2( p1.x - p2.x, p1.y - p2.y ); 50 | dir.normalize(); 51 | dir.scalarMult( theSize.x/2 ); 52 | 53 | // Create a polygon. 54 | theShape.setFrame( (p1.x-dir.x())-(theSize.x/2), (p1.y-dir.y())-(theSize.y/2), theSize.x, theSize.y ); 55 | } 56 | 57 | private void makeOnLine(boolean forShadow, DefaultCamera2D camera) { 58 | double off = ShapeUtil.evalTargetRadius2D( theEdge, camera ) + ((theSize.x+theSize.y)/4); 59 | Vector2 theDirection = new Vector2( 60 | theConnector.toPos().x - theConnector.fromPos().x, 61 | theConnector.toPos().y - theConnector.fromPos().y ); 62 | 63 | theDirection.normalize(); 64 | 65 | double x = theCenter.x - ( theDirection.x() * off ); 66 | double y = theCenter.y - ( theDirection.y() * off ); 67 | //val perp = new Vector2( theDirection(1), -theDirection(0) ) 68 | 69 | //perp.normalize 70 | theDirection.scalarMult( theSize.x ); 71 | //perp.scalarMult( theSize.y ) 72 | 73 | if( forShadow ) { 74 | x += shadowable.theShadowOff.x; 75 | y += shadowable.theShadowOff.y; 76 | } 77 | 78 | // Set the shape. 79 | theShape.setFrame( x-(theSize.x/2), y-(theSize.y/2), theSize.x, theSize.y ); 80 | } 81 | 82 | @Override 83 | public void render(Backend bck, DefaultCamera2D camera, GraphicElement element, Skeleton skeleton) { 84 | Canvas g = bck.graphics2D(); 85 | Paint p = bck.getPaint(); 86 | make( false, camera ); 87 | strokable.stroke(bck.drawingSurface(), g, p, theShape ); 88 | fillable.fill(bck.drawingSurface(), g, p, theShape, camera ); 89 | } 90 | 91 | public double lengthOfCurve( Connector c ) { 92 | // Computing a curve real length is really heavy. 93 | // We approximate it using the length of the 3 line segments of the enclosing 94 | // control points. 95 | return ( c.fromPos().distance( c.byPos1() ) + c.byPos1().distance( c.byPos2() ) + c.byPos2().distance( c.toPos() ) ) * 0.75f; 96 | } 97 | 98 | @Override 99 | public void renderShadow(Backend bck, DefaultCamera2D camera, GraphicElement element, Skeleton skeleton) { 100 | make( true, camera ); 101 | shadowable.cast(bck.drawingSurface(), bck.graphics2D(), bck.getPaint(), theShape ); 102 | } 103 | 104 | } -------------------------------------------------------------------------------- /app/src/main/java/org/graphstream/ui/android/renderer/shape/android/arrowShapes/DiamondOnEdge.java: -------------------------------------------------------------------------------- 1 | package org.graphstream.ui.android.renderer.shape.android.arrowShapes; 2 | 3 | import android.graphics.Canvas; 4 | import android.graphics.Paint; 5 | 6 | import org.graphstream.ui.geom.Point2; 7 | import org.graphstream.ui.geom.Vector2; 8 | import org.graphstream.ui.graphicGraph.GraphicElement; 9 | import org.graphstream.ui.graphicGraph.stylesheet.Style; 10 | import org.graphstream.ui.android.Backend; 11 | import org.graphstream.ui.view.camera.DefaultCamera2D; 12 | import org.graphstream.ui.android.renderer.Skeleton; 13 | import org.graphstream.ui.android.renderer.shape.android.baseShapes.AreaOnConnectorShape; 14 | import org.graphstream.ui.android.renderer.shape.android.baseShapes.Form.Path2D; 15 | import org.graphstream.ui.android.util.AttributeUtils.Tuple; 16 | import org.graphstream.ui.android.util.CubicCurve; 17 | import org.graphstream.ui.android.util.ShapeUtil; 18 | 19 | public class DiamondOnEdge extends AreaOnConnectorShape { 20 | Path2D theShape = new Path2D(0, true); 21 | 22 | @Override 23 | public void make(Backend backend, DefaultCamera2D camera) { 24 | make( false, camera ); 25 | } 26 | 27 | @Override 28 | public void makeShadow(Backend backend, DefaultCamera2D camera) { 29 | make( true, camera ); 30 | } 31 | 32 | private void make(boolean forShadow, DefaultCamera2D camera) { 33 | if( theConnector.skel.isCurve() ) 34 | makeOnCurve( forShadow, camera ); 35 | else 36 | makeOnLine( forShadow, camera ); 37 | } 38 | 39 | 40 | private void makeOnCurve(boolean forShadow, DefaultCamera2D camera) { 41 | Tuple tuple = CubicCurve.approxIntersectionPointOnCurve( theEdge, theConnector, camera ); 42 | 43 | Point2 p1 = tuple.x ; 44 | double t = tuple.y ; 45 | 46 | Style style = theEdge.getStyle(); 47 | 48 | Point2 p2 = CubicCurve.eval( theConnector.fromPos(), theConnector.byPos1(), theConnector.byPos2(), theConnector.toPos(), t-0.1f ); 49 | Vector2 dir = new Vector2( p1.x - p2.x, p1.y - p2.y ); 50 | dir.normalize(); 51 | dir.scalarMult( theSize.x ); 52 | Vector2 per = new Vector2( dir.y(), -dir.x() ); 53 | per.normalize(); 54 | per.scalarMult( theSize.y ); 55 | 56 | // Create a polygon. 57 | 58 | theShape = new Path2D(5, true); 59 | theShape.moveTo( p1.x , p1.y ); 60 | theShape.lineTo( p1.x - dir.x()/2 + per.x(), p1.y - dir.y()/2 + per.y() ); 61 | theShape.lineTo( p1.x - dir.x(), p1.y - dir.y() ); 62 | theShape.lineTo( p1.x - dir.x()/2 - per.x(), p1.y - dir.y()/2 - per.y() ); 63 | theShape.closePath(); 64 | } 65 | 66 | private void makeOnLine(boolean forShadow, DefaultCamera2D camera) { 67 | double off = ShapeUtil.evalTargetRadius2D( theEdge, camera ); 68 | Vector2 theDirection = new Vector2( 69 | theConnector.toPos().x - theConnector.fromPos().x, 70 | theConnector.toPos().y - theConnector.fromPos().y ); 71 | 72 | theDirection.normalize(); 73 | 74 | double x = theCenter.x - ( theDirection.x() * off ); 75 | double y = theCenter.y - ( theDirection.y() * off ); 76 | Vector2 perp = new Vector2( theDirection.y(), -theDirection.x() ); 77 | 78 | perp.normalize(); 79 | theDirection.scalarMult( theSize.x / 2 ); 80 | perp.scalarMult( theSize.y ); 81 | 82 | if( forShadow ) { 83 | x += shadowable.theShadowOff.x; 84 | y += shadowable.theShadowOff.y; 85 | } 86 | 87 | // Create a polygon. 88 | 89 | theShape = new Path2D(5, true); 90 | theShape.moveTo( x , y ); 91 | theShape.lineTo( x - theDirection.x() + perp.x(), y - theDirection.y() + perp.y() ); 92 | theShape.lineTo( x - theDirection.x()*2, y - theDirection.y()*2 ); 93 | theShape.lineTo( x - theDirection.x() - perp.x(), y - theDirection.y() - perp.y() ); 94 | theShape.closePath(); 95 | } 96 | 97 | @Override 98 | public void render(Backend bck, DefaultCamera2D camera, GraphicElement element, Skeleton skeleton) { 99 | Canvas g = bck.graphics2D(); 100 | Paint p = bck.getPaint(); 101 | make( false, camera ); 102 | strokable.stroke(bck.drawingSurface(), g, p, theShape ); 103 | fillable.fill(bck.drawingSurface(), g, p, theShape, camera ); 104 | } 105 | 106 | @Override 107 | public void renderShadow(Backend bck, DefaultCamera2D camera, GraphicElement element, Skeleton skeleton) { 108 | make( true, camera ); 109 | shadowable.cast(bck.drawingSurface(), bck.graphics2D(), bck.getPaint(), theShape ); 110 | } 111 | } -------------------------------------------------------------------------------- /app/src/main/java/org/graphstream/ui/android/renderer/shape/android/arrowShapes/ImageOnEdge.java: -------------------------------------------------------------------------------- 1 | package org.graphstream.ui.android.renderer.shape.android.arrowShapes; 2 | 3 | import android.graphics.Bitmap; 4 | import android.graphics.Canvas; 5 | import android.graphics.Matrix; 6 | import android.graphics.Paint; 7 | 8 | import org.graphstream.ui.android.util.ColorManager; 9 | import org.graphstream.ui.geom.Point2; 10 | import org.graphstream.ui.geom.Point3; 11 | import org.graphstream.ui.geom.Vector2; 12 | import org.graphstream.ui.graphicGraph.GraphicElement; 13 | import org.graphstream.ui.graphicGraph.stylesheet.Style; 14 | import org.graphstream.ui.graphicGraph.stylesheet.StyleConstants.Units; 15 | import org.graphstream.ui.android.Backend; 16 | import org.graphstream.ui.view.camera.DefaultCamera2D; 17 | import org.graphstream.ui.android.renderer.Skeleton; 18 | import org.graphstream.ui.android.renderer.shape.android.baseShapes.AreaOnConnectorShape; 19 | import org.graphstream.ui.android.util.CubicCurve; 20 | import org.graphstream.ui.android.util.ImageCache; 21 | import org.graphstream.ui.android.util.ShapeUtil; 22 | import org.graphstream.ui.android.util.AttributeUtils.Tuple; 23 | 24 | public class ImageOnEdge extends AreaOnConnectorShape { 25 | Bitmap image = null; 26 | Point3 p = null ; 27 | double angle = 0.0; 28 | 29 | @Override 30 | public void configureForGroup(Backend bck, Style style, DefaultCamera2D camera) { 31 | super.configureForGroup(bck, style, camera); 32 | } 33 | 34 | @Override 35 | public void configureForElement(Backend bck, GraphicElement element, Skeleton skel, DefaultCamera2D camera) { 36 | super.configureForElement(bck, element, skel, camera); 37 | 38 | String url = element.getStyle().getArrowImage(); 39 | 40 | if( url.equals( "dynamic" ) ) { 41 | if( element.hasLabel( "ui.arrow-image" ) ) 42 | url = element.getLabel( "ui.arrow-image" ).toString(); 43 | else 44 | url = null; 45 | } 46 | 47 | if( url != null ) { 48 | try { 49 | image = ImageCache.loadImage(url); 50 | } 51 | catch (Exception e) { 52 | if (image == null) { 53 | image = ImageCache.dummyImage(); 54 | } 55 | } 56 | } 57 | } 58 | 59 | @Override 60 | public void make(Backend backend, DefaultCamera2D camera) { 61 | make( false, camera ); 62 | } 63 | @Override 64 | public void makeShadow(Backend backend, DefaultCamera2D camera) { 65 | make( true, camera ); 66 | } 67 | 68 | private void make(boolean forShadow, DefaultCamera2D camera) { 69 | if( theConnector.skel.isCurve() ) 70 | makeOnCurve( forShadow, camera ); 71 | else 72 | makeOnLine( forShadow, camera ); 73 | } 74 | 75 | private void makeOnCurve(boolean forShadow, DefaultCamera2D camera) { 76 | Tuple tuple = CubicCurve.approxIntersectionPointOnCurve( theEdge, theConnector, camera ); 77 | Point2 p1 = tuple.x ; 78 | double t = tuple.y ; 79 | 80 | Style style = theEdge.getStyle(); 81 | Point3 p2 = CubicCurve.eval( theConnector.fromPos(), theConnector.byPos1(), theConnector.byPos2(), theConnector.toPos(), t-0.1f ); 82 | Vector2 dir = new Vector2( p1.x - p2.x, p1.y - p2.y ); 83 | 84 | dir.normalize(); 85 | 86 | double iw = camera.getMetrics().lengthToGu( image.getWidth(), Units.PX ) / 2; 87 | double x = p1.x - ( dir.x() * iw ); 88 | double y = p1.y - ( dir.y() * iw ); 89 | 90 | if( forShadow ) { 91 | x += shadowable.theShadowOff.x; 92 | y += shadowable.theShadowOff.y; 93 | } 94 | 95 | p = camera.transformGuToPx( x, y, 0 ); 96 | angle = Math.acos( dir.dotProduct( 1, 0 ) ); 97 | 98 | if( dir.y() > 0 ) 99 | angle = ( Math.PI - angle ); 100 | } 101 | 102 | private void makeOnLine(boolean forShadow, DefaultCamera2D camera) { 103 | double off = ShapeUtil.evalTargetRadius2D( theEdge, camera ); 104 | 105 | Vector2 theDirection = new Vector2( 106 | theConnector.toPos().x - theConnector.fromPos().x, 107 | theConnector.toPos().y - theConnector.fromPos().y ); 108 | 109 | theDirection.normalize(); 110 | 111 | double iw = camera.getMetrics().lengthToGu( image.getWidth(), Units.PX ) / 2; 112 | double x = theCenter.x - ( theDirection.x() * ( off + iw ) ); 113 | double y = theCenter.y - ( theDirection.y() * ( off + iw ) ); 114 | 115 | if( forShadow ) { 116 | x += shadowable.theShadowOff.x; 117 | y += shadowable.theShadowOff.y; 118 | } 119 | 120 | p = camera.transformGuToPx( x, y, 0 ); // Pass to pixels, the image will be drawn in pixels. 121 | angle = Math.acos( theDirection.dotProduct( 1, 0 ) ); 122 | 123 | if( theDirection.y() > 0 ) // The angle is always computed for acute angles 124 | angle = ( Math.PI - angle ); 125 | } 126 | 127 | @Override 128 | public void render(Backend bck, DefaultCamera2D camera, GraphicElement element, Skeleton skeleton) { 129 | Canvas g = bck.graphics2D(); 130 | 131 | make( false, camera ); 132 | // stroke( g, theShape ) 133 | // fill( g, theShape, camera ) 134 | 135 | if( image != null ) { 136 | Matrix Tx = bck.getMatrix(); 137 | bck.setMatrix( new Matrix() ); // An identity matrix. 138 | 139 | g.translate( (float)p.x, (float)p.y ); // 3. Position the image at its position in the graph. 140 | g.rotate( (float)angle ); // 2. Rotate the image from its center. 141 | g.translate( (float)-image.getWidth()/2, (float)-image.getHeight()/2 ); // 1. Position in center of the image. 142 | 143 | g.drawBitmap(image, 0, 0, new Paint()); // Paint the image. 144 | bck.setMatrix( Tx ); // Restore the original transform 145 | } 146 | } 147 | 148 | @Override 149 | public void renderShadow(Backend bck, DefaultCamera2D camera, GraphicElement element, Skeleton skeleton) { 150 | //make( true, camera ); 151 | //shadowable.cast( g, theShape ); 152 | } 153 | } -------------------------------------------------------------------------------- /app/src/main/java/org/graphstream/ui/android/renderer/shape/android/baseShapes/AreaConnectorShape.java: -------------------------------------------------------------------------------- 1 | package org.graphstream.ui.android.renderer.shape.android.baseShapes; 2 | 3 | import org.graphstream.ui.graphicGraph.GraphicElement; 4 | import org.graphstream.ui.graphicGraph.stylesheet.Style; 5 | import org.graphstream.ui.android.Backend; 6 | import org.graphstream.ui.view.camera.DefaultCamera2D; 7 | import org.graphstream.ui.android.renderer.Skeleton; 8 | import org.graphstream.ui.android.renderer.shape.android.shapePart.Fillable; 9 | import org.graphstream.ui.android.renderer.shape.android.shapePart.Shadowable; 10 | import org.graphstream.ui.android.renderer.shape.android.shapePart.Strokable; 11 | 12 | public abstract class AreaConnectorShape extends ConnectorShape { 13 | 14 | public Fillable fillable ; 15 | public Strokable strokable ; 16 | public Shadowable shadowable ; 17 | 18 | public AreaConnectorShape() { 19 | this.fillable = new Fillable(); 20 | this.strokable = new Strokable(); 21 | this.shadowable = new Shadowable(); 22 | } 23 | 24 | public void configureForGroup(Backend bck, Style style, DefaultCamera2D camera) { 25 | fillable.configureFillableForGroup(bck, style, camera); 26 | strokable.configureStrokableForGroup(style, camera); 27 | shadowable.configureShadowableForGroup(style, camera); 28 | super.configureForGroup(bck, style, camera); 29 | } 30 | 31 | public void configureForElement(Backend bck, GraphicElement element, Skeleton skel, DefaultCamera2D camera) { 32 | fillable.configureFillableForElement(element.getStyle(), camera, element); 33 | super.configureForElement(bck, element, skel, camera); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /app/src/main/java/org/graphstream/ui/android/renderer/shape/android/baseShapes/AreaOnConnectorShape.java: -------------------------------------------------------------------------------- 1 | package org.graphstream.ui.android.renderer.shape.android.baseShapes; 2 | 3 | import org.graphstream.ui.graphicGraph.GraphicEdge; 4 | import org.graphstream.ui.graphicGraph.GraphicElement; 5 | import org.graphstream.ui.graphicGraph.stylesheet.Style; 6 | import org.graphstream.ui.android.Backend; 7 | import org.graphstream.ui.view.camera.DefaultCamera2D; 8 | import org.graphstream.ui.android.renderer.Skeleton; 9 | import org.graphstream.ui.android.renderer.shape.AreaOnConnector; 10 | import org.graphstream.ui.android.renderer.shape.Shape; 11 | import org.graphstream.ui.android.renderer.shape.android.shapePart.Fillable; 12 | import org.graphstream.ui.android.renderer.shape.android.shapePart.Shadowable; 13 | import org.graphstream.ui.android.renderer.shape.android.shapePart.Strokable; 14 | 15 | public abstract class AreaOnConnectorShape extends AreaOnConnector implements Shape { 16 | 17 | public Fillable fillable ; 18 | public Strokable strokable ; 19 | public Shadowable shadowable ; 20 | 21 | public AreaOnConnectorShape() { 22 | this.fillable = new Fillable(); 23 | this.strokable = new Strokable(); 24 | this.shadowable = new Shadowable(); 25 | } 26 | 27 | public void configureForGroup(Backend bck, Style style, DefaultCamera2D camera) { 28 | fillable.configureFillableForGroup(bck, style, camera); 29 | strokable.configureStrokableForGroup(style, camera); 30 | shadowable.configureShadowableForGroup(style, camera); 31 | configureAreaOnConnectorForGroup(style, camera); 32 | } 33 | 34 | public void configureForElement(Backend bck, GraphicElement element, Skeleton skel, DefaultCamera2D camera) { 35 | fillable.configureFillableForElement(element.getStyle(), camera, element); 36 | configureAreaOnConnectorForElement((GraphicEdge)element, element.getStyle(), camera); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /app/src/main/java/org/graphstream/ui/android/renderer/shape/android/baseShapes/AreaShape.java: -------------------------------------------------------------------------------- 1 | package org.graphstream.ui.android.renderer.shape.android.baseShapes; 2 | 3 | import org.graphstream.ui.graphicGraph.GraphicElement; 4 | import org.graphstream.ui.graphicGraph.stylesheet.Style; 5 | import org.graphstream.ui.android.Backend; 6 | import org.graphstream.ui.view.camera.DefaultCamera2D; 7 | import org.graphstream.ui.android.renderer.AreaSkeleton; 8 | import org.graphstream.ui.android.renderer.Skeleton; 9 | import org.graphstream.ui.android.renderer.shape.Decorable; 10 | import org.graphstream.ui.android.renderer.shape.Shape; 11 | import org.graphstream.ui.android.renderer.shape.android.Area; 12 | import org.graphstream.ui.android.renderer.shape.android.shapePart.Fillable; 13 | import org.graphstream.ui.android.renderer.shape.android.shapePart.Shadowable; 14 | import org.graphstream.ui.android.renderer.shape.android.shapePart.Strokable; 15 | 16 | public abstract class AreaShape extends Decorable implements Shape { 17 | 18 | public Fillable fillable ; 19 | public Strokable strokable ; 20 | public Shadowable shadowable ; 21 | public Area area ; 22 | 23 | public AreaShape() { 24 | this.fillable = new Fillable(); 25 | this.strokable = new Strokable(); 26 | this.shadowable = new Shadowable(); 27 | this.area = new Area(); 28 | } 29 | 30 | 31 | public void configureForGroup(Backend bck, Style style, DefaultCamera2D camera) { 32 | fillable.configureFillableForGroup(bck, style, camera); 33 | strokable.configureStrokableForGroup(style, camera); 34 | shadowable.configureShadowableForGroup(style, camera); 35 | configureDecorableForGroup(style, camera); 36 | area.configureAreaForGroup(style, camera); 37 | } 38 | 39 | public void configureForElement(Backend bck, GraphicElement element, Skeleton skel, DefaultCamera2D camera) { 40 | fillable.configureFillableForElement(element.getStyle(), camera, element); 41 | configureDecorableForElement(bck, camera, element, skel); 42 | area.configureAreaForElement(bck, camera, (AreaSkeleton)skel, element, theDecor); 43 | } 44 | } -------------------------------------------------------------------------------- /app/src/main/java/org/graphstream/ui/android/renderer/shape/android/baseShapes/ConnectorShape.java: -------------------------------------------------------------------------------- 1 | package org.graphstream.ui.android.renderer.shape.android.baseShapes; 2 | 3 | import org.graphstream.ui.graphicGraph.GraphicEdge; 4 | import org.graphstream.ui.graphicGraph.GraphicElement; 5 | import org.graphstream.ui.graphicGraph.stylesheet.Style; 6 | import org.graphstream.ui.android.Backend; 7 | import org.graphstream.ui.view.camera.DefaultCamera2D; 8 | import org.graphstream.ui.android.renderer.ConnectorSkeleton; 9 | import org.graphstream.ui.android.renderer.Skeleton; 10 | import org.graphstream.ui.android.renderer.shape.Connector; 11 | import org.graphstream.ui.android.renderer.shape.Decorable; 12 | import org.graphstream.ui.android.renderer.shape.Shape; 13 | 14 | public abstract class ConnectorShape extends Connector implements Shape { 15 | 16 | public Decorable decorable ; 17 | 18 | public ConnectorShape() { 19 | this.decorable = new Decorable(); 20 | } 21 | 22 | public void configureForGroup(Backend bck, Style style, DefaultCamera2D camera) { 23 | decorable.configureDecorableForGroup(style, camera); 24 | configureConnectorForGroup(style, camera); 25 | } 26 | 27 | public void configureForElement(Backend bck, GraphicElement element, Skeleton skel, DefaultCamera2D camera) { 28 | decorable.configureDecorableForElement(bck, camera, element, skel); 29 | configureConnectorForElement(camera, (GraphicEdge)element, (ConnectorSkeleton)skel /* TODO check this ! */); 30 | } 31 | } -------------------------------------------------------------------------------- /app/src/main/java/org/graphstream/ui/android/renderer/shape/android/baseShapes/LineConnectorShape.java: -------------------------------------------------------------------------------- 1 | package org.graphstream.ui.android.renderer.shape.android.baseShapes; 2 | 3 | import org.graphstream.ui.graphicGraph.GraphicElement; 4 | import org.graphstream.ui.graphicGraph.stylesheet.Style; 5 | import org.graphstream.ui.android.Backend; 6 | import org.graphstream.ui.view.camera.DefaultCamera2D; 7 | import org.graphstream.ui.android.renderer.Skeleton; 8 | import org.graphstream.ui.android.renderer.shape.android.shapePart.FillableLine; 9 | import org.graphstream.ui.android.renderer.shape.android.shapePart.ShadowableLine; 10 | import org.graphstream.ui.android.renderer.shape.android.shapePart.StrokableLine; 11 | 12 | public abstract class LineConnectorShape extends ConnectorShape { 13 | 14 | public FillableLine fillableLine ; 15 | public StrokableLine strokableLine; 16 | public ShadowableLine shadowableLine; 17 | 18 | public LineConnectorShape() { 19 | this.fillableLine = new FillableLine() ; 20 | this.strokableLine = new StrokableLine() ; 21 | this.shadowableLine = new ShadowableLine() ; 22 | } 23 | 24 | 25 | public void configureForGroup(Backend bck, Style style, DefaultCamera2D camera) { 26 | super.configureForGroup(bck, style, camera); 27 | fillableLine.configureFillableLineForGroup(bck, style, camera, theSize); 28 | strokableLine.configureStrokableLineForGroup(style, camera); 29 | shadowableLine.configureShadowableLineForGroup(style, camera); 30 | } 31 | 32 | public void configureForElement(Backend bck, GraphicElement element, Skeleton skel, DefaultCamera2D camera) { 33 | fillableLine.configureFillableLineForElement(element.getStyle(), camera, element); 34 | super.configureForElement(bck, element, skel, camera); 35 | } 36 | } -------------------------------------------------------------------------------- /app/src/main/java/org/graphstream/ui/android/renderer/shape/android/baseShapes/LineShape.java: -------------------------------------------------------------------------------- 1 | package org.graphstream.ui.android.renderer.shape.android.baseShapes; 2 | 3 | import android.graphics.Canvas; 4 | import android.graphics.Paint; 5 | 6 | import org.graphstream.ui.geom.Point3; 7 | import org.graphstream.ui.graphicGraph.GraphicElement; 8 | import org.graphstream.ui.android.Backend; 9 | import org.graphstream.ui.view.camera.DefaultCamera2D; 10 | import org.graphstream.ui.android.renderer.Skeleton; 11 | import org.graphstream.ui.android.renderer.shape.android.baseShapes.Form.CubicCurve2D; 12 | import org.graphstream.ui.android.renderer.shape.android.baseShapes.Form.Line2D; 13 | 14 | public class LineShape extends LineConnectorShape { 15 | protected Line2D theShapeL = new Line2D(); 16 | protected CubicCurve2D theShapeC = new CubicCurve2D(); 17 | protected Form theShape = null; 18 | 19 | @Override 20 | public void make(Backend backend, DefaultCamera2D camera) { 21 | Point3 from = skel.from(); 22 | Point3 to = skel.to(); 23 | if( skel.isCurve() ) { 24 | Point3 ctrl1 = skel.apply(1); 25 | Point3 ctrl2 = skel.apply(2); 26 | theShapeC = new CubicCurve2D( from.x, from.y, ctrl1.x, ctrl1.y, ctrl2.x, ctrl2.y, to.x, to.y ); 27 | theShape = theShapeC; 28 | } else { 29 | theShapeL = new Line2D( from.x, from.y, to.x, to.y ); 30 | theShape = theShapeL; 31 | } 32 | } 33 | 34 | @Override 35 | public void makeShadow(Backend backend, DefaultCamera2D camera) { 36 | double x0 = skel.from().x + shadowableLine.theShadowOff.x; 37 | double y0 = skel.from().y + shadowableLine.theShadowOff.y; 38 | double x1 = skel.to().x + shadowableLine.theShadowOff.x; 39 | double y1 = skel.to().y + shadowableLine.theShadowOff.y; 40 | 41 | if( skel.isCurve() ) { 42 | double ctrlx0 = skel.apply(1).x + shadowableLine.theShadowOff.x; 43 | double ctrly0 = skel.apply(1).y + shadowableLine.theShadowOff.y; 44 | double ctrlx1 = skel.apply(2).x + shadowableLine.theShadowOff.x; 45 | double ctrly1 = skel.apply(2).y + shadowableLine.theShadowOff.y; 46 | 47 | theShapeC = new CubicCurve2D( x0, y0, ctrlx0, ctrly0, ctrlx1, ctrly1, x1, y1 ); 48 | theShape = theShapeC; 49 | } else { 50 | theShapeL = new Line2D( x0, y0, x1, y1 ); 51 | theShape = theShapeL; 52 | } 53 | } 54 | 55 | @Override 56 | public void render(Backend bck, DefaultCamera2D camera, GraphicElement element, Skeleton skeleton) { 57 | Canvas g = bck.graphics2D(); 58 | Paint p = bck.getPaint(); 59 | make(bck, camera); 60 | strokableLine.stroke(bck.drawingSurface(), g, p, theShape); 61 | fillableLine.fill(bck.drawingSurface(), g, p, theSize, theShape); 62 | decorable.decorConnector(bck, camera, skel.iconAndText, element, theShape); 63 | } 64 | 65 | @Override 66 | public void renderShadow(Backend bck, DefaultCamera2D camera, GraphicElement element, Skeleton skeleton) { 67 | makeShadow(bck, camera); 68 | shadowableLine.cast(bck.drawingSurface(), bck.graphics2D(), bck.getPaint(), theShape); 69 | } 70 | } -------------------------------------------------------------------------------- /app/src/main/java/org/graphstream/ui/android/renderer/shape/android/baseShapes/OrientableRectangularAreaShape.java: -------------------------------------------------------------------------------- 1 | package org.graphstream.ui.android.renderer.shape.android.baseShapes; 2 | 3 | import android.graphics.Canvas; 4 | import android.graphics.Matrix; 5 | import android.graphics.Paint; 6 | 7 | import org.graphstream.ui.geom.Point3; 8 | import org.graphstream.ui.geom.Vector2; 9 | import org.graphstream.ui.graphicGraph.GraphicElement; 10 | import org.graphstream.ui.graphicGraph.GraphicSprite; 11 | import org.graphstream.ui.graphicGraph.stylesheet.Style; 12 | import org.graphstream.ui.graphicGraph.stylesheet.StyleConstants; 13 | import org.graphstream.ui.graphicGraph.stylesheet.StyleConstants.Units; 14 | import org.graphstream.ui.android.Backend; 15 | import org.graphstream.ui.view.camera.DefaultCamera2D; 16 | import org.graphstream.ui.android.renderer.Skeleton; 17 | import org.graphstream.ui.android.renderer.shape.Orientable; 18 | 19 | public class OrientableRectangularAreaShape extends RectangularAreaShape { 20 | Orientable orientable ; 21 | 22 | Point3 p = null; 23 | double angle = 0.0; 24 | double w = 0.0; 25 | double h = 0.0; 26 | boolean oriented = false; 27 | 28 | public OrientableRectangularAreaShape() { 29 | orientable = new Orientable(); 30 | } 31 | 32 | public void configureForGroup(Backend bck, Style style, DefaultCamera2D camera) { 33 | super.configureForGroup(bck, style, camera); 34 | orientable.configureOrientableForGroup(style, camera); 35 | oriented = (style.getSpriteOrientation() != StyleConstants.SpriteOrientation.NONE); 36 | } 37 | 38 | public void configureForElement(Backend bck, GraphicElement element, Skeleton skel, DefaultCamera2D camera) { 39 | super.configureForElement(bck, element, skel, camera); 40 | orientable.configureOrientableForElement(camera, (GraphicSprite) element /* Check This XXX TODO !*/); 41 | } 42 | 43 | public void make(Backend backend, DefaultCamera2D camera) {make(backend, false, camera);} 44 | 45 | public void makeShadow(Backend backend, DefaultCamera2D camera) {make(backend, true, camera);} 46 | 47 | private void make(Backend bck, boolean forShadow, DefaultCamera2D camera) { 48 | if (oriented) { 49 | Vector2 theDirection = new Vector2( 50 | orientable.target.x - area.theCenter.x, 51 | orientable.target.y - area.theCenter.y ); 52 | 53 | theDirection.normalize(); 54 | 55 | double x = area.theCenter.x; 56 | double y = area.theCenter.y; 57 | 58 | if( forShadow ) { 59 | x += shadowable.theShadowOff.x; 60 | y += shadowable.theShadowOff.y; 61 | } 62 | 63 | p = camera.transformGuToPx(x, y, 0); // Pass to pixels, the image will be drawn in pixels. 64 | angle = Math.acos(theDirection.dotProduct( 1, 0 )); 65 | 66 | if( theDirection.y() > 0 ) // The angle is always computed for acute angles 67 | angle = ( Math.PI - angle ); 68 | 69 | w = camera.getMetrics().lengthToPx(area.theSize.x, Units.GU); 70 | h = camera.getMetrics().lengthToPx(area.theSize.y, Units.GU); 71 | ((Form) theShape()).setFrame(0, 0, w, h); 72 | } else { 73 | if (forShadow) 74 | super.makeShadow(bck, camera); 75 | else 76 | super.make(bck, camera); 77 | } 78 | } 79 | 80 | public void render(Backend bck, DefaultCamera2D camera, GraphicElement element, Skeleton skel) { 81 | make(bck, false, camera); 82 | 83 | Canvas g = bck.graphics2D(); 84 | Paint paint = bck.getPaint(); 85 | 86 | if (oriented) { 87 | Matrix Tx = bck.getMatrix(); 88 | bck.setMatrix(new Matrix()); // An identity matrix. 89 | g.translate((float) p.x, (float)p.y ); // 3. Position the image at its position in the graph. 90 | g.rotate( (float)angle ); // 2. Rotate the image from its center. 91 | g.translate( (float)-w/2, (float)-h/2 ); // 1. Position in center of the image. 92 | 93 | strokable.stroke(bck.drawingSurface(), g, paint, theShape()); 94 | fillable.fill(bck.drawingSurface(), g, paint, theShape(), camera); 95 | bck.setMatrix(Tx); // Restore the original transform 96 | ((Form) theShape()).setFrame(area.theCenter.x-w/2, area.theCenter.y-h/2, w, h); 97 | decorArea(bck, camera, skel.iconAndText, element, theShape()); 98 | } 99 | else { 100 | super.render(bck, camera, element, skel); 101 | } 102 | } 103 | 104 | 105 | public void renderShadow(Backend bck, DefaultCamera2D camera, GraphicElement element, Skeleton skel) { 106 | make(bck, true, camera); 107 | 108 | Canvas g = bck.graphics2D(); 109 | 110 | if (oriented) { 111 | Matrix Tx = bck.getMatrix(); 112 | bck.setMatrix(new Matrix()); // An identity matrix. 113 | g.translate( (float)p.x, (float)p.y ); // 3. Position the image at its position in the graph. 114 | g.rotate( (float)angle ); // 2. Rotate the image from its center. 115 | g.translate( (float)-w/2, (float)-h/2 ); // 1. Position in center of the image. 116 | 117 | shadowable.cast(bck.drawingSurface(), g, bck.getPaint(), theShape()); 118 | bck.setMatrix( Tx ); // Restore the original transform 119 | } else { 120 | super.renderShadow(bck, camera, element, skel); 121 | } 122 | } 123 | } 124 | -------------------------------------------------------------------------------- /app/src/main/java/org/graphstream/ui/android/renderer/shape/android/baseShapes/PolygonalShape.java: -------------------------------------------------------------------------------- 1 | package org.graphstream.ui.android.renderer.shape.android.baseShapes; 2 | 3 | import android.graphics.Canvas; 4 | import android.graphics.Paint; 5 | 6 | import org.graphstream.ui.graphicGraph.GraphicElement; 7 | import org.graphstream.ui.android.Backend; 8 | import org.graphstream.ui.view.camera.DefaultCamera2D; 9 | import org.graphstream.ui.android.renderer.Skeleton; 10 | import org.graphstream.ui.android.renderer.shape.android.baseShapes.Form.Path2D; 11 | 12 | public abstract class PolygonalShape extends AreaShape { 13 | protected Path2D theShape = null; 14 | 15 | public void renderShadow(Backend bck, DefaultCamera2D camera, GraphicElement element, Skeleton skel) { 16 | makeShadow(bck, camera); 17 | shadowable.cast(bck.drawingSurface(), bck.graphics2D(), bck.getPaint(), theShape()); 18 | } 19 | 20 | public void render(Backend bck, DefaultCamera2D camera, GraphicElement element, Skeleton skel) { 21 | Canvas g = bck.graphics2D(); 22 | Paint p = bck.getPaint(); 23 | make(bck, camera); 24 | fillable.fill(bck.drawingSurface(), g, p, theShape(), camera); 25 | strokable.stroke(bck.drawingSurface(), g, p, theShape()); 26 | decorArea(bck, camera, skel.iconAndText, element, theShape()); 27 | } 28 | 29 | public Path2D theShape() { 30 | return theShape ; 31 | } 32 | } -------------------------------------------------------------------------------- /app/src/main/java/org/graphstream/ui/android/renderer/shape/android/baseShapes/PolylineEdgeShape.java: -------------------------------------------------------------------------------- 1 | package org.graphstream.ui.android.renderer.shape.android.baseShapes; 2 | 3 | import android.graphics.Canvas; 4 | import android.graphics.Paint; 5 | 6 | import org.graphstream.ui.graphicGraph.GraphicElement; 7 | import org.graphstream.ui.android.Backend; 8 | import org.graphstream.ui.view.camera.DefaultCamera2D; 9 | import org.graphstream.ui.android.renderer.Skeleton; 10 | import org.graphstream.ui.android.renderer.shape.android.ShowCubics; 11 | import org.graphstream.ui.android.renderer.shape.android.baseShapes.Form.Path2D; 12 | 13 | public class PolylineEdgeShape extends LineConnectorShape { 14 | public ShowCubics showCubics ; 15 | protected Path2D theShape = new Path2D(0, false); 16 | 17 | public PolylineEdgeShape() { 18 | this.showCubics = new ShowCubics(); 19 | } 20 | 21 | @Override 22 | public void make(Backend backend, DefaultCamera2D camera) { 23 | int n = skel.size(); 24 | 25 | theShape = new Path2D(n+2, false); 26 | theShape.moveTo(skel.apply(0).x, skel.apply(0).y); 27 | 28 | for(int i = 0 ; i < n ; i++) { 29 | theShape.lineTo(skel.apply(i).x, skel.apply(i).y); 30 | } 31 | } 32 | 33 | @Override 34 | public void makeShadow(Backend backend, DefaultCamera2D camera) {} 35 | 36 | @Override 37 | public void render(Backend bck, DefaultCamera2D camera, GraphicElement element, Skeleton skeleton) { 38 | Canvas g = bck.graphics2D(); 39 | Paint p = bck.getPaint(); 40 | make(bck, camera); 41 | strokableLine.stroke(bck.drawingSurface(), g, p, theShape); 42 | fillableLine.fill(bck.drawingSurface(), g, p, theSize, theShape); 43 | decorable.decorConnector(bck, camera, skel.iconAndText, element, theShape); 44 | } 45 | 46 | @Override 47 | public void renderShadow(Backend bck, DefaultCamera2D camera, GraphicElement element, Skeleton skeleton) { 48 | makeShadow(bck, camera); 49 | shadowableLine.cast(bck.drawingSurface(), bck.graphics2D(), bck.getPaint(), theShape); 50 | } 51 | 52 | } -------------------------------------------------------------------------------- /app/src/main/java/org/graphstream/ui/android/renderer/shape/android/baseShapes/RectangularAreaShape.java: -------------------------------------------------------------------------------- 1 | package org.graphstream.ui.android.renderer.shape.android.baseShapes; 2 | 3 | import org.graphstream.ui.graphicGraph.GraphicElement; 4 | import org.graphstream.ui.android.Backend; 5 | import org.graphstream.ui.view.camera.DefaultCamera2D; 6 | import org.graphstream.ui.android.renderer.Skeleton; 7 | 8 | public abstract class RectangularAreaShape extends AreaShape { 9 | private Form.Rectangle2D theShape = new Form.Rectangle2D(); 10 | 11 | @Override 12 | public void make(Backend backend, DefaultCamera2D camera) { 13 | float w = (float)area.theSize.x; 14 | float h = (float)area.theSize.y; 15 | 16 | ((Form)theShape()).setFrame((float)area.theCenter.x-w/2, (float)area.theCenter.y-h/2, w, h); 17 | } 18 | 19 | @Override 20 | public void makeShadow(Backend backend, DefaultCamera2D camera) { 21 | float x = (float)(area.theCenter.x + shadowable.theShadowOff.x); 22 | float y = (float)(area.theCenter.y + shadowable.theShadowOff.y); 23 | float w = (float)(area.theSize.x + shadowable.theShadowWidth.x * 2); 24 | float h = (float)(area.theSize.y + shadowable.theShadowWidth.y * 2); 25 | 26 | ((Form)theShape()).setFrame(x-w/2, y-h/2, w, h); 27 | } 28 | 29 | @Override 30 | public void render(Backend bck, DefaultCamera2D camera, GraphicElement element, Skeleton skel) { 31 | make(bck, camera); 32 | fillable.fill(bck.drawingSurface(), bck.graphics2D(), bck.getPaint(), theShape(), camera); 33 | strokable.stroke(bck.drawingSurface(), bck.graphics2D(), bck.getPaint(), theShape()); 34 | decorArea(bck, camera, skel.iconAndText, element, theShape()); 35 | } 36 | 37 | @Override 38 | public void renderShadow(Backend bck, DefaultCamera2D camera, GraphicElement element, Skeleton skeleton) { 39 | makeShadow(bck, camera); 40 | shadowable.cast(bck.drawingSurface(), bck.graphics2D(), bck.getPaint(), theShape()); 41 | } 42 | 43 | public Form theShape() { 44 | return theShape; 45 | } 46 | } -------------------------------------------------------------------------------- /app/src/main/java/org/graphstream/ui/android/renderer/shape/android/basicShapes/CircleShape.java: -------------------------------------------------------------------------------- 1 | package org.graphstream.ui.android.renderer.shape.android.basicShapes; 2 | 3 | import org.graphstream.ui.android.renderer.shape.android.baseShapes.Form; 4 | import org.graphstream.ui.android.renderer.shape.android.baseShapes.Form.Ellipse2D; 5 | import org.graphstream.ui.android.renderer.shape.android.baseShapes.RectangularAreaShape; 6 | 7 | public class CircleShape extends RectangularAreaShape { 8 | private Form theShape = new Ellipse2D(); 9 | 10 | public Form theShape() { 11 | return theShape; 12 | } 13 | } -------------------------------------------------------------------------------- /app/src/main/java/org/graphstream/ui/android/renderer/shape/android/basicShapes/CrossShape.java: -------------------------------------------------------------------------------- 1 | package org.graphstream.ui.android.renderer.shape.android.basicShapes; 2 | 3 | import org.graphstream.ui.android.Backend; 4 | import org.graphstream.ui.view.camera.DefaultCamera2D; 5 | import org.graphstream.ui.android.renderer.shape.android.baseShapes.PolygonalShape; 6 | import org.graphstream.ui.android.renderer.shape.android.baseShapes.Form.Path2D; 7 | 8 | public class CrossShape extends PolygonalShape { 9 | 10 | @Override 11 | public void make(Backend backend, DefaultCamera2D camera) { 12 | double x = area.theCenter.x; 13 | double y = area.theCenter.y; 14 | double h2 = area.theSize.x / 2; 15 | double w2 = area.theSize.y / 2; 16 | double w1 = area.theSize.x * 0.2f; 17 | double h1 = area.theSize.y * 0.2f; 18 | double w4 = area.theSize.x * 0.3f; 19 | double h4 = area.theSize.y * 0.3f; 20 | 21 | theShape = new Path2D(20, true); 22 | theShape().moveTo( x - w2, y + h4 ); 23 | theShape().lineTo( x - w4, y + h2 ); 24 | theShape().lineTo( x, y + h1 ); 25 | theShape().lineTo( x + w4, y + h2 ); 26 | theShape().lineTo( x + w2, y + h4 ); 27 | theShape().lineTo( x + w1, y ); 28 | theShape().lineTo( x + w2, y - h4 ); 29 | theShape().lineTo( x + w4, y - h2 ); 30 | theShape().lineTo( x, y - h1 ); 31 | theShape().lineTo( x - w4, y - h2 ); 32 | theShape().lineTo( x - w2, y - h4 ); 33 | theShape().lineTo( x - w1, y ); 34 | theShape().closePath(); 35 | } 36 | 37 | @Override 38 | public void makeShadow(Backend backend, DefaultCamera2D camera) { 39 | double x = area.theCenter.x + shadowable.theShadowOff.x; 40 | double y = area.theCenter.y + shadowable.theShadowOff.y; 41 | double h2 = ( area.theSize.x + shadowable.theShadowWidth.x ) / 2; 42 | double w2 = ( area.theSize.y + shadowable.theShadowWidth.y ) / 2; 43 | double w1 = ( area.theSize.x + shadowable.theShadowWidth.x ) * 0.2f; 44 | double h1 = ( area.theSize.y + shadowable.theShadowWidth.y ) * 0.2f; 45 | double w4 = ( area.theSize.x + shadowable.theShadowWidth.x ) * 0.3f; 46 | double h4 = ( area.theSize.y + shadowable.theShadowWidth.y ) * 0.3f; 47 | 48 | theShape = new Path2D(20, true); 49 | theShape().moveTo( x - w2, y + h4 ); 50 | theShape().lineTo( x - w4, y + h2 ); 51 | theShape().lineTo( x, y + h1 ); 52 | theShape().lineTo( x + w4, y + h2 ); 53 | theShape().lineTo( x + w2, y + h4 ); 54 | theShape().lineTo( x + w1, y ); 55 | theShape().lineTo( x + w2, y - h4 ); 56 | theShape().lineTo( x + w4, y - h2 ); 57 | theShape().lineTo( x, y - h1 ); 58 | theShape().lineTo( x - w4, y - h2 ); 59 | theShape().lineTo( x - w2, y - h4 ); 60 | theShape().lineTo( x - w1, y ); 61 | theShape().closePath(); 62 | } 63 | } -------------------------------------------------------------------------------- /app/src/main/java/org/graphstream/ui/android/renderer/shape/android/basicShapes/DiamondShape.java: -------------------------------------------------------------------------------- 1 | package org.graphstream.ui.android.renderer.shape.android.basicShapes; 2 | 3 | import org.graphstream.ui.android.Backend; 4 | import org.graphstream.ui.view.camera.DefaultCamera2D; 5 | import org.graphstream.ui.android.renderer.shape.android.baseShapes.PolygonalShape; 6 | import org.graphstream.ui.android.renderer.shape.android.baseShapes.Form.Path2D; 7 | 8 | public class DiamondShape extends PolygonalShape { 9 | 10 | @Override 11 | public void make(Backend backend, DefaultCamera2D camera) { 12 | double x = area.theCenter.x; 13 | double y = area.theCenter.y; 14 | double w2 = area.theSize.x / 2; 15 | double h2 = area.theSize.y / 2; 16 | 17 | theShape = new Path2D(10, true); 18 | theShape().moveTo( x - w2, y ); 19 | theShape().lineTo( x, y - h2 ); 20 | theShape().lineTo( x + w2, y ); 21 | theShape().lineTo( x, y + h2 ); 22 | theShape.closePath(); 23 | } 24 | 25 | @Override 26 | public void makeShadow(Backend backend, DefaultCamera2D camera) { 27 | double x = area.theCenter.x + shadowable.theShadowOff.x; 28 | double y = area.theCenter.y + shadowable.theShadowOff.y; 29 | double w2 = ( area.theSize.x + shadowable.theShadowWidth.x ) / 2; 30 | double h2 = ( area.theSize.y + shadowable.theShadowWidth.y ) / 2; 31 | 32 | theShape = new Path2D(10, true); 33 | theShape().moveTo( x - w2, y ); 34 | theShape().lineTo( x, y - h2 ); 35 | theShape().lineTo( x + w2, y ); 36 | theShape().lineTo( x, y + h2 ); 37 | theShape.closePath(); 38 | } 39 | } -------------------------------------------------------------------------------- /app/src/main/java/org/graphstream/ui/android/renderer/shape/android/basicShapes/FreePlaneNodeShape.java: -------------------------------------------------------------------------------- 1 | package org.graphstream.ui.android.renderer.shape.android.basicShapes; 2 | 3 | import android.graphics.Canvas; 4 | import android.graphics.Paint; 5 | 6 | import org.graphstream.ui.graphicGraph.GraphicElement; 7 | import org.graphstream.ui.android.Backend; 8 | import org.graphstream.ui.view.camera.DefaultCamera2D; 9 | import org.graphstream.ui.android.renderer.Skeleton; 10 | import org.graphstream.ui.android.renderer.shape.android.baseShapes.Form; 11 | import org.graphstream.ui.android.renderer.shape.android.baseShapes.Form.Line2D; 12 | import org.graphstream.ui.android.renderer.shape.android.baseShapes.Form.Rectangle2D; 13 | import org.graphstream.ui.android.renderer.shape.android.baseShapes.RectangularAreaShape; 14 | 15 | public class FreePlaneNodeShape extends RectangularAreaShape { 16 | Rectangle2D theShape = new Rectangle2D(); 17 | Line2D theLineShape = new Line2D(); 18 | 19 | @Override 20 | public void make(Backend backend, DefaultCamera2D camera) { 21 | double w = area.theSize.x ; 22 | double h = area.theSize.y ; 23 | double x = area.theCenter.x ; 24 | double y = area.theCenter.y ; 25 | 26 | ((Rectangle2D) theShape()).setFrame( x-w/2, y-h/2, w, h ); 27 | 28 | w -= strokable.theStrokeWidth; 29 | 30 | theLineShape.setFrame( x-w/2, y-h/2, x+w/2, y-h/2 ); 31 | } 32 | 33 | @Override 34 | public void makeShadow(Backend backend, DefaultCamera2D camera) { 35 | double x = area.theCenter.x + shadowable.theShadowOff.x; 36 | double y = area.theCenter.y + shadowable.theShadowOff.y; 37 | double w = area.theSize.x + shadowable.theShadowWidth.x * 2; 38 | double h = area.theSize.y + shadowable.theShadowWidth.y * 2; 39 | 40 | ((Rectangle2D) theShape()).setFrame( x-w/2, y-h/2, w, h ); 41 | theLineShape.setFrame( x-w/2, y-h/2, x+w/2, y-h/2 ); 42 | } 43 | 44 | @Override 45 | public void render(Backend bck, DefaultCamera2D camera, GraphicElement element, Skeleton skel) { 46 | Canvas g = bck.graphics2D(); 47 | Paint p = bck.getPaint(); 48 | make(bck, camera); 49 | fillable.fill(bck.drawingSurface(), g, p, theShape(), camera); 50 | strokable.stroke(bck.drawingSurface(), g, p, theLineShape); 51 | decorArea(bck, camera, skel.iconAndText, element, theShape()); 52 | } 53 | 54 | @Override 55 | public Form theShape() { 56 | return theShape; 57 | } 58 | 59 | } 60 | -------------------------------------------------------------------------------- /app/src/main/java/org/graphstream/ui/android/renderer/shape/android/basicShapes/PolygonShape.java: -------------------------------------------------------------------------------- 1 | package org.graphstream.ui.android.renderer.shape.android.basicShapes; 2 | 3 | import org.graphstream.ui.geom.Point3; 4 | import org.graphstream.ui.graphicGraph.GraphicElement; 5 | import org.graphstream.ui.android.Backend; 6 | import org.graphstream.ui.view.camera.DefaultCamera2D; 7 | import org.graphstream.ui.android.renderer.AreaSkeleton; 8 | import org.graphstream.ui.android.renderer.Skeleton; 9 | import org.graphstream.ui.android.renderer.shape.android.baseShapes.Form.Path2D; 10 | import org.graphstream.ui.android.renderer.shape.android.baseShapes.PolygonalShape; 11 | import org.graphstream.ui.android.util.AttributeUtils; 12 | 13 | public class PolygonShape extends PolygonalShape implements AttributeUtils { 14 | Point3[] theValues = null ; 15 | Point3 minPoint = null ; 16 | Point3 maxPoint = null ; 17 | Object valuesRef = null ; 18 | 19 | @Override 20 | public void configureForElement(Backend bck, GraphicElement element, Skeleton skel, DefaultCamera2D camera) { 21 | super.configureForElement(bck, element, skel, camera); 22 | 23 | if(element.hasAttribute( "ui.points" )) { 24 | Object oldRef = valuesRef; 25 | valuesRef = element.getAttribute("ui.points"); 26 | // We use valueRef to avoid 27 | // recreating the values array for nothing. 28 | if( ( theValues == null ) || ( oldRef != valuesRef ) ) { 29 | theValues = getPoints(valuesRef); 30 | 31 | if(skel instanceof AreaSkeleton) { 32 | Tuple tuple = boundingBoxOfPoints(theValues); 33 | 34 | minPoint = tuple.x; 35 | maxPoint = tuple.y; 36 | } 37 | } 38 | 39 | AreaSkeleton ninfo = (AreaSkeleton)skel; 40 | ninfo.theSize.set(maxPoint.x-minPoint.x, maxPoint.y-minPoint.y); 41 | area.theSize.copy(ninfo.theSize); 42 | } 43 | } 44 | 45 | @Override 46 | public void make(Backend backend, DefaultCamera2D camera) { 47 | double x = area.theCenter.x; 48 | double y = area.theCenter.y; 49 | double n = theValues.length; 50 | 51 | theShape = new Path2D((int)n+2, true); 52 | 53 | if(n > 0) { 54 | theShape().moveTo(x+theValues[0].x, y+theValues[0].y); 55 | for(int i = 0 ; i < n ; i++) { 56 | theShape().lineTo(x+theValues[i].x, y+theValues[i].y); 57 | } 58 | } 59 | theShape.closePath(); 60 | } 61 | 62 | @Override 63 | public void makeShadow(Backend backend, DefaultCamera2D camera) { 64 | double n = theValues.length; 65 | double x = area.theCenter.x + shadowable.theShadowOff.x; 66 | double y = area.theCenter.y + shadowable.theShadowOff.y; 67 | 68 | theShape = new Path2D((int)n+2, true); 69 | 70 | if(n > 0) { 71 | theShape().moveTo(x+theValues[0].x, y+theValues[0].y); 72 | for(int i = 0 ; i < n ; i++) { 73 | theShape().lineTo(x+theValues[i].x, y+theValues[i].y); 74 | } 75 | } 76 | theShape.closePath(); 77 | } 78 | } -------------------------------------------------------------------------------- /app/src/main/java/org/graphstream/ui/android/renderer/shape/android/basicShapes/RoundedSquareShape.java: -------------------------------------------------------------------------------- 1 | package org.graphstream.ui.android.renderer.shape.android.basicShapes; 2 | 3 | import org.graphstream.ui.android.Backend; 4 | import org.graphstream.ui.view.camera.DefaultCamera2D; 5 | import org.graphstream.ui.android.renderer.shape.android.baseShapes.Form; 6 | import org.graphstream.ui.android.renderer.shape.android.baseShapes.Form.Rectangle2D; 7 | import org.graphstream.ui.android.renderer.shape.android.baseShapes.RectangularAreaShape; 8 | 9 | public class RoundedSquareShape extends RectangularAreaShape { 10 | Rectangle2D theShape = new Rectangle2D(); 11 | 12 | @Override 13 | public void make(Backend backend, DefaultCamera2D camera) { 14 | double w = area.theSize.x ; 15 | double h = area.theSize.x ; 16 | double r = h/8 ; 17 | if( h/8 > w/8 ) 18 | r = w/8 ; 19 | ((Rectangle2D) theShape()).setRoundRect( area.theCenter.x-w/2, area.theCenter.y-h/2, w, h, r, r ) ; 20 | } 21 | 22 | @Override 23 | public void makeShadow(Backend backend, DefaultCamera2D camera) { 24 | double x = area.theCenter.x + shadowable.theShadowOff.x; 25 | double y = area.theCenter.y + shadowable.theShadowOff.y; 26 | double w = area.theSize.x + shadowable.theShadowWidth.x * 2; 27 | double h = area.theSize.y + shadowable.theShadowWidth.y * 2; 28 | double r = h/8 ; 29 | if( h/8 > w/8 ) 30 | r = w/8; 31 | 32 | ((Rectangle2D) theShape()).setRoundRect( x-w/2, y-h/2, w, h, r, r ); 33 | } 34 | 35 | @Override 36 | public Form theShape() { 37 | return theShape; 38 | } 39 | } -------------------------------------------------------------------------------- /app/src/main/java/org/graphstream/ui/android/renderer/shape/android/basicShapes/SquareShape.java: -------------------------------------------------------------------------------- 1 | package org.graphstream.ui.android.renderer.shape.android.basicShapes; 2 | 3 | import org.graphstream.ui.android.renderer.shape.android.baseShapes.Form; 4 | import org.graphstream.ui.android.renderer.shape.android.baseShapes.Form.Rectangle2D; 5 | import org.graphstream.ui.android.renderer.shape.android.baseShapes.RectangularAreaShape; 6 | 7 | public class SquareShape extends RectangularAreaShape { 8 | private Rectangle2D theShape = new Rectangle2D(); 9 | 10 | public Form theShape() { 11 | return theShape; 12 | } 13 | } -------------------------------------------------------------------------------- /app/src/main/java/org/graphstream/ui/android/renderer/shape/android/basicShapes/TriangleShape.java: -------------------------------------------------------------------------------- 1 | package org.graphstream.ui.android.renderer.shape.android.basicShapes; 2 | 3 | import org.graphstream.ui.android.Backend; 4 | import org.graphstream.ui.view.camera.DefaultCamera2D; 5 | import org.graphstream.ui.android.renderer.shape.android.baseShapes.PolygonalShape; 6 | import org.graphstream.ui.android.renderer.shape.android.baseShapes.Form.Path2D; 7 | 8 | public class TriangleShape extends PolygonalShape { 9 | 10 | @Override 11 | public void make(Backend backend, DefaultCamera2D camera) { 12 | double x = area.theCenter.x; 13 | double y = area.theCenter.y; 14 | double w2 = area.theSize.x / 2; 15 | double h2 = area.theSize.y / 2; 16 | 17 | theShape = new Path2D(5, true); 18 | theShape().moveTo( x, y + h2 ); 19 | theShape().lineTo( x + w2, y - h2 ); 20 | theShape().lineTo( x - w2, y - h2 ); 21 | theShape.closePath(); 22 | } 23 | 24 | @Override 25 | public void makeShadow(Backend backend, DefaultCamera2D camera) { 26 | double x = area.theCenter.x + shadowable.theShadowOff.x; 27 | double y = area.theCenter.y + shadowable.theShadowOff.y; 28 | double w2 = ( area.theSize.x + shadowable.theShadowWidth.x ) / 2; 29 | double h2 = ( area.theSize.y + shadowable.theShadowWidth.y ) / 2; 30 | 31 | theShape = new Path2D(5, true); 32 | theShape().moveTo( x, y + h2 ); 33 | theShape().lineTo( x + w2, y - h2 ); 34 | theShape().lineTo( x - w2, y - h2 ); 35 | theShape.closePath(); 36 | } 37 | } -------------------------------------------------------------------------------- /app/src/main/java/org/graphstream/ui/android/renderer/shape/android/shapePart/Fillable.java: -------------------------------------------------------------------------------- 1 | package org.graphstream.ui.android.renderer.shape.android.shapePart; 2 | 3 | import android.graphics.Canvas; 4 | import android.graphics.Paint; 5 | import android.util.Log; 6 | import android.view.SurfaceView; 7 | 8 | import org.graphstream.ui.android.util.Background; 9 | import org.graphstream.ui.android.util.ColorManager; 10 | import org.graphstream.ui.graphicGraph.GraphicElement; 11 | import org.graphstream.ui.graphicGraph.stylesheet.Style; 12 | import org.graphstream.ui.graphicGraph.stylesheet.StyleConstants; 13 | import org.graphstream.ui.android.Backend; 14 | import org.graphstream.ui.view.camera.DefaultCamera2D; 15 | import org.graphstream.ui.android.renderer.shape.android.ShapePaint; 16 | import org.graphstream.ui.android.renderer.shape.android.ShapePaint.ShapeAreaPaint; 17 | import org.graphstream.ui.android.renderer.shape.android.ShapePaint.ShapeColorPaint; 18 | import org.graphstream.ui.android.renderer.shape.android.ShapePaint.ShapePlainColorPaint; 19 | import org.graphstream.ui.android.renderer.shape.android.baseShapes.Form; 20 | 21 | public class Fillable { 22 | 23 | /** The fill paint. */ 24 | private ShapePaint fillPaint = null; 25 | 26 | /** Value in [0..1] for dyn-colors. */ 27 | private double theFillPercent = 0.0; 28 | 29 | private int theFillColor = -1; 30 | 31 | private boolean plainFast = false; 32 | 33 | /** Fill the shape. 34 | * @param g The Java2D graphics. 35 | * @param dynColor The value between 0 and 1 allowing to know the dynamic plain color, if any. 36 | * @param shape The shape to fill. */ 37 | public void fill(SurfaceView view, Canvas g, Paint p, double dynColor, int optColor, Form shape, DefaultCamera2D camera) { 38 | if(plainFast) { 39 | p.setColor(theFillColor); 40 | shape.drawByPoints(view, g, p, false); 41 | } 42 | else { 43 | if ( fillPaint instanceof ShapeAreaPaint ) { 44 | Background background = ((ShapeAreaPaint)fillPaint).paint(shape, camera.getMetrics().ratioPx2Gu) ; 45 | background.applyPaint(g, p); 46 | if (!background.isImage()) 47 | shape.drawByPoints(view, g, p, false); 48 | background.removePaint(p); 49 | } 50 | else if (fillPaint instanceof ShapeColorPaint ) { 51 | Background background = ((ShapeColorPaint)fillPaint).paint(dynColor, optColor); 52 | background.applyPaint(g, p); 53 | if (!background.isImage()) 54 | shape.drawByPoints(view, g, p, false); 55 | background.removePaint(p); 56 | } 57 | } 58 | } 59 | 60 | /** Fill the shape. 61 | * @param g The Java2D graphics. 62 | * @param shape The shape to fill. */ 63 | public void fill(SurfaceView view, Canvas g, Paint p, Form shape, DefaultCamera2D camera) { 64 | fill(view, g, p, theFillPercent, theFillColor, shape, camera ); 65 | } 66 | 67 | /** Configure all static parts needed to fill the shape. */ 68 | public void configureFillableForGroup(Backend bck, Style style, DefaultCamera2D camera ) { 69 | fillPaint = ShapePaint.apply(style); 70 | 71 | if(fillPaint instanceof ShapePlainColorPaint) { 72 | ShapePlainColorPaint paint = (ShapePlainColorPaint)fillPaint; 73 | 74 | plainFast = true; 75 | theFillColor = paint.color; 76 | bck.getPaint().setColor(theFillColor); 77 | // We prepare to accelerate the filling process if we know the color is not dynamic 78 | // and is plain: no need to change the paint at each new position for the shape. 79 | } 80 | else { 81 | plainFast = false; 82 | } 83 | } 84 | 85 | /** Configure the dynamic parts needed to fill the shape. */ 86 | public void configureFillableForElement( Style style, DefaultCamera2D camera, GraphicElement element ) { 87 | if( style.getFillMode() == StyleConstants.FillMode.DYN_PLAIN && element != null ) { 88 | if ( element.getAttribute( "ui.color" ) instanceof Integer) { 89 | theFillColor = ((int)element.getAttribute( "ui.color" )); 90 | theFillPercent = 0; 91 | } 92 | else if ( element.getAttribute( "ui.color" ) instanceof Number ) { 93 | theFillPercent = (float) ((Number) element.getAttribute("ui.color")); 94 | theFillColor = -1; 95 | } 96 | else { 97 | theFillPercent = 0; 98 | theFillColor = -1; 99 | } 100 | } 101 | else { 102 | theFillPercent = 0; 103 | } 104 | } 105 | } -------------------------------------------------------------------------------- /app/src/main/java/org/graphstream/ui/android/renderer/shape/android/shapePart/FillableLine.java: -------------------------------------------------------------------------------- 1 | package org.graphstream.ui.android.renderer.shape.android.shapePart; 2 | 3 | import android.graphics.Canvas; 4 | import android.graphics.Paint; 5 | import android.view.SurfaceView; 6 | 7 | import org.graphstream.ui.graphicGraph.GraphicElement; 8 | import org.graphstream.ui.graphicGraph.stylesheet.Style; 9 | import org.graphstream.ui.graphicGraph.stylesheet.StyleConstants; 10 | import org.graphstream.ui.android.Backend; 11 | import org.graphstream.ui.view.camera.DefaultCamera2D; 12 | import org.graphstream.ui.android.renderer.shape.android.ShapePaint; 13 | import org.graphstream.ui.android.renderer.shape.android.ShapeStroke; 14 | import org.graphstream.ui.android.renderer.shape.android.baseShapes.Form; 15 | import org.graphstream.ui.android.util.ColorManager; 16 | 17 | public class FillableLine { 18 | ShapeStroke fillStroke = null ; 19 | double theFillPercent = 0.0 ; 20 | int theFillColor = -1 ; 21 | boolean plainFast = false ; 22 | 23 | public void fill(SurfaceView view, Canvas g, Paint p, double width, double dynColor, Form shape) { 24 | if(fillStroke != null) { 25 | if(plainFast) { 26 | p.setColor(theFillColor); 27 | shape.drawByPoints(view, g, p, false); 28 | } 29 | else { 30 | p.setColor(theFillColor); 31 | fillStroke.stroke((float)width, shape, -1).changeStrokeProperties(g, p); 32 | 33 | shape.drawByPoints(view, g, p, false); 34 | } 35 | } 36 | } 37 | 38 | public void fill(SurfaceView view, Canvas g, Paint p, double width, Form shape) { fill(view, g, p, width, theFillPercent, shape); } 39 | 40 | public void configureFillableLineForGroup(Backend bck, Style style, DefaultCamera2D camera, double theSize) { 41 | fillStroke = ShapeStroke.strokeForConnectorFill( style ); 42 | plainFast = (style.getSizeMode() == StyleConstants.SizeMode.NORMAL); 43 | theFillColor = ColorManager.getFillColor(style, 0); 44 | bck.getPaint().setColor(theFillColor); 45 | if(fillStroke != null) { 46 | fillStroke.stroke((float)theSize, null, theFillColor).changeStrokeProperties(bck.graphics2D(), bck.getPaint()); 47 | } 48 | } 49 | 50 | public void configureFillableLineForElement( Style style, DefaultCamera2D camera, GraphicElement element ) { 51 | theFillPercent = 0 ; 52 | if( style.getFillMode() == StyleConstants.FillMode.DYN_PLAIN && element != null ) { 53 | if ( element.getAttribute( "ui.color" ) instanceof Integer ) { 54 | theFillColor = ((int)element.getAttribute( "ui.color" )); 55 | theFillPercent = 0; 56 | } 57 | else if ( element.getAttribute( "ui.color" ) instanceof Number ) { 58 | theFillPercent = (float)((Number)element.getAttribute( "ui.color" )); 59 | theFillColor = ShapePaint.interpolateColor( style.getFillColors(), theFillPercent ) ; 60 | } 61 | else { 62 | theFillPercent = 0f; 63 | theFillColor = ColorManager.getFillColor(style, 0); 64 | } 65 | 66 | plainFast = false; 67 | } 68 | } 69 | } -------------------------------------------------------------------------------- /app/src/main/java/org/graphstream/ui/android/renderer/shape/android/shapePart/FillableMulticolored.java: -------------------------------------------------------------------------------- 1 | package org.graphstream.ui.android.renderer.shape.android.shapePart; 2 | 3 | import org.graphstream.ui.graphicGraph.stylesheet.Style; 4 | import org.graphstream.ui.view.camera.DefaultCamera2D; 5 | import org.graphstream.ui.android.util.ColorManager; 6 | 7 | public class FillableMulticolored { 8 | public int[] fillColors = null ; 9 | 10 | public void configureFillableMultiColoredForGroup(Style style, DefaultCamera2D camera) { 11 | int count = style.getFillColorCount(); 12 | 13 | if(fillColors == null || fillColors.length != count) { 14 | fillColors = new int[count]; 15 | } 16 | 17 | for (int i = 0 ; i < count ; i++) { 18 | fillColors[i] = ColorManager.getFillColor(style, i); 19 | } 20 | } 21 | } -------------------------------------------------------------------------------- /app/src/main/java/org/graphstream/ui/android/renderer/shape/android/shapePart/Shadowable.java: -------------------------------------------------------------------------------- 1 | package org.graphstream.ui.android.renderer.shape.android.shapePart; 2 | 3 | import android.graphics.Canvas; 4 | import android.graphics.Paint; 5 | import android.view.SurfaceView; 6 | 7 | import org.graphstream.ui.android.util.Background; 8 | import org.graphstream.ui.geom.Point2; 9 | import org.graphstream.ui.graphicGraph.stylesheet.Style; 10 | import org.graphstream.ui.view.camera.DefaultCamera2D; 11 | import org.graphstream.ui.android.renderer.shape.android.ShapePaint; 12 | import org.graphstream.ui.android.renderer.shape.android.ShapePaint.ShapeAreaPaint; 13 | import org.graphstream.ui.android.renderer.shape.android.ShapePaint.ShapeColorPaint; 14 | import org.graphstream.ui.android.renderer.shape.android.baseShapes.Form; 15 | 16 | public class Shadowable { 17 | /** The shadow paint. */ 18 | public ShapePaint shadowPaint = null ; 19 | 20 | /** Additional width of a shadow (added to the shape size). */ 21 | public Point2 theShadowWidth = new Point2(); 22 | 23 | /** Offset of the shadow according to the shape center. */ 24 | public Point2 theShadowOff = new Point2(); 25 | 26 | /** Set the shadow width added to the shape width. */ 27 | public void shadowWidth( double width, double height ) { theShadowWidth.set( width, height ); } 28 | 29 | /** Set the shadow offset according to the shape. */ 30 | public void shadowOffset( double xoff, double yoff ) { theShadowOff.set( xoff, yoff ); } 31 | 32 | /** 33 | * Render the shadow. 34 | * @param g The Java2D graphics. 35 | */ 36 | public void cast(SurfaceView view, Canvas g, Paint p, Form shape) { 37 | if ( shadowPaint instanceof ShapeAreaPaint ) { 38 | Background background = ((ShapeAreaPaint)shadowPaint).paint( shape, 1 ) ; 39 | background.applyPaint(g, p); 40 | if (!background.isImage()) 41 | shape.drawByPoints(view, g, p, false); 42 | background.removePaint(p); 43 | } 44 | else if ( shadowPaint instanceof ShapeColorPaint ) { 45 | Background background = ((ShapeColorPaint)shadowPaint).paint( 0, -1 ) ; 46 | background.applyPaint(g, p); 47 | if (!background.isImage()) 48 | shape.drawByPoints(view, g, p, false); 49 | background.removePaint(p); 50 | } 51 | else { 52 | System.out.println("no shadow !!!"); 53 | } 54 | } 55 | 56 | /** Configure all the static parts needed to cast the shadow of the shape. */ 57 | public void configureShadowableForGroup( Style style, DefaultCamera2D camera ) { 58 | theShadowWidth.x = camera.getMetrics().lengthToGu( style.getShadowWidth() ); 59 | theShadowWidth.y = theShadowWidth.x; 60 | theShadowOff.x = camera.getMetrics().lengthToGu( style.getShadowOffset(), 0 ); 61 | theShadowOff.y = theShadowOff.x ; 62 | if( style.getShadowOffset().size() > 1 ) 63 | theShadowOff.y = camera.getMetrics().lengthToGu( style.getShadowOffset(), 1 ); 64 | 65 | /*if( shadowPaint == null )*/ shadowPaint = ShapePaint.apply( style, true ); 66 | } 67 | } -------------------------------------------------------------------------------- /app/src/main/java/org/graphstream/ui/android/renderer/shape/android/shapePart/ShadowableLine.java: -------------------------------------------------------------------------------- 1 | package org.graphstream.ui.android.renderer.shape.android.shapePart; 2 | 3 | import android.graphics.Canvas; 4 | import android.graphics.Paint; 5 | import android.view.SurfaceView; 6 | 7 | import org.graphstream.ui.geom.Point2; 8 | import org.graphstream.ui.graphicGraph.stylesheet.Style; 9 | import org.graphstream.ui.view.camera.DefaultCamera2D; 10 | import org.graphstream.ui.android.renderer.shape.android.ShapeStroke; 11 | import org.graphstream.ui.android.renderer.shape.android.baseShapes.Form; 12 | import org.graphstream.ui.android.util.ColorManager; 13 | 14 | public class ShadowableLine { 15 | /** The shadow paint. */ 16 | public ShapeStroke shadowStroke = null; 17 | 18 | /** Additional width of a shadow (added to the shape size). */ 19 | public float theShadowWidth = 0.0f; 20 | 21 | /** Offset of the shadow according to the shape center. */ 22 | public Point2 theShadowOff = new Point2(); 23 | 24 | public int theShadowColor = -1 ; 25 | 26 | /** Sety the shadow width added to the shape width. */ 27 | public void shadowWidth( float width ) { theShadowWidth = width; } 28 | 29 | /** Set the shadow offset according to the shape. */ 30 | public void shadowOffset( double xoff, double yoff ) { theShadowOff.set( xoff, yoff ); } 31 | 32 | /** 33 | * Render the shadow. 34 | * @param g The Java2D graphics. 35 | */ 36 | public void cast(SurfaceView view, Canvas g, Paint p, Form shape ) { 37 | p.setColor(theShadowColor); 38 | shadowStroke.stroke( theShadowWidth , shape, -1 ).changeStrokeProperties(g, p); 39 | shape.drawByPoints(view, g, p, true); 40 | } 41 | 42 | /** Configure all the static parts needed to cast the shadow of the shape. */ 43 | public void configureShadowableLineForGroup( Style style, DefaultCamera2D camera) { 44 | theShadowWidth = (float)(camera.getMetrics().lengthToGu( style.getSize(), 0 ) + 45 | camera.getMetrics().lengthToGu( style.getShadowWidth() ) + 46 | camera.getMetrics().lengthToGu( style.getStrokeWidth() ) ); 47 | theShadowOff.x = camera.getMetrics().lengthToGu( style.getShadowOffset(), 0 ); 48 | theShadowOff.y = theShadowOff.x ; 49 | if( style.getShadowOffset().size() > 1 ) 50 | camera.getMetrics().lengthToGu( style.getShadowOffset(), 1 ) ; 51 | theShadowColor = ColorManager.getShadowColor(style, 0); 52 | shadowStroke = ShapeStroke.strokeForConnectorFill( style ); 53 | } 54 | } -------------------------------------------------------------------------------- /app/src/main/java/org/graphstream/ui/android/renderer/shape/android/shapePart/Strokable.java: -------------------------------------------------------------------------------- 1 | package org.graphstream.ui.android.renderer.shape.android.shapePart; 2 | 3 | import android.graphics.Canvas; 4 | import android.graphics.Paint; 5 | import android.view.SurfaceView; 6 | 7 | import org.graphstream.ui.graphicGraph.stylesheet.Style; 8 | import org.graphstream.ui.view.camera.DefaultCamera2D; 9 | import org.graphstream.ui.android.renderer.shape.android.ShapeStroke; 10 | import org.graphstream.ui.android.renderer.shape.android.baseShapes.Form; 11 | import org.graphstream.ui.android.util.ColorManager; 12 | 13 | public class Strokable { 14 | /** The stroke color. */ 15 | public int strokeColor = -1 ; 16 | 17 | public int fillColor = -1 ; // Used by doubleStroke 18 | 19 | /** The stroke. */ 20 | public ShapeStroke theStroke = null ; 21 | 22 | /** The stroke width. */ 23 | public float theStrokeWidth = 0.0f ; 24 | 25 | /** Paint the stroke of the shape. */ 26 | public void stroke(SurfaceView view, Canvas g, Paint p, Form shape ) { 27 | if(theStroke != null) { 28 | p.setColor(strokeColor); 29 | theStroke.stroke(theStrokeWidth, shape, fillColor).changeStrokeProperties(g, p); 30 | shape.drawByPoints(view, g, p, true); 31 | } 32 | } 33 | 34 | /** Configure all the static parts needed to stroke the shape. */ 35 | public void configureStrokableForGroup( Style style, DefaultCamera2D camera ) { 36 | theStrokeWidth = (float)camera.getMetrics().lengthToGu( style.getStrokeWidth() ); 37 | 38 | /*if( strokeColor == null )*/ strokeColor = ShapeStroke.strokeColor( style ); 39 | /*if( theStroke == null )*/ theStroke = ShapeStroke.strokeForArea( style ); 40 | 41 | fillColor = ColorManager.getFillColor(style, 0); 42 | } 43 | } -------------------------------------------------------------------------------- /app/src/main/java/org/graphstream/ui/android/renderer/shape/android/shapePart/StrokableLine.java: -------------------------------------------------------------------------------- 1 | package org.graphstream.ui.android.renderer.shape.android.shapePart; 2 | 3 | import org.graphstream.ui.graphicGraph.stylesheet.Style; 4 | import org.graphstream.ui.view.camera.DefaultCamera2D; 5 | import org.graphstream.ui.android.renderer.shape.android.ShapeStroke; 6 | 7 | public class StrokableLine extends Strokable { 8 | public void configureStrokableForGroup( Style style, DefaultCamera2D camera ) { 9 | theStrokeWidth = (float)(camera.getMetrics().lengthToGu( style.getStrokeWidth() ) + camera.getMetrics().lengthToGu( style.getSize(), 0 )); 10 | strokeColor = ShapeStroke.strokeColor( style ); 11 | theStroke = ShapeStroke.strokeForArea( style ); 12 | } 13 | 14 | public void configureStrokableLineForGroup( Style style, DefaultCamera2D camera ) { 15 | configureStrokableForGroup( style, camera ) ; 16 | } 17 | } -------------------------------------------------------------------------------- /app/src/main/java/org/graphstream/ui/android/renderer/shape/android/spriteShapes/OrientableSquareShape.java: -------------------------------------------------------------------------------- 1 | package org.graphstream.ui.android.renderer.shape.android.spriteShapes; 2 | 3 | import org.graphstream.ui.android.renderer.shape.android.baseShapes.Form; 4 | import org.graphstream.ui.android.renderer.shape.android.baseShapes.Form.Rectangle2D; 5 | import org.graphstream.ui.android.renderer.shape.android.baseShapes.OrientableRectangularAreaShape; 6 | 7 | public class OrientableSquareShape extends OrientableRectangularAreaShape { 8 | private Rectangle2D theShape = new Rectangle2D(); 9 | 10 | public Form theShape() { 11 | return theShape; 12 | } 13 | } -------------------------------------------------------------------------------- /app/src/main/java/org/graphstream/ui/android/renderer/shape/android/spriteShapes/ShapeStroke.java: -------------------------------------------------------------------------------- 1 | package org.graphstream.ui.android.renderer.shape.android.spriteShapes; 2 | 3 | import org.graphstream.ui.graphicGraph.stylesheet.Style; 4 | import org.graphstream.ui.android.renderer.shape.android.baseShapes.Form; 5 | import org.graphstream.ui.android.renderer.shape.android.baseShapes.Form.Ellipse2D; 6 | import org.graphstream.ui.android.renderer.shape.android.baseShapes.Form.Rectangle2D; 7 | import org.graphstream.ui.android.util.ColorManager; 8 | import org.graphstream.ui.android.util.Stroke; 9 | 10 | import android.graphics.Canvas; 11 | import android.graphics.Paint; 12 | 13 | public abstract class ShapeStroke { 14 | public abstract Stroke stroke(float width, Form shape, int fillColor) ; 15 | 16 | public static ShapeStroke strokeForArea(Style style) { 17 | switch (style.getStrokeMode()) { 18 | case PLAIN: return new PlainShapeStroke(); 19 | case DOTS: return new DotsShapeStroke(); 20 | case DASHES: return new DashesShapeStroke(); 21 | case DOUBLE: return new DoubleShapeStroke(); 22 | default: return null ; 23 | } 24 | } 25 | 26 | public static ShapeStroke strokeForConnectorFill(Style style) { 27 | switch (style.getFillMode()) { 28 | case PLAIN: return new PlainShapeStroke(); 29 | case DYN_PLAIN: return new PlainShapeStroke(); 30 | case NONE: return null ; // Gracefully handled by the drawing part. 31 | default: return new PlainShapeStroke() ; 32 | } 33 | } 34 | 35 | public ShapeStroke strokeForConnectorStroke(Style style) { 36 | return strokeForArea(style); 37 | } 38 | 39 | public static int strokeColor(Style style) { 40 | if( style.getStrokeMode() != org.graphstream.ui.graphicGraph.stylesheet.StyleConstants.StrokeMode.NONE ) { 41 | return ColorManager.getStrokeColor(style, 0); 42 | } 43 | else { 44 | return -1; 45 | } 46 | } 47 | } 48 | 49 | class PlainShapeStroke extends ShapeStroke { 50 | private float oldWidth = 0 ; 51 | private Stroke oldStroke = null ; 52 | 53 | @Override 54 | public Stroke stroke(float width, Form shape, int fillColor) { 55 | return stroke(width); 56 | } 57 | 58 | public Stroke stroke(float width) { 59 | if( width == oldWidth ) { 60 | if( oldStroke == null ) 61 | oldStroke = new Stroke(width); 62 | return oldStroke; 63 | } 64 | else { 65 | oldWidth = width; 66 | oldStroke = new Stroke(width); 67 | return oldStroke; 68 | } 69 | } 70 | } 71 | 72 | class DotsShapeStroke extends ShapeStroke { 73 | private float oldWidth = 0.0f ; 74 | private Stroke oldStroke = null ; 75 | 76 | @Override 77 | public Stroke stroke(float width, Form shape, int fillColor) { 78 | return stroke(width); 79 | } 80 | 81 | public Stroke stroke(float width) { 82 | if( width == oldWidth ) { 83 | if( oldStroke == null ) { 84 | oldStroke = new Stroke( width, width, Paint.Cap.BUTT); 85 | } 86 | return oldStroke; 87 | } else { 88 | oldWidth = width; 89 | oldStroke = new Stroke( width, width, Paint.Cap.BUTT); 90 | return oldStroke; 91 | } 92 | } 93 | } 94 | 95 | class DashesShapeStroke extends ShapeStroke { 96 | private float oldWidth = 0.0f ; 97 | private Stroke oldStroke = null ; 98 | 99 | @Override 100 | public Stroke stroke(float width, Form shape, int fillColor) { 101 | return stroke(width); 102 | } 103 | 104 | public Stroke stroke(float width) { 105 | if( width == oldWidth ) { 106 | if( oldStroke == null ){ 107 | oldStroke = new Stroke( width, (3*width), Paint.Cap.BUTT); 108 | } 109 | return oldStroke ; 110 | } else { 111 | oldWidth = width ; 112 | oldStroke = new Stroke( width, (3*width), Paint.Cap.BUTT); 113 | return oldStroke ; 114 | } 115 | } 116 | } 117 | 118 | class DoubleShapeStroke extends ShapeStroke { 119 | 120 | @Override 121 | public Stroke stroke(float width, Form shape, int fillColor) { 122 | return new CompositeStroke( new Stroke(width*3), new Stroke(width), width, shape, fillColor); 123 | } 124 | 125 | class CompositeStroke extends Stroke { 126 | private Stroke stroke1 ; 127 | private Stroke stroke2 ; 128 | private Form form ; 129 | private int fillColor ; 130 | 131 | public CompositeStroke(Stroke stroke1, Stroke stroke2, float w, Form form, int fillColor) { 132 | super(w); 133 | this.stroke1 = stroke1 ; 134 | this.stroke2 = stroke2 ; 135 | this.form = form ; 136 | this.fillColor = fillColor ; 137 | } 138 | 139 | @Override 140 | public void changeStrokeProperties(Canvas g, Paint p) { 141 | // if form is null ==> debug in FillableLine 142 | 143 | if (form.getIdForm().equals("Rect")) { 144 | ((Rectangle2D)form).setDoubleStroke(stroke1, stroke2, fillColor); 145 | } 146 | else if (form.getIdForm().equals("Path")) { 147 | System.err.println("DoubleStroke for Path not implemented yet"); 148 | stroke2.changeStrokeProperties(g, p); 149 | } 150 | else if (form.getIdForm().equals("CubicCurve")) { 151 | System.err.println("DoubleStroke for CubicCurve not implemented yet"); 152 | stroke2.changeStrokeProperties(g, p); 153 | } 154 | else if (form.getIdForm().equals("Line")) { 155 | float[][] path = (float[][]) form.getPath(); 156 | float x1 = path[0][0]; 157 | float y1 = path[0][1]; 158 | float x2 = path[1][0]; 159 | float y2 = path[1][1]; 160 | 161 | stroke2.changeStrokeProperties(g, p); 162 | double angle = Math.toDegrees(Math.atan2(y2-y1, x2-x1) - Math.atan2(1, 1)); 163 | if ( angle >= 90 || angle <= -180 || (angle >= -90 && angle < 0)) { 164 | y1 += width*3 ; 165 | y2 += width*3 ; 166 | } 167 | else { 168 | x1 += width*3 ; 169 | x2 += width*3 ; 170 | } 171 | p.setStyle(Paint.Style.STROKE); 172 | g.drawLine(x1, y1, x2, y2, p); 173 | } 174 | else if (form.getIdForm().equals("Ellipse")) { 175 | ((Ellipse2D)form).setDoubleStroke(stroke1, stroke2, fillColor); 176 | } 177 | } 178 | } 179 | } 180 | 181 | -------------------------------------------------------------------------------- /app/src/main/java/org/graphstream/ui/android/renderer/shape/android/spriteShapes/SpriteArrowShape.java: -------------------------------------------------------------------------------- 1 | package org.graphstream.ui.android.renderer.shape.android.spriteShapes; 2 | 3 | import org.graphstream.ui.geom.Vector2; 4 | import org.graphstream.ui.graphicGraph.GraphicElement; 5 | import org.graphstream.ui.graphicGraph.GraphicSprite; 6 | import org.graphstream.ui.graphicGraph.stylesheet.Style; 7 | import org.graphstream.ui.android.Backend; 8 | import org.graphstream.ui.view.camera.DefaultCamera2D; 9 | import org.graphstream.ui.android.renderer.Skeleton; 10 | import org.graphstream.ui.android.renderer.shape.Orientable; 11 | import org.graphstream.ui.android.renderer.shape.android.baseShapes.PolygonalShape; 12 | import org.graphstream.ui.android.renderer.shape.android.baseShapes.Form.Path2D; 13 | 14 | public class SpriteArrowShape extends PolygonalShape { 15 | Orientable orientable ; 16 | 17 | public SpriteArrowShape() { 18 | this.orientable = new Orientable() ; 19 | } 20 | 21 | @Override 22 | public void configureForGroup(Backend bck, Style style, DefaultCamera2D camera) { 23 | super.configureForGroup(bck, style, camera); 24 | orientable.configureOrientableForGroup(style, camera); 25 | } 26 | 27 | @Override 28 | public void configureForElement(Backend bck, GraphicElement element, Skeleton skel, DefaultCamera2D camera) { 29 | super.configureForElement(bck, element, skel, camera); 30 | orientable.configureOrientableForElement(camera, (GraphicSprite)element); 31 | } 32 | 33 | @Override 34 | public void make(Backend backend, DefaultCamera2D camera) { 35 | double x = area.theCenter.x; 36 | double y = area.theCenter.y; 37 | Vector2 dir = new Vector2( orientable.target.x - x, orientable.target.y - y ); 38 | 39 | dir.normalize(); 40 | Vector2 per = new Vector2( dir.y(), -dir.x() ); 41 | 42 | dir.scalarMult( area.theSize.x ); 43 | per.scalarMult( area.theSize.y / 2 ); 44 | 45 | theShape = new Path2D(5, true); 46 | theShape().moveTo( x + per.x(), y + per.y() ); 47 | theShape().lineTo( x + dir.x(), y + dir.y() ); 48 | theShape().lineTo( x - per.x(), y - per.y() ); 49 | theShape.closePath(); 50 | } 51 | 52 | @Override 53 | public void makeShadow(Backend backend, DefaultCamera2D camera) { 54 | double x = area.theCenter.x + shadowable.theShadowOff.x; 55 | double y = area.theCenter.y + shadowable.theShadowOff.y; 56 | Vector2 dir = new Vector2( orientable.target.x - x, orientable.target.y - y ); 57 | dir.normalize(); 58 | Vector2 per = new Vector2( dir.y(), -dir.x() ); 59 | 60 | dir.scalarMult( area.theSize.x + shadowable.theShadowWidth.x ); 61 | per.scalarMult( ( area.theSize.y + shadowable.theShadowWidth.y ) / 2 ); 62 | 63 | theShape = new Path2D(5, true); 64 | theShape().moveTo( x + per.x(), y + per.y() ); 65 | theShape().lineTo( x + dir.x(), y + dir.y() ); 66 | theShape().lineTo( x - per.x(), y - per.y() ); 67 | theShape.closePath(); 68 | } 69 | } -------------------------------------------------------------------------------- /app/src/main/java/org/graphstream/ui/android/util/AttributeUtils.java: -------------------------------------------------------------------------------- 1 | package org.graphstream.ui.android.util; 2 | 3 | import java.util.logging.Logger; 4 | 5 | import org.graphstream.ui.geom.Point3; 6 | 7 | public interface AttributeUtils { 8 | 9 | default Point3[] getPoints(Object values) { 10 | if ( values instanceof Point3[] ) { 11 | if(((Point3[]) values).length == 0) { 12 | Logger.getLogger(this.getClass().getSimpleName()).info("0 ui.points"); 13 | } 14 | return (Point3[]) values ; 15 | } 16 | else if (values instanceof Object[]) { 17 | Object[] tabValues = (Object[]) values ; 18 | 19 | if(tabValues.length > 0) { 20 | if (tabValues[0] instanceof Point3) { 21 | Point3[] res = new Point3[tabValues.length]; 22 | for ( int i = 0 ; i < tabValues.length ; i++ ) { 23 | res[i] = (Point3) tabValues[i] ; 24 | } 25 | return res ; 26 | } 27 | else if (tabValues[0] instanceof Number) { 28 | int size = tabValues.length / 3; 29 | Point3[] res = new Point3[size]; 30 | 31 | for (int i = 0 ; i < size ; i++) { 32 | res[i] = new Point3(((Number)tabValues[i*3]).doubleValue(), 33 | ((Number)tabValues[i*3+1]).doubleValue(), 34 | ((Number)tabValues[i*3+2]).doubleValue()); 35 | } 36 | return res ; 37 | } 38 | else { 39 | Logger.getLogger(this.getClass().getSimpleName()).warning("Cannot interpret ui.points elements type "+((Object[]) values)[0].getClass().getName()); 40 | return new Point3[0]; 41 | } 42 | } 43 | else { 44 | Logger.getLogger(this.getClass().getSimpleName()).warning("ui.points array size is zero !"); 45 | return new Point3[0]; 46 | } 47 | } 48 | else if (values instanceof double[]) { 49 | double[] tabValues = ((double[]) values) ; 50 | if(tabValues.length > 0) { 51 | int size = tabValues.length / 3; 52 | Point3[] res = new Point3[size]; 53 | 54 | for (int i = 0 ; i < size ; i++) { 55 | res[i] = new Point3(tabValues[i*3], tabValues[i*3+1],tabValues[i*3+2]); 56 | } 57 | return res ; 58 | } 59 | else { 60 | Logger.getLogger(this.getClass().getSimpleName()).warning("ui.points array size is zero !"); 61 | return new Point3[0]; 62 | } 63 | } 64 | else if (values instanceof float[] || values instanceof Float[]) { 65 | float[] tabValues = ((float[]) values) ; 66 | 67 | if(tabValues.length > 0) { 68 | int size = tabValues.length / 3; 69 | Point3[] res = new Point3[size]; 70 | 71 | for (int i = 0 ; i < size ; i++) { 72 | res[i] = new Point3(tabValues[i*3], tabValues[i*3+1],tabValues[i*3+2]); 73 | } 74 | return res ; 75 | } 76 | else { 77 | Logger.getLogger(this.getClass().getSimpleName()).warning("ui.points array size is zero !"); 78 | return new Point3[0]; 79 | } 80 | } 81 | else { 82 | Logger.getLogger(this.getClass().getSimpleName()).warning("Cannot interpret ui.points contents "+values.getClass().getName()); 83 | return new Point3[0]; 84 | } 85 | } 86 | 87 | 88 | default double[] getDoubles(Object values) { 89 | if (values instanceof Object[]) { 90 | Object[] tabValues = (Object[]) values ; 91 | double[] result = new double[tabValues.length]; 92 | 93 | for(int i = 0 ; i < tabValues.length ; i++) { 94 | if(tabValues[i] instanceof Number) 95 | result[i] = ((Number)tabValues[i]).doubleValue(); 96 | else if(tabValues[i] instanceof String) 97 | result[i] = Double.parseDouble((String)tabValues[i]); 98 | else 99 | result[i] = 0.0 ; 100 | } 101 | 102 | return result ; 103 | } 104 | else if (values instanceof double[]) { 105 | double[] tabValues = (double[]) values ; 106 | return tabValues ; 107 | } 108 | else if (values instanceof float[]) { 109 | float[] tabValues = (float[]) values ; 110 | double[] result = new double[tabValues.length]; 111 | 112 | for(int i = 0 ; i < tabValues.length ; i++) { 113 | result[i] = (double)tabValues[i]; 114 | } 115 | 116 | return result ; 117 | } 118 | else if (values instanceof int[]) { 119 | int[] tabValues = (int[]) values ; 120 | double[] result = new double[tabValues.length]; 121 | 122 | for(int i = 0 ; i < tabValues.length ; i++) { 123 | result[i] = (double)tabValues[i]; 124 | } 125 | 126 | return result ; 127 | } 128 | else if (values instanceof String[]) { 129 | String[] tabValues = (String[]) values ; 130 | double[] result = new double[tabValues.length]; 131 | 132 | for(int i = 0 ; i < tabValues.length ; i++) { 133 | for(int j = 0 ; j < tabValues[i].split(",").length ; j++) { 134 | result[i] = Double.parseDouble(tabValues[i].split(",")[j]); 135 | } 136 | } 137 | 138 | return result ; 139 | } 140 | else { 141 | Logger.getLogger(this.getClass().getSimpleName()).warning("Cannot extract double values from array "+values.getClass().getName()); 142 | return new double[0]; 143 | } 144 | } 145 | 146 | default Tuple boundingBoxOfPoints(Point3[] points) { 147 | Double minx = Double.MAX_VALUE; 148 | Double miny = Double.MAX_VALUE; 149 | Double minz = Double.MAX_VALUE; 150 | Double maxx = Double.MIN_VALUE; 151 | Double maxy = Double.MIN_VALUE; 152 | Double maxz = Double.MIN_VALUE; 153 | 154 | for(int i = 0 ; i < points.length ; i++) { 155 | if(points[i].xmaxx) maxx = points[i].x ; 159 | if(points[i].y>maxy) maxy = points[i].y ; 160 | if(points[i].z>maxz) maxz = points[i].z ; 161 | } 162 | 163 | return new Tuple(new Point3(minx, miny, minz), new Point3(maxx, maxy, maxz)); 164 | } 165 | 166 | 167 | class Tuple { 168 | public final X x; 169 | public final Y y; 170 | 171 | public Tuple(X x, Y y) { 172 | this.x = x; 173 | this.y = y; 174 | } 175 | } 176 | } 177 | -------------------------------------------------------------------------------- /app/src/main/java/org/graphstream/ui/android/util/Background.java: -------------------------------------------------------------------------------- 1 | package org.graphstream.ui.android.util; 2 | 3 | import android.graphics.Bitmap; 4 | import android.graphics.Canvas; 5 | import android.graphics.Color; 6 | import android.graphics.Matrix; 7 | import android.graphics.Paint; 8 | import android.graphics.Shader; 9 | import android.util.Log; 10 | 11 | public class Background { 12 | private int color = -1; 13 | private int oldColor = -1 ; 14 | 15 | private Shader gradient = null; 16 | 17 | private Bitmap img = null; 18 | private float x = 0; 19 | private float y = 0; 20 | 21 | public Background(int color) { 22 | this.color = color ; 23 | } 24 | 25 | public Background(Shader gradient) { 26 | this.gradient = gradient ; 27 | } 28 | 29 | public Background(Bitmap img, double xFrom, double yFrom, int width, int height) { 30 | this.x = (float)xFrom ; 31 | this.y = (float)yFrom ; 32 | this.img = getResizedBitmap(img, width, height) ; 33 | } 34 | 35 | 36 | public static Bitmap getResizedBitmap(Bitmap bm, int newWidth, int newHeight) { 37 | int width = bm.getWidth(); 38 | int height = bm.getHeight(); 39 | float scaleWidth = ((float) newWidth) / width; 40 | float scaleHeight = ((float) newHeight) / height; 41 | 42 | Matrix matrix = new Matrix(); 43 | // Resize the bitmap 44 | matrix.postScale(scaleWidth, scaleHeight); 45 | 46 | Bitmap resizedBitmap = Bitmap.createBitmap( 47 | bm, 0, 0, width, height, matrix, false); 48 | bm.recycle(); 49 | return resizedBitmap; 50 | } 51 | 52 | public void applyPaint(Canvas c, Paint p) { 53 | if( color != -1 ) { 54 | oldColor = p.getColor(); 55 | p.setColor(color); 56 | } 57 | else if (gradient != null) { 58 | p.setShader(gradient); 59 | } 60 | else if ( img != null ) { 61 | c.drawBitmap(img, x, y, p); 62 | } 63 | } 64 | 65 | public void removePaint(Paint p) { 66 | if( color != -1 ) { 67 | p.setColor(oldColor); 68 | } 69 | else if (gradient != null) { 70 | p.setShader(null); 71 | } 72 | } 73 | 74 | @Override 75 | public String toString() { 76 | return "color = "+color+" shader = "+gradient+" img = "+img+" x = "+x+" y = "+y; 77 | } 78 | 79 | public boolean isImage() { 80 | return (img!=null); 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /app/src/main/java/org/graphstream/ui/android/util/ColorManager.java: -------------------------------------------------------------------------------- 1 | package org.graphstream.ui.android.util; 2 | 3 | import android.graphics.Color; 4 | import android.graphics.Paint; 5 | 6 | import org.graphstream.ui.graphicGraph.StyleGroup; 7 | import org.graphstream.ui.graphicGraph.stylesheet.Style; 8 | 9 | public class ColorManager { 10 | public static Float dashes = null ; 11 | /** 12 | * Get fill awt color in styleGroup and convert to android Color 13 | * @param group 14 | * @param id 15 | * @return int 16 | */ 17 | public static int getFillColor(StyleGroup group, int id) { 18 | return getColor(group.getFillColor(id)); 19 | } 20 | 21 | /** 22 | * Get fill awt color in group and convert to android Color 23 | * @param group 24 | * @param id 25 | * @return int 26 | */ 27 | public static int getFillColor(Style group, int id) { 28 | return getColor(group.getFillColor(id)); 29 | } 30 | 31 | /** 32 | * Get stroke awt color in styleGroup and convert to android Color 33 | * @param group 34 | * @param id 35 | * @return int 36 | */ 37 | public static int getStrokeColor(StyleGroup group, int id) { 38 | return getColor(group.getStrokeColor(id)); 39 | } 40 | 41 | /** 42 | * Get stroke awt color in group and convert to android Color 43 | * @param group 44 | * @param id 45 | * @return int 46 | */ 47 | public static int getStrokeColor(Style group, int id) { 48 | return getColor(group.getStrokeColor(id)); 49 | } 50 | 51 | /** 52 | * Get canvas awt color in styleGroup and convert to android Color 53 | * @param group 54 | * @param id 55 | * @return int 56 | */ 57 | public static int getCanvasColor(StyleGroup group, int id) { 58 | return getColor(group.getCanvasColor(id)); 59 | } 60 | 61 | /** 62 | * Get shadow awt color in styleGroup and convert to android Color 63 | * @param group 64 | * @param id 65 | * @return int 66 | */ 67 | public static int getShadowColor(StyleGroup group, int id) { 68 | return getColor(group.getShadowColor(id)); 69 | } 70 | 71 | /** 72 | * Get shadow awt color in group and convert to android Color 73 | * @param group 74 | * @param id 75 | * @return int 76 | */ 77 | public static int getShadowColor(Style group, int id) { 78 | return getColor(group.getShadowColor(id)); 79 | } 80 | 81 | /** 82 | * Get text awt color in group and convert to android Color 83 | * @param group 84 | * @param id 85 | * @return int 86 | */ 87 | public static int getTextColor(Style group, int id) { 88 | return getColor(group.getTextColor(id)); 89 | } 90 | 91 | /** 92 | * Get text background awt color in group and convert to android Color 93 | * @param group 94 | * @param id 95 | * @return int 96 | */ 97 | public static int getTextBackgroundColor(Style group, int id) { 98 | return getColor(group.getTextBackgroundColor(id)); 99 | } 100 | 101 | public static int getColor(org.graphstream.ui.graphicGraph.stylesheet.Color c) { 102 | return Color.argb(c.getAlpha(), c.getRed(), c.getGreen(), c.getBlue()); 103 | } 104 | 105 | public static org.graphstream.ui.graphicGraph.stylesheet.Color getGraphstreamColor(int color) { 106 | return new org.graphstream.ui.graphicGraph.stylesheet.Color(Color.red(color), Color.green(color), Color.blue(color), Color.alpha(color)); 107 | } 108 | } 109 | -------------------------------------------------------------------------------- /app/src/main/java/org/graphstream/ui/android/util/Display.java: -------------------------------------------------------------------------------- 1 | package org.graphstream.ui.android.util; 2 | 3 | import org.graphstream.graph.Graph; 4 | import org.graphstream.ui.view.Viewer; 5 | 6 | public class Display implements org.graphstream.util.Display { 7 | 8 | @Override 9 | public Viewer display(Graph g, boolean b) { 10 | throw new RuntimeException("Please create your own Activity !"); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /app/src/main/java/org/graphstream/ui/android/util/EdgePoints.java: -------------------------------------------------------------------------------- 1 | package org.graphstream.ui.android.util; 2 | 3 | import org.graphstream.ui.geom.Point3; 4 | 5 | public class EdgePoints { 6 | protected Point3[] points ; 7 | 8 | 9 | public EdgePoints(int n) { 10 | this.points = new Point3[n]; 11 | 12 | for ( int i = 0 ; i < size() ; i++ ) 13 | points[i] = new Point3(); 14 | } 15 | 16 | 17 | public int size() { 18 | return points.length; 19 | } 20 | 21 | public void copy(Point3[] newPoints) { 22 | points = new Point3[newPoints.length]; 23 | for ( int i = 0 ; i < size() ; i++ ) { 24 | points[i] = new Point3(newPoints[i]); 25 | } 26 | } 27 | 28 | public void set(int i, double x, double y, double z) { 29 | points[i].set(x, y, z); 30 | } 31 | 32 | public Point3 get(int i) { 33 | return points[i]; 34 | } 35 | 36 | public Point3 apply(int i) { 37 | return points[i]; 38 | } 39 | 40 | public void update(int i, Point3 coos) { 41 | points[i] = new Point3(coos.x, coos.y, coos.z); 42 | } 43 | 44 | @Override 45 | public String toString() { 46 | String s = "pts("; 47 | for (int i = 0 ; i < size() ; i++) 48 | s += points[i].toString()+", " ; 49 | s += ") : "+size(); 50 | 51 | return s ; 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /app/src/main/java/org/graphstream/ui/android/util/FPSLogger.java: -------------------------------------------------------------------------------- 1 | package org.graphstream.ui.android.util; 2 | 3 | import java.io.FileNotFoundException; 4 | import java.io.PrintStream; 5 | 6 | /** Very simple logger for Frame-Per-Second measurements. 7 | */ 8 | public class FPSLogger { 9 | 10 | String fileName ; 11 | 12 | /** Start time for a frame. */ 13 | protected long T1 = 0; 14 | 15 | /** End Time for a frame. */ 16 | protected long T2 = 0; 17 | 18 | /** Output channel. */ 19 | protected PrintStream out = null; 20 | 21 | /** @param fileName The name of the file where measurements will be written, frame by frame. */ 22 | public FPSLogger(String fileName) { 23 | this.fileName = fileName ; 24 | } 25 | 26 | /**Start a new frame measurement. */ 27 | public void beginFrame() { 28 | T1 = System.currentTimeMillis(); 29 | } 30 | 31 | public void endFrame() { 32 | T2 = System.currentTimeMillis(); 33 | 34 | if(out == null) { 35 | try { 36 | out = new PrintStream(fileName); 37 | } 38 | catch (FileNotFoundException e) { e.printStackTrace(); } 39 | out.println("# Each line is a frame."); 40 | out.println("# 1 FPS instantaneous frame per second"); 41 | out.println("# 2 Time in milliseconds of the frame"); 42 | } 43 | 44 | long time = T2 - T1; 45 | double fps = 1000.0 / time; 46 | out.println(fps+".2f "+time); 47 | } 48 | 49 | /** Ensure the log file is flushed and closed. Be careful, calling `endFrame()` 50 | * after `close()` will reopen the log file and erase prior measurements. */ 51 | public void close() { 52 | if(out != null) { 53 | out.flush(); 54 | out.close(); 55 | out = null; 56 | } 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /app/src/main/java/org/graphstream/ui/android/util/Font.java: -------------------------------------------------------------------------------- 1 | package org.graphstream.ui.android.util; 2 | 3 | import android.graphics.Typeface; 4 | 5 | public class Font { 6 | private Typeface font ; 7 | private float size ; 8 | 9 | public Font(Typeface font, float size) { 10 | this.font = font ; 11 | this.size = size ; 12 | } 13 | 14 | public Typeface getFont() { 15 | return font ; 16 | } 17 | 18 | public float getSizeFont() { 19 | return size ; 20 | } 21 | } -------------------------------------------------------------------------------- /app/src/main/java/org/graphstream/ui/android/util/FontCache.java: -------------------------------------------------------------------------------- 1 | package org.graphstream.ui.android.util; 2 | 3 | import android.graphics.Typeface; 4 | import android.util.Log; 5 | 6 | import java.util.HashMap; 7 | import java.util.Map; 8 | 9 | import org.graphstream.ui.graphicGraph.stylesheet.StyleConstants.TextStyle; 10 | 11 | public class FontCache { 12 | 13 | protected static Font defFont = new Font(Typeface.create("SansSerif", Typeface.NORMAL), 11) ; 14 | 15 | protected static HashMap cache = new HashMap<>(); 16 | 17 | public static Font getDefaultFont() { 18 | return defFont; 19 | } 20 | 21 | public static Font getDefaultFont(TextStyle style, int size) { 22 | return getFont( "SansSerif", style, size ); 23 | } 24 | 25 | public static Font getFont(String name, TextStyle style, int size) { 26 | if ( cache.get(name) == null ) { 27 | FontSlot slot = new FontSlot(name, style, size); 28 | cache.put(name, slot); 29 | return slot.getFont(style, size); 30 | } 31 | else { 32 | return cache.get(name).getFont(style, size); 33 | } 34 | } 35 | } 36 | 37 | class FontSlot { 38 | 39 | HashMap normal = null ; 40 | HashMap bold = null ; 41 | HashMap italic = null ; 42 | HashMap boldItalic = null ; 43 | 44 | private String name ; 45 | 46 | public FontSlot(String name, TextStyle style, int size) { 47 | this.name = name ; 48 | insert(style, size); 49 | } 50 | 51 | private Font insert(TextStyle style, int size) { 52 | return insert(mapFromStyle(style), toJavaStyle(style), size); 53 | } 54 | 55 | private Font insert(Map map, int style, int size) { 56 | if (map.get(size) == null) { 57 | Font font = new Font(Typeface.create(name, style), size); 58 | map.put(size, font); 59 | return font ; 60 | } 61 | else { 62 | return map.get(size); 63 | } 64 | } 65 | 66 | public Font getFont(TextStyle style, int size) { 67 | Map map = mapFromStyle(style); 68 | 69 | if (map.get(size) == null) { 70 | return insert( map, toJavaStyle( style ), size ); 71 | } 72 | else { 73 | return map.get(size); 74 | } 75 | } 76 | 77 | private int toJavaStyle(TextStyle style) { 78 | switch (style) { 79 | case BOLD: 80 | return Typeface.BOLD; 81 | case ITALIC: 82 | return Typeface.ITALIC; 83 | case BOLD_ITALIC: 84 | return Typeface.BOLD_ITALIC; 85 | case NORMAL: 86 | return Typeface.NORMAL; 87 | default: 88 | return Typeface.NORMAL; 89 | } 90 | } 91 | 92 | private Map mapFromStyle(TextStyle style) { 93 | switch (style) { 94 | case BOLD: 95 | if (bold == null) { 96 | bold = new HashMap(); 97 | } 98 | return bold ; 99 | case ITALIC: 100 | if (italic == null) { 101 | italic = new HashMap(); 102 | } 103 | return italic ; 104 | case BOLD_ITALIC: 105 | if (boldItalic == null) { 106 | boldItalic = new HashMap(); 107 | } 108 | return boldItalic ; 109 | case NORMAL: 110 | if (normal == null) { 111 | normal = new HashMap(); 112 | } 113 | return normal ; 114 | default: 115 | if (normal == null) { 116 | normal = new HashMap(); 117 | } 118 | return normal ; 119 | } 120 | } 121 | } -------------------------------------------------------------------------------- /app/src/main/java/org/graphstream/ui/android/util/ImageCache.java: -------------------------------------------------------------------------------- 1 | package org.graphstream.ui.android.util; 2 | 3 | import android.content.Context; 4 | import android.graphics.Bitmap; 5 | import android.graphics.BitmapFactory; 6 | import java.util.HashMap; 7 | 8 | public class ImageCache { 9 | 10 | protected static HashMap imageCache = new HashMap<>(); 11 | 12 | protected static Bitmap dummy = null ; 13 | 14 | public static Context context = null ; 15 | 16 | public static void init(Context c) { 17 | context = c ; 18 | } 19 | 20 | public static Bitmap loadImage(String drawable) { 21 | return loadImage(drawable, false); 22 | } 23 | 24 | public static Bitmap loadImage(String drawable, boolean forceTryReload) { 25 | if (imageCache.get(drawable) == null) { 26 | Bitmap image = null ; 27 | try { 28 | int img = Integer.parseInt(drawable); 29 | image = BitmapFactory.decodeResource(context.getResources(), img); 30 | } 31 | catch (Exception e) { e.printStackTrace(); } 32 | 33 | 34 | return image ; 35 | } 36 | else { 37 | if(imageCache.get(drawable) == dummy && forceTryReload) { 38 | imageCache.remove(drawable) ; 39 | return loadImage(drawable); 40 | } 41 | else 42 | return imageCache.get(drawable); 43 | } 44 | } 45 | 46 | public static Bitmap dummyImage() { 47 | return dummy ; 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /app/src/main/java/org/graphstream/ui/android/util/Selection.java: -------------------------------------------------------------------------------- 1 | package org.graphstream.ui.android.util; 2 | 3 | import org.graphstream.ui.android.renderer.SelectionRenderer; 4 | import org.graphstream.ui.geom.Point3; 5 | 6 | public class Selection { 7 | 8 | private boolean active = false; 9 | private Point3 lo = new Point3() ; 10 | private Point3 hi = new Point3() ; 11 | private SelectionRenderer renderer = null ; 12 | 13 | public void begins(double x, double y) { 14 | lo.x = x ; 15 | lo.y = y ; 16 | hi.x = x ; 17 | hi.y = y ; 18 | } 19 | 20 | public void grows(double x, double y) { 21 | hi.x = x ; 22 | hi.y = y ; 23 | } 24 | 25 | public boolean isActive() { 26 | return active; 27 | } 28 | 29 | public void setActive(boolean active) { 30 | this.active = active; 31 | } 32 | 33 | public float x1() { 34 | return (float)lo.x ; 35 | } 36 | 37 | public float x2() { 38 | return (float)hi.x ; 39 | } 40 | 41 | public float y1() { 42 | return (float)lo.y ; 43 | } 44 | 45 | public float y2() { 46 | return (float)hi.y ; 47 | } 48 | 49 | public float z1() { 50 | return (float)lo.z ; 51 | } 52 | 53 | public float z2() { 54 | return (float)hi.z ; 55 | } 56 | 57 | public SelectionRenderer getRenderer() { 58 | return renderer; 59 | } 60 | 61 | public void setRenderer(SelectionRenderer renderer) { 62 | this.renderer = renderer; 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /app/src/main/java/org/graphstream/ui/android/util/Stroke.java: -------------------------------------------------------------------------------- 1 | package org.graphstream.ui.android.util; 2 | 3 | import android.graphics.Canvas; 4 | import android.graphics.DashPathEffect; 5 | import android.graphics.Paint; 6 | 7 | public class Stroke { 8 | protected float width ; 9 | private Float dashes; 10 | private Paint.Cap cap ; 11 | 12 | public Stroke() { 13 | this(1, null, Paint.Cap.SQUARE); 14 | } 15 | 16 | public Stroke(float width) { 17 | this(width, null, Paint.Cap.SQUARE); 18 | } 19 | 20 | public Stroke(float width, Float dashes, Paint.Cap cap) { 21 | this.width = width ; 22 | this.dashes = dashes ; 23 | this.cap = cap ; 24 | } 25 | 26 | public void changeStrokeProperties(Canvas c, Paint p) { 27 | p.setStrokeWidth(width); 28 | 29 | if (dashes == null) { 30 | p.setPathEffect(null); 31 | } 32 | else { 33 | ColorManager.dashes = dashes ; 34 | p.setPathEffect(new DashPathEffect(new float[]{dashes, dashes}, 0)); 35 | } 36 | p.setStrokeCap(cap); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /app/src/main/java/org/graphstream/ui/android_viewer/ViewPanel.java: -------------------------------------------------------------------------------- 1 | package org.graphstream.ui.android_viewer; 2 | 3 | import android.content.Context; 4 | import android.view.SurfaceHolder; 5 | import android.view.SurfaceView; 6 | 7 | import org.graphstream.ui.view.View; 8 | 9 | 10 | public abstract class ViewPanel extends SurfaceView implements SurfaceHolder.Callback, View { 11 | 12 | // Holder 13 | SurfaceHolder mSurfaceHolder; 14 | 15 | /** 16 | * The view identifier. 17 | */ 18 | private final String id; 19 | 20 | protected Context context ; 21 | 22 | public ViewPanel (Context context, final String identifier) { 23 | super(context); 24 | this.context = context ; 25 | 26 | if (null == identifier || identifier.isEmpty()) { 27 | throw new IllegalArgumentException("View id cannot be null/empty."); 28 | } 29 | id = identifier; 30 | 31 | setWillNotDraw(false); 32 | 33 | this.mSurfaceHolder = getHolder(); 34 | this.mSurfaceHolder.addCallback(this); 35 | } 36 | 37 | public String getIdView() { 38 | return id; 39 | } 40 | 41 | public SurfaceHolder getSurface() { 42 | return mSurfaceHolder ; 43 | } 44 | 45 | public abstract void enableMouseOptions(); 46 | } -------------------------------------------------------------------------------- /app/src/main/java/org/graphstream/ui/android_viewer/util/DefaultFragment.java: -------------------------------------------------------------------------------- 1 | package org.graphstream.ui.android_viewer.util; 2 | 3 | import android.content.Context; 4 | import android.os.Bundle; 5 | import android.support.annotation.Nullable; 6 | import android.support.v4.app.Fragment; 7 | import android.util.Log; 8 | import android.view.LayoutInflater; 9 | import android.view.View; 10 | import android.view.ViewGroup; 11 | 12 | import org.graphstream.graph.Graph; 13 | import org.graphstream.ui.android.AndroidFullGraphRenderer; 14 | import org.graphstream.ui.android_viewer.AndroidViewer; 15 | import org.graphstream.ui.android_viewer.DefaultView; 16 | import org.graphstream.ui.layout.Layout; 17 | import org.graphstream.ui.layout.Layouts; 18 | 19 | public class DefaultFragment extends Fragment { 20 | 21 | private Graph graph ; 22 | public static boolean autoLayout = true; 23 | private AndroidViewer viewer = null ; 24 | private AndroidFullGraphRenderer renderer ; 25 | 26 | public void init(Graph g, boolean autoLayout) { 27 | this.graph = g ; 28 | this.autoLayout = autoLayout; 29 | } 30 | /** 31 | * 1- Create only one Viewer 32 | * @param savedInstanceState 33 | */ 34 | @Override 35 | public void onCreate(@Nullable Bundle savedInstanceState) { 36 | super.onCreate(savedInstanceState); 37 | Log.e("Debug","DefaultFragment : onCreate"); 38 | viewer = new AndroidViewer(graph, AndroidViewer.ThreadingModel.GRAPH_IN_ANOTHER_THREAD); 39 | } 40 | 41 | /** 42 | * 2- Link the context 43 | * @param context 44 | */ 45 | @Override 46 | public void onAttach(Context context) { 47 | super.onAttach(context); 48 | Log.e("Debug","DefaultFragment : onAttach"); 49 | renderer = new AndroidFullGraphRenderer(); 50 | renderer.setContext(context); 51 | } 52 | 53 | /** 54 | * 3- Create the view 55 | * @param inflater 56 | * @param container 57 | * @param savedInstanceState 58 | * @return view 59 | */ 60 | public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 61 | Log.e("Debug","DefaultFragment : onCreateView"); 62 | DefaultView view = (DefaultView)viewer.addView(AndroidViewer.DEFAULT_VIEW_ID, renderer); 63 | 64 | if (autoLayout) { 65 | Layout layout = Layouts.newLayoutAlgorithm(); 66 | viewer.enableAutoLayout(layout); 67 | } 68 | 69 | return view ; 70 | } 71 | 72 | public AndroidViewer getViewer() { return viewer; } 73 | } 74 | -------------------------------------------------------------------------------- /app/src/main/java/org/graphstream/ui/android_viewer/util/GradientFactory.java: -------------------------------------------------------------------------------- 1 | package org.graphstream.ui.android_viewer.util; 2 | 3 | import android.graphics.LinearGradient; 4 | import android.graphics.RadialGradient; 5 | import android.graphics.Shader; 6 | import android.util.Log; 7 | 8 | import org.graphstream.ui.android.util.Background; 9 | import org.graphstream.ui.graphicGraph.stylesheet.Style; 10 | import org.graphstream.ui.graphicGraph.stylesheet.StyleConstants.FillMode; 11 | import org.graphstream.ui.android.util.ColorManager; 12 | 13 | public class GradientFactory { 14 | /** 15 | * Generate a gradient in the given pixel area following the given style. 16 | * This produces a gradient only if the style fill-mode is compatible. 17 | * 18 | * @param x0 19 | * The left corner of the area. 20 | * @param y0 21 | * The bottom corner of the area. 22 | * @param width 23 | * The area width. 24 | * @param height 25 | * The area height. 26 | * @param style 27 | * The style. 28 | * @return A gradient paint or null if the style does not specify a 29 | * gradient. 30 | */ 31 | public static Background gradientInArea(int x0, int y0, int width, int height, 32 | Style style) { 33 | switch (style.getFillMode()) { 34 | case GRADIENT_VERTICAL: 35 | return linearGradientFromStyle(x0, y0, x0, y0 + height, style); 36 | case GRADIENT_HORIZONTAL: 37 | return linearGradientFromStyle(x0, y0, x0 + width, y0, style); 38 | case GRADIENT_DIAGONAL1: 39 | return linearGradientFromStyle(x0, y0, x0 + width, y0 + height, 40 | style); 41 | case GRADIENT_DIAGONAL2: 42 | return linearGradientFromStyle(x0 + width, y0, x0, y0 + height, 43 | style); 44 | case GRADIENT_RADIAL: 45 | return radialGradientFromStyle(x0 + (width / 2), y0 + (height / 2), 46 | width > height ? width / 2 : height / 2, style); 47 | default: 48 | return null; 49 | } 50 | } 51 | 52 | /** 53 | * Generate a linear gradient between two given points corresponding to the 54 | * given style. 55 | * 56 | * @param x0 57 | * The start point abscissa. 58 | * @param y0 59 | * The start point ordinate. 60 | * @param x1 61 | * The end point abscissa. 62 | * @param y1 63 | * The end point ordinate. 64 | * @param style 65 | * The style. 66 | * @return A paint for the gradient or null if the style specifies no 67 | * gradient (the fill mode is not a linear gradient or there is only 68 | * one fill colour). 69 | */ 70 | public static Background linearGradientFromStyle(float x0, float y0, float x1, 71 | float y1, Style style) { 72 | Background paint = null; 73 | 74 | if (style.getFillColorCount() > 1) { 75 | switch (style.getFillMode()) { 76 | case GRADIENT_DIAGONAL1: 77 | case GRADIENT_DIAGONAL2: 78 | case GRADIENT_HORIZONTAL: 79 | case GRADIENT_VERTICAL: 80 | paint = new Background(new LinearGradient(x0, y0, x1, y1, 81 | createColors(style), createFractions(style), Shader.TileMode.CLAMP)); 82 | break; 83 | default: 84 | break; 85 | } 86 | } 87 | 88 | return paint; 89 | } 90 | 91 | public static Background radialGradientFromStyle(float cx, float cy, 92 | float radius, Style style) { 93 | return radialGradientFromStyle(cx, cy, radius, cx, cy, style); 94 | } 95 | 96 | /** 97 | * Generate a radial gradient between whose center is at (cx,cy) with the 98 | * given radius. The focus (fx,fy) is the start position of the gradient in 99 | * the circle. 100 | * 101 | * @param cx 102 | * The center point abscissa. 103 | * @param cy 104 | * The center point ordinate. 105 | * @param fx 106 | * The start point abscissa. 107 | * @param fy 108 | * The start point ordinate. 109 | * @param radius 110 | * The gradient radius. 111 | * @param style 112 | * The style. 113 | * @return A paint for the gradient or null if the style specifies no 114 | * gradient (the fill mode is not a radial gradient or there is only 115 | * one fill colour). 116 | */ 117 | public static Background radialGradientFromStyle(float cx, float cy, 118 | float radius, float fx, float fy, Style style) { 119 | Background paint = null; 120 | 121 | if (style.getFillColorCount() > 1 122 | && style.getFillMode() == FillMode.GRADIENT_RADIAL) { 123 | float fractions[] = createFractions(style); 124 | int colors[] = createColors(style); 125 | paint = new Background(new RadialGradient(cx, cy, radius, colors, fractions, 126 | Shader.TileMode.MIRROR)); 127 | } 128 | 129 | 130 | return paint; 131 | } 132 | 133 | protected static float[] createFractions(Style style) { 134 | int n = style.getFillColorCount(); 135 | 136 | if (n < predefFractions.length) 137 | return predefFractions[n]; 138 | 139 | float fractions[] = new float[n]; 140 | float div = 1f / (n - 1); 141 | 142 | for (int i = 1; i < (n - 1); i++) 143 | fractions[i] = div * i; 144 | 145 | fractions[0] = 0f; 146 | fractions[n - 1] = 1f; 147 | 148 | return fractions; 149 | } 150 | 151 | protected static int[] createColors(Style style) { 152 | int n = style.getFillColorCount(); 153 | int colors[] = new int[n]; 154 | 155 | for (int i = 0; i < n; i++) 156 | colors[i] = ColorManager.getFillColor(style, i); 157 | 158 | return colors; 159 | } 160 | 161 | public static float[][] predefFractions = new float[11][]; 162 | public static float[] predefFractions2 = { 0f, 1f }; 163 | public static float[] predefFractions3 = { 0f, 0.5f, 1f }; 164 | public static float[] predefFractions4 = { 0f, 0.33f, 0.66f, 1f }; 165 | public static float[] predefFractions5 = { 0f, 0.25f, 0.5f, 0.75f, 1f }; 166 | public static float[] predefFractions6 = { 0f, 0.2f, 0.4f, 0.6f, 0.8f, 1f }; 167 | public static float[] predefFractions7 = { 0f, 0.1666f, 0.3333f, 0.4999f, 168 | 0.6666f, 0.8333f, 1f }; 169 | public static float[] predefFractions8 = { 0f, 0.1428f, 0.2856f, 0.4284f, 170 | 0.5712f, 0.7140f, 0.8568f, 1f }; 171 | public static float[] predefFractions9 = { 0f, 0.125f, 0.25f, 0.375f, 0.5f, 172 | 0.625f, .75f, 0.875f, 1f }; 173 | public static float[] predefFractions10 = { 0f, 0.1111f, 0.2222f, 0.3333f, 174 | 0.4444f, 0.5555f, 0.6666f, 0.7777f, 0.8888f, 1f }; 175 | 176 | static { 177 | predefFractions[0] = null; 178 | predefFractions[1] = null; 179 | predefFractions[2] = predefFractions2; 180 | predefFractions[3] = predefFractions3; 181 | predefFractions[4] = predefFractions4; 182 | predefFractions[5] = predefFractions5; 183 | predefFractions[6] = predefFractions6; 184 | predefFractions[7] = predefFractions7; 185 | predefFractions[8] = predefFractions8; 186 | predefFractions[9] = predefFractions9; 187 | predefFractions[10] = predefFractions10; 188 | } 189 | } -------------------------------------------------------------------------------- /app/src/main/res/drawable-v24/ic_launcher_foreground.xml: -------------------------------------------------------------------------------- 1 | 7 | 12 | 13 | 19 | 22 | 25 | 26 | 27 | 28 | 34 | 35 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_launcher_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 10 | 15 | 20 | 25 | 30 | 35 | 40 | 45 | 50 | 55 | 60 | 65 | 70 | 75 | 80 | 85 | 90 | 95 | 100 | 105 | 110 | 115 | 120 | 125 | 130 | 135 | 140 | 145 | 150 | 155 | 160 | 165 | 170 | 171 | -------------------------------------------------------------------------------- /app/src/main/res/layout/fragment_default.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/graphstream/gs-ui-android/232eb7ffffdc7053173b002489dcccec8226ac43/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/graphstream/gs-ui-android/232eb7ffffdc7053173b002489dcccec8226ac43/app/src/main/res/mipmap-hdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/graphstream/gs-ui-android/232eb7ffffdc7053173b002489dcccec8226ac43/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-mdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/graphstream/gs-ui-android/232eb7ffffdc7053173b002489dcccec8226ac43/app/src/main/res/mipmap-mdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/graphstream/gs-ui-android/232eb7ffffdc7053173b002489dcccec8226ac43/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/graphstream/gs-ui-android/232eb7ffffdc7053173b002489dcccec8226ac43/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/graphstream/gs-ui-android/232eb7ffffdc7053173b002489dcccec8226ac43/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/graphstream/gs-ui-android/232eb7ffffdc7053173b002489dcccec8226ac43/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/graphstream/gs-ui-android/232eb7ffffdc7053173b002489dcccec8226ac43/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/graphstream/gs-ui-android/232eb7ffffdc7053173b002489dcccec8226ac43/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #3F51B5 4 | #303F9F 5 | #FF4081 6 | 7 | -------------------------------------------------------------------------------- /app/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | GraphStream Android 3 | 4 | -------------------------------------------------------------------------------- /app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /build.gradle: -------------------------------------------------------------------------------- 1 | // Top-level build file where you can add configuration options common to all sub-projects/modules. 2 | 3 | buildscript { 4 | 5 | repositories { 6 | google() 7 | jcenter() 8 | } 9 | dependencies { 10 | classpath 'com.android.tools.build:gradle:3.1.1' 11 | classpath 'com.github.dcendents:android-maven-gradle-plugin:2.1' 12 | 13 | // NOTE: Do not place your application dependencies here; they belong 14 | // in the individual module build.gradle files 15 | } 16 | } 17 | 18 | allprojects { 19 | repositories { 20 | google() 21 | jcenter() 22 | } 23 | } 24 | 25 | task clean(type: Delete) { 26 | delete rootProject.buildDir 27 | } 28 | -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | # Project-wide Gradle settings. 2 | 3 | # IDE (e.g. Android Studio) users: 4 | # Gradle settings configured through the IDE *will override* 5 | # any settings specified in this file. 6 | 7 | # For more details on how to configure your build environment visit 8 | # http://www.gradle.org/docs/current/userguide/build_environment.html 9 | 10 | # Specifies the JVM arguments used for the daemon process. 11 | # The setting is particularly useful for tweaking memory settings. 12 | org.gradle.jvmargs=-Xmx1536m -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/graphstream/gs-ui-android/232eb7ffffdc7053173b002489dcccec8226ac43/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Thu Apr 12 15:49:17 CEST 2018 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-4.4-all.zip 7 | -------------------------------------------------------------------------------- /gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | ############################################################################## 4 | ## 5 | ## Gradle start up script for UN*X 6 | ## 7 | ############################################################################## 8 | 9 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 10 | DEFAULT_JVM_OPTS="" 11 | 12 | APP_NAME="Gradle" 13 | APP_BASE_NAME=`basename "$0"` 14 | 15 | # Use the maximum available, or set MAX_FD != -1 to use that value. 16 | MAX_FD="maximum" 17 | 18 | warn ( ) { 19 | echo "$*" 20 | } 21 | 22 | die ( ) { 23 | echo 24 | echo "$*" 25 | echo 26 | exit 1 27 | } 28 | 29 | # OS specific support (must be 'true' or 'false'). 30 | cygwin=false 31 | msys=false 32 | darwin=false 33 | case "`uname`" in 34 | CYGWIN* ) 35 | cygwin=true 36 | ;; 37 | Darwin* ) 38 | darwin=true 39 | ;; 40 | MINGW* ) 41 | msys=true 42 | ;; 43 | esac 44 | 45 | # Attempt to set APP_HOME 46 | # Resolve links: $0 may be a link 47 | PRG="$0" 48 | # Need this for relative symlinks. 49 | while [ -h "$PRG" ] ; do 50 | ls=`ls -ld "$PRG"` 51 | link=`expr "$ls" : '.*-> \(.*\)$'` 52 | if expr "$link" : '/.*' > /dev/null; then 53 | PRG="$link" 54 | else 55 | PRG=`dirname "$PRG"`"/$link" 56 | fi 57 | done 58 | SAVED="`pwd`" 59 | cd "`dirname \"$PRG\"`/" >/dev/null 60 | APP_HOME="`pwd -P`" 61 | cd "$SAVED" >/dev/null 62 | 63 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 64 | 65 | # Determine the Java command to use to start the JVM. 66 | if [ -n "$JAVA_HOME" ] ; then 67 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 68 | # IBM's JDK on AIX uses strange locations for the executables 69 | JAVACMD="$JAVA_HOME/jre/sh/java" 70 | else 71 | JAVACMD="$JAVA_HOME/bin/java" 72 | fi 73 | if [ ! -x "$JAVACMD" ] ; then 74 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 75 | 76 | Please set the JAVA_HOME variable in your environment to match the 77 | location of your Java installation." 78 | fi 79 | else 80 | JAVACMD="java" 81 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 82 | 83 | Please set the JAVA_HOME variable in your environment to match the 84 | location of your Java installation." 85 | fi 86 | 87 | # Increase the maximum file descriptors if we can. 88 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then 89 | MAX_FD_LIMIT=`ulimit -H -n` 90 | if [ $? -eq 0 ] ; then 91 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 92 | MAX_FD="$MAX_FD_LIMIT" 93 | fi 94 | ulimit -n $MAX_FD 95 | if [ $? -ne 0 ] ; then 96 | warn "Could not set maximum file descriptor limit: $MAX_FD" 97 | fi 98 | else 99 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 100 | fi 101 | fi 102 | 103 | # For Darwin, add options to specify how the application appears in the dock 104 | if $darwin; then 105 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 106 | fi 107 | 108 | # For Cygwin, switch paths to Windows format before running java 109 | if $cygwin ; then 110 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 111 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 112 | JAVACMD=`cygpath --unix "$JAVACMD"` 113 | 114 | # We build the pattern for arguments to be converted via cygpath 115 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 116 | SEP="" 117 | for dir in $ROOTDIRSRAW ; do 118 | ROOTDIRS="$ROOTDIRS$SEP$dir" 119 | SEP="|" 120 | done 121 | OURCYGPATTERN="(^($ROOTDIRS))" 122 | # Add a user-defined pattern to the cygpath arguments 123 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 124 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 125 | fi 126 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 127 | i=0 128 | for arg in "$@" ; do 129 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 130 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 131 | 132 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 133 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 134 | else 135 | eval `echo args$i`="\"$arg\"" 136 | fi 137 | i=$((i+1)) 138 | done 139 | case $i in 140 | (0) set -- ;; 141 | (1) set -- "$args0" ;; 142 | (2) set -- "$args0" "$args1" ;; 143 | (3) set -- "$args0" "$args1" "$args2" ;; 144 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;; 145 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 146 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 147 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 148 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 149 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 150 | esac 151 | fi 152 | 153 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules 154 | function splitJvmOpts() { 155 | JVM_OPTS=("$@") 156 | } 157 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS 158 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" 159 | 160 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" 161 | -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @if "%DEBUG%" == "" @echo off 2 | @rem ########################################################################## 3 | @rem 4 | @rem Gradle startup script for Windows 5 | @rem 6 | @rem ########################################################################## 7 | 8 | @rem Set local scope for the variables with windows NT shell 9 | if "%OS%"=="Windows_NT" setlocal 10 | 11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 12 | set DEFAULT_JVM_OPTS= 13 | 14 | set DIRNAME=%~dp0 15 | if "%DIRNAME%" == "" set DIRNAME=. 16 | set APP_BASE_NAME=%~n0 17 | set APP_HOME=%DIRNAME% 18 | 19 | @rem Find java.exe 20 | if defined JAVA_HOME goto findJavaFromJavaHome 21 | 22 | set JAVA_EXE=java.exe 23 | %JAVA_EXE% -version >NUL 2>&1 24 | if "%ERRORLEVEL%" == "0" goto init 25 | 26 | echo. 27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 28 | echo. 29 | echo Please set the JAVA_HOME variable in your environment to match the 30 | echo location of your Java installation. 31 | 32 | goto fail 33 | 34 | :findJavaFromJavaHome 35 | set JAVA_HOME=%JAVA_HOME:"=% 36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 37 | 38 | if exist "%JAVA_EXE%" goto init 39 | 40 | echo. 41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 42 | echo. 43 | echo Please set the JAVA_HOME variable in your environment to match the 44 | echo location of your Java installation. 45 | 46 | goto fail 47 | 48 | :init 49 | @rem Get command-line arguments, handling Windowz variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | if "%@eval[2+2]" == "4" goto 4NT_args 53 | 54 | :win9xME_args 55 | @rem Slurp the command line arguments. 56 | set CMD_LINE_ARGS= 57 | set _SKIP=2 58 | 59 | :win9xME_args_slurp 60 | if "x%~1" == "x" goto execute 61 | 62 | set CMD_LINE_ARGS=%* 63 | goto execute 64 | 65 | :4NT_args 66 | @rem Get arguments from the 4NT Shell from JP Software 67 | set CMD_LINE_ARGS=%$ 68 | 69 | :execute 70 | @rem Setup the command line 71 | 72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 73 | 74 | @rem Execute Gradle 75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 76 | 77 | :end 78 | @rem End local scope for the variables with windows NT shell 79 | if "%ERRORLEVEL%"=="0" goto mainEnd 80 | 81 | :fail 82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 83 | rem the _cmd.exe /c_ return code! 84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 85 | exit /b 1 86 | 87 | :mainEnd 88 | if "%OS%"=="Windows_NT" endlocal 89 | 90 | :omega 91 | -------------------------------------------------------------------------------- /scripts/publish-mavencentral.gradle: -------------------------------------------------------------------------------- 1 | task androidSourcesJar(type: Jar) { 2 | classifier = 'sources' 3 | from android.sourceSets.main.java.source 4 | } 5 | 6 | artifacts { 7 | archives androidSourcesJar 8 | } 9 | 10 | 11 | apply plugin: 'maven-publish' 12 | apply plugin: 'signing' 13 | 14 | group = PUBLISH_GROUP_ID 15 | version = PUBLISH_VERSION 16 | 17 | 18 | ext["signing.keyId"] = '' 19 | ext["signing.password"] = '' 20 | ext["signing.secretKeyRingFile"] = '' 21 | ext["ossrhUsername"] = '' 22 | ext["ossrhPassword"] = '' 23 | 24 | File secretPropsFile = project.rootProject.file('local.properties') 25 | if (secretPropsFile.exists()) { 26 | println "Found secret props file, loading props" 27 | Properties p = new Properties() 28 | p.load(new FileInputStream(secretPropsFile)) 29 | p.each { name, value -> 30 | ext[name] = value 31 | } 32 | } else { 33 | println "No props file, loading env vars" 34 | ext["signing.keyId"] = System.getenv('SIGNING_KEY_ID') 35 | ext["signing.password"] = System.getenv('SIGNING_PASSWORD') 36 | ext["signing.secretKeyRingFile"] = System.getenv('SIGNING_SECRET_KEY_RING_FILE') 37 | ext["ossrhUsername"] = System.getenv('OSSRH_USERNAME') 38 | ext["ossrhPassword"] = System.getenv('OSSRH_PASSWORD') 39 | } 40 | 41 | 42 | 43 | publishing { 44 | publications { 45 | release(MavenPublication) { 46 | // The coordinates of the library, being set from variables that 47 | // we'll set up in a moment 48 | groupId PUBLISH_GROUP_ID 49 | artifactId PUBLISH_ARTIFACT_ID 50 | version PUBLISH_VERSION 51 | 52 | // Two artifacts, the `aar` and the sources 53 | artifact("$buildDir/outputs/aar/${project.getName()}.aar") 54 | artifact androidSourcesJar 55 | 56 | // Self-explanatory metadata for the most part 57 | pom { 58 | name = PUBLISH_ARTIFACT_ID 59 | description = 'The GraphStream library. With GraphStream you deal with graphs. Static and Dynamic. You create them from scratch, from a file or any source. You display and render them. This is the core package that contains the minimal needed to read and write a graph.' 60 | // If your project has a dedicated site, use its URL here 61 | url = 'https://graphstream-project.org' 62 | licenses { 63 | license { 64 | name = 'LGPL3' 65 | url = 'http://www.gnu.org/copyleft/lesser.html' 66 | } 67 | license { 68 | name = 'Cecill-C' 69 | url = 'http://www.cecill.info/licences/Licence_CeCILL-C_V1-en.html' 70 | } 71 | } 72 | developers { 73 | developer { 74 | id = 'brahimi' 75 | name = 'Hicham Brahimi' 76 | email = 'bhicham.brahimi@graphstream-project.org' 77 | } 78 | } 79 | // Version control info, if you're using GitHub, follow the format as seen here 80 | scm { 81 | connection = 'scm:git:git://github.com/graphstream/gs-core.git' 82 | developerConnection = 'scm:git:git://github.com/graphstream/gs-core.git' 83 | url = 'https://github.com/graphstream/gs-core' 84 | } 85 | // A slightly hacky fix so that your POM will include any transitive dependencies 86 | // that your library builds upon 87 | withXml { 88 | def dependenciesNode = asNode().appendNode('dependencies') 89 | 90 | project.configurations.implementation.allDependencies.each { 91 | def dependencyNode = dependenciesNode.appendNode('dependency') 92 | dependencyNode.appendNode('groupId', it.group) 93 | dependencyNode.appendNode('artifactId', it.name) 94 | dependencyNode.appendNode('version', it.version) 95 | } 96 | } 97 | } 98 | } 99 | } 100 | repositories { 101 | // The repository to publish to, Sonatype/MavenCentral 102 | maven { 103 | // This is an arbitrary name, you may also use "mavencentral" or 104 | // any other name that's descriptive for you 105 | name = "sonatype" 106 | 107 | def releasesRepoUrl = "https://oss.sonatype.org/service/local/staging/deploy/maven2/" 108 | def snapshotsRepoUrl = "https://oss.sonatype.org/content/repositories/snapshots/" 109 | // You only need this if you want to publish snapshots, otherwise just set the URL 110 | // to the release repo directly 111 | url = version.endsWith('SNAPSHOT') ? snapshotsRepoUrl : releasesRepoUrl 112 | 113 | // The username and password we've fetched earlier 114 | credentials { 115 | username ossrhUsername 116 | password ossrhPassword 117 | } 118 | } 119 | } 120 | } 121 | 122 | signing { 123 | sign publishing.publications 124 | } 125 | -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | include ':app' 2 | --------------------------------------------------------------------------------