Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Paintroid 761 - Backwards #96

Open
wants to merge 26 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
48020a6
PAINTROID-761:Added the bridge communication between native and dart
Lenkomotive Jul 4, 2024
4e89c6a
Merge branch 'PAINTROID-761' of github.com:exland/Paintroid-Flutter i…
exland Jul 11, 2024
ce8b821
PAINTROID-761 - Added some functionalityy
exland Jul 12, 2024
d317eb0
PAINTROID-761 - Added some native provider
exland Jul 12, 2024
f4c6c65
PAINTROID-761 - Native call works
exland Jul 12, 2024
36e4c4f
PAINTROID-761 - Command works
exland Jul 12, 2024
d7dea37
PAINTROID-761 - CompositeCommand works
exland Jul 12, 2024
ad54183
PAINTROID-761 - FloatArray works
exland Jul 12, 2024
352e51d
PAINTROID-761 - Point/PointF works
exland Jul 12, 2024
c66913a
PAINTROID-761 - CommandManagerModel works
exland Jul 12, 2024
313a262
PAINTROID-761 - SetDimensionCommand works
exland Jul 12, 2024
0e4c89a
PAINTROID-761 - Paint works
exland Jul 12, 2024
c279a89
PAINTROID-761 - Layers work
exland Aug 3, 2024
418cde1
PAINTROID-761 - Load work
exland Aug 3, 2024
6d5d9b1
PAINTROID-761 - TextToolCommand work
exland Aug 3, 2024
a29f75f
PAINTROID-761 - FillCommand work
exland Aug 3, 2024
43bf27b
PAINTROID-761 - CropCommand work
exland Aug 3, 2024
9177484
PAINTROID-761 - ReorderLayersCommand work
exland Aug 3, 2024
79b5fc8
PAINTROID-761 - RemoveLayerCommand work
exland Aug 3, 2024
963d6f8
PAINTROID-761 - PathCommand work
exland Aug 3, 2024
0ae22cf
PAINTROID-761 - ShapeDrawable work
exland Aug 3, 2024
9b793ec
PAINTROID-761 - ClipboardCommand work
exland Aug 3, 2024
4526c1c
PAINTROID-761 - PointCommand work
exland Aug 3, 2024
062ef75
PAINTROID-761 - SmudgePathCommand work
exland Aug 3, 2024
359e5ff
PAINTROID-761 - LayerOpacityCommand work
exland Aug 3, 2024
f0ced4c
PAINTROID-761 - registerClasses
exland Aug 3, 2024
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
1 change: 1 addition & 0 deletions android/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -50,4 +50,5 @@ flutter {

dependencies {
implementation "androidx.window:window:1.0.0"
implementation 'com.esotericsoftware:kryo:5.5.0'
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package org.catrobat.paintroid.colorpicker

import java.io.Serializable

const val COLOR_HISTORY_SIZE = 4

class ColorHistory : Serializable {
private val colorHistory: ArrayList<Int> = arrayListOf()

val colors: ArrayList<Int>
get() = colorHistory

fun addColor(color: Int) {
if (colorHistory.lastOrNull() != color) {
colorHistory.add(color)
}

if (colorHistory.size > COLOR_HISTORY_SIZE) {
colorHistory.removeFirst()
}
}
}
213 changes: 213 additions & 0 deletions android/app/src/main/kotlin/org/catrobat/paintroid/FileReader.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,213 @@
package org.catrobat.paintroid

import android.content.Context
import android.net.Uri
import com.esotericsoftware.kryo.Kryo
import com.esotericsoftware.kryo.io.Input
import com.esotericsoftware.kryo.io.Output
import java.io.InputStream
import org.catrobat.paintroid.model.Layer

import org.catrobat.paintroid.command.serialization.VersionSerializer
import org.catrobat.paintroid.command.Command
import org.catrobat.paintroid.command.implementation.CompositeCommand
import org.catrobat.paintroid.command.serialization.CompositeCommandSerializer
import org.catrobat.paintroid.command.serialization.DataStructuresSerializer
import org.catrobat.paintroid.model.CommandManagerModel
import org.catrobat.paintroid.command.serialization.CommandManagerModelSerializer
import org.catrobat.paintroid.command.implementation.SetDimensionCommand
import org.catrobat.paintroid.command.implementation.SprayCommand
import org.catrobat.paintroid.command.serialization.SetDimensionCommandSerializer
import org.catrobat.paintroid.command.serialization.SprayCommandSerializer
import org.catrobat.paintroid.command.serialization.PaintSerializer

import org.catrobat.paintroid.command.implementation.AddEmptyLayerCommand
import org.catrobat.paintroid.command.serialization.AddLayerCommandSerializer

import org.catrobat.paintroid.command.implementation.SelectLayerCommand
import org.catrobat.paintroid.command.serialization.SelectLayerCommandSerializer

import org.catrobat.paintroid.command.implementation.LoadCommand
import org.catrobat.paintroid.command.serialization.LoadCommandSerializer

import org.catrobat.paintroid.command.implementation.TextToolCommand
import org.catrobat.paintroid.command.serialization.TextToolCommandSerializer

import org.catrobat.paintroid.command.implementation.FillCommand
import org.catrobat.paintroid.command.serialization.FillCommandSerializer

import org.catrobat.paintroid.command.implementation.FlipCommand
import org.catrobat.paintroid.command.serialization.FlipCommandSerializer

import org.catrobat.paintroid.command.implementation.CropCommand
import org.catrobat.paintroid.command.serialization.CropCommandSerializer

import org.catrobat.paintroid.command.implementation.CutCommand
import org.catrobat.paintroid.command.serialization.CutCommandSerializer



import org.catrobat.paintroid.command.implementation.ResizeCommand
import org.catrobat.paintroid.command.serialization.ResizeCommandSerializer

import org.catrobat.paintroid.command.implementation.RotateCommand
import org.catrobat.paintroid.command.serialization.RotateCommandSerializer
import org.catrobat.paintroid.command.implementation.ResetCommand
import org.catrobat.paintroid.command.serialization.ResetCommandSerializer


import org.catrobat.paintroid.command.implementation.ReorderLayersCommand
import org.catrobat.paintroid.command.serialization.ReorderLayersCommandSerializer

import org.catrobat.paintroid.command.implementation.RemoveLayerCommand
import org.catrobat.paintroid.command.serialization.RemoveLayerCommandSerializer



import org.catrobat.paintroid.command.implementation.MergeLayersCommand
import org.catrobat.paintroid.command.serialization.MergeLayersCommandSerializer

import org.catrobat.paintroid.command.implementation.PathCommand
import org.catrobat.paintroid.command.serialization.PathCommandSerializer


import org.catrobat.paintroid.command.serialization.SerializablePath

import org.catrobat.paintroid.command.implementation.LoadLayerListCommand
import org.catrobat.paintroid.command.serialization.LoadLayerListCommandSerializer


import org.catrobat.paintroid.command.implementation.GeometricFillCommand
import org.catrobat.paintroid.command.serialization.GeometricFillCommandSerializer


import org.catrobat.paintroid.command.implementation.ClipboardCommand
import org.catrobat.paintroid.command.serialization.ClipboardCommandSerializer


import org.catrobat.paintroid.command.serialization.SerializableTypeface


import org.catrobat.paintroid.command.implementation.PointCommand
import org.catrobat.paintroid.command.serialization.PointCommandSerializer


import org.catrobat.paintroid.command.serialization.BitmapSerializer


import org.catrobat.paintroid.command.implementation.SmudgePathCommand
import org.catrobat.paintroid.command.serialization.SmudgePathCommandSerializer


//import org.catrobat.paintroid.command.implementation.SmudgePathCommand
import org.catrobat.paintroid.colorpicker.ColorHistory
import org.catrobat.paintroid.command.serialization.ColorHistorySerializer



import org.catrobat.paintroid.command.implementation.ClippingCommand
import org.catrobat.paintroid.command.serialization.ClippingCommandSerializer


import org.catrobat.paintroid.command.implementation.LayerOpacityCommand
import org.catrobat.paintroid.command.serialization.LayerOpacityCommandSerializer

import android.graphics.Paint
import android.graphics.Point
import android.graphics.PointF
import android.graphics.RectF
import android.graphics.Bitmap

import android.content.ContentResolver
import android.content.ContentUris
import android.content.ContentValues


import org.catrobat.paintroid.tools.drawable.HeartDrawable
import org.catrobat.paintroid.tools.drawable.OvalDrawable
import org.catrobat.paintroid.tools.drawable.RectangleDrawable
import org.catrobat.paintroid.tools.drawable.ShapeDrawable
import org.catrobat.paintroid.tools.drawable.StarDrawable


class FileReader(private val context : Context)
{
private lateinit var activityContext: Context // MAYBE CAUSE A CRASH
private val kryo = Kryo()
private val registerMap = LinkedHashMap<Class<*>, VersionSerializer<*>?>()
companion object {
const val MAGIC_VALUE = "CatrobatImg"
const val CURRENT_IMAGE_VERSION = 2 // handle 1 look up how to do it in the native verson
}
init {
setRegisterMapVersion(CURRENT_IMAGE_VERSION)
registerClasses()
}
/* fun readFromFile(uri: String): CatrobatFileContent{
var commandModel: CommandManagerModel
var colorHistory: ColorHistory? = null
}*/
private fun setRegisterMapVersion(version: Int) {
// Only add new classes at the end
// because Kryo assigns an ID to each class
with(registerMap) {
put(Command::class.java, null)
put(CompositeCommand::class.java, CompositeCommandSerializer(version))
put(FloatArray::class.java, DataStructuresSerializer.FloatArraySerializer(version))
put(PointF::class.java, DataStructuresSerializer.PointFSerializer(version))
put(Point::class.java, DataStructuresSerializer.PointSerializer(version))
put(CommandManagerModel::class.java, CommandManagerModelSerializer(version))
put(SetDimensionCommand::class.java, SetDimensionCommandSerializer(version))
put(SprayCommand::class.java, SprayCommandSerializer(version))
put(Paint::class.java, PaintSerializer(version, activityContext)) // maybe will cause a crash ? activityContext is lateinnit
put(AddEmptyLayerCommand::class.java, AddLayerCommandSerializer(version))
put(SelectLayerCommand::class.java, SelectLayerCommandSerializer(version))
put(LoadCommand::class.java, LoadCommandSerializer(version))
put(TextToolCommand::class.java, TextToolCommandSerializer(version, activityContext))
put(Array<String>::class.java, DataStructuresSerializer.StringArraySerializer(version))
put(FillCommand::class.java, FillCommandSerializer(version))
put(FlipCommand::class.java, FlipCommandSerializer(version))
put(CropCommand::class.java, CropCommandSerializer(version))
put(CutCommand::class.java, CutCommandSerializer(version))
put(ResizeCommand::class.java, ResizeCommandSerializer(version))
put(RotateCommand::class.java, RotateCommandSerializer(version))
put(ResetCommand::class.java, ResetCommandSerializer(version))
put(ReorderLayersCommand::class.java, ReorderLayersCommandSerializer(version))
put(RemoveLayerCommand::class.java, RemoveLayerCommandSerializer(version))
put(MergeLayersCommand::class.java, MergeLayersCommandSerializer(version))
put(PathCommand::class.java, PathCommandSerializer(version))
put(SerializablePath::class.java, SerializablePath.PathSerializer(version))
put(SerializablePath.Move::class.java, SerializablePath.PathActionMoveSerializer(version))
put(SerializablePath.Line::class.java, SerializablePath.PathActionLineSerializer(version))
put(SerializablePath.Quad::class.java, SerializablePath.PathActionQuadSerializer(version))
put(SerializablePath.Rewind::class.java, SerializablePath.PathActionRewindSerializer(version))
put(LoadLayerListCommand::class.java, LoadLayerListCommandSerializer(version))
put(GeometricFillCommand::class.java, GeometricFillCommandSerializer(version))
put(HeartDrawable::class.java, GeometricFillCommandSerializer.HeartDrawableSerializer(version))
put(OvalDrawable::class.java, GeometricFillCommandSerializer.OvalDrawableSerializer(version))
put(RectangleDrawable::class.java, GeometricFillCommandSerializer.RectangleDrawableSerializer(version))
put(StarDrawable::class.java, GeometricFillCommandSerializer.StarDrawableSerializer(version))
put(ShapeDrawable::class.java, null)
put(RectF::class.java, DataStructuresSerializer.RectFSerializer(version))
put(ClipboardCommand::class.java, ClipboardCommandSerializer(version))
put(SerializableTypeface::class.java, SerializableTypeface.TypefaceSerializer(version))
put(PointCommand::class.java, PointCommandSerializer(version))
put(SerializablePath.Cube::class.java, SerializablePath.PathActionCubeSerializer(version))
put(Bitmap::class.java, BitmapSerializer(version))
put(SmudgePathCommand::class.java, SmudgePathCommandSerializer(version))
put(ColorHistory::class.java, ColorHistorySerializer(version))
put(ClippingCommand::class.java, ClippingCommandSerializer(version))
put(LayerOpacityCommand::class.java, LayerOpacityCommandSerializer(version))
}
}
private fun registerClasses() {
registerMap.forEach { (classRegister, serializer) ->
val registration = kryo.register(classRegister)
serializer?.let {
registration.serializer = serializer
}
}
}


}
52 changes: 52 additions & 0 deletions android/app/src/main/kotlin/org/catrobat/paintroid/MainActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,14 @@ import io.flutter.embedding.engine.FlutterEngine
import io.flutter.plugin.common.MethodCall
import io.flutter.plugin.common.MethodChannel
import java.io.IOException
import android.util.Log

import com.esotericsoftware.kryo.Kryo
import com.esotericsoftware.kryo.io.Input
import com.esotericsoftware.kryo.io.Output
import java.nio.ByteBuffer
class MainActivity : FlutterActivity() {
private val kryo = Kryo()
private val hasWritePermission: Boolean
get() = Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q ||
ContextCompat.checkSelfPermission(
Expand All @@ -26,6 +32,7 @@ class MainActivity : FlutterActivity() {
super.configureFlutterEngine(flutterEngine)
setupPhotoLibraryChannel(flutterEngine)
setupDeviceChannel(flutterEngine)
setupNativeCatrobat(flutterEngine)
}

private fun setupDeviceChannel(flutterEngine: FlutterEngine) {
Expand Down Expand Up @@ -72,6 +79,43 @@ class MainActivity : FlutterActivity() {
}
}

// TODO getHeightInPixels
private fun setupNativeCatrobat(flutterEngine: FlutterEngine) {
MethodChannel(flutterEngine.dartExecutor.binaryMessenger, "org.catrobat.paintroid/native").apply {
setMethodCallHandler { call, result ->
when (call.method) {
"getNativeClassData" -> {
val parameter = call.argument<String>("path")
if (parameter == null) {
Log.d("MethodChannel", "No path received")
result.error("NO_PARAM", "No path provided", null)
} else {
try {
//Log.d("MethodChannel", "Received path: $parameter")
//val data = getNativeClassData(parameter)
val byteBuffer = ByteBuffer.allocate(4) // Allocate a ByteBuffer with space for 4 bytes
byteBuffer.put(0x01) // Example byte
byteBuffer.put(0x02) // Example byte
byteBuffer.put(0x03) // Example byte
byteBuffer.put(0x04) // Example byte
val byteArray = ByteArray(byteBuffer.remaining())
byteBuffer.get(byteArray)
result.success(byteArray)
} catch (e: Exception) {
Log.e("MethodChannel", "Error processing data", e)
result.error("ERROR_PROCESSING", "Failed to process data", e.localizedMessage)
}
}
}
else -> {
Log.d("MethodChannel", "Method not implemented")
result.notImplemented()
}
}
}
}
}

private fun saveImageToPictures(filename: String, data: ByteArray) {
val picturesUri = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
MediaStore.Images.Media.getContentUri(MediaStore.VOLUME_EXTERNAL_PRIMARY)
Expand Down Expand Up @@ -109,3 +153,11 @@ class MainActivity : FlutterActivity() {
return Pair(filename, imageData)
}
}



private fun getNativeClassData(path: String): ByteArray {
// Assuming you have a method to process the data, e.g., using Kryo for serialization
// Replace with actual data processing logic
return byteArrayOf() // Placeholder for actual data processing
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/*
* Paintroid: An image manipulation application for Android.
* Copyright (C) 2010-2022 The Catrobat Team
* (<http://developer.catrobat.org/credits>)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

package org.catrobat.paintroid.command

import android.graphics.Canvas
import org.catrobat.paintroid.contract.LayerContracts

interface Command {
fun run(canvas: Canvas, layerModel: LayerContracts.Model)
fun freeResources()
}
Loading
Loading