]> rtime.felk.cvut.cz Git - orte.git/blob - orte/contrib/shape_android/src/org/ocera/orte/shape_android/PublisherActivity.java
7725783308e6bb42c44a253fce9ec85990a8a6af
[orte.git] / orte / contrib / shape_android / src / org / ocera / orte / shape_android / PublisherActivity.java
1 /**
2  * 
3  *      This file is part of shape_android.
4  *
5  *  shape_android is free software: you can redistribute it and/or modify
6  *  it under the terms of the GNU General Public License as published by
7  *  the Free Software Foundation, either version 3 of the License, or
8  *  (at your option) any later version.
9  *
10  *  shape_android is distributed in the hope that it will be useful,
11  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  *  GNU General Public License for more details.
14  *
15  *  You should have received a copy of the GNU General Public License
16  *  along with shape_android.  If not, see <http://www.gnu.org/licenses/>.
17  *
18  */
19 package org.ocera.orte.shape_android;
20
21 import java.util.regex.Pattern;
22
23 import org.ocera.orte.DomainApp;
24 import org.ocera.orte.Manager;
25 import org.ocera.orte.types.NtpTime;
26
27 import android.annotation.SuppressLint;
28 import android.app.Activity;
29 import android.app.AlertDialog;
30 import android.content.Context;
31 import android.content.DialogInterface;
32 import android.content.Intent;
33 import android.content.SharedPreferences;
34 import android.content.res.Configuration;
35 import android.net.wifi.WifiManager;
36 import android.net.wifi.WifiManager.WifiLock;
37 import android.os.Bundle;
38 import android.os.Handler;
39 import android.preference.PreferenceManager;
40 import android.view.Menu;
41 import android.view.MenuItem;
42 import android.widget.LinearLayout;
43 import android.widget.SeekBar;
44 import android.widget.ViewSwitcher;
45
46 /**
47  * Class for object sent and received throw the ORTE middleware.
48  * 
49  * @author jiri hubacek <jiri.hubacek@gmail.com>
50  * @version %I, %G
51  * @since 1.2
52  */
53 public class PublisherActivity extends Activity {
54         //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]?))");
55
56         private static final int REDRAW_INTERVAL = 50;
57         private static final int STRENGTH_MAX = 5;
58         private static final int MINSEPARATION_MAX = 5;
59         private static final int RESULT_SETTINGS = 1;
60         
61         private WifiManager wifiManager;
62         private WifiLock wifiLock;
63         
64         private Manager orteManager;
65         private DomainApp appDomain;
66         
67         private PublisherView publisherView;
68         private SubscriberView subscriberView;
69         
70         private ViewSwitcher switcher;
71         private boolean actualIsPublisher;
72         private SharedPreferences sp;
73         
74         private Handler handler = new Handler();
75         private Runnable redraw = new Runnable()
76         {
77                 @Override
78                 public void run()
79                 {
80                         publisherView.countShapes();
81                         publisherView.invalidate();
82                         handler.postDelayed(this, REDRAW_INTERVAL);
83                 }
84         };
85         
86         /**
87          * Setting up main workspace.
88          * 
89          * @since 1.2
90          */
91         @Override
92         protected void onCreate(Bundle savedInstanceState) {
93                 super.onCreate(savedInstanceState);
94                 setContentView(R.layout.activity_publisher);
95                 
96                 // From Robot_Demo project.
97                 wifiManager = (WifiManager) getSystemService(Context.WIFI_SERVICE);
98                 wifiLock = (WifiLock) wifiManager.createWifiLock((
99                                         (android.os.Build.VERSION.SDK_INT >= 12)
100                                         ? WifiManager.WIFI_MODE_FULL_HIGH_PERF
101                                         : WifiManager.WIFI_MODE_FULL
102                                 ), getClass().getName());
103
104                 sp = PreferenceManager.getDefaultSharedPreferences(getBaseContext());
105                 
106                 // Start ORTE.
107                 orteManager = new Manager(sp.getString("prefManagers", ""));
108                 appDomain = new DomainApp();
109                 
110                 this.switcher = (ViewSwitcher) findViewById(R.id.switcher);
111                 this.actualIsPublisher = true;
112                 
113                 this.publisherView = (PublisherView) findViewById(R.id.publisher_view);
114                 this.subscriberView = (SubscriberView) findViewById(R.id.subscriber_view);
115                 
116                 this.redraw.run();
117                 this.subscriberView.addElements(this.appDomain);
118                 for (SubscriberElement e : this.subscriberView.elements) {
119                         e.setScale(this.getWindowManager().getDefaultDisplay().getWidth(), this.getWindowManager().getDefaultDisplay().getHeight());
120                         e.setAllowScaling(sp.getBoolean("prefScaling", true));
121                 }
122         }
123
124         /**
125          * When pause activity, release WiFi lock.
126          * 
127          * @since 1.0
128          */
129         @Override
130         public void onPause()
131         {
132                 super.onPause();
133                 
134                 wifiLock.release();
135         }
136         
137         /**
138          * When resume activity, acquire WiFi lock.
139          * 
140          * @since 1.0
141          */
142         @Override
143         public void onResume()
144         {
145                 super.onResume();
146                 
147                 wifiLock.acquire();
148         }
149         
150         /**
151          * When switching application off.
152          * 
153          * @since 1.0
154          */
155         @Override
156         public void onDestroy()
157         {
158                 super.onDestroy();
159                 
160                 if (appDomain != null) {
161                         appDomain.destroy();
162                         appDomain = null;
163                 }
164                 if (orteManager != null) {
165                         orteManager.destroy();
166                         orteManager = null;
167                 }
168         }
169         
170         /**
171          * When screen orientation is changed,
172          * scale recalculation is needed.
173          * 
174          * @since 1.0
175          */
176         @Override
177         public void onConfigurationChanged(Configuration newConfig)
178         {
179                 super.onConfigurationChanged(newConfig);
180                 
181                 for (PublisherShape s : this.publisherView.shapes) {
182                         s.setScale(this.getWindowManager().getDefaultDisplay().getWidth(), this.getWindowManager().getDefaultDisplay().getHeight());
183                 }
184                 for (SubscriberElement e : this.subscriberView.elements) {
185                         e.setScale(this.getWindowManager().getDefaultDisplay().getWidth(), this.getWindowManager().getDefaultDisplay().getHeight());
186                 }
187                 
188                 //TODO  When change rotation in Subscriber view,
189                 //              there is no change in Publisher view, which
190                 //              leads to misbehavior. For example, there
191                 //              is Publisher of Black color in Publisher view,
192                 //              and we are looking at it in Subscriber view,
193                 //              when rotation is changed, Publisher view remains
194                 //              in old rotation while Subscriber view is in new
195                 //              rotation. Therefore Black Publisher thinks that
196                 //              it's still in old rotation and the problem with
197                 //              leaving screen is here.
198         }
199
200         /**
201          * When returning from SettingsActivity, apply settings.
202          * 
203          * @since 1.2
204          */
205     @Override
206     protected void onActivityResult(int requestCode, int resultCode, Intent data)
207     {
208             super.onActivityResult(requestCode, resultCode, data);
209         
210             switch(requestCode) {
211             case RESULT_SETTINGS:
212                 boolean allowScaling = sp.getBoolean("prefScaling", true);
213
214                         for (PublisherShape s : this.publisherView.shapes) {
215                                 s.box.allowScaling = allowScaling;
216                         }
217                 for (SubscriberElement e : this.subscriberView.elements) {
218                                 e.setAllowScaling(allowScaling);
219                         }
220                 
221                 if (orteManager != null) orteManager.destroy();
222                         orteManager = new Manager(sp.getString("prefManagers", ""));
223                         
224                 break;
225             }
226
227     }
228     
229     /**
230      * Creating menu.
231      * 
232      * @since 1.2
233      */
234         @Override
235         public boolean onCreateOptionsMenu(Menu menu) {
236                 // Inflate the menu; this adds items to the action bar if it is present.
237                 getMenuInflater().inflate(R.menu.publisher, menu);
238                 return true;
239         }
240         
241         /**
242          * All created publishers are in menu.
243          * @return 
244          * 
245          * @since 1.0
246          */
247         @Override
248         public boolean onPrepareOptionsMenu(Menu menu)
249         {
250                 menu.clear();
251                 
252                 if (this.actualIsPublisher) {
253                         getMenuInflater().inflate(R.menu.publisher, menu);
254                         for (PublisherShape shape : this.publisherView.shapes) {
255                                 menu.add(0, this.publisherView.shapes.indexOf(shape), 20 + this.publisherView.shapes.indexOf(shape), "#" + this.publisherView.shapes.indexOf(shape) + " " + shape.getColorName() + " " + shape.getShapeName());
256                         }
257                 } else {
258                         getMenuInflater().inflate(R.menu.subscriber, menu);
259                 }
260                 
261                 return super.onPrepareOptionsMenu(menu);
262         }
263         
264         /**
265          * Logic for menu selecting.
266          * 
267          * Contains switching between Publishers and Subscribers, adding
268          * new Publisher, setting Publishers, setting Subscribers, moving
269          * to SettingsActivity and HelpActivity.
270          * 
271          * @since 1.2
272          */
273         @SuppressLint("NewApi")
274         @Override
275         public boolean onOptionsItemSelected(MenuItem item) {
276                 // Handle action bar item clicks here. The action bar will
277                 // automatically handle clicks on the Home/Up button, so long
278                 // as you specify a parent activity in AndroidManifest.xml.
279                 final int id = item.getItemId();
280                 final Activity me = this;
281                 Intent intent;
282                 
283                 switch(id) {
284                 case R.id.action_switch:
285                         if (this.actualIsPublisher) {
286                                 this.switcher.showNext();
287                                 this.setTitle(R.string.title_activity_subscriber);
288                         } else {
289                                 this.switcher.showPrevious();
290                                 this.setTitle(R.string.title_activity_publisher);
291                         }
292                         this.actualIsPublisher = !this.actualIsPublisher;
293                         
294                         if (android.os.Build.VERSION.SDK_INT >= 11) this.invalidateOptionsMenu();
295                         
296                         return true;
297                 case R.id.action_new:
298                         String[] colors = new String[5];
299                         
300                         colors[0] = "Blue";
301                         colors[1] = "Green";
302                         colors[2] = "Red";
303                         colors[3] = "Black";
304                         colors[4] = "Yellow";
305                         
306                         AlertDialog.Builder builderNew = new AlertDialog.Builder(me);
307                         builderNew.setTitle(R.string.dialog_newPublisher)
308                         .setItems(colors, new DialogInterface.OnClickListener()
309                         {
310                                 @Override
311                                 public void onClick(DialogInterface dialog, int which)
312                                 {
313                                         // new publisher
314                                         
315                                         publisherView.addShape(which, appDomain);
316
317                                         for (PublisherShape s : publisherView.shapes) {
318                                                 s.setScale(me.getWindowManager().getDefaultDisplay().getWidth(), me.getWindowManager().getDefaultDisplay().getHeight());
319                                                 s.box.allowScaling = sp.getBoolean("prefScaling", true);
320                                         }
321                                         
322                                         if (android.os.Build.VERSION.SDK_INT >= 11) me.invalidateOptionsMenu();
323                                 }
324                         })
325                         .setNegativeButton(R.string.dialog_cancel, new DialogInterface.OnClickListener()
326                         {
327                                 @Override
328                                 public void onClick(DialogInterface dialog, int which)
329                                 {       
330                                 }
331                         });
332                         
333                         AlertDialog dialogNew = builderNew.create();
334                         dialogNew.show();
335                         
336                         return true;
337                 case R.id.action_settings:
338                         intent = new Intent(this, SettingsActivity.class);
339                         startActivityForResult(intent, RESULT_SETTINGS);
340                         return true;
341                 case R.id.action_help:
342                         intent = new Intent(this, HelpActivity.class);
343                         startActivity(intent);
344                         return true;
345                 default:
346                         // For settings of Publisher/Subscriber elements.
347                         LinearLayout l = new LinearLayout(me);
348                         l.setOrientation(LinearLayout.VERTICAL);
349                         AlertDialog.Builder builderSettings = new AlertDialog.Builder(me);
350                         
351                         if (this.actualIsPublisher) {
352                                 /*
353                                  * Parameters of Publisher shapes.
354                                  */
355                                 final int shapeStrength = publisherView.shapes.get(id).getStrength();
356                                 SeekBar seekStrength;
357                                 
358                                 /* seekBar */
359                                 seekStrength = new SeekBar(me);
360                                 seekStrength.setMax(STRENGTH_MAX);
361                                 seekStrength.setProgress(shapeStrength);
362                                 
363                                 seekStrength.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener()
364                                 {
365                                         @Override
366                                         public void onStopTrackingTouch(SeekBar seekBar) {
367                                         }
368                                         
369                                         @Override
370                                         public void onStartTrackingTouch(SeekBar seekBar) {
371                                         }
372                                         
373                                         @Override
374                                         public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser)
375                                         {
376                                                 publisherView.shapes.get(id).setStrength(progress);
377                                         }
378                                 });
379                                 
380                                 l.addView(seekStrength);
381                                 /* seekBar - end */
382                                 
383                                 builderSettings.setTitle("#" + id + " " + publisherView.shapes.get(id).getColorName() + " " + publisherView.shapes.get(id).getShapeName() + " strength:")
384                                 .setView(l)
385                                 .setPositiveButton(R.string.dialog_OK, new DialogInterface.OnClickListener()
386                                 {
387                                         @Override
388                                         public void onClick(DialogInterface dialog, int which)
389                                         {}
390                                 })
391                                 .setNeutralButton(R.string.dialog_delete, new DialogInterface.OnClickListener()
392                                 {       
393                                         @Override
394                                         public void onClick(DialogInterface dialog, int which) {
395                                                 publisherView.shapes.get(id).killMe();
396                                                 publisherView.shapes.remove(id);
397                                                 
398                                                 if (android.os.Build.VERSION.SDK_INT >= 11) me.invalidateOptionsMenu();
399                                         }
400                                 })
401                                 .setNegativeButton(R.string.dialog_cancel, new DialogInterface.OnClickListener()
402                                 {
403                                         @Override
404                                         public void onClick(DialogInterface dialog, int which)
405                                         {
406                                                 publisherView.shapes.get(id).setStrength(shapeStrength);
407                                         }
408                                 });
409                         
410                                 AlertDialog dialogSettings = builderSettings.create();
411                                 dialogSettings.show();
412                         } else {
413                                 /*
414                                  * Parameters of Subscriber shapes.
415                                  */
416                                 final int eId;
417                                 SeekBar seekMinSeparation;
418                                 
419                                 switch (id) {
420                                 case R.id.action_blue:
421                                         eId = 0;
422                                         break;
423                                 case R.id.action_green:
424                                         eId = 1;
425                                         break;
426                                 case R.id.action_red:
427                                         eId = 2;
428                                         break;
429                                 case R.id.action_black:
430                                         eId = 3;
431                                         break;
432                                 case R.id.action_yellow:
433                                         eId = 4;
434                                         break;
435                                 default:
436                                         eId = 0;
437                                 }
438                                 
439                                 /* seekBar */
440                                 seekMinSeparation = new SeekBar(me);
441                                 seekMinSeparation.setMax(MINSEPARATION_MAX);
442                                 seekMinSeparation.setProgress(0);
443                                 subscriberView.elements.get(eId).setMinSeparation(new NtpTime(0));
444                                 
445                                 seekMinSeparation.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener()
446                                 {
447                                         @Override
448                                         public void onStopTrackingTouch(SeekBar seekBar) {
449                                         }
450                                         
451                                         @Override
452                                         public void onStartTrackingTouch(SeekBar seekBar) {
453                                         }
454                                         
455                                         @Override
456                                         public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser)
457                                         {
458                                                 subscriberView.elements.get(eId).setMinSeparation(new NtpTime(progress));
459                                                 subscriberView.elements.get(eId).setEnabled(true);
460                                         }
461                                 });
462                                 
463                                 l.addView(seekMinSeparation);
464                                 /* seekBar - end */
465                                 
466                                 builderSettings.setTitle(PublisherShape.getColorName(eId) + " settings")
467                                 .setView(l)
468                                 .setPositiveButton(R.string.dialog_OK, new DialogInterface.OnClickListener()
469                                 {
470                                         @Override
471                                         public void onClick(DialogInterface dialog, int which)
472                                         {}
473                                 })
474                                 .setNeutralButton(subscriberView.elements.get(eId).getEnabled()?R.string.dialog_delete:R.string.dialog_add, new DialogInterface.OnClickListener()
475                                 {       
476                                         @Override
477                                         public void onClick(DialogInterface dialog, int which) {
478                                                 if (subscriberView.elements.get(eId).getEnabled()) {
479                                                         subscriberView.elements.get(eId).setEnabled(false);
480                                                 } else {
481                                                         subscriberView.elements.get(eId).setMinSeparation(new NtpTime(0));
482                                                         subscriberView.elements.get(eId).setEnabled(true);
483                                                 }
484                                         }
485                                 });
486                         
487                                 AlertDialog dialogSettings = builderSettings.create();
488                                 dialogSettings.show();
489                         }
490                 }
491                 
492                 return super.onOptionsItemSelected(item);
493         }
494 }