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.preference.PreferenceManager;
38 import android.view.Menu;
39 import android.view.MenuItem;
40 import android.widget.LinearLayout;
41 import android.widget.SeekBar;
42 import android.widget.ViewSwitcher;
45 * Class for object sent and received throw the ORTE middleware.
47 * @author jiri hubacek <jiri.hubacek@gmail.com>
51 public class PublisherActivity extends Activity {
52 //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]?))");
54 private static final int REDRAW_INTERVAL = 50;
55 private static final int STRENGTH_MAX = 5;
56 private static final int MINSEPARATION_MAX = 5;
57 private static final int RESULT_SETTINGS = 1;
59 public static int SHAPE_WIDTH = 0;
60 public static int SHAPE_HEIGHT = 0;
62 private WifiManager wifiManager;
63 private WifiLock wifiLock;
65 private Manager orteManager;
66 private DomainApp appDomain;
68 private PublisherView publisherView;
69 private SubscriberView subscriberView;
71 private ViewSwitcher switcher;
72 private boolean actualIsPublisher;
73 private SharedPreferences sp;
75 private Handler handler = new Handler();
76 private Runnable redraw = new Runnable()
81 publisherView.countShapes();
82 publisherView.invalidate();
83 handler.postDelayed(this, REDRAW_INTERVAL);
88 * Setting up main workspace.
93 protected void onCreate(Bundle savedInstanceState) {
94 super.onCreate(savedInstanceState);
95 setContentView(R.layout.activity_publisher);
97 // count default shape size
98 SHAPE_WIDTH = (int) (this.getWindowManager().getDefaultDisplay().getWidth() * 25 / BoxType.DESTINATION_WIDTH);
99 SHAPE_HEIGHT = (int) (this.getWindowManager().getDefaultDisplay().getHeight() * 45 / BoxType.DESTINATION_HEIGHT);
101 // From Robot_Demo project.
102 wifiManager = (WifiManager) getSystemService(Context.WIFI_SERVICE);
103 wifiLock = (WifiLock) wifiManager.createWifiLock((
104 (android.os.Build.VERSION.SDK_INT >= 12)
105 ? WifiManager.WIFI_MODE_FULL_HIGH_PERF
106 : WifiManager.WIFI_MODE_FULL
107 ), getClass().getName());
109 sp = PreferenceManager.getDefaultSharedPreferences(getBaseContext());
112 orteManager = new Manager(sp.getString("prefManagers", ""));
113 appDomain = new DomainApp();
115 this.switcher = (ViewSwitcher) findViewById(R.id.switcher);
116 this.actualIsPublisher = true;
118 this.publisherView = (PublisherView) findViewById(R.id.publisher_view);
119 this.subscriberView = (SubscriberView) findViewById(R.id.subscriber_view);
122 this.subscriberView.addElements(this.appDomain);
123 for (SubscriberElement e : this.subscriberView.elements) {
124 e.setScale(this.getWindowManager().getDefaultDisplay().getWidth(), this.getWindowManager().getDefaultDisplay().getHeight());
125 e.setAllowScaling(sp.getBoolean("prefScaling", true));
130 * When pause activity, release WiFi lock.
135 public void onPause()
143 * When resume activity, acquire WiFi lock.
148 public void onResume()
156 * When switching application off.
161 public void onDestroy()
165 if (appDomain != null) {
169 if (orteManager != null) {
170 orteManager.destroy();
176 * When screen orientation is changed,
177 * scale recalculation is needed.
182 public void onConfigurationChanged(Configuration newConfig)
184 super.onConfigurationChanged(newConfig);
186 // count default shape size
187 SHAPE_WIDTH = (int) (this.getWindowManager().getDefaultDisplay().getWidth() * 25 / BoxType.DESTINATION_WIDTH);
188 SHAPE_HEIGHT = (int) (this.getWindowManager().getDefaultDisplay().getHeight() * 45 / BoxType.DESTINATION_HEIGHT);
190 for (PublisherShape s : this.publisherView.shapes) {
191 s.setScale(this.getWindowManager().getDefaultDisplay().getWidth(), this.getWindowManager().getDefaultDisplay().getHeight());
193 for (SubscriberElement e : this.subscriberView.elements) {
194 e.setScale(this.getWindowManager().getDefaultDisplay().getWidth(), this.getWindowManager().getDefaultDisplay().getHeight());
197 //TODO When change rotation in Subscriber view,
198 // there is no change in Publisher view, which
199 // leads to misbehavior. For example, there
200 // is Publisher of Black color in Publisher view,
201 // and we are looking at it in Subscriber view,
202 // when rotation is changed, Publisher view remains
203 // in old rotation while Subscriber view is in new
204 // rotation. Therefore Black Publisher thinks that
205 // it's still in old rotation and the problem with
206 // leaving screen is here.
210 * When returning from SettingsActivity, apply settings.
215 protected void onActivityResult(int requestCode, int resultCode, Intent data)
217 super.onActivityResult(requestCode, resultCode, data);
219 switch(requestCode) {
220 case RESULT_SETTINGS:
221 boolean allowScaling = sp.getBoolean("prefScaling", true);
223 for (PublisherShape s : this.publisherView.shapes) {
224 s.box.allowScaling = allowScaling;
226 for (SubscriberElement e : this.subscriberView.elements) {
227 e.setAllowScaling(allowScaling);
230 if (orteManager != null) orteManager.destroy();
231 orteManager = new Manager(sp.getString("prefManagers", ""));
244 public boolean onCreateOptionsMenu(Menu menu) {
245 // Inflate the menu; this adds items to the action bar if it is present.
246 getMenuInflater().inflate(R.menu.publisher, menu);
251 * All created publishers are in menu.
257 public boolean onPrepareOptionsMenu(Menu menu)
261 if (this.actualIsPublisher) {
262 getMenuInflater().inflate(R.menu.publisher, menu);
263 for (PublisherShape shape : this.publisherView.shapes) {
264 menu.add(0, this.publisherView.shapes.indexOf(shape), 20 + this.publisherView.shapes.indexOf(shape), "#" + this.publisherView.shapes.indexOf(shape) + " " + shape.getColorName() + " " + shape.getShapeName());
267 getMenuInflater().inflate(R.menu.subscriber, menu);
270 return super.onPrepareOptionsMenu(menu);
274 * Logic for menu selecting.
276 * Contains switching between Publishers and Subscribers, adding
277 * new Publisher, setting Publishers, setting Subscribers, moving
278 * to SettingsActivity and HelpActivity.
282 @SuppressLint("NewApi")
284 public boolean onOptionsItemSelected(MenuItem item) {
285 // Handle action bar item clicks here. The action bar will
286 // automatically handle clicks on the Home/Up button, so long
287 // as you specify a parent activity in AndroidManifest.xml.
288 final int id = item.getItemId();
289 final Activity me = this;
293 case R.id.action_switch:
294 if (this.actualIsPublisher) {
295 this.switcher.showNext();
296 this.setTitle(R.string.title_activity_subscriber);
298 this.switcher.showPrevious();
299 this.setTitle(R.string.title_activity_publisher);
301 this.actualIsPublisher = !this.actualIsPublisher;
303 if (android.os.Build.VERSION.SDK_INT >= 11) this.invalidateOptionsMenu();
306 case R.id.action_new:
307 String[] colors = new String[5];
313 colors[4] = "Yellow";
315 AlertDialog.Builder builderNew = new AlertDialog.Builder(me);
316 builderNew.setTitle(R.string.dialog_newPublisher)
317 .setItems(colors, new DialogInterface.OnClickListener()
320 public void onClick(DialogInterface dialog, int which)
324 publisherView.addShape(which, appDomain);
326 for (PublisherShape s : publisherView.shapes) {
327 s.setScale(me.getWindowManager().getDefaultDisplay().getWidth(), me.getWindowManager().getDefaultDisplay().getHeight());
328 s.box.allowScaling = sp.getBoolean("prefScaling", true);
331 if (android.os.Build.VERSION.SDK_INT >= 11) me.invalidateOptionsMenu();
334 .setNegativeButton(R.string.dialog_cancel, new DialogInterface.OnClickListener()
337 public void onClick(DialogInterface dialog, int which)
342 AlertDialog dialogNew = builderNew.create();
346 case R.id.action_settings:
347 intent = new Intent(this, SettingsActivity.class);
348 startActivityForResult(intent, RESULT_SETTINGS);
350 case R.id.action_help:
351 intent = new Intent(this, HelpActivity.class);
352 startActivity(intent);
355 // For settings of Publisher/Subscriber elements.
356 LinearLayout l = new LinearLayout(me);
357 l.setOrientation(LinearLayout.VERTICAL);
358 AlertDialog.Builder builderSettings = new AlertDialog.Builder(me);
360 if (this.actualIsPublisher) {
362 * Parameters of Publisher shapes.
364 final int shapeStrength = publisherView.shapes.get(id).getStrength();
365 SeekBar seekStrength;
368 seekStrength = new SeekBar(me);
369 seekStrength.setMax(STRENGTH_MAX);
370 seekStrength.setProgress(shapeStrength);
372 seekStrength.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener()
375 public void onStopTrackingTouch(SeekBar seekBar) {
379 public void onStartTrackingTouch(SeekBar seekBar) {
383 public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser)
385 publisherView.shapes.get(id).setStrength(progress);
389 l.addView(seekStrength);
392 builderSettings.setTitle("#" + id + " " + publisherView.shapes.get(id).getColorName() + " " + publisherView.shapes.get(id).getShapeName() + " strength:")
394 .setPositiveButton(R.string.dialog_OK, new DialogInterface.OnClickListener()
397 public void onClick(DialogInterface dialog, int which)
400 .setNeutralButton(R.string.dialog_delete, new DialogInterface.OnClickListener()
403 public void onClick(DialogInterface dialog, int which) {
404 publisherView.shapes.get(id).killMe();
405 publisherView.shapes.remove(id);
407 if (android.os.Build.VERSION.SDK_INT >= 11) me.invalidateOptionsMenu();
410 .setNegativeButton(R.string.dialog_cancel, new DialogInterface.OnClickListener()
413 public void onClick(DialogInterface dialog, int which)
415 publisherView.shapes.get(id).setStrength(shapeStrength);
419 AlertDialog dialogSettings = builderSettings.create();
420 dialogSettings.show();
423 * Parameters of Subscriber shapes.
426 SeekBar seekMinSeparation;
429 case R.id.action_blue:
432 case R.id.action_green:
435 case R.id.action_red:
438 case R.id.action_black:
441 case R.id.action_yellow:
449 seekMinSeparation = new SeekBar(me);
450 seekMinSeparation.setMax(MINSEPARATION_MAX);
451 seekMinSeparation.setProgress(0);
452 subscriberView.elements.get(eId).setMinSeparation(new NtpTime(0));
454 seekMinSeparation.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener()
457 public void onStopTrackingTouch(SeekBar seekBar) {
461 public void onStartTrackingTouch(SeekBar seekBar) {
465 public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser)
467 subscriberView.elements.get(eId).setMinSeparation(new NtpTime(progress));
468 subscriberView.elements.get(eId).setEnabled(true);
472 l.addView(seekMinSeparation);
475 builderSettings.setTitle(PublisherShape.getColorName(eId) + " settings")
477 .setPositiveButton(R.string.dialog_OK, new DialogInterface.OnClickListener()
480 public void onClick(DialogInterface dialog, int which)
483 .setNeutralButton(subscriberView.elements.get(eId).getEnabled()?R.string.dialog_delete:R.string.dialog_add, new DialogInterface.OnClickListener()
486 public void onClick(DialogInterface dialog, int which) {
487 if (subscriberView.elements.get(eId).getEnabled()) {
488 subscriberView.elements.get(eId).setEnabled(false);
490 subscriberView.elements.get(eId).setMinSeparation(new NtpTime(0));
491 subscriberView.elements.get(eId).setEnabled(true);
496 AlertDialog dialogSettings = builderSettings.create();
497 dialogSettings.show();
501 return super.onOptionsItemSelected(item);