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 for (PublisherShape shape : publisherView.shapes)
178 for (SubscriberElement element : subscriberView.elements)
181 if (appDomain != null) {
185 if (orteManager != null) {
186 orteManager.destroy();
192 * When screen orientation is changed,
193 * scale recalculation is needed.
198 public void onConfigurationChanged(Configuration newConfig)
200 super.onConfigurationChanged(newConfig);
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);
206 for (PublisherShape s : this.publisherView.shapes) {
207 s.setScale(this.getWindowManager().getDefaultDisplay().getWidth(), this.getWindowManager().getDefaultDisplay().getHeight());
209 for (SubscriberElement e : this.subscriberView.elements) {
210 e.setScale(this.getWindowManager().getDefaultDisplay().getWidth(), this.getWindowManager().getDefaultDisplay().getHeight());
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.
226 * When returning from SettingsActivity, apply settings.
231 protected void onActivityResult(int requestCode, int resultCode, Intent data)
233 super.onActivityResult(requestCode, resultCode, data);
235 switch(requestCode) {
236 case RESULT_SETTINGS:
237 boolean allowScaling = sp.getBoolean("prefScaling", true);
239 for (PublisherShape s : this.publisherView.shapes) {
240 s.box.allowScaling = allowScaling;
242 for (SubscriberElement e : this.subscriberView.elements) {
243 e.setAllowScaling(allowScaling);
246 if (orteManager != null) orteManager.destroy();
247 orteManager = new Manager(sp.getString("prefManagers", ""));
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);
268 * All created publishers are in menu.
274 public boolean onPrepareOptionsMenu(Menu menu)
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());
284 getMenuInflater().inflate(R.menu.subscriber, menu);
287 return super.onPrepareOptionsMenu(menu);
291 * Logic for menu selecting.
293 * Contains switching between Publishers and Subscribers, adding
294 * new Publisher, setting Publishers, setting Subscribers, moving
295 * to SettingsActivity and HelpActivity.
299 @SuppressLint("NewApi")
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;
310 case R.id.action_switch:
311 if (this.actualIsPublisher) {
312 this.switcher.showNext();
313 this.setTitle(R.string.title_activity_subscriber);
315 this.switcher.showPrevious();
316 this.setTitle(R.string.title_activity_publisher);
318 this.actualIsPublisher = !this.actualIsPublisher;
320 if (android.os.Build.VERSION.SDK_INT >= 11) this.invalidateOptionsMenu();
323 case R.id.action_new:
324 String[] colors = new String[5];
330 colors[4] = "Yellow";
332 AlertDialog.Builder builderNew = new AlertDialog.Builder(me);
333 builderNew.setTitle(R.string.dialog_newPublisher)
334 .setItems(colors, new DialogInterface.OnClickListener()
337 public void onClick(DialogInterface dialog, int which)
341 publisherView.addShape(which, appDomain);
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);
348 if (android.os.Build.VERSION.SDK_INT >= 11) me.invalidateOptionsMenu();
351 .setNegativeButton(R.string.dialog_cancel, new DialogInterface.OnClickListener()
354 public void onClick(DialogInterface dialog, int which)
359 AlertDialog dialogNew = builderNew.create();
363 case R.id.action_settings:
364 intent = new Intent(this, SettingsActivity.class);
365 startActivityForResult(intent, RESULT_SETTINGS);
367 case R.id.action_help:
368 intent = new Intent(this, HelpActivity.class);
369 startActivity(intent);
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);
377 if (this.actualIsPublisher) {
379 * Parameters of Publisher shapes.
381 final int shapeStrength = publisherView.shapes.get(id).getStrength();
382 SeekBar seekStrength;
385 seekStrength = new SeekBar(me);
386 seekStrength.setMax(STRENGTH_MAX);
387 seekStrength.setProgress(shapeStrength);
389 seekStrength.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener()
392 public void onStopTrackingTouch(SeekBar seekBar) {
396 public void onStartTrackingTouch(SeekBar seekBar) {
400 public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser)
402 publisherView.shapes.get(id).setStrength(progress);
406 l.addView(seekStrength);
409 builderSettings.setTitle("#" + id + " " + publisherView.shapes.get(id).getColorName() + " " + publisherView.shapes.get(id).getShapeName() + " strength:")
411 .setPositiveButton(R.string.dialog_OK, new DialogInterface.OnClickListener()
414 public void onClick(DialogInterface dialog, int which)
417 .setNeutralButton(R.string.dialog_delete, new DialogInterface.OnClickListener()
420 public void onClick(DialogInterface dialog, int which) {
421 publisherView.shapes.get(id).killMe();
422 publisherView.shapes.remove(id);
424 if (android.os.Build.VERSION.SDK_INT >= 11) me.invalidateOptionsMenu();
427 .setNegativeButton(R.string.dialog_cancel, new DialogInterface.OnClickListener()
430 public void onClick(DialogInterface dialog, int which)
432 publisherView.shapes.get(id).setStrength(shapeStrength);
436 AlertDialog dialogSettings = builderSettings.create();
437 dialogSettings.show();
440 * Parameters of Subscriber shapes.
443 SeekBar seekMinSeparation;
446 case R.id.action_blue:
449 case R.id.action_green:
452 case R.id.action_red:
455 case R.id.action_black:
458 case R.id.action_yellow:
466 seekMinSeparation = new SeekBar(me);
467 seekMinSeparation.setMax(MINSEPARATION_MAX);
468 seekMinSeparation.setProgress(0);
469 subscriberView.elements.get(eId).setMinSeparation(new NtpTime(0));
471 seekMinSeparation.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener()
474 public void onStopTrackingTouch(SeekBar seekBar) {
478 public void onStartTrackingTouch(SeekBar seekBar) {
482 public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser)
484 subscriberView.elements.get(eId).setMinSeparation(new NtpTime(progress));
485 subscriberView.elements.get(eId).setEnabled(true);
489 l.addView(seekMinSeparation);
492 builderSettings.setTitle(PublisherShape.getColorName(eId) + " settings")
494 .setPositiveButton(R.string.dialog_OK, new DialogInterface.OnClickListener()
497 public void onClick(DialogInterface dialog, int which)
500 .setNeutralButton(subscriberView.elements.get(eId).getEnabled()?R.string.dialog_delete:R.string.dialog_add, new DialogInterface.OnClickListener()
503 public void onClick(DialogInterface dialog, int which) {
504 if (subscriberView.elements.get(eId).getEnabled()) {
505 subscriberView.elements.get(eId).setEnabled(false);
507 subscriberView.elements.get(eId).setMinSeparation(new NtpTime(0));
508 subscriberView.elements.get(eId).setEnabled(true);
513 AlertDialog dialogSettings = builderSettings.create();
514 dialogSettings.show();
518 return super.onOptionsItemSelected(item);