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", ""));
255 public boolean onCreateOptionsMenu(Menu menu) {
256 // Inflate the menu; this adds items to the action bar if it is present.
257 getMenuInflater().inflate(R.menu.publisher, menu);
262 * All created publishers are in menu.
268 public boolean onPrepareOptionsMenu(Menu menu)
272 if (this.actualIsPublisher) {
273 getMenuInflater().inflate(R.menu.publisher, menu);
274 for (PublisherShape shape : this.publisherView.shapes) {
275 menu.add(0, this.publisherView.shapes.indexOf(shape), 20 + this.publisherView.shapes.indexOf(shape), "#" + this.publisherView.shapes.indexOf(shape) + " " + shape.getColorName() + " " + shape.getShapeName());
278 getMenuInflater().inflate(R.menu.subscriber, menu);
281 return super.onPrepareOptionsMenu(menu);
285 * Logic for menu selecting.
287 * Contains switching between Publishers and Subscribers, adding
288 * new Publisher, setting Publishers, setting Subscribers, moving
289 * to SettingsActivity and HelpActivity.
293 @SuppressLint("NewApi")
295 public boolean onOptionsItemSelected(MenuItem item) {
296 // Handle action bar item clicks here. The action bar will
297 // automatically handle clicks on the Home/Up button, so long
298 // as you specify a parent activity in AndroidManifest.xml.
299 final int id = item.getItemId();
300 final Activity me = this;
304 case R.id.action_switch:
305 if (this.actualIsPublisher) {
306 this.switcher.showNext();
307 this.setTitle(R.string.title_activity_subscriber);
309 this.switcher.showPrevious();
310 this.setTitle(R.string.title_activity_publisher);
312 this.actualIsPublisher = !this.actualIsPublisher;
314 if (android.os.Build.VERSION.SDK_INT >= 11) this.invalidateOptionsMenu();
317 case R.id.action_new:
318 String[] colors = new String[5];
324 colors[4] = "Yellow";
326 AlertDialog.Builder builderNew = new AlertDialog.Builder(me);
327 builderNew.setTitle(R.string.dialog_newPublisher)
328 .setItems(colors, new DialogInterface.OnClickListener()
331 public void onClick(DialogInterface dialog, int which)
335 publisherView.addShape(which, appDomain);
337 for (PublisherShape s : publisherView.shapes) {
338 s.setScale(me.getWindowManager().getDefaultDisplay().getWidth(), me.getWindowManager().getDefaultDisplay().getHeight());
339 s.box.allowScaling = sp.getBoolean("prefScaling", true);
342 if (android.os.Build.VERSION.SDK_INT >= 11) me.invalidateOptionsMenu();
345 .setNegativeButton(R.string.dialog_cancel, new DialogInterface.OnClickListener()
348 public void onClick(DialogInterface dialog, int which)
353 AlertDialog dialogNew = builderNew.create();
357 case R.id.action_settings:
358 intent = new Intent(this, SettingsActivity.class);
359 startActivityForResult(intent, RESULT_SETTINGS);
361 case R.id.action_help:
362 intent = new Intent(this, HelpActivity.class);
363 startActivity(intent);
366 // For settings of Publisher/Subscriber elements.
367 LinearLayout l = new LinearLayout(me);
368 l.setOrientation(LinearLayout.VERTICAL);
369 AlertDialog.Builder builderSettings = new AlertDialog.Builder(me);
371 if (this.actualIsPublisher) {
373 * Parameters of Publisher shapes.
375 final int shapeStrength = publisherView.shapes.get(id).getStrength();
376 SeekBar seekStrength;
379 seekStrength = new SeekBar(me);
380 seekStrength.setMax(STRENGTH_MAX);
381 seekStrength.setProgress(shapeStrength);
383 seekStrength.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener()
386 public void onStopTrackingTouch(SeekBar seekBar) {
390 public void onStartTrackingTouch(SeekBar seekBar) {
394 public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser)
396 publisherView.shapes.get(id).setStrength(progress);
400 l.addView(seekStrength);
403 builderSettings.setTitle("#" + id + " " + publisherView.shapes.get(id).getColorName() + " " + publisherView.shapes.get(id).getShapeName() + " strength:")
405 .setPositiveButton(R.string.dialog_OK, new DialogInterface.OnClickListener()
408 public void onClick(DialogInterface dialog, int which)
411 .setNeutralButton(R.string.dialog_delete, new DialogInterface.OnClickListener()
414 public void onClick(DialogInterface dialog, int which) {
415 publisherView.shapes.get(id).killMe();
416 publisherView.shapes.remove(id);
418 if (android.os.Build.VERSION.SDK_INT >= 11) me.invalidateOptionsMenu();
421 .setNegativeButton(R.string.dialog_cancel, new DialogInterface.OnClickListener()
424 public void onClick(DialogInterface dialog, int which)
426 publisherView.shapes.get(id).setStrength(shapeStrength);
430 AlertDialog dialogSettings = builderSettings.create();
431 dialogSettings.show();
434 * Parameters of Subscriber shapes.
437 SeekBar seekMinSeparation;
440 case R.id.action_blue:
443 case R.id.action_green:
446 case R.id.action_red:
449 case R.id.action_black:
452 case R.id.action_yellow:
460 seekMinSeparation = new SeekBar(me);
461 seekMinSeparation.setMax(MINSEPARATION_MAX);
462 seekMinSeparation.setProgress(0);
463 subscriberView.elements.get(eId).setMinSeparation(new NtpTime(0));
465 seekMinSeparation.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener()
468 public void onStopTrackingTouch(SeekBar seekBar) {
472 public void onStartTrackingTouch(SeekBar seekBar) {
476 public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser)
478 subscriberView.elements.get(eId).setMinSeparation(new NtpTime(progress));
479 subscriberView.elements.get(eId).setEnabled(true);
483 l.addView(seekMinSeparation);
486 builderSettings.setTitle(PublisherShape.getColorName(eId) + " settings")
488 .setPositiveButton(R.string.dialog_OK, new DialogInterface.OnClickListener()
491 public void onClick(DialogInterface dialog, int which)
494 .setNeutralButton(subscriberView.elements.get(eId).getEnabled()?R.string.dialog_delete:R.string.dialog_add, new DialogInterface.OnClickListener()
497 public void onClick(DialogInterface dialog, int which) {
498 if (subscriberView.elements.get(eId).getEnabled()) {
499 subscriberView.elements.get(eId).setEnabled(false);
501 subscriberView.elements.get(eId).setMinSeparation(new NtpTime(0));
502 subscriberView.elements.get(eId).setEnabled(true);
507 AlertDialog dialogSettings = builderSettings.create();
508 dialogSettings.show();
512 return super.onOptionsItemSelected(item);