Add hamburger menu to the shelf that opens the About screen

This commit is contained in:
2026-10-17 06:17:54 -07:00
parent 45b3069b96
commit fbf372916d
7 changed files with 168 additions and 2 deletions

View File

@@ -40,6 +40,10 @@
android:name=".BookActivity"
android:exported="false"
android:label="@string/title_book" />
</application>
<activity
android:name=".AboutActivity"
android:exported="false"
android:theme="@style/Theme.PageScribe" />
</application>
</manifest>

View File

@@ -0,0 +1,37 @@
package com.bm.pagescribe
import android.os.Bundle
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.widget.Toolbar
import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat
/** Shows the app icon, name and version. Reached from the shelf's hamburger. */
class AboutActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_about)
// The app theme is NoActionBar, so each screen draws its own toolbar.
val toolbar = findViewById<Toolbar>(R.id.toolbar)
setSupportActionBar(toolbar)
supportActionBar?.setDisplayHomeAsUpEnabled(true)
toolbar.setNavigationOnClickListener { finish() }
findViewById<TextView>(R.id.versionText).text =
"Version " + BuildInfo.versionName(this)
ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main)) { v, insets ->
val bars = insets.getInsets(WindowInsetsCompat.Type.systemBars())
v.setPadding(bars.left, bars.top, bars.right, bars.bottom)
insets
}
}
override fun onSupportNavigateUp(): Boolean {
finish()
return true
}
}

View File

@@ -0,0 +1,13 @@
package com.bm.pagescribe
import android.content.Context
/** Version string for the About screen, kept in one place. */
object BuildInfo {
fun versionName(context: Context): String = try {
@Suppress("DEPRECATION")
context.packageManager.getPackageInfo(context.packageName, 0).versionName ?: "unknown"
} catch (e: Exception) {
"unknown"
}
}

View File

@@ -57,9 +57,13 @@ class MainActivity : AppCompatActivity() {
enableEdgeToEdge(statusBarStyle = SystemBarStyle.dark(Color.TRANSPARENT))
setContentView(R.layout.activity_main)
setSupportActionBar(findViewById<MaterialToolbar>(R.id.toolbar))
val toolbar = findViewById<MaterialToolbar>(R.id.toolbar)
setSupportActionBar(toolbar)
EdgeToEdge.padTop(findViewById(R.id.appBar))
EdgeToEdge.padBottom(findViewById(R.id.contentRoot))
// Hamburger menu → About. Single destination, so no drawer needed.
toolbar.setNavigationIcon(R.drawable.ic_hamburger)
toolbar.setNavigationOnClickListener { showAbout() }
repository = BookRepository(this)
statusText = findViewById(R.id.ocrStatus)
@@ -158,6 +162,9 @@ class MainActivity : AppCompatActivity() {
private companion object {
const val POLL_INTERVAL = 1500L
}
private fun showAbout() {
startActivity(android.content.Intent(this, AboutActivity::class.java))
}
}
/** Row of the book list. */
@@ -197,3 +204,4 @@ private class BookAdapter(
holder.itemView.setOnClickListener { onClick(book) }
}
}

View File

@@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Three bars, the conventional "menu" affordance. White so it reads on the
brand-blue toolbar; drawn on a 24dp grid to match the other action icons. -->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24"
android:tint="@android:color/white">
<path
android:fillColor="@android:color/white"
android:pathData="M3,6h18v2h-18z" />
<path
android:fillColor="@android:color/white"
android:pathData="M3,11h18v2h-18z" />
<path
android:fillColor="@android:color/white"
android:pathData="M3,16h18v2h-18z" />
</vector>

View File

@@ -0,0 +1,82 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:background="@color/paper">
<com.google.android.material.appbar.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/primary"
android:elevation="4dp">
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="@color/primary"
app:title="About"
app:titleTextColor="@android:color/white"
app:navigationIconTint="@android:color/white" />
</com.google.android.material.appbar.AppBarLayout>
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="32dp"
android:gravity="center_horizontal">
<ImageView
android:layout_width="120dp"
android:layout_height="120dp"
android:layout_marginTop="32dp"
android:src="@mipmap/ic_launcher"
android:contentDescription="@string/app_name" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="24dp"
android:text="@string/app_name"
android:textSize="24sp"
android:textStyle="bold"
android:textColor="@color/ink" />
<TextView
android:id="@+id/versionText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:text="Version"
android:textSize="14sp"
android:textColor="@color/ink_muted" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="32dp"
android:gravity="center"
android:text="@string/about_blurb"
android:textSize="14sp"
android:textColor="@color/ink_muted" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="32dp"
android:text="@string/about_copyright"
android:textSize="14sp"
android:textColor="@color/ink_muted" />
</LinearLayout>
</ScrollView>
</LinearLayout>

View File

@@ -59,4 +59,7 @@
<string name="notif_running">Reading pages of %1$s</string>
<string name="notif_done">Finished: %1$s</string>
<string name="notif_failed">OCR failed for %1$s</string>
<string name="about_title">About</string>
<string name="about_copyright">© 2026 UmbraTools</string>
<string name="about_blurb">Photographs two-page spreads, reads the printed page numbers, and assembles each book into a single ordered text file.</string>
</resources>