Skip to content

Commit

Permalink
feat: Added the logic to display the clipart and text on the virtual …
Browse files Browse the repository at this point in the history
…badge.

feat: Added the modes support for left right top down fixed and animation support for flash and marquee.

animation right
  • Loading branch information
Jhalakupadhyay committed Aug 27, 2024
1 parent 3ece383 commit 4a85f72
Show file tree
Hide file tree
Showing 8 changed files with 225 additions and 15 deletions.
Binary file removed assets/icons/postman collections.zip
Binary file not shown.
53 changes: 53 additions & 0 deletions lib/bademagic_module/utils/byte_array_utils.dart
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,56 @@ List<int> hexStringToByteArray(String hexString) {
logger.d(data.length);
return data;
}

List<List<int>> byteArrayToBinaryArray(List<int> byteArray) {
List<List<int>> binaryArray = List.generate(11, (_) => []);

int rowIndex = 0;
for (int byte in byteArray) {
List<int> binaryRepresentation = [];
for (int i = 7; i >= 0; i--) {
binaryRepresentation.add((byte >> i) & 1);
}

binaryArray[rowIndex].addAll(binaryRepresentation);

rowIndex = (rowIndex + 1) % 11;
}

logger.d(
"binaryArray: $binaryArray"); // Use print instead of logger for standalone example
return binaryArray;
}

String hexToBin(String hex) {
// Convert hex to binary string
String binaryString = BigInt.parse(hex, radix: 16).toRadixString(2);

// Pad the binary string with leading zeros if necessary to ensure it's a multiple of 8 bits
int paddingLength = (8 - (binaryString.length % 8)) % 8;
binaryString = binaryString.padLeft(binaryString.length + paddingLength, '0');
logger.d("binaryString: $binaryString");
return binaryString;
}

List<List<int>> binaryStringTo2DList(String binaryString) {
int maxHeight = 11;
List<List<int>> binary2DList = List.generate(maxHeight, (_) => []);

for (int x = 0; x < binaryString.length; x++) {
int a = 0;
for (int y = a; y < 11; y++) {
for (int z = 0; z < 8; z++) {
binary2DList[y].add(int.parse(binaryString[x++]));
if (x >= binaryString.length) {
break;
}
}
if (x >= binaryString.length) {
break;
}
}
}
logger.d("binary2DList: $binary2DList");
return binary2DList;
}
23 changes: 15 additions & 8 deletions lib/bademagic_module/utils/converters.dart
Original file line number Diff line number Diff line change
@@ -1,32 +1,33 @@
import 'dart:math';
import 'package:badgemagic/bademagic_module/utils/byte_array_utils.dart';
import 'package:badgemagic/bademagic_module/utils/data_to_bytearray_converter.dart';
import 'package:badgemagic/bademagic_module/utils/file_helper.dart';
import 'package:badgemagic/bademagic_module/utils/image_utils.dart';
import 'package:badgemagic/providers/cardsprovider.dart';
import 'package:badgemagic/providers/drawbadge_provider.dart';
import 'package:badgemagic/providers/imageprovider.dart';
import 'package:get_it/get_it.dart';

class Converters {
InlineImageProvider controllerData =
GetIt.instance.get<InlineImageProvider>();
DrawBadgeProvider badgeList = GetIt.instance.get<DrawBadgeProvider>();
DataToByteArrayConverter converter = DataToByteArrayConverter();
ImageUtils imageUtils = ImageUtils();
FileHelper fileHelper = FileHelper();

int controllerLength = 0;
bool isEmpty = false;

Future<List<String>> messageTohex(String message) async {
List<String> hexStrings = [];
for (int x = 0; x < message.length; x++) {
if (message[x] == '<' && message[min(x + 5, message.length - 1)] == '>') {
if (message[x] == '<' && message[x + 5] == '>') {
int index = int.parse(message[x + 2] + message[x + 3]);
var key = controllerData.imageCache.keys.toList()[index];
if (key is List) {
String filename = key[0];
logger.d("Filename: $filename");
List<List<int>>? image = await fileHelper.readFromFile(filename);
logger.d("Image: $image");
hexStrings = convertBitmapToLEDHex(image!, true);
hexStrings += convertBitmapToLEDHex(image!, true);
x += 5;
} else {
List<String> hs =
Expand All @@ -40,6 +41,15 @@ class Converters {
}
}
}
if (message.isEmpty) {
badgeList.resetGrid();
isEmpty = true;
} else {
isEmpty = false;
List<int> byteArray = hexStringToByteArray(hexStrings.join());
List<List<int>> binaryArray = byteArrayToBinaryArray(byteArray);
badgeList.startAnimation(binaryArray, isEmpty);
}
return hexStrings;
}

Expand Down Expand Up @@ -121,8 +131,6 @@ class Converters {
}
}

logger.d("Padded image: $list");

// Convert each 8-bit segment into hexadecimal strings
List<String> allHexs = [];
for (int i = 0; i < list[0].length ~/ 8; i++) {
Expand All @@ -145,7 +153,6 @@ class Converters {

allHexs.add(lineHex.toString()); // Store completed hexadecimal line
}
logger.d("All hexs: $allHexs");
return allHexs; // Return list of hexadecimal strings
}
}
2 changes: 0 additions & 2 deletions lib/bademagic_module/utils/file_helper.dart
Original file line number Diff line number Diff line change
Expand Up @@ -114,8 +114,6 @@ class FileHelper {
// Convert the 2D list to JSON string
String jsonData = jsonEncode(image);

logger.d('JSON data: $jsonData');

// Write the JSON string to a file
await _writeToFile(filename, jsonData);

Expand Down
1 change: 0 additions & 1 deletion lib/bademagic_module/utils/image_utils.dart
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,6 @@ class ImageUtils {
}
}
}
logger.d("Pixel Array generated = $pixelArray");
return Converters.convertBitmapToLEDHex(pixelArray, false);
}
}
142 changes: 142 additions & 0 deletions lib/providers/drawbadge_provider.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,15 @@
import 'dart:async';
import 'package:badgemagic/bademagic_module/models/mode.dart';
import 'package:badgemagic/providers/cardsprovider.dart';
import 'package:flutter/material.dart';
import 'package:get_it/get_it.dart';

class DrawBadgeProvider extends ChangeNotifier {
CardProvider cardData = GetIt.instance<CardProvider>();
Timer? _timer;
int countFrame = 0;
int animationIndex = 0;
int lastFrame = 0;
//List that contains the state of each cell of the badge
List<List<bool>> grid =
List.generate(11, (i) => List.generate(44, (j) => false));
Expand Down Expand Up @@ -31,4 +40,137 @@ class DrawBadgeProvider extends ChangeNotifier {

//function to get the isDrawing variable
bool getIsDrawing() => isDrawing;

void startAnimation(List<List<int>> newGrid, bool isEmpty) {
_timer?.cancel(); // Cancel any existing timer
_timer = Timer.periodic(const Duration(milliseconds: 200), (timer) {
animationIndex++;
if (isEmpty) {
newGrid = List.generate(11, (i) => List.generate(44, (j) => 0));
}
changeGridValue(newGrid);
});
}

void changeGridValue(List<List<int>> newGrid) {
int badgeHeight = grid.length;
int badgeWidth = grid[0].length;
int newHeight = newGrid.length;
int newWidth = newGrid[0].length;

// Process grid
for (int i = 0; i < badgeHeight; i++) {
// bool matchFrame = false;

for (int j = 0; j < badgeWidth; j++) {
bool flashLEDOn = true;

if (cardData.getEffectIndex(1) == 1) {
int aIFlash = animationIndex % 2;
flashLEDOn = aIFlash > 4;
}

bool validMarquee = false;

if (cardData.getEffectIndex(2) == 1) {
int aIMarquee = animationIndex ~/ 2;
validMarquee =
(i == 0 || j == 0 || i == badgeHeight - 1 || j == badgeWidth - 1);

if (validMarquee) {
if ((i == 0 || j == badgeWidth - 1) &&
!(i == badgeHeight - 1 && j == badgeWidth - 1)) {
validMarquee = (i + j) % 4 == (aIMarquee % 4);
} else {
validMarquee = (i + j - 1) % 4 == (3 - (aIMarquee % 4));
}
}
}
if (Mode == Mode.fixed) {
// Offsets to center newGrid in the existing grid
int verticalOffset = (badgeHeight - newHeight) ~/ 2;
int horizontalOffset = (badgeWidth - newWidth) ~/ 2;
// Calculate position in newGrid
int newGridRow = i - verticalOffset;
int newGridCol = j - horizontalOffset;

bool isNewGridCell = newGridRow >= 0 &&
newGridRow < newHeight &&
newGridCol >= 0 &&
newGridCol < newWidth;

bool fixedCondition = false;
if (isNewGridCell) {
// Handle the fixed mode update
fixedCondition = validMarquee ||
flashLEDOn && newGrid[newGridRow][newGridCol] == 1;
}

grid[i][j] = fixedCondition;
}
if (Mode == Mode.right) {
int animationValue = animationIndex ~/ 1;
int newGridLength = newGrid[0].length;

int startPosition = badgeWidth + animationValue;

int gridIndex = (j - startPosition);
gridIndex = gridIndex %
(newGridLength < badgeWidth - 1 ? badgeWidth : newGridLength);

bool leftCondition = validMarquee ||
(i < newHeight &&
j >= 0 &&
j < badgeWidth &&
gridIndex >= 0 &&
gridIndex < newGridLength &&
newGrid[i][gridIndex] == 1);

grid[i][j] = leftCondition;
}
if (Mode == Mode.down) {
int animationValue = animationIndex ~/ 2;
int newGridHeight = newGrid.length;
int verticalOffset = (badgeHeight - newHeight) ~/ 2;
int horizontalOffset = (badgeWidth - newWidth) ~/ 2;
int newGridRow = (i - animationValue + newGridHeight) % newGridHeight;
int newGridCol = j - horizontalOffset;

bool isNewGridCell = newGridRow >= 0 &&
newGridRow < newHeight &&
newGridCol >= 0 &&
newGridCol < newWidth;

bool upCondition = validMarquee ||
(i >= verticalOffset &&
isNewGridCell &&
newGrid[newGridRow][newGridCol] == 1);

grid[i][j] = upCondition;
}
if (Mode == Mode.up) {
int animationValue = animationIndex ~/ 2;
int newGridHeight = newGrid.length;
int verticalOffset = (badgeHeight - newHeight) ~/ 2;
int horizontalOffset = (badgeWidth - newWidth) ~/ 2;
int newGridRow = (i + animationValue + newGridHeight) % newGridHeight;
int newGridCol = j - horizontalOffset;

bool isNewGridCell = newGridRow >= 0 &&
newGridRow < newHeight &&
newGridCol >= 0 &&
newGridCol < newWidth;

bool upCondition = validMarquee ||
(i >= verticalOffset &&
isNewGridCell &&
newGrid[newGridRow][newGridCol] == 1);

grid[i][j] = upCondition;
}
}
}
}

notifyListeners();
}
4 changes: 3 additions & 1 deletion lib/providers/imageprovider.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import 'dart:convert';
import 'dart:ui' as ui;

import 'package:badgemagic/bademagic_module/utils/byte_array_utils.dart';
import 'package:badgemagic/bademagic_module/utils/file_helper.dart';
import 'package:badgemagic/bademagic_module/utils/image_utils.dart';
Expand Down Expand Up @@ -87,10 +88,11 @@ class InlineImageProvider extends ChangeNotifier {
message.text = beforeCursor + placeholder + afterCursor;
message.selection = TextSelection.fromPosition(
TextPosition(offset: cursorPos + placeholder.length));
logger.d('Message text: ${message.text}');
notifyListeners();
}

void controllerListener() {
// Assuming controllerLength is meant to be message.text.length
int textLength = message.text.length;

// Check if the text length is sufficient to contain the pattern
Expand Down
15 changes: 12 additions & 3 deletions lib/view/homescreen.dart
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import 'package:badgemagic/bademagic_module/utils/byte_array_utils.dart';
import 'package:badgemagic/bademagic_module/utils/converters.dart';
import 'package:badgemagic/bademagic_module/utils/image_utils.dart';
import 'package:badgemagic/constants.dart';
Expand Down Expand Up @@ -26,6 +27,7 @@ class HomeScreen extends StatefulWidget {
}

class _HomeScreenState extends State<HomeScreen> with TickerProviderStateMixin {
final ValueNotifier<String> textNotifier = ValueNotifier<String>('');
late final TabController _tabController;
BadgeMessageProvider badgeData = BadgeMessageProvider();
ImageUtils imageUtils = ImageUtils();
Expand All @@ -34,9 +36,11 @@ class _HomeScreenState extends State<HomeScreen> with TickerProviderStateMixin {
Converters converters = Converters();
DrawBadgeProvider drawBadgeProvider = GetIt.instance<DrawBadgeProvider>();
bool isPrefixIconClicked = false;
int textfieldLength = 0;

@override
void initState() {
inlineImageProvider.getController().addListener(_controllerListner);
drawBadgeProvider.resetGrid();
SystemChrome.setPreferredOrientations([
DeviceOrientation.portraitUp,
Expand All @@ -47,6 +51,13 @@ class _HomeScreenState extends State<HomeScreen> with TickerProviderStateMixin {
_tabController = TabController(length: 3, vsync: this);
}

void _controllerListner() {
logger
.d('Controller Listener : ${inlineImageProvider.getController().text}');
converters.messageTohex(inlineImageProvider.getController().text);
inlineImageProvider.controllerListener();
}

@override
void dispose() {
_tabController.dispose();
Expand Down Expand Up @@ -92,9 +103,7 @@ class _HomeScreenState extends State<HomeScreen> with TickerProviderStateMixin {
borderRadius: BorderRadius.circular(10.r),
elevation: 10,
child: ExtendedTextField(
onChanged: (value) {
inlineImageProvider.controllerListener();
},
onChanged: (value) {},
controller: inlineImageProvider.getController(),
specialTextSpanBuilder: MySpecialTextSpanBuilder(),
decoration: InputDecoration(
Expand Down

0 comments on commit 4a85f72

Please sign in to comment.