]> rtime.felk.cvut.cz Git - orte.git/commitdiff
Initial commit of shape4a v1.0 - shape for android.
authorjiri hubacek <jiri.hubacek@gmail.com>
Sat, 20 Sep 2014 07:44:00 +0000 (10:44 +0300)
committerMichal Sojka <sojkam1@fel.cvut.cz>
Mon, 9 Feb 2015 16:56:15 +0000 (17:56 +0100)
48 files changed:
orte/contrib/shape_android/.classpath [new file with mode: 0644]
orte/contrib/shape_android/.gitignore [new file with mode: 0644]
orte/contrib/shape_android/.project [new file with mode: 0644]
orte/contrib/shape_android/.settings/org.eclipse.jdt.ui.prefs [new file with mode: 0644]
orte/contrib/shape_android/AndroidManifest.xml [new file with mode: 0644]
orte/contrib/shape_android/COPYING [new file with mode: 0644]
orte/contrib/shape_android/build.xml [new file with mode: 0644]
orte/contrib/shape_android/ic_launcher-web.png [new file with mode: 0644]
orte/contrib/shape_android/lint.xml [new file with mode: 0644]
orte/contrib/shape_android/proguard-project.txt [new file with mode: 0644]
orte/contrib/shape_android/project.properties [new file with mode: 0644]
orte/contrib/shape_android/res/drawable-hdpi/ic_action_cast.png [new file with mode: 0644]
orte/contrib/shape_android/res/drawable-hdpi/ic_action_download.png [new file with mode: 0644]
orte/contrib/shape_android/res/drawable-hdpi/ic_action_new.png [new file with mode: 0644]
orte/contrib/shape_android/res/drawable-hdpi/ic_launcher.png [new file with mode: 0644]
orte/contrib/shape_android/res/drawable-mdpi/ic_action_cast.png [new file with mode: 0644]
orte/contrib/shape_android/res/drawable-mdpi/ic_action_download.png [new file with mode: 0644]
orte/contrib/shape_android/res/drawable-mdpi/ic_action_new.png [new file with mode: 0644]
orte/contrib/shape_android/res/drawable-mdpi/ic_launcher.png [new file with mode: 0644]
orte/contrib/shape_android/res/drawable-xhdpi/ic_action_cast.png [new file with mode: 0644]
orte/contrib/shape_android/res/drawable-xhdpi/ic_action_download.png [new file with mode: 0644]
orte/contrib/shape_android/res/drawable-xhdpi/ic_action_new.png [new file with mode: 0644]
orte/contrib/shape_android/res/drawable-xhdpi/ic_launcher.png [new file with mode: 0644]
orte/contrib/shape_android/res/drawable-xxhdpi/ic_action_cast.png [new file with mode: 0644]
orte/contrib/shape_android/res/drawable-xxhdpi/ic_action_download.png [new file with mode: 0644]
orte/contrib/shape_android/res/drawable-xxhdpi/ic_action_new.png [new file with mode: 0644]
orte/contrib/shape_android/res/drawable-xxhdpi/ic_launcher.png [new file with mode: 0644]
orte/contrib/shape_android/res/layout/activity_main.xml [new file with mode: 0644]
orte/contrib/shape_android/res/layout/fragment_main.xml [new file with mode: 0644]
orte/contrib/shape_android/res/layout/fragment_publisher.xml [new file with mode: 0644]
orte/contrib/shape_android/res/layout/fragment_subscriber.xml [new file with mode: 0644]
orte/contrib/shape_android/res/menu/main.xml [new file with mode: 0644]
orte/contrib/shape_android/res/menu/publisher.xml [new file with mode: 0644]
orte/contrib/shape_android/res/menu/subscriber.xml [new file with mode: 0644]
orte/contrib/shape_android/res/values-v11/styles.xml [new file with mode: 0644]
orte/contrib/shape_android/res/values-v14/styles.xml [new file with mode: 0644]
orte/contrib/shape_android/res/values-w820dp/dimens.xml [new file with mode: 0644]
orte/contrib/shape_android/res/values/dimens.xml [new file with mode: 0644]
orte/contrib/shape_android/res/values/strings.xml [new file with mode: 0644]
orte/contrib/shape_android/res/values/styles.xml [new file with mode: 0644]
orte/contrib/shape_android/src/org/ocera/orte/shape4a/Box.java [new file with mode: 0644]
orte/contrib/shape_android/src/org/ocera/orte/shape4a/MainActivity.java [new file with mode: 0644]
orte/contrib/shape_android/src/org/ocera/orte/shape4a/PublisherFragment.java [new file with mode: 0644]
orte/contrib/shape_android/src/org/ocera/orte/shape4a/PublisherShape.java [new file with mode: 0644]
orte/contrib/shape_android/src/org/ocera/orte/shape4a/PublisherView.java [new file with mode: 0644]
orte/contrib/shape_android/src/org/ocera/orte/shape4a/SubscriberElement.java [new file with mode: 0644]
orte/contrib/shape_android/src/org/ocera/orte/shape4a/SubscriberFragment.java [new file with mode: 0644]
orte/contrib/shape_android/src/org/ocera/orte/shape4a/SubscriberView.java [new file with mode: 0644]

diff --git a/orte/contrib/shape_android/.classpath b/orte/contrib/shape_android/.classpath
new file mode 100644 (file)
index 0000000..5176974
--- /dev/null
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+       <classpathentry kind="con" path="com.android.ide.eclipse.adt.ANDROID_FRAMEWORK"/>
+       <classpathentry exported="true" kind="con" path="com.android.ide.eclipse.adt.LIBRARIES"/>
+       <classpathentry exported="true" kind="con" path="com.android.ide.eclipse.adt.DEPENDENCIES"/>
+       <classpathentry kind="src" path="src"/>
+       <classpathentry kind="src" path="gen"/>
+       <classpathentry kind="output" path="bin/classes"/>
+</classpath>
diff --git a/orte/contrib/shape_android/.gitignore b/orte/contrib/shape_android/.gitignore
new file mode 100644 (file)
index 0000000..943202a
--- /dev/null
@@ -0,0 +1,28 @@
+# Built application files
+*.apk
+*.ap_
+
+# Files for the Dalvik VM
+*.dex
+
+# Java class files
+*.class
+
+# Generated files
+bin/
+gen/
+libs/
+obj/
+
+# Gradle files
+.gradle/
+build/
+
+# Local configuration file (sdk path, etc)
+local.properties
+
+# Proguard folder generated by Eclipse
+proguard/
+
+# Log Files
+*.log
diff --git a/orte/contrib/shape_android/.project b/orte/contrib/shape_android/.project
new file mode 100644 (file)
index 0000000..cfa3e9a
--- /dev/null
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+       <name>shape4a</name>
+       <comment></comment>
+       <projects>
+       </projects>
+       <buildSpec>
+               <buildCommand>
+                       <name>com.android.ide.eclipse.adt.ResourceManagerBuilder</name>
+                       <arguments>
+                       </arguments>
+               </buildCommand>
+               <buildCommand>
+                       <name>com.android.ide.eclipse.adt.PreCompilerBuilder</name>
+                       <arguments>
+                       </arguments>
+               </buildCommand>
+               <buildCommand>
+                       <name>org.eclipse.jdt.core.javabuilder</name>
+                       <arguments>
+                       </arguments>
+               </buildCommand>
+               <buildCommand>
+                       <name>com.android.ide.eclipse.adt.ApkBuilder</name>
+                       <arguments>
+                       </arguments>
+               </buildCommand>
+       </buildSpec>
+       <natures>
+               <nature>com.android.ide.eclipse.adt.AndroidNature</nature>
+               <nature>org.eclipse.jdt.core.javanature</nature>
+       </natures>
+</projectDescription>
diff --git a/orte/contrib/shape_android/.settings/org.eclipse.jdt.ui.prefs b/orte/contrib/shape_android/.settings/org.eclipse.jdt.ui.prefs
new file mode 100644 (file)
index 0000000..b2e981b
--- /dev/null
@@ -0,0 +1,3 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.ui.javadoc=false
+org.eclipse.jdt.ui.text.custom_code_templates=<?xml version\="1.0" encoding\="UTF-8" standalone\="no"?><templates><template autoinsert\="true" context\="gettercomment_context" deleted\="false" description\="Comment for getter method" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.gettercomment" name\="gettercomment">/**\n * @return the ${bare_field_name}\n */</template><template autoinsert\="true" context\="settercomment_context" deleted\="false" description\="Comment for setter method" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.settercomment" name\="settercomment">/**\n * @param ${param} the ${bare_field_name} to set\n */</template><template autoinsert\="true" context\="constructorcomment_context" deleted\="false" description\="Comment for created constructors" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.constructorcomment" name\="constructorcomment">/**\n * ${tags}\n */</template><template autoinsert\="false" context\="filecomment_context" deleted\="false" description\="Comment for created Java files" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.filecomment" name\="filecomment">/**\n * \n *\tThis file is part of shape4a.\n *\n *  shape4a is free software\: you can redistribute it and/or modify\n *  it under the terms of the GNU General Public License as published by\n *  the Free Software Foundation, either version 3 of the License, or\n *  (at your option) any later version.\n *\n *  shape4a is distributed in the hope that it will be useful,\n *  but WITHOUT ANY WARRANTY; without even the implied warranty of\n *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n *  GNU General Public License for more details.\n *\n *  You should have received a copy of the GNU General Public License\n *  along with shape4a.  If not, see &lt;http\://www.gnu.org/licenses/&gt;.\n *\n */</template><template autoinsert\="true" context\="typecomment_context" deleted\="false" description\="Comment for created types" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.typecomment" name\="typecomment">/**\n * @author ${user}\n *\n * ${tags}\n */</template><template autoinsert\="true" context\="fieldcomment_context" deleted\="false" description\="Comment for fields" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.fieldcomment" name\="fieldcomment">/**\n * \n */</template><template autoinsert\="true" context\="methodcomment_context" deleted\="false" description\="Comment for non-overriding methods" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.methodcomment" name\="methodcomment">/**\n * ${tags}\n */</template><template autoinsert\="true" context\="overridecomment_context" deleted\="false" description\="Comment for overriding methods" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.overridecomment" name\="overridecomment">/* (non-Javadoc)\n * ${see_to_overridden}\n */</template><template autoinsert\="true" context\="delegatecomment_context" deleted\="false" description\="Comment for delegate methods" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.delegatecomment" name\="delegatecomment">/**\n * ${tags}\n * ${see_to_target}\n */</template><template autoinsert\="true" context\="newtype_context" deleted\="false" description\="Newly created files" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.newtype" name\="newtype">${filecomment}\n${package_declaration}\n\n${typecomment}\n${type_declaration}</template><template autoinsert\="true" context\="classbody_context" deleted\="false" description\="Code in new class type bodies" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.classbody" name\="classbody">\n</template><template autoinsert\="true" context\="interfacebody_context" deleted\="false" description\="Code in new interface type bodies" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.interfacebody" name\="interfacebody">\n</template><template autoinsert\="true" context\="enumbody_context" deleted\="false" description\="Code in new enum type bodies" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.enumbody" name\="enumbody">\n</template><template autoinsert\="true" context\="annotationbody_context" deleted\="false" description\="Code in new annotation type bodies" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.annotationbody" name\="annotationbody">\n</template><template autoinsert\="true" context\="catchblock_context" deleted\="false" description\="Code in new catch blocks" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.catchblock" name\="catchblock">// ${todo} Auto-generated catch block\n${exception_var}.printStackTrace();</template><template autoinsert\="true" context\="methodbody_context" deleted\="false" description\="Code in created method stubs" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.methodbody" name\="methodbody">// ${todo} Auto-generated method stub\n${body_statement}</template><template autoinsert\="true" context\="constructorbody_context" deleted\="false" description\="Code in created constructor stubs" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.constructorbody" name\="constructorbody">${body_statement}\n// ${todo} Auto-generated constructor stub</template><template autoinsert\="true" context\="getterbody_context" deleted\="false" description\="Code in created getters" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.getterbody" name\="getterbody">return ${field};</template><template autoinsert\="true" context\="setterbody_context" deleted\="false" description\="Code in created setters" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.setterbody" name\="setterbody">${field} \= ${param};</template></templates>
diff --git a/orte/contrib/shape_android/AndroidManifest.xml b/orte/contrib/shape_android/AndroidManifest.xml
new file mode 100644 (file)
index 0000000..e872068
--- /dev/null
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="org.ocera.orte.shape4a"
+    android:versionCode="1"
+    android:versionName="1.0" >
+
+    <uses-sdk
+        android:minSdkVersion="8"
+        android:targetSdkVersion="15" />
+
+     <uses-permission android:name="android.permission.INTERNET"/>
+     <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
+     <uses-permission android:name="android.permission.WAKE_LOCK"/>
+    
+    <application
+        android:allowBackup="true"
+        android:icon="@drawable/ic_launcher"
+        android:label="@string/app_name"
+        android:theme="@style/AppTheme" >
+        <activity
+            android:name=".MainActivity"
+            android:label="@string/app_name"
+            android:configChanges="screenSize|orientation" >
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+    </application>
+
+</manifest>
diff --git a/orte/contrib/shape_android/COPYING b/orte/contrib/shape_android/COPYING
new file mode 100644 (file)
index 0000000..d159169
--- /dev/null
@@ -0,0 +1,339 @@
+                    GNU GENERAL PUBLIC LICENSE
+                       Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+                            Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users.  This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it.  (Some other Free Software Foundation software is covered by
+the GNU Lesser General Public License instead.)  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+  To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have.  You must make sure that they, too, receive or can get the
+source code.  And you must show them these terms so they know their
+rights.
+
+  We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+  Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software.  If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+  Finally, any free program is threatened constantly by software
+patents.  We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary.  To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+                    GNU GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License.  The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language.  (Hereinafter, translation is included without limitation in
+the term "modification".)  Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+  1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+  2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) You must cause the modified files to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    b) You must cause any work that you distribute or publish, that in
+    whole or in part contains or is derived from the Program or any
+    part thereof, to be licensed as a whole at no charge to all third
+    parties under the terms of this License.
+
+    c) If the modified program normally reads commands interactively
+    when run, you must cause it, when started running for such
+    interactive use in the most ordinary way, to print or display an
+    announcement including an appropriate copyright notice and a
+    notice that there is no warranty (or else, saying that you provide
+    a warranty) and that users may redistribute the program under
+    these conditions, and telling the user how to view a copy of this
+    License.  (Exception: if the Program itself is interactive but
+    does not normally print such an announcement, your work based on
+    the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+    a) Accompany it with the complete corresponding machine-readable
+    source code, which must be distributed under the terms of Sections
+    1 and 2 above on a medium customarily used for software interchange; or,
+
+    b) Accompany it with a written offer, valid for at least three
+    years, to give any third party, for a charge no more than your
+    cost of physically performing source distribution, a complete
+    machine-readable copy of the corresponding source code, to be
+    distributed under the terms of Sections 1 and 2 above on a medium
+    customarily used for software interchange; or,
+
+    c) Accompany it with the information you received as to the offer
+    to distribute corresponding source code.  (This alternative is
+    allowed only for noncommercial distribution and only if you
+    received the program in object code or executable form with such
+    an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it.  For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable.  However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+  4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License.  Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+  5. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Program or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+  6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+  7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+  8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded.  In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+  9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation.  If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+  10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission.  For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this.  Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+                            NO WARRANTY
+
+  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+                     END OF TERMS AND CONDITIONS
+
+            How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License along
+    with this program; if not, write to the Free Software Foundation, Inc.,
+    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+    Gnomovision version 69, Copyright (C) year name of author
+    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License.  Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+  `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+  <signature of Ty Coon>, 1 April 1989
+  Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs.  If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library.  If this is what you want to do, use the GNU Lesser General
+Public License instead of this License.
diff --git a/orte/contrib/shape_android/build.xml b/orte/contrib/shape_android/build.xml
new file mode 100644 (file)
index 0000000..a64a1ea
--- /dev/null
@@ -0,0 +1,92 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project name="shape4a" default="help">
+
+    <!-- The local.properties file is created and updated by the 'android' tool.
+         It contains the path to the SDK. It should *NOT* be checked into
+         Version Control Systems. -->
+    <property file="local.properties" />
+
+    <!-- The ant.properties file can be created by you. It is only edited by the
+         'android' tool to add properties to it.
+         This is the place to change some Ant specific build properties.
+         Here are some properties you may want to change/update:
+
+         source.dir
+             The name of the source directory. Default is 'src'.
+         out.dir
+             The name of the output directory. Default is 'bin'.
+
+         For other overridable properties, look at the beginning of the rules
+         files in the SDK, at tools/ant/build.xml
+
+         Properties related to the SDK location or the project target should
+         be updated using the 'android' tool with the 'update' action.
+
+         This file is an integral part of the build system for your
+         application and should be checked into Version Control Systems.
+
+         -->
+    <property file="ant.properties" />
+
+    <!-- if sdk.dir was not set from one of the property file, then
+         get it from the ANDROID_HOME env var.
+         This must be done before we load project.properties since
+         the proguard config can use sdk.dir -->
+    <property environment="env" />
+    <condition property="sdk.dir" value="${env.ANDROID_HOME}">
+        <isset property="env.ANDROID_HOME" />
+    </condition>
+
+    <!-- The project.properties file is created and updated by the 'android'
+         tool, as well as ADT.
+
+         This contains project specific properties such as project target, and library
+         dependencies. Lower level build properties are stored in ant.properties
+         (or in .classpath for Eclipse projects).
+
+         This file is an integral part of the build system for your
+         application and should be checked into Version Control Systems. -->
+    <loadproperties srcFile="project.properties" />
+
+    <!-- quick check on sdk.dir -->
+    <fail
+            message="sdk.dir is missing. Make sure to generate local.properties using 'android update project' or to inject it through the ANDROID_HOME environment variable."
+            unless="sdk.dir"
+    />
+
+    <!--
+        Import per project custom build rules if present at the root of the project.
+        This is the place to put custom intermediary targets such as:
+            -pre-build
+            -pre-compile
+            -post-compile (This is typically used for code obfuscation.
+                           Compiled code location: ${out.classes.absolute.dir}
+                           If this is not done in place, override ${out.dex.input.absolute.dir})
+            -post-package
+            -post-build
+            -pre-clean
+    -->
+    <import file="custom_rules.xml" optional="true" />
+
+    <!-- Import the actual build file.
+
+         To customize existing targets, there are two options:
+         - Customize only one target:
+             - copy/paste the target into this file, *before* the
+               <import> task.
+             - customize it to your needs.
+         - Customize the whole content of build.xml
+             - copy/paste the content of the rules files (minus the top node)
+               into this file, replacing the <import> task.
+             - customize to your needs.
+
+         ***********************
+         ****** IMPORTANT ******
+         ***********************
+         In all cases you must update the value of version-tag below to read 'custom' instead of an integer,
+         in order to avoid having your file be overridden by tools such as "android update project"
+    -->
+    <!-- version-tag: 1 -->
+    <import file="${sdk.dir}/tools/ant/build.xml" />
+
+</project>
diff --git a/orte/contrib/shape_android/ic_launcher-web.png b/orte/contrib/shape_android/ic_launcher-web.png
new file mode 100644 (file)
index 0000000..f73f87b
Binary files /dev/null and b/orte/contrib/shape_android/ic_launcher-web.png differ
diff --git a/orte/contrib/shape_android/lint.xml b/orte/contrib/shape_android/lint.xml
new file mode 100644 (file)
index 0000000..ee0eead
--- /dev/null
@@ -0,0 +1,3 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<lint>
+</lint>
\ No newline at end of file
diff --git a/orte/contrib/shape_android/proguard-project.txt b/orte/contrib/shape_android/proguard-project.txt
new file mode 100644 (file)
index 0000000..f2fe155
--- /dev/null
@@ -0,0 +1,20 @@
+# To enable ProGuard in your project, edit project.properties
+# to define the proguard.config property as described in that file.
+#
+# Add project specific ProGuard rules here.
+# By default, the flags in this file are appended to flags specified
+# in ${sdk.dir}/tools/proguard/proguard-android.txt
+# You can edit the include path and order by changing the ProGuard
+# include property in project.properties.
+#
+# For more details, see
+#   http://developer.android.com/guide/developing/tools/proguard.html
+
+# Add any project specific keep options here:
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+#   public *;
+#}
diff --git a/orte/contrib/shape_android/project.properties b/orte/contrib/shape_android/project.properties
new file mode 100644 (file)
index 0000000..f970a6c
--- /dev/null
@@ -0,0 +1,16 @@
+# This file is automatically generated by Android Tools.
+# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
+#
+# This file must be checked in Version Control Systems.
+#
+# To customize properties used by the Ant build system edit
+# "ant.properties", and override values to adapt the script to your
+# project structure.
+#
+# To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home):
+#proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
+
+# Project target.
+target=android-15
+android.library.reference.1=../../../../../workspace/appcompat_v7
+android.library.reference.2=../../libaorte
diff --git a/orte/contrib/shape_android/res/drawable-hdpi/ic_action_cast.png b/orte/contrib/shape_android/res/drawable-hdpi/ic_action_cast.png
new file mode 100644 (file)
index 0000000..066ddd5
Binary files /dev/null and b/orte/contrib/shape_android/res/drawable-hdpi/ic_action_cast.png differ
diff --git a/orte/contrib/shape_android/res/drawable-hdpi/ic_action_download.png b/orte/contrib/shape_android/res/drawable-hdpi/ic_action_download.png
new file mode 100644 (file)
index 0000000..9fc6455
Binary files /dev/null and b/orte/contrib/shape_android/res/drawable-hdpi/ic_action_download.png differ
diff --git a/orte/contrib/shape_android/res/drawable-hdpi/ic_action_new.png b/orte/contrib/shape_android/res/drawable-hdpi/ic_action_new.png
new file mode 100644 (file)
index 0000000..d866d61
Binary files /dev/null and b/orte/contrib/shape_android/res/drawable-hdpi/ic_action_new.png differ
diff --git a/orte/contrib/shape_android/res/drawable-hdpi/ic_launcher.png b/orte/contrib/shape_android/res/drawable-hdpi/ic_launcher.png
new file mode 100644 (file)
index 0000000..18e088b
Binary files /dev/null and b/orte/contrib/shape_android/res/drawable-hdpi/ic_launcher.png differ
diff --git a/orte/contrib/shape_android/res/drawable-mdpi/ic_action_cast.png b/orte/contrib/shape_android/res/drawable-mdpi/ic_action_cast.png
new file mode 100644 (file)
index 0000000..49e214b
Binary files /dev/null and b/orte/contrib/shape_android/res/drawable-mdpi/ic_action_cast.png differ
diff --git a/orte/contrib/shape_android/res/drawable-mdpi/ic_action_download.png b/orte/contrib/shape_android/res/drawable-mdpi/ic_action_download.png
new file mode 100644 (file)
index 0000000..84b43d3
Binary files /dev/null and b/orte/contrib/shape_android/res/drawable-mdpi/ic_action_download.png differ
diff --git a/orte/contrib/shape_android/res/drawable-mdpi/ic_action_new.png b/orte/contrib/shape_android/res/drawable-mdpi/ic_action_new.png
new file mode 100644 (file)
index 0000000..f17e798
Binary files /dev/null and b/orte/contrib/shape_android/res/drawable-mdpi/ic_action_new.png differ
diff --git a/orte/contrib/shape_android/res/drawable-mdpi/ic_launcher.png b/orte/contrib/shape_android/res/drawable-mdpi/ic_launcher.png
new file mode 100644 (file)
index 0000000..69a0b61
Binary files /dev/null and b/orte/contrib/shape_android/res/drawable-mdpi/ic_launcher.png differ
diff --git a/orte/contrib/shape_android/res/drawable-xhdpi/ic_action_cast.png b/orte/contrib/shape_android/res/drawable-xhdpi/ic_action_cast.png
new file mode 100644 (file)
index 0000000..7c4d657
Binary files /dev/null and b/orte/contrib/shape_android/res/drawable-xhdpi/ic_action_cast.png differ
diff --git a/orte/contrib/shape_android/res/drawable-xhdpi/ic_action_download.png b/orte/contrib/shape_android/res/drawable-xhdpi/ic_action_download.png
new file mode 100644 (file)
index 0000000..702ad47
Binary files /dev/null and b/orte/contrib/shape_android/res/drawable-xhdpi/ic_action_download.png differ
diff --git a/orte/contrib/shape_android/res/drawable-xhdpi/ic_action_new.png b/orte/contrib/shape_android/res/drawable-xhdpi/ic_action_new.png
new file mode 100644 (file)
index 0000000..dde2141
Binary files /dev/null and b/orte/contrib/shape_android/res/drawable-xhdpi/ic_action_new.png differ
diff --git a/orte/contrib/shape_android/res/drawable-xhdpi/ic_launcher.png b/orte/contrib/shape_android/res/drawable-xhdpi/ic_launcher.png
new file mode 100644 (file)
index 0000000..22a9e5f
Binary files /dev/null and b/orte/contrib/shape_android/res/drawable-xhdpi/ic_launcher.png differ
diff --git a/orte/contrib/shape_android/res/drawable-xxhdpi/ic_action_cast.png b/orte/contrib/shape_android/res/drawable-xxhdpi/ic_action_cast.png
new file mode 100644 (file)
index 0000000..f394a34
Binary files /dev/null and b/orte/contrib/shape_android/res/drawable-xxhdpi/ic_action_cast.png differ
diff --git a/orte/contrib/shape_android/res/drawable-xxhdpi/ic_action_download.png b/orte/contrib/shape_android/res/drawable-xxhdpi/ic_action_download.png
new file mode 100644 (file)
index 0000000..6bcd831
Binary files /dev/null and b/orte/contrib/shape_android/res/drawable-xxhdpi/ic_action_download.png differ
diff --git a/orte/contrib/shape_android/res/drawable-xxhdpi/ic_action_new.png b/orte/contrib/shape_android/res/drawable-xxhdpi/ic_action_new.png
new file mode 100644 (file)
index 0000000..c42c2bf
Binary files /dev/null and b/orte/contrib/shape_android/res/drawable-xxhdpi/ic_action_new.png differ
diff --git a/orte/contrib/shape_android/res/drawable-xxhdpi/ic_launcher.png b/orte/contrib/shape_android/res/drawable-xxhdpi/ic_launcher.png
new file mode 100644 (file)
index 0000000..4256a0f
Binary files /dev/null and b/orte/contrib/shape_android/res/drawable-xxhdpi/ic_launcher.png differ
diff --git a/orte/contrib/shape_android/res/layout/activity_main.xml b/orte/contrib/shape_android/res/layout/activity_main.xml
new file mode 100644 (file)
index 0000000..57bafec
--- /dev/null
@@ -0,0 +1,6 @@
+<android.support.v4.view.ViewPager xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:id="@+id/pager"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    tools:context="org.ocera.orte.shape4a.MainActivity" />
diff --git a/orte/contrib/shape_android/res/layout/fragment_main.xml b/orte/contrib/shape_android/res/layout/fragment_main.xml
new file mode 100644 (file)
index 0000000..fcb917b
--- /dev/null
@@ -0,0 +1,16 @@
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:paddingBottom="@dimen/activity_vertical_margin"
+    android:paddingLeft="@dimen/activity_horizontal_margin"
+    android:paddingRight="@dimen/activity_horizontal_margin"
+    android:paddingTop="@dimen/activity_vertical_margin"
+    tools:context="org.ocera.orte.shape4a.MainActivity$PlaceholderFragment" >
+
+    <TextView
+        android:id="@+id/section_label"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content" />
+
+</RelativeLayout>
diff --git a/orte/contrib/shape_android/res/layout/fragment_publisher.xml b/orte/contrib/shape_android/res/layout/fragment_publisher.xml
new file mode 100644 (file)
index 0000000..83d4697
--- /dev/null
@@ -0,0 +1,16 @@
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:paddingBottom="@dimen/activity_vertical_margin"
+    android:paddingLeft="@dimen/activity_horizontal_margin"
+    android:paddingRight="@dimen/activity_horizontal_margin"
+    android:paddingTop="@dimen/activity_vertical_margin"
+    tools:context="org.ocera.orte.shape4a.MainActivity$PublisherFragment" >
+
+    <org.ocera.orte.shape4a.PublisherView
+        android:id="@+id/publisher_view"
+        android:layout_width="fill_parent"
+        android:layout_height="fill_parent" />
+    
+</RelativeLayout>
diff --git a/orte/contrib/shape_android/res/layout/fragment_subscriber.xml b/orte/contrib/shape_android/res/layout/fragment_subscriber.xml
new file mode 100644 (file)
index 0000000..eff30d5
--- /dev/null
@@ -0,0 +1,16 @@
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:paddingBottom="@dimen/activity_vertical_margin"
+    android:paddingLeft="@dimen/activity_horizontal_margin"
+    android:paddingRight="@dimen/activity_horizontal_margin"
+    android:paddingTop="@dimen/activity_vertical_margin"
+    tools:context="org.ocera.orte.shape4a.MainActivity$SubscriberFragment" >
+
+    <org.ocera.orte.shape4a.SubscriberView
+        android:id="@+id/subscriber_view"
+        android:layout_width="fill_parent"
+        android:layout_height="fill_parent" />
+
+</RelativeLayout>
diff --git a/orte/contrib/shape_android/res/menu/main.xml b/orte/contrib/shape_android/res/menu/main.xml
new file mode 100644 (file)
index 0000000..3671a87
--- /dev/null
@@ -0,0 +1,19 @@
+<menu xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    xmlns:tools="http://schemas.android.com/tools"
+    tools:context="org.ocera.orte.shape4a.MainActivity" >
+
+    <item
+        android:id="@+id/action_settings"
+        android:orderInCategory="100"
+        android:title="@string/action_settings"
+        app:showAsAction="never" />
+    
+    <item 
+        android:id="@+id/action_help"  
+        android:orderInCategory="101"
+        android:title="@string/action_help"
+        app:showAsAction="never" />
+    
+
+</menu>
diff --git a/orte/contrib/shape_android/res/menu/publisher.xml b/orte/contrib/shape_android/res/menu/publisher.xml
new file mode 100644 (file)
index 0000000..090b25d
--- /dev/null
@@ -0,0 +1,14 @@
+<menu xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    xmlns:tools="http://schemas.android.com/tools"
+    tools:context="org.ocera.orte.shape4a.MainActivity" >
+    
+    <item
+        android:id="@+id/action_new"
+        android:orderInCategory="10"
+        android:title="@string/action_new"
+        android:icon="@drawable/ic_action_new"
+        app:showAsAction="ifRoom" />
+    
+
+</menu>
diff --git a/orte/contrib/shape_android/res/menu/subscriber.xml b/orte/contrib/shape_android/res/menu/subscriber.xml
new file mode 100644 (file)
index 0000000..1e0a5b0
--- /dev/null
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<menu xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    xmlns:tools="http://schemas.android.com/tools"
+    tools:context="org.ocera.orte.shape4a.MainActivity" >
+    
+    <item android:id="@+id/action_blue"
+          android:title="@string/action_blue"
+          app:showAsAction="never" />
+    
+    <item android:id="@+id/action_green"
+          android:title="@string/action_green"
+          app:showAsAction="never" />
+    
+    <item android:id="@+id/action_red"
+          android:title="@string/action_red"
+          app:showAsAction="never" />
+    
+    <item android:id="@+id/action_black"
+          android:title="@string/action_black"
+          app:showAsAction="never" />
+    
+    <item android:id="@+id/action_yellow"
+          android:title="@string/action_yellow"
+          app:showAsAction="never" />
+
+</menu>
diff --git a/orte/contrib/shape_android/res/values-v11/styles.xml b/orte/contrib/shape_android/res/values-v11/styles.xml
new file mode 100644 (file)
index 0000000..a4a95bc
--- /dev/null
@@ -0,0 +1,11 @@
+<resources>
+
+    <!--
+        Base application theme for API 11+. This theme completely replaces
+        AppBaseTheme from res/values/styles.xml on API 11+ devices.
+    -->
+    <style name="AppBaseTheme" parent="Theme.AppCompat.Light">
+        <!-- API 11 theme customizations can go here. -->
+    </style>
+
+</resources>
diff --git a/orte/contrib/shape_android/res/values-v14/styles.xml b/orte/contrib/shape_android/res/values-v14/styles.xml
new file mode 100644 (file)
index 0000000..664f4f1
--- /dev/null
@@ -0,0 +1,12 @@
+<resources>
+
+    <!--
+        Base application theme for API 14+. This theme completely replaces
+        AppBaseTheme from BOTH res/values/styles.xml and
+        res/values-v11/styles.xml on API 14+ devices.
+    -->
+    <style name="AppBaseTheme" parent="Theme.AppCompat.Light.DarkActionBar">
+        <!-- API 14 theme customizations can go here. -->
+    </style>
+
+</resources>
diff --git a/orte/contrib/shape_android/res/values-w820dp/dimens.xml b/orte/contrib/shape_android/res/values-w820dp/dimens.xml
new file mode 100644 (file)
index 0000000..f3e7020
--- /dev/null
@@ -0,0 +1,10 @@
+<resources>
+
+    <!--
+         Example customization of dimensions originally defined in res/values/dimens.xml
+         (such as screen margins) for screens with more than 820dp of available width. This
+         would include 7" and 10" devices in landscape (~960dp and ~1280dp respectively).
+    -->
+    <dimen name="activity_horizontal_margin">64dp</dimen>
+
+</resources>
diff --git a/orte/contrib/shape_android/res/values/dimens.xml b/orte/contrib/shape_android/res/values/dimens.xml
new file mode 100644 (file)
index 0000000..55c1e59
--- /dev/null
@@ -0,0 +1,7 @@
+<resources>
+
+    <!-- Default screen margins, per the Android Design guidelines. -->
+    <dimen name="activity_horizontal_margin">16dp</dimen>
+    <dimen name="activity_vertical_margin">16dp</dimen>
+
+</resources>
diff --git a/orte/contrib/shape_android/res/values/strings.xml b/orte/contrib/shape_android/res/values/strings.xml
new file mode 100644 (file)
index 0000000..3a3b40b
--- /dev/null
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+
+    <string name="app_name">shape4a</string>
+    <string name="dialog_OK">OK</string>
+    <string name="dialog_cancel">Cancel</string>
+    <string name="dialog_newPublisher">Color for new Publisher?</string>
+    <string name="dialog_publisherSettings">Publisher #</string>
+    <string name="dialog_delete">Delete</string>
+    <string name="dialog_add">Add</string>
+    <string name="action_settings">Settings</string>
+    <string name="action_help">Help</string>
+    <string name="action_blue">Blue</string>
+    <string name="action_green">Green</string>
+    <string name="action_red">Red</string>
+    <string name="action_black">Black</string>
+    <string name="action_yellow">Yellow</string>
+    <string name="action_new">New</string>
+
+</resources>
diff --git a/orte/contrib/shape_android/res/values/styles.xml b/orte/contrib/shape_android/res/values/styles.xml
new file mode 100644 (file)
index 0000000..845fb57
--- /dev/null
@@ -0,0 +1,20 @@
+<resources>
+
+    <!--
+        Base application theme, dependent on API level. This theme is replaced
+        by AppBaseTheme from res/values-vXX/styles.xml on newer devices.
+    -->
+    <style name="AppBaseTheme" parent="Theme.AppCompat.Light">
+        <!--
+            Theme customizations available in newer API levels can go in
+            res/values-vXX/styles.xml, while customizations related to
+            backward-compatibility can go here.
+        -->
+    </style>
+
+    <!-- Application theme. -->
+    <style name="AppTheme" parent="AppBaseTheme">
+        <!-- All customizations that are NOT specific to a particular API-level can go here. -->
+    </style>
+
+</resources>
diff --git a/orte/contrib/shape_android/src/org/ocera/orte/shape4a/Box.java b/orte/contrib/shape_android/src/org/ocera/orte/shape4a/Box.java
new file mode 100644 (file)
index 0000000..f20eab0
--- /dev/null
@@ -0,0 +1,151 @@
+/**
+ * 
+ *     This file is part of shape4a.
+ *
+ *  shape4a is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  shape4a is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with shape4a.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+package org.ocera.orte.shape4a;
+
+import org.ocera.orte.*;
+import org.ocera.orte.types.*;
+
+import android.util.Log;
+
+/**
+ * Object to be send throw ORTE.
+ * 
+ * @author jiri hubacek <jiri.hubacek@gmail.com>
+ * @version %I%, %G%
+ * @since 1.0
+ */
+public class Box extends MessageData
+{
+       private static final double DESTINATION_WIDTH = 389.0;
+       private static final double DESTINATION_HEIGHT = 256.0;
+       
+       public boolean allowScaling;
+       public int color;
+       // is more shape than strength,
+       // strength is solved throw
+       // publisherProperties or
+       // throw subscriberProperties...
+       public int strength;
+       public BoxRect rectangle;
+       
+       private double scaleWidth;
+       private double scaleHeight;
+       
+       /**
+        * Add topic of new object.
+        * 
+        * @param appDomain
+        * @param newTopic
+        * @since 1.0
+        */
+       public Box(DomainApp appDomain, String newTopic) {
+               super();
+               this.setTopic(newTopic);
+               
+               if (!appDomain.regNewDataType("Box", this.getMaxDataLength())) {
+                       Log.e("Box", "Cannot register data type 'Box'.");
+               }
+               
+               this.rectangle = new BoxRect();
+               this.allowScaling = true;
+               this.scaleWidth = 1;
+               this.scaleHeight = 1;
+       }
+
+       /**
+        * Read data from buffer.
+        * @since 1.0
+        */
+       @Override
+       public void read() {
+               buffer.rewind();
+               if (this.allowScaling) {
+                       this.rectangle.top_left_x = (short) (buffer.getShort() / this.scaleWidth);
+                       this.rectangle.top_left_y = (short) (buffer.getShort() / this.scaleHeight);
+                       this.rectangle.bottom_right_x = (short) (buffer.getShort() / this.scaleWidth);
+                       this.rectangle.bottom_right_y = (short) (buffer.getShort() / this.scaleHeight);
+               } else {
+                       this.rectangle.top_left_x = buffer.getShort();
+                       this.rectangle.top_left_y = buffer.getShort();
+                       this.rectangle.bottom_right_x = buffer.getShort();
+                       this.rectangle.bottom_right_y = buffer.getShort();
+               }
+               
+               this.strength = (int) buffer.getShort();
+       }
+
+       /**
+        * Write data to buffer.
+        * @since 1.0
+        */
+       @Override
+       public void write() {
+               buffer.rewind();
+               if (this.allowScaling) {
+                       buffer.putShort((short) (rectangle.top_left_x * this.scaleWidth));
+                       buffer.putShort((short) (rectangle.top_left_y * this.scaleHeight));
+                       buffer.putShort((short) (rectangle.bottom_right_x * this.scaleWidth));
+                       buffer.putShort((short) (rectangle.bottom_right_y * this.scaleHeight));
+               } else {
+                       buffer.putShort(rectangle.top_left_x);
+                       buffer.putShort(rectangle.top_left_y);
+                       buffer.putShort(rectangle.bottom_right_x);
+                       buffer.putShort(rectangle.bottom_right_y);
+               }
+               
+               buffer.putShort((short) this.strength);
+       }
+
+       /**
+        * Get maximum length of data.
+        * @since 1.0
+        */
+       @Override
+       public int getMaxDataLength() {
+               return 5 * ORTEConstant.SHORT_FIELD_SIZE;
+       }
+       
+       /**
+        * Object to be truly send throw ORTE.
+        * 
+        * @since 1.0
+        */
+       public class BoxRect
+       {
+               public short top_left_x;
+               public short top_left_y;
+               public short bottom_right_x;
+               public short bottom_right_y;
+               
+               public BoxRect()
+               {}
+       }
+       
+       /**
+        * When screen rotates, change scale variables to
+        * fit the destination screen.
+        * 
+        * @since 1.0
+        */
+       public void setScale(int currentWidth, int currentHeight)
+       {
+               this.scaleWidth = DESTINATION_WIDTH / currentWidth;
+               this.scaleHeight = DESTINATION_HEIGHT / currentHeight;
+       }
+}
diff --git a/orte/contrib/shape_android/src/org/ocera/orte/shape4a/MainActivity.java b/orte/contrib/shape_android/src/org/ocera/orte/shape4a/MainActivity.java
new file mode 100644 (file)
index 0000000..7de0d7b
--- /dev/null
@@ -0,0 +1,342 @@
+/**
+ * 
+ *     This file is part of shape4a.
+ *
+ *  shape4a is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  shape4a is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with shape4a.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+package org.ocera.orte.shape4a;
+
+import java.util.regex.Pattern;
+
+import android.support.v7.app.ActionBarActivity;
+import android.support.v4.app.DialogFragment;
+import android.support.v4.app.Fragment;
+import android.support.v4.app.FragmentManager;
+import android.support.v4.app.FragmentPagerAdapter;
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.net.wifi.WifiManager;
+import android.net.wifi.WifiManager.WifiLock;
+import android.os.Bundle;
+import android.support.v4.view.ViewPager;
+import android.text.InputType;
+import android.text.format.Formatter;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.View;
+import android.widget.EditText;
+import android.widget.LinearLayout;
+
+import org.ocera.orte.DomainApp;
+import org.ocera.orte.Manager;
+
+//TODO Better navigation (swipe sometimes miss drag).
+
+/**
+ * Main application activity, when application
+ * launch, this activity is choosen.
+ * 
+ * @author jiri hubacek <jiri.hubacek@gmail.com>
+ * @version %I%, %G%
+ * @since 1.0
+ */
+public class MainActivity extends ActionBarActivity {
+       public final static Pattern IP_ADDRESS = Pattern.compile("((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?).(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?).(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?).(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?))");
+       
+       /**
+        * The {@link android.support.v4.view.PagerAdapter} that will provide
+        * fragments for each of the sections. We use a {@link FragmentPagerAdapter}
+        * derivative, which will keep every loaded fragment in memory. If this
+        * becomes too memory intensive, it may be best to switch to a
+        * {@link android.support.v4.app.FragmentStatePagerAdapter}.
+        */
+       SectionsPagerAdapter mSectionsPagerAdapter;
+
+       /**
+        * The {@link ViewPager} that will host the section contents.
+        */
+       ViewPager mViewPager;
+
+       private WifiManager wifiManager;
+       private WifiLock wifiLock;
+       
+       private Manager orteManager;
+       private DomainApp appDomain;
+       
+       private SettingsDialogFragment settingsDialogFragment = new SettingsDialogFragment();
+       private HelpDialogFragment helpDialogFragment = new HelpDialogFragment();
+
+       /**
+        * Setting up workspace.
+        * 
+        * @param savedInstanceState
+        * @since 1.0
+        */
+       @Override
+       protected void onCreate(Bundle savedInstanceState) {
+               super.onCreate(savedInstanceState);
+               setContentView(R.layout.activity_main);
+
+               // Create the adapter that will return a fragment for each of the three
+               // primary sections of the activity.
+               mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());
+
+               // Set up the ViewPager with the sections adapter.
+               mViewPager = (ViewPager) findViewById(R.id.pager);
+               mViewPager.setAdapter(mSectionsPagerAdapter);
+               
+               // From Robot_Demo project.
+               wifiManager = (WifiManager) getSystemService(Context.WIFI_SERVICE);
+               wifiLock = (WifiLock) wifiManager.createWifiLock((
+                                       (android.os.Build.VERSION.SDK_INT >= 12)
+                                       ? WifiManager.WIFI_MODE_FULL_HIGH_PERF
+                                       : WifiManager.WIFI_MODE_FULL
+                               ), getClass().getName());
+               
+                               
+               // Start ORTE.
+               orteManager = new Manager("");
+               appDomain = new DomainApp();
+               
+       }
+
+       /**
+        * When pause activity, release WiFi lock.
+        * 
+        * @since 1.0
+        */
+       @Override
+       public void onPause()
+       {
+               super.onPause();
+               
+               wifiLock.release();
+       }
+       
+       /**
+        * When resume activity, acquire WiFi lock.
+        * 
+        * @since 1.0
+        */
+       @Override
+       public void onResume()
+       {
+               super.onResume();
+               
+               wifiLock.acquire();
+       }
+       
+       /**
+        * When switching application off.
+        * 
+        * @since 1.0
+        */
+       @Override
+       public void onDestroy()
+       {
+               super.onDestroy();
+               
+               if (appDomain != null) {
+                       appDomain.destroy();
+                       appDomain = null;
+               }
+               if (orteManager != null) {
+                       orteManager.destroy();
+                       orteManager = null;
+               }
+       }
+       
+       /**
+        * Adding elements to menu.
+        * 
+        * @since 1.0
+        */
+       @Override
+       public boolean onCreateOptionsMenu(Menu menu) {
+               // Inflate the menu; this adds items to the action bar if it is present.
+               getMenuInflater().inflate(R.menu.main, menu);
+               return true;
+       }
+
+       /**
+        * When Settings or Help button is selected.
+        * 
+        * @since 1.0
+        */
+       @Override
+       public boolean onOptionsItemSelected(MenuItem item) {
+               // Handle action bar item clicks here. The action bar will
+               // automatically handle clicks on the Home/Up button, so long
+               // as you specify a parent activity in AndroidManifest.xml.
+               int id = item.getItemId();
+               switch (id) {
+               case R.id.action_settings:
+                       //TODO Menu Settings (prefer own activity)
+                       // Ideas about settings:
+                       // - input for manager's ip adresses
+                       // - enable/disable scaling, destination screen size
+                       
+                       settingsDialogFragment.show(getSupportFragmentManager(), "dialog");
+                       return true;
+               case R.id.action_help:
+                       //TODO Menu Help (prefer own activity)
+                       
+                       helpDialogFragment.show(getSupportFragmentManager(), "dialog");
+                       return true;
+               default:
+                       // Nothing...
+               }
+               return super.onOptionsItemSelected(item);
+       }
+
+       /**
+        * A {@link FragmentPagerAdapter} that returns a fragment corresponding to
+        * one of the sections/tabs/pages.
+        */
+       public class SectionsPagerAdapter extends FragmentPagerAdapter {
+
+               public SectionsPagerAdapter(FragmentManager fm) {
+                       super(fm);
+               }
+
+               @Override
+               public Fragment getItem(int position) {
+                       // getItem is called to instantiate the fragment for the given page.
+                       // Return a PlaceholderFragment (defined as a static inner class
+                       // below).
+                       if (position == 0) {
+                               PublisherFragment fragment = new PublisherFragment(appDomain);
+                               fragment.setHasOptionsMenu(true);
+                               return fragment;
+                       } else {
+                               SubscriberFragment fragment = new SubscriberFragment(appDomain);
+                               fragment.setHasOptionsMenu(true);
+                               return fragment;
+                       }
+               }
+
+               @Override
+               public int getCount() {
+                       // Show 2 total pages - Publisher and Subscriber
+                       return 2;
+               }
+       }
+       
+       /**
+        * Very easy help/about.
+        * 
+        * @since 1.0
+        */
+       public class HelpDialogFragment extends DialogFragment
+       {
+               /**
+                * Create dialog window.
+                * 
+                * @since 1.0
+                */
+               @Override
+               public Dialog onCreateDialog(Bundle savedInstanceState)
+               {
+                       AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
+                       builder.setTitle("Help/About")
+                               .setMessage("Under construction\n" +
+                                               "\n" +
+                                               "written by jiri hubacek\n")
+                               .setPositiveButton(R.string.dialog_OK, new DialogInterface.OnClickListener() {
+                                       @Override
+                                       public void onClick(DialogInterface dialog, int which)
+                                       {}
+                               });
+                       
+                       return builder.create();
+               }
+       }
+       
+       /**
+        * Set up IP addresses of other managers.
+        * 
+        * @since 1.0
+        */
+       public class SettingsDialogFragment extends DialogFragment
+       {
+               private EditText om;
+               
+               /**
+                * Create dialog window.
+                * 
+                * @since 1.0
+                */
+               @Override
+               public Dialog onCreateDialog(Bundle savedInstanceState)
+               {
+                       // Strings should be done better way, like
+                       // centralized in strings.xml
+                       
+                       AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
+                       builder.setTitle("Your IP is " + Formatter.formatIpAddress(wifiManager.getConnectionInfo().getIpAddress()) + ",\nadd other managers:")
+                               .setView(text())
+                               .setPositiveButton(R.string.dialog_OK, new DialogInterface.OnClickListener() {
+                                       
+                                       /**
+                                        * When IP addresses of managers changes,
+                                        * destroy manager and create new one.
+                                        * 
+                                        * @since 1.0
+                                        */
+                                       @Override
+                                       public void onClick(DialogInterface dialog, int which)
+                                       {
+                                               if (IP_ADDRESS.matcher(om.getText()).matches()) {
+                                                       if (orteManager != null) orteManager.destroy();
+                                                       
+                                                       String managers[] = new String[1];
+                                                       managers[0] = om.getText().toString();
+                                                       
+                                                       orteManager = new Manager(managers);
+                                               }
+                                       }
+                               })
+                               .setNegativeButton(R.string.dialog_cancel, new DialogInterface.OnClickListener() {
+                                       
+                                       @Override
+                                       public void onClick(DialogInterface dialog, int which) {
+                                       }
+                               });
+                       
+                       return builder.create();
+               }
+               
+               /**
+                * SeekBar for setting-up strength of publishers.
+                * 
+                * @return Layout of SeekBar.
+                * @since 1.0
+                */
+               private View text(){
+                       LinearLayout l = new LinearLayout(getActivity());
+                       l.setOrientation(LinearLayout.VERTICAL);
+                       
+                       om = new EditText(getActivity());
+                       om.setInputType(InputType.TYPE_CLASS_PHONE);
+                       om.setText("192.168.1.108");
+                       
+                       l.addView(om);
+                       return l;
+               }
+       }
+       
+}
diff --git a/orte/contrib/shape_android/src/org/ocera/orte/shape4a/PublisherFragment.java b/orte/contrib/shape_android/src/org/ocera/orte/shape4a/PublisherFragment.java
new file mode 100644 (file)
index 0000000..21faf03
--- /dev/null
@@ -0,0 +1,337 @@
+/**
+ * 
+ *     This file is part of shape4a.
+ *
+ *  shape4a is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  shape4a is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with shape4a.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+package org.ocera.orte.shape4a;
+
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.content.DialogInterface;
+import android.content.res.Configuration;
+import android.os.Bundle;
+import android.os.Handler;
+import android.support.v4.app.DialogFragment;
+import android.support.v4.app.Fragment;
+import android.view.LayoutInflater;
+import android.view.Menu;
+import android.view.MenuInflater;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.LinearLayout;
+import android.widget.SeekBar;
+
+import org.ocera.orte.DomainApp;
+
+/**
+ * Fragment containing publishing workspace.
+ * 
+ * @author jiri hubacek <jiri.hubacek@gmail.com>
+ * @version %I%, %G%
+ * @since 1.0
+ */
+public class PublisherFragment extends Fragment {
+       private static final int REDRAW_INTERVAL = 50;
+       private static final int STRENGTH_MAX = 5;
+       
+       private View rootView;
+       private PublisherView publisherView;
+       
+       private Handler handler = new Handler();
+       private Runnable redraw = new Runnable()
+       {
+               @Override
+               public void run()
+               {
+                       publisherView.countShapes();
+                       publisherView.invalidate();
+                       handler.postDelayed(this, REDRAW_INTERVAL);
+               }
+       };
+       
+       NewDialogFragment newDialogFragment = new NewDialogFragment();
+       PublisherSettingsDialogFragment publisherSettingsDialogFragment = new PublisherSettingsDialogFragment();
+       
+       private DomainApp appDomain;
+       
+       /**
+        * Constructor just stores appDomain variable.
+        * 
+        * @param appDomain
+        * @since 1.0
+        */
+       public PublisherFragment(DomainApp appDomain)
+       {
+               this.appDomain = appDomain;
+       }
+
+       /**
+        * When screen orientation is changed,
+        * scale recalculation is needed.
+        * 
+        * @since 1.0
+        */
+       @Override
+       public void onConfigurationChanged(Configuration newConfig)
+       {
+               for (PublisherShape s : this.publisherView.shapes) {
+                       s.setScale(getActivity().getWindowManager().getDefaultDisplay().getWidth(), getActivity().getWindowManager().getDefaultDisplay().getHeight());
+               }
+       }
+       
+       /**
+        * Setting up workspace, adding publisherView
+        * and timer (handler) for drawing objects.
+        * 
+        * @since 1.0
+        */
+       @Override
+       public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
+       {
+               this.rootView = inflater.inflate(R.layout.fragment_publisher, container, false);
+               this.publisherView = (PublisherView) this.rootView.findViewById(R.id.publisher_view);
+               this.handler.postDelayed(redraw, REDRAW_INTERVAL);
+               
+               return this.rootView;
+       }
+       
+       /**
+        * Creating menu.
+        * 
+        * @since 1.0
+        */
+       @Override
+       public void onCreateOptionsMenu(Menu menu, MenuInflater inflater)
+       {
+               inflater.inflate(R.menu.publisher, menu);
+       }
+       
+       /**
+        * All created publishers are in menu.
+        * 
+        * @since 1.0
+        */
+       @Override
+       public void onPrepareOptionsMenu(Menu  menu)
+       {
+               for (PublisherShape shape : publisherView.shapes) {
+                       menu.add(0, publisherView.shapes.indexOf(shape), 20 + publisherView.shapes.indexOf(shape), "#" + publisherView.shapes.indexOf(shape) + " " + shape.getColorName() + " " + shape.getShapeName());
+               }
+       }
+       
+       /**
+        * Select settings of publishers
+        * or add new publisher.
+        * 
+        * @since 1.0
+        */
+       @Override
+       public boolean onOptionsItemSelected(MenuItem item)
+       {
+               // Handle action bar item clicks here. The action bar will
+               // automatically handle clicks on the Home/Up button, so long
+               // as you specify a parent activity in AndroidManifest.xml.
+               int id = item.getItemId();
+               
+               if (id >= 0 && id < publisherView.shapes.size()) {
+                       publisherSettingsDialogFragment.setId(id);
+                       publisherSettingsDialogFragment.show(getFragmentManager(), "dialog");
+               } else {
+                       switch (id) {
+                       case R.id.action_new:
+                               newDialogFragment.show(getFragmentManager(), "dialog");
+                               break;
+                       }
+               }
+               return super.onOptionsItemSelected(item);
+       }
+       
+       /**
+        * Dialog for adding new publisher
+        * throw action bar button +.
+        * 
+        * @since 1.0
+        */
+       public class NewDialogFragment extends DialogFragment
+       {
+               /*
+                * Selection of colors is badly solved,
+                * it should be altered..
+                * 
+                */
+               private String[] colors = new String[5];
+               
+               /**
+                * In constructor, make array
+                * of colors.
+                * 
+                * @since 1.0
+                */
+               public NewDialogFragment()
+               {
+                       // Texts should be done better way,
+                       // like centralized in strings.xml
+                       
+                       colors[0] = "Blue";
+                       colors[1] = "Green";
+                       colors[2] = "Red";
+                       colors[3] = "Black";
+                       colors[4] = "Yellow";
+               }
+               
+               /**
+                * Creating dialog for new publisher.
+                * 
+                * @since 1.0
+                */
+               @Override
+               public Dialog onCreateDialog(Bundle savedInstanceState)
+               {
+                       AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
+                       builder.setTitle(R.string.dialog_newPublisher)
+                               .setItems(colors, new DialogInterface.OnClickListener()
+                               {
+                                       @Override
+                                       public void onClick(DialogInterface dialog, int which)
+                                       {
+                                               // new publisher
+                                               
+                                               publisherView.addShape(which, appDomain);
+
+                                               for (PublisherShape s : publisherView.shapes) {
+                                                       s.setScale(getActivity().getWindowManager().getDefaultDisplay().getWidth(), getActivity().getWindowManager().getDefaultDisplay().getHeight());
+                                               }
+                                               
+                                               getActivity().supportInvalidateOptionsMenu();
+                                       }
+                               })
+                               .setNegativeButton(R.string.dialog_cancel, new DialogInterface.OnClickListener()
+                               {
+                                       @Override
+                                       public void onClick(DialogInterface dialog, int which)
+                                       {       
+                                       }
+                               });
+                       return builder.create();
+                       
+               }
+       }
+       
+       /**
+        * When click on shape in Action Bar menu.
+        * 
+        * @since 1.0
+        */
+       public class PublisherSettingsDialogFragment extends DialogFragment
+       {
+               private int shapeId;
+               private int shapeStrength;
+               private SeekBar seekStrength;
+               
+               /**
+                * No constructor needed.
+                * 
+                * @since 1.0
+                */
+               public PublisherSettingsDialogFragment()
+               {}
+               
+               /**
+                * Set wanted publisher's dialog.
+                * 
+                * @param i Index of publisher.
+                * @since 1.0
+                */
+               public void setId(int i)
+               {
+                       this.shapeId = i;
+                       this.shapeStrength = publisherView.shapes.get(this.shapeId).getStrength();
+               }
+               
+               /**
+                * Creating dialog for publisher's settings.
+                * 
+                * @since 1.0
+                */
+               @Override
+               public Dialog onCreateDialog(Bundle savedInstanceState)
+               {
+                       AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
+                       builder.setTitle("#" + this.shapeId + " " + publisherView.shapes.get(this.shapeId).getColorName() + " " + publisherView.shapes.get(this.shapeId).getShapeName() + " strength:")
+                               .setView(seekBar())
+                               .setPositiveButton(R.string.dialog_OK, new DialogInterface.OnClickListener()
+                               {
+                                       @Override
+                                       public void onClick(DialogInterface dialog, int which)
+                                       {
+                                               publisherView.shapes.get(shapeId).setStrength(shapeStrength);
+                                       }
+                               })
+                               .setNeutralButton(R.string.dialog_delete, new DialogInterface.OnClickListener()
+                               {       
+                                       @Override
+                                       public void onClick(DialogInterface dialog, int which) {
+                                               publisherView.shapes.get(shapeId).killMe();
+                                               publisherView.shapes.remove(shapeId);
+                                               getActivity().supportInvalidateOptionsMenu();
+                                       }
+                               })
+                               .setNegativeButton(R.string.dialog_cancel, new DialogInterface.OnClickListener()
+                               {
+                                       @Override
+                                       public void onClick(DialogInterface dialog, int which)
+                                       {       
+                                       }
+                               });
+                       return builder.create();
+               }
+               
+               /**
+                * SeekBar for setting-up strength of publishers.
+                * 
+                * @return Layout of SeekBar.
+                * @since 1.0
+                */
+               private View seekBar(){
+                       LinearLayout l = new LinearLayout(getActivity());
+                       l.setOrientation(LinearLayout.VERTICAL);
+                       
+                       seekStrength = new SeekBar(getActivity());
+                       seekStrength.setMax(STRENGTH_MAX);
+                       seekStrength.setProgress(shapeStrength);
+                       seekStrength.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener()
+                       {
+                               @Override
+                               public void onStopTrackingTouch(SeekBar seekBar) {
+                               }
+                               
+                               @Override
+                               public void onStartTrackingTouch(SeekBar seekBar) {
+                               }
+                               
+                               @Override
+                               public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser)
+                               {
+                                       shapeStrength = progress;
+                               }
+                       });
+                       
+                       l.addView(seekStrength);
+                       return l;
+               }
+       }
+}
diff --git a/orte/contrib/shape_android/src/org/ocera/orte/shape4a/PublisherShape.java b/orte/contrib/shape_android/src/org/ocera/orte/shape4a/PublisherShape.java
new file mode 100644 (file)
index 0000000..2f90bf3
--- /dev/null
@@ -0,0 +1,331 @@
+/**
+ * 
+ *     This file is part of shape4a.
+ *
+ *  shape4a is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  shape4a is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with shape4a.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+package org.ocera.orte.shape4a;
+
+import org.ocera.orte.DomainApp;
+import org.ocera.orte.Publication;
+import org.ocera.orte.types.NtpTime;
+import org.ocera.orte.types.PublProp;
+
+import android.graphics.Color;
+import android.graphics.Path;
+import android.graphics.Path.FillType;
+import android.graphics.drawable.ShapeDrawable;
+import android.graphics.drawable.shapes.OvalShape;
+import android.graphics.drawable.shapes.PathShape;
+import android.graphics.drawable.shapes.RectShape;
+import android.graphics.drawable.shapes.Shape;
+
+/**
+ * Some additional parameters for {@link ShapeDrawable}
+ * to make it Publisher-friendly.
+ * 
+ * @author jiri hubacek <jiri.hubacek@gmail.com>
+ * @version %I%, %G%
+ * @since 1.0
+ */
+public class PublisherShape extends ShapeDrawable
+{
+       // Prefer at least 48x48 shape size (Full asset), for more
+       //  info, please refer to http://developer.android.com/
+       
+       private static final int SHAPE_WIDTH = 48;
+       private static final int SHAPE_HEIGHT = 48;
+       private boolean manual;
+       private int incX, incY;
+       
+       private PublProp publisherProperties;
+       private NtpTime persistence;
+       
+       public Publication publication;
+       public Box box;
+       
+       /**
+        * Set new {@link Shape}, strength and color.
+        * 
+        * @param s strength, shape
+        * @param c color
+        * @param appDomain
+        * @since 1.0
+        */
+       public PublisherShape(int s, int c, DomainApp appDomain)
+       {
+               super((s == 0)
+                               ?new RectShape()
+                               :((s == 1)
+                                       ?new OvalShape()
+                                       :((s == 2)
+                                               ?new PathShape(new  Path(), 96, 96)
+                                               :new RectShape()
+                                       )
+                               )
+                       );
+               
+               if (s == 2) { // fix triangle
+                       this.setShape(new PathShape(PublisherShape.returnTrianglePath(), 96, 96));
+               }
+               
+               this.manual = false;
+               this.persistence = new NtpTime(5);
+
+               this.box = new Box(appDomain, PublisherShape.getColorName(c));
+               this.publisherProperties = new PublProp(this.box.getTopic(),
+                               "Box",
+                               this.persistence,
+                               s+1);
+               this.publication = appDomain.createPublication(this.publisherProperties, this.box);
+               
+               this.box.strength = s;
+               this.box.color = c;
+
+               this.getPaint().setColor(PublisherShape.getColorConstant(c));
+               this.setPadding(0, 0, 0, 0);
+               this.setBounds(0, 0, SHAPE_WIDTH, SHAPE_HEIGHT);
+               
+               //Log.d("PublisherShape", "s: "+s+", c: "+c+", left: "+this.getBounds().left+", top: "+this.getBounds().top+", right: "+this.getBounds().right+", bottom: "+this.getBounds().bottom);
+       }
+       
+       /**
+        * Update parameters of object to send.
+        * 
+        * @return Object to send.
+        * @since 1.0
+        */
+       public Box toSend()
+       {
+               this.box.rectangle.top_left_x = (short) this.getBounds().left;
+               this.box.rectangle.top_left_y = (short) this.getBounds().top;
+               this.box.rectangle.bottom_right_x = (short) this.getBounds().right;
+               this.box.rectangle.bottom_right_y = (short) this.getBounds().bottom;
+               
+               return this.box;
+       }
+       
+       /**
+        * Revert proprietary color to android color constant.
+        * 
+        * @param c Proprietary value of color.
+        * @return Android color constant.
+        * @since 1.0
+        */
+       public static int getColorConstant(int c)
+       {
+               switch (c) {
+               case 0:
+                       return Color.BLUE;
+               case 1:
+                       return Color.GREEN;
+               case 2:
+                       return Color.RED;
+               case 3:
+                       return Color.BLACK;
+               case 4:
+                       return Color.YELLOW;
+               default:
+                       return 0;
+               }
+       }
+       
+       /**
+        * Revert proprietary color to android color constant.
+        * 
+        * @return Android color constant.
+        * @since 1.0
+        */
+       public int getColorConstant()
+       {
+               return PublisherShape.getColorConstant(this.box.color);
+       }
+       
+       /**
+        * Revert proprietary color to word.
+        * 
+        * @param c Proprietary value of color.
+        * @return Name of color.
+        * @since 1.0
+        */
+       public static String getColorName(int c)
+       {
+               // should be done better way
+               // texts shouldn't be static
+               // but dynamically mapped to
+               // strings.xml
+               
+               switch (c) {
+               case 0:
+                       return "Blue";
+               case 1:
+                       return "Green";
+               case 2:
+                       return "Red";
+               case 3:
+                       return "Black";
+               case 4:
+                       return "Yellow";
+               default:
+                       return "NONE";
+               }
+       }
+       
+       /**
+        * Revert proprietary color to word.
+        * 
+        * @return Name of color.
+        * @since 1.0
+        */
+       public String getColorName()
+       {
+               return PublisherShape.getColorName(this.box.color);
+       }
+       
+       /**
+        * Revert strength to shape.
+        * 
+        * @return Name of shape.
+        * @since 1.0
+        */
+       public String getShapeName()
+       {
+               switch (this.box.strength) {
+               case 0:
+                       return "Square";
+               case 1:
+                       return "Circle";
+               case 2:
+                       return "Triangle";
+               default:
+                       return "NONE";
+               }
+       }
+       
+       /* getters, setters */
+       
+       /**
+        * Set value of incX - how much move object
+        * in x-axis direction.
+        * 
+        * @param x
+        * @since 1.0
+        */
+       public void setIncX(int x) { this.incX = x; }
+       /**
+        * Get value of incX - how much move object
+        * in x-axis direction.
+        * 
+        * @return Distance to move in x-axis. 
+        * @since 1.0
+        */
+       public int getIncX() { return this.incX; }
+       
+       /**
+        * Set value of incY - how much move object
+        * in y-axis direction.
+        * 
+        * @param y
+        * @since 1.0
+        */
+       public void setIncY(int y) { this.incY = y; }
+       /**
+        * Get value of incY - how much move object
+        * in y-axis direction.
+        * 
+        * @return Distance to move in y-axis. 
+        * @since 1.0
+        */
+       public int getIncY() { return this.incY; }
+       
+       /**
+        * Set strength of publishing.
+        * 
+        * @param s
+        * @since 1.0
+        */
+       public void setStrength(int s) {
+               PublProp properties = this.publication.getProperties();
+               properties.setStrength(s);
+               this.publication.setProperties(properties);
+       }
+       /**
+        * Get strength of publishing.
+        * 
+        * @return Strength of publishing.
+        * @since 1.0
+        */
+       public int getStrength() { return this.publication.getProperties().getStrength(); }
+       
+       /**
+        * Set if object is moved automatically or by
+        * user.
+        *      TRUE - by user
+        *  FALSE - automatically
+        *  
+        * @param b
+        * @since 1.0
+        */
+       public void setManual(boolean b) { this.manual = b; }
+       /**
+        * Get if object is moved automatically or by
+        * user.
+        * 
+        * @return How is object moved.
+        * @since 1.0
+        */
+       public boolean getManual() { return this.manual; }
+
+       /**
+        * Make triangle path for new instance.
+        * 
+        * @return Triangle path.
+        * @since 1.0
+        */
+       public static Path returnTrianglePath()
+       {
+               Path path = new Path();
+               path.setFillType(FillType.EVEN_ODD);
+               path.moveTo(48, 0);
+               path.lineTo(96, 96);
+               path.lineTo(0, 96);
+               path.lineTo(48, 0);
+               path.close();
+               
+               return path;
+       }
+       
+       /**
+        * When publisher is removed, destroy publication.
+        * 
+        * @since 1.0
+        */
+       public void killMe()
+       {
+               this.publication.destroy();
+       }
+       
+       /**
+        * Pass parameters to box.
+        * 
+        * @param currentWidth
+        * @param currentHeight
+        * @since 1.0
+        */
+       public void setScale(int currentWidth, int currentHeight)
+       {
+               this.box.setScale(currentWidth, currentHeight);
+       }
+}
diff --git a/orte/contrib/shape_android/src/org/ocera/orte/shape4a/PublisherView.java b/orte/contrib/shape_android/src/org/ocera/orte/shape4a/PublisherView.java
new file mode 100644 (file)
index 0000000..d079a93
--- /dev/null
@@ -0,0 +1,176 @@
+/**
+ * 
+ *     This file is part of shape4a.
+ *
+ *  shape4a is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  shape4a is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with shape4a.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+package org.ocera.orte.shape4a;
+
+import java.util.ArrayList;
+import java.util.Random;
+
+import android.content.Context;
+import android.graphics.Canvas;
+import android.util.AttributeSet;
+import android.view.MotionEvent;
+import android.view.View;
+
+import org.ocera.orte.DomainApp;
+
+/**
+ * View, where publisher objects are drawn.
+ * 
+ * @author jiri hubacek <jiri.hubacek@gmail.com>
+ * @version %I%, %G%
+ * @since 1.0
+ */
+public class PublisherView extends View
+{
+       private static final int STEP_X = 2;
+       private static final int STEP_Y = 2;
+
+       public ArrayList<PublisherShape> shapes = new ArrayList<PublisherShape>();
+       
+       private Random random = new Random();
+       
+       /**
+        * Just compatibility method.
+        * 
+        * @param context
+        * @param attrs
+        * @since 1.0
+        */
+       public PublisherView(Context context, AttributeSet attrs)
+       {
+               super(context, attrs);
+       }
+       
+       /**
+        * Update publisher shape's position.
+        * 
+        * @since 1.0
+        */
+       public void countShapes()
+       {
+               for (PublisherShape shape : shapes) {
+                       if (!shape.getManual()) {
+                               if (shape.getBounds().left <= 0) shape.setIncX(STEP_X);
+                               if (shape.getBounds().top <= 0) shape.setIncY(STEP_Y);
+                               if (shape.getBounds().right >= getWidth()) shape.setIncX(-STEP_X);
+                               if (shape.getBounds().bottom >= getHeight()) shape.setIncY(-STEP_Y);
+                       } else {
+                               shape.setIncX(0);
+                               shape.setIncY(0);
+                       }
+                       
+                       shape.setBounds(shape.getBounds().left + shape.getIncX(), shape.getBounds().top + shape.getIncY(), shape.getBounds().right + shape.getIncX(), shape.getBounds().bottom + shape.getIncY());
+                       shape.publication.send(shape.toSend());
+               }
+       }       
+       
+       /**
+        * Draw all publisher objects.
+        * 
+        * @since 1.0
+        */
+       @Override
+       protected void onDraw(Canvas canvas)
+       {
+               for (PublisherShape shape : shapes) {
+                       shape.draw(canvas);
+               }
+       }
+
+       @Override
+       public boolean performClick()
+       {
+               return super.performClick();
+       }
+       
+       /**
+        * When touch the publisher object, start manual
+        * mode and let user change position of object. When
+        * user finishes, just generate random direction and
+        * let object moving automatically again.
+        * 
+        * @since 1.0
+        */
+       @Override
+       public boolean onTouchEvent(MotionEvent event)
+       {
+               int myX = 0, myY = 0;
+               
+               switch (event.getActionMasked()) {
+               case MotionEvent.ACTION_DOWN:
+                       myX = (int) event.getX();
+                       myY = (int) event.getY();
+                       
+                       for (PublisherShape shape : shapes) {
+                               if (myX <= shape.getBounds().right
+                                               && myX >= shape.getBounds().left
+                                               && myY >= shape.getBounds().top
+                                               && myY <= shape.getBounds().bottom) {
+                                       shape.setManual(true);
+                                       break;
+                               }
+                       }
+                       
+                       return true;
+               case MotionEvent.ACTION_MOVE:
+                       myX = (int) event.getX();
+                       myY = (int) event.getY();
+                       
+                       for (PublisherShape shape : shapes) {
+                               if (shape.getManual()) {
+                                       shape.setBounds((int) (myX - shape.getShape().getWidth()/2), (int) (myY - shape.getShape().getHeight()/2), (int) (myX + shape.getShape().getWidth()/2), (int) (myY + shape.getShape().getHeight()/2));
+                                       break;
+                               }
+                       }
+                       
+                       return true;
+               case MotionEvent.ACTION_UP:
+                       myX = (int) event.getX();
+                       myY = (int) event.getY();
+                       
+                       for (PublisherShape shape : shapes) {
+                               if (myX <= shape.getBounds().right
+                                               && myX >= shape.getBounds().left
+                                               && myY >= shape.getBounds().top
+                                               && myY <= shape.getBounds().bottom) {
+                                       shape.setManual(false);
+                                       shape.setIncX(STEP_X * (1 -2*random.nextInt(2)));
+                                       shape.setIncY(STEP_Y * (1 -2*random.nextInt(2)));
+                               }
+                       }
+                       
+                       return true;
+               default:
+                       return super.onTouchEvent(event) || this.performClick();
+               }
+       }
+       
+       /**
+        * When OK is selected on {@link NewDialogFragment},
+        * this method is called to add new publisher object.
+        *  
+        * @param color
+        * @param appDomain
+        * @since 1.0
+        */
+       public void addShape(int color, DomainApp appDomain)
+       {
+               this.shapes.add(new PublisherShape(random.nextInt(3), color, appDomain));
+       }
+}
diff --git a/orte/contrib/shape_android/src/org/ocera/orte/shape4a/SubscriberElement.java b/orte/contrib/shape_android/src/org/ocera/orte/shape4a/SubscriberElement.java
new file mode 100644 (file)
index 0000000..6a635f5
--- /dev/null
@@ -0,0 +1,227 @@
+/**
+ * 
+ *     This file is part of shape4a.
+ *
+ *  shape4a is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  shape4a is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with shape4a.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+package org.ocera.orte.shape4a;
+
+import android.graphics.Canvas;
+import android.graphics.drawable.ShapeDrawable;
+import android.graphics.drawable.shapes.OvalShape;
+import android.graphics.drawable.shapes.PathShape;
+import android.graphics.drawable.shapes.RectShape;
+import android.view.View;
+
+import org.ocera.orte.DomainApp;
+import org.ocera.orte.Subscription;
+import org.ocera.orte.SubscriptionCallback;
+import org.ocera.orte.types.MessageData;
+import org.ocera.orte.types.NtpTime;
+import org.ocera.orte.types.RecvInfo;
+import org.ocera.orte.types.SubsProp;
+import org.ocera.orte.types.ORTEConstant;
+
+/**
+ * Subscribing objects are made by this class.
+ * 
+ * @author jiri hubacek <jiri.hubacek@gmail.com>
+ * @version %I%, %G%
+ * @since 1.0
+ */
+public class SubscriberElement extends SubscriptionCallback
+{
+       private Subscription subscription;
+       
+       private NtpTime deadline;
+       private NtpTime minSeparation;
+       
+       private Box box;
+       private ShapeDrawable shape;
+       
+       private View parentView;
+       
+       private boolean receiving;
+       private boolean enabled;
+
+       /**
+        * Set default variables of subscriber's object.
+        * 
+        * @param appDomain
+        * @param color Topic is dependent on color.
+        * @since 1.0
+        */
+       public SubscriberElement(DomainApp appDomain, int color, View v) {
+               this.deadline = new NtpTime(6);
+               this.minSeparation = new NtpTime(0);
+               
+               this.box = new Box(appDomain, PublisherShape.getColorName(color));
+               SubsProp subscriberProperties = new SubsProp(this.box.getTopic(),
+                               "Box",
+                               this.minSeparation,
+                               this.deadline,
+                               ORTEConstant.IMMEDIATE,
+                               ORTEConstant.BEST_EFFORTS,
+                               0);
+               
+               this.subscription = appDomain.createSubscription(subscriberProperties, this.box, this);
+               
+               this.shape = new ShapeDrawable();
+               this.shape.getPaint().setColor(PublisherShape.getColorConstant(color));
+               
+               this.setShape();
+               
+               this.parentView = v;
+               
+               this.enabled = true;
+       }
+       
+       /**
+        * What should be done when new data are received.
+        * 
+        * @param info
+        * @param msg
+        * @since 1.0
+        */
+       public void callback(RecvInfo info, MessageData msg)
+       {
+               switch (info.getRecvStatus()) {
+               case ORTEConstant.NEW_DATA:
+                       this.receiving = true;
+                       //Log.d("SubscriberElement", "new data: " + (int) ((Box) msg).strength + "(was "+ this.box.strength +"); " + ((Box) msg).rectangle.top_left_x + ", " + ((Box) msg).rectangle.top_left_y + ", "  +((Box) msg).rectangle.bottom_right_x + ", " + ((Box) msg).rectangle.bottom_right_y);
+                       
+                       this.shape.getBounds().left = this.box.rectangle.top_left_x;
+                       this.shape.getBounds().top = this.box.rectangle.top_left_y;
+                       this.shape.getBounds().right = this.box.rectangle.bottom_right_x;
+                       this.shape.getBounds().bottom = this.box.rectangle.bottom_right_y;
+                       
+                       this.setShape();
+
+                       this.parentView.postInvalidate();
+                       break;
+               case ORTEConstant.DEADLINE:
+                       this.receiving = false;
+                       this.parentView.postInvalidate();
+                       break;
+               }
+       }
+       
+       /**
+        * Draw shape, which is private object.
+        * 
+        * @param canvas
+        * @since 1.0
+        */
+       public void drawMe(Canvas canvas)
+       {
+               this.shape.draw(canvas);
+       }
+       
+       /**
+        * Set desired shape of object.
+        * 
+        * @since 1.0
+        */
+       public void setShape()
+       {
+               switch (this.box.strength) {
+               case 0:
+                       this.shape.setShape(new RectShape());
+                       break;
+               case 1:
+                       this.shape.setShape(new OvalShape());
+                       break;
+               case 2:
+                       this.shape.setShape(new PathShape(PublisherShape.returnTrianglePath(), 96, 96));
+                       break;
+               default:
+                       this.shape.setShape(new RectShape());
+               }
+       }
+       
+       /**
+        * Getter for enabled value. Should be object
+        * drawn or not?
+        * 
+        * @return Enabled?
+        * @since 1.0
+        */
+       public boolean getEnabled()     { return this.enabled; }
+       
+       /**
+        * Set value enabled. Should be object
+        * drawn or not?
+        * 
+        * @param b Enable?
+        * @since 1.0
+        */
+       public void setEnabled(boolean b) { this.enabled = b; }
+
+       /**
+        * Getter for receiving value. Should be object
+        * drawn or not?
+        * 
+        * @return Receiving?
+        * @since 1.0
+        */
+       public boolean getReceiving()   { return this.receiving; }
+       
+       /**
+        * Set value receiving. Should be object
+        * drawn or not?
+        * 
+        * @param b Receiving?
+        * @since 1.0
+        */
+       public void setReceiving(boolean b) { this.receiving = b; }
+       
+       /**
+        * Min. Separation value is used for desired update delay.
+        * 
+        * @return NtpTime value of Min. Separation.
+        * @since 1.0
+        */
+       public NtpTime getMinSeparation()
+       {
+               return this.subscription.getProperties().getMinSeparation();
+       }
+       
+       /**
+        * Min. Separation value is used for desired update delay,
+        * this is setter for this value.
+        * 
+        * @param newMinSeparation
+        * @since 1.0
+        */
+       public void setMinSeparation(NtpTime newMinSeparation)
+       {
+               SubsProp properties = this.subscription.getProperties();
+               properties.setMinSeparation(newMinSeparation);
+               this.subscription.setProperties(properties);
+       }
+       
+       /**
+        * Pass parameters to box.
+        * 
+        * @param currentWidth
+        * @param currentHeight
+        * @since 1.0
+        */
+       public void setScale(int currentWidth, int currentHeight)
+       {
+               this.box.setScale(currentWidth, currentHeight);
+       }
+
+}
diff --git a/orte/contrib/shape_android/src/org/ocera/orte/shape4a/SubscriberFragment.java b/orte/contrib/shape_android/src/org/ocera/orte/shape4a/SubscriberFragment.java
new file mode 100644 (file)
index 0000000..5818e6d
--- /dev/null
@@ -0,0 +1,246 @@
+/**
+ * 
+ *     This file is part of shape4a.
+ *
+ *  shape4a is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  shape4a is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with shape4a.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+package org.ocera.orte.shape4a;
+
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.content.DialogInterface;
+import android.content.res.Configuration;
+import android.os.Bundle;
+import android.support.v4.app.DialogFragment;
+import android.support.v4.app.Fragment;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.Menu;
+import android.view.MenuInflater;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.LinearLayout;
+import android.widget.SeekBar;
+
+import org.ocera.orte.DomainApp;
+import org.ocera.orte.types.NtpTime;
+
+/**
+ * Fragment containing subscribing workspace.
+ * 
+ * @author jiri hubacek <jiri.hubacek@gmail.com>
+ * @version %I%, %G%
+ * @since 1.0
+ */
+public class SubscriberFragment extends Fragment {
+       private static final int MINSEPARATION_MAX = 5;
+       
+       private View rootView;
+       private SubscriberView subscriberView;
+       private DomainApp appDomain;
+       
+       private SubscriberSettingsDialogFragment subscriberSettingsDialogFragment = new SubscriberSettingsDialogFragment();
+       
+       /**
+        * Constructor just stores appDomain variable.
+        * 
+        * @param appDomain
+        * @since 1.0
+        */
+       public SubscriberFragment(DomainApp appDomain)
+       {
+               this.appDomain = appDomain;
+       }
+       
+       /**
+        * When screen orientation is changed,
+        * scale recalculation is needed.
+        * 
+        * @since 1.0
+        */
+       @Override
+       public void onConfigurationChanged(Configuration newConfig)
+       {
+               for (SubscriberElement e : this.subscriberView.elements) {
+                       e.setScale(getActivity().getWindowManager().getDefaultDisplay().getWidth(), getActivity().getWindowManager().getDefaultDisplay().getHeight());
+               }
+       }
+       
+       /**
+        * Setting up workspace, adding publisherView
+        * and timer (handler) for drawing objects.
+        * 
+        * @since 1.0
+        */
+       @Override
+       public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
+               
+               this.rootView = inflater.inflate(R.layout.fragment_subscriber, container, false);
+               this.subscriberView = (SubscriberView) this.rootView.findViewById(R.id.subscriber_view);
+               this.subscriberView.addElements(this.appDomain);
+               for (SubscriberElement e : this.subscriberView.elements) {
+                       e.setScale(getActivity().getWindowManager().getDefaultDisplay().getWidth(), getActivity().getWindowManager().getDefaultDisplay().getHeight());
+               }
+               return this.rootView;
+       }
+       
+       /**
+        * Creating menu.
+        * 
+        * @since 1.0
+        */
+       @Override
+       public void onCreateOptionsMenu(Menu menu, MenuInflater inflater)
+       {
+               inflater.inflate(R.menu.subscriber, menu);
+       }
+       
+       /**
+        * Setting up subscriber objects.
+        * 
+        * @since 1.0
+        */
+       @Override
+       public boolean onOptionsItemSelected(MenuItem item)
+       {
+               int id = 0;
+               switch (item.getItemId()) {
+               case R.id.action_blue:
+                       id = 0;
+                       break;
+               case R.id.action_green:
+                       id = 1;
+                       break;
+               case R.id.action_red:
+                       id = 2;
+                       break;
+               case R.id.action_black:
+                       id = 3;
+                       break;
+               case R.id.action_yellow:
+                       id = 4;
+                       break;
+               default:
+               }
+               
+               subscriberSettingsDialogFragment.setId(id);
+               subscriberSettingsDialogFragment.show(getFragmentManager(), "dialog");
+               
+               return super.onOptionsItemSelected(item);
+       }
+       
+       /**
+        * When click on shape in Action Bar menu.
+        * 
+        * @since 1.0
+        */
+       public class SubscriberSettingsDialogFragment extends DialogFragment
+       {
+               private int eId, ms;
+               private NtpTime minSeparation;
+               private SeekBar seekMinSeparation;
+               
+               /**
+                * Set wanted publisher's dialog.
+                * 
+                * @param i Index of publisher.
+                * @since 1.0
+                */
+               public void setId(int i)
+               {
+                       this.eId = i;
+                       this.minSeparation = subscriberView.elements.get(this.eId).getMinSeparation();
+                       this.ms = 0;
+               }
+               
+               /**
+                * Creating dialog for subscriber's settings.
+                * 
+                * @since 1.0
+                */
+               @Override
+               public Dialog onCreateDialog(Bundle savedInstanceState)
+               {
+                       AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
+                       builder.setTitle(PublisherShape.getColorName(this.eId) + " settings")
+                               .setView(seekBar())
+                               .setPositiveButton(R.string.dialog_OK, new DialogInterface.OnClickListener()
+                               {
+                                       @Override
+                                       public void onClick(DialogInterface dialog, int which)
+                                       {
+                                               minSeparation = new NtpTime(ms);
+                                               subscriberView.elements.get(eId).setMinSeparation(minSeparation);
+                                               subscriberView.elements.get(eId).setEnabled(true);
+                                       }
+                               })
+                               .setNeutralButton(subscriberView.elements.get(eId).getEnabled()?R.string.dialog_delete:R.string.dialog_add, new DialogInterface.OnClickListener()
+                               {       
+                                       @Override
+                                       public void onClick(DialogInterface dialog, int which) {
+                                               if (subscriberView.elements.get(eId).getEnabled()) {
+                                                       subscriberView.elements.get(eId).setEnabled(false);
+                                               } else {
+                                                       minSeparation = new NtpTime(ms);
+                                                       subscriberView.elements.get(eId).setMinSeparation(minSeparation);
+                                                       subscriberView.elements.get(eId).setEnabled(true);
+                                               }
+                                       }
+                               })
+                               .setNegativeButton(R.string.dialog_cancel, new DialogInterface.OnClickListener()
+                               {
+                                       @Override
+                                       public void onClick(DialogInterface dialog, int which)
+                                       {}
+                               });
+                       return builder.create();
+               }
+               
+               /**
+                * SeekBar for setting-up min. separation of subscribers.
+                * 
+                * @return Layout of SeekBar.
+                * @since 1.0
+                */
+               private View seekBar(){
+                       LinearLayout l = new LinearLayout(getActivity());
+                       l.setOrientation(LinearLayout.VERTICAL);
+                       
+                       seekMinSeparation = new SeekBar(getActivity());
+                       seekMinSeparation.setMax(MINSEPARATION_MAX);
+                       seekMinSeparation.setProgress(0);
+                       seekMinSeparation.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener()
+                       {
+                               @Override
+                               public void onStopTrackingTouch(SeekBar seekBar) {
+                               }
+                               
+                               @Override
+                               public void onStartTrackingTouch(SeekBar seekBar) {
+                               }
+                               
+                               @Override
+                               public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser)
+                               {
+                                       ms = progress;
+                               }
+                       });
+                       
+                       l.addView(seekMinSeparation);
+                       return l;
+               }
+       }
+}
diff --git a/orte/contrib/shape_android/src/org/ocera/orte/shape4a/SubscriberView.java b/orte/contrib/shape_android/src/org/ocera/orte/shape4a/SubscriberView.java
new file mode 100644 (file)
index 0000000..3d8de08
--- /dev/null
@@ -0,0 +1,74 @@
+/**
+ * 
+ *     This file is part of shape4a.
+ *
+ *  shape4a is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  shape4a is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with shape4a.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+package org.ocera.orte.shape4a;
+
+import java.util.ArrayList;
+
+import android.content.Context;
+import android.graphics.Canvas;
+import android.util.AttributeSet;
+import android.view.View;
+
+import org.ocera.orte.DomainApp;
+
+/**
+ * View, where subscriber objects are drawn.
+ * 
+ * @author jiri hubacek <jiri.hubacek@gmail.com>
+ * @version %I%, %G%
+ * @since 1.0
+ */
+public class SubscriberView extends View {
+       public ArrayList<SubscriberElement> elements = new ArrayList<SubscriberElement>();
+       
+       /**
+        * Default constructor.
+        * 
+        * @param context
+        * @param attrs
+        */
+       public SubscriberView(Context context, AttributeSet attrs) {
+               super(context, attrs);
+       }
+       
+       /**
+        * When drawing, draw all subscribers shapes.
+        * 
+        * @param canvas
+        */
+       @Override
+       protected void onDraw(Canvas canvas)
+       {
+               for (SubscriberElement element : elements) {
+                       if (element.getReceiving() && element.getEnabled()) element.drawMe(canvas);
+               }
+       }
+       
+       /**
+        * Make objects of all colors ready to subscribe.
+        * 
+        * @param appDomain
+        */
+       public void addElements(DomainApp appDomain)
+       {
+               for (int i = 0; i < 5; i++) {
+                       this.elements.add(new SubscriberElement(appDomain, i, this));
+               }
+       }
+}