diff --git a/app/src/main/java/com/lhw/pdf/MainActivity.kt b/app/src/main/java/com/lhw/pdf/MainActivity.kt index c0790ef..9ee902a 100644 --- a/app/src/main/java/com/lhw/pdf/MainActivity.kt +++ b/app/src/main/java/com/lhw/pdf/MainActivity.kt @@ -5,9 +5,9 @@ import android.content.Intent import android.graphics.PorterDuff import android.hardware.display.DisplayManager import android.hardware.display.DisplayManager.DisplayListener -import android.media.MediaRouter import android.os.Bundle import android.util.DisplayMetrics +import android.view.Display import android.view.Menu import android.view.WindowManager import android.widget.ImageView @@ -33,12 +33,11 @@ class MainActivity : AppCompatActivity() { private lateinit var appBarConfiguration: AppBarConfiguration private lateinit var binding: ActivityMainBinding private lateinit var displayManager: DisplayManager - private lateinit var mediaRouter: MediaRouter private val thumbnailWidth = 500 private val thumbnailHeight = 700 private var renderAutoCrop = true private var pagesPerLandscape = 3F - private var presentation: MyPresentation? = null + private val presentations = mutableMapOf() private lateinit var pdfDocument: PdfDocument private val showPages = mutableListOf() private val thumbnailImageViews = mutableListOf() @@ -46,18 +45,27 @@ class MainActivity : AppCompatActivity() { private val displayListener = object: DisplayListener { override fun onDisplayAdded(p0: Int) { - updateDisplayText() + reevaluateDisplay(p0) } override fun onDisplayChanged(p0: Int) { - updateDisplayText() + reevaluateDisplay(p0) } override fun onDisplayRemoved(p0: Int) { - updateDisplayText() + reevaluateDisplay(p0) } } + private fun reevaluateDisplay(p0: Int) { + presentations.remove(p0)?.cancel() // Pop any presentation associated with this display index, and clean it up + displayManager.getDisplay(p0)?.let { display -> + if (display.flags and Display.FLAG_PRESENTATION == 0) return + makePresentationView(display) + } + updateDisplayText() + } + private fun inputStreamToCache(outputFilename: String, inputStream: InputStream): File { val fileCached = File(cacheDir, outputFilename) val output = FileOutputStream(fileCached) @@ -69,30 +77,34 @@ class MainActivity : AppCompatActivity() { return fileCached } - private fun updatePresentationImages(reRender: Boolean = true) { - presentation?.let { p -> - if (reRender) { - println(p.displayMetrics) - val maxHeight: Int = p.displayMetrics.heightPixels - val maxWidth: Int = min(maxHeight * 5 / 7, (p.displayMetrics.widthPixels / pagesPerLandscape).toInt()) - println("Rendering pages with maxHeight=$maxHeight maxWidth=$maxWidth") - pdfDocument.renderPagesPresentation(maxWidth, maxHeight, renderAutoCrop) - } - val bitmaps = showPages.withIndex() - .mapNotNull { (i, show) -> if (show) pdfDocument.bitmapPagesPresentation[i] else null } - .toList() - p.updateImages(bitmaps) - } + private fun updateBitmaps(maxWidth: Int, maxHeight: Int) { + println("Rendering pages with maxHeight=$maxHeight maxWidth=$maxWidth") + pdfDocument.renderPages(maxWidth, maxHeight, renderAutoCrop) } - private fun makePresentationView() { - presentation = null - mediaRouter.getSelectedRoute(MediaRouter.ROUTE_TYPE_LIVE_VIDEO)?.presentationDisplay?.let { display -> - presentation = MyPresentation(this, display) - updatePresentationImages() - presentation?.setOnCancelListener { presentation = null } - presentation?.show() - } + private fun updatePresentationImages(p: MyPresentation) { + val maxHeight: Int = p.displayMetrics.heightPixels + val maxWidth: Int = min(maxHeight * 5 / 7, (p.displayMetrics.widthPixels / pagesPerLandscape).toInt()) + updateBitmaps(maxWidth, maxHeight) + val key = Pair(maxWidth, maxHeight) + val bitmaps = showPages.withIndex() + .mapNotNull { (i, show) -> if (show) pdfDocument.bitmapPages[key]?.get(i) else null } + .toList() + p.updateImages(bitmaps) + } + + private fun updatePresentations(reRender: Boolean = true) { + if (reRender) pdfDocument.invalidateCache() + presentations.values.forEach(::updatePresentationImages) + } + + private fun makePresentationView(display: Display) { + val id = display.displayId + val presentation = MyPresentation(this, display) + updatePresentationImages(presentation) + //presentation.setOnCancelListener { presentations.remove(id) } + presentations[id] = presentation + presentation.show() } private fun reLayoutThumbnails() { @@ -103,11 +115,10 @@ class MainActivity : AppCompatActivity() { showPages.map { if (it) container else disabledContainer }.zip(thumbnailImageViews).forEach { (cont, img) -> cont.addView(img) } - updatePresentationImages(false) + updatePresentations(false) } private fun populateThumbnails() { - val container = binding.appBarMain.contentMain.thumbnailsLayout for ((index, bitmap) in pdfDocument.bitmapThumbnails) { val img = ImageView(this) img.setImageBitmap(bitmap) @@ -125,7 +136,7 @@ class MainActivity : AppCompatActivity() { private fun updateDisplayText() { val displayText = binding.appBarMain.contentMain.textDisplays val text = StringBuilder() - //displayManager.getDisplays(DisplayManager.DISPLAY_CATEGORY_PRESENTATION).forEach { + displayManager.displays.forEach { val displayMetrics = DisplayMetrics() @Suppress("DEPRECATION") @@ -135,6 +146,7 @@ class MainActivity : AppCompatActivity() { text.append(s) text.append("\n") } + text.append(presentations) displayText.text = text.toString() } @@ -142,14 +154,12 @@ class MainActivity : AppCompatActivity() { super.onCreate(savedInstanceState) window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON) displayManager = getSystemService(Context.DISPLAY_SERVICE) as DisplayManager - mediaRouter = getSystemService(Context.MEDIA_ROUTER_SERVICE) as MediaRouter //val windowInsetsController = WindowCompat.getInsetsController(window, window.decorView) //windowInsetsController.hide(WindowInsetsCompat.Type.systemBars()) //Doesn't seem to actually fill the vacant space by default binding = ActivityMainBinding.inflate(layoutInflater) setContentView(binding.root) - updateDisplayText() displayManager.registerDisplayListener(displayListener, null) setSupportActionBar(binding.appBarMain.toolbar) @@ -164,13 +174,14 @@ class MainActivity : AppCompatActivity() { handleIntent(intent) pdfDocument.renderThumbnails(thumbnailWidth, thumbnailHeight) - makePresentationView() + displayManager.getDisplays(DisplayManager.DISPLAY_CATEGORY_PRESENTATION).forEach(::makePresentationView) populateThumbnails() val container = binding.appBarMain.contentMain.thumbnailsLayout val containerScroll = binding.appBarMain.contentMain.thumbnailsScroll containerScroll.viewTreeObserver.addOnScrollChangedListener { - presentation?.setScrollProgress(containerScroll.scrollX.toFloat() / (container.width - containerScroll.width)) + val progress = containerScroll.scrollX.toFloat() / (container.width - containerScroll.width) + presentations.values.forEach {it.setScrollProgress(progress)} } binding.appBarMain.crop.setOnClickListener { view -> @@ -179,21 +190,21 @@ class MainActivity : AppCompatActivity() { Snackbar.make(view, "Toggling Auto Crop $s", Snackbar.LENGTH_LONG) .setAction("Action", null) .setAnchorView(R.id.crop).show() - updatePresentationImages() + updatePresentations() } binding.appBarMain.zoomIn.setOnClickListener { view -> pagesPerLandscape = max(pagesPerLandscape - 0.5F, 1F) Snackbar.make(view, "Aiming for $pagesPerLandscape pages at a time", Snackbar.LENGTH_LONG) .setAction("Action", null) .setAnchorView(R.id.zoom_in).show() - updatePresentationImages() + updatePresentations() } binding.appBarMain.zoomOut.setOnClickListener { view -> pagesPerLandscape = min(pagesPerLandscape + 0.5F, 10F) Snackbar.make(view, "Aiming for $pagesPerLandscape pages at a time", Snackbar.LENGTH_LONG) .setAction("Action", null) .setAnchorView(R.id.zoom_out).show() - updatePresentationImages() + updatePresentations() } val drawerLayout: DrawerLayout = binding.drawerLayout val navView: NavigationView = binding.navView @@ -207,6 +218,7 @@ class MainActivity : AppCompatActivity() { ) setupActionBarWithNavController(navController, appBarConfiguration) navView.setupWithNavController(navController) + updateDisplayText() } private fun handleIntent(intent: Intent?) { diff --git a/app/src/main/java/com/lhw/pdf/PdfDocument.kt b/app/src/main/java/com/lhw/pdf/PdfDocument.kt index ff93a90..7708e34 100644 --- a/app/src/main/java/com/lhw/pdf/PdfDocument.kt +++ b/app/src/main/java/com/lhw/pdf/PdfDocument.kt @@ -7,7 +7,6 @@ import android.graphics.Rect import android.graphics.RectF import android.graphics.pdf.PdfRenderer import android.os.ParcelFileDescriptor -import androidx.core.graphics.times import java.io.File import kotlin.math.max import kotlin.math.min @@ -16,8 +15,7 @@ class PdfDocument(private val fileCached: File, private val autoCrop: Boolean = private val pfd = ParcelFileDescriptor.open(fileCached, ParcelFileDescriptor.MODE_READ_ONLY) private val renderer = PdfRenderer(pfd) val bitmapThumbnails = mutableMapOf() - val bitmapPagesMain = mutableMapOf() - val bitmapPagesPresentation = mutableMapOf() + val bitmapPages = mutableMapOf, MutableMap>() // bitmapPages[][pageId] private val pagePtWidths = mutableListOf() private val pagePtHeights = mutableListOf() private val pageAutoCropRects = mutableListOf() @@ -57,11 +55,11 @@ class PdfDocument(private val fileCached: File, private val autoCrop: Boolean = return bitmap } - private fun renderPagesToMap(map: MutableMap, width: Int, height: Int, crop: Boolean = false) { - map.clear() + private fun renderPagesToMap(map: MutableMap, width: Int, height: Int, crop: Boolean = false, overwrite: Boolean = true) { + if (overwrite) map.clear() val numPages = renderer.pageCount for (i in 0..() } + renderPagesToMap(map, maxWidth, maxHeight, crop, false) } } \ No newline at end of file