From e4538d81200f7482bec45ccd678590c435bb2fb7 Mon Sep 17 00:00:00 2001 From: Carlos Eduardo Leite de Andrade Date: Mon, 25 Sep 2023 16:15:08 -0300 Subject: [PATCH] Parser to String. #1 --- lib/docking.dart | 4 + lib/src/layout/layout_parser.dart | 220 ++++++++++++++++++++++++++++ lib/src/layout/typedef_parsers.dart | 11 ++ 3 files changed, 235 insertions(+) create mode 100644 lib/src/layout/layout_parser.dart create mode 100644 lib/src/layout/typedef_parsers.dart diff --git a/lib/docking.dart b/lib/docking.dart index 0878d95..4251429 100644 --- a/lib/docking.dart +++ b/lib/docking.dart @@ -1,6 +1,10 @@ library docking; export 'src/layout/docking_layout.dart'; +export 'src/layout/docking_area_type.dart'; +export 'src/layout/drop_position.dart'; +export 'src/layout/typedef_parsers.dart'; +export 'src/layout/layout_parser.dart'; export 'src/on_item_selection.dart'; export 'src/on_item_close.dart'; export 'src/docking_buttons_builder.dart'; diff --git a/lib/src/layout/layout_parser.dart b/lib/src/layout/layout_parser.dart new file mode 100644 index 0000000..69eaa76 --- /dev/null +++ b/lib/src/layout/layout_parser.dart @@ -0,0 +1,220 @@ +import 'package:docking/src/layout/docking_layout.dart'; +import 'package:docking/src/layout/typedef_parsers.dart'; +import 'package:meta/meta.dart'; + +/// Parser from DockingLayout to String. +class LayoutParser { + /// Converts a layout into a String to be stored. + /// + /// The String will have the following structure: + /// VERSION:AREAS_LENGTH:AREAS + /// + /// The VERSION group has a fixed value: V1 + /// + /// The AREAS group separates each area with a comma and follows the + /// pattern: AREA_INDEX_1(AREA_CONFIGURATION),...,AREA_INDEX_N(AREA_CONFIGURATION) + /// Example: 1(AREA_CONFIGURATION),2(AREA_CONFIGURATION),3(AREA_CONFIGURATION) + /// + /// The AREA_CONFIGURATION group represents all area data given the class: + /// + /// * [DockingItem] + /// * AREA_ACRONYM + /// * WEIGHT + /// * MINIMAL_WEIGHT + /// * MINIMAL_SIZE + /// * ID_LENGTH + /// * ID + /// * NAME_LENGTH + /// * NAME + /// * VALUE_LENGTH + /// * VALUE + /// * CLOSABLE + /// * MAXIMIZABLE + /// * MAXIMIZED + /// * CHILDREN_INDEXES + /// * [DockingColumn] + /// * AREA_ACRONYM + /// * WEIGHT + /// * MINIMAL_WEIGHT + /// * MINIMAL_SIZE + /// * CHILDREN_INDEXES + /// * [DockingRow] + /// * AREA_ACRONYM + /// * WEIGHT + /// * MINIMAL_WEIGHT + /// * MINIMAL_SIZE + /// * CHILDREN_INDEXES + /// * [DockingTabs] + /// * AREA_ACRONYM + /// * WEIGHT + /// * MINIMAL_WEIGHT + /// * MINIMAL_SIZE + /// * MAXIMIZABLE + /// * MAXIMIZED + /// * CHILDREN_INDEXES + /// + /// Example: + /// V1:1:1(1;I;.2;;100;5;my_id;7;my_name;8;my_value;T;;F) + String stringify( + {required DockingLayout layout, + IdToString? idToString, + ValueToString? valueToString}) { + final List areas = layout.layoutAreas(); + + String str = 'V1:${areas.length}:'; + for (int i = 0; i < areas.length; i++) { + if (i > 0) { + str += ','; + } + final DockingArea area = areas[i]; + str += '${area.index}('; + str += '${area.areaAcronym};'; + str += '${stringifyArea(area: area)};'; + + if (area is DockingItem) { + str += stringifyItem( + item: area, + idToString: idToString ?? defaultIdToString, + valueToString: valueToString ?? defaultValueToString); + } else if (area is DockingTabs) { + str += stringifyTabs(tabs: area); + } + + if (area is DockingParentArea) { + str += ';'; + str += stringifyParent(parent: area); + } + str += ')'; + } + + return str; + } + + /// Converts the [DockingArea] configuration into a String with the + /// following data separated by semicolons: + /// * WEIGHT + /// * MINIMAL_WEIGHT + /// * MINIMAL_SIZE + /// + /// Example: .2;;100 + @visibleForTesting + String stringifyArea({required DockingArea area}) { + List data = []; + // WEIGHT + data.add('${area.minimalWeight?.toString()}'); + // MINIMAL_SIZE + data.add('${area.minimalWeight?.toString()}'); + // MINIMAL_SIZE + data.add('${area.minimalSize?.toString()}'); + + return data.join(';'); + } + + /// Converts the [DockingItem] configuration into a String with the + /// following data separated by semicolons: + /// * ID_LENGTH + /// * ID + /// * NAME_LENGTH + /// * NAME + /// * VALUE_LENGTH + /// * VALUE + /// * CLOSABLE + /// * MAXIMIZABLE + /// * MAXIMIZED + /// + /// [T] is [TRUE] and [F] is [FALSE]. + /// + /// Example: + /// 5;my_id;7;my_name;8;my_value;T;;F + @visibleForTesting + String stringifyItem( + {required DockingItem item, + required IdToString idToString, + required ValueToString valueToString}) { + List data = []; + + // ID_LENGTH and ID + final String id = idToString(item.id); + data.add(id.length.toString()); + data.add(id); + + // NAME_LENGTH and NAME + final String name = item.name ?? ''; + data.add(name.length.toString()); + data.add(name); + + // VALUE_LENGTH and VALUE + final String value = valueToString(item.value); + data.add(value.length.toString()); + data.add(value); + + // CLOSABLE + data.add(item.closable ? 'T' : 'F'); + + // MAXIMIZABLE + if (item.maximizable != null) { + data.add(item.maximizable! ? 'T' : 'F'); + } else { + data.add(''); + } + + // MAXIMIZED + data.add(item.maximized ? 'T' : 'F'); + + return data.join(';'); + } + + /// Converts the [DockingTabs] configuration into a String with the + /// following data separated by semicolons: + /// * MAXIMIZABLE + /// * MAXIMIZED + /// + /// Example: + /// T;T + @visibleForTesting + String stringifyTabs({required DockingTabs tabs}) { + List data = []; + + // MAXIMIZABLE + if (tabs.maximizable != null) { + data.add(tabs.maximizable! ? 'T' : 'F'); + } else { + data.add(''); + } + + // MAXIMIZED + data.add(tabs.maximized ? 'T' : 'F'); + + return data.join(';'); + } + + /// Converts the children indexes to String separated by colon. + /// + /// Example: + /// 4,5,6 + @visibleForTesting + String stringifyParent({required DockingParentArea parent}) { + List indexes = []; + for (int i = 0; i < parent.childrenCount; i++) { + final DockingArea child = parent.childAt(i); + indexes.add(child.index.toString()); + } + return indexes.join(','); + } + + /// Default conversion from ID to String. + static String defaultIdToString(dynamic id) { + if (id == null) { + return ''; + } + return id.toString(); + } + + /// Default conversion from ID to String. + static String defaultValueToString(dynamic value) { + if (value == null) { + return ''; + } + return value.toString(); + } +} diff --git a/lib/src/layout/typedef_parsers.dart b/lib/src/layout/typedef_parsers.dart new file mode 100644 index 0000000..bad09e2 --- /dev/null +++ b/lib/src/layout/typedef_parsers.dart @@ -0,0 +1,11 @@ +/// Converts ID to String. +typedef IdToString = String Function(dynamic id); + +/// Converts String to ID. +typedef StringToId = dynamic Function(String id); + +/// Converts value to String. +typedef ValueToString = String Function(dynamic value); + +/// Converts String to value. +typedef StringToValue = dynamic Function(String value);