Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions app/src/main/java/com/ethran/notable/MainActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,13 @@ class MainActivity : ComponentActivity() {
CanvasEventBus.onFocusChange.emit(hasFocus)
}
}
override fun onResume() {
super.onResume()
enableFullScreen()
lifecycleScope.launch {
CanvasEventBus.onFocusChange.emit(true)
}
}


// when the screen orientation is changed, set new screen width restart is not necessary,
Expand Down
14 changes: 8 additions & 6 deletions app/src/main/java/com/ethran/notable/editor/EditorView.kt
Original file line number Diff line number Diff line change
Expand Up @@ -185,12 +185,14 @@ fun EditorView(
}

// Handle focus changes from Canvas
LaunchedEffect(Unit) {
CanvasEventBus.onFocusChange.collect { hasFocus ->
log.d("Canvas has focus: $hasFocus")
viewModel.onFocusChanged(hasFocus)
}
}
// LaunchedEffect(Unit) {
// CanvasEventBus.onFocusChange.collect { hasFocus ->
// log.d("Canvas has focus: $hasFocus")
// if (hasFocus)
// viewModel.updateDrawingState()
//
// }
// }

val toolbarState by viewModel.toolbarState.collectAsStateWithLifecycle()

Expand Down
23 changes: 10 additions & 13 deletions app/src/main/java/com/ethran/notable/editor/EditorViewModel.kt
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import com.ethran.notable.editor.state.ClipboardStore
import com.ethran.notable.editor.state.History
import com.ethran.notable.editor.state.Mode
import com.ethran.notable.editor.state.SelectionState
import com.ethran.notable.editor.utils.DeviceCompat
import com.ethran.notable.editor.utils.Eraser
import com.ethran.notable.editor.utils.Pen
import com.ethran.notable.editor.utils.PenSetting
Expand Down Expand Up @@ -103,7 +104,7 @@ sealed class ToolbarAction {
data class ChangePenSetting(val pen: Pen, val setting: PenSetting) : ToolbarAction()
data class ChangeEraser(val eraser: Eraser) : ToolbarAction()
object ToggleMenu : ToolbarAction()
data class UpdateMenuOpenTo(val isOpen: Boolean) : ToolbarAction()
data class ToggleEraserManu(val isOpen: Boolean) : ToolbarAction()
data class ToggleBackgroundSelector(val isOpen: Boolean) : ToolbarAction()
data class ToggleScribbleToErase(val enabled: Boolean) : ToolbarAction()

Expand Down Expand Up @@ -250,17 +251,17 @@ class EditorViewModel @Inject constructor(
is ToolbarAction.ChangeEraser -> handleEraserChange(action.eraser)
is ToolbarAction.ToggleMenu -> {
_toolbarState.update { it.copy(isMenuOpen = !it.isMenuOpen) }
updateDrawingState()
// updateDrawingState() // on focus change is doing this
}

is ToolbarAction.UpdateMenuOpenTo -> {
is ToolbarAction.ToggleEraserManu -> {
_toolbarState.update { it.copy(isStrokeSelectionOpen = action.isOpen) }
updateDrawingState()
// updateDrawingState() // on focus change is doing this
}

is ToolbarAction.ToggleBackgroundSelector -> {
_toolbarState.update { it.copy(isBackgroundSelectorModalOpen = action.isOpen) }
updateDrawingState()
// updateDrawingState() // on focus change is doing this
}

is ToolbarAction.ToggleScribbleToErase -> updateScribbleToErase(action.enabled)
Expand Down Expand Up @@ -441,21 +442,17 @@ class EditorViewModel @Inject constructor(
* Re-evaluates whether drawing should be enabled based on menu and selection states.
*/
fun updateDrawingState() {
log.v("updateDrawingState")
// It get called three times on canvas creation.
val shouldBeDrawing = _toolbarState.value.isDrawingAllowed
_toolbarState.update { it.copy(isDrawing = shouldBeDrawing) }
log.d("Drawing state: $shouldBeDrawing")
log.d("updateDrawingState: Drawing state: $shouldBeDrawing")
viewModelScope.launch {
if (shouldBeDrawing)
DeviceCompat.delayBeforeResumingDrawing()
CanvasEventBus.isDrawing.emit(shouldBeDrawing)
}
}

fun onFocusChanged(isFocused: Boolean) {
if (isFocused) {
updateDrawingState()
}
}

// --------------------------------------------------------
// Book / Page Data
// --------------------------------------------------------
Expand Down
8 changes: 5 additions & 3 deletions app/src/main/java/com/ethran/notable/editor/PageView.kt
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,7 @@ class PageView(
}

private fun loadPage() {
// loadingJob?.cancel()
logCache.i("Init from persist layer, pageId: $currentPageId")
windowedCanvas.scale(zoomLevel.value, zoomLevel.value)
loadingJob = coroutineScope.launch(Dispatchers.IO) {
Expand All @@ -284,7 +285,7 @@ class PageView(
}
// TODO: If we put it in loadPage(…) sometimes it will try to refresh
// without seeing strokes, I have no idea why.
coroutineScope.launch(Dispatchers.Main.immediate) {
coroutineScope.launch(Dispatchers.Main) {
CanvasEventBus.forceUpdate.emit(null)
}
// sleep(5000)
Expand Down Expand Up @@ -444,7 +445,7 @@ class PageView(
// let's control that the last preview fits the present orientation. Otherwise we'll ask for a redraw.
if (bitmapFromDisc.height == windowedCanvas.height && bitmapFromDisc.width == windowedCanvas.width) {
windowedCanvas.drawBitmap(bitmapFromDisc, 0f, 0f, Paint())
log.d("loaded initial bitmap")
log.d("loaded initial bitmap, drawing to canvas: ${windowedCanvas.hashCode()}, bitmap: ${windowedBitmap.hashCode()}")
return true
} else
log.i("Image preview does not fit canvas area - redrawing")
Expand All @@ -457,6 +458,7 @@ class PageView(
drawBgToCanvas(null)
} else
windowedCanvas.drawColor(Color.WHITE)
log.d("loaded initial bitmap, drawing to canvas: ${windowedCanvas.hashCode()}, bitmap: ${windowedBitmap.hashCode()}")
return false
}

Expand Down Expand Up @@ -666,7 +668,7 @@ class PageView(
val redrawRect = Rect(0, 0, windowedBitmap.width, windowedBitmap.height)

log.d("Redrawing full logical rect: $redrawRect")
windowedCanvas.drawColor(Color.BLACK)
windowedCanvas.drawColor(Color.GREEN)
drawBgToCanvas(redrawRect)
pageDataManager.cacheBitmap(currentPageId, windowedBitmap)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ class CanvasObserverRegistry(
private val pageDataManager = page.pageDataManager

fun registerAll() {
// NOTE: Be careful with the dispatchers, choose them wisely.

ImageHandler(drawCanvas.context, page, viewModel, coroutineScope).observeImageUri()

observeRefreshUiImmediately()
Expand All @@ -58,7 +60,7 @@ class CanvasObserverRegistry(
}

private fun observeRefreshUiImmediately() {
coroutineScope.launch {
coroutineScope.launch(Dispatchers.Main) {
CanvasEventBus.refreshUiImmediately.collect {
log.v("Refreshing UI!")
val zoneToRedraw = Rect(0, 0, page.viewWidth, page.viewHeight)
Expand All @@ -71,7 +73,7 @@ class CanvasObserverRegistry(
// observe forceUpdate, takes rect in screen coordinates
// given null it will redraw whole page
// BE CAREFUL: partial update is not tested fairly -- might not work in some situations.
coroutineScope.launch(Dispatchers.Main.immediate) {
coroutineScope.launch(Dispatchers.Main) {
CanvasEventBus.forceUpdate.collect { dirtyRectangle ->
// On loading, make sure that the loaded strokes are visible to it.
log.v("Force update, zone: $dirtyRectangle, Strokes to draw: ${page.strokes.size}")
Expand Down Expand Up @@ -103,6 +105,7 @@ class CanvasObserverRegistry(
if (hasFocus) {
inputHandler.updatePenAndStroke() // The setting might been changed by other app.
drawCanvas.drawCanvasToView(null)
viewModel.updateDrawingState()
} else {
CanvasEventBus.isDrawing.emit(false)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,9 +66,10 @@ class CanvasRefreshManager(
resetScreenFreeze(touchHelper)
}


// private val renderScope = CoroutineScope(Dispatchers.Main)
fun drawCanvasToView(dirtyRect: Rect?) {
log.v("Canvas refresh started, dirtyRect: $dirtyRect")
// renderScope.launch {
log.v("Canvas refresh started, dirtyRect: $dirtyRect, bitmap: ${page.windowedBitmap.hashCode()}, thread: ${Thread.currentThread().name}")

val zoneToRedraw = dirtyRect ?: Rect(0, 0, page.viewWidth, page.viewHeight)
var canvas: Canvas? = null
Expand Down Expand Up @@ -103,6 +104,7 @@ class CanvasRefreshManager(
log.w("Surface released during unlock", e)
}
}
// }
}


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import com.onyx.android.sdk.api.device.epd.EpdController
import io.shipbook.shipbooksdk.Log
import io.shipbook.shipbooksdk.ShipBook
import kotlinx.coroutines.CoroutineScope
import java.lang.Thread.sleep


val pressure = EpdController.getMaxTouchPressure()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import com.ethran.notable.editor.EditorViewModel
import com.ethran.notable.editor.state.Mode
import com.ethran.notable.editor.PageView
import com.ethran.notable.editor.state.History
import com.ethran.notable.editor.state.SelectionState
import com.ethran.notable.editor.utils.DeviceCompat
import com.ethran.notable.editor.utils.Eraser
import com.ethran.notable.editor.utils.Pen
Expand Down Expand Up @@ -167,6 +166,7 @@ class OnyxInputHandler(
if(touchHelper == null) return
log.i("Update is drawing: $toolbarState.isDrawing")
if (toolbarState.isDrawing) {
// DeviceCompat.delayBeforeResumingDrawing()
touchHelper!!.setRawDrawingEnabled(true)
} else {
// Check if drawing is completed
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -193,10 +193,13 @@ fun drawOnCanvasFromPage(
drawStroke(this, stroke, -page.scroll)
}
} catch (e: Exception) {
val error = DomainError.DrawingError("Strokes failed: ${e.message ?: e.toString()}")
val error = DomainError.DrawingError("Strokes failed: ${e.message ?: e.toString()}")
pageDrawingLog.e("PageView.kt: ${error.userMessage}", e)
persistentError = persistentError?.let { it + error } ?: error
}
}
pageDrawingLog.d(
"drawOnCanvasFromPage, finished drawing to canvas: ${canvas.hashCode()}"
)
return persistentError?.let { AppResult.Error(it) } ?: AppResult.Success(Unit)
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import androidx.compose.runtime.setValue
import androidx.compose.ui.graphics.Color
import com.ethran.notable.editor.utils.Pen
import com.ethran.notable.editor.utils.PenSetting
import io.shipbook.shipbooksdk.Log

@Composable
fun PenToolbarButton(
Expand All @@ -20,15 +21,16 @@ fun PenToolbarButton(
sizes: List<Pair<String, Float>>,
penSetting: PenSetting,
onChangeSetting: (PenSetting) -> Unit,
onStrokeMenuOpenChange: ((Boolean) -> Unit)? = null
// onStrokeMenuOpenChange: ((Boolean) -> Unit)? = null
) {
var isStrokeMenuOpen by remember { mutableStateOf(false) }

if (onStrokeMenuOpenChange != null) {
LaunchedEffect(isStrokeMenuOpen) {
onStrokeMenuOpenChange(isStrokeMenuOpen)
}
}
// if (onStrokeMenuOpenChange != null) {
// LaunchedEffect(isStrokeMenuOpen) {
// Log.d("PenToolbarButton", "isStrokeMenuOpen: $isStrokeMenuOpen")
// onStrokeMenuOpenChange(isStrokeMenuOpen)
// }
// }


Box {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -273,7 +273,7 @@ fun ToolbarContent(
value = uiState.eraser,
onChange = { onAction(ToolbarAction.ChangeEraser(it)) },
toggleScribbleToErase = { onAction(ToolbarAction.ToggleScribbleToErase(it)) },
onMenuOpenChange = { onAction(ToolbarAction.UpdateMenuOpenTo(it)) },
onMenuOpenChange = { onAction(ToolbarAction.ToggleEraserManu(it)) },
isMenuOpen = uiState.isStrokeSelectionOpen
)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,9 @@ import androidx.compose.ui.window.Popup
import androidx.compose.ui.window.PopupProperties
import com.ethran.notable.R
import com.ethran.notable.data.datastore.BUTTON_SIZE
import com.ethran.notable.editor.state.Mode
import com.ethran.notable.editor.ToolbarAction
import com.ethran.notable.editor.ToolbarUiState
import com.ethran.notable.editor.state.Mode
import com.ethran.notable.editor.utils.Pen
import com.ethran.notable.editor.utils.PenSetting
import com.ethran.notable.io.ExportFormat
Expand All @@ -41,13 +41,15 @@ import com.ethran.notable.ui.noRippleClickable
@Composable
fun ToolbarMenu(
uiState: ToolbarUiState,
onAction: (ToolbarAction) -> Unit
onAction: (ToolbarAction) -> Unit,
) {
val context = LocalContext.current

Popup(
alignment = Alignment.TopEnd,
onDismissRequest = { onAction(ToolbarAction.ToggleMenu) },
onDismissRequest = {
onAction(ToolbarAction.ToggleMenu)
},
offset = IntOffset(
convertDpToPixel((-10).dp, context).toInt(),
convertDpToPixel(50.dp, context).toInt()
Expand Down
Loading
Loading