├── .github ├── ISSUE_TEMPLATE │ ├── bug_report.md │ ├── refactor-issue-template.md │ └── request-test-case-template.md └── workflows │ ├── codesee-arch-diagram.yml │ └── dart.yml ├── .gitignore ├── .gitmodules ├── .mergify.yml ├── CHANGELOG.md ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── Dockerfile ├── LICENSE ├── MANIFESTO.md ├── README.md ├── WINDOWS_SETUP.md ├── analysis_options.yaml ├── build.yaml ├── codesee_badge.svg ├── lib ├── analytics │ ├── amplitude_analytics_service.dart │ ├── analytics_constants.dart │ └── sentry_analytics_service.dart ├── configurations │ └── configurations.json ├── controllers │ ├── errors │ │ └── pre_generation_errors.dart │ ├── interpret.dart │ └── main_info.dart ├── generation │ ├── flutter_project_builder │ │ ├── file_system_analyzer.dart │ │ ├── file_writer_observer.dart │ │ ├── flutter_project_builder.dart │ │ ├── import_helper.dart │ │ └── post_gen_tasks │ │ │ ├── comp_isolation │ │ │ ├── component_isolation_generator.dart │ │ │ ├── dashbook │ │ │ │ ├── dashbook_generator.dart │ │ │ │ └── entities │ │ │ │ │ ├── dashbook_book.dart │ │ │ │ │ ├── dashbook_chapter.dart │ │ │ │ │ └── dashbook_story.dart │ │ │ ├── isolation_node.dart │ │ │ ├── isolation_post_gen_task.dart │ │ │ └── widgetbook │ │ │ │ ├── entities │ │ │ │ ├── widgetbook_category.dart │ │ │ │ ├── widgetbook_folder.dart │ │ │ │ ├── widgetbook_use_case.dart │ │ │ │ └── widgetbook_widget.dart │ │ │ │ └── widgetbook_generator.dart │ │ │ ├── global_styling │ │ │ ├── colors_post_gen_task.dart │ │ │ ├── global_styling_aggregator.dart │ │ │ ├── text_styles_post_gen_task.dart │ │ │ └── theming_post_gen_task.dart │ │ │ └── post_gen_task.dart │ ├── generators │ │ ├── attribute-helper │ │ │ ├── pb_attribute_gen_helper.dart │ │ │ ├── pb_box_decoration_gen_helper.dart │ │ │ ├── pb_color_gen_helper.dart │ │ │ └── pb_size_helper.dart │ │ ├── helpers │ │ │ ├── pb_gen_helper.dart │ │ │ └── pb_layout_helper.dart │ │ ├── import_generator.dart │ │ ├── layouts │ │ │ ├── pb_column_gen.dart │ │ │ ├── pb_layout_gen.dart │ │ │ ├── pb_material_gen.dart │ │ │ ├── pb_row_gen.dart │ │ │ ├── pb_scaffold_gen.dart │ │ │ └── pb_stack_gen.dart │ │ ├── middleware │ │ │ ├── command_gen_middleware.dart │ │ │ ├── middleware.dart │ │ │ └── state_management │ │ │ │ ├── bloc_middleware.dart │ │ │ │ ├── provider_middleware.dart │ │ │ │ ├── riverpod_middleware.dart │ │ │ │ ├── state_management_middleware.dart │ │ │ │ ├── stateful_middleware.dart │ │ │ │ └── utils │ │ │ │ └── middleware_utils.dart │ │ ├── pb_flutter_generator.dart │ │ ├── pb_generation_manager.dart │ │ ├── pb_generator.dart │ │ ├── pb_variable.dart │ │ ├── plugins │ │ │ └── pb_plugin_node.dart │ │ ├── screen_builder.dart │ │ ├── symbols │ │ │ ├── layout_builder_gen.dart │ │ │ ├── pb_instancesym_gen.dart │ │ │ ├── pb_mastersym_gen.dart │ │ │ ├── pb_sym_mas_param_gen.dart │ │ │ └── pb_symbol_model.dart │ │ ├── util │ │ │ ├── pb_generation_project_data.dart │ │ │ ├── pb_generation_view_data.dart │ │ │ ├── pb_input_formatter.dart │ │ │ └── topo_tree_iterator.dart │ │ ├── value_objects │ │ │ ├── file_resource.dart │ │ │ ├── file_structure_strategy │ │ │ │ ├── bloc_file_structure_strategy.dart │ │ │ │ ├── command_invoker.dart │ │ │ │ ├── commands │ │ │ │ │ ├── add_constant_command.dart │ │ │ │ │ ├── add_dependency_command.dart │ │ │ │ │ ├── entry_file_command.dart │ │ │ │ │ ├── export_platform_command.dart │ │ │ │ │ ├── file_structure_command.dart │ │ │ │ │ ├── node_file_structure_command.dart │ │ │ │ │ ├── orientation_builder_command.dart │ │ │ │ │ ├── responsive_layout_builder_command.dart │ │ │ │ │ ├── write_screen_command.dart │ │ │ │ │ └── write_symbol_command.dart │ │ │ │ ├── file_ownership_policy.dart │ │ │ │ ├── flutter_file_structure_strategy.dart │ │ │ │ ├── path_services │ │ │ │ │ ├── domain_path_service.dart │ │ │ │ │ └── path_service.dart │ │ │ │ ├── pb_file_structure_strategy.dart │ │ │ │ ├── provider_file_structure_strategy.dart │ │ │ │ └── riverpod_file_structure_strategy.dart │ │ │ ├── generation_configuration │ │ │ │ ├── bloc_generation_configuration.dart │ │ │ │ ├── pb_generation_configuration.dart │ │ │ │ ├── pb_platform_orientation_generation_mixin.dart │ │ │ │ ├── provider_generation_configuration.dart │ │ │ │ ├── riverpod_generation_configuration.dart │ │ │ │ └── stateful_generation_configuration.dart │ │ │ ├── generator_adapter.dart │ │ │ └── template_strategy │ │ │ │ ├── bloc_state_template_strategy.dart │ │ │ │ ├── empty_page_template_strategy.dart │ │ │ │ ├── inline_template_strategy.dart │ │ │ │ ├── pb_template_strategy.dart │ │ │ │ ├── stateful_template_strategy.dart │ │ │ │ └── stateless_template_strategy.dart │ │ ├── visual-widgets │ │ │ ├── pb_align_gen.dart │ │ │ ├── pb_bitmap_gen.dart │ │ │ ├── pb_center_gen.dart │ │ │ ├── pb_container_gen.dart │ │ │ ├── pb_flexible_gen.dart │ │ │ ├── pb_padding_gen.dart │ │ │ ├── pb_positioned_gen.dart │ │ │ ├── pb_shape_group_gen.dart │ │ │ ├── pb_spacer_gen.dart │ │ │ ├── pb_text_gen.dart │ │ │ └── pb_text_style_gen_mixin.dart │ │ └── writers │ │ │ ├── pb_flutter_writer.dart │ │ │ ├── pb_page_writer.dart │ │ │ └── pb_traversal_adapter_writer.dart │ ├── helperScripts │ │ ├── index.dart │ │ ├── shell-proxy.dart │ │ └── shell-proxy.sh │ └── prototyping │ │ ├── pb_dest_holder.dart │ │ ├── pb_prototype_aggregation_service.dart │ │ ├── pb_prototype_gen.dart │ │ ├── pb_prototype_linker_service.dart │ │ ├── pb_prototype_node.dart │ │ ├── pb_prototype_node.g.dart │ │ └── pb_prototype_storage.dart ├── interpret_and_optimize │ ├── entities │ │ ├── alignments │ │ │ ├── expanded.dart │ │ │ ├── flexible.dart │ │ │ ├── injected_align.dart │ │ │ ├── injected_center.dart │ │ │ ├── injected_positioned.dart │ │ │ ├── padding.dart │ │ │ └── spacer.dart │ │ ├── container.dart │ │ ├── inherited_bitmap.dart │ │ ├── inherited_bitmap.g.dart │ │ ├── inherited_circle.dart │ │ ├── inherited_circle.g.dart │ │ ├── inherited_container.dart │ │ ├── inherited_container.g.dart │ │ ├── inherited_material.dart │ │ ├── inherited_material.g.dart │ │ ├── inherited_oval.dart │ │ ├── inherited_oval.g.dart │ │ ├── inherited_polygon.dart │ │ ├── inherited_polygon.g.dart │ │ ├── inherited_scaffold.dart │ │ ├── inherited_scaffold.g.dart │ │ ├── inherited_shape_group.dart │ │ ├── inherited_shape_group.g.dart │ │ ├── inherited_shape_path.dart │ │ ├── inherited_shape_path.g.dart │ │ ├── inherited_star.dart │ │ ├── inherited_star.g.dart │ │ ├── inherited_text.dart │ │ ├── inherited_text.g.dart │ │ ├── inherited_triangle.dart │ │ ├── inherited_triangle.g.dart │ │ ├── injected_container.dart │ │ ├── injected_container.g.dart │ │ ├── injected_sized_box.dart │ │ ├── interfaces │ │ │ ├── pb_inherited_intermediate.dart │ │ │ ├── pb_injected_intermediate.dart │ │ │ └── pb_prototype_enabled.dart │ │ ├── layouts │ │ │ ├── auto_layout_align_strategy.dart │ │ │ ├── column.dart │ │ │ ├── column.g.dart │ │ │ ├── exceptions │ │ │ │ ├── layout_exception.dart │ │ │ │ └── stack_exception.dart │ │ │ ├── group │ │ │ │ ├── base_group.dart │ │ │ │ ├── base_group.g.dart │ │ │ │ ├── frame_group.dart │ │ │ │ ├── frame_group.g.dart │ │ │ │ └── group.dart │ │ │ ├── layout_properties.dart │ │ │ ├── layout_properties.g.dart │ │ │ ├── row.dart │ │ │ ├── row.g.dart │ │ │ ├── rules │ │ │ │ ├── axis_comparison_rules.dart │ │ │ │ ├── container_constraint_rule.dart │ │ │ │ ├── container_rule.dart │ │ │ │ ├── handle_flex.dart │ │ │ │ ├── layout_rule.dart │ │ │ │ └── stack_reduction_visual_rule.dart │ │ │ └── stack.dart │ │ ├── pb_deny_list_node.dart │ │ ├── pb_shared_instance.dart │ │ ├── pb_shared_instance.g.dart │ │ ├── pb_shared_master_node.dart │ │ ├── pb_shared_master_node.g.dart │ │ └── subclasses │ │ │ ├── pb_intermediate_constraints.dart │ │ │ ├── pb_intermediate_constraints.g.dart │ │ │ ├── pb_intermediate_node.dart │ │ │ ├── pb_intermediate_node.g.dart │ │ │ ├── pb_layout_intermediate_node.dart │ │ │ └── pb_visual_intermediate_node.dart │ ├── helpers │ │ ├── abstract_intermediate_node_factory.dart │ │ ├── align_strategy.dart │ │ ├── child_strategy.dart │ │ ├── component_isolation_configuration.dart │ │ ├── element_storage.dart │ │ ├── index_walker.dart │ │ ├── layer_tuple.dart │ │ ├── node_tuple.dart │ │ ├── override_helper.dart │ │ ├── pb_color.dart │ │ ├── pb_color.g.dart │ │ ├── pb_configuration.dart │ │ ├── pb_configuration.g.dart │ │ ├── pb_context.dart │ │ ├── pb_deny_list_helper.dart │ │ ├── pb_gen_cache.dart │ │ ├── pb_image_reference_storage.dart │ │ ├── pb_intermediate_node_tree.dart │ │ ├── pb_intermediate_node_tree.g.dart │ │ ├── pb_plugin_list_helper.dart │ │ ├── pb_project.dart │ │ ├── pb_project.g.dart │ │ ├── pb_state_management_helper.dart │ │ ├── pb_state_management_linker.dart │ │ └── pb_symbol_storage.dart │ ├── services │ │ ├── component_isolation │ │ │ ├── dashbook_service.dart │ │ │ └── widgetbook_service.dart │ │ ├── design_to_pbdl │ │ │ ├── design_to_pbdl_service.dart │ │ │ ├── figma_to_pbdl_service.dart │ │ │ └── json_to_pbdl_service.dart │ │ ├── intermediate_node_searcher_service.dart │ │ ├── pb_alignment_generation_service.dart │ │ ├── pb_constraint_generation_service.dart │ │ ├── pb_layout_generation_service.dart │ │ ├── pb_platform_orientation_linker_service.dart │ │ ├── pb_plugin_control_service.dart │ │ ├── pb_semantic_generation_service.dart │ │ ├── pb_shared_aggregation_service.dart │ │ ├── pb_symbol_linker_service.dart │ │ └── state_management_node_interpreter.dart │ ├── state_management │ │ ├── auxilary_data_helpers │ │ │ ├── intermediate_border.dart │ │ │ ├── intermediate_border.g.dart │ │ │ ├── intermediate_border_info.dart │ │ │ ├── intermediate_border_info.g.dart │ │ │ ├── intermediate_effect.dart │ │ │ ├── intermediate_effect.g.dart │ │ │ ├── intermediate_fill.dart │ │ │ ├── intermediate_fill.g.dart │ │ │ ├── intermediate_text_style.dart │ │ │ └── intermediate_text_style.g.dart │ │ ├── directed_state_graph.dart │ │ ├── intermediate_auxillary_data.dart │ │ ├── intermediate_auxillary_data.g.dart │ │ └── intermediate_vertex.dart │ └── value_objects │ │ ├── pb_symbol_instance_overridable_value.dart │ │ ├── pb_symbol_master_overridable_prop.dart │ │ └── pb_symbol_master_params.dart ├── main.dart └── tags │ ├── custom_tag │ ├── custom_tag.dart │ └── custom_tag_bloc_generator.dart │ ├── custom_text_form_field │ ├── custom_text_form_field.dart │ └── custom_text_form_field_generator.dart │ ├── injected_app_bar.dart │ └── injected_tab_bar.dart ├── parabeac.dart ├── pb-scripts ├── auto_download.sh ├── automate.sh ├── check-git.sh ├── install.sh ├── merge-plugins.sh ├── parabird.txt └── sketchtool_proxy.sh ├── pubspec.yaml ├── repo_assets ├── Duplicate Figma File.gif ├── figma_component_example.png ├── figma_frame_example.png └── parabeac_core_image.png └── test └── golden ├── all_tests.dart ├── auto_layout_test.dart ├── global_styling_test.dart ├── golden_files ├── auto_layout │ ├── admin_city_section_edit_screen.golden │ ├── auto_layout_file_names.txt │ ├── col_hz_fx_vr_fx_sp_pk1.golden │ ├── col_hz_fx_vr_fx_sp_pk2.golden │ ├── col_hz_fx_vr_fx_sp_pk3.golden │ ├── col_hz_fx_vr_fx_sp_pk4.golden │ ├── col_hz_fx_vr_fx_sp_pk5.golden │ ├── col_hz_fx_vr_fx_sp_pk6.golden │ ├── col_hz_fx_vr_fx_sp_pk7.golden │ ├── col_hz_fx_vr_fx_sp_pk8.golden │ ├── col_hz_fx_vr_fx_sp_pk9.golden │ ├── col_hz_fx_vr_fx_sp_sb147.golden │ ├── col_hz_fx_vr_fx_sp_sb258.golden │ ├── col_hz_fx_vr_fx_sp_sb369.golden │ ├── col_hz_fx_vr_hg_sp_pk147.golden │ ├── col_hz_fx_vr_hg_sp_pk258.golden │ ├── col_hz_fx_vr_hg_sp_pk369.golden │ ├── col_hz_hg_vr_fx_sp_pk1.golden │ ├── col_hz_hg_vr_fx_sp_pk2.golden │ ├── col_hz_hg_vr_fx_sp_pk3.golden │ ├── col_hz_hg_vr_fx_sp_pk4.golden │ ├── col_hz_hg_vr_fx_sp_pk5.golden │ ├── col_hz_hg_vr_fx_sp_pk6.golden │ ├── col_hz_hg_vr_fx_sp_pk7.golden │ ├── col_hz_hg_vr_fx_sp_pk8.golden │ ├── col_hz_hg_vr_fx_sp_pk9.golden │ ├── col_hz_hg_vr_fx_sp_sb147.golden │ ├── col_hz_hg_vr_fx_sp_sb258.golden │ ├── col_hz_hg_vr_fx_sp_sb369.golden │ ├── col_hz_hg_vr_hg_sp_pk123456789.golden │ ├── custom_test_screen.golden │ ├── no_space_col_hz_hg_vr_hg_sp_pk123456789.golden │ ├── no_space_row_hz_hg_vr_hg_sp_pk123456789.golden │ ├── row_hz_fx_vr_fx_sp_pk1.golden │ ├── row_hz_fx_vr_fx_sp_pk2.golden │ ├── row_hz_fx_vr_fx_sp_pk3.golden │ ├── row_hz_fx_vr_fx_sp_pk4.golden │ ├── row_hz_fx_vr_fx_sp_pk5.golden │ ├── row_hz_fx_vr_fx_sp_pk6.golden │ ├── row_hz_fx_vr_fx_sp_pk7.golden │ ├── row_hz_fx_vr_fx_sp_pk8.golden │ ├── row_hz_fx_vr_fx_sp_pk9.golden │ ├── row_hz_fx_vr_fx_sp_sb123.golden │ ├── row_hz_fx_vr_fx_sp_sb456.golden │ ├── row_hz_fx_vr_fx_sp_sb789.golden │ ├── row_hz_fx_vr_hg_sp_pk147.golden │ ├── row_hz_fx_vr_hg_sp_pk258.golden │ ├── row_hz_fx_vr_hg_sp_pk369.golden │ ├── row_hz_fx_vr_hg_sp_sb123456789.golden │ ├── row_hz_hg_vr_fx_sp_pk147.golden │ ├── row_hz_hg_vr_fx_sp_pk258.golden │ ├── row_hz_hg_vr_fx_sp_pk369.golden │ ├── row_hz_hg_vr_hg_sp_pk123456789.golden │ └── test_screen.golden ├── global_styling │ ├── styling_colors.golden │ └── styling_text_styles.golden └── styling │ ├── helloworld.golden │ ├── primary_button.golden │ ├── primary_button_rect.golden │ ├── secondary_button.golden │ └── styling.golden └── styling_test.dart /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: bug 6 | assignees: '' 7 | 8 | --- 9 | 10 | ## **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | ## **To Reproduce** 14 | Steps to reproduce the behavior: 15 | 1. Go to '...' 16 | 2. Click on '....' 17 | 3. Scroll down to '....' 18 | 4. See error 19 | 20 | ## **Impact of the problem** 21 | A clear and concise description of what problem the bug is causing. 22 | 23 | 24 | ## **Environment:** 25 | - OS: [e.g. macOS] 26 | 27 | 28 | ## **Screenshots** 29 | If applicable, add screenshots to help explain your problem. 30 | 31 | ## **Additional comments/context:** 32 | If applicable, add any additional context related to the bug. 33 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/refactor-issue-template.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Refactor Issue Template 3 | about: Request a change in the codebase. 4 | title: '' 5 | labels: enhancement, refactor 6 | assignees: '' 7 | 8 | --- 9 | 10 | ## Change Proposal 11 | Describe in a sentence or two the change that is being requested. 12 | 13 | ### Module and Current Solution 14 | What is this change going to affect (Alignment Service, Generation Service, etc...) and the current solution that is implemented. 15 | 16 | ## Benefits of the Change 17 | What improvements occur because of this change? (Readability, Performance, Scalability, etc...) 18 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/request-test-case-template.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Test Case Request Template 3 | about: Request a test case. 4 | title: '' 5 | labels: Integration Testing 6 | assignees: '' 7 | 8 | --- 9 | 10 | ## Test Case Proposal 11 | Describe in a sentence or two the test case that is being requested. 12 | 13 | ## Additional information 14 | Screenshots, examples, etc. 15 | 16 | ## Benefits of the Test Case 17 | What improvements occur because of this change? 18 | -------------------------------------------------------------------------------- /.github/workflows/dart.yml: -------------------------------------------------------------------------------- 1 | name: Dart CI 2 | 3 | on: 4 | push: 5 | branches: [ stable, dev ] 6 | pull_request: 7 | branches: [ stable, dev ] 8 | 9 | jobs: 10 | 11 | build: 12 | 13 | runs-on: ubuntu-latest 14 | services: 15 | sketch_asset_converter: 16 | image: parabeac/sac 17 | ports: 18 | - 4000:4000 19 | 20 | steps: 21 | - uses: actions/checkout@v2 22 | - name: Flutter action 23 | uses: subosito/flutter-action@v2 24 | 25 | - name: Install dependencies 26 | run: dart pub get 27 | - name: Run tests 28 | run: dart run test 29 | env: 30 | FIG_API_KEY: ${{ secrets.FIG_API_KEY }} 31 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Files and directories created by pub 2 | .dart_tool/ 3 | .packages 4 | # Remove the following pattern if you wish to check in your lock file 5 | pubspec.lock 6 | # Conventional directory for build outputs 7 | build/ 8 | TestingSketch/ 9 | 10 | # Directory created by dartdoc 11 | doc/api/ 12 | 13 | .idea/ 14 | .vscode/ 15 | out/ 16 | temp/ 17 | .DS_Store 18 | TestingSketch 19 | debug 20 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Parabeac/parabeac_core/bbc4523c6682bbd3a43af04448a9870ff7d4699e/.gitmodules -------------------------------------------------------------------------------- /.mergify.yml: -------------------------------------------------------------------------------- 1 | pull_request_rules: 2 | 3 | - name: Close PR if it's going to stable but it's not dev or a hotfix 4 | conditions: 5 | - base=stable # Merging into stable 6 | - -head~=(?i)^hotfix # Name of branch does not start with hotfix 7 | - -head~=^dev$ # Branch is not dev 8 | - -head~=^mergify 9 | actions: 10 | close: 11 | message: "Please ensure that you are merging any non-hotfix branches 12 | into `dev`. If this branch is a hotfix, please use the prefix `hotfix` 13 | as title to your branch. If you have any questions check out our Tree Hygiene docs 14 | in the Wiki. Thank you!" 15 | 16 | - name: Comment on PR if conflicts are present 17 | conditions: 18 | - conflict 19 | actions: 20 | comment: 21 | message: "Thank you for your contribution @{{author}}, however this 22 | pull request contains conflicts. Could you please fix them? Feel free 23 | to contact us on Discord for help. Thank you!" 24 | 25 | 26 | - name: Backport PR to dev if merging to stable 27 | conditions: 28 | - base=stable 29 | - "#approved-reviews-by>=1" 30 | actions: 31 | backport: 32 | branches: ["dev"] 33 | 34 | - name: Merge pull request on approval 35 | conditions: 36 | - "#approved-reviews-by>=1" 37 | - -closed 38 | - label!=review-required # Only merge PRs that are NOT labeled review-required. 39 | - check-success=build 40 | actions: 41 | merge: 42 | method: merge 43 | 44 | 45 | - name: Automatically merge copied PRs 46 | conditions: 47 | - author~=^mergify\[bot\]$ 48 | - base=dev 49 | - -conflict 50 | actions: 51 | merge: 52 | method: merge 53 | 54 | - name: Delete merged branch 55 | conditions: 56 | - merged 57 | actions: 58 | delete_head_branch: {} 59 | 60 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ## 1.0.0 2 | 3 | - Initial version, created by Stagehand 4 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM google/dart 2 | 3 | WORKDIR /app 4 | 5 | ADD pubspec.* /app/ 6 | RUN pub get 7 | ADD . /app 8 | RUN pub get --offline 9 | 10 | CMD [] 11 | ENTRYPOINT ["/usr/bin/dart", "./lib/main.dart"] -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | BSD 3-Clause License 2 | 3 | Copyright (c) 2020, Parabeac 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 9 | 1. Redistributions of source code must retain the above copyright notice, this 10 | list of conditions and the following disclaimer. 11 | 12 | 2. Redistributions in binary form must reproduce the above copyright notice, 13 | this list of conditions and the following disclaimer in the documentation 14 | and/or other materials provided with the distribution. 15 | 16 | 3. Neither the name of the copyright holder nor the names of its 17 | contributors may be used to endorse or promote products derived from 18 | this software without specific prior written permission. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 23 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 24 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 26 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 27 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 28 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | -------------------------------------------------------------------------------- /MANIFESTO.md: -------------------------------------------------------------------------------- 1 | # Parabeac Core: Our Open Source Conversion Tool 2 | 3 | Why go to 8 months of effort to build a new tool, just to have developers around the world roaming through the source code? 4 | 5 | Easy. Parabeac builds apps for developers, so who better to ensure our tool quality? Frankly, the developers we built this tool for could probably build it themselves (though, honestly, we think we did a pretty sweet job). Our belief is that the quality of Parabeac code should be defined not by us, but instead by the real-time consensus of the global developer community. 6 | 7 | We love what we do at Parabeac. Most of us live out in far West Texas but we honor and respect the global developer community, from Mountain View to Shanghai. We know an ocean of global enthusiasts will make Parabeac better in ways we could never have envisioned by ourselves. They will configure and change to fit what their real requirements are, not what we thought their requirements might be. In short, we want Parabeac Core to be the clear pool of open source code into which every developer around the world can see a bit of their own reflection. 8 | 9 | So welcome. 10 | -------------------------------------------------------------------------------- /analysis_options.yaml: -------------------------------------------------------------------------------- 1 | # Defines a default set of lint rules enforced for 2 | # projects at Google. For details and rationale, 3 | # see https://github.com/dart-lang/pedantic#enabled-lints. 4 | include: package:pedantic/analysis_options.yaml 5 | 6 | # For lint rules and documentation, see http://dart-lang.github.io/linter/lints. 7 | # Uncomment to specify additional rules. 8 | linter: 9 | rules: 10 | - camel_case_types 11 | - always_require_non_null_named_parameters 12 | - avoid_empty_else 13 | - no_duplicate_case_values 14 | - always_put_control_body_on_new_line 15 | - annotate_overrides 16 | - avoid_init_to_null 17 | - empty_catches 18 | - file_names 19 | - package_api_docs 20 | # - public_member_api_docs 21 | - use_setters_to_change_properties 22 | 23 | analyzer: 24 | # exclude: 25 | # - path/to/excluded/files/** 26 | -------------------------------------------------------------------------------- /build.yaml: -------------------------------------------------------------------------------- 1 | targets: 2 | $default: 3 | builders: 4 | parabeac_core|json_serializable: 5 | generate_for: 6 | include: 7 | - lib/** 8 | exclude: 9 | - test/lib/** 10 | options: 11 | any_map: false 12 | checked: false 13 | create_factory: false 14 | create_to_json: true 15 | disallow_unrecognized_keys: false 16 | explicit_to_json: false 17 | ignore_unannotated: true 18 | include_if_null: true 19 | nullable: true -------------------------------------------------------------------------------- /lib/analytics/analytics_constants.dart: -------------------------------------------------------------------------------- 1 | const RUN_PARABEAC = 'Run Parabeac'; 2 | 3 | /// Interpretation 4 | const INTERPRETATION = 'Interpretation'; 5 | const HANDLE_CHILDREN = 'Handle Children'; 6 | const INTERMEDIATE_SERVICES = 'Intermediate Services'; 7 | 8 | /// Generation 9 | const GENERATION = 'Generation'; 10 | const COMMAND_QUEUE = 'Command Queue'; 11 | const GEN_DRY_RUN = 'Gen AIT Dry Run'; 12 | const GEN_AIT = 'Gen AIT'; 13 | 14 | /// Misc 15 | const PRE_GEN = 'Pre Gen Tasks'; 16 | const POST_GEN = 'Post Gen Tasks'; 17 | -------------------------------------------------------------------------------- /lib/analytics/sentry_analytics_service.dart: -------------------------------------------------------------------------------- 1 | import 'package:quick_log/quick_log.dart'; 2 | import 'package:sentry/sentry.dart'; 3 | 4 | /// Class that uses Sentry to log transactions. 5 | /// 6 | /// These transactions are meant to track performance throughout parabeac_core. 7 | class SentryService { 8 | static final _logger = Logger('$SentryService'); 9 | static var transactions = {}; 10 | 11 | /// Starts a main transaction. 12 | /// 13 | /// The [id] is the unique name of the transaction. The [operation] is what is being performed. 14 | /// The optional [description] is used to provide more context on the [operation] within Sentry. 15 | static void startTransaction(String id, String operation, 16 | {String description}) { 17 | if (!transactions.containsKey(id)) { 18 | final transaction = 19 | Sentry.startTransaction(id, operation, description: description); 20 | 21 | transactions[id] = transaction; 22 | } else { 23 | _logger 24 | .error('Transaction $id already exists. Cannot start transaction.'); 25 | } 26 | } 27 | 28 | /// Starts a child transaction from a parent transaction with a unique [id]. 29 | /// 30 | /// The [id] refers to the `parent` transaction. 31 | /// The [operation] is what the `child` transaction is performing, and must be unique. 32 | /// The optional [description] is used to provide more context on the [operation] within Sentry. 33 | static void startChildTransactionFrom(String id, String operation, 34 | {String description}) { 35 | if (transactions.containsKey(id) && !transactions.containsKey(operation)) { 36 | final transaction = 37 | transactions[id].startChild(operation, description: description); 38 | 39 | transactions[operation] = transaction; 40 | } else { 41 | _logger.error( 42 | 'Transaction \"$id\" does not exist or transaction \"$operation\" already exists. Cannot start child transaction.'); 43 | } 44 | } 45 | 46 | /// Finishes transaction with a unique [id]. 47 | static Future finishTransaction(String id) async { 48 | if (transactions.containsKey(id)) { 49 | await transactions[id].finish(); 50 | transactions.remove(id); 51 | } else { 52 | _logger 53 | .error('Transaction $id does not exist. Cannot finish transaction.'); 54 | } 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /lib/configurations/configurations.json: -------------------------------------------------------------------------------- 1 | { 2 | "breakpoints": { 3 | "mobile": 360, 4 | "tablet": 600, 5 | "desktop": 1280 6 | }, 7 | "designSystem": "material3", 8 | "componentIsolation": "widgetbook", 9 | "folderArchitecture": "domain", 10 | "project-name": "foo", 11 | "project-type": "screens", 12 | "fig": "Enter your Figma File ID here", 13 | "figKey": "Enter your Figma API Key here", 14 | "out": "/absolute/path/to/output/directory" 15 | } 16 | -------------------------------------------------------------------------------- /lib/controllers/errors/pre_generation_errors.dart: -------------------------------------------------------------------------------- 1 | class RootItemNotSetError extends Error { 2 | @override 3 | String toString() { 4 | return 'The root screen of the application must be set in the dashboard for a project conversion.'; 5 | } 6 | } -------------------------------------------------------------------------------- /lib/generation/flutter_project_builder/file_writer_observer.dart: -------------------------------------------------------------------------------- 1 | abstract class FileWriterObserver { 2 | ///Event receiver that a file was created. In the event, 3 | ///there is going to be access to the following parameters: 4 | /// 5 | ///`filePath`: the path of where the file was created at. 6 | ///`fileUUID`: the unique identifier of the file. 7 | void fileCreated(String filePath, String fileUUID); 8 | } 9 | -------------------------------------------------------------------------------- /lib/generation/flutter_project_builder/post_gen_tasks/comp_isolation/component_isolation_generator.dart: -------------------------------------------------------------------------------- 1 | import 'package:parabeac_core/generation/flutter_project_builder/import_helper.dart'; 2 | import 'package:parabeac_core/generation/generators/util/pb_generation_project_data.dart'; 3 | 4 | /// Class that represents a Component Isolation Generator. 5 | /// 6 | /// This class sets up the Component Isolation Package (i.e. Widgetbook, Dashbook, etc.) 7 | /// to create the necessary classes and generate the code at the end. 8 | abstract class ComponentIsolationGenerator { 9 | /// Method that generates the code for this generator. 10 | String generateCode(ImportHelper importHelper); 11 | 12 | /// Path to the file to be written, relative to the `lib` directory. 13 | String fileName; 14 | 15 | /// projectData used to add dependencies to the project. 16 | PBGenerationProjectData projectData; 17 | } 18 | -------------------------------------------------------------------------------- /lib/generation/flutter_project_builder/post_gen_tasks/comp_isolation/dashbook/dashbook_generator.dart: -------------------------------------------------------------------------------- 1 | import 'package:parabeac_core/controllers/main_info.dart'; 2 | import 'package:parabeac_core/generation/flutter_project_builder/import_helper.dart'; 3 | import 'package:parabeac_core/generation/flutter_project_builder/post_gen_tasks/comp_isolation/component_isolation_generator.dart'; 4 | import 'package:parabeac_core/generation/generators/import_generator.dart'; 5 | import 'package:parabeac_core/generation/generators/util/pb_generation_project_data.dart'; 6 | import 'package:parabeac_core/interpret_and_optimize/services/component_isolation/dashbook_service.dart'; 7 | 8 | class DashbookGenerator implements ComponentIsolationGenerator { 9 | @override 10 | String fileName = 'main_dashbook.dart'; 11 | 12 | DashbookGenerator(this.projectData) { 13 | projectData.addDependencies('dashbook', '^0.1.6'); 14 | } 15 | 16 | @override 17 | PBGenerationProjectData projectData; 18 | 19 | @override 20 | String generateCode(ImportHelper helper) { 21 | var book = DashbookService.book; 22 | var treeIds = DashbookService.treeIds; 23 | var generatedCode = book.generate(); 24 | 25 | var imports = treeIds 26 | .map( 27 | (id) => helper 28 | .getFormattedImports( 29 | id, 30 | importMapper: (import) => FlutterImport( 31 | import, 32 | MainInfo().projectName, 33 | ), 34 | ) 35 | .join('\n'), 36 | ) 37 | .join(''); 38 | return ''' 39 | import 'package:flutter/material.dart'; 40 | import 'package:dashbook/dashbook.dart'; 41 | $imports 42 | 43 | void main() { 44 | final dashbook = Dashbook(); 45 | 46 | $generatedCode 47 | 48 | runApp(dashbook); 49 | } 50 | '''; 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /lib/generation/flutter_project_builder/post_gen_tasks/comp_isolation/dashbook/entities/dashbook_book.dart: -------------------------------------------------------------------------------- 1 | import 'package:parabeac_core/generation/flutter_project_builder/post_gen_tasks/comp_isolation/dashbook/entities/dashbook_story.dart'; 2 | import 'package:parabeac_core/generation/flutter_project_builder/post_gen_tasks/comp_isolation/isolation_node.dart'; 3 | 4 | /// Class that represents a group of [DashBookStories]. 5 | /// 6 | /// This class does not actually exist in Dashbook. However, 7 | /// it makes it easier for us to group stories and generate them 8 | /// in a single step. 9 | class DashBookBook extends IsolationNode { 10 | DashBookBook({ 11 | String name = 'Parabeac-Generated', 12 | }) : super(name: name); 13 | 14 | @override 15 | String generate() { 16 | var stories = getType(); 17 | 18 | var storiesGen = ''; 19 | 20 | if (stories != null && stories.isNotEmpty) { 21 | storiesGen = stories.map((s) => s.generate()).join('\n'); 22 | } 23 | return ''' 24 | ${storiesGen.isNotEmpty ? ' $storiesGen\n' : ''} 25 | '''; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /lib/generation/flutter_project_builder/post_gen_tasks/comp_isolation/dashbook/entities/dashbook_chapter.dart: -------------------------------------------------------------------------------- 1 | import 'package:parabeac_core/generation/flutter_project_builder/post_gen_tasks/comp_isolation/isolation_node.dart'; 2 | 3 | class DashBookChapter extends IsolationNode { 4 | String builderCode; 5 | DashBookChapter(String name, this.builderCode) : super(name: name); 6 | 7 | @override 8 | String generate() { 9 | return ''' 10 | .add('$name', 11 | (ctx) => $builderCode) 12 | '''; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /lib/generation/flutter_project_builder/post_gen_tasks/comp_isolation/dashbook/entities/dashbook_story.dart: -------------------------------------------------------------------------------- 1 | import 'package:parabeac_core/generation/flutter_project_builder/post_gen_tasks/comp_isolation/dashbook/entities/dashbook_chapter.dart'; 2 | import 'package:parabeac_core/generation/flutter_project_builder/post_gen_tasks/comp_isolation/isolation_node.dart'; 3 | 4 | /// Node that represents a Widgetbook component. 5 | class DashBookStory extends IsolationNode { 6 | DashBookStory(String name) : super(name: name); 7 | 8 | @override 9 | String generate() { 10 | var chapters = getType(); 11 | var chaptersGen = ''; 12 | if (chapters != null && chapters.isNotEmpty) { 13 | chaptersGen = chapters.map((chapter) => chapter.generate()).join('\n'); 14 | } 15 | return ''' 16 | dashbook 17 | .storiesOf('$name') 18 | .decorator(CenterDecorator()) 19 | $chaptersGen 20 | ; 21 | '''; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /lib/generation/flutter_project_builder/post_gen_tasks/comp_isolation/isolation_node.dart: -------------------------------------------------------------------------------- 1 | /// Class that represents a generic Component Isolation Node. 2 | /// 3 | /// For instance, Widgetbook may have Categories, Folders, etc., 4 | /// while Dashbook has Stories and Chapters. This node can represent 5 | /// these in a generic way. 6 | abstract class IsolationNode { 7 | String name; 8 | 9 | List children; 10 | 11 | /// Generates a string representation of how the 12 | /// [IsolationNode] should be printed. 13 | String generate(); 14 | 15 | IsolationNode({this.children, this.name}) { 16 | children ??= []; 17 | } 18 | 19 | /// Adds a child to the [IsolationNode]. 20 | void addChild(IsolationNode child) { 21 | children.add(child); 22 | } 23 | 24 | List getType() => 25 | children.whereType().toList(); 26 | 27 | /// Returns [IsolationNode] with type [T] and name [name]. 28 | /// 29 | /// Returns null if no such node exists. 30 | IsolationNode getNamed(String name) => 31 | children.whereType().firstWhere( 32 | (element) => element.name == name, 33 | orElse: () => null, 34 | ); 35 | } 36 | -------------------------------------------------------------------------------- /lib/generation/flutter_project_builder/post_gen_tasks/comp_isolation/isolation_post_gen_task.dart: -------------------------------------------------------------------------------- 1 | import 'package:parabeac_core/generation/flutter_project_builder/post_gen_tasks/comp_isolation/component_isolation_generator.dart'; 2 | import 'package:parabeac_core/generation/flutter_project_builder/post_gen_tasks/post_gen_task.dart'; 3 | import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/commands/write_symbol_command.dart'; 4 | import 'package:parabeac_core/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart'; 5 | 6 | /// This class is responsible for coordinating the generation of the 7 | /// component isolation code based on the given configuration. 8 | class IsolationPostGenTask implements PostGenTask { 9 | /// Specific instance of the configuration to execute 10 | ComponentIsolationGenerator compIsoConfiguration; 11 | 12 | /// GenerationConfiguration to get strategy and imports 13 | GenerationConfiguration generationConfiguration; 14 | IsolationPostGenTask(this.compIsoConfiguration, this.generationConfiguration); 15 | @override 16 | void execute() { 17 | var isolationCode = compIsoConfiguration.generateCode( 18 | generationConfiguration.generationManager.importProcessor); 19 | var fileName = compIsoConfiguration.fileName; 20 | 21 | /// TODO: WriteSymbolCommand was used as a workaround. We should generate a command that generically writes any file 22 | generationConfiguration.fileStructureStrategy.commandCreated( 23 | WriteSymbolCommand(null, fileName, isolationCode, symbolPath: 'lib/')); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /lib/generation/flutter_project_builder/post_gen_tasks/comp_isolation/widgetbook/entities/widgetbook_category.dart: -------------------------------------------------------------------------------- 1 | import 'package:parabeac_core/generation/flutter_project_builder/post_gen_tasks/comp_isolation/isolation_node.dart'; 2 | import 'package:parabeac_core/generation/flutter_project_builder/post_gen_tasks/comp_isolation/widgetbook/entities/widgetbook_folder.dart'; 3 | import 'package:parabeac_core/generation/flutter_project_builder/post_gen_tasks/comp_isolation/widgetbook/entities/widgetbook_widget.dart'; 4 | 5 | /// Class that represents a WidgetBook Category. 6 | class WidgetBookCategory extends IsolationNode { 7 | WidgetBookCategory({ 8 | String name = 'Parabeac-Generated', 9 | }) : super(name: name); 10 | 11 | @override 12 | String generate() { 13 | var folders = getType(); 14 | var widgets = getType(); 15 | 16 | var folderGen = ''; 17 | var widgetsGen = ''; 18 | 19 | if (folders != null && folders.isNotEmpty) { 20 | folderGen = folders.map((f) => f.generate()).join('\n'); 21 | } 22 | if (widgets != null && widgets.isNotEmpty) { 23 | widgetsGen = widgets.map((w) => w.generate()).join('\n'); 24 | } 25 | return ''' 26 | WidgetbookCategory( 27 | name: 'Parabeac-Generated', 28 | ${folderGen.isNotEmpty ? 'folders: [\n$folderGen\n],\n' : ''} 29 | ${widgetsGen.isNotEmpty ? 'widgets: [\n$widgetsGen\n],\n' : ''} 30 | ) 31 | '''; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /lib/generation/flutter_project_builder/post_gen_tasks/comp_isolation/widgetbook/entities/widgetbook_folder.dart: -------------------------------------------------------------------------------- 1 | import 'package:parabeac_core/generation/flutter_project_builder/post_gen_tasks/comp_isolation/isolation_node.dart'; 2 | import 'package:parabeac_core/generation/flutter_project_builder/post_gen_tasks/comp_isolation/widgetbook/entities/widgetbook_widget.dart'; 3 | 4 | class WidgetBookFolder extends IsolationNode { 5 | WidgetBookFolder(String name) : super(name: name); 6 | 7 | @override 8 | String generate() { 9 | var widgets = getType(); 10 | var genWidgets = ''; 11 | if (widgets != null && widgets.isNotEmpty) { 12 | genWidgets = widgets.map((node) => node.generate()).join(',\n'); 13 | } 14 | return ''' 15 | WidgetbookFolder( 16 | name: '$name', 17 | ${genWidgets.isNotEmpty ? 'widgets: [\n$genWidgets\n],\n' : ''} 18 | ), 19 | '''; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /lib/generation/flutter_project_builder/post_gen_tasks/comp_isolation/widgetbook/entities/widgetbook_use_case.dart: -------------------------------------------------------------------------------- 1 | import 'package:parabeac_core/generation/flutter_project_builder/post_gen_tasks/comp_isolation/isolation_node.dart'; 2 | 3 | class WidgetBookUseCase extends IsolationNode { 4 | String builderCode; 5 | WidgetBookUseCase(String name, this.builderCode) : super(name: name); 6 | 7 | @override 8 | String generate() { 9 | return ''' 10 | WidgetbookUseCase( 11 | name: '$name', 12 | builder: (context) => Center(child: $builderCode), 13 | ), 14 | '''; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /lib/generation/flutter_project_builder/post_gen_tasks/comp_isolation/widgetbook/entities/widgetbook_widget.dart: -------------------------------------------------------------------------------- 1 | import 'package:parabeac_core/generation/flutter_project_builder/post_gen_tasks/comp_isolation/isolation_node.dart'; 2 | import 'package:parabeac_core/generation/flutter_project_builder/post_gen_tasks/comp_isolation/widgetbook/entities/widgetbook_use_case.dart'; 3 | 4 | /// Node that represents a Widgetbook component. 5 | class WidgetBookWidget extends IsolationNode { 6 | WidgetBookWidget(String name) : super(name: name); 7 | 8 | @override 9 | String generate() { 10 | var useCases = getType(); 11 | var useCasesGen = ''; 12 | if (useCases != null && useCases.isNotEmpty) { 13 | useCasesGen = useCases.map((useCase) => useCase.generate()).join('\n'); 14 | } 15 | return ''' 16 | WidgetbookWidget( 17 | name: '$name', 18 | ${useCasesGen.isNotEmpty ? 'useCases: [\n$useCasesGen\n],\n' : ''} 19 | ) 20 | '''; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /lib/generation/flutter_project_builder/post_gen_tasks/comp_isolation/widgetbook/widgetbook_generator.dart: -------------------------------------------------------------------------------- 1 | import 'package:parabeac_core/controllers/main_info.dart'; 2 | import 'package:parabeac_core/generation/flutter_project_builder/import_helper.dart'; 3 | import 'package:parabeac_core/generation/flutter_project_builder/post_gen_tasks/comp_isolation/component_isolation_generator.dart'; 4 | import 'package:parabeac_core/generation/generators/import_generator.dart'; 5 | import 'package:parabeac_core/generation/generators/util/pb_generation_project_data.dart'; 6 | import 'package:parabeac_core/interpret_and_optimize/services/component_isolation/widgetbook_service.dart'; 7 | 8 | class WidgetbookGenerator implements ComponentIsolationGenerator { 9 | @override 10 | String fileName = 'main_widgetbook.dart'; 11 | 12 | WidgetbookGenerator(this.projectData) { 13 | projectData.addDependencies('widgetbook', '2.0.5-beta'); 14 | } 15 | 16 | @override 17 | PBGenerationProjectData projectData; 18 | 19 | @override 20 | String generateCode(ImportHelper helper) { 21 | var category = WidgetBookService.category; 22 | var treeIds = WidgetBookService.treeIds; 23 | var generatedCode = category.generate(); 24 | 25 | var imports = treeIds 26 | .map( 27 | (id) => helper 28 | .getFormattedImports( 29 | id, 30 | importMapper: (import) => FlutterImport( 31 | import, 32 | MainInfo().projectName, 33 | ), 34 | ) 35 | .join('\n'), 36 | ) 37 | .join(''); 38 | return ''' 39 | import 'package:widgetbook/widgetbook.dart'; 40 | import 'package:flutter/material.dart'; 41 | $imports 42 | 43 | void main() { 44 | runApp(const MyApp()); 45 | } 46 | 47 | class MyApp extends StatelessWidget { 48 | const MyApp({Key? key}) : super(key: key); 49 | 50 | @override 51 | Widget build(BuildContext context){ 52 | return Widgetbook( 53 | themes: [ 54 | WidgetbookTheme(name: 'Light', data: ThemeData.light()), 55 | ], 56 | devices: const [ 57 | Apple.iPhone11ProMax, 58 | Samsung.s10, 59 | ], 60 | categories: [ 61 | $generatedCode, 62 | ], 63 | appInfo: AppInfo(name: 'MyApp'), 64 | ); 65 | } 66 | } 67 | '''; 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /lib/generation/flutter_project_builder/post_gen_tasks/global_styling/colors_post_gen_task.dart: -------------------------------------------------------------------------------- 1 | import 'package:get_it/get_it.dart'; 2 | import 'package:parabeac_core/analytics/amplitude_analytics_service.dart'; 3 | import 'package:parabeac_core/controllers/main_info.dart'; 4 | import 'package:parabeac_core/generation/flutter_project_builder/post_gen_tasks/post_gen_task.dart'; 5 | import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/commands/add_constant_command.dart'; 6 | import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/file_ownership_policy.dart'; 7 | import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/path_services/path_service.dart'; 8 | import 'package:parabeac_core/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart'; 9 | import 'package:pbdl/pbdl.dart'; 10 | import 'package:recase/recase.dart'; 11 | import 'package:uuid/uuid.dart'; 12 | 13 | class ColorsPostGenTask extends PostGenTask { 14 | GenerationConfiguration generationConfiguration; 15 | 16 | List colors; 17 | 18 | ColorsPostGenTask( 19 | this.generationConfiguration, 20 | this.colors, 21 | ); 22 | @override 23 | void execute() { 24 | var constColors = []; 25 | var mainInfo = MainInfo(); 26 | 27 | /// Format colors to be added to constants file 28 | colors.forEach((color) { 29 | constColors.add(ConstantHolder( 30 | 'Color', 31 | color.name.camelCase, 32 | 'Color(${color.color.toHex()})', 33 | description: color.description, 34 | )); 35 | }); 36 | 37 | /// Write colors to constants file in `colors.g.dart` 38 | generationConfiguration.fileStructureStrategy.commandCreated( 39 | WriteConstantsCommand( 40 | Uuid().v4(), 41 | constColors, 42 | filename: '${mainInfo.projectName.snakeCase}_colors', 43 | ownershipPolicy: FileOwnership.PBC, 44 | imports: 'import \'package:flutter/material.dart\';', 45 | relativePath: GetIt.I.get().themingRelativePath, 46 | ), 47 | ); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /lib/generation/flutter_project_builder/post_gen_tasks/post_gen_task.dart: -------------------------------------------------------------------------------- 1 | import 'package:parabeac_core/controllers/main_info.dart'; 2 | 3 | /// Abstract class for Tasks that will run post-generation. 4 | abstract class PostGenTask { 5 | /// Executes the [PostGenTask]. 6 | void execute(); 7 | } 8 | -------------------------------------------------------------------------------- /lib/generation/generators/attribute-helper/pb_attribute_gen_helper.dart: -------------------------------------------------------------------------------- 1 | import 'package:parabeac_core/generation/generators/pb_generator.dart'; 2 | import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; 3 | import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; 4 | 5 | ///For example, generating the size of Container or any other widget. 6 | abstract class PBAttributesHelper extends PBGenerator { 7 | PBAttributesHelper() : super(); 8 | @override 9 | String generate(PBIntermediateNode source, PBContext generatorContext); 10 | } 11 | -------------------------------------------------------------------------------- /lib/generation/generators/attribute-helper/pb_box_decoration_gen_helper.dart: -------------------------------------------------------------------------------- 1 | import 'package:parabeac_core/generation/generators/attribute-helper/pb_attribute_gen_helper.dart'; 2 | import 'package:parabeac_core/generation/generators/attribute-helper/pb_color_gen_helper.dart'; 3 | import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; 4 | import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; 5 | 6 | class PBBoxDecorationHelper extends PBAttributesHelper { 7 | PBBoxDecorationHelper() : super(); 8 | 9 | @override 10 | String generate(PBIntermediateNode source, PBContext generatorContext) { 11 | final buffer = StringBuffer(); 12 | 13 | buffer.write('decoration: BoxDecoration('); 14 | var borderInfo = source.auxiliaryData.borderInfo; 15 | var effectsInfo = source.auxiliaryData.effects; 16 | var colors = source.auxiliaryData.colors; 17 | if (colors != null && colors.isNotEmpty) { 18 | buffer.write(PBColorGenHelper().generate(source, generatorContext)); 19 | } 20 | if (borderInfo != null) { 21 | if (borderInfo.borderRadius != null) { 22 | // Write border radius if it exists 23 | buffer.write( 24 | 'borderRadius: BorderRadius.all(Radius.circular(${borderInfo.borderRadius})),'); 25 | } else if (borderInfo.type == 'circle') { 26 | buffer.write('shape: BoxShape.circle,'); 27 | } 28 | 29 | // Write border outline properties if applicable 30 | if (borderInfo.thickness > 0 && borderInfo.visible) { 31 | buffer.write('border: Border.all('); 32 | if (borderInfo.color != null) { 33 | buffer.write('color: Color(${borderInfo.color.toString()}),'); 34 | } 35 | buffer.write('width: ${borderInfo.thickness},'); 36 | buffer.write('),'); // end of Border.all( 37 | } 38 | } 39 | final shadows = effectsInfo 40 | ?.where((element) => element.type.toLowerCase().contains('shadow')) 41 | ?.toList() ?? 42 | []; 43 | 44 | if (shadows.isNotEmpty) { 45 | buffer.write('boxShadow: ['); 46 | 47 | for (final shadow in shadows) { 48 | buffer.write(''' 49 | BoxShadow( 50 | ${PBColorGenHelper().getHexColor(shadow.color)} 51 | spreadRadius: ${shadow.radius}, 52 | blurRadius: ${shadow.radius}, 53 | offset: Offset(${shadow.offset['x']}, ${shadow.offset['y']}), 54 | ), 55 | '''); 56 | } 57 | 58 | buffer.write('],'); 59 | } 60 | 61 | buffer.write('),'); 62 | 63 | return buffer.toString(); 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /lib/generation/generators/helpers/pb_gen_helper.dart: -------------------------------------------------------------------------------- 1 | import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; 2 | import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; 3 | 4 | abstract class PBGenHelper { 5 | String generate(PBIntermediateNode source, PBContext context); 6 | bool containsIntermediateNode(PBIntermediateNode node); 7 | void registerIntemediateNode(PBIntermediateNode generator); 8 | } 9 | -------------------------------------------------------------------------------- /lib/generation/generators/helpers/pb_layout_helper.dart: -------------------------------------------------------------------------------- 1 | import 'package:parabeac_core/generation/generators/helpers/pb_gen_helper.dart'; 2 | import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; 3 | import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_layout_intermediate_node.dart'; 4 | import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; 5 | 6 | class PBLayoutManager implements PBGenHelper { 7 | final List _registeredGenLayouts = []; 8 | 9 | @override 10 | String generate(PBIntermediateNode source, PBContext generatorContext) { 11 | if (source == null) { 12 | throw NullThrownError(); 13 | } 14 | if (source is PBLayoutIntermediateNode) { 15 | var buffer = StringBuffer(); 16 | var body = _registeredGenLayouts 17 | .firstWhere((layout) => layout.runtimeType == source.runtimeType) 18 | .generator 19 | .generate(source, generatorContext); 20 | buffer.write(body); 21 | 22 | return buffer.toString(); 23 | } 24 | return ''; 25 | } 26 | 27 | @override 28 | bool containsIntermediateNode(PBIntermediateNode node) => 29 | _registeredGenLayouts 30 | .any((layout) => layout.runtimeType == node.runtimeType); 31 | 32 | @override 33 | void registerIntemediateNode(PBIntermediateNode generator) { 34 | if (generator == null) { 35 | throw NullThrownError(); 36 | } 37 | if (!containsIntermediateNode(generator)) { 38 | _registeredGenLayouts.add(generator); 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /lib/generation/generators/layouts/pb_column_gen.dart: -------------------------------------------------------------------------------- 1 | import 'package:parabeac_core/generation/generators/layouts/pb_layout_gen.dart'; 2 | import 'package:parabeac_core/interpret_and_optimize/entities/layouts/column.dart'; 3 | import 'package:parabeac_core/interpret_and_optimize/entities/layouts/layout_properties.dart'; 4 | import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; 5 | import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; 6 | 7 | class PBColumnGenerator extends PBLayoutGenerator { 8 | PBColumnGenerator() : super(); 9 | 10 | @override 11 | String generate(PBIntermediateNode source, PBContext context) { 12 | if (source is PBIntermediateColumnLayout) { 13 | // Generate layout with the template 14 | return layoutTemplate(source, 'Column', context); 15 | } 16 | return ''; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /lib/generation/generators/layouts/pb_material_gen.dart: -------------------------------------------------------------------------------- 1 | import 'package:parabeac_core/generation/generators/attribute-helper/pb_color_gen_helper.dart'; 2 | import 'package:parabeac_core/generation/generators/pb_generator.dart'; 3 | import 'package:parabeac_core/generation/generators/value_objects/template_strategy/stateful_template_strategy.dart'; 4 | import 'package:parabeac_core/interpret_and_optimize/entities/inherited_material.dart'; 5 | import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; 6 | import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; 7 | 8 | class PBMaterialGenerator extends PBGenerator { 9 | PBMaterialGenerator() : super(strategy: StatefulTemplateStrategy()); 10 | 11 | @override 12 | String generate(PBIntermediateNode source, PBContext context) { 13 | context.sizingContext = context.configuration.scaling 14 | ? SizingValueContext.ScaleValue 15 | : SizingValueContext.PointValue; 16 | var tree = context.tree; 17 | var body = source.getAttributeNamed(tree, 'child'); 18 | if (source is InheritedMaterial) { 19 | var buffer = StringBuffer(); 20 | buffer.write('Material(\n'); 21 | 22 | if (source.auxiliaryData.color != null) { 23 | var str = PBColorGenHelper().generate(source, context); 24 | buffer.write(str); 25 | } 26 | if (body != null) { 27 | context.sizingContext = context.configuration.scaling 28 | ? SizingValueContext.ScaleValue 29 | : SizingValueContext.PointValue; 30 | 31 | buffer.write('child: '); 32 | 33 | var bodyStr = body.generator.generate(body, context); 34 | buffer.write('$bodyStr, \n'); 35 | } 36 | buffer.write(')'); 37 | return buffer.toString(); 38 | } else { 39 | return ''; 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /lib/generation/generators/layouts/pb_row_gen.dart: -------------------------------------------------------------------------------- 1 | import 'package:parabeac_core/generation/generators/layouts/pb_layout_gen.dart'; 2 | import 'package:parabeac_core/interpret_and_optimize/entities/layouts/row.dart'; 3 | import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; 4 | import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; 5 | 6 | class PBRowGenerator extends PBLayoutGenerator { 7 | PBRowGenerator() : super(); 8 | 9 | @override 10 | String generate(PBIntermediateNode source, PBContext context) { 11 | if (source is PBIntermediateRowLayout) { 12 | // Generate layout with the template 13 | return layoutTemplate(source, 'Row', context); 14 | } 15 | return ''; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /lib/generation/generators/layouts/pb_scaffold_gen.dart: -------------------------------------------------------------------------------- 1 | import 'package:parabeac_core/generation/generators/attribute-helper/pb_color_gen_helper.dart'; 2 | import 'package:parabeac_core/generation/generators/pb_generator.dart'; 3 | import 'package:parabeac_core/generation/generators/value_objects/template_strategy/stateful_template_strategy.dart'; 4 | import 'package:parabeac_core/interpret_and_optimize/entities/inherited_scaffold.dart'; 5 | import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; 6 | import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; 7 | 8 | class PBScaffoldGenerator extends PBGenerator { 9 | PBScaffoldGenerator() : super(strategy: StatefulTemplateStrategy()); 10 | 11 | @override 12 | String generate(PBIntermediateNode source, PBContext context) { 13 | context.sizingContext = context.configuration.scaling 14 | ? SizingValueContext.ScaleValue 15 | : SizingValueContext.PointValue; 16 | var tree = context.tree; 17 | var appBar = source.getAttributeNamed(tree, 'appBar'); 18 | var body = source.getAttributeNamed(tree, 'body'); 19 | var bottomNavBar = source.getAttributeNamed(tree, 'bottomNavigationBar'); 20 | if (source is InheritedScaffold) { 21 | var buffer = StringBuffer(); 22 | buffer.write('Scaffold(\n'); 23 | 24 | if (source.auxiliaryData.color != null) { 25 | var str = PBColorGenHelper().generate(source, context); 26 | buffer.write(str); 27 | } 28 | if (appBar != null) { 29 | buffer.write('appBar: '); 30 | // generatorContext.sizingContext = SizingValueContext.PointValue; 31 | var appbarStr = appBar.generator.generate(appBar, context); 32 | 33 | buffer.write('$appbarStr,\n'); 34 | } 35 | if (bottomNavBar != null) { 36 | buffer.write('bottomNavigationBar: '); 37 | var navigationBar = 38 | bottomNavBar.generator.generate(bottomNavBar, context); 39 | buffer.write('$navigationBar, \n'); 40 | } 41 | 42 | if (body != null) { 43 | context.sizingContext = context.configuration.scaling 44 | ? SizingValueContext.ScaleValue 45 | : SizingValueContext.PointValue; 46 | 47 | // hack to pass screen width and height to the child 48 | buffer.write('body: '); 49 | // generatorContext.sizingContext = SizingValueContext.ScaleValue; 50 | var bodyStr = body.generator.generate(body, context); 51 | buffer.write('$bodyStr, \n'); 52 | } 53 | buffer.write(')'); 54 | return buffer.toString(); 55 | } else { 56 | return ''; 57 | } 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /lib/generation/generators/layouts/pb_stack_gen.dart: -------------------------------------------------------------------------------- 1 | import 'package:get_it/get_it.dart'; 2 | import 'package:parabeac_core/analytics/amplitude_analytics_service.dart'; 3 | import 'package:parabeac_core/generation/generators/pb_generator.dart'; 4 | import 'package:parabeac_core/interpret_and_optimize/entities/layouts/stack.dart'; 5 | import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; 6 | import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; 7 | import 'package:parabeac_core/tags/injected_app_bar.dart'; 8 | 9 | class PBStackGenerator extends PBGenerator { 10 | PBStackGenerator() : super(); 11 | 12 | @override 13 | String generate(PBIntermediateNode source, PBContext context) { 14 | if (source is PBIntermediateStackLayout) { 15 | var children = context.tree.childrenOf(source); 16 | var buffer = StringBuffer(); 17 | 18 | buffer.write('Stack('); 19 | if (children.isNotEmpty) { 20 | buffer.write('\nchildren: ['); 21 | for (var index = 0; index < children.length; index++) { 22 | var element = 23 | children[index].generator.generate(children[index], context); 24 | buffer.write(element); 25 | var endingChar = element != null && element.isEmpty ? '' : ','; 26 | buffer.write(endingChar); 27 | } 28 | buffer.write(']'); 29 | buffer.write(')'); 30 | } 31 | if (source.parent is InjectedAppbar) { 32 | return containerWrapper(buffer.toString(), source, context); 33 | } 34 | return buffer.toString(); 35 | } 36 | return ''; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /lib/generation/generators/middleware/middleware.dart: -------------------------------------------------------------------------------- 1 | import 'package:parabeac_core/generation/flutter_project_builder/import_helper.dart'; 2 | import 'package:parabeac_core/generation/generators/pb_generation_manager.dart'; 3 | import 'package:parabeac_core/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart'; 4 | import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; 5 | import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; 6 | import 'package:parabeac_core/interpret_and_optimize/helpers/pb_gen_cache.dart'; 7 | import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart'; 8 | import 'package:recase/recase.dart'; 9 | 10 | abstract class Middleware { 11 | static var variableNames = {}; 12 | 13 | /// Using chain of reponsibility to handle the incoming nodes in the generation phase, [nextMiddleware] 14 | /// will be responsible of handling the incoming node or passing it to the next node. 15 | Middleware nextMiddleware; 16 | 17 | PBGenerationManager generationManager; 18 | GenerationConfiguration configuration; 19 | 20 | Middleware(this.generationManager, this.configuration, {this.nextMiddleware}); 21 | 22 | String getNameOfNode(PBIntermediateNode node) => 23 | ImportHelper.getName(node.name); 24 | 25 | /// Applying the [Middleware] logic to the [node]; modifying it or even eliminating it by returning `null`. 26 | Future applyMiddleware( 27 | PBIntermediateTree tree, PBContext context) => 28 | handleTree(tree, context); 29 | 30 | Future handleTree( 31 | PBIntermediateTree tree, PBContext context) { 32 | return nextMiddleware == null 33 | ? Future.value(tree) 34 | : nextMiddleware.applyMiddleware(tree, context); 35 | } 36 | 37 | void addImportToCache(String id, String path) { 38 | PBGenCache().setPathToCache(id, path); 39 | } 40 | 41 | String getVariableName(String name) { 42 | if (!variableNames.containsKey(name)) { 43 | variableNames[name] = 1; 44 | return name; 45 | } else { 46 | return name + '_' + (++variableNames[name]).toString(); 47 | } 48 | } 49 | } 50 | 51 | class GeneartionConfiguration {} 52 | -------------------------------------------------------------------------------- /lib/generation/generators/pb_generation_manager.dart: -------------------------------------------------------------------------------- 1 | import 'package:parabeac_core/generation/flutter_project_builder/import_helper.dart'; 2 | import 'package:parabeac_core/generation/generators/util/pb_generation_view_data.dart'; 3 | import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; 4 | import 'package:parabeac_core/interpret_and_optimize/helpers/pb_gen_cache.dart'; 5 | import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; 6 | 7 | /// Resposible for generating the code of a [PBIntermediateNode] Tree. 8 | /// 9 | /// Furthermore, it provides a set of method that allows [PBIntermediateNode]s to add 10 | /// imports, dependencies, etc. 11 | abstract class PBGenerationManager { 12 | ///* Keep track of the current page body 13 | StringBuffer body; 14 | 15 | Type rootType; 16 | 17 | /// In charge of processing all the imports of the files that are being written in the file sytem 18 | ImportHelper importProcessor; 19 | 20 | PBGenerationViewData _data; 21 | PBGenerationViewData get data => _data; 22 | set data(PBGenerationViewData data) => _data = data; 23 | 24 | PBGenerationManager(this.importProcessor, {data}) { 25 | _data = data; 26 | } 27 | 28 | String generate(PBIntermediateNode rootNode, PBContext context); 29 | 30 | Set getPaths(String uuid) => PBGenCache().getPaths(uuid); 31 | 32 | String generateImports(); 33 | 34 | String generateGlobalVariables(); 35 | 36 | String generateConstructor(String name); 37 | 38 | String generateDispose(); 39 | } 40 | -------------------------------------------------------------------------------- /lib/generation/generators/pb_generator.dart: -------------------------------------------------------------------------------- 1 | import 'package:parabeac_core/controllers/main_info.dart'; 2 | import 'package:parabeac_core/generation/generators/value_objects/template_strategy/inline_template_strategy.dart'; 3 | import 'package:parabeac_core/generation/generators/value_objects/template_strategy/pb_template_strategy.dart'; 4 | import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; 5 | import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; 6 | import 'package:quick_log/quick_log.dart'; 7 | 8 | import 'attribute-helper/pb_box_decoration_gen_helper.dart'; 9 | 10 | abstract class PBGenerator { 11 | final String OBJECTID = 'UUID'; 12 | static String MEDIAQUERY_HORIZONTAL_BOILERPLATE = 13 | 'MediaQuery.of(context).size.width'; 14 | static String MEDIAQUERY_VERTICAL_BOILERPLATE = 15 | 'MediaQuery.of(context).size.height'; 16 | 17 | Logger logger; 18 | 19 | /// Chain of responsability restructure 20 | 21 | PBGenerator next; 22 | 23 | ///The [TemplateStrategy] that is going to be used to generate the boilerplate code around the node. 24 | /// 25 | ///The `default` [TemplateStrategy] is going to be [InlineTemplateStrategy] 26 | TemplateStrategy templateStrategy; 27 | 28 | PBGenerator({TemplateStrategy strategy, this.next}) { 29 | templateStrategy = strategy; 30 | templateStrategy ??= InlineTemplateStrategy(); 31 | logger = Logger(runtimeType.toString()); 32 | } 33 | 34 | String generate(PBIntermediateNode source, PBContext context); 35 | 36 | /// Method that wraps `this` with a `Container`. 37 | /// 38 | /// The container will also contain the [source]'s `styling` properties if applicable. 39 | /// The container will contain [source]'s `width` and `height` properties if [includeSize] is `true`. 40 | String containerWrapper( 41 | String body, 42 | PBIntermediateNode source, 43 | PBContext context, { 44 | bool includeSize = true, 45 | }) { 46 | var decoration = PBBoxDecorationHelper().generate(source, context); 47 | return ''' 48 | Container( 49 | ${includeSize ? 'width: ${source.frame.width}, height: ${source.frame.height},' : ''} 50 | ${decoration.isEmpty || decoration.contains('BoxDecoration()') ? '' : '$decoration'} 51 | child: $body, 52 | ) 53 | '''; 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /lib/generation/generators/pb_variable.dart: -------------------------------------------------------------------------------- 1 | class PBVariable { 2 | ///Name of the variable 3 | String variableName; 4 | 5 | ///static type of the variable. 6 | String type; 7 | bool isRequired; 8 | String defaultValue; 9 | 10 | PBVariable( 11 | this.variableName, 12 | this.type, 13 | this.isRequired, 14 | this.defaultValue, 15 | ); 16 | 17 | @override 18 | bool operator ==(Object other) => 19 | (other as PBVariable).variableName == variableName && 20 | (other as PBVariable).type == type; 21 | } 22 | -------------------------------------------------------------------------------- /lib/generation/generators/screen_builder.dart: -------------------------------------------------------------------------------- 1 | import 'package:build/build.dart'; 2 | import 'package:parabeac_core/generation/generators/pb_flutter_generator.dart'; 3 | 4 | Builder simpleBuilder(BuilderOptions options) => SimpleBuilder(); 5 | 6 | class SimpleBuilder extends Builder { 7 | final String GLOBAL_SYMBOL_KEY = 'globalSymbols'; 8 | 9 | @override 10 | Map> get buildExtensions => const >{ 11 | '.json': ['.dart'] 12 | }; 13 | 14 | @override 15 | Future build(BuildStep buildStep) async { 16 | print('GENERATING CODE'); 17 | Map source; 18 | final outputId = buildStep.inputId.changeExtension('.dart'); 19 | 20 | if (source.containsKey(GLOBAL_SYMBOL_KEY)) { 21 | _generateArray(source[GLOBAL_SYMBOL_KEY], outputId, buildStep); 22 | } 23 | } 24 | 25 | void _generateArray(List data, var output_id, var build_step) { 26 | data ??= []; 27 | var buffer = StringBuffer(); 28 | buffer.write("import \'package:flutter/material.dart\';\n"); 29 | _generateCode(output_id, buffer.toString(), build_step); 30 | } 31 | 32 | ///Generating the code 33 | ///`buildMethod`: is the string that represents the code 34 | ///`outputID`: is the output general info 35 | void _generateCode(var output_id, var build_method, var build_step) => 36 | build_step.writeAsString(output_id, build_method); 37 | } 38 | -------------------------------------------------------------------------------- /lib/generation/generators/symbols/layout_builder_gen.dart: -------------------------------------------------------------------------------- 1 | import 'package:parabeac_core/generation/generators/pb_generator.dart'; 2 | import 'package:parabeac_core/generation/generators/value_objects/template_strategy/stateful_template_strategy.dart'; 3 | import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; 4 | import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; 5 | import 'package:quick_log/quick_log.dart'; 6 | 7 | class LayoutBuilderGenerator extends PBGenerator { 8 | LayoutBuilderGenerator(PBGenerator next) 9 | : super(strategy: StatefulTemplateStrategy(), next: next); 10 | 11 | var log = Logger('Layout Builder Generator'); 12 | @override 13 | String generate(PBIntermediateNode source, PBContext context) { 14 | var buffer = StringBuffer(); 15 | buffer.write('LayoutBuilder( \n'); 16 | buffer.write(' builder: (context, constraints) {\n'); 17 | buffer.write(' return '); 18 | 19 | buffer.write(next.generate(source, context)); 20 | 21 | buffer.write(';\n'); 22 | buffer.write('}\n'); 23 | buffer.write(')'); 24 | 25 | return buffer.toString(); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /lib/generation/generators/symbols/pb_mastersym_gen.dart: -------------------------------------------------------------------------------- 1 | import 'package:parabeac_core/generation/generators/attribute-helper/pb_box_decoration_gen_helper.dart'; 2 | import 'package:parabeac_core/generation/generators/pb_generator.dart'; 3 | import 'package:parabeac_core/generation/generators/value_objects/template_strategy/stateful_template_strategy.dart'; 4 | import 'package:parabeac_core/interpret_and_optimize/entities/pb_shared_master_node.dart'; 5 | import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; 6 | import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; 7 | import 'package:quick_log/quick_log.dart'; 8 | 9 | class PBMasterSymbolGenerator extends PBGenerator { 10 | PBMasterSymbolGenerator() : super(strategy: StatefulTemplateStrategy()); 11 | 12 | var log = Logger('Symbol Master Generator'); 13 | @override 14 | String generate(PBIntermediateNode source, PBContext context) { 15 | context.sizingContext = SizingValueContext.LayoutBuilderStatefulValue; 16 | var children = context.tree.childrenOf(source); 17 | var sourceChild = children.isNotEmpty ? children.first : null; 18 | var buffer = StringBuffer(); 19 | if (source is PBSharedMasterNode) { 20 | if (sourceChild == null) { 21 | return ''; 22 | } 23 | // override styles if need be. 24 | context.masterNode = source; 25 | 26 | // see if widget itself is overridden, need to pass 27 | var generatedWidget = 28 | sourceChild.generator.generate(sourceChild, context); 29 | 30 | context.masterNode = null; 31 | if (generatedWidget == null || generatedWidget.isEmpty) { 32 | return ''; 33 | } 34 | var decoration = PBBoxDecorationHelper().generate(source, context); 35 | buffer.write('Container($decoration child:'); 36 | buffer.write(generatedWidget); 37 | buffer.write(')'); 38 | return buffer.toString(); 39 | } else { 40 | return ''; 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /lib/generation/generators/symbols/pb_sym_mas_param_gen.dart: -------------------------------------------------------------------------------- 1 | import 'package:parabeac_core/generation/generators/pb_generator.dart'; 2 | import 'package:parabeac_core/generation/generators/pb_variable.dart'; 3 | import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; 4 | import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; 5 | 6 | class PBSymbolMasterParamGen extends PBGenerator { 7 | PBSymbolMasterParamGen() : super(); 8 | 9 | @override 10 | String generate(PBIntermediateNode source, PBContext generatorContext) { 11 | //TODO: is PBParam correct here? 12 | var name = (source as PBVariable).variableName; 13 | 14 | if (name == null) { 15 | return ''; 16 | } 17 | return name; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /lib/generation/generators/symbols/pb_symbol_model.dart: -------------------------------------------------------------------------------- 1 | 2 | class PBSymbolModel { 3 | static final PBSymbolModel _model = PBSymbolModel._internal(); 4 | final Map _symbols = {}; 5 | 6 | factory PBSymbolModel() => _model; 7 | PBSymbolModel._internal(); 8 | 9 | String getSymbol(String id) => _symbols[id]; 10 | void setSymbol(String id, String value) { 11 | if(_symbols.containsKey(id)){ 12 | return; 13 | } 14 | _symbols[id] = value; 15 | } 16 | 17 | } 18 | -------------------------------------------------------------------------------- /lib/generation/generators/util/pb_generation_project_data.dart: -------------------------------------------------------------------------------- 1 | import 'dart:collection'; 2 | 3 | import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/commands/file_structure_command.dart'; 4 | import 'package:parabeac_core/generation/generators/writers/pb_flutter_writer.dart'; 5 | 6 | class PBGenerationProjectData { 7 | Map dependencies = {}; 8 | void addDependencies(String packageName, String version) => dependencies[packageName] = version; 9 | } 10 | -------------------------------------------------------------------------------- /lib/generation/generators/util/pb_input_formatter.dart: -------------------------------------------------------------------------------- 1 | import 'package:recase/recase.dart'; 2 | 3 | class PBInputFormatter { 4 | ///Formats input to destroy spaces and other intrusive characters. 5 | /// 6 | ///Returns an upper-camelcase string if `isTitle` is true, 7 | ///or a lowercase string otherwise. 8 | static String formatLabel(String input, 9 | {bool isTitle = false, 10 | bool spaceToUnderscore = true, 11 | bool destroyDigits = false, 12 | bool destroySpecialSym = false}) { 13 | assert(input != null); 14 | var result = _formatStr(input, 15 | spaceToUnderscore: spaceToUnderscore, destroyDigits: destroyDigits); 16 | 17 | (isTitle) ? result = result.pascalCase : result = result.toLowerCase(); 18 | return result; 19 | } 20 | 21 | /// Removes all non alphabet characters at the beggining of the string, and remove spaces 22 | static String formatPageName(String input) { 23 | return input.replaceAll(RegExp(r'^[^a-zA-Z]*'), '').replaceAll(' ', ''); 24 | } 25 | 26 | ///Formats `input` to destroy spaces and other intrusive characters. 27 | /// 28 | ///Returns a camelCase string. 29 | static String formatVariable(String input) => _formatStr(input).camelCase; 30 | 31 | static String _formatStr( 32 | String input, { 33 | bool spaceToUnderscore = true, 34 | bool destroyDigits = false, 35 | }) { 36 | var result = input; 37 | // TODO: set a temporal name 38 | result = (result.isEmpty) ? 'tempName' : result; 39 | 40 | result = result.trim(); 41 | var spaceChar = (spaceToUnderscore) ? '_' : ''; 42 | result = result.replaceAll(r'[\s\./_+?]+', spaceChar); 43 | result = result.replaceAll(RegExp(r'\s+'), spaceChar); 44 | result = result.replaceAll(' ', '').replaceAll(RegExp(r'[^\s\w]'), ''); 45 | result = removeFirstDigits(result); 46 | result = (destroyDigits) ? result.replaceAll(RegExp(r'\d+'), '') : result; 47 | return result; 48 | } 49 | 50 | static String removeFirstDigits(String str) => 51 | str.startsWith(RegExp(r'^[\d]+')) 52 | ? str.replaceFirstMapped(RegExp(r'^[\d]+'), (e) => '') 53 | : str; 54 | 55 | /// Method that splits `target` according to `delimeter` 56 | /// and returns the last entry in the list. 57 | static String findLastOf(String target, String delimeter) { 58 | if (target == null || delimeter == null) { 59 | return ''; 60 | } 61 | return target.split(delimeter).last; 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /lib/generation/generators/value_objects/file_resource.dart: -------------------------------------------------------------------------------- 1 | import 'dart:io'; 2 | import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/pb_file_structure_strategy.dart'; 3 | import 'package:path/path.dart' as p; 4 | import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/file_ownership_policy.dart'; 5 | 6 | /// Represents a wrapper to a [File] that is going to be written in the File System 7 | class FileResource { 8 | /// Unique Identifier to the [FileResource] 9 | String UUID; 10 | 11 | /// The parent directory that the [file] is located at. 12 | String dirName; 13 | 14 | /// The basename of the [file] 15 | String fileName; 16 | 17 | /// The file extension for [file] 18 | String fileExtension; 19 | 20 | /// The path for the [file] 21 | String path; 22 | 23 | FileOwnership ownership; 24 | 25 | FileStructureStrategy fileSystem; 26 | 27 | File get file => _file; 28 | File _file; 29 | 30 | FileResource( 31 | {this.UUID, 32 | this.dirName, 33 | this.fileName, 34 | this.path, 35 | this.fileExtension = '.dart', 36 | this.fileSystem, 37 | File file}) { 38 | assert( 39 | (dirName == null && fileName == null) && path == null || file == null, 40 | 'Either the [dirName] & [fileName] or [path] should be specified and not null'); 41 | if (path != null) { 42 | dirName = p.dirname(path); 43 | fileName = p.basename(path); 44 | 45 | var extInPath = p.extension(path); 46 | if (extInPath != null || extInPath.isNotEmpty) { 47 | fileExtension = extInPath; 48 | } 49 | } else if (file != null) { 50 | fileName = p.basename(file.path); 51 | dirName = p.dirname(file.path); 52 | fileExtension = p.extension(file.path); 53 | } else { 54 | path = p.join(dirName, fileName, fileExtension); 55 | } 56 | } 57 | 58 | void _constructFile() {} 59 | 60 | void resolveFileExtension({FileOwnershipPolicy policy}) { 61 | assert(policy != null && fileSystem != null, 62 | 'No way of resolving the file extension with null $policy and $FileStructureStrategy'); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /lib/generation/generators/value_objects/file_structure_strategy/bloc_file_structure_strategy.dart: -------------------------------------------------------------------------------- 1 | import 'package:parabeac_core/generation/flutter_project_builder/file_system_analyzer.dart'; 2 | import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/pb_file_structure_strategy.dart'; 3 | import 'package:parabeac_core/generation/generators/writers/pb_page_writer.dart'; 4 | import 'package:parabeac_core/interpret_and_optimize/helpers/pb_project.dart'; 5 | 6 | class BLoCFileStructureStrategy extends FileStructureStrategy { 7 | final RELATIVE_BLOC_PATH = 'lib/blocs'; 8 | 9 | BLoCFileStructureStrategy( 10 | String genProjectPath, PBPageWriter pageWriter, PBProject pbProject, FileSystemAnalyzer fileSystemAnalyzer) 11 | : super(genProjectPath, pageWriter, pbProject, fileSystemAnalyzer); 12 | } 13 | -------------------------------------------------------------------------------- /lib/generation/generators/value_objects/file_structure_strategy/command_invoker.dart: -------------------------------------------------------------------------------- 1 | import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/commands/file_structure_command.dart'; 2 | 3 | abstract class CommandInvoker { 4 | void commandCreated(FileStructureCommand command); 5 | } 6 | -------------------------------------------------------------------------------- /lib/generation/generators/value_objects/file_structure_strategy/commands/add_dependency_command.dart: -------------------------------------------------------------------------------- 1 | import 'package:parabeac_core/controllers/main_info.dart'; 2 | import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/commands/file_structure_command.dart'; 3 | import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/pb_file_structure_strategy.dart'; 4 | 5 | /// Command used to add a dependency to `pubspec.yaml` 6 | class AddDependencyCommand extends FileStructureCommand { 7 | final _PUBSPEC_YAML_NAME = 'pubspec.yaml'; 8 | 9 | ///assets yaml decleration 10 | final String _ASSET_DECLERATION = 11 | '\t\t- packages/${MainInfo().projectName}/assets/images/'; 12 | 13 | /// Name of the [package] 14 | String package; 15 | 16 | /// The version of [package] 17 | String version; 18 | 19 | AddDependencyCommand(String UUID, this.package, this.version) : super(UUID); 20 | 21 | /// Appends `package` and `version` to `pubspec.yaml` dependencies. 22 | @override 23 | Future write(FileStructureStrategy strategy) async { 24 | strategy.appendDataToFile( 25 | _addPackage, 26 | strategy.GENERATED_PROJECT_PATH, 27 | _PUBSPEC_YAML_NAME, 28 | createFileIfNotFound: false, 29 | ); 30 | } 31 | 32 | List _addPackage(List lines) { 33 | ///Appending the [package] in the [PUBSPEC_YAML_NAME] file. 34 | var depIndex = lines.indexOf('dependencies:') + 1; 35 | if (depIndex >= 0) { 36 | lines.insert(depIndex, '$package: $version'); 37 | } 38 | 39 | ///Appending the images path into the [PUBSPEC_YAML_NAME] file. 40 | // TODO: we may want to move this to a separate Command to ensure it only gets called once. 41 | var assetIndex = lines.indexOf(' assets:') + 1; 42 | if (!lines.contains(_ASSET_DECLERATION) && assetIndex >= 0) { 43 | if (assetIndex == lines.length) { 44 | lines.add(_ASSET_DECLERATION); 45 | } else { 46 | lines.insert(assetIndex, _ASSET_DECLERATION); 47 | } 48 | } 49 | return lines; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /lib/generation/generators/value_objects/file_structure_strategy/commands/export_platform_command.dart: -------------------------------------------------------------------------------- 1 | import 'package:get_it/get_it.dart'; 2 | import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/file_ownership_policy.dart'; 3 | import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/path_services/path_service.dart'; 4 | import 'package:path/path.dart' as p; 5 | import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/commands/node_file_structure_command.dart'; 6 | import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/pb_file_structure_strategy.dart'; 7 | import 'package:parabeac_core/interpret_and_optimize/services/pb_platform_orientation_linker_service.dart'; 8 | 9 | /// Command to export `code` under a specific `platform` 10 | class ExportPlatformCommand extends NodeFileStructureCommand { 11 | PLATFORM platform; 12 | String fileName; 13 | String folderName; 14 | static final String WIDGET_PATH = 15 | GetIt.I.get().viewsRelativePath; 16 | 17 | ExportPlatformCommand( 18 | String UUID, this.platform, this.folderName, this.fileName, String code, 19 | {FileOwnership ownership = FileOwnership.PBC}) 20 | : super(UUID, code, ownership); 21 | 22 | @override 23 | Future write(FileStructureStrategy strategy) async { 24 | var path = p.join( 25 | strategy.GENERATED_PROJECT_PATH, 26 | WIDGET_PATH, 27 | folderName, 28 | platform.toString().toLowerCase().replaceAll('platform.', ''), 29 | ); 30 | strategy.writeDataToFile(code, path, fileName, 31 | UUID: UUID, ownership: ownership); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /lib/generation/generators/value_objects/file_structure_strategy/commands/file_structure_command.dart: -------------------------------------------------------------------------------- 1 | import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/pb_file_structure_strategy.dart'; 2 | import 'package:path/path.dart' as p; 3 | /// [FileStructureCommand] uses the command pattern to create units of works that create/modify the 4 | /// FileSystem. 5 | /// 6 | /// The [FileStructureCommand]s are send to the [FileStructureCommand] that is responsible for 7 | /// executing the command and actually writing them into the file system. 8 | abstract class FileStructureCommand { 9 | final String UUID; 10 | 11 | FileStructureCommand(this.UUID); 12 | 13 | /// Method that executes the [FileStructureCommand]'s action. 14 | Future write(FileStructureStrategy strategy); 15 | } 16 | -------------------------------------------------------------------------------- /lib/generation/generators/value_objects/file_structure_strategy/commands/node_file_structure_command.dart: -------------------------------------------------------------------------------- 1 | import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/commands/file_structure_command.dart'; 2 | import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/file_ownership_policy.dart'; 3 | import 'package:path/path.dart'; 4 | 5 | /// Class that relies on `code` to implement its `write` method. 6 | abstract class NodeFileStructureCommand extends FileStructureCommand { 7 | String code; 8 | 9 | /// Depicts the [FileOwnership] of the files that is going to be created 10 | /// through [write] 11 | FileOwnership ownership; 12 | 13 | NodeFileStructureCommand(String UUID, this.code, this.ownership) 14 | : super(UUID); 15 | } 16 | -------------------------------------------------------------------------------- /lib/generation/generators/value_objects/file_structure_strategy/commands/orientation_builder_command.dart: -------------------------------------------------------------------------------- 1 | import 'package:get_it/get_it.dart'; 2 | import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/path_services/path_service.dart'; 3 | import 'package:path/path.dart' as p; 4 | import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/commands/file_structure_command.dart'; 5 | import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/pb_file_structure_strategy.dart'; 6 | 7 | import '../file_ownership_policy.dart'; 8 | 9 | class OrientationBuilderCommand extends FileStructureCommand { 10 | static final DIR_TO_ORIENTATION_BUILDER = 11 | GetIt.I.get().widgetsRelativePath; 12 | static final NAME_TO_ORIENTAION_BUILDER = 13 | 'responsive_orientation_builder.dart'; 14 | 15 | OrientationBuilderCommand(String UUID) : super(UUID); 16 | 17 | @override 18 | Future write(FileStructureStrategy strategy) { 19 | var template = ''' 20 | import 'package:flutter/material.dart'; 21 | 22 | class ResponsiveOrientationBuilder extends StatelessWidget { 23 | final Widget? verticalPage; 24 | final Widget? horizontalPage; 25 | 26 | const ResponsiveOrientationBuilder({ 27 | this.verticalPage, 28 | this.horizontalPage, 29 | }); 30 | 31 | @override 32 | Widget build(BuildContext context) { 33 | return OrientationBuilder(builder: (context, orientation) { 34 | switch (orientation) { 35 | case Orientation.portrait: 36 | return verticalPage!; 37 | break; 38 | case Orientation.landscape: 39 | return horizontalPage!; 40 | default: 41 | return ErrorScreen(); 42 | } 43 | }); 44 | } 45 | } 46 | 47 | class ErrorScreen extends StatelessWidget { 48 | // TODO: Change this screen to match your project 49 | @override 50 | Widget build(BuildContext context) { 51 | return const Material( 52 | child: Center( 53 | child: Text('Something went wrong!'), 54 | ), 55 | ); 56 | } 57 | } 58 | 59 | '''; 60 | 61 | strategy.writeDataToFile( 62 | template, 63 | p.join(strategy.GENERATED_PROJECT_PATH, DIR_TO_ORIENTATION_BUILDER), 64 | NAME_TO_ORIENTAION_BUILDER, 65 | UUID: UUID, 66 | ownership: FileOwnership.DEV, 67 | ); 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /lib/generation/generators/value_objects/file_structure_strategy/commands/write_screen_command.dart: -------------------------------------------------------------------------------- 1 | import 'package:get_it/get_it.dart'; 2 | import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/file_ownership_policy.dart'; 3 | import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/path_services/path_service.dart'; 4 | import 'package:path/path.dart' as p; 5 | import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/commands/node_file_structure_command.dart'; 6 | import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/pb_file_structure_strategy.dart'; 7 | 8 | /// Command that writes a `screen` to the project. 9 | class WriteScreenCommand extends NodeFileStructureCommand { 10 | String name; 11 | String relativePath; 12 | String fileExtension; 13 | 14 | static final SCREEN_PATH = GetIt.I.get().viewsRelativePath; 15 | 16 | WriteScreenCommand(String UUID, this.name, this.relativePath, String code, 17 | {FileOwnership ownership = FileOwnership.PBC, 18 | this.fileExtension = '.dart'}) 19 | : super(UUID, code, ownership); 20 | 21 | /// Writes a screen file containing [code] to [path] with [name] as its filename. 22 | /// 23 | /// Returns path to the file that was created. 24 | @override 25 | Future write(FileStructureStrategy strategy) { 26 | var absPath = 27 | p.join(strategy.GENERATED_PROJECT_PATH, SCREEN_PATH, relativePath); 28 | strategy.writeDataToFile(code, absPath, name, 29 | UUID: UUID, ownership: ownership, ext: fileExtension); 30 | return Future.value(p.join(absPath, name)); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /lib/generation/generators/value_objects/file_structure_strategy/commands/write_symbol_command.dart: -------------------------------------------------------------------------------- 1 | import 'package:get_it/get_it.dart'; 2 | import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/file_ownership_policy.dart'; 3 | import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/path_services/path_service.dart'; 4 | import 'package:path/path.dart' as p; 5 | import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/commands/node_file_structure_command.dart'; 6 | import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/pb_file_structure_strategy.dart'; 7 | 8 | /// Command that writes a `symbol` to the project. 9 | class WriteSymbolCommand extends NodeFileStructureCommand { 10 | static String DEFAULT_SYMBOL_PATH = 11 | GetIt.I.get().widgetsRelativePath; 12 | 13 | String symbolPath; 14 | String fileName; 15 | 16 | /// The [symbolPath] has the relative path within 17 | /// 18 | /// For example, you are looking for `lib/widgets/some_element/element.dart`, 19 | /// then the [symbolPath] would be `lib/widgets/some_element/` 20 | 21 | WriteSymbolCommand( 22 | String UUID, 23 | this.fileName, 24 | String code, { 25 | this.symbolPath = '', 26 | FileOwnership ownership = FileOwnership.PBC, 27 | }) : super(UUID, code, ownership); 28 | 29 | /// Writes a symbol file containing [generationViewData] with [fileName] as its filename. 30 | /// 31 | /// Returns path to the file that was created. 32 | @override 33 | Future write(FileStructureStrategy strategy) { 34 | symbolPath = symbolPath.isEmpty ? DEFAULT_SYMBOL_PATH : symbolPath; 35 | var absPath = p.join(strategy.GENERATED_PROJECT_PATH, symbolPath); 36 | 37 | strategy.writeDataToFile(code, absPath, fileName, 38 | UUID: UUID, ownership: ownership); 39 | return Future.value(p.join(absPath, fileName)); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /lib/generation/generators/value_objects/file_structure_strategy/flutter_file_structure_strategy.dart: -------------------------------------------------------------------------------- 1 | import 'package:parabeac_core/generation/flutter_project_builder/file_system_analyzer.dart'; 2 | import 'package:parabeac_core/generation/generators/writers/pb_page_writer.dart'; 3 | import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/pb_file_structure_strategy.dart'; 4 | import 'package:parabeac_core/interpret_and_optimize/helpers/pb_project.dart'; 5 | 6 | class FlutterFileStructureStrategy extends FileStructureStrategy { 7 | FlutterFileStructureStrategy( 8 | String genProjectPath, PBPageWriter pageWriter, PBProject pbProject, FileSystemAnalyzer fileSystemAnalyzer) 9 | : super(genProjectPath, pageWriter, pbProject, fileSystemAnalyzer); 10 | } 11 | -------------------------------------------------------------------------------- /lib/generation/generators/value_objects/file_structure_strategy/path_services/domain_path_service.dart: -------------------------------------------------------------------------------- 1 | import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/path_services/path_service.dart'; 2 | 3 | class DomainPathService extends PathService { 4 | DomainPathService({ 5 | String viewsRelativePath = 'lib/views', 6 | String widgetsRelativePath = 'lib/widgets', 7 | String customRelativePath = 'custom', 8 | String constantsRelativePath = 'lib/constants', 9 | String themingRelativePath = 'lib/theme', 10 | }) : super( 11 | viewsRelativePath, 12 | widgetsRelativePath, 13 | customRelativePath, 14 | constantsRelativePath, 15 | themingRelativePath, 16 | ); 17 | } 18 | -------------------------------------------------------------------------------- /lib/generation/generators/value_objects/file_structure_strategy/path_services/path_service.dart: -------------------------------------------------------------------------------- 1 | import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/path_services/domain_path_service.dart'; 2 | 3 | /// PathService class helps file writers commands to determine 4 | /// the right path for their views, widgets, custom and constants 5 | /// by centralizing the path to this class 6 | /// 7 | /// The class can be extended to create different types of PathService 8 | /// by default we made [DomainPathService] 9 | abstract class PathService { 10 | final String viewsRelativePath; 11 | final String widgetsRelativePath; 12 | final String customRelativePath; 13 | final String constantsRelativePath; 14 | final String themingRelativePath; 15 | PathService( 16 | this.viewsRelativePath, 17 | this.widgetsRelativePath, 18 | this.customRelativePath, 19 | this.constantsRelativePath, 20 | this.themingRelativePath, 21 | ); 22 | 23 | factory PathService.fromConfiguration(String architecture) { 24 | // TODO: Once we add more if statements, we can declare `domain` case as the else statement 25 | if (architecture.toLowerCase() == 'domain') { 26 | return DomainPathService(); 27 | } 28 | 29 | /// If no architecture is set 30 | /// we will return DomainPathService as default 31 | return DomainPathService(); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /lib/generation/generators/value_objects/file_structure_strategy/provider_file_structure_strategy.dart: -------------------------------------------------------------------------------- 1 | import 'dart:io'; 2 | 3 | import 'package:parabeac_core/generation/flutter_project_builder/file_system_analyzer.dart'; 4 | import 'package:parabeac_core/generation/generators/writers/pb_page_writer.dart'; 5 | import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/pb_file_structure_strategy.dart'; 6 | import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; 7 | import 'package:parabeac_core/interpret_and_optimize/helpers/pb_project.dart'; 8 | import 'package:path/path.dart' as p; 9 | 10 | class ProviderFileStructureStrategy extends FileStructureStrategy { 11 | final RELATIVE_MODEL_PATH = 'lib/models/'; 12 | var _modelsPath; 13 | 14 | ProviderFileStructureStrategy( 15 | String genProjectPath, PBPageWriter pageWriter, PBProject pbProject, FileSystemAnalyzer fileSystemAnalyzer) 16 | : super(genProjectPath, pageWriter, pbProject, fileSystemAnalyzer) { 17 | _modelsPath = p.join(genProjectPath, RELATIVE_MODEL_PATH); 18 | } 19 | 20 | @override 21 | Future setUpDirectories() async { 22 | if (!isSetUp) { 23 | await Future.wait( 24 | [super.setUpDirectories(), _generateMissingDirectories()]); 25 | isSetUp = true; 26 | } 27 | } 28 | 29 | Future _generateMissingDirectories() async { 30 | Directory(_modelsPath).createSync(recursive: true); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /lib/generation/generators/value_objects/file_structure_strategy/riverpod_file_structure_strategy.dart: -------------------------------------------------------------------------------- 1 | import 'dart:io'; 2 | import 'package:parabeac_core/generation/flutter_project_builder/file_system_analyzer.dart'; 3 | import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; 4 | import 'package:path/path.dart' as p; 5 | 6 | import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/pb_file_structure_strategy.dart'; 7 | import 'package:parabeac_core/generation/generators/writers/pb_page_writer.dart'; 8 | import 'package:parabeac_core/interpret_and_optimize/helpers/pb_project.dart'; 9 | 10 | class RiverpodFileStructureStrategy extends FileStructureStrategy { 11 | final RELATIVE_PROVIDER_PATH = 'lib/riverpod/'; 12 | final RELATIVE_MODEL_PATH = 'lib/models/'; 13 | var _providersPath; 14 | var _modelsPath; 15 | 16 | RiverpodFileStructureStrategy(String genProjectPath, PBPageWriter pageWriter, 17 | PBProject pbProject, FileSystemAnalyzer fileSystemAnalyzer) 18 | : super(genProjectPath, pageWriter, pbProject, fileSystemAnalyzer) { 19 | _providersPath = p.join(genProjectPath, RELATIVE_PROVIDER_PATH); 20 | _modelsPath = p.join(genProjectPath, RELATIVE_MODEL_PATH); 21 | } 22 | 23 | @override 24 | Future setUpDirectories() async { 25 | if (!isSetUp) { 26 | await Future.wait( 27 | [super.setUpDirectories(), _generateMissingDirectories()]); 28 | isSetUp = true; 29 | } 30 | } 31 | 32 | Future _generateMissingDirectories() async { 33 | Directory(_providersPath).createSync(recursive: true); 34 | Directory(_modelsPath).createSync(recursive: true); 35 | } 36 | 37 | void writeRiverpodModelFile(String code, String fileName) { 38 | super.pageWriter.write(code, '$_modelsPath$fileName.dart'); // Removed .g 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /lib/generation/generators/value_objects/generation_configuration/bloc_generation_configuration.dart: -------------------------------------------------------------------------------- 1 | import 'package:parabeac_core/generation/generators/middleware/state_management/bloc_middleware.dart'; 2 | import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/bloc_file_structure_strategy.dart'; 3 | import 'package:parabeac_core/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart'; 4 | import 'package:quick_log/quick_log.dart'; 5 | 6 | class BLoCGenerationConfiguration extends GenerationConfiguration { 7 | BLoCGenerationConfiguration(); 8 | 9 | @override 10 | Future setUpConfiguration(pbProject) async { 11 | await super.setUpConfiguration(pbProject); 12 | logger = Logger('BLoC'); 13 | logger.info( 14 | 'Thanks for trying our state management configuration that is now in Beta!\nIf you run into any issues please feel free to post it in Github or in our Discord!'); 15 | fileStructureStrategy = BLoCFileStructureStrategy( 16 | pbProject.projectAbsPath, pageWriter, pbProject, fileSystemAnalyzer); 17 | registerMiddleware(BLoCMiddleware(generationManager, this)); 18 | logger.info('Setting up the directories'); 19 | await fileStructureStrategy.setUpDirectories(); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /lib/generation/generators/value_objects/generation_configuration/provider_generation_configuration.dart: -------------------------------------------------------------------------------- 1 | import 'package:parabeac_core/generation/generators/import_generator.dart'; 2 | import 'package:parabeac_core/generation/generators/middleware/state_management/provider_middleware.dart'; 3 | import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/provider_file_structure_strategy.dart'; 4 | import 'package:parabeac_core/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart'; 5 | import 'package:parabeac_core/interpret_and_optimize/helpers/pb_project.dart'; 6 | import 'package:quick_log/quick_log.dart'; 7 | import 'package:recase/recase.dart'; 8 | import 'package:path/path.dart' as p; 9 | 10 | class ProviderGenerationConfiguration extends GenerationConfiguration { 11 | ProviderGenerationConfiguration(); 12 | 13 | Set registeredModels = {}; 14 | 15 | @override 16 | Future setUpConfiguration(pbProject) async { 17 | logger = Logger('Provider'); 18 | logger.info( 19 | 'Thanks for trying our state management configuration that is now in Beta!\nIf you run into any issues please feel free to post it in Github or in our Discord!'); 20 | fileStructureStrategy = ProviderFileStructureStrategy( 21 | pbProject.projectAbsPath, pageWriter, pbProject, fileSystemAnalyzer); 22 | registerMiddleware(ProviderMiddleware(generationManager, this)); 23 | logger.info('Setting up the directories'); 24 | await fileStructureStrategy.setUpDirectories(); 25 | } 26 | 27 | @override 28 | Future generateProject(PBProject pb_project) async { 29 | await super.generateProject(pb_project); 30 | Set imports = {FlutterImport('provider.dart', 'provider')}; 31 | imports.addAll(registeredModels 32 | .map((e) => FlutterImport( 33 | p.setExtension( 34 | p.join(fileStructureStrategy.GENERATED_PROJECT_PATH, 'models', 35 | e.snakeCase), 36 | '.dart'), 37 | pb_project.projectName)) 38 | .toList()); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /lib/generation/generators/value_objects/generation_configuration/riverpod_generation_configuration.dart: -------------------------------------------------------------------------------- 1 | import 'package:parabeac_core/generation/generators/import_generator.dart'; 2 | import 'package:parabeac_core/generation/generators/middleware/state_management/riverpod_middleware.dart'; 3 | import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/commands/file_structure_command.dart'; 4 | import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/riverpod_file_structure_strategy.dart'; 5 | import 'package:parabeac_core/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart'; 6 | import 'package:parabeac_core/generation/generators/writers/pb_flutter_writer.dart'; 7 | import 'package:parabeac_core/interpret_and_optimize/helpers/pb_project.dart'; 8 | import 'package:quick_log/quick_log.dart'; 9 | import 'package:path/path.dart' as p; 10 | 11 | class RiverpodGenerationConfiguration extends GenerationConfiguration { 12 | RiverpodGenerationConfiguration(); 13 | 14 | @override 15 | Future setUpConfiguration(pbProject) async { 16 | logger = Logger('Riverpod'); 17 | logger.info( 18 | 'Thanks for trying our state management configuration that is now in Beta!\nIf you run into any issues please feel free to post it in Github or in our Discord!'); 19 | fileStructureStrategy = RiverpodFileStructureStrategy( 20 | pbProject.projectAbsPath,pageWriter, pbProject, fileSystemAnalyzer); 21 | registerMiddleware(RiverpodMiddleware(generationManager, this)); 22 | logger.info('Setting up the directories'); 23 | await fileStructureStrategy.setUpDirectories(); 24 | } 25 | 26 | @override 27 | Future generateProject(PBProject pb_project) async { 28 | await super.generateProject(pb_project); 29 | if (pageWriter is PBFlutterWriter) { 30 | (pageWriter as PBFlutterWriter).rewriteMainFunction( 31 | p.join(fileStructureStrategy.GENERATED_PROJECT_PATH, 'lib/main.dart'), 32 | _generateMainFunction(), 33 | imports: {FlutterImport('flutter_riverpod.dart', 'flutter_riverpod')}, 34 | ); 35 | } 36 | } 37 | 38 | String _generateMainFunction() { 39 | return ''' 40 | runApp( 41 | ProviderScope( 42 | child: MyApp(), 43 | ), 44 | ); 45 | '''; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /lib/generation/generators/value_objects/generation_configuration/stateful_generation_configuration.dart: -------------------------------------------------------------------------------- 1 | import 'package:parabeac_core/generation/generators/middleware/state_management/stateful_middleware.dart'; 2 | import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/flutter_file_structure_strategy.dart'; 3 | import 'package:parabeac_core/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart'; 4 | 5 | class StatefulGenerationConfiguration extends GenerationConfiguration { 6 | StatefulGenerationConfiguration(); 7 | 8 | @override 9 | Future setUpConfiguration(pbProject) async { 10 | fileStructureStrategy = FlutterFileStructureStrategy( 11 | pbProject.projectAbsPath, pageWriter, pbProject, fileSystemAnalyzer); 12 | registerMiddleware(StatefulMiddleware(generationManager, this)); 13 | logger.info('Setting up the directories'); 14 | await fileStructureStrategy.setUpDirectories(); 15 | return super.setUpConfiguration(pbProject); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /lib/generation/generators/value_objects/generator_adapter.dart: -------------------------------------------------------------------------------- 1 | import 'package:parabeac_core/generation/generators/pb_generator.dart'; 2 | import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; 3 | import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; 4 | 5 | ///An Adapter that allows custom string to be injected into a generator instead of a [PBIntermediateNode] 6 | class StringGeneratorAdapter extends PBGenerator { 7 | final String overridenString; 8 | StringGeneratorAdapter(this.overridenString); 9 | @override 10 | String generate(PBIntermediateNode source, PBContext context) { 11 | return overridenString; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /lib/generation/generators/value_objects/template_strategy/bloc_state_template_strategy.dart: -------------------------------------------------------------------------------- 1 | import 'package:parabeac_core/generation/generators/pb_generation_manager.dart'; 2 | import 'package:parabeac_core/generation/generators/value_objects/template_strategy/pb_template_strategy.dart'; 3 | import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; 4 | import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; 5 | import 'package:recase/recase.dart'; 6 | 7 | class BLoCStateTemplateStrategy extends TemplateStrategy { 8 | bool isFirst = true; 9 | String abstractClassName; 10 | BLoCStateTemplateStrategy({this.isFirst, this.abstractClassName}); 11 | @override 12 | String generateTemplate( 13 | PBIntermediateNode node, PBGenerationManager manager, PBContext context, 14 | {args}) { 15 | context.managerData.hasParams = true; 16 | context.managerData.hasParams = false; 17 | 18 | return ''' 19 | ${isFirst ? _getHeader(manager) : ''} 20 | 21 | class ${node.name.pascalCase}State extends ${abstractClassName.pascalCase}State{}'''; 22 | } 23 | 24 | String _getHeader(manager) { 25 | return ''' 26 | part of '${abstractClassName.snakeCase}_cubit.dart'; 27 | 28 | @immutable 29 | abstract class ${abstractClassName.pascalCase}State{ 30 | 31 | } 32 | '''; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /lib/generation/generators/value_objects/template_strategy/empty_page_template_strategy.dart: -------------------------------------------------------------------------------- 1 | import 'package:parabeac_core/generation/generators/pb_generation_manager.dart'; 2 | import 'package:parabeac_core/generation/generators/value_objects/template_strategy/pb_template_strategy.dart'; 3 | import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; 4 | import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; 5 | 6 | class EmptyPageTemplateStrategy extends TemplateStrategy { 7 | @override 8 | String generateTemplate(PBIntermediateNode node, PBGenerationManager manager, 9 | PBContext generatorContext, 10 | {var args}) => 11 | args is String ? args : ''; 12 | } 13 | -------------------------------------------------------------------------------- /lib/generation/generators/value_objects/template_strategy/inline_template_strategy.dart: -------------------------------------------------------------------------------- 1 | import 'package:parabeac_core/generation/generators/pb_generation_manager.dart'; 2 | import 'package:parabeac_core/generation/generators/value_objects/template_strategy/pb_template_strategy.dart'; 3 | import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; 4 | import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; 5 | 6 | class InlineTemplateStrategy extends TemplateStrategy { 7 | @override 8 | String generateTemplate(PBIntermediateNode node, PBGenerationManager manager, 9 | PBContext generatorContext, 10 | {var args}) { 11 | return node is String 12 | ? node 13 | : node.generator.generate(node, generatorContext); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /lib/generation/generators/value_objects/template_strategy/pb_template_strategy.dart: -------------------------------------------------------------------------------- 1 | import 'package:parabeac_core/generation/generators/pb_generation_manager.dart'; 2 | import 'package:parabeac_core/generation/generators/util/pb_input_formatter.dart'; 3 | import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; 4 | import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; 5 | 6 | abstract class TemplateStrategy { 7 | String generateTemplate(PBIntermediateNode node, PBGenerationManager manager, 8 | PBContext generatorContext, 9 | {var args}); 10 | String retrieveNodeName(var node) { 11 | var formatter = (name) => PBInputFormatter.formatLabel(name, 12 | isTitle: true, spaceToUnderscore: false); 13 | var widgetName; 14 | if (node is PBIntermediateNode) { 15 | widgetName = formatter(node.name); 16 | } else if (node is String) { 17 | widgetName = formatter(node); 18 | } else { 19 | widgetName = node; 20 | } 21 | return widgetName; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /lib/generation/generators/value_objects/template_strategy/stateless_template_strategy.dart: -------------------------------------------------------------------------------- 1 | import 'package:parabeac_core/generation/generators/pb_generation_manager.dart'; 2 | import 'package:parabeac_core/generation/generators/value_objects/template_strategy/pb_template_strategy.dart'; 3 | import 'package:parabeac_core/interpret_and_optimize/entities/pb_shared_master_node.dart'; 4 | import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; 5 | import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; 6 | import 'package:recase/recase.dart'; 7 | 8 | class StatelessTemplateStrategy extends TemplateStrategy { 9 | @override 10 | String generateTemplate( 11 | PBIntermediateNode node, PBGenerationManager manager, PBContext context, 12 | {args}) { 13 | var widgetName = node.name; 14 | context.managerData.hasParams = true; 15 | var returnStatement = node.generator.generate(node, context); 16 | context.managerData.hasParams = false; 17 | var overrides = ''; 18 | var overrideVars = ''; 19 | 20 | if (node is PBSharedMasterNode && node.overridableProperties.isNotEmpty) { 21 | node.overridableProperties.forEach((prop) { 22 | var overrideType = 'Widget?'; 23 | if (prop.ovrType == 'stringValue') { 24 | overrideType = 'String?'; 25 | } 26 | overrides += 'this.${prop.propertyName}, '; 27 | overrideVars += 'final $overrideType ${prop.propertyName};'; 28 | }); 29 | } 30 | return ''' 31 | ${manager.generateImports()} 32 | 33 | class ${widgetName.pascalCase} extends StatelessWidget{ 34 | ${overrideVars.isNotEmpty ? overrideVars : ''} 35 | const ${widgetName.pascalCase}({Key? key, ${overrides.isNotEmpty ? overrides : ''}}) : super(key : key); 36 | ${manager.generateGlobalVariables()} 37 | 38 | @override 39 | Widget build(BuildContext context){ 40 | return $returnStatement; 41 | } 42 | }'''; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /lib/generation/generators/visual-widgets/pb_align_gen.dart: -------------------------------------------------------------------------------- 1 | import 'package:parabeac_core/generation/generators/pb_generator.dart'; 2 | import 'package:parabeac_core/interpret_and_optimize/entities/alignments/injected_align.dart'; 3 | import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; 4 | import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; 5 | import 'package:quick_log/quick_log.dart'; 6 | import 'package:sentry/sentry.dart'; 7 | 8 | class PBAlignGenerator extends PBGenerator { 9 | var log = Logger('Align Generator'); 10 | PBAlignGenerator() : super(); 11 | 12 | @override 13 | String generate(PBIntermediateNode source, PBContext context) { 14 | if (source is InjectedAlign) { 15 | var sourceChild = context.tree.childrenOf(source)?.first; 16 | var buffer = StringBuffer(); 17 | buffer.write('Align('); 18 | 19 | buffer.write( 20 | 'alignment: Alignment(${source.alignX.toStringAsFixed(2)}, ${source.alignY.toStringAsFixed(2)}),'); 21 | 22 | try { 23 | // source.child.currentContext = source.currentContext; 24 | buffer.write( 25 | 'child: ${sourceChild.generator.generate(sourceChild, context)},'); 26 | } catch (e, stackTrace) { 27 | Sentry.captureException(e, stackTrace: stackTrace); 28 | log.error(e.toString()); 29 | } 30 | 31 | buffer.write(')'); 32 | return buffer.toString(); 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /lib/generation/generators/visual-widgets/pb_center_gen.dart: -------------------------------------------------------------------------------- 1 | import 'package:parabeac_core/generation/generators/pb_generator.dart'; 2 | import 'package:parabeac_core/interpret_and_optimize/entities/alignments/injected_center.dart'; 3 | import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; 4 | import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; 5 | 6 | class PBCenterGenerator extends PBGenerator { 7 | @override 8 | String generate(PBIntermediateNode source, PBContext context) { 9 | var children = context.tree.childrenOf(source); 10 | if (!(source is InjectedCenter) || children.isEmpty) { 11 | return ''; 12 | } 13 | if (children.length > 1) { 14 | logger.error( 15 | '$runtimeType contains more than a single child. Rendering only the first one'); 16 | } 17 | return 'Center(\nchild: ${children.first.generator.generate(children.first, context)})'; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /lib/generation/generators/visual-widgets/pb_flexible_gen.dart: -------------------------------------------------------------------------------- 1 | import 'package:parabeac_core/generation/generators/pb_generator.dart'; 2 | import 'package:parabeac_core/interpret_and_optimize/entities/alignments/flexible.dart'; 3 | import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; 4 | import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; 5 | import 'package:quick_log/quick_log.dart'; 6 | 7 | class PBFlexibleGenerator extends PBGenerator { 8 | var log = Logger('Flexible Generator'); 9 | PBFlexibleGenerator() : super(); 10 | 11 | @override 12 | String generate(PBIntermediateNode source, PBContext context) { 13 | if (source is Flexible) { 14 | var sourceChildren = context.tree.childrenOf(source); 15 | var buffer = StringBuffer(); 16 | buffer.write('Flexible('); 17 | buffer.write('flex: ${source.flex},'); 18 | try { 19 | // source.child.currentContext = source.currentContext; 20 | buffer.write( 21 | 'child: ${sourceChildren.first.generator.generate(sourceChildren.first, context)},'); 22 | } catch (e) { 23 | log.error(e.toString()); 24 | } 25 | buffer.write(')'); 26 | return buffer.toString(); 27 | } 28 | return ''; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /lib/generation/generators/visual-widgets/pb_shape_group_gen.dart: -------------------------------------------------------------------------------- 1 | import 'package:parabeac_core/controllers/main_info.dart'; 2 | import 'package:parabeac_core/generation/generators/attribute-helper/pb_size_helper.dart'; 3 | import 'package:parabeac_core/generation/generators/pb_generator.dart'; 4 | import 'package:parabeac_core/interpret_and_optimize/entities/inherited_shape_group.dart'; 5 | import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; 6 | import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; 7 | 8 | class PBShapeGroupGen extends PBGenerator { 9 | var _sizehelper; 10 | PBShapeGroupGen() : super() { 11 | _sizehelper = PBSizeHelper(); 12 | } 13 | 14 | @override 15 | String generate(PBIntermediateNode source, PBContext generatorContext) { 16 | if (source is InheritedShapeGroup) { 17 | var buffer = StringBuffer(); 18 | buffer.write( 19 | 'Image.asset(\'assets/images/${source.UUID}.png\', ${_sizehelper.generate(source)}), package: \'${MainInfo().projectName}\','); 20 | return buffer.toString(); 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /lib/generation/generators/visual-widgets/pb_spacer_gen.dart: -------------------------------------------------------------------------------- 1 | import 'package:parabeac_core/generation/generators/pb_generator.dart'; 2 | import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; 3 | import 'package:parabeac_core/interpret_and_optimize/entities/alignments/spacer.dart'; 4 | import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; 5 | 6 | class PBSpacerGenerator extends PBGenerator { 7 | PBSpacerGenerator() : super(); 8 | 9 | @override 10 | String generate( 11 | PBIntermediateNode source, PBContext generatorContext) { 12 | if (source is Spacer) { 13 | var buffer = StringBuffer(); 14 | buffer.write('Spacer('); 15 | buffer.write('flex: ${source.flex},'); 16 | buffer.write(')'); 17 | return buffer.toString(); 18 | } 19 | return ''; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /lib/generation/generators/visual-widgets/pb_text_style_gen_mixin.dart: -------------------------------------------------------------------------------- 1 | import 'package:parabeac_core/generation/generators/attribute-helper/pb_color_gen_helper.dart'; 2 | import 'package:parabeac_core/interpret_and_optimize/entities/inherited_text.dart'; 3 | import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; 4 | import 'package:parabeac_core/interpret_and_optimize/state_management/auxilary_data_helpers/intermediate_effect.dart'; 5 | 6 | mixin PBTextStyleGen { 7 | String getStyle(InheritedText source, PBContext context) { 8 | var textStyle = source.auxiliaryData.intermediateTextStyle; 9 | var buffer = StringBuffer(); 10 | buffer.write('TextStyle(\n'); 11 | if (textStyle.fontFamily != null) { 12 | buffer.write('fontFamily: \'${textStyle.fontFamily}\',\n'); 13 | } 14 | if (textStyle.fontSize != null) { 15 | buffer.write('fontSize: ${textStyle.fontSize.toString()},\n'); 16 | } 17 | if (textStyle.fontWeight != null) { 18 | buffer.write( 19 | 'fontWeight: FontWeight.w${textStyle.fontWeight.toString()},\n'); 20 | } 21 | if (textStyle.italics != null) { 22 | buffer.write( 23 | 'fontStyle: ${(textStyle.italics ?? false) ? 'FontStyle.italic' : 'FontStyle.normal'},\n'); 24 | } 25 | if (textStyle.letterSpacing != null) { 26 | buffer.write('letterSpacing: ${textStyle.letterSpacing},\n'); 27 | } 28 | if (source.auxiliaryData.color != null) { 29 | buffer.write(PBColorGenHelper().generate(source, context)); 30 | } 31 | 32 | if (source.auxiliaryData.effects != null) { 33 | buffer.write(_getEffects(source.auxiliaryData.effects)); 34 | } 35 | 36 | buffer.write(')'); 37 | 38 | return buffer.toString(); 39 | } 40 | 41 | String _getEffects(List effects) { 42 | var shadows = ''; 43 | effects.forEach((effect) { 44 | if (effect.visible && effect.type.toLowerCase().contains('shadow')) { 45 | shadows += ''' 46 | Shadow( 47 | ${PBColorGenHelper().getHexColor(effect.color)} 48 | offset: Offset(${effect.offset['x']}, ${effect.offset['y']}), 49 | blurRadius: ${effect.radius}, 50 | ), 51 | '''; 52 | } 53 | }); 54 | if (shadows.isNotEmpty) { 55 | return ''' 56 | shadows: [ 57 | $shadows 58 | ], 59 | '''; 60 | } 61 | return ''; 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /lib/generation/generators/writers/pb_page_writer.dart: -------------------------------------------------------------------------------- 1 | abstract class PBPageWriter { 2 | void write(String code, String fileName); 3 | 4 | void append(String code, String fileName); 5 | } 6 | -------------------------------------------------------------------------------- /lib/generation/generators/writers/pb_traversal_adapter_writer.dart: -------------------------------------------------------------------------------- 1 | import 'package:parabeac_core/generation/generators/writers/pb_page_writer.dart'; 2 | 3 | /// Adapter used to traverse trees using generation 4 | /// without actually writing to the tree itself. 5 | /// 6 | /// The adapter's purpose is to disregard requests to modify any files, 7 | /// hence the empty return methods. 8 | class PBTraversalAdapterWriter extends PBPageWriter { 9 | // @override 10 | // void addDependency(String packageName, String version) { 11 | // return; 12 | // } 13 | 14 | @override 15 | void write(String code, String fileName) { 16 | return; 17 | } 18 | 19 | @override 20 | void append(String code, String fileName) { 21 | return; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /lib/generation/helperScripts/index.dart: -------------------------------------------------------------------------------- 1 | export 'shell-proxy.dart'; -------------------------------------------------------------------------------- /lib/generation/helperScripts/shell-proxy.dart: -------------------------------------------------------------------------------- 1 | import 'dart:io'; 2 | 3 | class Proxy { 4 | String currentDirectory = Directory.current.path; 5 | 6 | String get proxyPath { 7 | var proxyPath = '$currentDirectory/lib/helperScripts/shell-proxy.sh'; 8 | 9 | return proxyPath; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /lib/generation/helperScripts/shell-proxy.sh: -------------------------------------------------------------------------------- 1 | $1 -------------------------------------------------------------------------------- /lib/generation/prototyping/pb_dest_holder.dart: -------------------------------------------------------------------------------- 1 | import 'package:parabeac_core/generation/prototyping/pb_prototype_gen.dart'; 2 | import 'package:parabeac_core/generation/prototyping/pb_prototype_node.dart'; 3 | import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; 4 | import 'package:parabeac_core/interpret_and_optimize/helpers/child_strategy.dart'; 5 | import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; 6 | import 'dart:math'; 7 | 8 | class PBDestHolder extends PBIntermediateNode { 9 | PrototypeNode pNode; 10 | 11 | PBDestHolder( 12 | String UUID, Rectangle3D frame, this.pNode) 13 | : super(UUID, frame, '') { 14 | generator = PBPrototypeGenerator(pNode); 15 | childrenStrategy = OneChildStrategy('child'); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /lib/generation/prototyping/pb_prototype_gen.dart: -------------------------------------------------------------------------------- 1 | import 'package:parabeac_core/generation/generators/pb_generator.dart'; 2 | import 'package:parabeac_core/generation/prototyping/pb_prototype_node.dart'; 3 | import 'package:parabeac_core/generation/prototyping/pb_prototype_storage.dart'; 4 | import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; 5 | import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; 6 | import 'package:recase/recase.dart'; 7 | 8 | class PBPrototypeGenerator extends PBGenerator { 9 | PrototypeNode prototypeNode; 10 | PBPrototypeStorage _storage; 11 | 12 | PBPrototypeGenerator(this.prototypeNode) : super() { 13 | _storage = PBPrototypeStorage(); 14 | } 15 | 16 | @override 17 | String generate(PBIntermediateNode source, PBContext context) { 18 | var name = _storage 19 | .getPageNodeById(prototypeNode.destinationUUID) 20 | ?.name 21 | ?.pascalCase; 22 | var tree = context.tree; 23 | var sourceChildren = tree.childrenOf(source); 24 | if (name != null && name.isNotEmpty) { 25 | return '''GestureDetector( 26 | onTap: () { 27 | Navigator.push( 28 | context, 29 | MaterialPageRoute(builder: (context) => $name()), 30 | ); 31 | }, 32 | child: ${sourceChildren.first.generator.generate(sourceChildren.first, context)}, 33 | )'''; 34 | } else { 35 | return sourceChildren.first.generator 36 | .generate(sourceChildren.first, context); 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /lib/generation/prototyping/pb_prototype_linker_service.dart: -------------------------------------------------------------------------------- 1 | import 'package:parabeac_core/generation/prototyping/pb_prototype_aggregation_service.dart'; 2 | import 'package:parabeac_core/generation/prototyping/pb_prototype_storage.dart'; 3 | import 'package:parabeac_core/interpret_and_optimize/entities/inherited_scaffold.dart'; 4 | import 'package:parabeac_core/interpret_and_optimize/entities/interfaces/pb_prototype_enabled.dart'; 5 | import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; 6 | import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; 7 | import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart'; 8 | import 'package:parabeac_core/interpret_and_optimize/services/intermediate_node_searcher_service.dart'; 9 | 10 | class PBPrototypeLinkerService { 11 | PBPrototypeStorage _prototypeStorage; 12 | PBPrototypeAggregationService _aggregationService; 13 | 14 | PBPrototypeLinkerService() { 15 | _prototypeStorage = PBPrototypeStorage(); 16 | _aggregationService = PBPrototypeAggregationService(); 17 | } 18 | 19 | Future linkPrototypeNodes( 20 | PBIntermediateTree tree, PBContext context) async { 21 | var rootNode = tree.rootNode; 22 | if (rootNode == null) { 23 | return rootNode; 24 | } 25 | for (var element in tree) { 26 | if (element is InheritedScaffold) { 27 | await _prototypeStorage.addPageNode(element, context); 28 | } else if (element is PrototypeEnable) { 29 | if (element.prototypeNode?.destinationUUID != null && 30 | (element).prototypeNode.destinationUUID.isNotEmpty) { 31 | await addAndPopulatePrototypeNode(element, rootNode, context); 32 | } 33 | } 34 | } 35 | return rootNode; 36 | } 37 | 38 | Future addAndPopulatePrototypeNode( 39 | var currentNode, var rootNode, PBContext context) async { 40 | await _prototypeStorage.addPrototypeInstance(currentNode, context); 41 | var pNode = _aggregationService.populatePrototypeNode(context, currentNode); 42 | if (pNode != null) { 43 | context.tree.addEdges(pNode.parent, [pNode]); 44 | context.tree.removeEdges(pNode.parent, [currentNode]); 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /lib/generation/prototyping/pb_prototype_node.dart: -------------------------------------------------------------------------------- 1 | import 'package:json_annotation/json_annotation.dart'; 2 | 3 | part 'pb_prototype_node.g.dart'; 4 | 5 | @JsonSerializable(nullable: true) 6 | class PrototypeNode { 7 | String destinationUUID; 8 | String destinationName; 9 | PrototypeNode({this.destinationUUID, this.destinationName}); 10 | factory PrototypeNode.fromJson(Map json) => 11 | _$PrototypeNodeFromJson(json); 12 | Map toJson() => _$PrototypeNodeToJson(this); 13 | 14 | static PrototypeNode prototypeNodeFromJson(String prototypeNodeUUID) => 15 | PrototypeNode(destinationUUID: prototypeNodeUUID); 16 | } 17 | -------------------------------------------------------------------------------- /lib/generation/prototyping/pb_prototype_node.g.dart: -------------------------------------------------------------------------------- 1 | // GENERATED CODE - DO NOT MODIFY BY HAND 2 | 3 | part of 'pb_prototype_node.dart'; 4 | 5 | // ************************************************************************** 6 | // JsonSerializableGenerator 7 | // ************************************************************************** 8 | 9 | PrototypeNode _$PrototypeNodeFromJson(Map json) { 10 | return PrototypeNode( 11 | destinationUUID: json['destinationUUID'] as String, 12 | destinationName: json['destinationName'] as String, 13 | ); 14 | } 15 | 16 | Map _$PrototypeNodeToJson(PrototypeNode instance) => 17 | { 18 | 'destinationUUID': instance.destinationUUID, 19 | 'destinationName': instance.destinationName, 20 | }; 21 | -------------------------------------------------------------------------------- /lib/interpret_and_optimize/entities/alignments/expanded.dart: -------------------------------------------------------------------------------- 1 | import 'package:parabeac_core/generation/generators/pb_generator.dart'; 2 | import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; 3 | import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_visual_intermediate_node.dart'; 4 | import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; 5 | 6 | class InjectedExpanded extends PBVisualIntermediateNode { 7 | InjectedExpanded(String UUID, Rectangle3D rectangle3d, String name) 8 | : super(UUID, rectangle3d, name) { 9 | generator = ExpandedGenerator(); 10 | } 11 | } 12 | 13 | class ExpandedGenerator extends PBGenerator { 14 | @override 15 | String generate(PBIntermediateNode source, PBContext context) { 16 | if (source is InjectedExpanded) { 17 | var children = context.tree.childrenOf(source); 18 | if (children.isNotEmpty) { 19 | var child = children.first; 20 | if (child != null) { 21 | return '''Expanded( 22 | child: ${child.generator.generate(child, context)} 23 | )'''; 24 | } 25 | } 26 | } 27 | return ''; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /lib/interpret_and_optimize/entities/alignments/flexible.dart: -------------------------------------------------------------------------------- 1 | import 'package:parabeac_core/generation/generators/visual-widgets/pb_flexible_gen.dart'; 2 | import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; 3 | import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_visual_intermediate_node.dart'; 4 | import 'package:parabeac_core/interpret_and_optimize/helpers/align_strategy.dart'; 5 | import 'package:parabeac_core/interpret_and_optimize/helpers/child_strategy.dart'; 6 | import 'dart:math'; 7 | 8 | import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; 9 | 10 | class Flexible extends PBVisualIntermediateNode { 11 | int flex; 12 | 13 | //TODO: Find a way to make currentContext required 14 | //without breaking the json serializable 15 | Flexible( 16 | String UUID, 17 | Rectangle3D frame, { 18 | // child, 19 | this.flex, 20 | }) : super( 21 | UUID, 22 | frame, 23 | '', 24 | ) { 25 | generator = PBFlexibleGenerator(); 26 | childrenStrategy = OneChildStrategy('child'); 27 | // if(child != null){ 28 | // addChild(child); 29 | // } 30 | } 31 | 32 | @override 33 | PBIntermediateNode fromJson(Map json) => null; 34 | } 35 | -------------------------------------------------------------------------------- /lib/interpret_and_optimize/entities/alignments/injected_align.dart: -------------------------------------------------------------------------------- 1 | import 'dart:math'; 2 | 3 | import 'package:parabeac_core/generation/generators/visual-widgets/pb_align_gen.dart'; 4 | import 'package:parabeac_core/interpret_and_optimize/entities/interfaces/pb_injected_intermediate.dart'; 5 | import 'package:parabeac_core/interpret_and_optimize/entities/layouts/group/group.dart'; 6 | import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; 7 | import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_visual_intermediate_node.dart'; 8 | import 'package:parabeac_core/interpret_and_optimize/helpers/child_strategy.dart'; 9 | import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; 10 | 11 | class InjectedAlign extends PBVisualIntermediateNode 12 | implements PBInjectedIntermediate { 13 | double alignX; 14 | double alignY; 15 | 16 | InjectedAlign(String UUID, Rectangle3D frame, String name) 17 | : super(UUID, frame, name) { 18 | generator = PBAlignGenerator(); 19 | childrenStrategy = TempChildrenStrategy('child'); 20 | } 21 | 22 | @override 23 | void alignChild() { 24 | // var maxX = (frame.topLeft.x - frame.bottomRight.x).abs() - 25 | // (child.frame.bottomRight.x - child.frame.topLeft.x).abs(); 26 | // var parentCenterX = (frame.topLeft.x + frame.bottomRight.x) / 2; 27 | // var childCenterX = (child.frame.topLeft.x + child.frame.bottomRight.x) / 2; 28 | // var alignmentX = 0.0; 29 | 30 | // if (maxX != 0.0) { 31 | // alignmentX = ((childCenterX - parentCenterX) / maxX) * 2; 32 | // } 33 | 34 | // var parentCenterY = (frame.topLeft.y + frame.bottomRight.y) / 2; 35 | // var maxY = (frame.topLeft.y - frame.bottomRight.y).abs() - 36 | // (child.frame.bottomRight.y - child.frame.topLeft.y).abs(); 37 | // var childCenterY = (child.frame.topLeft.y + child.frame.bottomRight.y) / 2; 38 | // var alignmentY = ((childCenterY - parentCenterY) / maxY) * 2; 39 | 40 | // if (maxY != 0.0) { 41 | // alignmentY = ((childCenterY - parentCenterY) / maxY) * 2; 42 | // } 43 | 44 | // if (alignmentX.isNaN) { 45 | // alignmentX = 0; 46 | // } 47 | // if (alignmentY.isNaN) { 48 | // alignmentY = 0; 49 | // } 50 | 51 | // alignX = alignmentX.toDouble(); 52 | // alignY = alignmentY.toDouble(); 53 | } 54 | 55 | @override 56 | PBIntermediateNode fromJson(Map json) => null; 57 | } 58 | -------------------------------------------------------------------------------- /lib/interpret_and_optimize/entities/alignments/injected_center.dart: -------------------------------------------------------------------------------- 1 | import 'package:parabeac_core/generation/generators/visual-widgets/pb_center_gen.dart'; 2 | import 'package:parabeac_core/interpret_and_optimize/entities/interfaces/pb_injected_intermediate.dart'; 3 | import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_constraints.dart'; 4 | import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; 5 | import 'package:parabeac_core/interpret_and_optimize/helpers/align_strategy.dart'; 6 | import 'package:parabeac_core/interpret_and_optimize/helpers/child_strategy.dart'; 7 | 8 | /// Represents the Center widget used in flutter to center its elements within 9 | class InjectedCenter extends PBIntermediateNode 10 | implements PBInjectedIntermediate { 11 | InjectedCenter( 12 | String UUID, 13 | Rectangle3D frame, 14 | String name, { 15 | constraints, 16 | }) : super(UUID, frame, name, constraints: constraints) { 17 | generator = PBCenterGenerator(); 18 | childrenStrategy = OneChildStrategy('child'); 19 | alignStrategy = NoAlignment(); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /lib/interpret_and_optimize/entities/alignments/injected_positioned.dart: -------------------------------------------------------------------------------- 1 | import 'package:parabeac_core/generation/generators/visual-widgets/pb_positioned_gen.dart'; 2 | import 'package:parabeac_core/interpret_and_optimize/entities/interfaces/pb_injected_intermediate.dart'; 3 | import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_constraints.dart'; 4 | import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; 5 | import 'package:parabeac_core/interpret_and_optimize/helpers/child_strategy.dart'; 6 | 7 | class InjectedPositioned extends PBIntermediateNode 8 | implements PBInjectedIntermediate { 9 | final PositionedValueHolder valueHolder; 10 | 11 | @override 12 | ChildrenStrategy childrenStrategy = OneChildStrategy('child'); 13 | 14 | @override 15 | String name; 16 | 17 | InjectedPositioned( 18 | this.name, 19 | String UUID, 20 | Rectangle3D frame, { 21 | this.valueHolder, 22 | constraints, 23 | }) : super(UUID, frame, '', constraints: constraints) { 24 | generator = PBPositionedGenerator(overrideChildDim: true); 25 | } 26 | 27 | @override 28 | PBIntermediateNode fromJson(Map json) => null; 29 | } 30 | 31 | /// Class to help us communicate and manipulate positioning values. 32 | class PositionedValueHolder { 33 | double top; 34 | double bottom; 35 | double left; 36 | double right; 37 | 38 | double height; 39 | double width; 40 | 41 | PositionedValueHolder( 42 | {this.top, this.bottom, this.left, this.right, this.height, this.width}) { 43 | // top ??= 0; 44 | // bottom ??= 0; 45 | // left ??= 0; 46 | // right ??= 0; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /lib/interpret_and_optimize/entities/alignments/spacer.dart: -------------------------------------------------------------------------------- 1 | import 'dart:math'; 2 | 3 | import 'package:parabeac_core/generation/generators/visual-widgets/pb_spacer_gen.dart'; 4 | import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; 5 | import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_visual_intermediate_node.dart'; 6 | import 'package:parabeac_core/interpret_and_optimize/helpers/align_strategy.dart'; 7 | import 'package:parabeac_core/interpret_and_optimize/helpers/child_strategy.dart'; 8 | import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; 9 | 10 | class Spacer extends PBVisualIntermediateNode { 11 | int flex; 12 | 13 | Spacer(String UUID, Rectangle3D frame, {this.flex, PBContext currentContext}) 14 | : super( 15 | UUID, 16 | frame, 17 | '', 18 | ) { 19 | generator = PBSpacerGenerator(); 20 | childrenStrategy = NoChildStrategy(); 21 | } 22 | 23 | @override 24 | PBIntermediateNode fromJson(Map json) => null; 25 | } 26 | -------------------------------------------------------------------------------- /lib/interpret_and_optimize/entities/container.dart: -------------------------------------------------------------------------------- 1 | import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; 2 | 3 | import 'injected_container.dart'; 4 | 5 | class PBContainer extends PBIntermediateNode { 6 | bool showWidth; 7 | bool showHeight; 8 | InjectedPadding padding; 9 | 10 | PBContainer({String UUID, Rectangle3D frame, String name}) 11 | : super(UUID, frame, name); 12 | } 13 | -------------------------------------------------------------------------------- /lib/interpret_and_optimize/entities/injected_sized_box.dart: -------------------------------------------------------------------------------- 1 | import 'package:parabeac_core/generation/generators/pb_generator.dart'; 2 | import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; 3 | import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_visual_intermediate_node.dart'; 4 | import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; 5 | 6 | class IntermediateSizedBox extends PBVisualIntermediateNode { 7 | num height, width; 8 | 9 | IntermediateSizedBox({ 10 | String UUID, 11 | Rectangle3D frame, 12 | String name, 13 | this.width, 14 | this.height, 15 | }) : super(UUID, frame, name) { 16 | generator = PBSizedBoxGenerator(); 17 | } 18 | } 19 | 20 | class PBSizedBoxGenerator extends PBGenerator { 21 | @override 22 | String generate(PBIntermediateNode source, PBContext context) { 23 | if (source is IntermediateSizedBox) { 24 | var buffer = StringBuffer(); 25 | 26 | buffer.write('SizedBox('); 27 | 28 | if (source.height != null) { 29 | if (source.height < 0) { 30 | buffer.write('height: 0.0'); 31 | } else { 32 | buffer.write('height: ${source.height},'); 33 | } 34 | } 35 | if (source.width != null) { 36 | if (source.width < 0) { 37 | buffer.write('width: 0.0'); 38 | } else { 39 | buffer.write('width: ${source.width},'); 40 | } 41 | } 42 | 43 | buffer.write(')'); 44 | 45 | return buffer.toString(); 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /lib/interpret_and_optimize/entities/interfaces/pb_inherited_intermediate.dart: -------------------------------------------------------------------------------- 1 | import 'package:parabeac_core/interpret_and_optimize/entities/interfaces/pb_prototype_enabled.dart'; 2 | 3 | /// Interface that defines that the node was derived from the design files. 4 | abstract class PBInheritedIntermediate implements PrototypeEnable { 5 | final Map originalRef; 6 | PBInheritedIntermediate(this.originalRef); 7 | 8 | static Map originalRefFromJson(Map json) => 9 | json; 10 | } 11 | -------------------------------------------------------------------------------- /lib/interpret_and_optimize/entities/interfaces/pb_injected_intermediate.dart: -------------------------------------------------------------------------------- 1 | /// Interface that defines that the node was injected by some semantic or understanding of the design files. 2 | abstract class PBInjectedIntermediate {} 3 | -------------------------------------------------------------------------------- /lib/interpret_and_optimize/entities/interfaces/pb_prototype_enabled.dart: -------------------------------------------------------------------------------- 1 | import 'package:parabeac_core/generation/prototyping/pb_prototype_node.dart'; 2 | 3 | //TODO: refactoring it into [PBIntermediateNode] 4 | abstract class PrototypeEnable { 5 | PrototypeNode prototypeNode; 6 | } 7 | -------------------------------------------------------------------------------- /lib/interpret_and_optimize/entities/layouts/exceptions/layout_exception.dart: -------------------------------------------------------------------------------- 1 | import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; 2 | 3 | ///Represents some exceptions to the rules. 4 | abstract class LayoutException { 5 | bool testException( 6 | PBIntermediateNode currentNode, PBIntermediateNode nextNode); 7 | } 8 | -------------------------------------------------------------------------------- /lib/interpret_and_optimize/entities/layouts/exceptions/stack_exception.dart: -------------------------------------------------------------------------------- 1 | import 'package:parabeac_core/interpret_and_optimize/entities/layouts/exceptions/layout_exception.dart'; 2 | import 'package:parabeac_core/interpret_and_optimize/entities/layouts/rules/axis_comparison_rules.dart'; 3 | import 'package:parabeac_core/interpret_and_optimize/entities/layouts/stack.dart'; 4 | import 'package:parabeac_core/interpret_and_optimize/entities/layouts/group/group.dart'; 5 | import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; 6 | import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_layout_intermediate_node.dart'; 7 | 8 | class ColumnOverlappingException extends LayoutException 9 | with AxisComparisonRule { 10 | @override 11 | bool testException( 12 | PBIntermediateNode currentNode, PBIntermediateNode incomingNode) { 13 | return (areXCoordinatesOverlapping( 14 | currentNode.frame.topLeft, 15 | currentNode.frame.bottomRight, 16 | incomingNode.frame.topLeft, 17 | currentNode.frame.bottomRight) && 18 | (currentNode is PBLayoutIntermediateNode && 19 | currentNode is! Group && 20 | currentNode is! PBIntermediateStackLayout)); 21 | } 22 | } 23 | 24 | class RowOverlappingException extends LayoutException with AxisComparisonRule { 25 | @override 26 | bool testException( 27 | PBIntermediateNode currentNode, PBIntermediateNode incomingNode) { 28 | return (areYCoordinatesOverlapping( 29 | currentNode.frame.topLeft, 30 | currentNode.frame.bottomRight, 31 | incomingNode.frame.topLeft, 32 | incomingNode.frame.bottomRight) && 33 | (currentNode is PBLayoutIntermediateNode && 34 | currentNode is! Group && 35 | currentNode is! PBIntermediateStackLayout)); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /lib/interpret_and_optimize/entities/layouts/group/base_group.dart: -------------------------------------------------------------------------------- 1 | import 'dart:math'; 2 | 3 | import 'package:parabeac_core/generation/prototyping/pb_prototype_node.dart'; 4 | import 'package:parabeac_core/interpret_and_optimize/entities/interfaces/pb_inherited_intermediate.dart'; 5 | import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_constraints.dart'; 6 | import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; 7 | import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_layout_intermediate_node.dart'; 8 | import 'package:parabeac_core/interpret_and_optimize/helpers/abstract_intermediate_node_factory.dart'; 9 | import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; 10 | import 'package:json_annotation/json_annotation.dart'; 11 | import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart'; 12 | 13 | import 'package:parabeac_core/interpret_and_optimize/state_management/intermediate_auxillary_data.dart'; 14 | 15 | import 'group.dart'; 16 | 17 | part 'base_group.g.dart'; 18 | 19 | @JsonSerializable(ignoreUnannotated: true, createToJson: true) 20 | 21 | /// A temporary node that must be removed 22 | class BaseGroup extends Group 23 | implements PBInheritedIntermediate, IntermediateNodeFactory { 24 | BaseGroup( 25 | String UUID, 26 | Rectangle3D frame, { 27 | Map originalRef, 28 | String name, 29 | PrototypeNode prototypeNode, 30 | PBIntermediateConstraints constraints, 31 | }) : super( 32 | UUID, 33 | frame, 34 | name: name, 35 | prototypeNode: prototypeNode, 36 | originalRef: originalRef, 37 | constraints: constraints, 38 | ); 39 | 40 | @override 41 | PBIntermediateNode createIntermediateNode(Map json, 42 | PBIntermediateNode parent, PBIntermediateTree tree) => 43 | _$BaseGroupFromJson(json) 44 | ..mapRawChildren(json, tree) 45 | ..originalRef = json; 46 | } 47 | -------------------------------------------------------------------------------- /lib/interpret_and_optimize/entities/layouts/group/frame_group.dart: -------------------------------------------------------------------------------- 1 | import 'package:get_it/get_it.dart'; 2 | import 'package:parabeac_core/analytics/amplitude_analytics_service.dart'; 3 | import 'package:parabeac_core/generation/prototyping/pb_prototype_node.dart'; 4 | import 'package:parabeac_core/interpret_and_optimize/entities/interfaces/pb_inherited_intermediate.dart'; 5 | import 'package:parabeac_core/interpret_and_optimize/entities/layouts/group/group.dart'; 6 | import 'package:json_annotation/json_annotation.dart'; 7 | import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_constraints.dart'; 8 | import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; 9 | import 'package:parabeac_core/interpret_and_optimize/helpers/abstract_intermediate_node_factory.dart'; 10 | import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart'; 11 | import 'package:parabeac_core/interpret_and_optimize/state_management/intermediate_auxillary_data.dart'; 12 | 13 | part 'frame_group.g.dart'; 14 | 15 | @JsonSerializable(ignoreUnannotated: true, createToJson: true) 16 | 17 | /// When creating [FrameGroup]s that is not from JSON (In other words, its being injected rather than inherited) 18 | /// the values for the [PBIntermediateConstraints] are going to be [PBIntermediateConstraints.defaultConstraints()]. 19 | /// Furthermore, the [frame] is going to be as big as it could be if the [FrameGroup] was injected rather than derived 20 | /// from the JSON file. 21 | class FrameGroup extends Group 22 | implements PBInheritedIntermediate, IntermediateNodeFactory { 23 | @override 24 | @JsonKey() 25 | String type = 'frame'; 26 | 27 | FrameGroup( 28 | String UUID, 29 | Rectangle3D frame, { 30 | String name, 31 | PrototypeNode prototypeNode, 32 | PBIntermediateConstraints constraints, 33 | }) : super(UUID, frame, 34 | name: name, prototypeNode: prototypeNode, constraints: constraints); 35 | 36 | @override 37 | PBIntermediateNode createIntermediateNode(Map json, 38 | PBIntermediateNode parent, PBIntermediateTree tree) { 39 | // Add number of Frame groups to analytics 40 | if (!tree.lockData) { 41 | GetIt.I 42 | .get() 43 | .addToAnalytics('Number of positional frames'); 44 | } 45 | var tempFrame = _$FrameGroupFromJson(json); 46 | return tempFrame 47 | ..mapRawChildren(json, tree) 48 | ..originalRef = json; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /lib/interpret_and_optimize/entities/layouts/group/group.dart: -------------------------------------------------------------------------------- 1 | import 'dart:math'; 2 | 3 | import 'package:parabeac_core/generation/prototyping/pb_prototype_node.dart'; 4 | import 'package:parabeac_core/interpret_and_optimize/entities/interfaces/pb_inherited_intermediate.dart'; 5 | import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_constraints.dart'; 6 | import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; 7 | import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_layout_intermediate_node.dart'; 8 | import 'package:parabeac_core/interpret_and_optimize/helpers/abstract_intermediate_node_factory.dart'; 9 | import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; 10 | import 'package:json_annotation/json_annotation.dart'; 11 | 12 | // @JsonSerializable(ignoreUnannotated: true, explicitToJson: true) 13 | 14 | /// A temporary node that must be removed 15 | abstract class Group extends PBLayoutIntermediateNode 16 | implements PBInheritedIntermediate, IntermediateNodeFactory { 17 | @override 18 | @JsonKey( 19 | fromJson: PrototypeNode.prototypeNodeFromJson, name: 'prototypeNodeUUID') 20 | PrototypeNode prototypeNode; 21 | 22 | @override 23 | @JsonKey() 24 | String type = 'group'; 25 | 26 | @override 27 | Map originalRef; 28 | 29 | Group( 30 | String UUID, 31 | Rectangle3D frame, { 32 | this.originalRef, 33 | String name, 34 | this.prototypeNode, 35 | PBIntermediateConstraints constraints, 36 | }) : super( 37 | UUID, 38 | frame, 39 | [], 40 | [], 41 | name, 42 | constraints: constraints, 43 | prototypeNode: prototypeNode, 44 | ); 45 | 46 | @override 47 | bool satisfyRules(PBContext context, PBIntermediateNode currentNode, 48 | PBIntermediateNode nextNode) { 49 | assert(false, 'Attempted to satisfyRules for class type [$runtimeType]'); 50 | return null; 51 | } 52 | 53 | @override 54 | PBLayoutIntermediateNode generateLayout(List children, 55 | PBContext currentContext, String name) { 56 | assert(false, 'Attempted to generateLayout for class type [$runtimeType]'); 57 | return null; 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /lib/interpret_and_optimize/entities/layouts/layout_properties.dart: -------------------------------------------------------------------------------- 1 | import 'package:json_annotation/json_annotation.dart'; 2 | 3 | part 'layout_properties.g.dart'; 4 | 5 | @JsonSerializable(createToJson: true) 6 | class LayoutProperties { 7 | num spacing; 8 | 9 | num leftPadding; 10 | num rightPadding; 11 | num topPadding; 12 | num bottomPadding; 13 | 14 | IntermediateAxisAlignment primaryAxisAlignment; 15 | @JsonKey(name: 'counterAxisAlignment') 16 | IntermediateAxisAlignment crossAxisAlignment; 17 | 18 | IntermediateAxisMode primaryAxisSizing; 19 | @JsonKey(name: 'counterAxisSizing') 20 | IntermediateAxisMode crossAxisSizing; 21 | 22 | LayoutProperties({ 23 | this.spacing, 24 | this.leftPadding, 25 | this.rightPadding, 26 | this.topPadding, 27 | this.bottomPadding, 28 | this.crossAxisAlignment, 29 | this.primaryAxisAlignment, 30 | this.crossAxisSizing, 31 | this.primaryAxisSizing, 32 | }); 33 | 34 | @override 35 | factory LayoutProperties.fromJson(Map json) => 36 | _$LayoutPropertiesFromJson(json); 37 | 38 | Map toJson() => _$LayoutPropertiesToJson(this); 39 | } 40 | 41 | enum IntermediateAxisAlignment { START, CENTER, END, SPACE_BETWEEN } 42 | 43 | enum IntermediateAxisMode { FIXED, HUGGED } 44 | -------------------------------------------------------------------------------- /lib/interpret_and_optimize/entities/layouts/rules/container_constraint_rule.dart: -------------------------------------------------------------------------------- 1 | import 'package:parabeac_core/interpret_and_optimize/entities/injected_container.dart'; 2 | import 'package:parabeac_core/interpret_and_optimize/entities/layouts/rules/layout_rule.dart'; 3 | import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; 4 | import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_layout_intermediate_node.dart'; 5 | import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; 6 | import 'package:uuid/uuid.dart'; 7 | 8 | class ContainerConstraintRule extends PostConditionRule { 9 | @override 10 | dynamic executeAction(PBContext context, PBIntermediateNode currentNode, 11 | PBIntermediateNode nextNode) { 12 | if (testRule(context, currentNode, nextNode)) { 13 | var container = InjectedContainer( 14 | null, 15 | currentNode.frame, 16 | name: currentNode.name, 17 | constraints: currentNode.constraints.copyWith(), 18 | ); 19 | //FIXME container.addChild(currentNode); 20 | return container; 21 | } 22 | return currentNode; 23 | } 24 | 25 | @override 26 | bool testRule(PBContext context, PBIntermediateNode currentNode, 27 | PBIntermediateNode nextNode) => 28 | (currentNode != null && currentNode is PBLayoutIntermediateNode); 29 | } 30 | -------------------------------------------------------------------------------- /lib/interpret_and_optimize/entities/layouts/rules/layout_rule.dart: -------------------------------------------------------------------------------- 1 | import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; 2 | import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; 3 | 4 | ///Represents specific Rules a [PBLayoutIntermediateNode] follows 5 | abstract class LayoutRule { 6 | bool testRule(PBContext context, PBIntermediateNode currentNode, PBIntermediateNode nextNode); 7 | } 8 | 9 | ///Are rules that execute certain actions post layout convertion 10 | abstract class PostConditionRule extends LayoutRule { 11 | dynamic executeAction( 12 | PBContext context, PBIntermediateNode currentNode, PBIntermediateNode nextNode); 13 | } 14 | -------------------------------------------------------------------------------- /lib/interpret_and_optimize/entities/pb_deny_list_node.dart: -------------------------------------------------------------------------------- 1 | import 'dart:math'; 2 | import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; 3 | import 'package:parabeac_core/interpret_and_optimize/helpers/child_strategy.dart'; 4 | import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; 5 | import 'package:json_annotation/json_annotation.dart'; 6 | 7 | @JsonSerializable() 8 | 9 | /// A node that should not be converted to intermediate. 10 | class PBDenyListNode extends PBIntermediateNode { 11 | @override 12 | ChildrenStrategy childrenStrategy = NoChildStrategy(); 13 | PBDenyListNode( 14 | String UUID, 15 | Rectangle3D frame, { 16 | String name, 17 | }) : super( 18 | UUID, 19 | frame, 20 | name, 21 | ); 22 | 23 | @override 24 | PBIntermediateNode fromJson(Map json) => null; 25 | } 26 | -------------------------------------------------------------------------------- /lib/interpret_and_optimize/entities/subclasses/pb_intermediate_constraints.g.dart: -------------------------------------------------------------------------------- 1 | // GENERATED CODE - DO NOT MODIFY BY HAND 2 | 3 | part of 'pb_intermediate_constraints.dart'; 4 | 5 | // ************************************************************************** 6 | // JsonSerializableGenerator 7 | // ************************************************************************** 8 | 9 | PBIntermediateConstraints _$PBIntermediateConstraintsFromJson( 10 | Map json) { 11 | return PBIntermediateConstraints( 12 | pinLeft: json['pinLeft'] as bool, 13 | pinRight: json['pinRight'] as bool, 14 | pinTop: json['pinTop'] as bool, 15 | pinBottom: json['pinBottom'] as bool, 16 | fixedHeight: json['fixedHeight'] as bool, 17 | fixedWidth: json['fixedWidth'] as bool, 18 | ); 19 | } 20 | 21 | Map _$PBIntermediateConstraintsToJson( 22 | PBIntermediateConstraints instance) => 23 | { 24 | 'pinLeft': instance.pinLeft, 25 | 'pinRight': instance.pinRight, 26 | 'pinTop': instance.pinTop, 27 | 'pinBottom': instance.pinBottom, 28 | 'fixedHeight': instance.fixedHeight, 29 | 'fixedWidth': instance.fixedWidth, 30 | }; 31 | -------------------------------------------------------------------------------- /lib/interpret_and_optimize/entities/subclasses/pb_intermediate_node.g.dart: -------------------------------------------------------------------------------- 1 | // GENERATED CODE - DO NOT MODIFY BY HAND 2 | 3 | part of 'pb_intermediate_node.dart'; 4 | 5 | // ************************************************************************** 6 | // JsonSerializableGenerator 7 | // ************************************************************************** 8 | 9 | Map _$PBIntermediateNodeToJson(PBIntermediateNode instance) => 10 | { 11 | 'UUID': instance.UUID, 12 | 'constraints': instance.constraints?.toJson(), 13 | 'layoutMainAxisSizing': 14 | _$ParentLayoutSizingEnumMap[instance.layoutMainAxisSizing], 15 | 'layoutCrossAxisSizing': 16 | _$ParentLayoutSizingEnumMap[instance.layoutCrossAxisSizing], 17 | 'boundaryRectangle': Rectangle3D.toJson(instance.frame), 18 | 'style': instance.auxiliaryData?.toJson(), 19 | 'name': instance.name, 20 | }; 21 | 22 | const _$ParentLayoutSizingEnumMap = { 23 | ParentLayoutSizing.INHERIT: 'INHERIT', 24 | ParentLayoutSizing.STRETCH: 'STRETCH', 25 | ParentLayoutSizing.NONE: 'NONE', 26 | }; 27 | -------------------------------------------------------------------------------- /lib/interpret_and_optimize/entities/subclasses/pb_visual_intermediate_node.dart: -------------------------------------------------------------------------------- 1 | import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_constraints.dart'; 2 | import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; 3 | import 'package:parabeac_core/interpret_and_optimize/state_management/intermediate_auxillary_data.dart'; 4 | 5 | /// Represents a typical node that the end-user could see, it usually has properties such as size and color. It only contains a single child, unlike PBLayoutIntermediateNode that contains a set of children. 6 | /// Superclass: PBIntermediateNode 7 | abstract class PBVisualIntermediateNode extends PBIntermediateNode { 8 | PBVisualIntermediateNode( 9 | String UUID, 10 | Rectangle3D rectangle3d, 11 | String name, { 12 | PBIntermediateConstraints constraints, 13 | IntermediateAuxiliaryData auxiliaryData, 14 | }) : super( 15 | UUID, 16 | rectangle3d, 17 | name, 18 | constraints: constraints, 19 | auxiliaryData: auxiliaryData, 20 | ); 21 | } 22 | -------------------------------------------------------------------------------- /lib/interpret_and_optimize/helpers/component_isolation_configuration.dart: -------------------------------------------------------------------------------- 1 | import 'package:parabeac_core/controllers/interpret.dart'; 2 | import 'package:parabeac_core/generation/flutter_project_builder/post_gen_tasks/comp_isolation/component_isolation_generator.dart'; 3 | import 'package:parabeac_core/generation/flutter_project_builder/post_gen_tasks/comp_isolation/dashbook/dashbook_generator.dart'; 4 | import 'package:parabeac_core/generation/flutter_project_builder/post_gen_tasks/comp_isolation/widgetbook/widgetbook_generator.dart'; 5 | import 'package:parabeac_core/generation/generators/util/pb_generation_project_data.dart'; 6 | import 'package:parabeac_core/interpret_and_optimize/helpers/pb_configuration.dart'; 7 | import 'package:parabeac_core/interpret_and_optimize/services/component_isolation/dashbook_service.dart'; 8 | import 'package:parabeac_core/interpret_and_optimize/services/component_isolation/widgetbook_service.dart'; 9 | 10 | /// Class that bundles a ComponentIsolationGenerator and an AITHandler 11 | /// to generate the component isolation package according to the type. 12 | class ComponentIsolationConfiguration { 13 | ComponentIsolationGenerator generator; 14 | AITHandler service; 15 | 16 | ComponentIsolationConfiguration._internal(this.generator, this.service); 17 | 18 | factory ComponentIsolationConfiguration.getConfiguration( 19 | String type, 20 | PBGenerationProjectData projectData, 21 | IntegrationLevel integrationLevel, 22 | ) { 23 | if (integrationLevel == IntegrationLevel.themes) { 24 | return null; 25 | } 26 | switch (type.toLowerCase()) { 27 | case 'widgetbook': 28 | return ComponentIsolationConfiguration._internal( 29 | WidgetbookGenerator(projectData), WidgetBookService()); 30 | case 'dashbook': 31 | return ComponentIsolationConfiguration._internal( 32 | DashbookGenerator(projectData), DashbookService()); 33 | default: 34 | return null; 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /lib/interpret_and_optimize/helpers/element_storage.dart: -------------------------------------------------------------------------------- 1 | import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart'; 2 | 3 | class ElementStorage { 4 | static final ElementStorage _elementStorageInstance = 5 | ElementStorage._internal(); 6 | 7 | /// This [Map] contains the [PBIntermediateNode.UUID] to [PBIntermediateTree.UUID]. 8 | /// 9 | /// This is primarly used to find a particular [PBIntermediateNode]s [PBIntermediateTree] 10 | final elementToTree = {}; 11 | 12 | /// Key value pair for [PBIntermediateTree.UUID] to [PBIntermediateTree] 13 | final treeUUIDs = {}; 14 | 15 | factory ElementStorage() => _elementStorageInstance; 16 | ElementStorage._internal(); 17 | } 18 | -------------------------------------------------------------------------------- /lib/interpret_and_optimize/helpers/index_walker.dart: -------------------------------------------------------------------------------- 1 | /// Class that helps traversing a [Map] without running into null errors 2 | class IndexWalker { 3 | dynamic value; 4 | IndexWalker(this.value); 5 | 6 | IndexWalker operator [](Object index) { 7 | if (value != null) { 8 | value = value[index]; 9 | } 10 | return this; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /lib/interpret_and_optimize/helpers/layer_tuple.dart: -------------------------------------------------------------------------------- 1 | import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; 2 | 3 | /// A simple PBIntermediateNode layer & Converted Parent Node holder. (Tuple) 4 | class LayerTuple { 5 | /// Child Sketch Node 6 | List nodeLayer; 7 | 8 | /// Parent Intermediate node where. 9 | PBIntermediateNode parent; 10 | 11 | /// Constructor for NodeTuple. 12 | LayerTuple(this.nodeLayer, this.parent); 13 | } 14 | -------------------------------------------------------------------------------- /lib/interpret_and_optimize/helpers/node_tuple.dart: -------------------------------------------------------------------------------- 1 | // import 'package:parabeac_core/design_logic/design_node.dart'; 2 | // import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; 3 | 4 | // /// A simple child Sketch Node & Converted Parent Node holder. (Tuple) 5 | // class NodeTuple { 6 | // /// Child Sketch Node 7 | // DesignNode designNode; 8 | 9 | // /// Parent Intermediate node where `sketchNode.interpretNode()` should be assigned as a child. 10 | // PBIntermediateNode convertedParent; 11 | 12 | // /// Constructor for NodeTuple. 13 | // NodeTuple(this.designNode, this.convertedParent); 14 | // } 15 | -------------------------------------------------------------------------------- /lib/interpret_and_optimize/helpers/override_helper.dart: -------------------------------------------------------------------------------- 1 | import 'package:parabeac_core/interpret_and_optimize/entities/pb_shared_master_node.dart'; 2 | 3 | class OverrideHelper { 4 | /// Map to keep track of overrides. 5 | /// 6 | /// The `key` is the [UUID] of the override property, 7 | /// while the `value` is the [List] of the properties for that particular element. 8 | /// This is useful in the case that a single UUID contains many overrides like text content and text style. 9 | static final SN_UUIDtoVarName = >{}; 10 | 11 | /// Adds `property` to `SN_UUIDtoVarName` map based on `property`'s [UUID] 12 | static void addProperty(PBMasterOverride property) { 13 | if (SN_UUIDtoVarName.containsKey(property.UUID)) { 14 | SN_UUIDtoVarName[property.UUID].add(property); 15 | } else { 16 | SN_UUIDtoVarName[property.UUID] = [property]; 17 | } 18 | } 19 | 20 | /// Returns a `PBMasterOverride` matching given `uuid` and `type` of override. 21 | /// 22 | /// Returns [null] if no match is found 23 | static PBMasterOverride getProperty(String uuid, String type) { 24 | if (SN_UUIDtoVarName.containsKey(uuid)) { 25 | return SN_UUIDtoVarName[uuid] 26 | .firstWhere((element) => element.ovrType == type, orElse: () => null); 27 | } 28 | return null; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /lib/interpret_and_optimize/helpers/pb_color.dart: -------------------------------------------------------------------------------- 1 | import 'package:hex/hex.dart'; 2 | import 'package:parabeac_core/interpret_and_optimize/helpers/index_walker.dart'; 3 | import 'package:json_annotation/json_annotation.dart'; 4 | 5 | part 'pb_color.g.dart'; 6 | 7 | @JsonSerializable() 8 | class PBColor { 9 | num a; 10 | num r; 11 | num g; 12 | num b; 13 | 14 | PBColor( 15 | this.a, 16 | this.r, 17 | this.g, 18 | this.b, 19 | ); 20 | 21 | factory PBColor.fromJson(Map json) => 22 | _$PBColorFromJson(json); 23 | 24 | Map toJson() => _$PBColorToJson(this); 25 | 26 | @override 27 | String toString() => ColorUtils.toHex(this); 28 | } 29 | 30 | class ColorUtils { 31 | static String toHex(PBColor color) { 32 | if (color != null) { 33 | int a, r, g, b; 34 | a = ((color.a ?? 0) * 255).round(); 35 | r = ((color.r ?? 0) * 255).round(); 36 | g = ((color.g ?? 0) * 255).round(); 37 | b = ((color.b ?? 0) * 255).round(); 38 | return '0x' + HEX.encode([a, r, g, b]); 39 | } else { 40 | return '0x' + HEX.encode([0, 0, 0, 0]); 41 | } 42 | } 43 | 44 | static String findDefaultColor(String hex) { 45 | switch (hex) { 46 | case '0xffffffff': 47 | return 'Colors.white'; 48 | break; 49 | case '0xff000000': 50 | return 'Colors.black'; 51 | break; 52 | } 53 | return null; 54 | } 55 | 56 | /// Returns a json representation of color assuming we receive a PBDL `style` in json format 57 | static PBColor pbColorFromJsonFills(List> json) { 58 | var fills = IndexWalker(json).value; 59 | 60 | if (fills != null && fills.isNotEmpty) { 61 | // Get first fill that has a color and is enabled 62 | var fill = fills.firstWhere( 63 | (fill) => fill['isEnabled'] as bool && fill['color'] != null, 64 | orElse: () => null); 65 | 66 | if (fill != null) { 67 | return PBColor.fromJson(fill['color']); 68 | } 69 | } 70 | return null; 71 | } 72 | 73 | // static List getColorListFromJsonFIlls(List> json){ 74 | // var tempList = []; 75 | 76 | // for(var fill in json){ 77 | // tempList 78 | // } 79 | 80 | // return tempList; 81 | // } 82 | } 83 | -------------------------------------------------------------------------------- /lib/interpret_and_optimize/helpers/pb_color.g.dart: -------------------------------------------------------------------------------- 1 | // GENERATED CODE - DO NOT MODIFY BY HAND 2 | 3 | part of 'pb_color.dart'; 4 | 5 | // ************************************************************************** 6 | // JsonSerializableGenerator 7 | // ************************************************************************** 8 | 9 | PBColor _$PBColorFromJson(Map json) { 10 | return PBColor( 11 | json['a'] as num, 12 | json['r'] as num, 13 | json['g'] as num, 14 | json['b'] as num, 15 | ); 16 | } 17 | 18 | Map _$PBColorToJson(PBColor instance) => { 19 | 'a': instance.a, 20 | 'r': instance.r, 21 | 'g': instance.g, 22 | 'b': instance.b, 23 | }; 24 | -------------------------------------------------------------------------------- /lib/interpret_and_optimize/helpers/pb_deny_list_helper.dart: -------------------------------------------------------------------------------- 1 | import 'package:parabeac_core/interpret_and_optimize/entities/pb_deny_list_node.dart'; 2 | import 'dart:math'; 3 | 4 | import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; 5 | 6 | // Helping understand indirect and direct semantics that should remove a node from a tree. 7 | class PBDenyListHelper { 8 | Map denyList = { 9 | //iOS Library 10 | '64A58F18-749F-477C-9B71-E65B82DDC277': true, 11 | '649B1B1E-2911-49F1-85C2-89387DB7B43F': true, 12 | '5FD734F9-A5BC-479E-8DDD-5537BCFE2AE4': true, 13 | '130A23DE-9787-44C2-B81F-D99CF2B323A2': true, 14 | '937FDFA9-BCF9-4577-AE5E-0CF7FDD47254': true, 15 | }; 16 | 17 | bool isInDenyListDirect(PBIntermediateNode node) { 18 | if (denyList[node.UUID] != null) { 19 | return true; 20 | } 21 | return false; 22 | } 23 | 24 | PBDenyListNode returnDenyListNodeIfExist(PBIntermediateNode node) { 25 | if (isInDenyListDirect(node)) { 26 | return PBDenyListNode(null, node.frame); 27 | } else { 28 | return null; 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /lib/interpret_and_optimize/helpers/pb_image_reference_storage.dart: -------------------------------------------------------------------------------- 1 | import 'dart:io'; 2 | import 'dart:typed_data'; 3 | import 'package:path/path.dart' as p; 4 | 5 | import 'package:parabeac_core/controllers/main_info.dart'; 6 | 7 | /// Singleton class that stores sketch node symbols for easy access 8 | class ImageReferenceStorage { 9 | static final ImageReferenceStorage _singleInstance = 10 | ImageReferenceStorage._internal(); 11 | 12 | ImageReferenceStorage._internal(); 13 | 14 | /// Singleton class that stores sketch node symbols for easy access 15 | factory ImageReferenceStorage() { 16 | return _singleInstance; 17 | } 18 | 19 | final Map images_references = {}; 20 | 21 | Iterable get names => images_references.keys; 22 | 23 | Iterable get paths => images_references.values; 24 | 25 | /// Adds the reference to the image and writes the png to the assets folder. 26 | /// Returns true if the image was written successfully, false otherwise 27 | bool addReferenceAndWrite(String name, String path, Uint8List image) { 28 | if(image == null){ 29 | return false; 30 | } 31 | var imgPath = p.join(MainInfo().pngPath, '$name.png'); 32 | if (image == null && 33 | File('${MainInfo().cwd?.path}/lib/input/assets/image-conversion-error.png') 34 | .existsSync() && 35 | addReference(name, 36 | '${MainInfo().cwd?.path}/lib/input/assets/image-conversion-error.png')) { 37 | File('${MainInfo().cwd?.path}/lib/input/assets/image-conversion-error.png') 38 | .copySync(imgPath); 39 | return true; 40 | } 41 | if (addReference(name, path)) { 42 | if (!File(imgPath).existsSync()) { 43 | File(imgPath).createSync(recursive: true); 44 | } 45 | File(imgPath).writeAsBytesSync(image); 46 | return true; 47 | } 48 | return false; 49 | } 50 | 51 | bool addReference(String name, String path) { 52 | if (name != null && path != null && name.isNotEmpty && path.isNotEmpty) { 53 | images_references[name] = path; 54 | return true; 55 | } else { 56 | return false; 57 | } 58 | } 59 | 60 | /// Removes the symbol with given [reference]. 61 | /// Returns [true] if the object was successfuly removed, 62 | /// [false] if the object did not exist. 63 | bool removeImageByName(String name) { 64 | return (images_references.remove(name) != null); 65 | } 66 | 67 | /// Returns the symbol with the given [reference], 68 | /// or [null] if no such symbol exists. 69 | String getImagePathByReference(String name) { 70 | return images_references[name]; 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /lib/interpret_and_optimize/helpers/pb_intermediate_node_tree.g.dart: -------------------------------------------------------------------------------- 1 | // GENERATED CODE - DO NOT MODIFY BY HAND 2 | 3 | part of 'pb_intermediate_node_tree.dart'; 4 | 5 | // ************************************************************************** 6 | // JsonSerializableGenerator 7 | // ************************************************************************** 8 | 9 | PBIntermediateTree _$PBIntermediateTreeFromJson(Map json) { 10 | return PBIntermediateTree( 11 | name: json['name'] as String, 12 | )..convert = json['convert'] as bool ?? true; 13 | } 14 | 15 | Map _$PBIntermediateTreeToJson(PBIntermediateTree instance) => 16 | { 17 | 'convert': instance.convert, 18 | 'name': instance.name, 19 | }; 20 | -------------------------------------------------------------------------------- /lib/interpret_and_optimize/helpers/pb_project.g.dart: -------------------------------------------------------------------------------- 1 | // GENERATED CODE - DO NOT MODIFY BY HAND 2 | 3 | part of 'pb_project.dart'; 4 | 5 | // ************************************************************************** 6 | // JsonSerializableGenerator 7 | // ************************************************************************** 8 | 9 | PBProject _$PBProjectFromJson(Map json) { 10 | return PBProject( 11 | json['name'] as String, 12 | json['projectAbsPath'] as String, 13 | )..forest = 14 | PBProject.forestFromJson(json['pages'] as List>); 15 | } 16 | 17 | Map _$PBProjectToJson(PBProject instance) => { 18 | 'name': instance.projectName, 19 | 'projectAbsPath': instance.projectAbsPath, 20 | 'pages': instance.forest?.map((e) => e?.toJson())?.toList(), 21 | }; 22 | -------------------------------------------------------------------------------- /lib/interpret_and_optimize/services/design_to_pbdl/design_to_pbdl_service.dart: -------------------------------------------------------------------------------- 1 | import 'package:parabeac_core/controllers/main_info.dart'; 2 | import 'package:pbdl/pbdl.dart'; 3 | 4 | abstract class DesignToPBDLService { 5 | DesignType designType; 6 | 7 | Future callPBDL(MainInfo info); 8 | } 9 | -------------------------------------------------------------------------------- /lib/interpret_and_optimize/services/design_to_pbdl/figma_to_pbdl_service.dart: -------------------------------------------------------------------------------- 1 | import 'package:parabeac_core/controllers/main_info.dart'; 2 | import 'package:parabeac_core/interpret_and_optimize/services/design_to_pbdl/design_to_pbdl_service.dart'; 3 | import 'package:pbdl/pbdl.dart'; 4 | import 'package:path/path.dart' as p; 5 | 6 | class FigmaToPBDLService implements DesignToPBDLService { 7 | @override 8 | DesignType designType = DesignType.FIGMA; 9 | 10 | @override 11 | Future callPBDL(MainInfo info) { 12 | return PBDL.fromFigma( 13 | info.configuration.figmaProjectID, 14 | key: info.configuration.figmaKey, 15 | oauthKey: info.configuration.figmaOauthToken, 16 | outputPath: p.join(info.genProjectPath, 'lib', 'assets'), 17 | // Generating all assets inside lib folder for package isolation 18 | pngPath: p.join(info.genProjectPath, 'lib', 'assets', 'images'), 19 | exportPbdlJson: info.configuration.exportPBDL, 20 | projectName: info.projectName, 21 | integrationStrategy: info.configuration.integrationLevel.name, 22 | designSystemType: info.configuration.designSystem, 23 | ); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /lib/interpret_and_optimize/services/design_to_pbdl/json_to_pbdl_service.dart: -------------------------------------------------------------------------------- 1 | import 'dart:convert'; 2 | import 'dart:io'; 3 | import 'package:parabeac_core/controllers/main_info.dart'; 4 | import 'package:parabeac_core/interpret_and_optimize/services/design_to_pbdl/design_to_pbdl_service.dart'; 5 | import 'package:pbdl/pbdl.dart'; 6 | import 'package:path/path.dart' as p; 7 | 8 | class JsonToPBDLService implements DesignToPBDLService { 9 | @override 10 | Future callPBDL(MainInfo info) async { 11 | var pbdlJson = 12 | jsonDecode(File(MainInfo().configuration.pbdlPath).readAsStringSync()); 13 | return await PBDL.fromJson(pbdlJson); 14 | } 15 | 16 | @override 17 | DesignType designType = DesignType.PBDL; 18 | } 19 | -------------------------------------------------------------------------------- /lib/interpret_and_optimize/services/pb_alignment_generation_service.dart: -------------------------------------------------------------------------------- 1 | import 'package:parabeac_core/controllers/interpret.dart'; 2 | import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; 3 | import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; 4 | import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart'; 5 | 6 | /// PBAlignmentGenerationService: 7 | /// Interpret the alignment relationship between a child node and a parent Visual or Layout Node. After interpretation, inject the proper alignment whether that’s Padding based or Flex-based. 8 | /// Input: PBIntermediateNode Tree 9 | /// Output: PBIntermediateNode Tree 10 | class PBAlignGenerationService extends AITHandler { 11 | /// Constructor for PBPluginGenerationService, must include the root SketchNode 12 | PBAlignGenerationService(); 13 | 14 | /// Should find all layout nodes 15 | Future addAlignmentToLayouts( 16 | PBIntermediateTree tree, PBContext context) { 17 | if (tree.rootNode == null) { 18 | logger.warning( 19 | '[PBAlignmentGenerationService] generate() attempted to generate a non-existing tree'); 20 | return null; 21 | } 22 | 23 | tree.rootNode.align(context); 24 | 25 | return Future.value(tree); 26 | } 27 | 28 | @override 29 | Future handleTree( 30 | PBContext context, PBIntermediateTree tree) { 31 | return addAlignmentToLayouts(tree, context); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /lib/interpret_and_optimize/services/pb_constraint_generation_service.dart: -------------------------------------------------------------------------------- 1 | import 'package:parabeac_core/controllers/interpret.dart'; 2 | import 'package:parabeac_core/interpret_and_optimize/entities/inherited_text.dart'; 3 | import 'package:parabeac_core/interpret_and_optimize/entities/injected_container.dart'; 4 | import 'package:parabeac_core/interpret_and_optimize/entities/layouts/column.dart'; 5 | import 'package:parabeac_core/interpret_and_optimize/entities/layouts/row.dart'; 6 | import 'package:parabeac_core/interpret_and_optimize/entities/layouts/stack.dart'; 7 | import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_constraints.dart'; 8 | import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_layout_intermediate_node.dart'; 9 | import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; 10 | import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart'; 11 | 12 | ///tree.where((element) => element != null).toList().reversed.map((e) => e.name).toList() 13 | class PBConstraintGenerationService extends AITHandler { 14 | PBConstraintGenerationService(); 15 | 16 | /// Traverse to the bottom of the tree, and implement constraints to nodes that don't already contain it such as [InjectedContainer] and then work our way up the tree. 17 | /// Through Traversal, discover whether there are elements that will conflict on scaling, if so, change the layout to a Stack. 18 | Future implementConstraints( 19 | PBIntermediateTree tree, PBContext context) { 20 | if (tree.rootNode == null) { 21 | return Future.value(tree); 22 | } 23 | 24 | for (var node 25 | in tree.where((element) => element != null).toList().reversed) { 26 | var children = tree.childrenOf(node); 27 | var child = children.isEmpty ? null : children.first; 28 | if (node.constraints == null) { 29 | if (child.constraints == null) { 30 | node.constraints = PBIntermediateConstraints( 31 | pinBottom: false, pinLeft: false, pinRight: false, pinTop: false); 32 | } else { 33 | node.constraints = child.constraints; 34 | } 35 | } 36 | } 37 | return Future.value(tree); 38 | } 39 | 40 | @override 41 | Future handleTree( 42 | PBContext context, PBIntermediateTree tree) { 43 | return implementConstraints(tree, context); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /lib/interpret_and_optimize/services/pb_semantic_generation_service.dart: -------------------------------------------------------------------------------- 1 | // import 'package:parabeac_core/design_logic/design_node.dart'; 2 | // import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; 3 | // import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; 4 | // import 'package:parabeac_core/interpret_and_optimize/helpers/pb_deny_list_helper.dart'; 5 | // import 'package:parabeac_core/interpret_and_optimize/helpers/pb_plugin_list_helper.dart'; 6 | // import 'package:parabeac_core/interpret_and_optimize/services/pb_generation_service.dart'; 7 | 8 | // /// PBSemanticInterpretationService: 9 | // /// Interprets certain SketchNodes and converts them into PBIntermediateNode based on certain Semantic Rules; indirect or direct semantics. Furthermore, it removes any SketchNode that are in the DenyList 10 | // /// Input: SketchNode 11 | // /// Output: PBIntermediateNode, null (No Semantics found that matches that SketchNode), or DenyListNode if the node is part of a DenyList set in the configuration. 12 | 13 | // class PBSemanticGenerationService implements PBGenerationService { 14 | // PBSemanticGenerationService({this.currentContext}); 15 | 16 | // /// Return DenyListNode if found in the deny List. Return null if there were no semantic node found. Return any other type of PBIntermediateNode if we can tell from direct or indirect semantics. 17 | // PBIntermediateNode checkForSemantics(DesignNode node) { 18 | // PBIntermediateNode convertedNode; 19 | // convertedNode = _checkDirectSemantics(node); 20 | // if (convertedNode != null) { 21 | // return convertedNode; 22 | // } 23 | // return convertedNode; 24 | // } 25 | 26 | // PBIntermediateNode _checkDirectSemantics(DesignNode node) { 27 | // PBIntermediateNode convertedNode; 28 | 29 | // convertedNode = PBDenyListHelper().returnDenyListNodeIfExist(node); 30 | // if (convertedNode != null) { 31 | // return convertedNode; 32 | // } 33 | 34 | // return PBPluginListHelper().returnAllowListNodeIfExists(node); 35 | // } 36 | 37 | // @override 38 | // PBContext currentContext; 39 | // } 40 | -------------------------------------------------------------------------------- /lib/interpret_and_optimize/services/pb_symbol_linker_service.dart: -------------------------------------------------------------------------------- 1 | import 'package:parabeac_core/controllers/interpret.dart'; 2 | import 'package:parabeac_core/interpret_and_optimize/entities/pb_shared_instance.dart'; 3 | import 'package:parabeac_core/interpret_and_optimize/entities/pb_shared_master_node.dart'; 4 | import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; 5 | import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_layout_intermediate_node.dart'; 6 | import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_visual_intermediate_node.dart'; 7 | import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; 8 | import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart'; 9 | import 'package:parabeac_core/interpret_and_optimize/helpers/pb_symbol_storage.dart'; 10 | import 'package:parabeac_core/interpret_and_optimize/services/pb_shared_aggregation_service.dart'; 11 | 12 | class PBSymbolLinkerService extends AITHandler { 13 | PBSymbolStorage _symbolStorage; 14 | PBSharedInterAggregationService _aggregationService; 15 | 16 | PBSymbolLinkerService() { 17 | _symbolStorage = PBSymbolStorage(); 18 | _aggregationService = PBSharedInterAggregationService(); 19 | } 20 | 21 | // /Linking [PBSharedMasterNode] and [PBSharedInstanceIntermediateNode] together; linking its 22 | // /parameter and values. 23 | Future linkSymbols( 24 | PBIntermediateTree tree, PBContext context) async { 25 | var rootNode = tree.rootNode; 26 | if (rootNode == null) { 27 | return Future.value(tree); 28 | } 29 | 30 | for (var vertex in tree) { 31 | var node = vertex; 32 | if (node is PBSharedMasterNode) { 33 | await _symbolStorage.addSharedMasterNode(node); 34 | _aggregationService.gatherSharedParameters( 35 | node, context.tree.childrenOf(node).first, context); 36 | } else if (node is PBSharedInstanceIntermediateNode) { 37 | await _symbolStorage.addSharedInstance(node); 38 | _aggregationService.gatherSharedValues(node); 39 | } 40 | } 41 | 42 | return Future.value(tree); 43 | } 44 | 45 | @override 46 | Future handleTree( 47 | PBContext context, PBIntermediateTree tree) { 48 | return linkSymbols(tree, context); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /lib/interpret_and_optimize/services/state_management_node_interpreter.dart: -------------------------------------------------------------------------------- 1 | import 'package:parabeac_core/controllers/interpret.dart'; 2 | import 'package:parabeac_core/interpret_and_optimize/entities/pb_shared_master_node.dart'; 3 | import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart'; 4 | import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; 5 | import 'package:parabeac_core/interpret_and_optimize/helpers/pb_state_management_helper.dart'; 6 | 7 | class StateManagementNodeInterpreter extends AITHandler { 8 | /// Checks whether `node` is a state management node, and interprets it accordingly. 9 | /// 10 | /// Returns `null` if `node` is a non-default state management node, effectively removing `node` from the tree. 11 | /// Returns `node` if it is a default state management node or a non-state management node. 12 | @override 13 | Future handleTree( 14 | PBContext context, PBIntermediateTree tree) { 15 | if (tree.rootNode is! PBSharedMasterNode) { 16 | return Future.value(tree); 17 | } 18 | var node = tree.rootNode; 19 | var smHelper = PBStateManagementHelper(); 20 | // if (smHelper.isValidStateNode(node)) { 21 | // if (smHelper.isDefaultNode(node)) { 22 | // smHelper.interpretStateManagementNode(node, tree); 23 | // return Future.value(tree); 24 | // } else { 25 | // /// Remove tree entirely 26 | // smHelper.interpretStateManagementNode(node, tree); 27 | // return Future.value(null); 28 | // } 29 | // } 30 | return Future.value(tree); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /lib/interpret_and_optimize/state_management/auxilary_data_helpers/intermediate_border.dart: -------------------------------------------------------------------------------- 1 | import 'package:json_annotation/json_annotation.dart'; 2 | import 'package:parabeac_core/interpret_and_optimize/helpers/pb_color.dart'; 3 | 4 | part 'intermediate_border.g.dart'; 5 | 6 | @JsonSerializable(explicitToJson: true) 7 | class PBBorder { 8 | String blendMode; 9 | 10 | String type; 11 | 12 | PBColor color; 13 | 14 | @JsonKey(defaultValue: true) 15 | bool visible; 16 | 17 | final pbdlType = 'border'; 18 | 19 | PBBorder({ 20 | this.blendMode, 21 | this.type, 22 | this.color, 23 | this.visible, 24 | }); 25 | 26 | factory PBBorder.fromJson(Map json) { 27 | return _$PBBorderFromJson(json); 28 | } 29 | @override 30 | Map toJson() => _$PBBorderToJson(this); 31 | } 32 | -------------------------------------------------------------------------------- /lib/interpret_and_optimize/state_management/auxilary_data_helpers/intermediate_border.g.dart: -------------------------------------------------------------------------------- 1 | // GENERATED CODE - DO NOT MODIFY BY HAND 2 | 3 | part of 'intermediate_border.dart'; 4 | 5 | // ************************************************************************** 6 | // JsonSerializableGenerator 7 | // ************************************************************************** 8 | 9 | PBBorder _$PBBorderFromJson(Map json) { 10 | return PBBorder( 11 | blendMode: json['blendMode'] as String, 12 | type: json['type'] as String, 13 | color: json['color'] == null 14 | ? null 15 | : PBColor.fromJson(json['color'] as Map), 16 | visible: json['visible'] as bool ?? true, 17 | ); 18 | } 19 | 20 | Map _$PBBorderToJson(PBBorder instance) => { 21 | 'blendMode': instance.blendMode, 22 | 'type': instance.type, 23 | 'color': instance.color?.toJson(), 24 | 'visible': instance.visible, 25 | }; 26 | -------------------------------------------------------------------------------- /lib/interpret_and_optimize/state_management/auxilary_data_helpers/intermediate_border_info.dart: -------------------------------------------------------------------------------- 1 | import 'package:json_annotation/json_annotation.dart'; 2 | import 'package:parabeac_core/interpret_and_optimize/helpers/pb_color.dart'; 3 | import 'intermediate_border.dart'; 4 | 5 | part 'intermediate_border_info.g.dart'; 6 | 7 | /// Class that represents the border information for a node. 8 | /// 9 | /// We are operating under the assumption that every [PBIntermediateNode] 10 | /// can only have a single border. 11 | @JsonSerializable(explicitToJson: true) 12 | class IntermediateBorderInfo { 13 | /// TODO: Consider removing this class and simplifying the structure of PBDL to 14 | /// lay out all border options insde a single class. 15 | @JsonKey(fromJson: _borderFromJson, name: 'borders') 16 | PBBorder border; 17 | 18 | @JsonKey(name: 'strokeWeight') 19 | num thickness; 20 | 21 | String strokeAlign; 22 | 23 | String strokeJoin; 24 | 25 | List strokeDashes; 26 | 27 | @JsonKey(name: 'cornerRadius') 28 | num borderRadius; 29 | 30 | final pbdlType = 'border_options'; 31 | 32 | /// These gets are used in order to not break existing tag files 33 | /// that use these attributes directly. We can deprecate these over time 34 | /// or rethink the way borders is structured. 35 | String get blendMode => border?.blendMode; 36 | 37 | String get type => border?.type; 38 | 39 | PBColor get color => border?.color; 40 | 41 | bool get visible => border?.visible ?? false; 42 | 43 | IntermediateBorderInfo({ 44 | this.border, 45 | this.thickness, 46 | this.strokeAlign, 47 | this.strokeJoin, 48 | this.strokeDashes, 49 | this.borderRadius, 50 | }); 51 | 52 | @override 53 | factory IntermediateBorderInfo.fromJson(Map json) => 54 | _$IntermediateBorderInfoFromJson(json); 55 | 56 | Map toJson() => _$IntermediateBorderInfoToJson(this); 57 | 58 | static PBBorder _borderFromJson(List borders) => 59 | borders == null || borders.isEmpty ? null : PBBorder.fromJson(borders[0]); 60 | } 61 | -------------------------------------------------------------------------------- /lib/interpret_and_optimize/state_management/auxilary_data_helpers/intermediate_border_info.g.dart: -------------------------------------------------------------------------------- 1 | // GENERATED CODE - DO NOT MODIFY BY HAND 2 | 3 | part of 'intermediate_border_info.dart'; 4 | 5 | // ************************************************************************** 6 | // JsonSerializableGenerator 7 | // ************************************************************************** 8 | 9 | IntermediateBorderInfo _$IntermediateBorderInfoFromJson( 10 | Map json) { 11 | return IntermediateBorderInfo( 12 | border: IntermediateBorderInfo._borderFromJson(json['borders'] as List), 13 | thickness: json['strokeWeight'] as num, 14 | strokeAlign: json['strokeAlign'] as String, 15 | strokeJoin: json['strokeJoin'] as String, 16 | strokeDashes: json['strokeDashes'] as List, 17 | borderRadius: json['cornerRadius'] as num, 18 | ); 19 | } 20 | 21 | Map _$IntermediateBorderInfoToJson( 22 | IntermediateBorderInfo instance) => 23 | { 24 | 'borders': instance.border?.toJson(), 25 | 'strokeWeight': instance.thickness, 26 | 'strokeAlign': instance.strokeAlign, 27 | 'strokeJoin': instance.strokeJoin, 28 | 'strokeDashes': instance.strokeDashes, 29 | 'cornerRadius': instance.borderRadius, 30 | }; 31 | -------------------------------------------------------------------------------- /lib/interpret_and_optimize/state_management/auxilary_data_helpers/intermediate_effect.dart: -------------------------------------------------------------------------------- 1 | import 'package:parabeac_core/interpret_and_optimize/helpers/pb_color.dart'; 2 | import 'package:json_annotation/json_annotation.dart'; 3 | 4 | part 'intermediate_effect.g.dart'; 5 | 6 | @JsonSerializable(explicitToJson: true) 7 | class PBEffect { 8 | String type; 9 | bool visible; 10 | num radius; 11 | PBColor color; 12 | String blendMode; 13 | Map offset; 14 | bool showShadowBehindNode; 15 | 16 | var pbdlType = 'effect'; 17 | 18 | PBEffect({ 19 | this.type, 20 | this.visible, 21 | this.radius, 22 | this.color, 23 | this.blendMode, 24 | this.offset, 25 | this.showShadowBehindNode, 26 | }); 27 | 28 | Map toJson() => _$PBEffectToJson(this); 29 | factory PBEffect.fromJson(Map json) => 30 | _$PBEffectFromJson(json); 31 | } 32 | -------------------------------------------------------------------------------- /lib/interpret_and_optimize/state_management/auxilary_data_helpers/intermediate_effect.g.dart: -------------------------------------------------------------------------------- 1 | // GENERATED CODE - DO NOT MODIFY BY HAND 2 | 3 | part of 'intermediate_effect.dart'; 4 | 5 | // ************************************************************************** 6 | // JsonSerializableGenerator 7 | // ************************************************************************** 8 | 9 | PBEffect _$PBEffectFromJson(Map json) { 10 | return PBEffect( 11 | type: json['type'] as String, 12 | visible: json['visible'] as bool, 13 | radius: json['radius'] as num, 14 | color: json['color'] == null 15 | ? null 16 | : PBColor.fromJson(json['color'] as Map), 17 | blendMode: json['blendMode'] as String, 18 | offset: json['offset'] as Map, 19 | showShadowBehindNode: json['showShadowBehindNode'] as bool, 20 | )..pbdlType = json['pbdlType'] as String; 21 | } 22 | 23 | Map _$PBEffectToJson(PBEffect instance) => { 24 | 'type': instance.type, 25 | 'visible': instance.visible, 26 | 'radius': instance.radius, 27 | 'color': instance.color?.toJson(), 28 | 'blendMode': instance.blendMode, 29 | 'offset': instance.offset, 30 | 'showShadowBehindNode': instance.showShadowBehindNode, 31 | 'pbdlType': instance.pbdlType, 32 | }; 33 | -------------------------------------------------------------------------------- /lib/interpret_and_optimize/state_management/auxilary_data_helpers/intermediate_fill.dart: -------------------------------------------------------------------------------- 1 | import 'dart:math'; 2 | import 'package:parabeac_core/interpret_and_optimize/helpers/pb_color.dart'; 3 | import 'package:json_annotation/json_annotation.dart'; 4 | 5 | part 'intermediate_fill.g.dart'; 6 | 7 | @JsonSerializable(explicitToJson: true) 8 | class PBFill { 9 | List gradientStops; 10 | @JsonKey(fromJson: _pointsFromJson, toJson: _pointsToJson) 11 | List gradientHandlePositions; 12 | 13 | // String that tidentifies the ID of the image 14 | String imageRef; 15 | 16 | PBColor color; 17 | 18 | @JsonKey(defaultValue: 100) 19 | num opacity; 20 | 21 | String blendMode; 22 | 23 | String type; 24 | 25 | @JsonKey(defaultValue: true) 26 | bool isEnabled; 27 | 28 | final pbdlType = 'fill'; 29 | 30 | PBFill({ 31 | this.opacity, 32 | this.blendMode, 33 | this.type, 34 | this.isEnabled, 35 | this.color, 36 | this.imageRef, 37 | }); 38 | 39 | @override 40 | factory PBFill.fromJson(Map json) => _$PBFillFromJson(json); 41 | 42 | Map toJson() => _$PBFillToJson(this); 43 | 44 | static List _pointsFromJson(List points) { 45 | var objPoints = []; 46 | for (var point in points) { 47 | objPoints.add(Point(point['x'], point['y'])); 48 | } 49 | return objPoints; 50 | } 51 | 52 | static List _pointsToJson(List points) { 53 | var maps = []; 54 | if (points != null) { 55 | for (var p in points) { 56 | maps.add({'x': p.x, 'y': p.y}); 57 | } 58 | } 59 | return maps; 60 | } 61 | } 62 | 63 | @JsonSerializable() 64 | class PBGradientStop { 65 | PBColor color; 66 | num position; 67 | 68 | PBGradientStop({ 69 | this.color, 70 | this.position, 71 | }); 72 | 73 | factory PBGradientStop.fromJson(Map json) => 74 | _$PBGradientStopFromJson(json); 75 | 76 | Map toJson() => _$PBGradientStopToJson(this); 77 | } 78 | -------------------------------------------------------------------------------- /lib/interpret_and_optimize/state_management/auxilary_data_helpers/intermediate_fill.g.dart: -------------------------------------------------------------------------------- 1 | // GENERATED CODE - DO NOT MODIFY BY HAND 2 | 3 | part of 'intermediate_fill.dart'; 4 | 5 | // ************************************************************************** 6 | // JsonSerializableGenerator 7 | // ************************************************************************** 8 | 9 | PBFill _$PBFillFromJson(Map json) { 10 | return PBFill( 11 | opacity: json['opacity'] as num ?? 100, 12 | blendMode: json['blendMode'] as String, 13 | type: json['type'] as String, 14 | isEnabled: json['isEnabled'] as bool ?? true, 15 | color: json['color'] == null 16 | ? null 17 | : PBColor.fromJson(json['color'] as Map), 18 | imageRef: json['imageRef'] as String, 19 | ) 20 | ..gradientStops = (json['gradientStops'] as List) 21 | ?.map((e) => e == null 22 | ? null 23 | : PBGradientStop.fromJson(e as Map)) 24 | ?.toList() 25 | ..gradientHandlePositions = 26 | PBFill._pointsFromJson(json['gradientHandlePositions'] as List); 27 | } 28 | 29 | Map _$PBFillToJson(PBFill instance) => { 30 | 'gradientStops': 31 | instance.gradientStops?.map((e) => e?.toJson())?.toList(), 32 | 'gradientHandlePositions': 33 | PBFill._pointsToJson(instance.gradientHandlePositions), 34 | 'imageRef': instance.imageRef, 35 | 'color': instance.color?.toJson(), 36 | 'opacity': instance.opacity, 37 | 'blendMode': instance.blendMode, 38 | 'type': instance.type, 39 | 'isEnabled': instance.isEnabled, 40 | }; 41 | 42 | PBGradientStop _$PBGradientStopFromJson(Map json) { 43 | return PBGradientStop( 44 | color: json['color'] == null 45 | ? null 46 | : PBColor.fromJson(json['color'] as Map), 47 | position: json['position'] as num, 48 | ); 49 | } 50 | 51 | Map _$PBGradientStopToJson(PBGradientStop instance) => 52 | { 53 | 'color': instance.color, 54 | 'position': instance.position, 55 | }; 56 | -------------------------------------------------------------------------------- /lib/interpret_and_optimize/state_management/auxilary_data_helpers/intermediate_text_style.dart: -------------------------------------------------------------------------------- 1 | import 'package:pbdl/pbdl.dart'; 2 | 3 | import 'package:json_annotation/json_annotation.dart'; 4 | 5 | part 'intermediate_text_style.g.dart'; 6 | 7 | @JsonSerializable(explicitToJson: true) 8 | class PBTextStyle { 9 | String fontFamily; 10 | 11 | String fontPostScriptName; 12 | 13 | @JsonKey(defaultValue: 0) 14 | num paragraphSpacing; 15 | 16 | @JsonKey(defaultValue: 0) 17 | num paragraphIndent; 18 | 19 | @JsonKey(defaultValue: 0) 20 | num listSpacing; 21 | 22 | bool italics; 23 | 24 | num fontWeight; 25 | 26 | num fontSize; 27 | 28 | @JsonKey(defaultValue: 'ORIGINAL') 29 | String textCase; 30 | 31 | @JsonKey(defaultValue: 'NONE') 32 | String textDecoration; 33 | 34 | @JsonKey(defaultValue: 'NONE') 35 | String textAutoResize; 36 | 37 | String textAlignHorizontal; 38 | 39 | String textAlignVertical; 40 | 41 | num letterSpacing; 42 | 43 | List fills; 44 | 45 | String hyperLink; 46 | 47 | @JsonKey(defaultValue: {}) 48 | Map opentypeFlags; 49 | 50 | num lineHeightPx; 51 | 52 | @JsonKey(defaultValue: 100) 53 | num lineHeightPercent; 54 | 55 | num lineHeightPercentFontSize; 56 | 57 | String lineHeightUnit; 58 | 59 | @override 60 | final pbdlType = 'text_style'; 61 | 62 | PBTextStyle({ 63 | this.fontFamily, 64 | this.fontPostScriptName, 65 | this.paragraphSpacing, 66 | this.paragraphIndent, 67 | this.listSpacing, 68 | this.italics, 69 | this.fontWeight, 70 | this.fontSize, 71 | this.textCase, 72 | this.textDecoration, 73 | this.textAutoResize, 74 | this.textAlignHorizontal, 75 | this.textAlignVertical, 76 | this.letterSpacing, 77 | this.fills, 78 | this.hyperLink, 79 | this.opentypeFlags, 80 | this.lineHeightPx, 81 | this.lineHeightPercent, 82 | this.lineHeightPercentFontSize, 83 | this.lineHeightUnit, 84 | }); 85 | 86 | @override 87 | factory PBTextStyle.fromJson(Map json) => 88 | _$PBTextStyleFromJson(json); 89 | @override 90 | Map toJson() => _$PBTextStyleToJson(this); 91 | } 92 | -------------------------------------------------------------------------------- /lib/interpret_and_optimize/state_management/directed_state_graph.dart: -------------------------------------------------------------------------------- 1 | import 'package:directed_graph/directed_graph.dart'; 2 | import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; 3 | 4 | /// [DirectedStateGraph] is used to represent the states of a 5 | /// `default state management node`. 6 | class DirectedStateGraph extends DirectedGraph { 7 | 8 | /// `defaultNode` is considered to be the starting point for this graph. 9 | /// 10 | /// Any other [PBIntermediateNode] that is pointed to by `defaultNode` is considered to be 11 | /// a `variation` of the `defaultNode`. 12 | PBIntermediateNode defaultNode; 13 | 14 | DirectedStateGraph( 15 | this.defaultNode, { 16 | Map, List>> edges, 17 | }) : super(edges); 18 | 19 | /// Adds `variation` as a state of `defaultNode` 20 | void addVariation(PBIntermediateNode variation) => 21 | super.addEdges(defaultNode, [variation]); 22 | 23 | /// Retrieves the states of `defaultNode` 24 | List get states => 25 | super.edges(defaultNode).cast(); 26 | } 27 | -------------------------------------------------------------------------------- /lib/interpret_and_optimize/state_management/intermediate_auxillary_data.g.dart: -------------------------------------------------------------------------------- 1 | // GENERATED CODE - DO NOT MODIFY BY HAND 2 | 3 | part of 'intermediate_auxillary_data.dart'; 4 | 5 | // ************************************************************************** 6 | // JsonSerializableGenerator 7 | // ************************************************************************** 8 | 9 | IntermediateAuxiliaryData _$IntermediateAuxiliaryDataFromJson( 10 | Map json) { 11 | return IntermediateAuxiliaryData( 12 | colors: (json['fills'] as List) 13 | ?.map((e) => 14 | e == null ? null : PBFill.fromJson(e as Map)) 15 | ?.toList(), 16 | borderInfo: json['borderOptions'] == null 17 | ? null 18 | : IntermediateBorderInfo.fromJson( 19 | json['borderOptions'] as Map), 20 | effects: (json['effects'] as List) 21 | ?.map((e) => 22 | e == null ? null : PBEffect.fromJson(e as Map)) 23 | ?.toList(), 24 | intermediateTextStyle: json['textStyle'] == null 25 | ? null 26 | : PBTextStyle.fromJson(json['textStyle'] as Map), 27 | clipsContent: json['clipsContent'] as bool ?? false, 28 | )..alignment = json['alignment'] as Map; 29 | } 30 | 31 | Map _$IntermediateAuxiliaryDataToJson( 32 | IntermediateAuxiliaryData instance) => 33 | { 34 | 'alignment': instance.alignment, 35 | 'fills': instance.colors?.map((e) => e?.toJson())?.toList(), 36 | 'borderOptions': instance.borderInfo?.toJson(), 37 | 'effects': instance.effects?.map((e) => e?.toJson())?.toList(), 38 | 'textStyle': instance.intermediateTextStyle?.toJson(), 39 | 'clipsContent': instance.clipsContent, 40 | }; 41 | -------------------------------------------------------------------------------- /lib/interpret_and_optimize/state_management/intermediate_vertex.dart: -------------------------------------------------------------------------------- 1 | class IntermediateVertex {} 2 | -------------------------------------------------------------------------------- /lib/interpret_and_optimize/value_objects/pb_symbol_instance_overridable_value.dart: -------------------------------------------------------------------------------- 1 | class PBSymbolInstanceOverridableValue { 2 | final Type type; 3 | 4 | final String UUID; 5 | final dynamic value; 6 | 7 | PBSymbolInstanceOverridableValue(this.UUID, this.value, this.type); 8 | } 9 | -------------------------------------------------------------------------------- /lib/interpret_and_optimize/value_objects/pb_symbol_master_overridable_prop.dart: -------------------------------------------------------------------------------- 1 | import 'package:json_annotation/json_annotation.dart'; 2 | 3 | class PBSymbolMasterOverridableProperty { 4 | final bool canOverride; 5 | final String overrideName; 6 | 7 | PBSymbolMasterOverridableProperty(this.canOverride, this.overrideName); 8 | } 9 | -------------------------------------------------------------------------------- /lib/interpret_and_optimize/value_objects/pb_symbol_master_params.dart: -------------------------------------------------------------------------------- 1 | import 'package:json_annotation/json_annotation.dart'; 2 | import 'package:parabeac_core/interpret_and_optimize/entities/interfaces/pb_injected_intermediate.dart'; 3 | import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; 4 | import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_visual_intermediate_node.dart'; 5 | import 'package:parabeac_core/interpret_and_optimize/helpers/align_strategy.dart'; 6 | import 'package:parabeac_core/interpret_and_optimize/helpers/child_strategy.dart'; 7 | import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; 8 | import 'dart:math'; 9 | 10 | ///TODO: Need another class for elements that generate but are not visuals. 11 | 12 | class PBSymbolMasterParameter extends PBIntermediateNode 13 | implements PBInjectedIntermediate { 14 | final Type type; 15 | final String parameterID; 16 | final bool canOverride; 17 | final String propertyName; 18 | final parameterDefinition; 19 | double topLeftX, topLeftY, bottomRightX, bottomRightY; 20 | 21 | PBContext context; 22 | 23 | @override 24 | ChildrenStrategy childrenStrategy = NoChildStrategy(); 25 | 26 | PBSymbolMasterParameter( 27 | String name, 28 | this.type, 29 | this.parameterID, 30 | this.canOverride, 31 | this.propertyName, 32 | this.parameterDefinition, 33 | this.topLeftX, 34 | this.topLeftY, 35 | this.bottomRightX, 36 | this.bottomRightY, 37 | ) : super( 38 | null, 39 | null, 40 | name, 41 | ); 42 | 43 | static String _typeToJson(type) { 44 | return type.toString(); 45 | } 46 | 47 | static Type _typeFromJson(jsonType) { 48 | //TODO: return a more specified Type 49 | return PBIntermediateNode; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /lib/tags/custom_text_form_field/custom_text_form_field.dart: -------------------------------------------------------------------------------- 1 | import 'package:parabeac_core/generation/generators/plugins/pb_plugin_node.dart'; 2 | import 'package:parabeac_core/interpret_and_optimize/entities/pb_shared_master_node.dart'; 3 | import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_constraints.dart'; 4 | import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; 5 | import 'package:parabeac_core/interpret_and_optimize/helpers/child_strategy.dart'; 6 | import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart'; 7 | import 'package:parabeac_core/interpret_and_optimize/state_management/intermediate_auxillary_data.dart'; 8 | import 'package:parabeac_core/tags/custom_text_form_field/custom_text_form_field_generator.dart'; 9 | import 'package:recase/recase.dart'; 10 | 11 | class CustomTextFormField extends PBTag { 12 | @override 13 | final String semanticName = ''; 14 | CustomTextFormField( 15 | String UUID, 16 | Rectangle3D frame, 17 | String name, 18 | PBIntermediateConstraints constraints, { 19 | IntermediateAuxiliaryData auxiliaryData, 20 | }) : super( 21 | UUID, 22 | frame, 23 | name, 24 | auxiliaryData: auxiliaryData, 25 | contraints: constraints, 26 | ) { 27 | generator = CustomTextFormFieldGenerator(); 28 | childrenStrategy = MultipleChildStrategy('children'); 29 | } 30 | 31 | @override 32 | PBIntermediateNode handleIntermediateNode(PBIntermediateNode iNode, 33 | PBIntermediateNode parent, PBTag tag, PBIntermediateTree tree) { 34 | /// Need to remove auxiliary data from component so it's not duplicated 35 | if (iNode is PBSharedMasterNode) { 36 | iNode.auxiliaryData = IntermediateAuxiliaryData(); 37 | } 38 | return super.handleIntermediateNode(iNode, parent, tag, tree); 39 | } 40 | 41 | @override 42 | void extractInformation(PBIntermediateNode incomingNode) { 43 | // TODO: implement extractInformation 44 | } 45 | 46 | @override 47 | PBTag generatePluginNode(Rectangle3D frame, PBIntermediateNode originalRef, 48 | PBIntermediateTree tree) { 49 | return CustomTextFormField( 50 | null, 51 | frame.copyWith(), 52 | originalRef.name.replaceAll(semanticName, '').pascalCase, 53 | originalRef.constraints.copyWith(), 54 | auxiliaryData: originalRef.auxiliaryData.copyWith(), 55 | ); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /pb-scripts/auto_download.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | secret="$1" 3 | region="$2" 4 | service="$3" 5 | keyID="$4" 6 | url="$5" 7 | filename="$6" 8 | 9 | date="`TZ=''"$region"'' date +"%Y%m%dT%k%M%SZ"`" 10 | 11 | fullformatdate=$date 12 | 13 | semiformatdate=${date%\T*} 14 | 15 | # echo $fullformatdate 16 | 17 | # echo $semiformatdate 18 | 19 | rm -rf get-pbc.creq 20 | 21 | touch get-pbc.creq 22 | 23 | requesting=${url##*.com} 24 | # echo $requesting 25 | echo -ne "GET 26 | $requesting 27 | 28 | host:parabeac-core-plugins-staging.s3.amazonaws.com 29 | x-amz-content-sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 30 | x-amz-date:$fullformatdate 31 | 32 | host;x-amz-content-sha256;x-amz-date 33 | e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" >> get-pbc.creq 34 | 35 | temp="`openssl dgst -sha256 get-pbc.creq`" 36 | 37 | temp=${temp##*= } 38 | 39 | rm -rf get-pbc.sts 40 | 41 | touch get-pbc.sts 42 | 43 | echo -ne "AWS4-HMAC-SHA256 44 | $fullformatdate 45 | $semiformatdate/$region/s3/aws4_request 46 | $temp" >> get-pbc.sts 47 | 48 | 49 | function hmac_sha256 { 50 | key="$1" 51 | data="$2" 52 | echo -n "$data" | openssl dgst -sha256 -mac HMAC -macopt "$key" | sed 's/^.* //' 53 | } 54 | 55 | # Four-step signing key calculation 56 | dateKey=$(hmac_sha256 key:"AWS4$secret" $semiformatdate) 57 | dateRegionKey=$(hmac_sha256 hexkey:$dateKey $region) 58 | dateRegionServiceKey=$(hmac_sha256 hexkey:$dateRegionKey $service) 59 | signingKey=$(hmac_sha256 hexkey:$dateRegionServiceKey "aws4_request") 60 | 61 | tempSignature="`openssl dgst -sha256 \ 62 | -mac HMAC \ 63 | -macopt hexkey:$signingKey \ 64 | get-pbc.sts`" 65 | 66 | tempSignature=${tempSignature##*= } 67 | 68 | # echo $tempSignature 69 | 70 | # filename=${url##*.com/*\/} 71 | 72 | # echo $filename 73 | 74 | if [[ "$filename" == *.dart ]] 75 | then 76 | curl $url \ 77 | -H "Authorization: AWS4-HMAC-SHA256 \ 78 | Credential=$keyID/$semiformatdate/$region/$service/aws4_request, \ 79 | SignedHeaders=host;x-amz-content-sha256;x-amz-date, \ 80 | Signature=$tempSignature" \ 81 | -H "x-amz-content-sha256: e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" \ 82 | -H "x-amz-date: $fullformatdate" -s -o $filename 83 | echo "[SUCCESS]: $filename" downloaded! 84 | else 85 | echo [WARNING]: Not a dart file, skipping! 86 | fi -------------------------------------------------------------------------------- /pb-scripts/automate.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | secret="$1" 3 | region="$2" 4 | service="$3" 5 | keyID="$4" 6 | url="$5" 7 | 8 | echo "[INFO]: Downloading eggs..." 9 | 10 | date="`TZ=''"$region"'' date +"%Y%m%dT%k%M%SZ"`" 11 | 12 | fullformatdate=$date 13 | 14 | semiformatdate=${date%\T*} 15 | 16 | # echo $fullformatdate 17 | 18 | # echo $semiformatdate 19 | 20 | rm -rf get-pbc.creq 21 | 22 | touch get-pbc.creq 23 | 24 | requesting=${url##*.com} 25 | # echo $requesting 26 | echo -ne "GET 27 | $requesting 28 | 29 | host:parabeac-core-plugins-staging.s3.amazonaws.com 30 | x-amz-content-sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 31 | x-amz-date:$fullformatdate 32 | 33 | host;x-amz-content-sha256;x-amz-date 34 | e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" >> get-pbc.creq 35 | 36 | temp="`openssl dgst -sha256 get-pbc.creq`" 37 | 38 | temp=${temp##*= } 39 | 40 | rm -rf get-pbc.sts 41 | 42 | touch get-pbc.sts 43 | 44 | echo -ne "AWS4-HMAC-SHA256 45 | $fullformatdate 46 | $semiformatdate/$region/s3/aws4_request 47 | $temp" >> get-pbc.sts 48 | 49 | 50 | function hmac_sha256 { 51 | key="$1" 52 | data="$2" 53 | echo -n "$data" | openssl dgst -sha256 -mac HMAC -macopt "$key" | sed 's/^.* //' 54 | } 55 | 56 | # Four-step signing key calculation 57 | dateKey=$(hmac_sha256 key:"AWS4$secret" $semiformatdate) 58 | dateRegionKey=$(hmac_sha256 hexkey:$dateKey $region) 59 | dateRegionServiceKey=$(hmac_sha256 hexkey:$dateRegionKey $service) 60 | signingKey=$(hmac_sha256 hexkey:$dateRegionServiceKey "aws4_request") 61 | 62 | tempSignature="`openssl dgst -sha256 \ 63 | -mac HMAC \ 64 | -macopt hexkey:$signingKey \ 65 | get-pbc.sts`" 66 | 67 | tempSignature=${tempSignature##*= } 68 | 69 | # echo $tempSignature 70 | 71 | # filename=${url##*.com/} 72 | 73 | curl $url \ 74 | -H "Authorization: AWS4-HMAC-SHA256 \ 75 | Credential=$keyID/$semiformatdate/$region/$service/aws4_request, \ 76 | SignedHeaders=host;x-amz-content-sha256;x-amz-date, \ 77 | Signature=$tempSignature" \ 78 | -H "x-amz-content-sha256: e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" \ 79 | -H "x-amz-date: $fullformatdate" -s -o tempout.xml 80 | 81 | 82 | 83 | xmllint --format tempout.xml >> clean.xml 84 | 85 | files="`sed -n 's:.*\(.*\)=2.7.0 <3.0.0" 9 | 10 | dependencies: 11 | args: ^2.2.0 12 | archive: ^3.1.2 13 | json_serializable: ^3.5.0 14 | build_runner: ^1.10.0 15 | mockito: ^5.0.7 16 | hex: ^0.1.2 17 | build: ^1.3.0 18 | logger: ^1.1.0 19 | uuid: ^3.0.0 20 | quick_log: ^1.1.3 21 | http2: ^1.0.1 22 | recase: "^3.0.0" 23 | tuple: ^2.0.0 24 | path: ^1.6.0 25 | file: ^6.1.2 26 | get_it: ^7.2.0 27 | pbdl: 28 | git: 29 | url: https://github.com/Parabeac/pbdl.git 30 | ref: master 31 | directed_graph: ^0.2.3 32 | sentry: ^6.2.2 33 | yaml_modify: ^1.0.1 34 | 35 | dev_dependencies: 36 | pedantic: ^1.8.0 37 | test: ^1.6.0 38 | build_config: ^0.4.2 39 | -------------------------------------------------------------------------------- /repo_assets/Duplicate Figma File.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Parabeac/parabeac_core/bbc4523c6682bbd3a43af04448a9870ff7d4699e/repo_assets/Duplicate Figma File.gif -------------------------------------------------------------------------------- /repo_assets/figma_component_example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Parabeac/parabeac_core/bbc4523c6682bbd3a43af04448a9870ff7d4699e/repo_assets/figma_component_example.png -------------------------------------------------------------------------------- /repo_assets/figma_frame_example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Parabeac/parabeac_core/bbc4523c6682bbd3a43af04448a9870ff7d4699e/repo_assets/figma_frame_example.png -------------------------------------------------------------------------------- /repo_assets/parabeac_core_image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Parabeac/parabeac_core/bbc4523c6682bbd3a43af04448a9870ff7d4699e/repo_assets/parabeac_core_image.png -------------------------------------------------------------------------------- /test/golden/all_tests.dart: -------------------------------------------------------------------------------- 1 | import 'auto_layout_test.dart' as auto_layout_test; 2 | import 'global_styling_test.dart' as global_styling_test; 3 | import 'styling_test.dart' as styling_test; 4 | 5 | void main(List args) { 6 | /// TODO: When we add more tests, here we can run parabeac core and pass as arguments 7 | /// the location of the generated file as parameter. 8 | auto_layout_test.main(); 9 | global_styling_test.main(); 10 | styling_test.main(); // TODO: Pass arguments 11 | } 12 | -------------------------------------------------------------------------------- /test/golden/global_styling_test.dart: -------------------------------------------------------------------------------- 1 | import 'dart:io'; 2 | 3 | import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/path_services/domain_path_service.dart'; 4 | import 'package:path/path.dart' as path; 5 | import 'package:test/test.dart'; 6 | 7 | void main() { 8 | final projectName = 'global_styling_golden_testing_project'; 9 | final basePath = path.join(path.current, 'test', 'golden'); 10 | final runtimeFilePath = path.join(basePath, projectName); 11 | final goldenFilesPath = path.join(basePath, 'golden_files', 'global_styling'); 12 | 13 | group('Global Styling tests', () { 14 | setUpAll(() async { 15 | // Run Parabeac core to generate test file 16 | await Process.run('dart', [ 17 | 'parabeac.dart', 18 | '-f', 19 | '3jHbHBXrDr74CTceGwE63Q', 20 | '-k', 21 | '346172-e6b93eec-364f-4baa-bee8-24bf1e4d26da', 22 | '-n', 23 | '$projectName', 24 | '-o', 25 | '$basePath' 26 | ]); 27 | }); 28 | 29 | /// Tests whether Global colors were generated as constants in the project. 30 | test('Testing Global Colors', () { 31 | final goldenFile = 32 | File(path.join(goldenFilesPath, 'styling_colors.golden')); 33 | final runtimeFile = File(path.join( 34 | runtimeFilePath, 35 | DomainPathService().themingRelativePath, 36 | '${projectName}_colors.g.dart', 37 | )); 38 | expect(runtimeFile.readAsStringSync(), goldenFile.readAsStringSync()); 39 | }); 40 | 41 | /// Tests whether Global TextStyles were generated as constants in the project. 42 | test('Testing Global TextStyles', () { 43 | final goldenFile = 44 | File(path.join(goldenFilesPath, 'styling_text_styles.golden')); 45 | final runtimeFile = File(path.join( 46 | runtimeFilePath, 47 | DomainPathService().themingRelativePath, 48 | '${projectName}_text_styles.g.dart', 49 | )); 50 | expect(runtimeFile.readAsStringSync(), goldenFile.readAsStringSync()); 51 | }); 52 | 53 | tearDownAll(() async { 54 | // Remove temporary project 55 | await Process.start('rm', ['-rf', path.join(basePath, projectName)]); 56 | }); 57 | }); 58 | } 59 | -------------------------------------------------------------------------------- /test/golden/golden_files/auto_layout/auto_layout_file_names.txt: -------------------------------------------------------------------------------- 1 | col_hz_fx_vr_fx_sp_pk1 2 | col_hz_fx_vr_fx_sp_pk2 3 | col_hz_fx_vr_fx_sp_pk3 4 | col_hz_fx_vr_fx_sp_pk4 5 | col_hz_fx_vr_fx_sp_pk5 6 | col_hz_fx_vr_fx_sp_pk6 7 | col_hz_fx_vr_fx_sp_pk7 8 | col_hz_fx_vr_fx_sp_pk8 9 | col_hz_fx_vr_fx_sp_pk9 10 | col_hz_fx_vr_fx_sp_sb147 11 | col_hz_fx_vr_fx_sp_sb258 12 | col_hz_fx_vr_fx_sp_sb369 13 | col_hz_fx_vr_hg_sp_pk147 14 | col_hz_fx_vr_hg_sp_pk258 15 | col_hz_fx_vr_hg_sp_pk369 16 | col_hz_hg_vr_fx_sp_pk1 17 | col_hz_hg_vr_fx_sp_pk2 18 | col_hz_hg_vr_fx_sp_pk3 19 | col_hz_hg_vr_fx_sp_pk4 20 | col_hz_hg_vr_fx_sp_pk5 21 | col_hz_hg_vr_fx_sp_pk6 22 | col_hz_hg_vr_fx_sp_pk7 23 | col_hz_hg_vr_fx_sp_pk8 24 | col_hz_hg_vr_fx_sp_pk9 25 | col_hz_hg_vr_fx_sp_sb147 26 | col_hz_hg_vr_fx_sp_sb258 27 | col_hz_hg_vr_fx_sp_sb369 28 | col_hz_hg_vr_hg_sp_pk123456789 29 | no_space_col_hz_hg_vr_hg_sp_pk123456789 30 | no_space_row_hz_hg_vr_hg_sp_pk123456789 31 | row_hz_fx_vr_fx_sp_pk1 32 | row_hz_fx_vr_fx_sp_pk2 33 | row_hz_fx_vr_fx_sp_pk3 34 | row_hz_fx_vr_fx_sp_pk4 35 | row_hz_fx_vr_fx_sp_pk5 36 | row_hz_fx_vr_fx_sp_pk6 37 | row_hz_fx_vr_fx_sp_pk7 38 | row_hz_fx_vr_fx_sp_pk8 39 | row_hz_fx_vr_fx_sp_pk9 40 | row_hz_fx_vr_fx_sp_sb123 41 | row_hz_fx_vr_fx_sp_sb456 42 | row_hz_fx_vr_fx_sp_sb789 43 | row_hz_fx_vr_hg_sp_pk147 44 | row_hz_fx_vr_hg_sp_pk258 45 | row_hz_fx_vr_hg_sp_pk369 46 | row_hz_fx_vr_hg_sp_sb123456789 47 | row_hz_hg_vr_fx_sp_pk147 48 | row_hz_hg_vr_fx_sp_pk258 49 | row_hz_hg_vr_fx_sp_pk369 50 | row_hz_hg_vr_hg_sp_pk123456789 51 | admin_city_section_edit_screen 52 | custom_test_screen 53 | test_screen -------------------------------------------------------------------------------- /test/golden/golden_files/global_styling/styling_colors.golden: -------------------------------------------------------------------------------- 1 | // ********************************************************************************* 2 | // PARABEAC-GENERATED CODE. DO NOT MODIFY. 3 | // 4 | // FOR MORE INFORMATION ON HOW TO USE PARABEAC, PLEASE VISIT docs.parabeac.com 5 | // ********************************************************************************* 6 | 7 | 8 | import 'package:flutter/material.dart'; 9 | class GlobalStylingGoldenTestingProjectColors { 10 | /** Parabeac Red Description **/ 11 | static const Color parabeacRed = Color(0xffff0d0d); 12 | 13 | static const Color parabeacBlue = Color(0xff28e5ff); 14 | 15 | static const Color parabeacGreen = Color(0xff49ff0a); 16 | } 17 | -------------------------------------------------------------------------------- /test/golden/golden_files/global_styling/styling_text_styles.golden: -------------------------------------------------------------------------------- 1 | // ********************************************************************************* 2 | // PARABEAC-GENERATED CODE. DO NOT MODIFY. 3 | // 4 | // FOR MORE INFORMATION ON HOW TO USE PARABEAC, PLEASE VISIT docs.parabeac.com 5 | // ********************************************************************************* 6 | 7 | 8 | import 'package:flutter/material.dart'; 9 | class GlobalStylingGoldenTestingProjectTextStyles { 10 | /** Parabeac Style Description **/ 11 | static const TextStyle parabeacTextStyle = TextStyle( 12 | fontSize: 12.0, 13 | fontWeight: FontWeight.w700, 14 | letterSpacing: 6.0, 15 | fontFamily: 'Inter', 16 | decoration: TextDecoration.none, 17 | fontStyle: FontStyle.italic, 18 | ) 19 | ; 20 | 21 | static const TextStyle newStyle = TextStyle( 22 | fontSize: 12.0, 23 | fontWeight: FontWeight.w400, 24 | letterSpacing: 0.0, 25 | fontFamily: 'Inter', 26 | decoration: TextDecoration.none, 27 | fontStyle: FontStyle.normal, 28 | ) 29 | ; 30 | /** headline1 description **/ 31 | static const TextStyle headline1 = TextStyle( 32 | fontSize: 12.0, 33 | fontWeight: FontWeight.w400, 34 | letterSpacing: 0.0, 35 | fontFamily: 'Inter', 36 | decoration: TextDecoration.none, 37 | fontStyle: FontStyle.normal, 38 | ) 39 | ; 40 | 41 | static const TextStyle mynewStyle = TextStyle( 42 | fontSize: 12.0, 43 | fontWeight: FontWeight.w400, 44 | letterSpacing: 0.0, 45 | fontFamily: 'Poppins', 46 | decoration: TextDecoration.none, 47 | fontStyle: FontStyle.normal, 48 | ) 49 | ; 50 | 51 | static const TextStyle headline2 = TextStyle( 52 | fontSize: 12.0, 53 | fontWeight: FontWeight.w700, 54 | letterSpacing: 6.0, 55 | fontFamily: 'Inter', 56 | decoration: TextDecoration.none, 57 | fontStyle: FontStyle.italic, 58 | ) 59 | ; 60 | } 61 | -------------------------------------------------------------------------------- /test/golden/golden_files/styling/helloworld.golden: -------------------------------------------------------------------------------- 1 | // ********************************************************************************* 2 | // PARABEAC-GENERATED CODE. DO NOT MODIFY. 3 | // 4 | // FOR MORE INFORMATION ON HOW TO USE PARABEAC, PLEASE VISIT docs.parabeac.com 5 | // ********************************************************************************* 6 | 7 | import 'package:flutter/material.dart'; 8 | import 'package:auto_size_text/auto_size_text.dart'; 9 | 10 | class Helloworld extends StatefulWidget { 11 | final String? ovrHelloworld; 12 | 13 | const Helloworld({ 14 | Key? key, 15 | this.ovrHelloworld, 16 | }) : super(key: key); 17 | 18 | @override 19 | _Helloworld createState() => _Helloworld(); 20 | } 21 | 22 | class _Helloworld extends State { 23 | _Helloworld(); 24 | 25 | @override 26 | Widget build(BuildContext context) { 27 | return LayoutBuilder(builder: (context, constraints) { 28 | return Container( 29 | decoration: BoxDecoration(), 30 | child: Stack(children: [ 31 | Positioned( 32 | left: constraints.maxWidth * 0.297, 33 | width: constraints.maxWidth * 0.41, 34 | top: constraints.maxHeight * 0.345, 35 | height: constraints.maxHeight * 0.221, 36 | child: Container( 37 | height: constraints.maxHeight * 0.22123893805309736, 38 | width: constraints.maxWidth * 0.40963855421686746, 39 | child: AutoSizeText( 40 | widget.ovrHelloworld ?? 'Hello world', 41 | style: TextStyle( 42 | fontFamily: 'Roboto', 43 | fontSize: 20.0, 44 | fontWeight: FontWeight.w400, 45 | letterSpacing: 0.0, 46 | color: Colors.black, 47 | ), 48 | textAlign: TextAlign.left, 49 | )), 50 | ), 51 | ])); 52 | }); 53 | } 54 | 55 | @override 56 | void dispose() { 57 | super.dispose(); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /test/golden/golden_files/styling/primary_button.golden: -------------------------------------------------------------------------------- 1 | // ********************************************************************************* 2 | // PARABEAC-GENERATED CODE. DO NOT MODIFY. 3 | // 4 | // FOR MORE INFORMATION ON HOW TO USE PARABEAC, PLEASE VISIT docs.parabeac.com 5 | // ********************************************************************************* 6 | 7 | import 'package:flutter/material.dart'; 8 | import 'package:auto_size_text/auto_size_text.dart'; 9 | 10 | class PrimaryButton extends StatefulWidget { 11 | final String? ovrClickMe; 12 | 13 | const PrimaryButton({ 14 | Key? key, 15 | this.ovrClickMe, 16 | }) : super(key: key); 17 | 18 | @override 19 | _PrimaryButton createState() => _PrimaryButton(); 20 | } 21 | 22 | class _PrimaryButton extends State { 23 | _PrimaryButton(); 24 | 25 | @override 26 | Widget build(BuildContext context) { 27 | return LayoutBuilder(builder: (context, constraints) { 28 | return Container( 29 | decoration: BoxDecoration( 30 | color: Color(0xff59afff), 31 | borderRadius: BorderRadius.all(Radius.circular(20.0)), 32 | ), 33 | child: Stack(children: [ 34 | Positioned( 35 | left: constraints.maxWidth * 0.336, 36 | width: constraints.maxWidth * 0.328, 37 | top: constraints.maxHeight * 0.39, 38 | height: constraints.maxHeight * 0.23, 39 | child: Container( 40 | height: constraints.maxHeight * 0.23, 41 | width: constraints.maxWidth * 0.3276595744680851, 42 | child: AutoSizeText( 43 | widget.ovrClickMe ?? 'Click Me', 44 | style: TextStyle( 45 | fontFamily: 'Roboto', 46 | fontSize: 20.0, 47 | fontWeight: FontWeight.w400, 48 | letterSpacing: 0.0, 49 | color: Colors.white, 50 | ), 51 | textAlign: TextAlign.left, 52 | )), 53 | ), 54 | ])); 55 | }); 56 | } 57 | 58 | @override 59 | void dispose() { 60 | super.dispose(); 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /test/golden/golden_files/styling/secondary_button.golden: -------------------------------------------------------------------------------- 1 | // ********************************************************************************* 2 | // PARABEAC-GENERATED CODE. DO NOT MODIFY. 3 | // 4 | // FOR MORE INFORMATION ON HOW TO USE PARABEAC, PLEASE VISIT docs.parabeac.com 5 | // ********************************************************************************* 6 | 7 | import 'package:flutter/material.dart'; 8 | import 'package:auto_size_text/auto_size_text.dart'; 9 | 10 | class SecondaryButton extends StatefulWidget { 11 | final String? ovrClickMe; 12 | 13 | const SecondaryButton({ 14 | Key? key, 15 | this.ovrClickMe, 16 | }) : super(key: key); 17 | 18 | @override 19 | _SecondaryButton createState() => _SecondaryButton(); 20 | } 21 | 22 | class _SecondaryButton extends State { 23 | _SecondaryButton(); 24 | 25 | @override 26 | Widget build(BuildContext context) { 27 | return LayoutBuilder(builder: (context, constraints) { 28 | return Container( 29 | decoration: BoxDecoration( 30 | color: Colors.white, 31 | borderRadius: BorderRadius.all(Radius.circular(20.0)), 32 | border: Border.all( 33 | color: Color(0xff000000), 34 | width: 2.0, 35 | ), 36 | ), 37 | child: Stack(children: [ 38 | Positioned( 39 | left: constraints.maxWidth * 0.336, 40 | width: constraints.maxWidth * 0.328, 41 | top: constraints.maxHeight * 0.39, 42 | height: constraints.maxHeight * 0.23, 43 | child: Container( 44 | height: constraints.maxHeight * 0.23, 45 | width: constraints.maxWidth * 0.3276595744680851, 46 | child: AutoSizeText( 47 | widget.ovrClickMe ?? 'Click Me', 48 | style: TextStyle( 49 | fontFamily: 'Roboto', 50 | fontSize: 20.0, 51 | fontWeight: FontWeight.w400, 52 | letterSpacing: 0.0, 53 | color: Colors.black, 54 | ), 55 | textAlign: TextAlign.left, 56 | )), 57 | ), 58 | ])); 59 | }); 60 | } 61 | 62 | @override 63 | void dispose() { 64 | super.dispose(); 65 | } 66 | } 67 | --------------------------------------------------------------------------------