Sub drawingPanel_gesture_onTouch(Action As Int, X As Float, Y As Float, MotionEvent As Object) As Boolean
If Action = gd.ACTION_DOWN Then 'start a new stroke
resetMinMaxXY
updateMinMaxXY(X, Y)
minY = Y
maxY = Y
oldX = X
oldY = Y
Else If Action = gd.ACTION_MOVE Then 'continue the current stroke
drawLineOnPanel(oldX, oldY, X, Y)
oldX = X
oldY = Y
updateMinMaxXY(X, Y)
Else If Action = gd.ACTION_UP Then 'finished the stroke
updateMinMaxXY(X, Y)
padMinMaxXY 'account for stroke width outside the rect
Dim tempRect As Rect
tempRect.Initialize(minX, minY, maxX, maxY)
storeForUndo(tempRect)
setUndo(UNDO_ALLOW)
End If
drawingPanel.Invalidate
Return True 'consume the event
End Sub
'reset min/max X and Y to values that will disappear on next update
Sub resetMinMaxXY
minX = 999999
minY = 999999
maxX = -1
maxY = -1
End Sub
'track the min and max values of the screen region covered by the drawn stroke
Sub updateMinMaxXY(xArg As Float, yArg As Float)
minX = Min(minX, xArg)
minY = Min(minY, yArg)
maxX = Max(maxX, xArg)
maxY = Max(maxY, yArg)
End Sub
'pad the undo rect to allow for half the stroke being drawn outside the region
Sub padMinMaxXY
Dim padding As Float = (currentStrokeWidth / 2) + 1
minX = Max(0, minX - padding)
minY = Max(0, minY - padding)
maxX = Min(drawingPanel.Width, maxX + padding)
maxY = Min(drawingPanel.Height, maxY + padding)
End Sub
Sub resetUndo
undoHistory.clear
undoPanelBitmap.Initialize3(panelCanvas.Bitmap) 'store the starting screen so we can crop a part of it next time
End Sub
Sub storeForUndo(rectArg As Rect)
'if we're short on memory, discard oldest screen to make room
If Not(enoughMemoryForUndo) AND (undoHistory.Size > 0) Then
undoHistory.RemoveAt(0) '~we should really remove as many items as required for the new rect
End If
Dim tempUndoItem As undoItem
tempUndoItem.Initialize
tempUndoItem.rectBitmap.Initialize3(bmPlus.Crop(undoPanelBitmap, rectArg.Left, rectArg.Top, (rectArg.Right - rectArg.Left), (rectArg.Bottom - rectArg.top)))
tempUndoItem.x = rectArg.Left
tempUndoItem.y = rectArg.Top
undoHistory.Add(tempUndoItem) 'add crop of old screen to history
undoTotal = undoHistory.Size
undoPanelBitmap.Initialize3(panelCanvas.Bitmap) 'store the current screen so we can crop a part of it next time
End Sub
Sub enoughMemoryForUndo As Boolean
Dim memoryForScreen As Long = drawingPanel.Width * drawingPanel.Height * 4 '4 bytes per pixel
Log("memcheck free/needed: " & common.appCache.FreeMemory & "/" & memoryForScreen)
Return common.appCache.FreeMemory > (memoryForScreen * 3) '3x the screen size, to give us a wide margin
End Sub
'undo the most recent stroke by drawing the matching rect of the previous screen
Sub undoButton_Click
Dim tempUndoItem As undoItem = undoHistory.Get(undoHistory.size - 1) 'get the most recent undo item
Dim targetRect As Rect
targetRect.Initialize(tempUndoItem.x, tempUndoItem.y, tempUndoItem.x + tempUndoItem.rectBitmap.Width, tempUndoItem.y + tempUndoItem.rectBitmap.Height)
panelCanvas.DrawBitmap(tempUndoItem.rectBitmap, Null, targetRect) 'redraw the previous screen
undoHistory.RemoveAt(undoHistory.size - 1) 'remove it once undone
If suppressToast = False Then
If undoHistory.size > 0 Then
ToastMessageShow("Undo : " & (undoHistory.size) & " of " & undoTotal, False)
Else
ToastMessageShow("No more to undo", False)
End If
End If
drawingPanel.Invalidate
undoPanelBitmap.Initialize3(panelCanvas.Bitmap) 'store the current screen so we can crop a part of it next time
setUndo(undoHistory.Size > 0)
End Sub