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