syncslides: Fullscreen slide view.
Change-Id: I1770811a17253c99e3a7adcf56243cac14327057
diff --git a/android/app/src/main/java/io/v/syncslides/FullscreenSlideFragment.java b/android/app/src/main/java/io/v/syncslides/FullscreenSlideFragment.java
new file mode 100644
index 0000000..da8d140
--- /dev/null
+++ b/android/app/src/main/java/io/v/syncslides/FullscreenSlideFragment.java
@@ -0,0 +1,150 @@
+// Copyright 2015 The Vanadium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package io.v.syncslides;
+
+import android.os.Bundle;
+import android.support.v4.app.Fragment;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ImageView;
+import android.widget.Toast;
+
+import io.v.syncslides.db.DB;
+import io.v.syncslides.model.DynamicList;
+import io.v.syncslides.model.ListListener;
+import io.v.syncslides.model.Session;
+import io.v.syncslides.model.Slide;
+import io.v.v23.verror.VException;
+
+public class FullscreenSlideFragment extends Fragment {
+ private static final String SESSION_ID_KEY = "session_id_key";
+ private static final String TAG = "FullscreenSlide";
+
+ private Session mSession;
+ private ImageView mFullScreenImage;
+ private DynamicList<Slide> mSlides;
+ private int mSlideNum = 0;
+ private final SlideNumberListener mSlideNumberListener = new SlideNumberListener();
+ private final ListListener mSlideListListener = new SlideListListener();
+
+ public static FullscreenSlideFragment newInstance(String sessionId) {
+ FullscreenSlideFragment fragment = new FullscreenSlideFragment();
+ Bundle args = new Bundle();
+ args.putString(SESSION_ID_KEY, sessionId);
+ fragment.setArguments(args);
+ return fragment;
+ }
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container,
+ Bundle savedInstanceState) {
+ Bundle bundle = savedInstanceState;
+ if (bundle == null) {
+ bundle = getArguments();
+ }
+ String sessionId = bundle.getString(SESSION_ID_KEY);
+ try {
+ mSession = DB.Singleton.get().getSession(sessionId);
+ } catch (VException e) {
+ handleFatalError("Failed to fetch Session", e);
+ }
+ // See comment at the top of fragment_slide_list.xml.
+ ((PresentationActivity) getActivity()).setUiImmersive(true);
+ // Inflate the layout for this fragment
+ View rootView = inflater.inflate(R.layout.fragment_fullscreen_slide, container, false);
+ mFullScreenImage = (ImageView) rootView.findViewById(R.id.fullscreen_slide_image);
+ mFullScreenImage.setOnClickListener(
+ v -> ((PresentationActivity) getActivity()).showNavigation());
+ return rootView;
+ }
+
+ @Override
+ public void onStart() {
+ super.onStart();
+ mSlides = mSession.getSlides();
+ mSlides.addListener(mSlideListListener);
+ mSession.addSlideNumberListener(mSlideNumberListener);
+ }
+
+ @Override
+ public void onStop() {
+ super.onStop();
+ mSession.removeSlideNumberListener(mSlideNumberListener);
+ mSlides.removeListener(mSlideListListener);
+ mSlides = null;
+ }
+
+ @Override
+ public void onSaveInstanceState(Bundle outState) {
+ super.onSaveInstanceState(outState);
+ outState.putString(SESSION_ID_KEY, mSession.getId());
+ }
+
+ private void updateView() {
+ if (mSlideNum < 0 || mSlideNum >= mSlides.getItemCount()) {
+ // Still loading...
+ return;
+ }
+ // TODO(kash): Display the fullsize image instead of the thumbnail.
+ mFullScreenImage.setImageBitmap(mSlides.get(mSlideNum).getThumb());
+ }
+
+ /**
+ * Updates the view whenever the list of slides changes.
+ */
+ private class SlideListListener implements ListListener {
+ @Override
+ public void notifyDataSetChanged() {
+ updateView();
+ }
+
+ @Override
+ public void notifyItemChanged(int position) {
+ updateView();
+ }
+
+ @Override
+ public void notifyItemInserted(int position) {
+ updateView();
+ }
+
+ @Override
+ public void notifyItemRemoved(int position) {
+ updateView();
+ }
+
+ @Override
+ public void onError(Exception e) {
+ handleFatalError("Error watching slide list", e);
+ }
+ }
+
+ private class SlideNumberListener implements Session.SlideNumberListener {
+ @Override
+ public void onChange(int slideNum) {
+ Log.i(TAG, "onChange " + slideNum);
+ mSlideNum = slideNum;
+ updateView();
+ }
+
+ @Override
+ public void onError(Exception e) {
+ handleFatalError("Error listening to slide number changes", e);
+ }
+ }
+
+ private void handleError(String msg, Throwable throwable) {
+ Log.e(TAG, msg + ": " + Log.getStackTraceString(throwable));
+ Toast.makeText(getContext(), msg, Toast.LENGTH_SHORT).show();
+ }
+
+ private void handleFatalError(String msg, Throwable throwable) {
+ handleError(msg, throwable);
+ getActivity().finish();
+ }
+
+}
diff --git a/android/app/src/main/java/io/v/syncslides/NavigateFragment.java b/android/app/src/main/java/io/v/syncslides/NavigateFragment.java
index e475c0b..e0f7245 100644
--- a/android/app/src/main/java/io/v/syncslides/NavigateFragment.java
+++ b/android/app/src/main/java/io/v/syncslides/NavigateFragment.java
@@ -135,16 +135,14 @@
// }
// });
mCurrentSlide = (ImageView) rootView.findViewById(R.id.slide_current_medium);
-// mCurrentSlide.setOnClickListener(new NavigateClickListener() {
-// @Override
-// public void onClick(View v) {
-// super.onClick(v);
-// if (mRole == Role.AUDIENCE || mRole == Role.BROWSER) {
-// ((PresentationActivity) getActivity()).showFullscreenSlide(mSlideNum);
-// }
-// }
-// });
-//
+ mCurrentSlide.setOnClickListener(new NavigateClickListener() {
+ @Override
+ public void onNavigate() {
+ // TODO(kash): Disallow presenter from switching to fullscreen.
+ ((PresentationActivity) getActivity()).showFullscreenSlide();
+ }
+ });
+
mSlideNumText = (TextView) rootView.findViewById(R.id.slide_num_text);
mNotes = (EditText) rootView.findViewById(R.id.notes);
mNotes.setOnFocusChangeListener((v, hasFocus) -> {
diff --git a/android/app/src/main/java/io/v/syncslides/PresentationActivity.java b/android/app/src/main/java/io/v/syncslides/PresentationActivity.java
index c56fe3e..b013f7a 100644
--- a/android/app/src/main/java/io/v/syncslides/PresentationActivity.java
+++ b/android/app/src/main/java/io/v/syncslides/PresentationActivity.java
@@ -118,6 +118,14 @@
}
/**
+ * Shows the current slide in fullscreen mode.
+ */
+ public void showFullscreenSlide() {
+ FullscreenSlideFragment fragment = FullscreenSlideFragment.newInstance(mSession.getId());
+ getSupportFragmentManager().beginTransaction().replace(R.id.fragment, fragment).commit();
+ }
+
+ /**
* Shows the navigate fragment where the user can see the given slide and
* navigate to other components of the slide presentation.
*/
@@ -128,6 +136,14 @@
handleError("Could not update session", e);
return;
}
+ showNavigation();
+ }
+
+ /**
+ * Shows the navigate fragment where the user can see the current slide and navigate
+ * to other components of the slide presentation.
+ */
+ public void showNavigation() {
NavigateFragment fragment = NavigateFragment.newInstance(mSession.getId());
FragmentTransaction transaction = getSupportFragmentManager()
.beginTransaction()
diff --git a/android/app/src/main/java/io/v/syncslides/db/SlideNumberWatcher.java b/android/app/src/main/java/io/v/syncslides/db/SlideNumberWatcher.java
index 1ed2f5b..db2edeb 100644
--- a/android/app/src/main/java/io/v/syncslides/db/SlideNumberWatcher.java
+++ b/android/app/src/main/java/io/v/syncslides/db/SlideNumberWatcher.java
@@ -124,7 +124,6 @@
// Runs in a background thread.
private void watchCurrentSlide() {
try {
- Log.i(TAG, "watchCurrentSlide");
String rowKey = NamingUtil.join(mDeckId, mPresentationId, SyncbaseDB.CURRENT_SLIDE);
BatchDatabase batch = sync(mDb.beginBatch(mCurrentContext, null));
Table presentations = batch.getTable(SyncbaseDB.PRESENTATIONS_TABLE);
diff --git a/android/app/src/main/res/layout/fragment_fullscreen_slide.xml b/android/app/src/main/res/layout/fragment_fullscreen_slide.xml
new file mode 100644
index 0000000..1ddfcb8
--- /dev/null
+++ b/android/app/src/main/res/layout/fragment_fullscreen_slide.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8"?>
+<ImageView
+ android:id="@+id/fullscreen_slide_image"
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:background="@color/matte_black"
+ android:scaleType="fitCenter">
+</ImageView>
\ No newline at end of file