]> rtime.felk.cvut.cz Git - orte.git/blob - orte/contrib/shape_android/src/org/ocera/orte/shape_android/PublisherActivity.java
557482de86fc4dcffbc4b5b7430902d090eee2d8
[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                 handler.removeCallbacks(redraw);
176
177                 for (PublisherShape shape : publisherView.shapes)
178                         shape.killMe();
179
180                 for (SubscriberElement element : subscriberView.elements)
181                         element.killMe();
182
183                 if (appDomain != null) {
184                         appDomain.destroy();
185                         appDomain = null;
186                 }
187                 if (orteManager != null) {
188                         orteManager.destroy();
189                         orteManager = null;
190                 }
191         }
192         
193         /**
194          * When screen orientation is changed,
195          * scale recalculation is needed.
196          * 
197          * @since 1.0
198          */
199         @Override
200         public void onConfigurationChanged(Configuration newConfig)
201         {
202                 super.onConfigurationChanged(newConfig);
203                 
204                 // count default shape size
205                 SHAPE_WIDTH = (int) (this.getWindowManager().getDefaultDisplay().getWidth() * 25 / BoxType.DESTINATION_WIDTH);
206                 SHAPE_HEIGHT = (int) (this.getWindowManager().getDefaultDisplay().getHeight() * 45 / BoxType.DESTINATION_HEIGHT);
207                                 
208                 for (PublisherShape s : this.publisherView.shapes) {
209                         s.setScale(this.getWindowManager().getDefaultDisplay().getWidth(), this.getWindowManager().getDefaultDisplay().getHeight());
210                 }
211                 for (SubscriberElement e : this.subscriberView.elements) {
212                         e.setScale(this.getWindowManager().getDefaultDisplay().getWidth(), this.getWindowManager().getDefaultDisplay().getHeight());
213                 }
214                 
215                 //TODO When change rotation in Subscriber view,
216                 //              there is no change in Publisher view, which
217                 //              leads to misbehavior. For example, there
218                 //              is Publisher of Black color in Publisher view,
219                 //              and we are looking at it in Subscriber view,
220                 //              when rotation is changed, Publisher view remains
221                 //              in old rotation while Subscriber view is in new
222                 //              rotation. Therefore Black Publisher thinks that
223                 //              it's still in old rotation and the problem with
224                 //              leaving screen is here.
225         }
226
227         /**
228          * When returning from SettingsActivity, apply settings.
229          * 
230          * @since 1.2
231          */
232     @Override
233     protected void onActivityResult(int requestCode, int resultCode, Intent data)
234     {
235             super.onActivityResult(requestCode, resultCode, data);
236         
237             switch(requestCode) {
238             case RESULT_SETTINGS:
239                 boolean allowScaling = sp.getBoolean("prefScaling", true);
240
241                         for (PublisherShape s : this.publisherView.shapes) {
242                                 s.box.allowScaling = allowScaling;
243                         }
244                 for (SubscriberElement e : this.subscriberView.elements) {
245                                 e.setAllowScaling(allowScaling);
246                         }
247                 
248                 if (orteManager != null) orteManager.destroy();
249                         orteManager = new Manager(sp.getString("prefManagers", ""));
250                         
251                 break;
252             default:
253             }
254
255     }
256     
257     /**
258      * Creating menu.
259      * 
260      * @since 1.2
261      */
262         @Override
263         public boolean onCreateOptionsMenu(Menu menu) {
264                 // Inflate the menu; this adds items to the action bar if it is present.
265                 getMenuInflater().inflate(R.menu.publisher, menu);
266                 return true;
267         }
268         
269         /**
270          * All created publishers are in menu.
271          * @return 
272          * 
273          * @since 1.0
274          */
275         @Override
276         public boolean onPrepareOptionsMenu(Menu menu)
277         {
278                 menu.clear();
279                 
280                 if (this.actualIsPublisher) {
281                         getMenuInflater().inflate(R.menu.publisher, menu);
282                         for (PublisherShape shape : this.publisherView.shapes) {
283                                 menu.add(0, this.publisherView.shapes.indexOf(shape), 20 + this.publisherView.shapes.indexOf(shape), "#" + this.publisherView.shapes.indexOf(shape) + " " + shape.getColorName() + " " + shape.getShapeName());
284                         }
285                 } else {
286                         getMenuInflater().inflate(R.menu.subscriber, menu);
287                 }
288                 
289                 return super.onPrepareOptionsMenu(menu);
290         }
291         
292         /**
293          * Logic for menu selecting.
294          * 
295          * Contains switching between Publishers and Subscribers, adding
296          * new Publisher, setting Publishers, setting Subscribers, moving
297          * to SettingsActivity and HelpActivity.
298          * 
299          * @since 1.2
300          */
301         @SuppressLint("NewApi")
302         @Override
303         public boolean onOptionsItemSelected(MenuItem item) {
304                 // Handle action bar item clicks here. The action bar will
305                 // automatically handle clicks on the Home/Up button, so long
306                 // as you specify a parent activity in AndroidManifest.xml.
307                 final int id = item.getItemId();
308                 final Activity me = this;
309                 Intent intent;
310                 
311                 switch(id) {
312                 case R.id.action_switch:
313                         if (this.actualIsPublisher) {
314                                 this.switcher.showNext();
315                                 this.setTitle(R.string.title_activity_subscriber);
316                         } else {
317                                 this.switcher.showPrevious();
318                                 this.setTitle(R.string.title_activity_publisher);
319                         }
320                         this.actualIsPublisher = !this.actualIsPublisher;
321                         
322                         if (android.os.Build.VERSION.SDK_INT >= 11) this.invalidateOptionsMenu();
323                         
324                         return true;
325                 case R.id.action_new:
326                         String[] colors = new String[5];
327                         
328                         colors[0] = "Blue";
329                         colors[1] = "Green";
330                         colors[2] = "Red";
331                         colors[3] = "Black";
332                         colors[4] = "Yellow";
333                         
334                         AlertDialog.Builder builderNew = new AlertDialog.Builder(me);
335                         builderNew.setTitle(R.string.dialog_newPublisher)
336                         .setItems(colors, new DialogInterface.OnClickListener()
337                         {
338                                 @Override
339                                 public void onClick(DialogInterface dialog, int which)
340                                 {
341                                         // new publisher
342                                         
343                                         publisherView.addShape(which, appDomain);
344
345                                         for (PublisherShape s : publisherView.shapes) {
346                                                 s.setScale(me.getWindowManager().getDefaultDisplay().getWidth(), me.getWindowManager().getDefaultDisplay().getHeight());
347                                                 s.box.allowScaling = sp.getBoolean("prefScaling", true);
348                                         }
349                                         
350                                         if (android.os.Build.VERSION.SDK_INT >= 11) me.invalidateOptionsMenu();
351                                 }
352                         })
353                         .setNegativeButton(R.string.dialog_cancel, new DialogInterface.OnClickListener()
354                         {
355                                 @Override
356                                 public void onClick(DialogInterface dialog, int which)
357                                 {       
358                                 }
359                         });
360                         
361                         AlertDialog dialogNew = builderNew.create();
362                         dialogNew.show();
363                         
364                         return true;
365                 case R.id.action_settings:
366                         intent = new Intent(this, SettingsActivity.class);
367                         startActivityForResult(intent, RESULT_SETTINGS);
368                         return true;
369                 case R.id.action_help:
370                         intent = new Intent(this, HelpActivity.class);
371                         startActivity(intent);
372                         return true;
373                 default:
374                         // For settings of Publisher/Subscriber elements.
375                         LinearLayout l = new LinearLayout(me);
376                         l.setOrientation(LinearLayout.VERTICAL);
377                         AlertDialog.Builder builderSettings = new AlertDialog.Builder(me);
378                         
379                         if (this.actualIsPublisher) {
380                                 /*
381                                  * Parameters of Publisher shapes.
382                                  */
383                                 final int shapeStrength = publisherView.shapes.get(id).getStrength();
384                                 SeekBar seekStrength;
385                                 
386                                 /* seekBar */
387                                 seekStrength = new SeekBar(me);
388                                 seekStrength.setMax(STRENGTH_MAX);
389                                 seekStrength.setProgress(shapeStrength);
390                                 
391                                 seekStrength.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener()
392                                 {
393                                         @Override
394                                         public void onStopTrackingTouch(SeekBar seekBar) {
395                                         }
396                                         
397                                         @Override
398                                         public void onStartTrackingTouch(SeekBar seekBar) {
399                                         }
400                                         
401                                         @Override
402                                         public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser)
403                                         {
404                                                 publisherView.shapes.get(id).setStrength(progress);
405                                         }
406                                 });
407                                 
408                                 l.addView(seekStrength);
409                                 /* seekBar - end */
410                                 
411                                 builderSettings.setTitle("#" + id + " " + publisherView.shapes.get(id).getColorName() + " " + publisherView.shapes.get(id).getShapeName() + " strength:")
412                                 .setView(l)
413                                 .setPositiveButton(R.string.dialog_OK, new DialogInterface.OnClickListener()
414                                 {
415                                         @Override
416                                         public void onClick(DialogInterface dialog, int which)
417                                         {}
418                                 })
419                                 .setNeutralButton(R.string.dialog_delete, new DialogInterface.OnClickListener()
420                                 {       
421                                         @Override
422                                         public void onClick(DialogInterface dialog, int which) {
423                                                 publisherView.shapes.get(id).killMe();
424                                                 publisherView.shapes.remove(id);
425                                                 
426                                                 if (android.os.Build.VERSION.SDK_INT >= 11) me.invalidateOptionsMenu();
427                                         }
428                                 })
429                                 .setNegativeButton(R.string.dialog_cancel, new DialogInterface.OnClickListener()
430                                 {
431                                         @Override
432                                         public void onClick(DialogInterface dialog, int which)
433                                         {
434                                                 publisherView.shapes.get(id).setStrength(shapeStrength);
435                                         }
436                                 });
437                         
438                                 AlertDialog dialogSettings = builderSettings.create();
439                                 dialogSettings.show();
440                         } else {
441                                 /*
442                                  * Parameters of Subscriber shapes.
443                                  */
444                                 final int eId;
445                                 SeekBar seekMinSeparation;
446                                 
447                                 switch (id) {
448                                 case R.id.action_blue:
449                                         eId = 0;
450                                         break;
451                                 case R.id.action_green:
452                                         eId = 1;
453                                         break;
454                                 case R.id.action_red:
455                                         eId = 2;
456                                         break;
457                                 case R.id.action_black:
458                                         eId = 3;
459                                         break;
460                                 case R.id.action_yellow:
461                                         eId = 4;
462                                         break;
463                                 default:
464                                         eId = 0;
465                                 }
466                                 
467                                 /* seekBar */
468                                 seekMinSeparation = new SeekBar(me);
469                                 seekMinSeparation.setMax(MINSEPARATION_MAX);
470                                 seekMinSeparation.setProgress(0);
471                                 subscriberView.elements.get(eId).setMinSeparation(new NtpTime(0));
472                                 
473                                 seekMinSeparation.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener()
474                                 {
475                                         @Override
476                                         public void onStopTrackingTouch(SeekBar seekBar) {
477                                         }
478                                         
479                                         @Override
480                                         public void onStartTrackingTouch(SeekBar seekBar) {
481                                         }
482                                         
483                                         @Override
484                                         public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser)
485                                         {
486                                                 subscriberView.elements.get(eId).setMinSeparation(new NtpTime(progress));
487                                                 subscriberView.elements.get(eId).setEnabled(true);
488                                         }
489                                 });
490                                 
491                                 l.addView(seekMinSeparation);
492                                 /* seekBar - end */
493                                 
494                                 builderSettings.setTitle(PublisherShape.getColorName(eId) + " settings")
495                                 .setView(l)
496                                 .setPositiveButton(R.string.dialog_OK, new DialogInterface.OnClickListener()
497                                 {
498                                         @Override
499                                         public void onClick(DialogInterface dialog, int which)
500                                         {}
501                                 })
502                                 .setNeutralButton(subscriberView.elements.get(eId).getEnabled()?R.string.dialog_delete:R.string.dialog_add, new DialogInterface.OnClickListener()
503                                 {       
504                                         @Override
505                                         public void onClick(DialogInterface dialog, int which) {
506                                                 if (subscriberView.elements.get(eId).getEnabled()) {
507                                                         subscriberView.elements.get(eId).setEnabled(false);
508                                                 } else {
509                                                         subscriberView.elements.get(eId).setMinSeparation(new NtpTime(0));
510                                                         subscriberView.elements.get(eId).setEnabled(true);
511                                                 }
512                                         }
513                                 });
514                         
515                                 AlertDialog dialogSettings = builderSettings.create();
516                                 dialogSettings.show();
517                         }
518                 }
519                 
520                 return super.onOptionsItemSelected(item);
521         }
522 }