3 * This file is part of shape_android.
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.
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.
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/>.
19 package org.ocera.orte.shape_android;
21 import org.ocera.orte.DomainApp;
22 import org.ocera.orte.Manager;
23 import org.ocera.orte.types.NtpTime;
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;
47 * Class for object sent and received throw the ORTE middleware.
49 * @author jiri hubacek <jiri.hubacek@gmail.com>
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]?))");
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;
61 public static int SHAPE_WIDTH = 0;
62 public static int SHAPE_HEIGHT = 0;
64 private PowerManager powerManager;
65 private WakeLock wakeLock;
67 private WifiManager wifiManager;
68 private WifiLock wifiLock;
70 private Manager orteManager;
71 private DomainApp appDomain;
73 private PublisherView publisherView;
74 private SubscriberView subscriberView;
76 private ViewSwitcher switcher;
77 private boolean actualIsPublisher;
78 private SharedPreferences sp;
80 private Handler handler = new Handler();
81 private Runnable redraw = new Runnable()
86 publisherView.countShapes();
87 publisherView.invalidate();
88 handler.postDelayed(this, REDRAW_INTERVAL);
93 * Setting up main workspace.
98 protected void onCreate(Bundle savedInstanceState) {
99 super.onCreate(savedInstanceState);
100 setContentView(R.layout.activity_publisher);
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);
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());
114 powerManager = (PowerManager) getSystemService(Context.POWER_SERVICE);
115 wakeLock = (WakeLock) powerManager.newWakeLock(PowerManager.SCREEN_DIM_WAKE_LOCK, getClass().getName() + " Dim");
117 sp = PreferenceManager.getDefaultSharedPreferences(getBaseContext());
120 orteManager = new Manager(sp.getString("prefManagers", ""));
121 appDomain = new DomainApp();
123 this.switcher = (ViewSwitcher) findViewById(R.id.switcher);
124 this.actualIsPublisher = true;
126 this.publisherView = (PublisherView) findViewById(R.id.publisher_view);
127 this.subscriberView = (SubscriberView) findViewById(R.id.subscriber_view);
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));
138 * When pause activity, release WiFi lock and Wake lock.
143 public void onPause()
152 * When resume activity, acquire WiFi lock and Wake lock.
157 public void onResume()
166 * When switching application off.
171 public void onDestroy()
175 if (appDomain != null) {
179 if (orteManager != null) {
180 orteManager.destroy();
186 * When screen orientation is changed,
187 * scale recalculation is needed.
192 public void onConfigurationChanged(Configuration newConfig)
194 super.onConfigurationChanged(newConfig);
196 // count default shape size
197 SHAPE_WIDTH = (int) (this.getWindowManager().getDefaultDisplay().getWidth() * 25 / BoxType.DESTINATION_WIDTH);
198 SHAPE_HEIGHT = (int) (this.getWindowManager().getDefaultDisplay().getHeight() * 45 / BoxType.DESTINATION_HEIGHT);
200 for (PublisherShape s : this.publisherView.shapes) {
201 s.setScale(this.getWindowManager().getDefaultDisplay().getWidth(), this.getWindowManager().getDefaultDisplay().getHeight());
203 for (SubscriberElement e : this.subscriberView.elements) {
204 e.setScale(this.getWindowManager().getDefaultDisplay().getWidth(), this.getWindowManager().getDefaultDisplay().getHeight());
207 //TODO When change rotation in Subscriber view,
208 // there is no change in Publisher view, which
209 // leads to misbehavior. For example, there
210 // is Publisher of Black color in Publisher view,
211 // and we are looking at it in Subscriber view,
212 // when rotation is changed, Publisher view remains
213 // in old rotation while Subscriber view is in new
214 // rotation. Therefore Black Publisher thinks that
215 // it's still in old rotation and the problem with
216 // leaving screen is here.
220 * When returning from SettingsActivity, apply settings.
225 protected void onActivityResult(int requestCode, int resultCode, Intent data)
227 super.onActivityResult(requestCode, resultCode, data);
229 switch(requestCode) {
230 case RESULT_SETTINGS:
231 boolean allowScaling = sp.getBoolean("prefScaling", true);
233 for (PublisherShape s : this.publisherView.shapes) {
234 s.box.allowScaling = allowScaling;
236 for (SubscriberElement e : this.subscriberView.elements) {
237 e.setAllowScaling(allowScaling);
240 if (orteManager != null) orteManager.destroy();
241 orteManager = new Manager(sp.getString("prefManagers", ""));
254 public boolean onCreateOptionsMenu(Menu menu) {
255 // Inflate the menu; this adds items to the action bar if it is present.
256 getMenuInflater().inflate(R.menu.publisher, menu);
261 * All created publishers are in menu.
267 public boolean onPrepareOptionsMenu(Menu menu)
271 if (this.actualIsPublisher) {
272 getMenuInflater().inflate(R.menu.publisher, menu);
273 for (PublisherShape shape : this.publisherView.shapes) {
274 menu.add(0, this.publisherView.shapes.indexOf(shape), 20 + this.publisherView.shapes.indexOf(shape), "#" + this.publisherView.shapes.indexOf(shape) + " " + shape.getColorName() + " " + shape.getShapeName());
277 getMenuInflater().inflate(R.menu.subscriber, menu);
280 return super.onPrepareOptionsMenu(menu);
284 * Logic for menu selecting.
286 * Contains switching between Publishers and Subscribers, adding
287 * new Publisher, setting Publishers, setting Subscribers, moving
288 * to SettingsActivity and HelpActivity.
292 @SuppressLint("NewApi")
294 public boolean onOptionsItemSelected(MenuItem item) {
295 // Handle action bar item clicks here. The action bar will
296 // automatically handle clicks on the Home/Up button, so long
297 // as you specify a parent activity in AndroidManifest.xml.
298 final int id = item.getItemId();
299 final Activity me = this;
303 case R.id.action_switch:
304 if (this.actualIsPublisher) {
305 this.switcher.showNext();
306 this.setTitle(R.string.title_activity_subscriber);
308 this.switcher.showPrevious();
309 this.setTitle(R.string.title_activity_publisher);
311 this.actualIsPublisher = !this.actualIsPublisher;
313 if (android.os.Build.VERSION.SDK_INT >= 11) this.invalidateOptionsMenu();
316 case R.id.action_new:
317 String[] colors = new String[5];
323 colors[4] = "Yellow";
325 AlertDialog.Builder builderNew = new AlertDialog.Builder(me);
326 builderNew.setTitle(R.string.dialog_newPublisher)
327 .setItems(colors, new DialogInterface.OnClickListener()
330 public void onClick(DialogInterface dialog, int which)
334 publisherView.addShape(which, appDomain);
336 for (PublisherShape s : publisherView.shapes) {
337 s.setScale(me.getWindowManager().getDefaultDisplay().getWidth(), me.getWindowManager().getDefaultDisplay().getHeight());
338 s.box.allowScaling = sp.getBoolean("prefScaling", true);
341 if (android.os.Build.VERSION.SDK_INT >= 11) me.invalidateOptionsMenu();
344 .setNegativeButton(R.string.dialog_cancel, new DialogInterface.OnClickListener()
347 public void onClick(DialogInterface dialog, int which)
352 AlertDialog dialogNew = builderNew.create();
356 case R.id.action_settings:
357 intent = new Intent(this, SettingsActivity.class);
358 startActivityForResult(intent, RESULT_SETTINGS);
360 case R.id.action_help:
361 intent = new Intent(this, HelpActivity.class);
362 startActivity(intent);
365 // For settings of Publisher/Subscriber elements.
366 LinearLayout l = new LinearLayout(me);
367 l.setOrientation(LinearLayout.VERTICAL);
368 AlertDialog.Builder builderSettings = new AlertDialog.Builder(me);
370 if (this.actualIsPublisher) {
372 * Parameters of Publisher shapes.
374 final int shapeStrength = publisherView.shapes.get(id).getStrength();
375 SeekBar seekStrength;
378 seekStrength = new SeekBar(me);
379 seekStrength.setMax(STRENGTH_MAX);
380 seekStrength.setProgress(shapeStrength);
382 seekStrength.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener()
385 public void onStopTrackingTouch(SeekBar seekBar) {
389 public void onStartTrackingTouch(SeekBar seekBar) {
393 public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser)
395 publisherView.shapes.get(id).setStrength(progress);
399 l.addView(seekStrength);
402 builderSettings.setTitle("#" + id + " " + publisherView.shapes.get(id).getColorName() + " " + publisherView.shapes.get(id).getShapeName() + " strength:")
404 .setPositiveButton(R.string.dialog_OK, new DialogInterface.OnClickListener()
407 public void onClick(DialogInterface dialog, int which)
410 .setNeutralButton(R.string.dialog_delete, new DialogInterface.OnClickListener()
413 public void onClick(DialogInterface dialog, int which) {
414 publisherView.shapes.get(id).killMe();
415 publisherView.shapes.remove(id);
417 if (android.os.Build.VERSION.SDK_INT >= 11) me.invalidateOptionsMenu();
420 .setNegativeButton(R.string.dialog_cancel, new DialogInterface.OnClickListener()
423 public void onClick(DialogInterface dialog, int which)
425 publisherView.shapes.get(id).setStrength(shapeStrength);
429 AlertDialog dialogSettings = builderSettings.create();
430 dialogSettings.show();
433 * Parameters of Subscriber shapes.
436 SeekBar seekMinSeparation;
439 case R.id.action_blue:
442 case R.id.action_green:
445 case R.id.action_red:
448 case R.id.action_black:
451 case R.id.action_yellow:
459 seekMinSeparation = new SeekBar(me);
460 seekMinSeparation.setMax(MINSEPARATION_MAX);
461 seekMinSeparation.setProgress(0);
462 subscriberView.elements.get(eId).setMinSeparation(new NtpTime(0));
464 seekMinSeparation.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener()
467 public void onStopTrackingTouch(SeekBar seekBar) {
471 public void onStartTrackingTouch(SeekBar seekBar) {
475 public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser)
477 subscriberView.elements.get(eId).setMinSeparation(new NtpTime(progress));
478 subscriberView.elements.get(eId).setEnabled(true);
482 l.addView(seekMinSeparation);
485 builderSettings.setTitle(PublisherShape.getColorName(eId) + " settings")
487 .setPositiveButton(R.string.dialog_OK, new DialogInterface.OnClickListener()
490 public void onClick(DialogInterface dialog, int which)
493 .setNeutralButton(subscriberView.elements.get(eId).getEnabled()?R.string.dialog_delete:R.string.dialog_add, new DialogInterface.OnClickListener()
496 public void onClick(DialogInterface dialog, int which) {
497 if (subscriberView.elements.get(eId).getEnabled()) {
498 subscriberView.elements.get(eId).setEnabled(false);
500 subscriberView.elements.get(eId).setMinSeparation(new NtpTime(0));
501 subscriberView.elements.get(eId).setEnabled(true);
506 AlertDialog dialogSettings = builderSettings.create();
507 dialogSettings.show();
511 return super.onOptionsItemSelected(item);