Bladeren bron

Merge branch 'share-cover-dialog'

Wayne 6 jaren geleden
bovenliggende
commit
c218eb464c

+ 4 - 0
build.gradle

@@ -47,6 +47,10 @@ dependencies {
     implementation project(':Bomo_for_Android_trackWidgetModule')
     implementation project(':Bomo_for_Android_cloudModule')
     implementation project(':Bomo_for_Android_encodeModule')
+    implementation project(':uikit')
+    implementation project(':pdfexport')
+
+    implementation 'com.squareup.picasso:picasso:2.71828'
 }
 repositories {
     mavenCentral()

+ 3 - 0
src/main/java/com/bomostory/sceneeditmodule/Config.kt

@@ -4,10 +4,13 @@ import android.os.Environment
 import java.io.File
 
 object Config {
+    private val ROOT = File(Environment.getExternalStorageDirectory(), "Bomo")
     private const val ASSETS_FOLDER_PATH = "/Android/yuheng"
     private const val PROJECTS_FOLDER_PATH = "/Android/yuheng/project"
     private const val IMAGE_FOLDER_PATH = "/Android/yuheng/image"
     val IMAGE_FOLDER = File(Environment.getExternalStorageDirectory(), IMAGE_FOLDER_PATH)
     val ASSETS_FOLDER = File(Environment.getExternalStorageDirectory(), ASSETS_FOLDER_PATH)
     val PROJECTS_FOLDER = File(Environment.getExternalStorageDirectory(), PROJECTS_FOLDER_PATH)
+
+    val PDF_FOLDER = File(ROOT, "pdf")
 }

+ 97 - 3
src/main/java/com/bomostory/sceneeditmodule/MovieEditActivity.kt

@@ -5,11 +5,11 @@ import android.app.ProgressDialog
 import android.content.DialogInterface
 import android.content.Intent
 import android.net.Uri
-import android.support.v7.app.AppCompatActivity
 import android.os.Bundle
 import android.os.Environment
 import android.os.Handler
 import android.support.v4.app.DialogFragment
+import android.support.v7.app.AppCompatActivity
 import android.util.Log
 import android.view.View
 import android.widget.CompoundButton
@@ -19,6 +19,8 @@ import com.bomostory.sceneeditmodule.basicdata.DataParser
 import com.bomostory.sceneeditmodule.basicdata.Music
 import com.bomostory.sceneeditmodule.basicdata.Project
 import com.bomostory.sceneeditmodule.basicdata.Scene
+import com.bomostory.sceneeditmodule.share.ExportPdfDialog
+import com.bomostory.sceneeditmodule.share.ShareDialog
 import com.bomostory.sceneeditmodule.utils.MoviePlayer
 import com.bomostory.sceneeditmodule.utils.MusicPlayer
 import com.bomostory.sceneeditmodule.view.AudioTrackGroupView
@@ -26,6 +28,7 @@ import com.bomostory.sceneeditmodule.view.MovieSelectView
 import com.example.exportmedia.MediaHelper
 import com.example.tfat.myapplication.R
 import com.google.gson.Gson
+import io.reactivex.Observable
 import io.reactivex.android.schedulers.AndroidSchedulers
 import io.reactivex.schedulers.Schedulers
 import kotlinx.android.synthetic.main.activity_movie_edit.*
@@ -71,6 +74,8 @@ class MovieEditActivity : AppCompatActivity(),
         dialogFragment.dismiss()
     }
 
+    private val shareDialog = ShareDialog()
+
     private val mHideHandler = Handler()
     private val mHidePart2Runnable = Runnable {
         window.decorView.systemUiVisibility =
@@ -151,7 +156,7 @@ class MovieEditActivity : AppCompatActivity(),
         movieEditView.onAddMusicClickListener = View.OnClickListener(this::addMusic)
         movieEditView.onEditMusicClickListener = View.OnClickListener(this::editMusic)
         movieEditView.onDeleteMusicClickListener = View.OnClickListener(this::deleteMusic)
-        movieEditView.onSaveMovieClickListener = View.OnClickListener(this::saveMovie)
+        movieEditView.onSaveMovieClickListener = View.OnClickListener(this::onClickSaveAndShareBtn)
         movieEditView.onSeekBarChangeListener = object : SeekBar.OnSeekBarChangeListener {
             override fun onProgressChanged(seekBar: SeekBar?, progress: Int, fromUser: Boolean) {
                 if (fromUser) {
@@ -264,7 +269,53 @@ class MovieEditActivity : AppCompatActivity(),
         }
     }
 
-    private fun saveMovie(view: View) {
+    private fun onClickSaveAndShareBtn(view: View) {
+        shareDialog.apply {
+            name = project?.name ?: ""
+            author = project?.author ?: ""
+            onClickMore = Runnable { saveMovie() }
+            onClickExportPdf = Runnable { onClickExportPdf() }
+        }.show(supportFragmentManager)
+    }
+
+    private fun onClickExportPdf() {
+        ExportPdfDialog().also { exportPdfDialog ->
+            exportPdfDialog.image1Path = project?.scene1File?.path ?: ""
+            exportPdfDialog.image2Path = project?.scene2File?.path ?: ""
+            exportPdfDialog.onClickPrint = Runnable {
+                when (exportPdfDialog.type) {
+                    ExportPdfDialog.Type.Standard -> {
+                        val name = "standard_${project?.name}_${System.currentTimeMillis()}.pdf"
+                        if (!Config.PDF_FOLDER.exists()) {
+                            Config.PDF_FOLDER.mkdirs()
+                        }
+                        val file = File(Config.PDF_FOLDER, name)
+                        file.createNewFile()
+                        val observable = PdfMaker.makeStandard(this@MovieEditActivity, project!!, file)
+                        Pair(file, observable)
+                    }
+                    ExportPdfDialog.Type.Booklet -> {
+                        val name = "booklet_${project?.name}_${System.currentTimeMillis()}.pdf"
+                        if (!Config.PDF_FOLDER.exists()) {
+                            Config.PDF_FOLDER.mkdirs()
+                        }
+                        val file = File(Config.PDF_FOLDER, name)
+                        file.createNewFile()
+                        val observable = PdfMaker.makeBooklet(this@MovieEditActivity, project!!, file)
+                        Pair(file, observable)
+                    }
+                }.apply {
+                    exportPdfFile(second, Runnable {
+                        exportPdfDialog.dismiss()
+                    }, Runnable {
+                        showPdfExportCompleteDialog(first)
+                    })
+                }
+            }
+        }.show(supportFragmentManager)
+    }
+
+    private fun saveMovie() {
         val scaledWidth = resources.getDimensionPixelSize(R.dimen.movie_width)
         val scaleHeight = resources.getDimensionPixelSize(R.dimen.movie_height)
 
@@ -322,4 +373,47 @@ class MovieEditActivity : AppCompatActivity(),
                 })
     }
 
+    private fun exportPdfFile(observable: Observable<Float>, onFinally: Runnable, onComplete: Runnable) {
+        val pd = ProgressDialog(this@MovieEditActivity).apply {
+            setCancelable(false)
+        }
+        observable.subscribeOn(Schedulers.io())
+                .observeOn(AndroidSchedulers.mainThread())
+                .doOnSubscribe { pd.show() }
+                .doFinally {
+                    pd.dismiss()
+                    onFinally.run()
+                }
+                .subscribe({
+                    val progress = (it * 100).toInt()
+                    val msg = if (progress >= 100) {
+                        "processing ..."
+                    } else {
+                        "$progress%"
+                    }
+                    pd.setMessage(msg)
+                }, {
+                }, {
+                    onComplete.run()
+                })
+    }
+
+    private fun showPdfExportCompleteDialog(file: File) {
+        AlertDialog.Builder(this@MovieEditActivity)
+                .setMessage("Complete")
+                .setPositiveButton("View") { _, _ ->
+                    val uri = Uri.parse(file.absolutePath)
+                    val intent = Intent(Intent.ACTION_VIEW, uri).apply {
+                        setDataAndType(uri, "application/pdf")
+                    }
+                    if (intent.resolveActivity(packageManager) != null) {
+                        Intent.createChooser(intent, "").apply {
+                            startActivity(this)
+                        }
+                    } else {
+                        Toast.makeText(this@MovieEditActivity, "No app can view pdf", Toast.LENGTH_SHORT).show()
+                    }
+                }.show()
+    }
+
 }

+ 103 - 0
src/main/java/com/bomostory/sceneeditmodule/PdfMaker.kt

@@ -0,0 +1,103 @@
+package com.bomostory.sceneeditmodule
+
+import android.content.Context
+import android.graphics.*
+import com.bomostory.pdfexport.PdfBookWriter
+import com.bomostory.pdfexport.StandardPdfWriter
+import com.bomostory.sceneeditmodule.basicdata.Project
+import com.example.tfat.myapplication.R
+import io.reactivex.Observable
+import java.io.File
+
+object PdfMaker {
+    fun makeStandard(context: Context, project: Project, file: File): Observable<Float> {
+        return Observable.create { emitter ->
+            val total = (2 + project.story?.scenes?.size!!).toFloat()
+            var progress = 0
+            val width = 1920
+            val height = 1080
+            val coverWidth = width / 2
+            emitter.onNext(progress++ / total)
+            val front = drawFrontCover(coverWidth, height, project.name ?: "")
+            emitter.onNext(progress++ / total)
+            val back = drawBackCover(context, coverWidth, height)
+            emitter.onNext(progress++ / total)
+            val standardPdfWriter = StandardPdfWriter(file, front, back)
+            project.story?.scenes?.forEach {
+                val bitmap = SceneDrawer.drawScene(it, 0, width, height) ?: return@forEach
+                standardPdfWriter.addImage(bitmap)
+                emitter.onNext(progress++ / total)
+            }
+            standardPdfWriter.finish()
+            emitter.onComplete()
+        }
+    }
+
+    fun makeBooklet(context: Context, project: Project, file: File): Observable<Float> {
+        return Observable.create { emitter ->
+            val total = (2 + project.story?.scenes?.size!!).toFloat()
+            var progress = 0
+            val width = 1920 / 2
+            val height = 1080
+            val name = project?.name ?: ""
+            val author = project?.author ?: ""
+            emitter.onNext(progress++ / total)
+            /** front **/
+            val front = drawFrontCover(width, height, name)
+            emitter.onNext(progress++ / total)
+            /** back **/
+            val back = drawBackCover(context, width, height)
+            emitter.onNext(progress++ / total)
+            /** pages **/
+            val pdfBookWriter = PdfBookWriter(file, front, back)
+            project.story?.scenes?.forEach {
+                val bitmap = SceneDrawer.drawScene(it, 0, width, height) ?: return@forEach
+                pdfBookWriter.addImage(bitmap)
+                emitter.onNext(progress++ / total)
+            }
+            pdfBookWriter.finish()
+            emitter.onComplete()
+        }
+    }
+
+    private fun drawFrontCover(width: Int, height: Int, name: String): Bitmap {
+        val paint = Paint(Paint.ANTI_ALIAS_FLAG).apply {
+            color = Color.WHITE
+            textSize = 100f
+            textAlign = Paint.Align.CENTER
+            flags += Paint.FAKE_BOLD_TEXT_FLAG
+        }
+        return Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_4444).apply {
+            Canvas(this).apply {
+                drawColor(Color.parseColor("#faa600"))
+                val marginBottom = height / 20
+                val rect = Rect(0, height - height / 3 - marginBottom, width, height - marginBottom)
+                val p = Paint(Paint.ANTI_ALIAS_FLAG).apply {
+                    color = Color.parseColor("#66ffffff")
+                    style = Paint.Style.FILL_AND_STROKE
+                }
+                drawRect(rect, p)
+                drawText(name, rect.centerX().toFloat(), rect.centerY().toFloat(), paint)
+            }
+        }
+    }
+
+    private fun drawBackCover(context: Context, width: Int, height: Int): Bitmap {
+        return Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_4444).apply {
+            Canvas(this).apply {
+                drawColor(Color.parseColor("#faa600"))
+                val drawable = context.getDrawable(R.drawable.ic_logo_full_white)
+                val marginBottom = this.height / 10
+                val w = this.width / 3
+                val scale = w.toFloat() / drawable.intrinsicWidth.toFloat()
+                val h = drawable.intrinsicHeight * scale
+                val left = (this.width - w) / 2
+                val top = (this.height - h) - marginBottom
+                val right = (this.width + w) / 2
+                val bottom = (this.height) - marginBottom
+                drawable.setBounds(left, top.toInt(), right, bottom)
+                drawable.draw(this)
+            }
+        }
+    }
+}

+ 35 - 0
src/main/java/com/bomostory/sceneeditmodule/SceneDrawer.kt

@@ -0,0 +1,35 @@
+package com.bomostory.sceneeditmodule
+
+import android.graphics.Bitmap
+import android.graphics.BitmapFactory
+import android.graphics.Canvas
+import android.graphics.Paint
+import com.bomostory.sceneeditmodule.basicdata.Scene
+import kotlin.math.pow
+
+object SceneDrawer {
+    fun drawScene(scene: Scene, trackX: Int, scaleWidth: Int, scaleHeight: Int): Bitmap? {
+        var sceneBitmap: Bitmap? = null
+
+        scene?.apply {
+            sceneBitmap = BitmapFactory.decodeFile(backgroundPath)
+            sceneBitmap = Bitmap.createScaledBitmap(sceneBitmap, scaleWidth, scaleHeight, true)
+
+            val canvas = Canvas(sceneBitmap)
+            for (layer in layers) {
+                for (actor in layer.actors) {
+                    var actorBitmap = BitmapFactory.decodeFile(actor.resourcePath)
+                    actorBitmap = Bitmap.createScaledBitmap(actorBitmap, actor.sideLength, actor.sideLength, true)
+
+                    canvas.save()
+                    canvas.translate(trackX / 2f.pow(layers.indexOf(layer)), 0f)
+                    canvas.drawBitmap(actorBitmap, actor.positionX.toFloat(), actor.positionY.toFloat(), Paint())
+                    canvas.restore()
+
+                    actorBitmap.recycle()
+                }
+            }
+        }
+        return sceneBitmap
+    }
+}

+ 3 - 31
src/main/java/com/bomostory/sceneeditmodule/SuperMovieMaker.kt

@@ -1,9 +1,6 @@
 package com.bomostory.sceneeditmodule
 
 import android.graphics.Bitmap
-import android.graphics.BitmapFactory
-import android.graphics.Canvas
-import android.graphics.Paint
 import android.util.Log
 import com.bomostory.sceneeditmodule.MovieEditActivity.Companion.FPS
 import com.bomostory.sceneeditmodule.basicdata.Music
@@ -21,7 +18,6 @@ import java.util.concurrent.Semaphore
 import kotlin.collections.ArrayList
 import kotlin.collections.LinkedHashMap
 import kotlin.collections.set
-import kotlin.math.pow
 
 class SuperMovieMaker {
 
@@ -53,7 +49,7 @@ class SuperMovieMaker {
                 Completable.create {
                     project?.story?.apply {
                         val scene = scenes[frameData.sceneIndex]
-                        val bitmap = drawScene(scene, frameData.x, scaleWidth, scaleHeight)
+                        val bitmap = SceneDrawer.drawScene(scene, frameData.x, scaleWidth, scaleHeight)
                         movieBuilder.addImage(i, bitmap!!).blockingSubscribe()
                     }
                     it.onComplete()
@@ -128,7 +124,7 @@ class SuperMovieMaker {
         return Observable.create<AbstractMap.SimpleEntry<Int, Bitmap>> {
             scene?.apply {
                 record?.apply {
-                    var bitmap = drawScene(scene, 0, scaleWidth, scaleHeight)
+                    var bitmap = SceneDrawer.drawScene(scene, 0, scaleWidth, scaleHeight)
                     var bitmapIndex = 0
                     var trackPosition = -1
 
@@ -138,7 +134,7 @@ class SuperMovieMaker {
                                 preBitmap = bitmap
                                 preBitmap?.recycle()
 
-                                bitmap = drawScene(scene, track.positionX, scaleWidth, scaleHeight)
+                                bitmap = SceneDrawer.drawScene(scene, track.positionX, scaleWidth, scaleHeight)
                                 trackPosition = tracks.indexOf(track)
                             }
                         }
@@ -153,30 +149,6 @@ class SuperMovieMaker {
         }
     }
 
-    private fun drawScene(scene: Scene, trackX: Int, scaleWidth: Int, scaleHeight: Int): Bitmap? {
-        var sceneBitmap: Bitmap? = null
-
-        scene?.apply {
-            sceneBitmap = BitmapFactory.decodeFile(backgroundPath)
-            sceneBitmap = Bitmap.createScaledBitmap(sceneBitmap, scaleWidth, scaleHeight, true)
-
-            val canvas = Canvas(sceneBitmap)
-            for (layer in layers) {
-                for (actor in layer.actors) {
-                    var actorBitmap = BitmapFactory.decodeFile(actor.resourcePath)
-                    actorBitmap = Bitmap.createScaledBitmap(actorBitmap, actor.sideLength, actor.sideLength, true)
-
-                    canvas.save()
-                    canvas.translate(trackX / 2f.pow(layers.indexOf(layer)), 0f)
-                    canvas.drawBitmap(actorBitmap, actor.positionX.toFloat(), actor.positionY.toFloat(), Paint())
-                    canvas.restore()
-
-                    actorBitmap.recycle()
-                }
-            }
-        }
-        return sceneBitmap
-    }
 
     data class FrameData(val sceneIndex: Int, val x: Int, var repeat: Int)
 }

+ 65 - 0
src/main/java/com/bomostory/sceneeditmodule/share/ExportPdfDialog.kt

@@ -0,0 +1,65 @@
+package com.bomostory.sceneeditmodule.share
+
+import android.os.Bundle
+import android.support.v4.app.DialogFragment
+import android.support.v4.app.FragmentManager
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import com.example.tfat.myapplication.R
+import com.squareup.picasso.Picasso
+import kotlinx.android.synthetic.main.dialog_export_pdf.view.*
+
+class ExportPdfDialog : DialogFragment() {
+    private val dialogTag = this::class.java.simpleName
+
+    enum class Type {
+        Standard,
+        Booklet,
+    }
+
+    var image1Path = ""
+    var image2Path = ""
+    var image3Path = ""
+    var onClickPrint = Runnable { }
+    var type = Type.Standard
+
+    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
+        return inflater.inflate(R.layout.dialog_export_pdf, container, false).apply {
+            rb_exportPdfDialog_foldableBooklet.setOnCheckedChangeListener { _, b ->
+                if (b) {
+                    rb_exportPdfDialog_standard.isChecked = false
+                    type = Type.Booklet
+                }
+            }
+            rb_exportPdfDialog_standard.setOnCheckedChangeListener { _, b ->
+                if (b) {
+                    rb_exportPdfDialog_foldableBooklet.isChecked = false
+                    type = Type.Standard
+                }
+            }
+            btn_exportPdfDialog_cancel.setOnClickListener { this@ExportPdfDialog.dismiss() }
+            btn_exportPdfDialog_print.setOnClickListener { onClickPrint.run() }
+            if (image1Path != "") {
+                Picasso.get().load(image1Path).into(iv_exportPdfDialog_standard_1)
+                Picasso.get().load(image1Path).into(iv_exportPdfDialog_foldableBooklet_1)
+            }
+            if (image2Path != "") {
+                Picasso.get().load(image2Path).into(iv_exportPdfDialog_standard_2)
+            }
+            if (image3Path != "") {
+                Picasso.get().load(image3Path).into(iv_exportPdfDialog_standard_3)
+            }
+        }
+    }
+
+    fun show(manager: FragmentManager?) {
+        manager?.apply {
+            val ft = beginTransaction()
+            findFragmentByTag(dialogTag)?.let { ft.remove(it) }
+            ft.addToBackStack(null)
+            ft.commit()
+        }
+        super.show(manager, dialogTag)
+    }
+}

+ 52 - 0
src/main/java/com/bomostory/sceneeditmodule/share/ShareDialog.kt

@@ -0,0 +1,52 @@
+package com.bomostory.sceneeditmodule.share
+
+import android.os.Bundle
+import android.support.v4.app.DialogFragment
+import android.support.v4.app.FragmentManager
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import com.example.tfat.myapplication.R
+import kotlinx.android.synthetic.main.dialog_share.view.*
+
+class ShareDialog : DialogFragment() {
+
+    private val dialogTag = this::class.java.simpleName
+
+    var name: String = ""
+    var author: String = ""
+
+    var onClickEditCover = Runnable {}
+    var onClickExportPdf = Runnable {}
+    var onClickPrint = Runnable {}
+    var onClickBomo = Runnable {}
+    var onClickYoutube = Runnable {}
+    var onClickFacebook = Runnable {}
+    var onClickTwitter = Runnable {}
+    var onClickMore = Runnable {}
+
+    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
+        return inflater.inflate(R.layout.dialog_share, container, false).apply {
+            tv_shareDialog_name.text = name
+            tv_shareDialog_author.text = author
+            tv_shareDialog_editCover.setOnClickListener { onClickEditCover.run() }
+            tv_shareDialog_exportPdf.setOnClickListener { onClickExportPdf.run() }
+            tv_shareDialog_print.setOnClickListener { onClickPrint.run() }
+            iv_shareDialog_bomo.setOnClickListener { onClickBomo.run() }
+            iv_shareDialog_youtube.setOnClickListener { onClickYoutube.run() }
+            iv_shareDialog_facebook.setOnClickListener { onClickFacebook.run() }
+            iv_shareDialog_twitter.setOnClickListener { onClickTwitter.run() }
+            iv_shareDialog_more.setOnClickListener { onClickMore.run() }
+        }
+    }
+
+    fun show(manager: FragmentManager?) {
+        manager?.apply {
+            val ft = beginTransaction()
+            findFragmentByTag(dialogTag)?.let { ft.remove(it) }
+            ft.addToBackStack(null)
+            ft.commit()
+        }
+        super.show(manager, dialogTag)
+    }
+}

+ 5 - 0
src/main/res/drawable/bg_rounded_8dp.xml

@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android">
+    <solid android:color="@android:color/transparent" />
+    <corners android:radius="8dp" />
+</shape>

File diff suppressed because it is too large
+ 38 - 0
src/main/res/drawable/ic_btn_bomo_01.xml


+ 18 - 0
src/main/res/drawable/ic_btn_facebook_01.xml

@@ -0,0 +1,18 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="24dp"
+    android:height="24dp"
+    android:viewportWidth="48"
+    android:viewportHeight="48">
+    <path
+        android:fillColor="#00000000"
+        android:fillType="evenOdd"
+        android:pathData="M24,24m-19.5,0a19.5,19.5 0,1 1,39 0a19.5,19.5 0,1 1,-39 0"
+        android:strokeWidth="1"
+        android:strokeColor="#4E342E" />
+    <path
+        android:fillColor="#4E342E"
+        android:fillType="evenOdd"
+        android:pathData="M25.5469,33.9844L21.8438,33.9844L21.8438,24.8906L18.75,24.8906L18.75,21.3281L21.8438,21.3281L21.8438,18.7031C21.8438,17.2031 22.2656,16.0469 23.1094,15.2344C23.9531,14.4219 25.0781,14.0156 26.4844,14.0156C27.6094,14.0156 28.5312,14.0625 29.25,14.1563L29.25,17.2969L27.3281,17.3438C26.6406,17.3438 26.1719,17.4844 25.9219,17.7656C25.6719,18.0469 25.5469,18.4687 25.5469,19.0313L25.5469,21.3281L29.1094,21.3281L28.6406,24.8906L25.5469,24.8906L25.5469,33.9844Z"
+        android:strokeWidth="1"
+        android:strokeColor="#00000000" />
+</vector>

File diff suppressed because it is too large
+ 18 - 0
src/main/res/drawable/ic_btn_more_01.xml


File diff suppressed because it is too large
+ 18 - 0
src/main/res/drawable/ic_btn_twitter_01.xml


File diff suppressed because it is too large
+ 18 - 0
src/main/res/drawable/ic_btn_youtube_01.xml


+ 20 - 0
src/main/res/drawable/ic_cover.xml

@@ -0,0 +1,20 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="24dp"
+    android:height="24dp"
+    android:viewportWidth="24"
+    android:viewportHeight="24">
+    <path
+        android:fillAlpha="0.3"
+        android:fillColor="#4E342E"
+        android:fillType="nonZero"
+        android:pathData="M13,13l-3,-2.25l-3,2.25l0,-9l-1,0l0,16l12,0l0,-16l-5,0z"
+        android:strokeWidth="1"
+        android:strokeAlpha="0.3"
+        android:strokeColor="#00000000" />
+    <path
+        android:fillColor="#4E342E"
+        android:fillType="nonZero"
+        android:pathData="M18,2L6,2C4.9,2 4,2.9 4,4L4,20C4,21.1 4.9,22 6,22L18,22C19.1,22 20,21.1 20,20L20,4C20,2.9 19.1,2 18,2ZM9,4L11,4L11,9L10,8.25L9,9L9,4ZM18,20L6,20L6,4L7,4L7,13L10,10.75L13,13L13,4L18,4L18,20Z"
+        android:strokeWidth="1"
+        android:strokeColor="#00000000" />
+</vector>

+ 9 - 0
src/main/res/drawable/ic_cover_36dp.xml

@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8"?>
+<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
+
+    <item
+        android:width="36dp"
+        android:height="36dp"
+        android:drawable="@drawable/ic_cover" />
+
+</layer-list>

+ 32 - 0
src/main/res/drawable/ic_exportpdf.xml

@@ -0,0 +1,32 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="24dp"
+    android:height="24dp"
+    android:viewportWidth="24"
+    android:viewportHeight="24">
+    <path
+        android:fillAlpha="0.3"
+        android:fillColor="#4E342E"
+        android:fillType="nonZero"
+        android:pathData="M13,4L6,4L6,20L18,20L18,9L13,9L13,4ZM16,18L8,18L8,16L16,16L16,18ZM16,12L16,14L8,14L8,12L16,12Z"
+        android:strokeWidth="1"
+        android:strokeAlpha="0.3"
+        android:strokeColor="#00000000" />
+    <path
+        android:fillColor="#4E342E"
+        android:fillType="nonZero"
+        android:pathData="M8,16h8v2h-8z"
+        android:strokeWidth="1"
+        android:strokeColor="#00000000" />
+    <path
+        android:fillColor="#4E342E"
+        android:fillType="nonZero"
+        android:pathData="M8,12h8v2h-8z"
+        android:strokeWidth="1"
+        android:strokeColor="#00000000" />
+    <path
+        android:fillColor="#4E342E"
+        android:fillType="nonZero"
+        android:pathData="M14,2L6,2C4.9,2 4,2.9 4,4L4,20C4,21.1 4.89,22 5.99,22L18,22C19.1,22 20,21.1 20,20L20,8L14,2ZM18,20L6,20L6,4L13,4L13,9L18,9L18,20Z"
+        android:strokeWidth="1"
+        android:strokeColor="#00000000" />
+</vector>

+ 9 - 0
src/main/res/drawable/ic_exportpdf_36dp.xml

@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8"?>
+<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
+
+    <item
+        android:width="36dp"
+        android:height="36dp"
+        android:drawable="@drawable/ic_exportpdf" />
+
+</layer-list>

File diff suppressed because it is too large
+ 475 - 0
src/main/res/drawable/ic_img_foldable.xml


File diff suppressed because it is too large
+ 76 - 0
src/main/res/drawable/ic_logo_full_white.xml


+ 5 - 1
src/main/res/drawable/ic_play.xml

@@ -6,11 +6,15 @@
   <path
       android:pathData="M10,8.64l0,6.72l5.27,-3.36z"
       android:strokeAlpha="0.3"
+      android:strokeWidth="1"
       android:fillColor="#4E342E"
       android:fillType="nonZero"
+      android:strokeColor="#00000000"
       android:fillAlpha="0.3"/>
   <path
       android:pathData="M8,19L19,12L8,5L8,19ZM10,8.64L15.27,12L10,15.36L10,8.64Z"
+      android:fillType="nonZero"
       android:fillColor="#4E342E"
-      android:fillType="nonZero"/>
+      android:strokeWidth="1"
+      android:strokeColor="#00000000" />
 </vector>

+ 34 - 0
src/main/res/drawable/ic_print.xml

@@ -0,0 +1,34 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="24dp"
+    android:height="24dp"
+    android:viewportWidth="24"
+    android:viewportHeight="24">
+    <path
+        android:fillAlpha="0.3"
+        android:fillColor="#4E342E"
+        android:fillType="nonZero"
+        android:pathData="M8,5h8v3h-8z"
+        android:strokeWidth="1"
+        android:strokeAlpha="0.3"
+        android:strokeColor="#00000000" />
+    <path
+        android:fillAlpha="0.3"
+        android:fillColor="#4E342E"
+        android:fillType="nonZero"
+        android:pathData="M6,13L18,13L18,15L20,15L20,11C20,10.45 19.55,10 19,10L18,10L6,10L5,10C4.45,10 4,10.45 4,11L4,15L6,15L6,13ZM18,10.5C18.55,10.5 19,10.95 19,11.5C19,12.05 18.55,12.5 18,12.5C17.45,12.5 17,12.05 17,11.5C17,10.95 17.45,10.5 18,10.5Z"
+        android:strokeWidth="1"
+        android:strokeAlpha="0.3"
+        android:strokeColor="#00000000" />
+    <path
+        android:fillColor="#4E342E"
+        android:fillType="nonZero"
+        android:pathData="M18,11.5m-1,0a1,1 0,1 1,2 0a1,1 0,1 1,-2 0"
+        android:strokeWidth="1"
+        android:strokeColor="#00000000" />
+    <path
+        android:fillColor="#4E342E"
+        android:fillType="nonZero"
+        android:pathData="M19,8L18,8L18,3L6,3L6,8L5,8C3.34,8 2,9.34 2,11L2,15L2,17L6,17L6,21L18,21L18,17L22,17L22,15L22,11C22,9.34 20.66,8 19,8ZM8,5L16,5L16,8L8,8L8,5ZM16,19L8,19L8,15L16,15L16,19ZM20,15L18,15L18,13L6,13L6,15L4,15L4,11C4,10.45 4.45,10 5,10L6,10L18,10L19,10C19.55,10 20,10.45 20,11L20,15Z"
+        android:strokeWidth="1"
+        android:strokeColor="#00000000" />
+</vector>

+ 9 - 0
src/main/res/drawable/ic_print_36dp.xml

@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8"?>
+<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
+
+    <item
+        android:width="36dp"
+        android:height="36dp"
+        android:drawable="@drawable/ic_print" />
+
+</layer-list>

+ 144 - 0
src/main/res/layout/dialog_export_pdf.xml

@@ -0,0 +1,144 @@
+<?xml version="1.0" encoding="utf-8"?>
+<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    android:layout_width="800dp"
+    android:layout_height="544dp"
+    android:background="@drawable/bg_rounded_8dp"
+    android:elevation="8dp">
+
+    <View
+        android:id="@+id/view_exportPdfDialog_header"
+        android:layout_width="0dp"
+        android:layout_height="64dp"
+        android:background="@color/pale_peach"
+        app:layout_constraintLeft_toLeftOf="parent"
+        app:layout_constraintRight_toRightOf="parent"
+        app:layout_constraintTop_toTopOf="parent" />
+
+    <TextView
+        android:id="@+id/tv_exportPdfDialog_name"
+        style="@style/Title"
+        android:text="@string/export_pdf_dialog_title"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:textColor="@color/cocoa"
+        app:layout_constraintBottom_toBottomOf="@id/view_exportPdfDialog_header"
+        app:layout_constraintLeft_toLeftOf="@id/view_exportPdfDialog_header"
+        app:layout_constraintRight_toRightOf="@id/view_exportPdfDialog_header"
+        app:layout_constraintTop_toTopOf="@id/view_exportPdfDialog_header" />
+
+    <RadioButton
+        android:id="@+id/rb_exportPdfDialog_standard"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginLeft="52dp"
+        android:layout_marginTop="48dp"
+        android:buttonTint="@color/cocoa"
+        android:checked="true"
+        app:layout_constraintLeft_toLeftOf="parent"
+        app:layout_constraintTop_toBottomOf="@id/view_exportPdfDialog_header" />
+
+    <TextView
+        android:id="@+id/tv_exportPdfDialog_standard"
+        style="@style/Body1"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginLeft="36dp"
+        android:text="@string/export_pdf_dialog_radio_standard"
+        android:textColor="@color/cocoa"
+        app:layout_constraintBottom_toBottomOf="@id/rb_exportPdfDialog_standard"
+        app:layout_constraintLeft_toRightOf="@id/rb_exportPdfDialog_standard"
+        app:layout_constraintTop_toTopOf="@id/rb_exportPdfDialog_standard" />
+
+    <ImageView
+        android:id="@+id/iv_exportPdfDialog_standard_1"
+        android:layout_width="144dp"
+        android:layout_height="72dp"
+        android:layout_marginTop="24dp"
+        android:scaleType="centerCrop"
+        app:layout_constraintLeft_toLeftOf="@id/tv_exportPdfDialog_standard"
+        app:layout_constraintTop_toBottomOf="@id/tv_exportPdfDialog_standard" />
+
+    <ImageView
+        android:id="@+id/iv_exportPdfDialog_standard_2"
+        android:layout_width="144dp"
+        android:layout_height="72dp"
+        android:layout_marginLeft="16dp"
+        android:scaleType="centerCrop"
+        app:layout_constraintLeft_toRightOf="@id/iv_exportPdfDialog_standard_1"
+        app:layout_constraintTop_toTopOf="@id/iv_exportPdfDialog_standard_1" />
+
+    <ImageView
+        android:id="@+id/iv_exportPdfDialog_standard_3"
+        android:layout_width="144dp"
+        android:layout_height="72dp"
+        android:layout_marginLeft="16dp"
+        android:scaleType="centerCrop"
+        app:layout_constraintLeft_toRightOf="@id/iv_exportPdfDialog_standard_2"
+        app:layout_constraintTop_toTopOf="@id/iv_exportPdfDialog_standard_2" />
+
+    <RadioButton
+        android:id="@+id/rb_exportPdfDialog_foldableBooklet"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginLeft="52dp"
+        android:layout_marginTop="136dp"
+        android:buttonTint="@color/cocoa"
+        app:layout_constraintLeft_toLeftOf="parent"
+        app:layout_constraintTop_toBottomOf="@id/rb_exportPdfDialog_standard" />
+
+    <TextView
+        android:id="@+id/tv_exportPdfDialog_foldableBooklet"
+        style="@style/Body1"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginLeft="36dp"
+        android:text="@string/export_pdf_dialog_radio_foldable_booklet"
+        android:textColor="@color/cocoa"
+        app:layout_constraintBottom_toBottomOf="@id/rb_exportPdfDialog_foldableBooklet"
+        app:layout_constraintLeft_toRightOf="@id/rb_exportPdfDialog_foldableBooklet"
+        app:layout_constraintTop_toTopOf="@id/rb_exportPdfDialog_foldableBooklet" />
+
+    <ImageView
+        android:id="@+id/iv_exportPdfDialog_foldableBooklet_1"
+        android:layout_width="144dp"
+        android:layout_height="72dp"
+        android:layout_marginTop="24dp"
+        android:scaleType="centerCrop"
+        app:layout_constraintLeft_toLeftOf="@id/tv_exportPdfDialog_foldableBooklet"
+        app:layout_constraintTop_toBottomOf="@id/tv_exportPdfDialog_foldableBooklet" />
+
+    <ImageView
+        android:id="@+id/iv_exportPdfDialog_foldableBooklet_2"
+        android:layout_width="488dp"
+        android:layout_height="120dp"
+        android:layout_marginLeft="16dp"
+        android:layout_marginRight="40dp"
+        android:scaleType="centerCrop"
+        android:src="@drawable/ic_img_foldable"
+        app:layout_constraintLeft_toRightOf="@id/iv_exportPdfDialog_foldableBooklet_1"
+        app:layout_constraintRight_toRightOf="parent"
+        app:layout_constraintTop_toTopOf="@id/iv_exportPdfDialog_foldableBooklet_1" />
+    <Button
+        android:id="@+id/btn_exportPdfDialog_print"
+        style="@style/Widget.AppCompat.Button.Borderless.Colored"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:text="@string/export_pdf_dialog_print"
+        android:layout_marginTop="48dp"
+        android:layout_marginRight="24dp"
+        android:layout_marginBottom="24dp"
+        app:layout_constraintTop_toBottomOf="@id/iv_exportPdfDialog_foldableBooklet_2"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintRight_toRightOf="parent" />
+
+    <Button
+        android:id="@+id/btn_exportPdfDialog_cancel"
+        style="@style/Widget.AppCompat.Button.Borderless.Colored"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginRight="8dp"
+        android:text="@string/export_pdf_dialog_cancel"
+        app:layout_constraintBottom_toBottomOf="@id/btn_exportPdfDialog_print"
+        app:layout_constraintRight_toLeftOf="@id/btn_exportPdfDialog_print" />
+</android.support.constraint.ConstraintLayout>

+ 206 - 0
src/main/res/layout/dialog_share.xml

@@ -0,0 +1,206 @@
+<?xml version="1.0" encoding="utf-8"?>
+<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:layout_width="800dp"
+    android:layout_height="544dp"
+    android:background="@drawable/bg_rounded_8dp"
+    android:elevation="8dp">
+
+    <View
+        android:id="@+id/view_shareDialog_header"
+        android:layout_width="0dp"
+        android:layout_height="64dp"
+        android:background="@color/pale_peach"
+        app:layout_constraintLeft_toLeftOf="parent"
+        app:layout_constraintRight_toRightOf="parent"
+        app:layout_constraintTop_toTopOf="parent" />
+
+    <TextView
+        android:id="@+id/tv_shareDialog_name"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginTop="10dp"
+        android:fontFamily="sans-serif"
+        android:gravity="center_horizontal"
+        android:textColor="#de000000"
+        android:textSize="20sp"
+        android:textStyle="normal"
+        app:layout_constraintLeft_toLeftOf="parent"
+        app:layout_constraintRight_toRightOf="parent"
+        app:layout_constraintTop_toTopOf="parent"
+        tools:text="The frog king or Iron Henry" />
+
+    <TextView
+        android:id="@+id/tv_shareDialog_author"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginTop="4dp"
+        android:fontFamily="sans-serif"
+        android:gravity="center_horizontal"
+        android:textColor="#dd000000"
+        android:textSize="14sp"
+        android:textStyle="normal"
+        app:layout_constraintLeft_toLeftOf="parent"
+        app:layout_constraintRight_toRightOf="parent"
+        app:layout_constraintTop_toBottomOf="@id/tv_shareDialog_name"
+        tools:text="by Alexander Wilson" />
+
+    <View
+        android:id="@+id/view_shareDialog_preview"
+        android:layout_width="560dp"
+        android:layout_height="280dp"
+        android:layout_marginTop="24dp"
+        android:background="@color/cocoa"
+        app:layout_constraintLeft_toLeftOf="parent"
+        app:layout_constraintRight_toRightOf="parent"
+        app:layout_constraintTop_toBottomOf="@id/view_shareDialog_header" />
+
+    <TextView
+        android:id="@+id/tv_shareDialog_editCover"
+        style="@style/Body2"
+        android:layout_width="104dp"
+        android:layout_height="72dp"
+        android:layout_marginLeft="16dp"
+        android:layout_marginTop="16dp"
+        android:drawableTop="@drawable/ic_cover_36dp"
+        android:drawablePadding="8dp"
+        android:gravity="center"
+        android:text="@string/share_dialog_edit_cover"
+        app:layout_constraintBottom_toTopOf="@id/tv_shareDialog_exportPdf"
+        app:layout_constraintLeft_toLeftOf="parent"
+        app:layout_constraintRight_toLeftOf="@id/view_shareDialog_preview"
+        app:layout_constraintTop_toTopOf="@id/view_shareDialog_preview" />
+
+    <TextView
+        android:id="@+id/tv_shareDialog_exportPdf"
+        style="@style/Body2"
+        android:layout_width="104dp"
+        android:layout_height="72dp"
+        android:layout_marginLeft="16dp"
+        android:layout_marginTop="16dp"
+        android:drawableTop="@drawable/ic_exportpdf_36dp"
+        android:drawablePadding="8dp"
+        android:gravity="center"
+        android:text="@string/share_dialog_export_pdf"
+        app:layout_constraintBottom_toTopOf="@id/tv_shareDialog_print"
+        app:layout_constraintLeft_toLeftOf="parent"
+        app:layout_constraintRight_toLeftOf="@id/view_shareDialog_preview"
+        app:layout_constraintTop_toBottomOf="@id/tv_shareDialog_editCover" />
+
+    <TextView
+        android:id="@+id/tv_shareDialog_print"
+        style="@style/Body2"
+        android:layout_width="104dp"
+        android:layout_height="72dp"
+        android:layout_marginLeft="16dp"
+        android:layout_marginTop="16dp"
+        android:drawableTop="@drawable/ic_print_36dp"
+        android:drawablePadding="8dp"
+        android:gravity="center"
+        android:text="@string/share_dialog_print"
+        app:layout_constraintLeft_toLeftOf="parent"
+        app:layout_constraintRight_toLeftOf="@id/view_shareDialog_preview"
+        app:layout_constraintTop_toBottomOf="@id/tv_shareDialog_exportPdf" />
+
+    <ImageView
+        android:id="@+id/iv_shareDialog_bomo"
+        android:layout_width="48dp"
+        android:layout_height="48dp"
+        android:layout_marginLeft="36dp"
+        android:layout_marginRight="36dp"
+        android:src="@drawable/ic_btn_bomo_01"
+        app:layout_constraintLeft_toRightOf="@id/view_shareDialog_preview"
+        app:layout_constraintTop_toTopOf="@id/view_shareDialog_preview" />
+
+    <ImageView
+        android:id="@+id/iv_shareDialog_youtube"
+        android:layout_width="48dp"
+        android:layout_height="48dp"
+        android:layout_marginLeft="36dp"
+        android:layout_marginTop="16dp"
+        android:layout_marginRight="36dp"
+        android:src="@drawable/ic_btn_youtube_01"
+        app:layout_constraintLeft_toRightOf="@id/view_shareDialog_preview"
+        app:layout_constraintTop_toBottomOf="@id/iv_shareDialog_bomo" />
+
+    <ImageView
+        android:id="@+id/iv_shareDialog_facebook"
+        android:layout_width="48dp"
+        android:layout_height="48dp"
+        android:layout_marginLeft="36dp"
+        android:layout_marginTop="16dp"
+        android:layout_marginRight="36dp"
+        android:src="@drawable/ic_btn_facebook_01"
+        app:layout_constraintLeft_toRightOf="@id/view_shareDialog_preview"
+        app:layout_constraintTop_toBottomOf="@id/iv_shareDialog_youtube" />
+
+    <ImageView
+        android:id="@+id/iv_shareDialog_twitter"
+        android:layout_width="48dp"
+        android:layout_height="48dp"
+        android:layout_marginLeft="36dp"
+        android:layout_marginTop="16dp"
+        android:layout_marginRight="36dp"
+        android:src="@drawable/ic_btn_twitter_01"
+        app:layout_constraintLeft_toRightOf="@id/view_shareDialog_preview"
+        app:layout_constraintTop_toBottomOf="@id/iv_shareDialog_facebook" />
+
+    <ImageView
+        android:id="@+id/iv_shareDialog_more"
+        android:layout_width="48dp"
+        android:layout_height="48dp"
+        android:layout_marginLeft="36dp"
+        android:layout_marginTop="16dp"
+        android:layout_marginRight="36dp"
+        android:src="@drawable/ic_btn_more_01"
+        app:layout_constraintLeft_toRightOf="@id/view_shareDialog_preview"
+        app:layout_constraintTop_toBottomOf="@id/iv_shareDialog_twitter" />
+
+    <ImageView
+        android:id="@+id/iv_shareDialog_play"
+        android:layout_width="48dp"
+        android:layout_height="48dp"
+        android:layout_marginTop="8dp"
+        android:src="@drawable/ic_play"
+        app:layout_constraintLeft_toLeftOf="@id/view_shareDialog_preview"
+        app:layout_constraintTop_toBottomOf="@id/view_shareDialog_preview" />
+
+    <TextView
+        android:id="@+id/tv_shareDialog_time"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:fontFamily="sans-serif-medium"
+        android:textColor="#4e342e"
+        android:textSize="16sp"
+        android:textStyle="normal"
+        app:layout_constraintBottom_toBottomOf="@id/iv_shareDialog_play"
+        app:layout_constraintRight_toRightOf="@id/view_shareDialog_preview"
+        app:layout_constraintTop_toTopOf="@id/iv_shareDialog_play"
+        tools:text="0:20/3:00" />
+
+    <SeekBar
+        android:layout_width="0dp"
+        android:layout_height="wrap_content"
+        android:layout_marginLeft="16dp"
+        android:layout_marginRight="16dp"
+        android:progressTint="@color/cocoa"
+        android:thumbTint="@color/cocoa"
+        app:layout_constraintBottom_toBottomOf="@id/iv_shareDialog_play"
+        app:layout_constraintLeft_toRightOf="@id/iv_shareDialog_play"
+        app:layout_constraintRight_toLeftOf="@id/tv_shareDialog_time"
+        app:layout_constraintTop_toTopOf="@id/iv_shareDialog_play"
+        tools:progress="100" />
+
+    <View
+        android:id="@+id/view_shareDialog_scenes"
+        android:layout_width="560dp"
+        android:layout_height="88dp"
+        android:layout_marginTop="8dp"
+        android:layout_marginBottom="24dp"
+        android:background="@color/pale_peach"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintLeft_toLeftOf="parent"
+        app:layout_constraintRight_toRightOf="parent"
+        app:layout_constraintTop_toBottomOf="@id/iv_shareDialog_play" />
+</android.support.constraint.ConstraintLayout>

+ 10 - 0
src/main/res/values/strings.xml

@@ -12,4 +12,14 @@
 
     <!-- TODO: Remove or change this placeholder text -->
     <string name="hello_blank_fragment">Hello blank fragment</string>
+
+    <string name="share_dialog_edit_cover">Edit Cover</string>
+    <string name="share_dialog_export_pdf">Export PDF</string>
+    <string name="share_dialog_print">Print</string>
+
+    <string name="export_pdf_dialog_title">Choose PDF format</string>
+    <string name="export_pdf_dialog_radio_standard">Standard PDF</string>
+    <string name="export_pdf_dialog_radio_foldable_booklet">Foldable Booklet</string>
+    <string name="export_pdf_dialog_print">Print</string>
+    <string name="export_pdf_dialog_cancel">Cancel</string>
 </resources>