├── .github
└── FUNDING.yml
├── .gitignore
├── .idea
└── .gitignore
├── .travis.yml
├── .vscode
└── launch.json
├── LICENSE
├── README.md
├── gic_flutter
├── .gitignore
├── .metadata
├── .run
│ └── Flutter Dev.run.xml
├── README.md
├── analysis_options.yaml
├── android
│ ├── .gitignore
│ ├── .project
│ ├── app
│ │ ├── .project
│ │ ├── build.gradle
│ │ ├── proguard-rules.pro
│ │ ├── src
│ │ │ ├── debug
│ │ │ │ ├── AndroidManifest.xml
│ │ │ │ └── res
│ │ │ │ │ └── values
│ │ │ │ │ └── strings.xml
│ │ │ ├── main
│ │ │ │ ├── AndroidManifest.xml
│ │ │ │ ├── ic_launcher-web.png
│ │ │ │ ├── kotlin
│ │ │ │ │ └── ca
│ │ │ │ │ │ └── coffeeshopstudio
│ │ │ │ │ │ └── gaminginterfaceclient
│ │ │ │ │ │ └── MainActivity.kt
│ │ │ │ └── res
│ │ │ │ │ ├── drawable
│ │ │ │ │ ├── ic_arrow_back_white_24dp.xml
│ │ │ │ │ ├── launch_background.xml
│ │ │ │ │ └── launch_image.png
│ │ │ │ │ ├── mipmap-anydpi-v26
│ │ │ │ │ └── ic_launcher.xml
│ │ │ │ │ ├── mipmap-hdpi
│ │ │ │ │ ├── ic_launcher.png
│ │ │ │ │ └── ic_launcher_foreground.png
│ │ │ │ │ ├── mipmap-mdpi
│ │ │ │ │ ├── ic_launcher.png
│ │ │ │ │ └── ic_launcher_foreground.png
│ │ │ │ │ ├── mipmap-xhdpi
│ │ │ │ │ ├── ic_launcher.png
│ │ │ │ │ └── ic_launcher_foreground.png
│ │ │ │ │ ├── mipmap-xxhdpi
│ │ │ │ │ ├── ic_launcher.png
│ │ │ │ │ └── ic_launcher_foreground.png
│ │ │ │ │ ├── mipmap-xxxhdpi
│ │ │ │ │ ├── ic_launcher.png
│ │ │ │ │ └── ic_launcher_foreground.png
│ │ │ │ │ ├── values-sw720dp
│ │ │ │ │ └── dimens.xml
│ │ │ │ │ ├── values-v21
│ │ │ │ │ └── styles.xml
│ │ │ │ │ └── values
│ │ │ │ │ ├── attrs.xml
│ │ │ │ │ ├── colors.xml
│ │ │ │ │ ├── dimens.xml
│ │ │ │ │ ├── ic_launcher_background.xml
│ │ │ │ │ ├── strings.xml
│ │ │ │ │ └── styles.xml
│ │ │ └── profile
│ │ │ │ └── AndroidManifest.xml
│ │ └── web_hi_res_512.png
│ ├── build.gradle
│ ├── gradle.properties
│ ├── gradle
│ │ └── wrapper
│ │ │ └── gradle-wrapper.properties
│ └── settings.gradle
├── assets
│ ├── audio
│ │ └── flick.wav
│ ├── fonts
│ │ ├── Lobster-Regular.ttf
│ │ ├── Nunito-Regular.ttf
│ │ ├── OFL.txt
│ │ ├── Righteous-Regular.ttf
│ │ └── ShareTech-Regular.ttf
│ ├── images
│ │ ├── controls
│ │ │ ├── button_black.png
│ │ │ ├── button_black2.png
│ │ │ ├── button_black2_dark.png
│ │ │ ├── button_black_dark.png
│ │ │ ├── button_blue.png
│ │ │ ├── button_blue2.png
│ │ │ ├── button_blue2_dark.png
│ │ │ ├── button_blue_dark.png
│ │ │ ├── button_green.png
│ │ │ ├── button_green2.png
│ │ │ ├── button_green2_dark.png
│ │ │ ├── button_green_dark.png
│ │ │ ├── button_grey.png
│ │ │ ├── button_grey2.png
│ │ │ ├── button_grey2_dark.png
│ │ │ ├── button_grey_dark.png
│ │ │ ├── button_neon.png
│ │ │ ├── button_neon_dark.png
│ │ │ ├── button_purple.png
│ │ │ ├── button_purple_dark.png
│ │ │ ├── button_red.png
│ │ │ ├── button_red2.png
│ │ │ ├── button_red2_dark.png
│ │ │ ├── button_red_dark.png
│ │ │ ├── button_toggle_off.png
│ │ │ ├── button_toggle_on.png
│ │ │ ├── button_white.png
│ │ │ ├── button_white_dark.png
│ │ │ ├── button_yellow.png
│ │ │ ├── button_yellow_dark.png
│ │ │ ├── lever_off.png
│ │ │ ├── lever_on.png
│ │ │ ├── switch_off.png
│ │ │ ├── switch_on.png
│ │ │ ├── toggle_off.png
│ │ │ └── toggle_on.png
│ │ └── icons
│ │ │ └── app_icon.png
│ └── screens
│ │ ├── Elite-LargeTablet.json
│ │ ├── Elite-Phone.json
│ │ ├── Elite-SmallTablet.json
│ │ ├── SC-LargeTablet.json
│ │ ├── SC-Phone.json
│ │ └── SC-SmallTablet.json
├── ios
│ ├── .gitignore
│ ├── Flutter
│ │ ├── AppFrameworkInfo.plist
│ │ ├── Debug.xcconfig
│ │ └── Release.xcconfig
│ ├── Runner.xcodeproj
│ │ ├── project.pbxproj
│ │ ├── project.xcworkspace
│ │ │ ├── contents.xcworkspacedata
│ │ │ └── xcshareddata
│ │ │ │ ├── IDEWorkspaceChecks.plist
│ │ │ │ └── WorkspaceSettings.xcsettings
│ │ └── xcshareddata
│ │ │ └── xcschemes
│ │ │ └── Runner.xcscheme
│ ├── Runner.xcworkspace
│ │ ├── contents.xcworkspacedata
│ │ └── xcshareddata
│ │ │ ├── IDEWorkspaceChecks.plist
│ │ │ └── WorkspaceSettings.xcsettings
│ └── Runner
│ │ ├── AppDelegate.swift
│ │ ├── Assets.xcassets
│ │ ├── AppIcon.appiconset
│ │ │ ├── Contents.json
│ │ │ ├── Icon-App-1024x1024@1x.png
│ │ │ ├── Icon-App-20x20@1x.png
│ │ │ ├── Icon-App-20x20@2x.png
│ │ │ ├── Icon-App-20x20@3x.png
│ │ │ ├── Icon-App-29x29@1x.png
│ │ │ ├── Icon-App-29x29@2x.png
│ │ │ ├── Icon-App-29x29@3x.png
│ │ │ ├── Icon-App-40x40@1x.png
│ │ │ ├── Icon-App-40x40@2x.png
│ │ │ ├── Icon-App-40x40@3x.png
│ │ │ ├── Icon-App-60x60@2x.png
│ │ │ ├── Icon-App-60x60@3x.png
│ │ │ ├── Icon-App-76x76@1x.png
│ │ │ ├── Icon-App-76x76@2x.png
│ │ │ └── Icon-App-83.5x83.5@2x.png
│ │ └── LaunchImage.imageset
│ │ │ ├── Contents.json
│ │ │ ├── LaunchImage.png
│ │ │ ├── LaunchImage@2x.png
│ │ │ ├── LaunchImage@3x.png
│ │ │ └── README.md
│ │ ├── Base.lproj
│ │ ├── LaunchScreen.storyboard
│ │ └── Main.storyboard
│ │ ├── Info.plist
│ │ └── Runner-Bridging-Header.h
├── lib
│ └── src
│ │ ├── app.dart
│ │ ├── backend
│ │ ├── blocs
│ │ │ ├── launcherBloc.dart
│ │ │ └── newScreenWizardBloc.dart
│ │ ├── models
│ │ │ ├── autoItKeyMap.dart
│ │ │ ├── channel.dart
│ │ │ ├── intl
│ │ │ │ ├── intlAbout.dart
│ │ │ │ ├── intlFeedback.dart
│ │ │ │ ├── intlLauncher.dart
│ │ │ │ ├── intlNewScreenWizard.dart
│ │ │ │ ├── intlOptions.dart
│ │ │ │ ├── intlScreenEditor.dart
│ │ │ │ └── localizations.dart
│ │ │ ├── launcherModel.dart
│ │ │ ├── networkModel.dart
│ │ │ ├── newScreenWizardModel.dart
│ │ │ ├── screen
│ │ │ │ ├── command.dart
│ │ │ │ ├── controlDefaults.dart
│ │ │ │ ├── controlTypes.dart
│ │ │ │ ├── fonts.dart
│ │ │ │ ├── gicControl.dart
│ │ │ │ ├── screen.dart
│ │ │ │ └── viewModels
│ │ │ │ │ ├── controlViewModel.dart
│ │ │ │ │ ├── drawable.dart
│ │ │ │ │ ├── font.dart
│ │ │ │ │ └── screenViewModel.dart
│ │ │ ├── viewModel.dart
│ │ │ └── viewSection.dart
│ │ ├── repositories
│ │ │ ├── launcherRepository.dart
│ │ │ └── screenRepository.dart
│ │ └── services
│ │ │ ├── compressedFileService.dart
│ │ │ ├── cryptoService.dart
│ │ │ ├── firstRunService.dart
│ │ │ ├── networkService.dart
│ │ │ ├── screenImportService.dart
│ │ │ └── screenService.dart
│ │ ├── flavor.dart
│ │ ├── main_gplay.dart
│ │ ├── main_other.dart
│ │ ├── service_locator.dart
│ │ ├── theme
│ │ ├── dimensions.dart
│ │ ├── style.dart
│ │ └── theme.dart
│ │ └── views
│ │ ├── about
│ │ ├── aboutPresentation.dart
│ │ ├── aboutVM.dart
│ │ └── aboutView.dart
│ │ ├── accentButton.dart
│ │ ├── baseGicControl.dart
│ │ ├── basePage.dart
│ │ ├── feedback
│ │ ├── feedbackPresentation.dart
│ │ ├── feedbackVM.dart
│ │ └── feedbackView.dart
│ │ ├── intro
│ │ ├── introPresentation.dart
│ │ ├── introView.dart
│ │ ├── screenListWidget.dart
│ │ └── screenSizeWidget.dart
│ │ ├── launcher
│ │ ├── launcher.dart
│ │ ├── screenList.dart
│ │ └── serverLogin.dart
│ │ ├── menuOption.dart
│ │ ├── newScreenWizard
│ │ ├── controlDesignWidget.dart
│ │ ├── layoutWidget.dart
│ │ ├── newScreenWizard.dart
│ │ ├── newScreenWizardControls.dart
│ │ ├── newScreenWizardGeneral.dart
│ │ └── orientationWidget.dart
│ │ ├── options
│ │ ├── optionsPresentation.dart
│ │ ├── optionsVM.dart
│ │ └── optionsView.dart
│ │ ├── screen
│ │ ├── gicControl.dart
│ │ ├── screenVM.dart
│ │ └── screenView.dart
│ │ └── screenEditor
│ │ ├── backgroundDialog.dart
│ │ ├── colorPickerDialog.dart
│ │ ├── controlDialog
│ │ ├── baseTab.dart
│ │ ├── commandTab.dart
│ │ ├── controlDialog.dart
│ │ ├── designTab.dart
│ │ ├── imageDialog.dart
│ │ ├── sizeTab.dart
│ │ └── textTab.dart
│ │ ├── gicEditControl.dart
│ │ ├── helpDialog
│ │ ├── helpDialog.dart
│ │ └── selectTab.dart
│ │ ├── screenEditor.dart
│ │ └── settingsDialog
│ │ ├── dialogButton.dart
│ │ ├── dialogSlider.dart
│ │ └── settingsDialog.dart
├── pubspec.lock
├── pubspec.yaml
├── runbuild.sh
└── runbuild.win.sh
├── release_notes.txt
└── xgesture_flutter
├── .metadata
├── CHANGELOG.md
├── LICENSE
├── README.md
├── lib
└── gesture_x_detector.dart
├── pubspec.lock
├── pubspec.yaml
└── test
└── gesture_x_detector_test.dart
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | # These are supported funding model platforms
2 |
3 | #github: #
4 | patreon: coffeeshopstudio
5 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | /.idea/modules.xml
2 | /.idea/navEditor.xml
3 | .DS_Store
4 |
5 | # Built application files
6 | *.apk
7 | *.ap_
8 | *.aab
9 |
10 | # Files for the ART/Dalvik VM
11 | *.dex
12 |
13 | # Java class files
14 | *.class
15 |
16 | # Generated files
17 | bin/
18 | gen/
19 | out/
20 |
21 | # Gradle files
22 | .gradle/
23 | build/
24 |
25 | # Local configuration file (sdk path, etc)
26 | local.properties
27 |
28 | # Proguard folder generated by Eclipse
29 | proguard/
30 |
31 | # Log Files
32 | *.log
33 |
34 | # Android Studio Navigation editor temp files
35 | .navigation/
36 |
37 | # Android Studio captures folder
38 | captures/
39 |
40 | # IntelliJ
41 | *.iml
42 | .idea/workspace.xml
43 | .idea/tasks.xml
44 | .idea/gradle.xml
45 | .idea/assetWizardSettings.xml
46 | .idea/dictionaries
47 | .idea/libraries
48 | .idea/caches
49 |
50 | # Keystore files
51 | # Uncomment the following lines if you do not want to check your keystore files in.
52 | *.jks
53 | *.keystore
54 |
55 | # External native build folder generated in Android Studio 2.2 and later
56 | .externalNativeBuild
57 |
58 | # Google Services (e.g. APIs or Firebase)
59 | # google-services.json
60 |
61 | # Freeline
62 | freeline.py
63 | freeline/
64 | freeline_project_description.json
65 |
66 | # fastlane
67 | fastlane/report.xml
68 | fastlane/Preview.html
69 | fastlane/screenshots
70 | fastlane/test_output
71 | fastlane/readme.md
72 |
73 | # Version control
74 | vcs.xml
75 |
76 | # lint
77 | lint/intermediates/
78 | lint/generated/
79 | lint/outputs/
80 | lint/tmp/
81 | # lint/reports/
82 |
83 | gic_android/.idea/caches/
84 | gic_android/.idea/gradle.xml
85 | gic_android/.idea/libraries/
86 | gic_android/.idea/modules.xml
87 | gic_android/.idea/workspace.xml
88 | gic_flutter/android/key.properties
89 | gic_flutter/ios/Flutter/flutter_export_environment.sh
90 | gic_flutter/android/.settings/org.eclipse.buildship.core.prefs
91 | gic_flutter/android/app/.classpath
92 | gic_flutter/android/app/.settings/org.eclipse.buildship.core.prefs
93 | .idea/encodings.xml
94 | .idea/misc.xml
95 | .idea/codeStyles/Project.xml
96 | gic_flutter/.flutter-plugins-dependencies
97 | /xgesture_flutter/.dart_tool/package_config.json
98 | /xgesture_flutter/.dart_tool/package_config_subset
99 | /xgesture_flutter/.dart_tool/version
100 | /xgesture_flutter/.dart_tool/extension_discovery/vs_code.json
101 | /.idea/other.xml
102 |
--------------------------------------------------------------------------------
/.idea/.gitignore:
--------------------------------------------------------------------------------
1 | # Default ignored files
2 | /shelf/
3 | /workspace.xml
4 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | os:
2 | - linux
3 | sudo: false
4 | addons:
5 | apt:
6 | sources:
7 | - ubuntu-toolchain-r-test
8 | packages:
9 | - libstdc++6
10 | - fonts-noto
11 | git:
12 | depth: 3
13 | env:
14 | - FLUTTER_VERSION=stable
15 | - FLUTTER_VERSION=beta
16 | matrix:
17 | allow_failures:
18 | - env: FLUTTER_VERSION=beta
19 | before_script:
20 | - git clone https://github.com/flutter/flutter.git -b $FLUTTER_VERSION
21 | - ./flutter/bin/flutter doctor
22 | - chmod +x travis_script.sh
23 | script:
24 | - ./travis_script.sh
25 | cache:
26 | directories:
27 | - $HOME/shared/.pub-cache
28 | # notifications:
29 | # email:
30 | # brogdon+github@gmail.com
31 |
32 | # Only building master means that we don't run two builds for each pull request.
33 | branches:
34 | only: [master]
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 | # language: generic
48 | # dist: xenial
49 | # addons:
50 | # apt:
51 | # packages:
52 | # - lib32stdc++6
53 | # env:
54 | # global:
55 | # - FLUTTER_CHANNEL=stable
56 | # before_install:
57 | # cd gic_flutter
58 | # install:
59 | # - git clone https://github.com/flutter/flutter.git -b $FLUTTER_CHANNEL
60 | # - export PATH="$PATH:`pwd`/flutter/bin/cache/dart-sdk/bin"
61 | # - export PATH="$PATH:`pwd`/flutter/bin"
62 | # - flutter doctor -v
63 | # - flutter packages get
64 | # cache:
65 | # directories:
66 | # - $HOME/.pub-cache
67 |
--------------------------------------------------------------------------------
/.vscode/launch.json:
--------------------------------------------------------------------------------
1 | {
2 | // Use IntelliSense to learn about possible attributes.
3 | // Hover to view descriptions of existing attributes.
4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
5 | "version": "0.2.0",
6 | "configurations": [
7 | {
8 | "name": "Flutter Other",
9 | "program": "gic_flutter/lib/main_other.dart",
10 | "request": "launch",
11 | "type": "dart",
12 | "args": [
13 | "--flavor",
14 | "other"
15 | ]
16 | },
17 | {
18 | "name": "Flutter GPlay",
19 | "program": "gic_flutter/lib/main_gplay.dart",
20 | "request": "launch",
21 | "type": "dart",
22 | "args": [
23 | "--flavor",
24 | "gplay"
25 | ]
26 | }
27 | ]
28 | }
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | [](https://codemagic.io/apps/5df31599c3cc4f70a402350d/6501db48531b66edd968d29a/latest_build)
2 | # Gaming Interface Client (Android)
3 |
4 | Android client for the Gaming Interface Client
5 |
6 | **Download Android Files Here https://github.com/Terence-D/GamingInterfaceClientAndroid/releases**
7 |
8 | This is part of a two app system that allows the use of a remote device (Tablet or Phone) to provide input into a PC game or application. This software is the Android Client and runs on your Tablet or Phone. It talks to the GICServer - https://github.com/Terence-D/GameInputCommandServer For example if you play a space simulator, you can add custom buttons for Comms, Warp Drive, Power control, etc and have it accessible at your fingertips without remembering complex keystrokes.
9 |
10 | ## Features
11 | * Open Source and Free!
12 | * Completely customizable - build the layout YOU want
13 | * Supports multiple devices connecting to the server. Use one Tablet for your ship Systems, another for Comms!
14 | * Runs on Phones or Tablets
15 | * Supports practically any game
16 | * More features to be worked on!
17 |
18 | Check the Wiki here https://github.com/Terence-D/GamingInterfaceClientAndroid/wiki for more information. Any issues please add to the Issue tracker, or contact me at support [ a]t coffeeshopstudio.ca
19 |
20 | ## Help
21 | Help with testing or donations is always appreciated, donation links are on the right hand side!
22 |
23 | ## New Planned Features
24 | iOS and more! https://github.com/Terence-D/GamingInterfaceClientAndroid/labels/enhancement
25 |
--------------------------------------------------------------------------------
/gic_flutter/.gitignore:
--------------------------------------------------------------------------------
1 | # Miscellaneous
2 | *.class
3 | *.log
4 | *.pyc
5 | *.swp
6 | .DS_Store
7 | .atom/
8 | .buildlog/
9 | .history
10 | .svn/
11 |
12 | # IntelliJ related
13 | *.iml
14 | *.ipr
15 | *.iws
16 | .idea/
17 |
18 | # Visual Studio Code related
19 | .vscode/
20 |
21 | # Flutter/Dart/Pub related
22 | **/doc/api/
23 | .dart_tool/
24 | .flutter-plugins
25 | .packages
26 | .pub-cache/
27 | .pub/
28 | /build/
29 |
30 | # Android related
31 | **/android/**/gradle-wrapper.jar
32 | **/android/.gradle
33 | **/android/captures/
34 | **/android/gradlew
35 | **/android/gradlew.bat
36 | **/android/local.properties
37 | **/android/**/GeneratedPluginRegistrant.java
38 |
39 | # iOS/XCode related
40 | **/ios/**/*.mode1v3
41 | **/ios/**/*.mode2v3
42 | **/ios/**/*.moved-aside
43 | **/ios/**/*.pbxuser
44 | **/ios/**/*.perspectivev3
45 | **/ios/**/*sync/
46 | **/ios/**/.sconsign.dblite
47 | **/ios/**/.tags*
48 | **/ios/**/.vagrant/
49 | **/ios/**/DerivedData/
50 | **/ios/**/Icon?
51 | **/ios/**/Pods/
52 | **/ios/**/.symlinks/
53 | **/ios/**/profile
54 | **/ios/**/xcuserdata
55 | **/ios/.generated/
56 | **/ios/Flutter/App.framework
57 | **/ios/Flutter/Flutter.framework
58 | **/ios/Flutter/Generated.xcconfig
59 | **/ios/Flutter/app.flx
60 | **/ios/Flutter/app.zip
61 | **/ios/Flutter/flutter_assets/
62 | **/ios/ServiceDefinitions.json
63 | **/ios/Runner/GeneratedPluginRegistrant.*
64 |
65 | # Exceptions to above rules.
66 | !**/ios/**/default.mode1v3
67 | !**/ios/**/default.mode2v3
68 | !**/ios/**/default.pbxuser
69 | !**/ios/**/default.perspectivev3
70 | !/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages
71 | /android/settings_aar.gradle
72 | android/key.properties
--------------------------------------------------------------------------------
/gic_flutter/.metadata:
--------------------------------------------------------------------------------
1 | # This file tracks properties of this Flutter project.
2 | # Used by Flutter tool to assess capabilities and perform upgrades etc.
3 | #
4 | # This file should be version controlled and should not be manually edited.
5 |
6 | version:
7 | revision: 7a4c33425ddd78c54aba07d86f3f9a4a0051769b
8 | channel: stable
9 |
10 | project_type: app
11 |
--------------------------------------------------------------------------------
/gic_flutter/.run/Flutter Dev.run.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/gic_flutter/README.md:
--------------------------------------------------------------------------------
1 | # gic_flutter
2 |
3 | Gaming Interface Client
4 |
5 | ## Getting Started
6 |
7 | This project is a starting point for a Flutter application.
8 |
9 | A few resources to get you started if this is your first Flutter project:
10 |
11 | - [Lab: Write your first Flutter app](https://flutter.dev/docs/get-started/codelab)
12 | - [Cookbook: Useful Flutter samples](https://flutter.dev/docs/cookbook)
13 |
14 | For help getting started with Flutter, view our
15 | [online documentation](https://flutter.dev/docs), which offers tutorials,
16 | samples, guidance on mobile development, and a full API reference.
17 |
--------------------------------------------------------------------------------
/gic_flutter/analysis_options.yaml:
--------------------------------------------------------------------------------
1 | include: package:pedantic/analysis_options.1.8.0.yaml
2 |
3 | linter:
4 | rules:
5 | - unawaited_futures
--------------------------------------------------------------------------------
/gic_flutter/android/.gitignore:
--------------------------------------------------------------------------------
1 | gradle-wrapper.jar
2 | /.gradle
3 | /captures/
4 | /gradlew
5 | /gradlew.bat
6 | /local.properties
7 | GeneratedPluginRegistrant.java
8 |
9 | # Remember to never publicly share your keystore.
10 | # See https://flutter.dev/docs/deployment/android#reference-the-keystore-from-the-app
11 | key.properties
12 |
--------------------------------------------------------------------------------
/gic_flutter/android/.project:
--------------------------------------------------------------------------------
1 |
2 |
3 | android
4 | Project android created by Buildship.
5 |
6 |
7 |
8 |
9 | org.eclipse.buildship.core.gradleprojectbuilder
10 |
11 |
12 |
13 |
14 |
15 | org.eclipse.buildship.core.gradleprojectnature
16 |
17 |
18 |
--------------------------------------------------------------------------------
/gic_flutter/android/app/.project:
--------------------------------------------------------------------------------
1 |
2 |
3 | app
4 | Project app created by Buildship.
5 |
6 |
7 |
8 |
9 | org.eclipse.jdt.core.javabuilder
10 |
11 |
12 |
13 |
14 | org.eclipse.buildship.core.gradleprojectbuilder
15 |
16 |
17 |
18 |
19 |
20 | org.eclipse.jdt.core.javanature
21 | org.eclipse.buildship.core.gradleprojectnature
22 |
23 |
24 |
--------------------------------------------------------------------------------
/gic_flutter/android/app/build.gradle:
--------------------------------------------------------------------------------
1 | def localProperties = new Properties()
2 | def localPropertiesFile = rootProject.file('local.properties')
3 | if (localPropertiesFile.exists()) {
4 | localPropertiesFile.withReader('UTF-8') { reader ->
5 | localProperties.load(reader)
6 | }
7 | }
8 |
9 | def flutterRoot = localProperties.getProperty('flutter.sdk')
10 | if (flutterRoot == null) {
11 | throw new Exception("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.")
12 | }
13 |
14 | def flutterVersionCode = localProperties.getProperty('flutter.versionCode')
15 | if (flutterVersionCode == null) {
16 | flutterVersionCode = '1'
17 | }
18 |
19 | def flutterVersionName = localProperties.getProperty('flutter.versionName')
20 | if (flutterVersionName == null) {
21 | flutterVersionName = '1.0'
22 | }
23 |
24 | def keystoreProperties = new Properties()
25 | def keystorePropertiesFile = rootProject.file('key.properties')
26 | if (keystorePropertiesFile.exists()) {
27 | keystoreProperties.load(new FileInputStream(keystorePropertiesFile))
28 | }
29 |
30 | apply plugin: 'com.android.application'
31 | apply plugin: 'kotlin-android'
32 | apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
33 |
34 | android {
35 | flavorDimensions "version"
36 | compileSdk = flutter.compileSdkVersion
37 |
38 | sourceSets {
39 | main.java.srcDirs += 'src/main/kotlin'
40 | }
41 |
42 | lintOptions {
43 | disable 'InvalidPackage'
44 | checkReleaseBuilds false
45 | }
46 |
47 | defaultConfig {
48 | applicationId "ca.coffeeshopstudio.gaminginterfaceclient"
49 | minSdk = flutter.minSdkVersion
50 | targetSdk = 35 //flutter.targetSdkVersion
51 | versionCode flutterVersionCode.toInteger()
52 | versionName flutterVersionName
53 | multiDexEnabled true
54 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
55 | }
56 |
57 | productFlavors {
58 | gplay {
59 | }
60 |
61 | other {
62 | applicationId "ca.coffeeshopstudio.gaminginterfaceclient.internal"
63 | }
64 | }
65 |
66 | signingConfigs {
67 | release {
68 | keyAlias keystoreProperties['keyAlias']
69 | keyPassword keystoreProperties['keyPassword']
70 | storeFile file(keystoreProperties['storeFile'])
71 | storePassword keystoreProperties['storePassword']
72 | }
73 | debug {}
74 | }
75 |
76 | buildTypes {
77 | release {
78 | signingConfig signingConfigs.release
79 | minifyEnabled false
80 | shrinkResources false
81 | //useProguard true
82 | //proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
83 | }
84 | debug {
85 | signingConfig signingConfigs.debug
86 | }
87 | }
88 | }
89 |
90 | flutter {
91 | source '../..'
92 | }
93 |
94 | dependencies {
95 | implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:2.0.20"
96 | }
97 |
--------------------------------------------------------------------------------
/gic_flutter/android/app/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # You can control the set of applied configuration files using the
3 | # proguardFiles setting in build.gradle.
4 | #
5 | # For more details, see
6 | # http://developer.android.com/guide/developing/tools/proguard.html
7 |
8 | # If your project uses WebView with JS, uncomment the following
9 | # and specify the fully qualified class name to the JavaScript interface
10 | # class:
11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
12 | # public *;
13 | #}
14 |
15 | # Uncomment this to preserve the line number information for
16 | # debugging stack traces.
17 | #-keepattributes SourceFile,LineNumberTable
18 |
19 | # If you keep the line number information, uncomment this to
20 | # hide the original source file name.
21 | #-renamesourcefileattribute SourceFile
22 |
23 | ## Flutter wrapper
24 | -keep class io.flutter.app.** { *; }
25 | -keep class io.flutter.plugin.** { *; }
26 | -keep class io.flutter.util.** { *; }
27 | -keep class io.flutter.view.** { *; }
28 | -keep class io.flutter.** { *; }
29 | -keep class io.flutter.plugins.** { *; }
--------------------------------------------------------------------------------
/gic_flutter/android/app/src/debug/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/gic_flutter/android/app/src/debug/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | GIC-Int
3 |
4 | GIC-Int
5 |
6 |
--------------------------------------------------------------------------------
/gic_flutter/android/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
26 |
34 |
35 |
36 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
51 |
52 |
53 |
--------------------------------------------------------------------------------
/gic_flutter/android/app/src/main/ic_launcher-web.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Terence-D/GamingInterfaceClientAndroid/f71658c54f0c485e5c2791674ea53c2e271af6e3/gic_flutter/android/app/src/main/ic_launcher-web.png
--------------------------------------------------------------------------------
/gic_flutter/android/app/src/main/kotlin/ca/coffeeshopstudio/gaminginterfaceclient/MainActivity.kt:
--------------------------------------------------------------------------------
1 | package ca.coffeeshopstudio.gaminginterfaceclient
2 |
3 | import io.flutter.embedding.android.FlutterActivity
4 | class MainActivity: FlutterActivity() {
5 |
6 | }
7 |
--------------------------------------------------------------------------------
/gic_flutter/android/app/src/main/res/drawable/ic_arrow_back_white_24dp.xml:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/gic_flutter/android/app/src/main/res/drawable/launch_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | -
7 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/gic_flutter/android/app/src/main/res/drawable/launch_image.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Terence-D/GamingInterfaceClientAndroid/f71658c54f0c485e5c2791674ea53c2e271af6e3/gic_flutter/android/app/src/main/res/drawable/launch_image.png
--------------------------------------------------------------------------------
/gic_flutter/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/gic_flutter/android/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Terence-D/GamingInterfaceClientAndroid/f71658c54f0c485e5c2791674ea53c2e271af6e3/gic_flutter/android/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/gic_flutter/android/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Terence-D/GamingInterfaceClientAndroid/f71658c54f0c485e5c2791674ea53c2e271af6e3/gic_flutter/android/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png
--------------------------------------------------------------------------------
/gic_flutter/android/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Terence-D/GamingInterfaceClientAndroid/f71658c54f0c485e5c2791674ea53c2e271af6e3/gic_flutter/android/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/gic_flutter/android/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Terence-D/GamingInterfaceClientAndroid/f71658c54f0c485e5c2791674ea53c2e271af6e3/gic_flutter/android/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png
--------------------------------------------------------------------------------
/gic_flutter/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Terence-D/GamingInterfaceClientAndroid/f71658c54f0c485e5c2791674ea53c2e271af6e3/gic_flutter/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/gic_flutter/android/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Terence-D/GamingInterfaceClientAndroid/f71658c54f0c485e5c2791674ea53c2e271af6e3/gic_flutter/android/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png
--------------------------------------------------------------------------------
/gic_flutter/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Terence-D/GamingInterfaceClientAndroid/f71658c54f0c485e5c2791674ea53c2e271af6e3/gic_flutter/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/gic_flutter/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Terence-D/GamingInterfaceClientAndroid/f71658c54f0c485e5c2791674ea53c2e271af6e3/gic_flutter/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png
--------------------------------------------------------------------------------
/gic_flutter/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Terence-D/GamingInterfaceClientAndroid/f71658c54f0c485e5c2791674ea53c2e271af6e3/gic_flutter/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/gic_flutter/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Terence-D/GamingInterfaceClientAndroid/f71658c54f0c485e5c2791674ea53c2e271af6e3/gic_flutter/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png
--------------------------------------------------------------------------------
/gic_flutter/android/app/src/main/res/values-sw720dp/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 32dp
4 | 64dp
5 | 64dp
6 | 64sp
7 |
--------------------------------------------------------------------------------
/gic_flutter/android/app/src/main/res/values-v21/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
8 |
--------------------------------------------------------------------------------
/gic_flutter/android/app/src/main/res/values/attrs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/gic_flutter/android/app/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #3F51B5
4 | #2A41B3
5 | #43a047
6 | #F44336
7 |
8 | #66000000
9 | #FF383838
10 | #A1F8F8F8
11 |
12 | #33343B
13 | #8033343B
14 | #33343B
15 |
16 | #5160B6
17 |
18 |
--------------------------------------------------------------------------------
/gic_flutter/android/app/src/main/res/values/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 16dp
4 | 16dp
5 | 16dp
6 | 16dp
7 | 32sp
8 | 320dp
9 | 92dp
10 |
--------------------------------------------------------------------------------
/gic_flutter/android/app/src/main/res/values/ic_launcher_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #4C5DBA
4 |
--------------------------------------------------------------------------------
/gic_flutter/android/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | Gaming Interface Client
3 |
4 | Gaming Interface Client
5 |
6 |
--------------------------------------------------------------------------------
/gic_flutter/android/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
9 |
10 |
11 |
13 |
14 |
15 |
21 |
22 |
29 |
30 |
33 |
34 |
35 |
36 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
53 |
54 |
58 |
59 |
62 |
63 |
--------------------------------------------------------------------------------
/gic_flutter/android/app/src/profile/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/gic_flutter/android/app/web_hi_res_512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Terence-D/GamingInterfaceClientAndroid/f71658c54f0c485e5c2791674ea53c2e271af6e3/gic_flutter/android/app/web_hi_res_512.png
--------------------------------------------------------------------------------
/gic_flutter/android/build.gradle:
--------------------------------------------------------------------------------
1 | buildscript {
2 | repositories {
3 | google()
4 | mavenCentral()
5 | }
6 |
7 | dependencies {
8 | classpath 'com.android.tools.build:gradle:7.3.1'
9 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:2.0.20"
10 | }
11 | }
12 |
13 | allprojects {
14 | repositories {
15 | google()
16 | mavenCentral()
17 | maven { url 'https://jitpack.io' }
18 | }
19 | }
20 |
21 | rootProject.buildDir = '../build'
22 | subprojects {
23 | project.buildDir = "${rootProject.buildDir}/${project.name}"
24 | }
25 | subprojects {
26 | project.evaluationDependsOn(':app')
27 | }
28 |
29 | tasks.register("clean", Delete) {
30 | delete rootProject.buildDir
31 | }
32 |
--------------------------------------------------------------------------------
/gic_flutter/android/gradle.properties:
--------------------------------------------------------------------------------
1 | android.enableJetifier=true
2 | android.useAndroidX=true
3 | org.gradle.jvmargs=-Xmx1024M
4 | android.enableR8=true
5 |
--------------------------------------------------------------------------------
/gic_flutter/android/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Mon Dec 07 16:27:57 MST 2020
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-all.zip
7 |
--------------------------------------------------------------------------------
/gic_flutter/android/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':app'
2 |
3 | def flutterProjectRoot = rootProject.projectDir.parentFile.toPath()
4 |
5 | def plugins = new Properties()
6 | def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins')
7 | if (pluginsFile.exists()) {
8 | pluginsFile.withReader('UTF-8') { reader -> plugins.load(reader) }
9 | }
10 |
11 | plugins.each { name, path ->
12 | def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile()
13 | include ":$name"
14 | project(":$name").projectDir = pluginDirectory
15 | }
16 |
--------------------------------------------------------------------------------
/gic_flutter/assets/audio/flick.wav:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Terence-D/GamingInterfaceClientAndroid/f71658c54f0c485e5c2791674ea53c2e271af6e3/gic_flutter/assets/audio/flick.wav
--------------------------------------------------------------------------------
/gic_flutter/assets/fonts/Lobster-Regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Terence-D/GamingInterfaceClientAndroid/f71658c54f0c485e5c2791674ea53c2e271af6e3/gic_flutter/assets/fonts/Lobster-Regular.ttf
--------------------------------------------------------------------------------
/gic_flutter/assets/fonts/Nunito-Regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Terence-D/GamingInterfaceClientAndroid/f71658c54f0c485e5c2791674ea53c2e271af6e3/gic_flutter/assets/fonts/Nunito-Regular.ttf
--------------------------------------------------------------------------------
/gic_flutter/assets/fonts/OFL.txt:
--------------------------------------------------------------------------------
1 | Copyright 2010 The Lobster Project Authors (https://github.com/impallari/The-Lobster-Font), with Reserved Font Name "Lobster".
2 |
3 | This Font Software is licensed under the SIL Open Font License, Version 1.1.
4 | This license is copied below, and is also available with a FAQ at:
5 | http://scripts.sil.org/OFL
6 |
7 |
8 | -----------------------------------------------------------
9 | SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
10 | -----------------------------------------------------------
11 |
12 | PREAMBLE
13 | The goals of the Open Font License (OFL) are to stimulate worldwide
14 | development of collaborative font projects, to support the font creation
15 | efforts of academic and linguistic communities, and to provide a free and
16 | open framework in which fonts may be shared and improved in partnership
17 | with others.
18 |
19 | The OFL allows the licensed fonts to be used, studied, modified and
20 | redistributed freely as long as they are not sold by themselves. The
21 | fonts, including any derivative works, can be bundled, embedded,
22 | redistributed and/or sold with any software provided that any reserved
23 | names are not used by derivative works. The fonts and derivatives,
24 | however, cannot be released under any other type of license. The
25 | requirement for fonts to remain under this license does not apply
26 | to any document created using the fonts or their derivatives.
27 |
28 | DEFINITIONS
29 | "Font Software" refers to the set of files released by the Copyright
30 | Holder(s) under this license and clearly marked as such. This may
31 | include source files, build scripts and documentation.
32 |
33 | "Reserved Font Name" refers to any names specified as such after the
34 | copyright statement(s).
35 |
36 | "Original Version" refers to the collection of Font Software components as
37 | distributed by the Copyright Holder(s).
38 |
39 | "Modified Version" refers to any derivative made by adding to, deleting,
40 | or substituting -- in part or in whole -- any of the components of the
41 | Original Version, by changing formats or by porting the Font Software to a
42 | new environment.
43 |
44 | "Author" refers to any designer, engineer, programmer, technical
45 | writer or other person who contributed to the Font Software.
46 |
47 | PERMISSION & CONDITIONS
48 | Permission is hereby granted, free of charge, to any person obtaining
49 | a copy of the Font Software, to use, study, copy, merge, embed, modify,
50 | redistribute, and sell modified and unmodified copies of the Font
51 | Software, subject to the following conditions:
52 |
53 | 1) Neither the Font Software nor any of its individual components,
54 | in Original or Modified Versions, may be sold by itself.
55 |
56 | 2) Original or Modified Versions of the Font Software may be bundled,
57 | redistributed and/or sold with any software, provided that each copy
58 | contains the above copyright notice and this license. These can be
59 | included either as stand-alone text files, human-readable headers or
60 | in the appropriate machine-readable metadata fields within text or
61 | binary files as long as those fields can be easily viewed by the user.
62 |
63 | 3) No Modified Version of the Font Software may use the Reserved Font
64 | Name(s) unless explicit written permission is granted by the corresponding
65 | Copyright Holder. This restriction only applies to the primary font name as
66 | presented to the users.
67 |
68 | 4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
69 | Software shall not be used to promote, endorse or advertise any
70 | Modified Version, except to acknowledge the contribution(s) of the
71 | Copyright Holder(s) and the Author(s) or with their explicit written
72 | permission.
73 |
74 | 5) The Font Software, modified or unmodified, in part or in whole,
75 | must be distributed entirely under this license, and must not be
76 | distributed under any other license. The requirement for fonts to
77 | remain under this license does not apply to any document created
78 | using the Font Software.
79 |
80 | TERMINATION
81 | This license becomes null and void if any of the above conditions are
82 | not met.
83 |
84 | DISCLAIMER
85 | THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
86 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
87 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
88 | OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
89 | COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
90 | INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
91 | DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
92 | FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
93 | OTHER DEALINGS IN THE FONT SOFTWARE.
94 |
--------------------------------------------------------------------------------
/gic_flutter/assets/fonts/Righteous-Regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Terence-D/GamingInterfaceClientAndroid/f71658c54f0c485e5c2791674ea53c2e271af6e3/gic_flutter/assets/fonts/Righteous-Regular.ttf
--------------------------------------------------------------------------------
/gic_flutter/assets/fonts/ShareTech-Regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Terence-D/GamingInterfaceClientAndroid/f71658c54f0c485e5c2791674ea53c2e271af6e3/gic_flutter/assets/fonts/ShareTech-Regular.ttf
--------------------------------------------------------------------------------
/gic_flutter/assets/images/controls/button_black.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Terence-D/GamingInterfaceClientAndroid/f71658c54f0c485e5c2791674ea53c2e271af6e3/gic_flutter/assets/images/controls/button_black.png
--------------------------------------------------------------------------------
/gic_flutter/assets/images/controls/button_black2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Terence-D/GamingInterfaceClientAndroid/f71658c54f0c485e5c2791674ea53c2e271af6e3/gic_flutter/assets/images/controls/button_black2.png
--------------------------------------------------------------------------------
/gic_flutter/assets/images/controls/button_black2_dark.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Terence-D/GamingInterfaceClientAndroid/f71658c54f0c485e5c2791674ea53c2e271af6e3/gic_flutter/assets/images/controls/button_black2_dark.png
--------------------------------------------------------------------------------
/gic_flutter/assets/images/controls/button_black_dark.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Terence-D/GamingInterfaceClientAndroid/f71658c54f0c485e5c2791674ea53c2e271af6e3/gic_flutter/assets/images/controls/button_black_dark.png
--------------------------------------------------------------------------------
/gic_flutter/assets/images/controls/button_blue.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Terence-D/GamingInterfaceClientAndroid/f71658c54f0c485e5c2791674ea53c2e271af6e3/gic_flutter/assets/images/controls/button_blue.png
--------------------------------------------------------------------------------
/gic_flutter/assets/images/controls/button_blue2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Terence-D/GamingInterfaceClientAndroid/f71658c54f0c485e5c2791674ea53c2e271af6e3/gic_flutter/assets/images/controls/button_blue2.png
--------------------------------------------------------------------------------
/gic_flutter/assets/images/controls/button_blue2_dark.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Terence-D/GamingInterfaceClientAndroid/f71658c54f0c485e5c2791674ea53c2e271af6e3/gic_flutter/assets/images/controls/button_blue2_dark.png
--------------------------------------------------------------------------------
/gic_flutter/assets/images/controls/button_blue_dark.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Terence-D/GamingInterfaceClientAndroid/f71658c54f0c485e5c2791674ea53c2e271af6e3/gic_flutter/assets/images/controls/button_blue_dark.png
--------------------------------------------------------------------------------
/gic_flutter/assets/images/controls/button_green.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Terence-D/GamingInterfaceClientAndroid/f71658c54f0c485e5c2791674ea53c2e271af6e3/gic_flutter/assets/images/controls/button_green.png
--------------------------------------------------------------------------------
/gic_flutter/assets/images/controls/button_green2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Terence-D/GamingInterfaceClientAndroid/f71658c54f0c485e5c2791674ea53c2e271af6e3/gic_flutter/assets/images/controls/button_green2.png
--------------------------------------------------------------------------------
/gic_flutter/assets/images/controls/button_green2_dark.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Terence-D/GamingInterfaceClientAndroid/f71658c54f0c485e5c2791674ea53c2e271af6e3/gic_flutter/assets/images/controls/button_green2_dark.png
--------------------------------------------------------------------------------
/gic_flutter/assets/images/controls/button_green_dark.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Terence-D/GamingInterfaceClientAndroid/f71658c54f0c485e5c2791674ea53c2e271af6e3/gic_flutter/assets/images/controls/button_green_dark.png
--------------------------------------------------------------------------------
/gic_flutter/assets/images/controls/button_grey.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Terence-D/GamingInterfaceClientAndroid/f71658c54f0c485e5c2791674ea53c2e271af6e3/gic_flutter/assets/images/controls/button_grey.png
--------------------------------------------------------------------------------
/gic_flutter/assets/images/controls/button_grey2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Terence-D/GamingInterfaceClientAndroid/f71658c54f0c485e5c2791674ea53c2e271af6e3/gic_flutter/assets/images/controls/button_grey2.png
--------------------------------------------------------------------------------
/gic_flutter/assets/images/controls/button_grey2_dark.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Terence-D/GamingInterfaceClientAndroid/f71658c54f0c485e5c2791674ea53c2e271af6e3/gic_flutter/assets/images/controls/button_grey2_dark.png
--------------------------------------------------------------------------------
/gic_flutter/assets/images/controls/button_grey_dark.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Terence-D/GamingInterfaceClientAndroid/f71658c54f0c485e5c2791674ea53c2e271af6e3/gic_flutter/assets/images/controls/button_grey_dark.png
--------------------------------------------------------------------------------
/gic_flutter/assets/images/controls/button_neon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Terence-D/GamingInterfaceClientAndroid/f71658c54f0c485e5c2791674ea53c2e271af6e3/gic_flutter/assets/images/controls/button_neon.png
--------------------------------------------------------------------------------
/gic_flutter/assets/images/controls/button_neon_dark.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Terence-D/GamingInterfaceClientAndroid/f71658c54f0c485e5c2791674ea53c2e271af6e3/gic_flutter/assets/images/controls/button_neon_dark.png
--------------------------------------------------------------------------------
/gic_flutter/assets/images/controls/button_purple.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Terence-D/GamingInterfaceClientAndroid/f71658c54f0c485e5c2791674ea53c2e271af6e3/gic_flutter/assets/images/controls/button_purple.png
--------------------------------------------------------------------------------
/gic_flutter/assets/images/controls/button_purple_dark.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Terence-D/GamingInterfaceClientAndroid/f71658c54f0c485e5c2791674ea53c2e271af6e3/gic_flutter/assets/images/controls/button_purple_dark.png
--------------------------------------------------------------------------------
/gic_flutter/assets/images/controls/button_red.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Terence-D/GamingInterfaceClientAndroid/f71658c54f0c485e5c2791674ea53c2e271af6e3/gic_flutter/assets/images/controls/button_red.png
--------------------------------------------------------------------------------
/gic_flutter/assets/images/controls/button_red2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Terence-D/GamingInterfaceClientAndroid/f71658c54f0c485e5c2791674ea53c2e271af6e3/gic_flutter/assets/images/controls/button_red2.png
--------------------------------------------------------------------------------
/gic_flutter/assets/images/controls/button_red2_dark.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Terence-D/GamingInterfaceClientAndroid/f71658c54f0c485e5c2791674ea53c2e271af6e3/gic_flutter/assets/images/controls/button_red2_dark.png
--------------------------------------------------------------------------------
/gic_flutter/assets/images/controls/button_red_dark.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Terence-D/GamingInterfaceClientAndroid/f71658c54f0c485e5c2791674ea53c2e271af6e3/gic_flutter/assets/images/controls/button_red_dark.png
--------------------------------------------------------------------------------
/gic_flutter/assets/images/controls/button_toggle_off.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Terence-D/GamingInterfaceClientAndroid/f71658c54f0c485e5c2791674ea53c2e271af6e3/gic_flutter/assets/images/controls/button_toggle_off.png
--------------------------------------------------------------------------------
/gic_flutter/assets/images/controls/button_toggle_on.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Terence-D/GamingInterfaceClientAndroid/f71658c54f0c485e5c2791674ea53c2e271af6e3/gic_flutter/assets/images/controls/button_toggle_on.png
--------------------------------------------------------------------------------
/gic_flutter/assets/images/controls/button_white.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Terence-D/GamingInterfaceClientAndroid/f71658c54f0c485e5c2791674ea53c2e271af6e3/gic_flutter/assets/images/controls/button_white.png
--------------------------------------------------------------------------------
/gic_flutter/assets/images/controls/button_white_dark.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Terence-D/GamingInterfaceClientAndroid/f71658c54f0c485e5c2791674ea53c2e271af6e3/gic_flutter/assets/images/controls/button_white_dark.png
--------------------------------------------------------------------------------
/gic_flutter/assets/images/controls/button_yellow.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Terence-D/GamingInterfaceClientAndroid/f71658c54f0c485e5c2791674ea53c2e271af6e3/gic_flutter/assets/images/controls/button_yellow.png
--------------------------------------------------------------------------------
/gic_flutter/assets/images/controls/button_yellow_dark.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Terence-D/GamingInterfaceClientAndroid/f71658c54f0c485e5c2791674ea53c2e271af6e3/gic_flutter/assets/images/controls/button_yellow_dark.png
--------------------------------------------------------------------------------
/gic_flutter/assets/images/controls/lever_off.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Terence-D/GamingInterfaceClientAndroid/f71658c54f0c485e5c2791674ea53c2e271af6e3/gic_flutter/assets/images/controls/lever_off.png
--------------------------------------------------------------------------------
/gic_flutter/assets/images/controls/lever_on.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Terence-D/GamingInterfaceClientAndroid/f71658c54f0c485e5c2791674ea53c2e271af6e3/gic_flutter/assets/images/controls/lever_on.png
--------------------------------------------------------------------------------
/gic_flutter/assets/images/controls/switch_off.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Terence-D/GamingInterfaceClientAndroid/f71658c54f0c485e5c2791674ea53c2e271af6e3/gic_flutter/assets/images/controls/switch_off.png
--------------------------------------------------------------------------------
/gic_flutter/assets/images/controls/switch_on.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Terence-D/GamingInterfaceClientAndroid/f71658c54f0c485e5c2791674ea53c2e271af6e3/gic_flutter/assets/images/controls/switch_on.png
--------------------------------------------------------------------------------
/gic_flutter/assets/images/controls/toggle_off.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Terence-D/GamingInterfaceClientAndroid/f71658c54f0c485e5c2791674ea53c2e271af6e3/gic_flutter/assets/images/controls/toggle_off.png
--------------------------------------------------------------------------------
/gic_flutter/assets/images/controls/toggle_on.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Terence-D/GamingInterfaceClientAndroid/f71658c54f0c485e5c2791674ea53c2e271af6e3/gic_flutter/assets/images/controls/toggle_on.png
--------------------------------------------------------------------------------
/gic_flutter/assets/images/icons/app_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Terence-D/GamingInterfaceClientAndroid/f71658c54f0c485e5c2791674ea53c2e271af6e3/gic_flutter/assets/images/icons/app_icon.png
--------------------------------------------------------------------------------
/gic_flutter/ios/.gitignore:
--------------------------------------------------------------------------------
1 | *.mode1v3
2 | *.mode2v3
3 | *.moved-aside
4 | *.pbxuser
5 | *.perspectivev3
6 | **/*sync/
7 | .sconsign.dblite
8 | .tags*
9 | **/.vagrant/
10 | **/DerivedData/
11 | Icon?
12 | **/Pods/
13 | **/.symlinks/
14 | profile
15 | xcuserdata
16 | **/.generated/
17 | Flutter/App.framework
18 | Flutter/Flutter.framework
19 | Flutter/Flutter.podspec
20 | Flutter/Generated.xcconfig
21 | Flutter/app.flx
22 | Flutter/app.zip
23 | Flutter/flutter_assets/
24 | Flutter/flutter_export_environment.sh
25 | ServiceDefinitions.json
26 | Runner/GeneratedPluginRegistrant.*
27 |
28 | # Exceptions to above rules.
29 | !default.mode1v3
30 | !default.mode2v3
31 | !default.pbxuser
32 | !default.perspectivev3
33 |
--------------------------------------------------------------------------------
/gic_flutter/ios/Flutter/AppFrameworkInfo.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleExecutable
8 | App
9 | CFBundleIdentifier
10 | io.flutter.flutter.app
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | App
15 | CFBundlePackageType
16 | FMWK
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1.0
23 | MinimumOSVersion
24 | 8.0
25 |
26 |
27 |
--------------------------------------------------------------------------------
/gic_flutter/ios/Flutter/Debug.xcconfig:
--------------------------------------------------------------------------------
1 | #include "Generated.xcconfig"
2 |
--------------------------------------------------------------------------------
/gic_flutter/ios/Flutter/Release.xcconfig:
--------------------------------------------------------------------------------
1 | #include "Generated.xcconfig"
2 |
--------------------------------------------------------------------------------
/gic_flutter/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/gic_flutter/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/gic_flutter/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | PreviewsEnabled
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/gic_flutter/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
32 |
33 |
39 |
40 |
41 |
42 |
43 |
44 |
54 |
56 |
62 |
63 |
64 |
65 |
66 |
67 |
73 |
75 |
81 |
82 |
83 |
84 |
86 |
87 |
90 |
91 |
92 |
--------------------------------------------------------------------------------
/gic_flutter/ios/Runner.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/gic_flutter/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/gic_flutter/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | PreviewsEnabled
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/gic_flutter/ios/Runner/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | import UIKit
2 | import Flutter
3 |
4 | @UIApplicationMain
5 | @objc class AppDelegate: FlutterAppDelegate {
6 | override func application(
7 | _ application: UIApplication,
8 | didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
9 | ) -> Bool {
10 | GeneratedPluginRegistrant.register(with: self)
11 | return super.application(application, didFinishLaunchingWithOptions: launchOptions)
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/gic_flutter/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "size" : "20x20",
5 | "idiom" : "iphone",
6 | "filename" : "Icon-App-20x20@2x.png",
7 | "scale" : "2x"
8 | },
9 | {
10 | "size" : "20x20",
11 | "idiom" : "iphone",
12 | "filename" : "Icon-App-20x20@3x.png",
13 | "scale" : "3x"
14 | },
15 | {
16 | "size" : "29x29",
17 | "idiom" : "iphone",
18 | "filename" : "Icon-App-29x29@1x.png",
19 | "scale" : "1x"
20 | },
21 | {
22 | "size" : "29x29",
23 | "idiom" : "iphone",
24 | "filename" : "Icon-App-29x29@2x.png",
25 | "scale" : "2x"
26 | },
27 | {
28 | "size" : "29x29",
29 | "idiom" : "iphone",
30 | "filename" : "Icon-App-29x29@3x.png",
31 | "scale" : "3x"
32 | },
33 | {
34 | "size" : "40x40",
35 | "idiom" : "iphone",
36 | "filename" : "Icon-App-40x40@2x.png",
37 | "scale" : "2x"
38 | },
39 | {
40 | "size" : "40x40",
41 | "idiom" : "iphone",
42 | "filename" : "Icon-App-40x40@3x.png",
43 | "scale" : "3x"
44 | },
45 | {
46 | "size" : "60x60",
47 | "idiom" : "iphone",
48 | "filename" : "Icon-App-60x60@2x.png",
49 | "scale" : "2x"
50 | },
51 | {
52 | "size" : "60x60",
53 | "idiom" : "iphone",
54 | "filename" : "Icon-App-60x60@3x.png",
55 | "scale" : "3x"
56 | },
57 | {
58 | "size" : "20x20",
59 | "idiom" : "ipad",
60 | "filename" : "Icon-App-20x20@1x.png",
61 | "scale" : "1x"
62 | },
63 | {
64 | "size" : "20x20",
65 | "idiom" : "ipad",
66 | "filename" : "Icon-App-20x20@2x.png",
67 | "scale" : "2x"
68 | },
69 | {
70 | "size" : "29x29",
71 | "idiom" : "ipad",
72 | "filename" : "Icon-App-29x29@1x.png",
73 | "scale" : "1x"
74 | },
75 | {
76 | "size" : "29x29",
77 | "idiom" : "ipad",
78 | "filename" : "Icon-App-29x29@2x.png",
79 | "scale" : "2x"
80 | },
81 | {
82 | "size" : "40x40",
83 | "idiom" : "ipad",
84 | "filename" : "Icon-App-40x40@1x.png",
85 | "scale" : "1x"
86 | },
87 | {
88 | "size" : "40x40",
89 | "idiom" : "ipad",
90 | "filename" : "Icon-App-40x40@2x.png",
91 | "scale" : "2x"
92 | },
93 | {
94 | "size" : "76x76",
95 | "idiom" : "ipad",
96 | "filename" : "Icon-App-76x76@1x.png",
97 | "scale" : "1x"
98 | },
99 | {
100 | "size" : "76x76",
101 | "idiom" : "ipad",
102 | "filename" : "Icon-App-76x76@2x.png",
103 | "scale" : "2x"
104 | },
105 | {
106 | "size" : "83.5x83.5",
107 | "idiom" : "ipad",
108 | "filename" : "Icon-App-83.5x83.5@2x.png",
109 | "scale" : "2x"
110 | },
111 | {
112 | "size" : "1024x1024",
113 | "idiom" : "ios-marketing",
114 | "filename" : "Icon-App-1024x1024@1x.png",
115 | "scale" : "1x"
116 | }
117 | ],
118 | "info" : {
119 | "version" : 1,
120 | "author" : "xcode"
121 | }
122 | }
123 |
--------------------------------------------------------------------------------
/gic_flutter/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Terence-D/GamingInterfaceClientAndroid/f71658c54f0c485e5c2791674ea53c2e271af6e3/gic_flutter/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png
--------------------------------------------------------------------------------
/gic_flutter/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Terence-D/GamingInterfaceClientAndroid/f71658c54f0c485e5c2791674ea53c2e271af6e3/gic_flutter/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png
--------------------------------------------------------------------------------
/gic_flutter/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Terence-D/GamingInterfaceClientAndroid/f71658c54f0c485e5c2791674ea53c2e271af6e3/gic_flutter/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png
--------------------------------------------------------------------------------
/gic_flutter/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Terence-D/GamingInterfaceClientAndroid/f71658c54f0c485e5c2791674ea53c2e271af6e3/gic_flutter/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png
--------------------------------------------------------------------------------
/gic_flutter/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Terence-D/GamingInterfaceClientAndroid/f71658c54f0c485e5c2791674ea53c2e271af6e3/gic_flutter/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png
--------------------------------------------------------------------------------
/gic_flutter/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Terence-D/GamingInterfaceClientAndroid/f71658c54f0c485e5c2791674ea53c2e271af6e3/gic_flutter/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png
--------------------------------------------------------------------------------
/gic_flutter/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Terence-D/GamingInterfaceClientAndroid/f71658c54f0c485e5c2791674ea53c2e271af6e3/gic_flutter/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png
--------------------------------------------------------------------------------
/gic_flutter/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Terence-D/GamingInterfaceClientAndroid/f71658c54f0c485e5c2791674ea53c2e271af6e3/gic_flutter/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png
--------------------------------------------------------------------------------
/gic_flutter/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Terence-D/GamingInterfaceClientAndroid/f71658c54f0c485e5c2791674ea53c2e271af6e3/gic_flutter/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png
--------------------------------------------------------------------------------
/gic_flutter/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Terence-D/GamingInterfaceClientAndroid/f71658c54f0c485e5c2791674ea53c2e271af6e3/gic_flutter/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png
--------------------------------------------------------------------------------
/gic_flutter/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Terence-D/GamingInterfaceClientAndroid/f71658c54f0c485e5c2791674ea53c2e271af6e3/gic_flutter/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png
--------------------------------------------------------------------------------
/gic_flutter/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Terence-D/GamingInterfaceClientAndroid/f71658c54f0c485e5c2791674ea53c2e271af6e3/gic_flutter/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png
--------------------------------------------------------------------------------
/gic_flutter/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Terence-D/GamingInterfaceClientAndroid/f71658c54f0c485e5c2791674ea53c2e271af6e3/gic_flutter/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png
--------------------------------------------------------------------------------
/gic_flutter/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Terence-D/GamingInterfaceClientAndroid/f71658c54f0c485e5c2791674ea53c2e271af6e3/gic_flutter/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png
--------------------------------------------------------------------------------
/gic_flutter/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Terence-D/GamingInterfaceClientAndroid/f71658c54f0c485e5c2791674ea53c2e271af6e3/gic_flutter/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png
--------------------------------------------------------------------------------
/gic_flutter/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "LaunchImage.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "LaunchImage@2x.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "LaunchImage@3x.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/gic_flutter/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Terence-D/GamingInterfaceClientAndroid/f71658c54f0c485e5c2791674ea53c2e271af6e3/gic_flutter/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png
--------------------------------------------------------------------------------
/gic_flutter/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Terence-D/GamingInterfaceClientAndroid/f71658c54f0c485e5c2791674ea53c2e271af6e3/gic_flutter/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png
--------------------------------------------------------------------------------
/gic_flutter/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Terence-D/GamingInterfaceClientAndroid/f71658c54f0c485e5c2791674ea53c2e271af6e3/gic_flutter/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png
--------------------------------------------------------------------------------
/gic_flutter/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md:
--------------------------------------------------------------------------------
1 | # Launch Screen Assets
2 |
3 | You can customize the launch screen with your own desired assets by replacing the image files in this directory.
4 |
5 | You can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images.
--------------------------------------------------------------------------------
/gic_flutter/ios/Runner/Base.lproj/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
--------------------------------------------------------------------------------
/gic_flutter/ios/Runner/Base.lproj/Main.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/gic_flutter/ios/Runner/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | gic_flutter
15 | CFBundlePackageType
16 | APPL
17 | CFBundleShortVersionString
18 | $(FLUTTER_BUILD_NAME)
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | $(FLUTTER_BUILD_NUMBER)
23 | LSRequiresIPhoneOS
24 |
25 | UILaunchStoryboardName
26 | LaunchScreen
27 | UIMainStoryboardFile
28 | Main
29 | UISupportedInterfaceOrientations
30 |
31 | UIInterfaceOrientationPortrait
32 | UIInterfaceOrientationLandscapeLeft
33 | UIInterfaceOrientationLandscapeRight
34 |
35 | UISupportedInterfaceOrientations~ipad
36 |
37 | UIInterfaceOrientationPortrait
38 | UIInterfaceOrientationPortraitUpsideDown
39 | UIInterfaceOrientationLandscapeLeft
40 | UIInterfaceOrientationLandscapeRight
41 |
42 | UIViewControllerBasedStatusBarAppearance
43 |
44 |
45 |
46 |
--------------------------------------------------------------------------------
/gic_flutter/ios/Runner/Runner-Bridging-Header.h:
--------------------------------------------------------------------------------
1 | #import "GeneratedPluginRegistrant.h"
2 |
--------------------------------------------------------------------------------
/gic_flutter/lib/src/app.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter_localizations/flutter_localizations.dart';
3 | import 'package:gic_flutter/src/views/intro/introView.dart';
4 | import 'package:gic_flutter/src/views/launcher/launcher.dart';
5 | import 'backend/models/intl/localizations.dart';
6 | import 'backend/services/firstRunService.dart';
7 | import 'service_locator.dart';
8 | import 'theme/theme.dart';
9 |
10 | class GicApp extends StatelessWidget {
11 | GicApp ();
12 |
13 | @override
14 | Widget build(BuildContext context) {
15 | return MaterialApp(
16 | onGenerateTitle: (BuildContext context) => Intl.of(context)!.title,
17 | theme: MyAppThemes.lightTheme,
18 | darkTheme: MyAppThemes.darkTheme,
19 | themeMode: ThemeMode.system,
20 | home: _getStartupScreen(),
21 | localizationsDelegates: [
22 | const IntlDelegate(),
23 | GlobalMaterialLocalizations.delegate,
24 | GlobalWidgetsLocalizations.delegate,
25 | ],
26 | supportedLocales: [
27 | const Locale('en', ''),
28 | ],
29 | );
30 | }
31 |
32 | Widget _getStartupScreen() {
33 | var localStorageService = locator();
34 | if(localStorageService.firstRun) {
35 | return IntroView();
36 | }
37 | return Launcher();
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/gic_flutter/lib/src/backend/blocs/launcherBloc.dart:
--------------------------------------------------------------------------------
1 | import 'dart:async';
2 |
3 | import 'package:flutter/material.dart';
4 | import 'package:gic_flutter/src/backend/models/launcherModel.dart';
5 | import 'package:gic_flutter/src/backend/models/networkModel.dart';
6 | import 'package:gic_flutter/src/backend/models/screen/viewModels/screenViewModel.dart';
7 | import 'package:gic_flutter/src/backend/repositories/launcherRepository.dart';
8 | import 'package:rxdart/rxdart.dart';
9 |
10 | /// LauncherBloc acts as the Presentation layer for the Launcher UI
11 | class LauncherBloc {
12 | LauncherRepository? _repository;
13 | PublishSubject? _modelFetcher;
14 | LauncherModel? itemModel;
15 |
16 | LauncherBloc() {
17 | this._repository = LauncherRepository();
18 | this._modelFetcher = PublishSubject();
19 | }
20 |
21 | LauncherBloc.withMocks(repository) {
22 | _repository = repository;
23 | this._modelFetcher = PublishSubject();
24 | }
25 |
26 | Stream get preferences => _modelFetcher!.stream;
27 |
28 | /// Loads the preferences from the repository, and adds to the sink
29 | Future fetchAllPreferences() async {
30 | itemModel = await _repository!.fetch();
31 | _modelFetcher?.sink.add(itemModel);
32 | }
33 |
34 | /// saves the server connection settings
35 | ///
36 | /// @param address Address for the GIC server
37 | /// @param port Port number of the GIC server
38 | /// @param password Secret for securing the connection to the GIC server
39 | void saveConnectionSettings(NetworkModel networkModel) {
40 | _repository?.saveMainSettings(networkModel);
41 | }
42 |
43 | /// Sets the purchase value
44 | void setDonation(String id, bool newValue) {
45 | _repository?.setDonation(id, newValue);
46 | }
47 |
48 | /// closes the stream
49 | void dispose() {
50 | _modelFetcher?.close();
51 | }
52 |
53 | /// Changes the screen name
54 | ///
55 | /// @param id Id of the screen we want to update the name of
56 | /// @param newName New name of the screen
57 | Future updateScreenName(int? id, String? newName) async {
58 | await _repository?.updateName(id, newName);
59 | }
60 |
61 | /// Deletes the screen
62 | ///
63 | /// @param id The Id of the screen we want to remove
64 | /// @return The new cache size, or -1 if an error occurs
65 | Future deleteScreen(int? id) async {
66 | int? rv = await _repository?.deleteScreen(id);
67 |
68 | if (rv! >= 0) {
69 | await fetchAllPreferences();
70 | }
71 |
72 | return rv;
73 | }
74 |
75 | /// Imports a new screen into GIC
76 | ///
77 | /// @param file the file we are importing
78 | /// @return the new Id of the imported screen, or a negative value on failure
79 | Future import(String file) async {
80 | int newItemId = await _repository!.import(file);
81 | await fetchAllPreferences();
82 |
83 | return newItemId;
84 | }
85 |
86 | /// Exports a new screen into GIC
87 | ///
88 | /// @param exportPath directory we are exporting to
89 | /// @param id Id of the screen we want to export
90 | /// @return complete path of file
91 | Future export(String? exportPath, int? id) async {
92 | return await _repository!.export(exportPath, id);
93 | }
94 |
95 | Future checkScreenSize(int screenId) async {
96 | return await _repository!.checkScreenSize(screenId);
97 | }
98 |
99 | List getDimensions(BuildContext context) {
100 | return _repository!.buildDimensions(context);
101 | }
102 |
103 | bool getSound() {
104 | return itemModel!.sound;
105 | }
106 |
107 | bool getVibration() {
108 | return itemModel!.vibration;
109 | }
110 |
111 | bool getKeepScreenOn() => itemModel!.keepScreenOn;
112 |
113 | /// and resizes the screen to fit the devices dimensions
114 | /// saved as a new screen
115 | void resize(int screenId, BuildContext context) async {
116 | await _repository!.resizeScreen(screenId, context);
117 | await fetchAllPreferences();
118 | }
119 |
120 | Future loadScreen(int screenId) async {
121 | return await _repository!.setActiveScreen(screenId);
122 | }
123 | }
124 |
--------------------------------------------------------------------------------
/gic_flutter/lib/src/backend/blocs/newScreenWizardBloc.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:gic_flutter/src/backend/models/newScreenWizardModel.dart';
3 | import 'package:gic_flutter/src/backend/models/screen/command.dart';
4 | import 'package:gic_flutter/src/backend/models/screen/viewModels/controlViewModel.dart';
5 | import 'package:gic_flutter/src/backend/services/screenService.dart';
6 |
7 | /// This is the presentation layer of the new screen wizard ui
8 | /// It's pretty simplistic, and doesn't need a lot of bloc fanciness
9 | /// but in the interest of keeping like minded code together, keeping the
10 | /// naming convention standard
11 | class NewScreenWizardBloc {
12 | ScreenService _screenService = ScreenService();
13 | int _margins = 32; //may want to make this user selectable in a future release
14 |
15 | /// Creates a new empty screen
16 | /// Adds in the controls from the model
17 | /// Saves it
18 | Future saveScreen(NewScreenWizardModel model) async {
19 | //create an initial screen in the list / set the active screen to it
20 | await _screenService.createScreen();
21 | //now that we have an active, lets load in the defaults
22 | await _screenService.initDefaults();
23 |
24 | //set up the defaults based on the model
25 | _screenService.activeScreenViewModel!.name = model.screenName;
26 | _screenService.activeScreenViewModel!.backgroundColor = Colors.black54;
27 | await _buildControls(model);
28 |
29 | //save it
30 | await _screenService.activeScreenViewModel!.save();
31 | }
32 |
33 | /// Here we build all of the controls we will add to the new screen
34 | Future _buildControls(NewScreenWizardModel model) async {
35 | //to get workable screen width, we need to take the total width passed in
36 | //then remove a margin for every control we have horizontally, +1
37 | int workableWidth = model.screenWidth.floor() -
38 | (_margins * model.horizontalControlCount) -
39 | (_margins * 2);
40 | //now we divide that by the number of controls, and we have our control width
41 | double controlWidth = (workableWidth / model.horizontalControlCount);
42 |
43 | //now do the same for height
44 | int workableHeight = model.screenHeight.floor() -
45 | (_margins * model.verticalControlCount) -
46 | (_margins * 2);
47 | double controlHeight = (workableHeight / model.verticalControlCount);
48 |
49 | //lets limit the ugly, and hard code a height limit to be 20% max of the screen
50 | if (controlHeight > (workableHeight * .2))
51 | controlHeight = workableHeight * .2;
52 |
53 | //build the control in a grid fashion, horizontally x vertically
54 | int i = 0; //tracks which control we're on
55 | for (int y = 0; y < model.verticalControlCount; y++) {
56 | for (int x = 0; x < model.horizontalControlCount; x++) {
57 | NewScreenWizardControl element = model.controls[i];
58 |
59 | //only proceed if the control has valid OR key
60 | if (element.text == null && element.key == null) return;
61 |
62 | _screenService.activeScreenViewModel!.controls!
63 | .add(_buildControl(controlHeight, controlWidth, x, y, element));
64 | i++;
65 | }
66 | }
67 | }
68 |
69 | /// This builds an individual control we are adding to the new screen
70 | ControlViewModel _buildControl(double controlHeight, double controlWidth,
71 | int x, int y, NewScreenWizardControl element) {
72 | ControlViewModel control = ControlViewModel();
73 | control.height = controlHeight;
74 | control.width = controlWidth;
75 | control.left = (_margins + ((_margins + controlWidth) * x));
76 | control.top = (_margins + ((_margins + controlHeight) * y));
77 |
78 | List mods = [];
79 | if (element.ctrl) mods.add("CTRL");
80 | if (element.alt) mods.add("ALT");
81 | if (element.shift) mods.add("SHIFT");
82 | control.commands
83 | .add(Command(key: element.key, modifiers: mods, activatorType: 0));
84 |
85 | ControlViewModel defaultControl =
86 | _screenService.defaultControls.defaultButton;
87 |
88 | control.text = element.text;
89 | if (element.isSwitch) {
90 | //special conditions apply
91 | control.type = ControlViewModelType.Toggle;
92 | defaultControl = _screenService.defaultControls.defaultToggle;
93 | control.images.add("toggle_off");
94 | control.images.add("toggle_on");
95 | //shrink the switch to make room for text
96 | } else {
97 | control.type = ControlViewModelType.Button;
98 | control.images.add("button_black");
99 | control.images.add("button_black2");
100 | }
101 |
102 | control.colors = defaultControl.colors;
103 | return control;
104 | }
105 | }
106 |
--------------------------------------------------------------------------------
/gic_flutter/lib/src/backend/models/autoItKeyMap.dart:
--------------------------------------------------------------------------------
1 | import 'dart:collection';
2 |
3 | class AutoItKeyMap {
4 | Map map = LinkedHashMap();
5 |
6 | AutoItKeyMap() {
7 | //add every char in the english alphabet
8 | int c = "A".codeUnitAt(0);
9 | int end = "Z".codeUnitAt(0);
10 | while (c <= end) {
11 | map[String.fromCharCode(c)] = String.fromCharCode(c);
12 | c++;
13 | }
14 |
15 | for (int number = 0; number <= 9; number++) {
16 | map[number.toString()] = number.toString();
17 | }
18 | for (int number = 0; number <= 9; number++) {
19 | map["NUMPAD$number"] = "Numpad $number";
20 | }
21 | map["NUMPADMULT"] = "Numpad *";
22 | map["NUMPADADD"] = "Numpad +";
23 | map["NUMPADSUB"] = "Numpad -";
24 | map["NUMPADDIV"] = "Numpad /";
25 | map["NUMPADDOT"] = "Numpad .";
26 | map["NUMPADENTER"] = "Numpad Enter";
27 |
28 | for (int number = 0; number <= 12; number++) {
29 | map["F$number"] = "F$number";
30 | }
31 |
32 | map["`"] = "~/`";
33 | map["!"] = "!";
34 | map["@"] = "@";
35 | map["#"] = "#";
36 | map["\$"] = "\$";
37 | map["%"] = "%";
38 | map["^"] = "^";
39 | map["&"] = "&";
40 | map["*"] = "*";
41 | map["("] = "(";
42 | map[")"] = ")";
43 | map["-"] = "- / _";
44 | map["="] = "= / +";
45 | map["["] = "[ / {";
46 | map["]"] = "] / }";
47 | map["\\"] = "\\ / |";
48 | map[";"] = "; / :";
49 | map["'"] = "' / ";
50 | map[","] = "] = / <";
51 | map["."] = ". / >";
52 | map["/"] = "/ / ?";
53 |
54 | map["SPACE"] = "Space";
55 | map["ENTER"] = "Enter";
56 | map["BACKSPACE"] = "Backspace";
57 | map["DELETE"] = "Delete";
58 | map["UP"] = "Up arrow";
59 | map["DOWN"] = "Down arrow";
60 | map["LEFT"] = "Left arrow";
61 | map["RIGHT"] = "Right arrow";
62 | map["HOME"] = "Home";
63 | map["END"] = "End";
64 | map["ESCAPE"] = "Escape";
65 | map["INSERT"] = "Insert";
66 | map["PGUP"] = "Page Up";
67 | map["PGDN"] = "Page Down";
68 | map["TAB"] = "Tab Key";
69 | map["PRINTSCREEN"] = "Print Screen";
70 | map["LWIN"] = "Left Windows key";
71 | map["RWIN"] = "Right Windows key";
72 | map["NUMLOCK"] = "Numlock";
73 | map["CAPSLOCK"] = "Capslock";
74 | map["SCROLLLOCK"] = "Scroll Lock";
75 | map["BREAK"] = "Ctrl+Break ";
76 | map["PAUSE"] = "Pause";
77 | map["APPSKEY"] = "Windows App key";
78 | //this seems unnecessary?? map["SLEEP"] = " Computer SLEEP key";
79 | //map["LWINDOWN"] = " Holds the left Windows key down until map["LWINUP"] = "is sent";
80 | //map["RWINDOWN"] = " Holds the right Windows key down until map["RWINUP"] = "is sent";
81 |
82 | map["VOLUME_MUTE"] = "Mute the volume";
83 | map["VOLUME_DOWN"] = "Reduce the volume";
84 | map["VOLUME_UP"] = "Increase the volume";
85 | map["MEDIA_NEXT"] = "Select next track in media player";
86 | map["MEDIA_PREV"] = "Select previous track in media player";
87 | map["MEDIA_STOP"] = "Stop media player";
88 | map["MEDIA_PLAY_PAUSE"] = "Play/pause media player";
89 | }
90 | }
--------------------------------------------------------------------------------
/gic_flutter/lib/src/backend/models/channel.dart:
--------------------------------------------------------------------------------
1 | class Channel {
2 | static const String _channelName = "ca.coffeeshopstudio.gic";
3 |
4 | static const String channelUtil = "$_channelName/utils";
5 | static const String channelView = "$_channelName/views";
6 |
7 | static const String actionViewEditor = "editor";
8 | static const String actionViewStart = "start";
9 | static const String actionViewEdit = "edit";
10 | static const String actionViewManager = "manager";
11 |
12 | static const String actionUtilDecrypt = "decrypt";
13 | static const String actionUtilEncrypt = "encrypt";
14 | static const String actionGetDownloadFolder = "downloadFolder";
15 | static const String actionUtilGetSettings = "settings/get";
16 | static const String actionUtilUpdateDarkMode = "darkmode/set";
17 | static const String actionUtilUpdateScreens = "screens/upgrade";
18 | static const String actionCheckDefaults = "defaults";
19 | }
--------------------------------------------------------------------------------
/gic_flutter/lib/src/backend/models/intl/intlFeedback.dart:
--------------------------------------------------------------------------------
1 | enum FeedbackText {
2 | toolbarTitle,
3 | details,
4 | updown,
5 | email,
6 | emailTo,
7 | satisfaction,
8 | githubIssues,
9 | githubIssuesUrl,
10 | }
11 |
12 | class IntlFeedback {
13 | static Map> localizedStrings = {
14 | 'en': {
15 | FeedbackText.toolbarTitle: 'Feedback',
16 | FeedbackText.details:
17 | 'Got an idea for a feature you want? See something you hate? Feedback is always appreciated! You can open an issue directly on GitHub (3rd party website, link below), or if you prefer send me an email. Although I will not share any information sent, please ensure you do not include any sensitive information!',
18 | FeedbackText.githubIssues: 'Github Issue Tracker',
19 | FeedbackText.githubIssuesUrl:
20 | 'https://github.com/Terence-D/GamingInterfaceClientAndroid/issues',
21 | FeedbackText.satisfaction: 'Satisfaction',
22 | FeedbackText.updown:
23 | 'Tap on one of the images below (optionally) to quickly provide a thumbs up or down!',
24 | FeedbackText.email: 'Send Feedback',
25 | FeedbackText.emailTo: 'mailto:support@coffeeshopstudio.ca?subject=GIC',
26 | }
27 | };
28 | }
29 |
--------------------------------------------------------------------------------
/gic_flutter/lib/src/backend/models/intl/intlNewScreenWizard.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:gic_flutter/src/backend/models/intl/localizations.dart';
3 |
4 | enum NewScreenWizardText {
5 | toolbarTitle,
6 | save,
7 | next,
8 | screenName,
9 | increase,
10 | decrease,
11 | buttonDesign,
12 | buttonNormal,
13 | buttonPressed,
14 | switchDesign,
15 | switchNormal,
16 | switchPressed,
17 | orientation,
18 | layout,
19 | controlsWide,
20 | controlsDepth,
21 | totalControls,
22 | buttonType,
23 | switchType,
24 | quickTap,
25 | ctrl, alt, shift,
26 | errorEnterScreenName,
27 | controlText,
28 | controlCommand,
29 | width,
30 | height
31 | }
32 |
33 | class IntlNewScreenWizard {
34 | BuildContext _context;
35 |
36 | IntlNewScreenWizard(this ._context);
37 |
38 | String text(NewScreenWizardText text) {
39 | return _localizedStrings[Intl.of(_context)?.locale.languageCode]![text]!;
40 | }
41 |
42 | static Map> _localizedStrings = {
43 | 'en': {
44 | NewScreenWizardText.toolbarTitle: 'New Screen Wizard',
45 | NewScreenWizardText.save: "Save",
46 | NewScreenWizardText.next: "Next",
47 | NewScreenWizardText.screenName: 'Screen Name',
48 | NewScreenWizardText.increase: "Add",
49 | NewScreenWizardText.decrease: 'Remove',
50 | NewScreenWizardText.buttonDesign: "Button Design",
51 | NewScreenWizardText.buttonNormal: "Normal",
52 | NewScreenWizardText.buttonPressed: "Pressed",
53 | NewScreenWizardText.switchDesign: 'Switch Design',
54 | NewScreenWizardText.switchNormal: "Normal",
55 | NewScreenWizardText.switchPressed: "Pressed",
56 | NewScreenWizardText.orientation: "Orientation",
57 | NewScreenWizardText.layout: "Layout",
58 | NewScreenWizardText.controlsWide: "Controls Wide",
59 | NewScreenWizardText.controlsDepth: "Controls Deep",
60 | NewScreenWizardText.totalControls: "Total Controls",
61 | NewScreenWizardText.buttonType: "Button",
62 | NewScreenWizardText.switchType: "Switch",
63 | NewScreenWizardText.quickTap: "Quick Mode",
64 | NewScreenWizardText.ctrl: "Ctrl",
65 | NewScreenWizardText.alt: "Alt",
66 | NewScreenWizardText.shift: "Shift",
67 | NewScreenWizardText.errorEnterScreenName: "Please enter a screen name!",
68 | NewScreenWizardText.controlCommand: "Command on press",
69 | NewScreenWizardText.controlText: "Text to Display",
70 | NewScreenWizardText.width: "Width",
71 | NewScreenWizardText.height: "Height"
72 | }
73 | };
74 | }
75 |
--------------------------------------------------------------------------------
/gic_flutter/lib/src/backend/models/intl/intlOptions.dart:
--------------------------------------------------------------------------------
1 | enum OptionsText {
2 | toolbarTitle,
3 | darkModeTitle,
4 | darkModeText,
5 | soundTitle,
6 | soundText,
7 | vibrationTitle,
8 | vibrationText,
9 | keepScreenOnTitle,
10 | keepScreenOnText,
11 | }
12 |
13 | class IntlOptions {
14 | static Map> localizedStrings = {
15 | 'en': {
16 | OptionsText.toolbarTitle: 'Options',
17 | OptionsText.darkModeTitle: 'Dark Mode',
18 | OptionsText.darkModeText:
19 | 'Enable this for the Dark Theme, disable this for the Light Theme',
20 | OptionsText.soundTitle: 'Sound',
21 | OptionsText.soundText:
22 | 'Enable this an audio sound to be played when a Button or Toggle is activated. Ensure audio is not muted on your device before enabling!',
23 | OptionsText.vibrationTitle: 'Vibration',
24 | OptionsText.vibrationText:
25 | 'Enable this for the device to perform a light vibration when a Button or Toggle is activated',
26 | OptionsText.keepScreenOnTitle: 'Keep Screen On',
27 | OptionsText.keepScreenOnText:
28 | 'Enable this to keep the screen on when in game',
29 | }
30 | };
31 | }
32 |
--------------------------------------------------------------------------------
/gic_flutter/lib/src/backend/models/launcherModel.dart:
--------------------------------------------------------------------------------
1 | /// TODO this should be renamed
2 | class LauncherModel {
3 | String toolbarTitle = "";
4 | bool firstRun = false;
5 | bool darkMode = true;
6 | bool sound = false;
7 | bool vibration = false;
8 | bool keepScreenOn = false;
9 | String address = "";
10 | String password = "";
11 | String port = "";
12 | List screens = [];
13 | int newScreenid = 0;
14 | }
15 |
16 | class ScreenListItem {
17 | ScreenListItem(this.id, this.name);
18 |
19 | String? name;
20 | final int? id;
21 | }
22 |
--------------------------------------------------------------------------------
/gic_flutter/lib/src/backend/models/networkModel.dart:
--------------------------------------------------------------------------------
1 | import 'package:gic_flutter/src/backend/services/cryptoService.dart';
2 |
3 | class NetworkModel {
4 | String _password = "";
5 | String _address = "";
6 | String _port = "";
7 |
8 | String get password => _password;
9 | String get address => _address;
10 | String get port => _port;
11 |
12 | void toTest(String password, String address, String port) {
13 | _password = password;
14 | _address = address;
15 | _port = port;
16 | }
17 |
18 | Future init(String unencryptedPassword, String address, String port) async {
19 | _password = await CryptoService.encrypt(unencryptedPassword);
20 | _address = address;
21 | _port = port;
22 | }
23 | }
--------------------------------------------------------------------------------
/gic_flutter/lib/src/backend/models/newScreenWizardModel.dart:
--------------------------------------------------------------------------------
1 | class NewScreenWizardModel {
2 | String toolbarTitle = "";
3 | //These are built in the view and passed back as requires Context
4 | double screenWidth = 0;
5 | double screenHeight = 0;
6 |
7 | String screenName = "";
8 | bool isLandscape = true; // used for constructing the above screen values. User set
9 | //Grid view related
10 | int horizontalControlCount = 1;
11 | int verticalControlCount = 1;
12 | //default look for both
13 | String buttonNormalImage = "";
14 | String buttonPressedImage = "";
15 | String switchNormalImage = "";
16 | String switchPressedImage = "";
17 |
18 | late List controls; // our list of controls to create
19 | }
20 |
21 | /// This is used purely for the "new screen" view model
22 | class NewScreenWizardControl {
23 | String text = "";
24 | String key = "";
25 | bool isSwitch = false;
26 | bool alt = false;
27 | bool ctrl = false;
28 | bool shift= false;
29 | }
30 |
--------------------------------------------------------------------------------
/gic_flutter/lib/src/backend/models/screen/command.dart:
--------------------------------------------------------------------------------
1 | class Command {
2 | static const int KEY_DOWN = 0;
3 | static const int KEY_UP = 1;
4 |
5 | String? key = "A";
6 | List? modifiers = [];
7 | int? activatorType = 0; //key down, key up, etc
8 |
9 | Command.empty();
10 |
11 | Command ({this.key, this.modifiers, this.activatorType}) {
12 | if (this.modifiers == null) {
13 | this.modifiers = [];
14 | }
15 | }
16 |
17 | Map toJson() =>
18 | {
19 | 'activatorType': activatorType,
20 | 'key': key,
21 | 'modifier': modifiers
22 | };
23 |
24 | factory Command.fromJson(Map json) {
25 | if (json['modifier'] == null && json['Modifier'] == null) {
26 | json['modifier'] = [];
27 | }
28 |
29 | //handle both case possibilities
30 | var jsonMods;
31 | List? mods = [];
32 | if (json.containsKey('modifier'))
33 | jsonMods = json['modifier'];
34 | else if (json.containsKey('Modifier'))
35 | jsonMods = json['Modifier'];
36 | if (jsonMods != null)
37 | mods = List.from(jsonMods);
38 |
39 | String? jsonKey = "";
40 | if (json.containsKey('key'))
41 | jsonKey = json['key'];
42 | else if (json.containsKey('Key'))
43 | jsonKey = json['Key'];
44 |
45 | int? jsonActivator=0;
46 | if (json.containsKey('activatorType'))
47 | jsonActivator = json['activatorType'];
48 | else if (json.containsKey('ActivatorType'))
49 | jsonActivator = json['ActivatorType'];
50 |
51 | return Command(
52 | key: jsonKey,
53 | modifiers: mods,
54 | activatorType: jsonActivator
55 | );
56 | }
57 |
58 | }
59 |
--------------------------------------------------------------------------------
/gic_flutter/lib/src/backend/models/screen/controlDefaults.dart:
--------------------------------------------------------------------------------
1 | import 'dart:convert';
2 |
3 | import 'package:flutter/material.dart';
4 | import 'package:gic_flutter/src/backend/models/screen/gicControl.dart';
5 | import 'package:gic_flutter/src/backend/models/screen/viewModels/controlViewModel.dart';
6 | import 'package:shared_preferences/shared_preferences.dart';
7 |
8 | /// This is used to store / save default control values
9 | /// such as backgrounds, sizing, fonts, etc
10 | class ControlDefaults {
11 | final String _imageDefaults = "_image_defaults";
12 | final String _buttonDefaults = "_button_defaults";
13 | final String _textDefaults = "_text_defaults";
14 | final String _toggleDefaults = "_switch_defaults";
15 |
16 | ControlViewModel defaultImage = ControlViewModel();
17 | ControlViewModel defaultButton = ControlViewModel();
18 | ControlViewModel defaultText = ControlViewModel();
19 | ControlViewModel defaultToggle = ControlViewModel();
20 |
21 | SharedPreferences _prefs;
22 |
23 | ControlDefaults(this._prefs, int? screenId) {
24 | if (this._prefs.containsKey("v2$screenId$_imageDefaults")) {
25 | Map imageControlMap =
26 | jsonDecode(_prefs.getString("v2$screenId$_imageDefaults") ?? "");
27 | defaultImage = ControlViewModel.fromJson(imageControlMap);
28 |
29 | Map buttonControlMap =
30 | jsonDecode(_prefs.getString("v2$screenId$_buttonDefaults") ?? "");
31 | defaultButton = ControlViewModel.fromJson(buttonControlMap);
32 |
33 | Map textControlMap =
34 | jsonDecode(_prefs.getString("v2$screenId$_textDefaults") ?? "");
35 | defaultText = ControlViewModel.fromJson(textControlMap);
36 |
37 | Map toggleControlMap =
38 | jsonDecode(_prefs.getString("v2$screenId$_toggleDefaults") ?? "");
39 | defaultToggle = ControlViewModel.fromJson(toggleControlMap);
40 | } else if (_prefs.containsKey("$screenId$_imageDefaults")) {
41 | try {
42 | defaultImage = ControlViewModel.fromLegacyModel(
43 | loadControl("$screenId$_imageDefaults"));
44 | defaultButton = ControlViewModel.fromLegacyModel(
45 | loadControl("$screenId$_buttonDefaults"));
46 | defaultText = ControlViewModel.fromLegacyModel(
47 | loadControl("$screenId$_textDefaults"));
48 | defaultToggle = ControlViewModel.fromLegacyModel(
49 | loadControl("$screenId$_toggleDefaults"));
50 | } catch (ex) {
51 | print(ex);
52 | }
53 | }
54 |
55 | //if nothing was loaded in
56 | if (defaultImage.type != ControlViewModelType.Image) {
57 | defaultImage.type = ControlViewModelType.Image;
58 | defaultImage.images = [];
59 | defaultButton.type = ControlViewModelType.Button;
60 | defaultButton.design = ControlDesignType.Image;
61 | defaultButton.images = [];
62 | defaultButton.colors = [];
63 | defaultButton.colors.add(Colors.blue);
64 | defaultButton.colors.add(Colors.black);
65 | defaultButton.images.add("button_black");
66 | defaultButton.images.add("button_black2");
67 | defaultText.type = ControlViewModelType.Text;
68 | defaultToggle.type = ControlViewModelType.Toggle;
69 | defaultToggle.images = [];
70 | defaultToggle.images.add("toggle_off");
71 | defaultToggle.images.add("toggle_on");
72 | defaultToggle.colors = [];
73 | defaultToggle.colors.add(Colors.blue);
74 | defaultToggle.colors.add(Colors.black);
75 | }
76 | }
77 |
78 | GicControl loadControl(String preference) {
79 | if (!_prefs.containsKey(preference)) {
80 | return GicControl.empty();
81 | } else {
82 | Map controlMap = jsonDecode(_prefs.getString(preference) ?? "");
83 | return GicControl.fromJson(controlMap);
84 | }
85 | }
86 |
87 | bool saveDefaults(int screenId) {
88 | try {
89 | _prefs.setString(
90 | "v2$screenId$_imageDefaults", jsonEncode(defaultImage.toJson()));
91 | _prefs.setString(
92 | "v2$screenId$_buttonDefaults", jsonEncode(defaultButton.toJson()));
93 | _prefs.setString(
94 | "v2$screenId$_textDefaults", jsonEncode(defaultText.toJson()));
95 | _prefs.setString(
96 | "v2$screenId$_toggleDefaults", jsonEncode(defaultToggle.toJson()));
97 | return true;
98 | } catch (_) {
99 | return false;
100 | }
101 | }
102 | }
103 |
--------------------------------------------------------------------------------
/gic_flutter/lib/src/backend/models/screen/controlTypes.dart:
--------------------------------------------------------------------------------
1 | enum Controls {
2 | button,
3 | text,
4 | image,
5 | toggle
6 | }
7 |
8 | class ControlTypes {
9 | static final List buttonDrawables = [
10 | "button_neon",
11 | "button_neon_dark",
12 | "button_blue",
13 | "button_blue_dark",
14 | "button_green",
15 | "button_green_dark",
16 | "button_green2",
17 | "button_green2_dark",
18 | "button_purple",
19 | "button_purple_dark",
20 | "button_red",
21 | "button_red_dark",
22 | "button_yellow",
23 | "button_yellow_dark",
24 | "button_black",
25 | "button_black_dark",
26 | "button_black2",
27 | "button_black2_dark",
28 | "button_blue2",
29 | "button_blue2_dark",
30 | "button_grey",
31 | "button_grey_dark",
32 | "button_grey2",
33 | "button_grey2_dark",
34 | "button_red2",
35 | "button_red2_dark",
36 | "button_white",
37 | "button_white_dark",
38 | ];
39 |
40 | static final List toggleDrawables = [
41 | "switch_off",
42 | "switch_on",
43 | "toggle_off",
44 | "toggle_on",
45 | "lever_off",
46 | "lever_on",
47 | "button_toggle_off",
48 | "button_toggle_on"
49 | ];
50 |
51 | }
--------------------------------------------------------------------------------
/gic_flutter/lib/src/backend/models/screen/fonts.dart:
--------------------------------------------------------------------------------
1 | class Fonts {
2 | static Map list() {
3 | return {
4 | "Lobster-Regular": "Lobster",
5 | "Nunito-Regular": "Nunito",
6 | "Righteous-Regular": "Righteous",
7 | "ShareTech-Regular": "ShareTech",
8 | };
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/gic_flutter/lib/src/backend/models/screen/gicControl.dart:
--------------------------------------------------------------------------------
1 | import 'command.dart';
2 |
3 | class GicControl {
4 | static const int TYPE_BUTTON = 0;
5 | static const int TYPE_TEXT = 1;
6 | static const int TYPE_IMAGE = 2;
7 | static const int TYPE_SWITCH = 3;
8 | static const int TYPE_BUTTON_QUICK = 4;
9 |
10 | //this is required for the toggle button, there are 4 stages to track:
11 | //0 - switched off ready for mouse down
12 | //1 - switched off, ready for mouse up
13 | //2 - switched on, ready for mouse down,
14 | //3 - switched on, ready for mouse up
15 | //after 3, we reset back to 0
16 | int? stage = 0;
17 | Command command = Command.empty();
18 | String? text = "NONE";
19 | double? left = 140;
20 | double? width = 320;
21 | double? top = 200;
22 | double? height = 120;
23 | int? fontColor = -1;
24 | int? primaryColor = -1;
25 | int? secondaryColor = -1;
26 | int? fontSize = 36;
27 | int viewType = 0; //is it a button, switch, image, etc
28 | int? primaryImageResource = -1;//R.drawable.button_blue;
29 | int? secondaryImageResource = -1;//R.drawable.button_blue_dark;
30 | String primaryImage = "";
31 | String secondaryImage = "";
32 | String fontName = "";
33 | int fontType = 0;
34 | Command commandSecondary = Command.empty();
35 |
36 | GicControl.empty() {
37 | primaryImage = "button_black";
38 | secondaryImage = "button_black2";
39 | }
40 |
41 | GicControl ({
42 | this.stage,
43 | required this.command,
44 | this.text,
45 | this.left,
46 | this.width,
47 | this.top,
48 | this.height,
49 | this.fontColor,
50 | this.primaryColor,
51 | this.secondaryColor,
52 | this.fontSize,
53 | this.viewType = 0,
54 | this.primaryImageResource,
55 | this.secondaryImageResource,
56 | required this.primaryImage,
57 | required this.secondaryImage,
58 | required this.fontName,
59 | required this.fontType,
60 | required this.commandSecondary
61 | });
62 |
63 | factory GicControl.fromJson(Map json) {
64 | return GicControl(
65 | stage: json['stage'],
66 | command: Command.fromJson(json['command']),
67 | text: json['text'],
68 | left: json['left'],
69 | width: json['width'].toDouble(),
70 | top: json['top'],
71 | height: json['height'].toDouble(),
72 | fontColor: json['fontColor'],
73 | primaryColor: json['primaryColor'],
74 | secondaryColor: json['secondaryColor'],
75 | fontSize: json['fontSize'],
76 | viewType: json['viewType'],
77 | primaryImageResource: json['primaryImageResource'],
78 | secondaryImageResource: json['secondaryImageResource'],
79 | primaryImage: json['primaryImage'],
80 | secondaryImage: json['secondaryImage'],
81 | fontName: json['fontName'],
82 | fontType: json['fontType'],
83 | commandSecondary: Command.fromJson(json['commandSecondary']),
84 | );
85 | }
86 |
87 | Map toJson() =>
88 | {
89 | 'stage': stage,
90 | 'command': command,
91 | 'text': text,
92 | 'left': left,
93 | 'width': width,
94 | 'top': top,
95 | 'height': height,
96 | 'fontColor': fontColor,
97 | 'primaryColor': primaryColor,
98 | 'secondaryColor': secondaryColor,
99 | 'fontSize': fontSize,
100 | 'viewType': viewType,
101 | 'primaryImageResource': primaryImageResource,
102 | 'secondaryImageResource': secondaryImageResource,
103 | 'primaryImage': primaryImage,
104 | 'secondaryImage': secondaryImage,
105 | 'fontName': fontName,
106 | 'fontType': fontType,
107 | 'commandSecondary': commandSecondary
108 | };
109 | }
--------------------------------------------------------------------------------
/gic_flutter/lib/src/backend/models/screen/screen.dart:
--------------------------------------------------------------------------------
1 | import 'gicControl.dart';
2 |
3 | class Screen {
4 | static const MAX_CONTROL_SIZE = 800;
5 |
6 | int? screenId = -1;
7 | List? controls = [];
8 | //background
9 | int? newControlId = -1;
10 | int? backgroundColor;
11 | String? backgroundPath;
12 | //context;
13 | String? name;
14 |
15 | Screen({
16 | this.screenId = -1,
17 | this.controls = const[],
18 | this.backgroundColor = 0,
19 | this.backgroundPath = "",
20 | this.newControlId = -1,
21 | this.name = ""});
22 |
23 | factory Screen.fromJson(Map json) {
24 | var list = json['controls'] as List;
25 | List jsonControls = [];
26 | list.forEach((value) { jsonControls.add(GicControl.fromJson(value));});
27 |
28 | return Screen(
29 | screenId: json['screenId'],
30 | controls: jsonControls,
31 | backgroundColor: json['backgroundColor'],
32 | backgroundPath: json['backgroundPath'],
33 | newControlId: json['newControlId'],
34 | name: json['name']);
35 | }
36 |
37 | // factory Screen.fromModel(ScreenViewModel model, double pixelRatio) {
38 | // Screen rv = new Screen();
39 | // rv.screenId = model.screenId;
40 | // rv.name = model.name;
41 | // model.controls.forEach((element) {
42 | // rv.controls.add(new ControlViewModel.fromModel(element));
43 | // });
44 | // rv.newControlId = model.newControlId;
45 | //
46 | // if (model.backgroundColor == -1 || model.backgroundColor == null)
47 | // rv.backgroundColor = Colors.black;
48 | // else
49 | // rv.backgroundColor = _convertJavaColor(model.backgroundColor);
50 | // rv.backgroundPath = model.backgroundPath;
51 | // return rv;
52 | // }
53 |
54 | Map toJson() =>
55 | {
56 | 'screenId': screenId,
57 | 'controls': controls,
58 | 'backgroundColor': backgroundColor,
59 | 'backgroundPath': backgroundPath,
60 | 'newControlId': newControlId,
61 | 'name': name,
62 | };
63 |
64 | int getNewControlId() {
65 | newControlId = newControlId! + 1;
66 | return newControlId! - 1;
67 | }
68 |
69 | }
70 |
--------------------------------------------------------------------------------
/gic_flutter/lib/src/backend/models/screen/viewModels/drawable.dart:
--------------------------------------------------------------------------------
1 | class Drawable {
2 | final _value;
3 | const Drawable._internal(this._value);
4 | toString() => _value;
5 |
6 | static const Drawable button_neon = Drawable._internal("button_neon");
7 | }
--------------------------------------------------------------------------------
/gic_flutter/lib/src/backend/models/screen/viewModels/font.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 |
3 | class Font {
4 | int version = 0;
5 | Color color = Colors.blue;
6 | double size = 36;
7 | String? family = "";
8 |
9 | Font.empty() {
10 | color = Colors.blue;
11 | size = 36;
12 | family = "";
13 | }
14 |
15 | Font({this.color = Colors.blue, this.size = 36, this.family = ""});
16 |
17 | Font.fromJson(Map json)
18 | : version = json['version'],
19 | color = Color(json['color']),
20 | size = json['size'],
21 | family = json['family'];
22 |
23 | Font clone() {
24 | Font clone = Font();
25 | clone.version = version;
26 | clone.color = color;
27 | clone.size = size;
28 | clone.family = family;
29 |
30 | return clone;
31 | }
32 |
33 | Map toJson() {
34 |
35 | return {
36 | 'version': 2,
37 | 'color': color.value,
38 | 'size': size,
39 | 'family': family
40 | };
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/gic_flutter/lib/src/backend/models/viewModel.dart:
--------------------------------------------------------------------------------
1 | /// Abstract common class allowing shard view code to be called
2 | abstract class ViewModel {
3 | String get toolbarTitle;
4 | }
--------------------------------------------------------------------------------
/gic_flutter/lib/src/backend/models/viewSection.dart:
--------------------------------------------------------------------------------
1 |
2 | class ViewSection {
3 | String title = "";
4 | String text = "";
5 | String url = "";
6 |
7 | ViewSection (this.title, this.text, this.url);
8 | }
--------------------------------------------------------------------------------
/gic_flutter/lib/src/backend/services/compressedFileService.dart:
--------------------------------------------------------------------------------
1 | import 'dart:developer';
2 | import 'dart:io';
3 |
4 | import 'package:archive/archive_io.dart';
5 | import 'package:path/path.dart' as path;
6 |
7 | class CompressedFileService {
8 | /// Extracts the supplied compressed file path to the supplied path
9 | /// screen id saved on success, empty string on fail
10 | static String extract(String file, String tempPath) {
11 | String fileId = "";
12 | try {
13 | final File compressedFile = File(file);
14 | // Read the Zip file from disk.
15 | final bytes = compressedFile.readAsBytesSync();
16 | // Decode the Zip file
17 | final archive = ZipDecoder().decodeBytes(bytes);
18 |
19 | // Extract the contents of the Zip archive to the temp path.
20 | for (final file in archive) {
21 | final filename = file.name;
22 | if (file.isFile) {
23 | final data = file.content as List;
24 | File(path.join(tempPath, filename))
25 | ..createSync(recursive: true)
26 | ..writeAsBytesSync(data);
27 | }
28 | fileId = path.split(filename)[0];
29 | }
30 | } on Exception catch (e) {
31 | log(e.toString());
32 | }
33 | return fileId;
34 | }
35 |
36 | /// Creates a compressed file
37 | /// folderToCompress is the folder containing the files we want compressed
38 | /// destinationFolder is the destination folder
39 | /// exportFile is the file we are creating
40 | /// Returns 0 on success, -1 on error
41 | static Future compressFolder(String folderToCompress, String destinationFolder, String? exportFile) async {
42 | //add the zip extension if required
43 | try {
44 | if (!exportFile!.endsWith(".zip")) {
45 | exportFile = exportFile + ".zip";
46 | }
47 |
48 | Directory source = Directory(folderToCompress);
49 |
50 | ZipFileEncoder zipFileEncoder = ZipFileEncoder();
51 | zipFileEncoder.create(path.join(destinationFolder, exportFile));
52 | zipFileEncoder.addDirectory(source);
53 |
54 | zipFileEncoder.close();
55 | } on Exception catch (e) {
56 | log(e.toString());
57 | return -1;
58 | }
59 | return 0;
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/gic_flutter/lib/src/backend/services/cryptoService.dart:
--------------------------------------------------------------------------------
1 | import 'dart:convert';
2 | import 'dart:typed_data';
3 |
4 | import 'package:pointycastle/export.dart';
5 |
6 | class CryptoService {
7 | static final String salt = 'f-NS5Qnhn@sdC%_7RAD3K3GmYU5ZHW*\$';
8 | static final String passphrase =
9 | 'WCu8rer-kuJ58UZKcz*ABL\$?&=@pw=_d4L\$tr^cfFgdad-NxCUXRUz8LL*_5z?Xm^zFMP4FXRUvdEhNH=kwKJp8^-D3Uf8AG?6DtKrQH%HYC*c6KqW&XR2gF7hndfu+u';
10 | static final String iv = 'kYW-*%n^t!JkV3FU';
11 | static final int iterations = 100;
12 | static final int size = 32;
13 | static const Mode = 'CBC';
14 |
15 | static String encrypt(String toEncrypt) {
16 | Uint8List derivedKey = _buildKey();
17 | KeyParameter keyParam = KeyParameter(derivedKey);
18 | BlockCipher aes = AESFastEngine();
19 | Uint8List ivBytes = _createUint8ListFromString(iv);
20 | BlockCipher cipher = CBCBlockCipher(aes);
21 | ParametersWithIV params = ParametersWithIV(keyParam, ivBytes);
22 |
23 | cipher.init(true, params);
24 |
25 | Uint8List textBytes = _createUint8ListFromString(toEncrypt);
26 | Uint8List paddedText = _pad(textBytes, aes.blockSize);
27 | Uint8List cipherBytes = _processBlocks(cipher, paddedText);
28 |
29 | return base64.encode(cipherBytes);
30 | }
31 |
32 | static String decrypt(String toDecrypt) {
33 | Uint8List derivedKey = _buildKey();
34 | KeyParameter keyParam = KeyParameter(derivedKey);
35 | BlockCipher aes = AESFastEngine();
36 | Uint8List ivBytes = _createUint8ListFromString(iv);
37 | BlockCipher cipher = CBCBlockCipher(aes);
38 | ParametersWithIV params = ParametersWithIV(keyParam, ivBytes);
39 |
40 | String decryptThis = toDecrypt;
41 | if (decryptThis.length % 4 > 0) {
42 | decryptThis += '=' * (4 - decryptThis.length % 4);
43 | }
44 |
45 | Uint8List cipherBytesFromEncode;
46 | try {
47 | cipherBytesFromEncode = base64.decode(decryptThis);
48 | } catch (e) {
49 | return "";
50 | }
51 |
52 | Uint8List cipherIvBytes =
53 | Uint8List(cipherBytesFromEncode.length + ivBytes.length)
54 | ..setAll(0, ivBytes)
55 | ..setAll(ivBytes.length, cipherBytesFromEncode);
56 |
57 | cipher.init(false, params);
58 |
59 | int cipherLen = cipherIvBytes.length - aes.blockSize;
60 | Uint8List cipherBytes = Uint8List(cipherLen)
61 | ..setRange(0, cipherLen, cipherIvBytes, aes.blockSize);
62 | Uint8List paddedText = _processBlocks(cipher, cipherBytes);
63 | Uint8List? textBytes = _unpad(paddedText);
64 |
65 | if (textBytes == null) {
66 | return "";
67 | }
68 |
69 | return String.fromCharCodes(textBytes);
70 | }
71 |
72 | static Uint8List _buildKey() {
73 | if (passphrase.isEmpty) {
74 | throw ArgumentError('passphrase must not be empty');
75 | }
76 |
77 | Uint8List passphraseBytes = _createUint8ListFromString(passphrase);
78 | Uint8List saltBytes = _createUint8ListFromString(salt);
79 |
80 | Pbkdf2Parameters params = Pbkdf2Parameters(saltBytes, iterations, size);
81 | KeyDerivator keyDerivator = PBKDF2KeyDerivator(HMac(SHA1Digest(), 64));
82 | keyDerivator.init(params);
83 |
84 | return keyDerivator.process(passphraseBytes);
85 | }
86 |
87 | static Uint8List _pad(Uint8List src, int blockSize) {
88 | var pad = PKCS7Padding();
89 | pad.init(null);
90 |
91 | int padLength = blockSize - (src.length % blockSize);
92 | var out = Uint8List(src.length + padLength)..setAll(0, src);
93 | pad.addPadding(out, src.length);
94 |
95 | return out;
96 | }
97 |
98 | static Uint8List? _unpad(Uint8List src) {
99 | try {
100 | PKCS7Padding pad = PKCS7Padding();
101 | pad.init(null);
102 |
103 | int padLength = pad.padCount(src);
104 | int len = src.length - padLength;
105 |
106 | return Uint8List(len)..setRange(0, len, src);
107 | } catch (_) {
108 | return null;
109 | }
110 | }
111 |
112 | static Uint8List _processBlocks(BlockCipher cipher, Uint8List inp) {
113 | var out = Uint8List(inp.lengthInBytes);
114 |
115 | for (var offset = 0; offset < inp.lengthInBytes;) {
116 | var len = cipher.processBlock(inp, offset, out, offset);
117 | offset += len;
118 | }
119 |
120 | return out;
121 | }
122 |
123 | static Uint8List _createUint8ListFromString(String s) {
124 | Uint8List ret = Uint8List.fromList(s.codeUnits);
125 | return ret;
126 | }
127 | }
128 |
--------------------------------------------------------------------------------
/gic_flutter/lib/src/backend/services/firstRunService.dart:
--------------------------------------------------------------------------------
1 | import 'package:shared_preferences/shared_preferences.dart';
2 |
3 | class FirstRunService {
4 | static FirstRunService _instance = FirstRunService();
5 | static SharedPreferences? _preferences;
6 | static const String _prefFirstRun = "firstRun"; //show the whole intro thing
7 |
8 | static Future getInstance() async {
9 | if (_preferences == null) {
10 | _preferences = await SharedPreferences.getInstance();
11 | }
12 |
13 | return _instance;
14 | }
15 |
16 | dynamic _getBoolFromDisk(String key) {
17 | Object? value = true;
18 | if (_preferences!.containsKey(key)) {
19 | value = _preferences!.get(key);
20 | }
21 | return value;
22 | }
23 |
24 | void _saveBoolToDisk(String key, bool value){
25 | _preferences!.setBool(key, value);
26 | }
27 |
28 | bool get firstRun {
29 | bool firstRun = _getBoolFromDisk(_prefFirstRun);
30 | if (firstRun) {
31 | _saveBoolToDisk(_prefFirstRun, false);
32 | }
33 | return firstRun;
34 | }
35 | }
--------------------------------------------------------------------------------
/gic_flutter/lib/src/backend/services/networkService.dart:
--------------------------------------------------------------------------------
1 | import 'dart:convert';
2 | import 'dart:developer';
3 |
4 | import 'package:gic_flutter/src/backend/models/networkModel.dart';
5 | import 'package:gic_flutter/src/backend/models/screen/command.dart';
6 | import 'package:gic_flutter/src/views/launcher/screenList.dart';
7 | import 'package:http/http.dart' as http;
8 | import 'package:http/http.dart';
9 |
10 | enum NetworkResponse { Ok, OutOfDate, Error, Unauthorized }
11 |
12 | class NetworkService {
13 | static final String serverApiVersion = "2.1.0.1";
14 |
15 | static Future sendCommand(
16 | NetworkModel networkModel, String command, Command keystroke) async {
17 | String basicAuth =
18 | base64Encode(Latin1Codec().encode('gic:${networkModel.password}'));
19 | Map headers = Map();
20 | headers['Content-Type'] = 'application/json; charset=UTF-8';
21 | headers["Authorization"] = 'Basic $basicAuth';
22 |
23 | String body = json.encode(keystroke);
24 | NetworkResponse response = await http
25 | .post(
26 | Uri.http("${networkModel.address}:${networkModel.port}",
27 | "/api/$command"),
28 | body: body,
29 | headers: headers)
30 | .timeout(const Duration(seconds: 5))
31 | .then((response) {
32 | if (response.statusCode != 401)
33 | return NetworkResponse.Ok;
34 | else
35 | return NetworkResponse.Unauthorized;
36 | }).catchError((err) {
37 | log(err.toString());
38 | return NetworkResponse.Error;
39 | });
40 |
41 | return response;
42 | }
43 |
44 | static Future checkVersion(NetworkModel networkModel) async {
45 | Uri url = Uri.http("${networkModel.address}:${networkModel.port}", "api/version");
46 | try {
47 | Map headers = Map();
48 | String basicAuth =
49 | base64Encode(Latin1Codec().encode('gic:${networkModel.password}'));
50 | headers["Authorization"] = 'Basic $basicAuth';
51 | Response response = await http.post(url, headers: headers).timeout(const Duration(seconds: 5));
52 |
53 | if (response.statusCode < 500) {
54 | // If the server did return a 200 OK response then parse the JSON.
55 | if (response.statusCode == 401)
56 | return NetworkResponse.Unauthorized;
57 | VersionResponse versionResponse =VersionResponse.fromJson(jsonDecode(response.body));
58 | if (versionResponse.version == serverApiVersion) {
59 | return NetworkResponse.Ok;
60 | } else {
61 | return NetworkResponse.OutOfDate;
62 | }
63 | } else
64 | return NetworkResponse.Error;
65 | } catch (exception) {
66 | return NetworkResponse.Error;
67 | }
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/gic_flutter/lib/src/flavor.dart:
--------------------------------------------------------------------------------
1 | import 'package:meta/meta.dart';
2 |
3 | enum BuildFlavor { other, gplay }
4 |
5 | BuildEnvironment? _env;
6 |
7 | BuildEnvironment? get env => _env;
8 |
9 | class BuildEnvironment {
10 | final BuildFlavor flavor;
11 |
12 | BuildEnvironment._init({required this.flavor});
13 |
14 | static void init({@required flavor}) =>
15 | _env ??= BuildEnvironment._init(flavor: flavor);
16 | }
--------------------------------------------------------------------------------
/gic_flutter/lib/src/main_gplay.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:gic_flutter/src/service_locator.dart';
3 | import 'package:gic_flutter/src/theme/theme.dart';
4 | import 'package:flutter/foundation.dart';
5 | import 'app.dart';
6 | import 'flavor.dart';
7 |
8 | Future main() async {
9 | BuildEnvironment.init(flavor: BuildFlavor.gplay);
10 | var myApp = GicApp();
11 | var myTheme = CustomTheme(
12 | initialThemeKey: ThemeKeys.DARK,
13 | child: myApp,
14 | );
15 | WidgetsFlutterBinding.ensureInitialized();
16 | await setupLocator();
17 | runApp(myTheme);
18 | }
19 |
--------------------------------------------------------------------------------
/gic_flutter/lib/src/main_other.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:gic_flutter/src/service_locator.dart';
3 | import 'package:gic_flutter/src/theme/theme.dart';
4 | import 'app.dart';
5 | import 'flavor.dart';
6 |
7 | Future main() async {
8 | BuildEnvironment.init(flavor: BuildFlavor.other);
9 | var myApp = GicApp();
10 | var myTheme = CustomTheme(
11 | initialThemeKey: ThemeKeys.DARK,
12 | child: myApp,
13 | );
14 | WidgetsFlutterBinding.ensureInitialized();
15 | await setupLocator();
16 | runApp(myTheme);
17 | }
18 |
--------------------------------------------------------------------------------
/gic_flutter/lib/src/service_locator.dart:
--------------------------------------------------------------------------------
1 | import 'package:get_it/get_it.dart';
2 |
3 | import 'backend/services/firstRunService.dart';
4 |
5 | GetIt locator = GetIt.instance;
6 |
7 | Future setupLocator() async {
8 | var instance = await FirstRunService.getInstance();
9 | locator.registerSingleton(instance);
10 | }
--------------------------------------------------------------------------------
/gic_flutter/lib/src/theme/dimensions.dart:
--------------------------------------------------------------------------------
1 | double activityMargin = 16;
2 |
--------------------------------------------------------------------------------
/gic_flutter/lib/src/theme/style.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 |
3 | class DarkColors {
4 |
5 | }
6 |
7 | ThemeData myDarkTheme() {
8 | return ThemeData(
9 | primaryColor: Color(0xff3F51B5),
10 | primaryColorDark: Color(0xff2A41B3),
11 | scaffoldBackgroundColor: Color(0xFF383838),
12 | canvasColor: Color(0xFF383838),
13 | //buttonColor: Color(0xff575757),
14 | appBarTheme: const AppBarTheme(
15 | color: Colors.indigo,
16 | iconTheme: IconThemeData(color: Colors.white),
17 | foregroundColor: Color(0xA1F8F8F8)
18 | ),
19 | snackBarTheme: const SnackBarThemeData(
20 | actionTextColor: Colors.blue,
21 | backgroundColor: Colors.black54,
22 | contentTextStyle: TextStyle(color: Colors.white),
23 | ),
24 | // Define the default TextTheme. Use this to specify the default
25 | // text styling for headlines, titles, bodies of text, and more.
26 | textTheme: TextTheme(
27 | bodyMedium: TextStyle(color: Color(0xA1F8F8F8))
28 | ), colorScheme: ColorScheme.fromSwatch().copyWith(secondary: Color(0xff43a047),brightness: Brightness.dark,
29 |
30 | ).copyWith(error: Color(0xffF44336)),
31 | );
32 | }
33 |
34 | ThemeData myLightTheme() {
35 | return ThemeData(
36 | brightness: Brightness.light,
37 |
38 | primaryColor: Color(0xff3F51B5),
39 | primaryColorDark: Color(0xff2A41B3),
40 | scaffoldBackgroundColor: Color(0xffffffff),
41 | canvasColor: Color(0xFF383838),
42 |
43 | // Define the default TextTheme. Use this to specify the default
44 | // text styling for headlines, titles, bodies of text, and more.
45 | textTheme: TextTheme(
46 | bodyMedium: TextStyle(color: Color(0xFF383838))
47 | ), colorScheme: ColorScheme.fromSwatch().copyWith(secondary: Color(0xff43a047)).copyWith(error: Color(0xffF44336)),
48 | );
49 | }
--------------------------------------------------------------------------------
/gic_flutter/lib/src/theme/theme.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:gic_flutter/src/theme/style.dart';
3 |
4 | enum ThemeKeys { LIGHT, DARK }
5 |
6 | class MyAppThemes {
7 | static final lightTheme = ThemeData(
8 | primaryColor: myDarkTheme().primaryColor,
9 | brightness: Brightness.light,
10 | );
11 |
12 | static final darkTheme = ThemeData(
13 | primaryColor: myLightTheme().primaryColor,
14 | brightness: Brightness.dark,
15 | );
16 | }
17 |
18 | class Themes {
19 | static ThemeData getThemeFromKey(ThemeKeys themeKey) {
20 | switch (themeKey) {
21 | case ThemeKeys.LIGHT:
22 | return ThemeData.light();
23 | case ThemeKeys.DARK:
24 | return ThemeData.dark();
25 | default:
26 | return ThemeData.dark();
27 | }
28 | }
29 | }
30 |
31 | class _CustomTheme extends InheritedWidget {
32 | final CustomThemeState data;
33 |
34 | _CustomTheme({
35 | required this.data,
36 | Key? key,
37 | required Widget child,
38 | }) : super(key: key, child: child);
39 |
40 | @override
41 | bool updateShouldNotify(_CustomTheme oldWidget) {
42 | return true;
43 | }
44 | }
45 |
46 | class CustomTheme extends StatefulWidget {
47 | final Widget child;
48 | final ThemeKeys initialThemeKey;
49 |
50 | const CustomTheme({
51 | Key? key,
52 | required this.initialThemeKey,
53 | required this.child,
54 | }) : super(key: key);
55 |
56 | @override
57 | CustomThemeState createState() => CustomThemeState();
58 |
59 | static ThemeData of(BuildContext context) {
60 | _CustomTheme? inherited = context.dependOnInheritedWidgetOfExactType<_CustomTheme>();
61 | return inherited!.data.theme;
62 | }
63 |
64 | static CustomThemeState instanceOf(BuildContext context) {
65 | _CustomTheme? inherited = context.dependOnInheritedWidgetOfExactType<_CustomTheme>();
66 | return inherited!.data;
67 | }
68 | }
69 |
70 | class CustomThemeState extends State {
71 | late ThemeData _theme;
72 |
73 | ThemeData get theme => _theme;
74 |
75 | @override
76 | void initState() {
77 | _theme = Themes.getThemeFromKey(widget.initialThemeKey);
78 | super.initState();
79 | }
80 |
81 | void changeTheme(ThemeKeys themeKey) {
82 | setState(() {
83 | _theme = Themes.getThemeFromKey(themeKey);
84 | });
85 | }
86 |
87 | @override
88 | Widget build(BuildContext context) {
89 | return _CustomTheme(
90 | data: this,
91 | key: null,
92 | child: widget.child,
93 | );
94 | }
95 | }
--------------------------------------------------------------------------------
/gic_flutter/lib/src/views/about/aboutVM.dart:
--------------------------------------------------------------------------------
1 | import 'dart:core';
2 |
3 | import 'package:gic_flutter/src/backend/models/viewModel.dart';
4 | import 'package:gic_flutter/src/backend/models/viewSection.dart';
5 |
6 | class AboutVM implements ViewModel {
7 | String toolbarTitle = "";
8 |
9 | String appName = " ";
10 | String versionText = "";
11 | String libraryTitle = "";
12 | String emailTo = "";
13 | String emailTitle = "";
14 | String url = "";
15 | List? libraries;
16 | ViewSection legal = ViewSection("","","");
17 | ViewSection server = ViewSection("","","");
18 | }
19 |
20 |
--------------------------------------------------------------------------------
/gic_flutter/lib/src/views/about/aboutView.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:gic_flutter/src/backend/models/viewModel.dart';
3 | import 'package:gic_flutter/src/backend/models/viewSection.dart';
4 | import 'package:gic_flutter/src/theme/dimensions.dart' as dim;
5 |
6 | import '../basePage.dart';
7 | import 'aboutPresentation.dart';
8 | import 'aboutVM.dart';
9 |
10 | class AboutView extends BasePage {
11 | @override
12 | AboutViewState createState() {
13 | return AboutViewState();
14 | }
15 | }
16 |
17 | class AboutViewState extends BaseState {
18 | AboutVM viewModel = AboutVM();
19 |
20 | @override
21 | void initState() {
22 | presentation = AboutPresentation(this);
23 | super.initState();
24 | }
25 |
26 | @override
27 | void onLoadComplete(ViewModel viewModel) {
28 | setState(() {
29 | this.viewModel = viewModel as AboutVM;
30 | });
31 | }
32 |
33 | @override
34 | Widget build(BuildContext context) {
35 | String title = " ";
36 | title = viewModel.toolbarTitle;
37 | return Scaffold(
38 | appBar: AppBar(
39 | automaticallyImplyLeading: true,
40 | title: Text(title),
41 | ),
42 | body: SingleChildScrollView(
43 | child: Container(
44 | margin: EdgeInsets.all(dim.activityMargin),
45 | child: Column(
46 | crossAxisAlignment: CrossAxisAlignment.center,
47 | children: [
48 | header(viewModel.appName, Theme.of(context).textTheme.headlineMedium),
49 | Text(viewModel.versionText),
50 | link(viewModel.url),
51 | section(viewModel.server, centered: true),
52 | section(viewModel.legal, centered: true),
53 | header(viewModel.libraryTitle),
54 | _libraries(viewModel.libraries),
55 | ],
56 | ),
57 | ),
58 | ),
59 | );
60 | }
61 |
62 | Widget _libraries(List? sections) {
63 | if (sections != null) {
64 | List widgets = [];
65 | TextStyle? textStyle = Theme.of(context).textTheme.titleMedium;
66 | sections.forEach(
67 | (s) => widgets.add(section(s, optionalHeaderStyle: textStyle)));
68 |
69 | return Column(
70 | crossAxisAlignment: CrossAxisAlignment.start,
71 | children: widgets,
72 | );
73 | }
74 | return Column();
75 | }
76 |
77 | noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
78 | }
79 |
--------------------------------------------------------------------------------
/gic_flutter/lib/src/views/accentButton.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 |
3 | class AccentButton extends StatelessWidget {
4 | final VoidCallback? onPressed;
5 | final Widget? child;
6 |
7 | const AccentButton({this.child, this.onPressed, Key? key}) : super(key: key);
8 |
9 | @override
10 | Widget build(BuildContext context) {
11 | final theme = Theme.of(context);
12 |
13 | return ElevatedButton(
14 | onPressed: onPressed,
15 | child: child,
16 | // style: ElevatedButton.styleFrom(backgroundColor: theme.colorScheme.primary,
17 | // ),
18 | // textColor: theme.accentTextTheme.button.color,
19 | // highlightColor: theme.accentColor,
20 | );
21 | }
22 | }
--------------------------------------------------------------------------------
/gic_flutter/lib/src/views/basePage.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter_linkify/flutter_linkify.dart';
3 | import 'package:gic_flutter/src/backend/models/viewModel.dart';
4 | import 'package:gic_flutter/src/backend/models/viewSection.dart';
5 | import 'package:url_launcher/url_launcher.dart';
6 |
7 | abstract class BasePresentation {
8 | void buildVM(BuildContext context);
9 | }
10 |
11 | abstract class BasePage extends StatefulWidget {
12 | BasePage({Key? key}) : super(key: key);
13 | }
14 |
15 | abstract class BaseState extends State with WidgetsBindingObserver {
16 | BasePresentation? presentation;
17 |
18 | @override
19 | void initState() {
20 | WidgetsBinding.instance.addObserver(this);
21 | super.initState();
22 | }
23 |
24 | @override
25 | void didChangeDependencies() {
26 | presentation?.buildVM(context);
27 | super.didChangeDependencies();
28 | }
29 |
30 | // void onLoadComplete(ViewModel viewModel);
31 | //
32 | // void onError(int errorType);
33 | //
34 | @override
35 | void dispose() {
36 | WidgetsBinding.instance.removeObserver(this);
37 | super.dispose();
38 | }
39 |
40 | Widget section(ViewSection model, {TextStyle? optionalHeaderStyle, bool centered = false}) {
41 | var align = CrossAxisAlignment.start;
42 | if (centered) {
43 | align = CrossAxisAlignment.center;
44 | }
45 | return
46 | Column(
47 | crossAxisAlignment: align,
48 | children: [
49 | Padding(
50 | padding: const EdgeInsets.fromLTRB(0, 12, 0, 2),
51 | child: header(model.title, optionalHeaderStyle),
52 | ),
53 | Text(model.text),
54 | link(model.url)]
55 | );
56 | }
57 |
58 | Widget link(String link) {
59 | return Linkify(
60 | onOpen: (link) async {
61 | if (await canLaunch(link.url)) {
62 | await launch(link.url);
63 | } else {
64 | throw 'Could not launch $link';
65 | }
66 | },
67 | text: link
68 | );
69 | }
70 |
71 | Widget header(String text, [TextStyle? textStyle]) {
72 | if (textStyle == null) {
73 | textStyle = Theme.of(context).textTheme.headlineSmall;
74 | }
75 | return Text(
76 | text,
77 | style: textStyle,
78 | );
79 | }
80 |
81 | void onLoadComplete(ViewModel viewModel) {}
82 |
83 | void onError(int i) {}
84 | }
--------------------------------------------------------------------------------
/gic_flutter/lib/src/views/feedback/feedbackPresentation.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/cupertino.dart';
2 | import 'package:gic_flutter/src/backend/models/intl/intlFeedback.dart';
3 | import 'package:gic_flutter/src/backend/models/intl/localizations.dart';
4 | import 'package:gic_flutter/src/views/basePage.dart';
5 |
6 | import 'feedbackVM.dart';
7 |
8 | class FeedbackPresentation implements BasePresentation {
9 | BaseState _contract;
10 |
11 | FeedbackPresentation(this._contract);
12 |
13 | Future buildVM(BuildContext context) async {
14 | FeedbackVM _viewModel = FeedbackVM();
15 |
16 | _viewModel.toolbarTitle =
17 | Intl.of(context)!.feedback(FeedbackText.toolbarTitle);
18 | _viewModel.details = Intl.of(context)!.feedback(FeedbackText.details);
19 | _viewModel.updown = Intl.of(context)!.feedback(FeedbackText.updown);
20 | _viewModel.email = Intl.of(context)!.feedback(FeedbackText.email);
21 | _viewModel.emailTo = Intl.of(context)!.feedback(FeedbackText.emailTo);
22 | _viewModel.satisfaction = Intl.of(context)!.feedback(FeedbackText.satisfaction);
23 | _viewModel.githubIssues = Intl.of(context)!.feedback(FeedbackText.githubIssues);
24 | _viewModel.githubIssuesUrl = Intl.of(context)!.feedback(FeedbackText.githubIssuesUrl);
25 |
26 | _contract.onLoadComplete(_viewModel);
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/gic_flutter/lib/src/views/feedback/feedbackVM.dart:
--------------------------------------------------------------------------------
1 | import 'dart:core';
2 |
3 | import 'package:gic_flutter/src/backend/models/viewModel.dart';
4 |
5 | class FeedbackVM implements ViewModel {
6 | String toolbarTitle = "";
7 | String details = "";
8 | String updown = "";
9 | String email = "";
10 | String emailTo = "";
11 | String satisfaction = "";
12 | String githubIssues = "";
13 | String githubIssuesUrl = "";
14 | }
15 |
--------------------------------------------------------------------------------
/gic_flutter/lib/src/views/feedback/feedbackView.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:gic_flutter/src/backend/models/viewModel.dart';
3 | import 'package:gic_flutter/src/theme/dimensions.dart' as dim;
4 | import 'package:gic_flutter/src/views/feedback/feedbackVM.dart';
5 | import 'package:url_launcher/url_launcher.dart';
6 |
7 | import '../basePage.dart';
8 | import 'FeedbackPresentation.dart';
9 |
10 | class FeedbackView extends BasePage {
11 | @override
12 | FeedbackViewState createState() {
13 | return FeedbackViewState();
14 | }
15 | }
16 |
17 | class FeedbackViewState extends BaseState {
18 | FeedbackVM viewModel = FeedbackVM();
19 | String _feedback = "";
20 | List _isSelected = [false, false, false];
21 |
22 | @override
23 | void initState() {
24 | presentation = FeedbackPresentation(this);
25 | super.initState();
26 | }
27 |
28 | @override
29 | void onLoadComplete(ViewModel viewModel) {
30 | setState(() {
31 | this.viewModel = viewModel as FeedbackVM;
32 | });
33 | }
34 |
35 | @override
36 | Widget build(BuildContext context) {
37 | String title = " ";
38 | title = viewModel.toolbarTitle;
39 | return Scaffold(
40 | appBar: AppBar(
41 | automaticallyImplyLeading: true,
42 | title: Text(title),
43 | ),
44 | body: SingleChildScrollView(
45 | child: Container(
46 | margin: EdgeInsets.all(dim.activityMargin),
47 | child: Column(
48 | crossAxisAlignment: CrossAxisAlignment.center,
49 | children: [
50 | Text(viewModel.details),
51 | ElevatedButton(
52 | child: Text(viewModel.githubIssues),
53 | onPressed: () async {
54 | String url =
55 | viewModel.githubIssuesUrl;
56 | if (await canLaunch(url))
57 | await launch(url);
58 | else
59 | // can't launch url, there is some error
60 | throw "Could not launch $url";
61 | },),
62 | Padding(
63 | padding: const EdgeInsets.fromLTRB(0,32,0,0),
64 | child: header(viewModel.satisfaction),
65 | ),
66 | Text(viewModel.updown),
67 | Padding(
68 | padding: const EdgeInsets.fromLTRB(32.0, 0, 32.0, 0),
69 | child: ToggleButtons(
70 | children: [
71 | Icon(Icons.sentiment_satisfied, size: 64),
72 | Icon(Icons.sentiment_neutral, size: 64),
73 | Icon(Icons.sentiment_dissatisfied, size: 64),
74 | ],
75 | onPressed: (int index) {
76 | setState(() {
77 | for (int buttonIndex = 0; buttonIndex < _isSelected.length; buttonIndex++) {
78 | if (buttonIndex == index) {
79 | _isSelected[buttonIndex] = true;
80 | } else {
81 | _isSelected[buttonIndex] = false;
82 | }
83 | }
84 | _pickSatisfaction();
85 | });
86 | },
87 | isSelected: _isSelected,
88 | ),
89 | ),
90 | Padding(
91 | padding: const EdgeInsets.all(32.0),
92 | child: ElevatedButton(
93 | // onPressed: ,
94 | child: Row(
95 | mainAxisAlignment: MainAxisAlignment.center,
96 | children: [
97 | Text(viewModel.email),
98 | Padding(padding: const EdgeInsets.all(8.0)),
99 | Icon(Icons.email),
100 | ],
101 | ), onPressed: () {
102 | _sendEmail(viewModel.emailTo);
103 | },),
104 | )
105 | ],
106 | ),
107 | ),
108 | ));
109 | }
110 |
111 | _sendEmail(email) async {
112 | if (await canLaunch(email)) {
113 | await launch("$email$_feedback");
114 | } else {
115 | throw 'Could not launch $link';
116 | }
117 | }
118 |
119 | _pickSatisfaction() {
120 | if (_isSelected[0])
121 | _feedback = " :)";
122 | else if (_isSelected[1])
123 | _feedback = " :|";
124 | else
125 | _feedback = " :(";
126 | }
127 |
128 | noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
129 | }
130 |
--------------------------------------------------------------------------------
/gic_flutter/lib/src/views/intro/introView.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter/services.dart';
3 | import 'package:gic_flutter/src/backend/models/intl/localizations.dart';
4 | import 'package:gic_flutter/src/theme/theme.dart';
5 | import 'package:gic_flutter/src/views/launcher/launcher.dart';
6 | import 'package:gic_flutter/src/views/intro/introPresentation.dart';
7 | import 'package:introduction_screen/introduction_screen.dart';
8 |
9 | class IntroView extends StatefulWidget{
10 |
11 | const IntroView({Key? key}) : super(key: key);
12 |
13 | @override
14 | IntroViewState createState() {
15 | return IntroViewState();
16 | }
17 | }
18 |
19 | class IntroViewState extends State implements IntroViewContract {
20 | List? _pages;
21 | Color? _primaryColor;
22 | @override
23 | initState() {
24 | super.initState();
25 | }
26 |
27 | @override
28 | void didChangeDependencies() {
29 | super.didChangeDependencies();
30 | IntroPresentation(this).loadPages(context);
31 | }
32 |
33 | @override
34 | Widget build(BuildContext context) {
35 | SystemChrome.setSystemUIOverlayStyle(
36 | SystemUiOverlayStyle.dark.copyWith(statusBarColor: Colors.transparent),
37 | );
38 |
39 | _primaryColor = CustomTheme.of(context).primaryColor;
40 | if (_pages == null) {
41 | return Stack(
42 | children: [
43 | Opacity(
44 | opacity: 0.3,
45 | child: const ModalBarrier(dismissible: false, color: Colors.grey),
46 | ),
47 | Center(
48 | child: CircularProgressIndicator(),
49 | ),
50 | ],
51 | );
52 | } else {
53 | return IntroductionScreen(
54 | pages: _pages,
55 | dotsDecorator: DotsDecorator(
56 | activeColor: _primaryColor,
57 | ),
58 | onDone: () => _onIntroEnd(context),
59 | //onSkip: () => _onIntroEnd(context), // You can override onSkip callback
60 | showSkipButton: true,
61 | skipOrBackFlex: 0,
62 | nextFlex: 0,
63 | skip: Text(Intl.of(context)!.onboardSkip),
64 | next: const Icon(Icons.arrow_forward),
65 | done: Text(Intl.of(context)!.onboardDone, style: TextStyle(fontWeight: FontWeight.w600)),
66 | );
67 | }
68 | }
69 |
70 | @override
71 | void onIntroLoadCompleted(List pages) {
72 | setState(() {
73 | _pages = pages;
74 | });
75 | }
76 |
77 | void _onIntroEnd(context) {
78 | Navigator.pushReplacement(context,
79 | MaterialPageRoute(builder: (context) => Launcher())
80 | );
81 | }
82 | }
83 |
84 |
--------------------------------------------------------------------------------
/gic_flutter/lib/src/views/intro/screenListWidget.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:gic_flutter/src/theme/theme.dart';
3 |
4 | class ScreenItem {
5 | String title;
6 | bool selected = false;
7 | ScreenItem(this.title);
8 | }
9 |
10 | class ScreenListWidget extends StatefulWidget {
11 | final List _screens;
12 | ScreenListWidget(this._screens, {Key? key}) : super(key: key);
13 |
14 | @override
15 | _ScreenListWidgetState createState() => _ScreenListWidgetState();
16 | }
17 |
18 | class _ScreenListWidgetState extends State {
19 | @override
20 | Widget build(BuildContext context) {
21 | Color accent = CustomTheme
22 | .of(context)
23 | .primaryColor;
24 | return SizedBox(
25 | width: 200.0,
26 | height: 200.0,
27 | child: ListView(
28 | children: [
29 | Ink(
30 | color: widget._screens[0].selected ? accent : Colors.transparent,
31 | child: ListTile(
32 | title: Text(widget._screens[0].title),
33 | onTap: () {
34 | setState(() {
35 | widget._screens[0].selected = ! widget._screens[0].selected;
36 | });
37 | },
38 | )
39 | ),
40 | Ink(
41 | color: widget._screens[1].selected ? accent : Colors.transparent,
42 | child: ListTile(
43 | title: Text(widget._screens[1].title),
44 | onTap: () {
45 | setState(() {
46 | widget._screens[1].selected = ! widget._screens[1].selected;
47 | });
48 | },
49 | )
50 | ),
51 | ],
52 | ),
53 | );
54 | }
55 | }
56 |
57 |
--------------------------------------------------------------------------------
/gic_flutter/lib/src/views/intro/screenSizeWidget.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 |
3 | class ScreenSizeWidget extends StatefulWidget {
4 | final Function(String) onSelectParam;
5 |
6 | ScreenSizeWidget(this.onSelectParam, {Key? key}) : super(key: key);
7 |
8 | @override
9 | _ScreenSizeWidgetState createState() => _ScreenSizeWidgetState();
10 | }
11 |
12 | class _ScreenSizeWidgetState extends State {
13 | List dropdownItems = ['Phone', 'Small Tablet', 'Large Tablet'];
14 | String device = "";
15 | _ScreenSizeWidgetState() {
16 | device = (dropdownItems[0]);
17 | }
18 | @override
19 | Widget build(BuildContext context) {
20 | return SizedBox(
21 | width: 150.0,
22 | height: 100.0,
23 | child: Center(
24 | child: getDropdown()
25 | ),
26 | );
27 | }
28 | DropdownButton getDropdown() {
29 | return DropdownButton(
30 | value: device,
31 | elevation: 16,
32 | underline: Container(
33 | height: 2,
34 | ),
35 | onChanged: (String? newValue) {
36 | setState(() {
37 | device = newValue!;
38 | widget.onSelectParam(device);
39 | });
40 | },
41 | items: dropdownItems.map>((String value) {
42 | return DropdownMenuItem(
43 | value: value,
44 | child: Text(value),
45 | );
46 | }).toList(),
47 | );
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/gic_flutter/lib/src/views/menuOption.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 |
3 | class MenuOption {
4 | const MenuOption({this.title = "", this.icon = Icons.new_label});
5 |
6 | final String title;
7 | final IconData icon;
8 | }
9 |
--------------------------------------------------------------------------------
/gic_flutter/lib/src/views/newScreenWizard/controlDesignWidget.dart:
--------------------------------------------------------------------------------
1 | // this widget handles setting if we are portrait or landscape mode
2 | import 'package:flutter/material.dart';
3 | import 'package:gic_flutter/src/backend/models/intl/intlNewScreenWizard.dart';
4 |
5 | import 'newScreenWizard.dart';
6 |
7 | class ControlDesignWidget extends StatefulWidget {
8 | final NewScreenWizardState state;
9 |
10 | const ControlDesignWidget ( this.state, {Key? key }): super(key: key);
11 |
12 | @override
13 | State createState() => ControlDesignState();
14 |
15 | }
16 |
17 | class ControlDesignState extends State {
18 | Icon? icon;
19 |
20 | @override
21 | void initState() {
22 | _setButton();
23 | super.initState();
24 | }
25 |
26 | @override
27 | Widget build(BuildContext context) {
28 | return Container(
29 | child: Column(
30 | crossAxisAlignment: CrossAxisAlignment.center,
31 | children: [
32 | Text(
33 | widget.state.translation.text(NewScreenWizardText.buttonDesign),
34 | style: Theme.of(context).textTheme.headlineSmall,
35 | ),
36 | Container(
37 | height: 50.0,
38 | child: ElevatedButton(
39 | onPressed: () {},
40 | // shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(80.0)),
41 | // padding: EdgeInsets.all(0.0),
42 | child: Ink(
43 | decoration: BoxDecoration(
44 | gradient: LinearGradient(colors: [Color(0xff374ABE), Color(0xff64B6FF)],
45 | begin: Alignment.topRight,
46 | ),
47 | ),
48 | child: Container(
49 | constraints: BoxConstraints(maxWidth: 300.0, minHeight: 50.0),
50 | alignment: Alignment.center,
51 | child: Text(
52 | "Login",
53 | textAlign: TextAlign.center,
54 | style: TextStyle(
55 | color: Colors.white
56 | ),
57 | ),
58 | ),
59 | ),
60 | ),
61 | ),
62 | ],
63 | ),
64 | );
65 | }
66 |
67 | // void _updateControlDesign() {
68 | // setState(() {
69 | // widget.state.viewModel.isLandscape = !widget.state.viewModel.isLandscape;
70 | // _setButton();
71 | // });
72 | // }
73 |
74 | void _setButton() {
75 | icon = Icon(Icons.screen_lock_portrait);
76 | if (widget.state.viewModel.isLandscape) {
77 | icon = Icon(Icons.screen_lock_landscape);
78 | }
79 | }
80 | }
81 |
82 |
--------------------------------------------------------------------------------
/gic_flutter/lib/src/views/newScreenWizard/layoutWidget.dart:
--------------------------------------------------------------------------------
1 | // this widget handles setting if we are portrait or landscape mode
2 | import 'package:flutter/material.dart';
3 | import 'package:gic_flutter/src/backend/models/intl/intlNewScreenWizard.dart';
4 |
5 | import 'newScreenWizard.dart';
6 |
7 | class LayoutWidget extends StatefulWidget {
8 | final NewScreenWizardState state;
9 |
10 | const LayoutWidget ( this.state, {Key? key }): super(key: key);
11 |
12 | @override
13 | State createState() => LayoutState();
14 | }
15 |
16 | class LayoutState extends State {
17 | @override
18 | Widget build(BuildContext context) {
19 | return Container(
20 | child: Column(
21 | crossAxisAlignment: CrossAxisAlignment.center,
22 | children: [
23 | Text(
24 | widget.state.translation.text(NewScreenWizardText.layout),
25 | style: Theme.of(context).textTheme.headlineSmall,
26 | ),
27 | Row(
28 | mainAxisAlignment: MainAxisAlignment.spaceEvenly,
29 | children: [
30 | ElevatedButton(onPressed: () { _updateCount(horizontal: -1); },
31 | child: Text("${widget.state.translation.text(NewScreenWizardText.decrease)}"),),
32 | Text("${widget.state.viewModel.horizontalControlCount} ${widget.state.translation.text(NewScreenWizardText.controlsWide)}"),
33 | ElevatedButton(onPressed: () { _updateCount(horizontal: 1); },
34 | child: Text("${widget.state.translation.text(NewScreenWizardText.increase)}"),),
35 | ],
36 | ),
37 | Row(
38 | mainAxisAlignment: MainAxisAlignment.spaceEvenly,
39 | children: [
40 | ElevatedButton(onPressed: () { _updateCount(vertical: -1); },
41 | child: Text("${widget.state.translation.text(NewScreenWizardText.decrease)}"),),
42 | Text("${widget.state.viewModel.verticalControlCount} ${widget.state.translation.text(NewScreenWizardText.controlsDepth)}"),
43 | ElevatedButton(onPressed: () { _updateCount(vertical: 1); },
44 | child: Text("${widget.state.translation.text(NewScreenWizardText.increase)}"),),
45 | ],
46 | ),
47 | Text("${widget.state.viewModel.horizontalControlCount * widget.state.viewModel.verticalControlCount } ${widget.state.translation.text(NewScreenWizardText.totalControls)}",),
48 | ]
49 | )
50 | );
51 | }
52 |
53 | void _updateCount({int horizontal=0, int vertical=0}) {
54 | setState(() {
55 | if (widget.state.viewModel.horizontalControlCount + horizontal > 0 &&
56 | widget.state.viewModel.horizontalControlCount + horizontal < 25) {
57 | widget.state.viewModel.horizontalControlCount += horizontal;
58 | }
59 | if (widget.state.viewModel.verticalControlCount + vertical > 0 &&
60 | widget.state.viewModel.verticalControlCount + vertical < 25) {
61 | widget.state.viewModel.verticalControlCount += vertical;
62 | }
63 | });
64 | }
65 | }
66 |
67 |
--------------------------------------------------------------------------------
/gic_flutter/lib/src/views/newScreenWizard/newScreenWizardGeneral.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:gic_flutter/src/backend/models/intl/intlNewScreenWizard.dart';
3 | import 'package:gic_flutter/src/theme/dimensions.dart' as dim;
4 |
5 | import 'layoutWidget.dart';
6 | import 'orientationWidget.dart';
7 | import 'newScreenWizard.dart';
8 |
9 | class NewScreenWizardGeneral extends StatefulWidget {
10 | final NewScreenWizardState state;
11 |
12 | const NewScreenWizardGeneral (this.state, { Key? key }): super(key: key);
13 |
14 | @override
15 | State createState() {
16 | state.screenNameTextController.addListener(() { state.viewModel.screenName = state.screenNameTextController.text;});
17 | return NewScreenWizardGeneralState();
18 | }
19 | }
20 |
21 | class NewScreenWizardGeneralState extends State {
22 | @override
23 | Widget build(BuildContext context) {
24 | return SingleChildScrollView(
25 | child: Padding(
26 | padding: EdgeInsets.all(dim.activityMargin),
27 | child: Column(
28 | children: [
29 | TextField(
30 | controller: widget.state.screenNameTextController,
31 | decoration: InputDecoration(
32 | hintText: widget.state.translation.text(NewScreenWizardText.screenName)),
33 |
34 | ),
35 | OrientationWidget(widget.state),
36 | LayoutWidget(widget.state),
37 | //ControlDesignWidget(widget.state),
38 | ],
39 | ),
40 | ),
41 | );
42 |
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/gic_flutter/lib/src/views/options/optionsPresentation.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/cupertino.dart';
2 | import 'package:gic_flutter/src/backend/models/intl/intlOptions.dart';
3 | import 'package:gic_flutter/src/backend/models/intl/localizations.dart';
4 | import 'package:gic_flutter/src/backend/models/launcherModel.dart';
5 | import 'package:gic_flutter/src/backend/repositories/launcherRepository.dart';
6 | import 'package:gic_flutter/src/views/basePage.dart';
7 |
8 | import 'optionsVM.dart';
9 |
10 | class OptionsPresentation implements BasePresentation {
11 | BaseState _contract;
12 | LauncherRepository _repository = LauncherRepository();
13 | OptionsVM? _viewModel;
14 |
15 | OptionsPresentation(this._contract);
16 |
17 | Future buildVM(BuildContext context) async {
18 | _viewModel = OptionsVM();
19 | _viewModel!.toolbarTitle =
20 | Intl.of(context)!.options(OptionsText.toolbarTitle);
21 | _viewModel!.darkModeTitle =
22 | Intl.of(context)!.options(OptionsText.darkModeTitle);
23 | _viewModel!.darkModelText =
24 | Intl.of(context)!.options(OptionsText.darkModeText);
25 | _viewModel!.soundTitle = Intl.of(context)!.options(OptionsText.soundTitle);
26 | _viewModel!.soundText = Intl.of(context)!.options(OptionsText.soundText);
27 | _viewModel!.vibrationTitle =
28 | Intl.of(context)!.options(OptionsText.vibrationTitle);
29 | _viewModel!.vibrationText =
30 | Intl.of(context)!.options(OptionsText.vibrationText);
31 | _viewModel!.keepScreenOnTitle =
32 | Intl.of(context)!.options(OptionsText.keepScreenOnTitle);
33 | _viewModel!.keepScreenOnText =
34 | Intl.of(context)!.options(OptionsText.keepScreenOnText);
35 | await _fetchAllPreferences();
36 | _contract.onLoadComplete(_viewModel!);
37 | }
38 |
39 | void setTheme(bool isDarkMode) {
40 | _repository.setDarkMode(isDarkMode);
41 | _viewModel!.darkMode = isDarkMode;
42 | _contract.onLoadComplete(_viewModel!);
43 | }
44 |
45 | void setVibration(bool hapticsEnabled) {
46 | _repository.setVibration(hapticsEnabled);
47 | _viewModel!.vibration = hapticsEnabled;
48 | _contract.onLoadComplete(_viewModel!);
49 | }
50 |
51 | void setSound(bool soundEnabled) {
52 | _repository.setSound(soundEnabled);
53 | _viewModel!.sound = soundEnabled;
54 | _contract.onLoadComplete(_viewModel!);
55 | }
56 |
57 | void setScreenOn(bool keepScreenOn) {
58 | _repository.setScreenOn(keepScreenOn);
59 | _viewModel!.keepScreenOn = keepScreenOn;
60 | _contract.onLoadComplete(_viewModel!);
61 | }
62 |
63 | Future _fetchAllPreferences() async {
64 | LauncherModel itemModel = await _repository.fetch();
65 | _viewModel!.darkMode = itemModel.darkMode;
66 | _viewModel!.vibration = itemModel.vibration;
67 | _viewModel!.sound = itemModel.sound;
68 | _viewModel!.keepScreenOn = itemModel.keepScreenOn;
69 | }
70 | }
71 |
--------------------------------------------------------------------------------
/gic_flutter/lib/src/views/options/optionsVM.dart:
--------------------------------------------------------------------------------
1 | import 'dart:core';
2 |
3 | import 'package:gic_flutter/src/backend/models/viewModel.dart';
4 |
5 | class OptionsVM implements ViewModel {
6 | String _toolbarTitle = "";
7 | String darkModeTitle = "";
8 | String darkModelText = "";
9 | String _soundTitle = "";
10 | String _soundText = "";
11 | String _vibrationTitle = "";
12 | String _vibrationText = "";
13 | String _keepScreenOnTitle = "";
14 | String _keepScreenOnText = "";
15 |
16 | bool _sound = false;
17 | bool _haptics = false;
18 | bool _darkMode = true;
19 | bool _keepScreenOn = false;
20 |
21 | String get toolbarTitle => _toolbarTitle;
22 | String get soundTitle => _soundTitle;
23 | String get soundText => _soundText;
24 | String get vibrationTitle => _vibrationTitle;
25 | String get vibrationText => _vibrationText;
26 | String get keepScreenOnTitle => _keepScreenOnTitle;
27 | String get keepScreenOnText => _keepScreenOnText;
28 |
29 | bool get darkMode => _darkMode;
30 | bool get vibration => _haptics;
31 | bool get sound => _sound;
32 | bool get keepScreenOn => _keepScreenOn;
33 |
34 | set toolbarTitle(String toolbarTitle) {
35 | _toolbarTitle = toolbarTitle;
36 | }
37 |
38 | set darkMode(bool darkTheme) {
39 | _darkMode = darkTheme;
40 | }
41 |
42 | set vibration(bool haptics) {
43 | _haptics = haptics;
44 | }
45 |
46 | set sound(bool sound) {
47 | _sound = sound;
48 | }
49 |
50 | set keepScreenOn(bool keepScreenOn) {
51 | _keepScreenOn = keepScreenOn;
52 | }
53 |
54 | set soundTitle(String soundTitle) {
55 | _soundTitle = soundTitle;
56 | }
57 |
58 | set soundText(String soundText) {
59 | _soundText = soundText;
60 | }
61 |
62 | set vibrationTitle(String vibrationTitle) {
63 | _vibrationTitle = vibrationTitle;
64 | }
65 |
66 | set vibrationText(String vibrationText) {
67 | _vibrationText = vibrationText;
68 | }
69 |
70 | set keepScreenOnTitle(String keepScreenOnTitle) {
71 | _keepScreenOnTitle = keepScreenOnTitle;
72 | }
73 |
74 | set keepScreenOnText(String keepScreenOnText) {
75 | _keepScreenOnText = keepScreenOnText;
76 | }
77 | }
78 |
--------------------------------------------------------------------------------
/gic_flutter/lib/src/views/screen/gicControl.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:gic_flutter/src/backend/models/networkModel.dart';
3 | import 'package:gic_flutter/src/views/baseGicControl.dart';
4 | import 'package:gic_flutter/src/views/screen/screenView.dart';
5 |
6 | class GicControl extends BaseGicControl {
7 | final NetworkModel? networkModel;
8 | final BoxConstraints? constraints;
9 | final ScreenView? screenView;
10 |
11 | GicControl(
12 | {
13 | Key? key,
14 | required control,
15 | required this.networkModel,
16 | required pixelRatio,
17 | this.screenView,
18 | this.constraints
19 | })
20 | : super(
21 | key: key,
22 | control: control,
23 | pixelRatio: pixelRatio,
24 | constraints: constraints);
25 |
26 | @override
27 | State createState() {
28 | return GicButtonState(
29 | control: control,
30 | networkModel: networkModel,
31 | pixelRatio: pixelRatio,
32 | constraints: constraints);
33 | }
34 | }
35 |
36 | class GicButtonState extends BaseGicControlState {
37 | final NetworkModel? networkModel;
38 | final BoxConstraints? constraints;
39 |
40 | GicButtonState(
41 | {required control,
42 | required this.networkModel,
43 | required pixelRatio,
44 | required this.constraints})
45 | : super(control: control, pixelRatio: pixelRatio);
46 |
47 | void sendCommand(String? commandUrl, int commandIndex, bool provideFeedback) {
48 | if ((widget as GicControl).screenView != null)
49 | (widget as GicControl).screenView!.sendCommand(control, commandUrl!, context, commandIndex, provideFeedback).ignore();
50 | }
51 |
52 | GestureDetector buildControl() {
53 | return GestureDetector(
54 | onTapDown: (TapDownDetails details) => onTap(),
55 | onTapUp: (TapUpDetails details) => onTapUp(),
56 | child: buildControlContainer(constraints));
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/gic_flutter/lib/src/views/screen/screenVM.dart:
--------------------------------------------------------------------------------
1 | import 'dart:core';
2 |
3 | import 'package:gic_flutter/src/backend/models/networkModel.dart';
4 | import 'package:gic_flutter/src/backend/models/screen/viewModels/screenViewModel.dart';
5 | import 'package:gic_flutter/src/backend/models/viewModel.dart';
6 |
7 | class ScreenVM implements ViewModel {
8 | final ScreenViewModel screen;
9 | final NetworkModel networkModel;
10 | final bool playSound;
11 | final bool vibration;
12 | final bool keepScreenOn;
13 |
14 | ScreenVM(this.screen, this.networkModel, this.playSound, this.vibration,
15 | this.keepScreenOn);
16 |
17 | @override
18 | // TODO: implement toolbarTitle
19 | String get toolbarTitle => throw UnimplementedError();
20 | }
21 |
--------------------------------------------------------------------------------
/gic_flutter/lib/src/views/screen/screenView.dart:
--------------------------------------------------------------------------------
1 | import 'dart:io';
2 |
3 | import 'package:audioplayers/audioplayers.dart';
4 | import 'package:flutter/material.dart';
5 | import 'package:flutter/services.dart';
6 | import 'package:gic_flutter/src/backend/models/screen/viewModels/controlViewModel.dart';
7 | import 'package:gic_flutter/src/backend/services/networkService.dart';
8 | import 'package:gic_flutter/src/views/screen/screenVM.dart';
9 | import 'package:keep_screen_on/keep_screen_on.dart';
10 |
11 | import 'gicControl.dart';
12 |
13 | /// Wrapper for stateful functionality to provide onInit calls in our stateless
14 | /// screenview widget
15 | class ScreenViewStatefulWrapper extends StatefulWidget {
16 | final ScreenVM viewModel;
17 |
18 | const ScreenViewStatefulWrapper({required this.viewModel});
19 | @override
20 | _StatefulWrapperState createState() => _StatefulWrapperState(this.viewModel);
21 | }
22 |
23 | class _StatefulWrapperState extends State {
24 | final ScreenVM viewModel;
25 |
26 | _StatefulWrapperState(this.viewModel);
27 |
28 | @override
29 | void initState() {
30 | super.initState();
31 | SystemChrome.setEnabledSystemUIMode(SystemUiMode.immersiveSticky);
32 | }
33 |
34 | @override
35 | Widget build(BuildContext context) {
36 | return ScreenView(screenVM: viewModel);
37 | }
38 |
39 | @override
40 | void dispose() {
41 | super.dispose();
42 | KeepScreenOn.turnOff();
43 | }
44 | }
45 |
46 | class ScreenView extends StatelessWidget {
47 | final List widgets = [];
48 | final ScreenVM screenVM;
49 | final AudioPlayer player = new AudioPlayer();
50 | final alarmAudioPath = "audio/flick.wav";
51 |
52 | ScreenView({Key? key, required this.screenVM});
53 |
54 | @override
55 | Widget build(BuildContext context) {
56 | double pixelRatio = MediaQuery.of(context).devicePixelRatio;
57 | screenVM.screen.controls!.forEach((element) {
58 | widgets.add(_buildGicControl(element, pixelRatio));
59 | });
60 | if (screenVM.keepScreenOn) {
61 | KeepScreenOn.turnOn();
62 | }
63 |
64 | if (screenVM.screen.backgroundPath != null &&
65 | screenVM.screen.backgroundPath!.isNotEmpty) {
66 | imageCache.clear();
67 | imageCache.clearLiveImages();
68 |
69 | return Scaffold(
70 | body: Container(
71 | decoration: BoxDecoration(
72 | image: DecorationImage(
73 | image: FileImage(File(screenVM.screen.backgroundPath!)),
74 | fit: BoxFit.fill,
75 | ),
76 | ),
77 | child: Stack(children: widgets),
78 | ),
79 | );
80 | } else {
81 | return Scaffold(
82 | body: Container(
83 | color: screenVM.screen.backgroundColor,
84 | child: Stack(children: widgets),
85 | ),
86 | );
87 | }
88 | }
89 |
90 | Widget _buildGicControl(ControlViewModel element, double pixelRatio) {
91 | return Positioned(
92 | left: element.left / pixelRatio,
93 | top: element.top / pixelRatio,
94 | child: GicControl(
95 | control: element,
96 | networkModel: screenVM.networkModel,
97 | screenView: this,
98 | pixelRatio: pixelRatio));
99 | }
100 |
101 | Future sendCommand(ControlViewModel control, String commandUrl, BuildContext context,
102 | int commandIndex, bool provideFeedback) async {
103 | if (provideFeedback) {
104 | playSound();
105 | vibration();
106 | }
107 | NetworkResponse response = await NetworkService.sendCommand(
108 | screenVM.networkModel, commandUrl, control.commands[commandIndex]);
109 | if (response == NetworkResponse.Error) {
110 | var snackBar = SnackBar(content: Text("Error Connecting to Server"));
111 | ScaffoldMessenger.of(context).showSnackBar(snackBar);
112 | } else if (response == NetworkResponse.Unauthorized) {
113 | var snackBar = SnackBar(content: Text("Unauthorized, check that the passwords match"));
114 | ScaffoldMessenger.of(context).showSnackBar(snackBar);
115 | }
116 | }
117 |
118 | void playSound() {
119 | if (screenVM.playSound) {
120 | player.play(AssetSource(alarmAudioPath));
121 | }
122 | }
123 |
124 | void vibration() {
125 | if (screenVM.vibration) {
126 | HapticFeedback.lightImpact().ignore();
127 | }
128 | }
129 | }
130 |
--------------------------------------------------------------------------------
/gic_flutter/lib/src/views/screenEditor/backgroundDialog.dart:
--------------------------------------------------------------------------------
1 | import 'dart:io';
2 |
3 | import 'package:file_picker/file_picker.dart';
4 | import 'package:flutter/material.dart';
5 | import 'package:gic_flutter/src/backend/models/intl/intlScreenEditor.dart';
6 | import 'package:gic_flutter/src/backend/models/screen/viewModels/screenViewModel.dart';
7 | import 'package:gic_flutter/src/views/screenEditor/colorPickerDialog.dart';
8 | import 'package:gic_flutter/src/views/screenEditor/settingsDialog/dialogButton.dart';
9 | import 'package:path/path.dart' as path;
10 | import 'package:path_provider/path_provider.dart';
11 |
12 | class BackgroundDialog extends StatefulWidget {
13 | final IntlScreenEditor? translation;
14 | final ScreenViewModel? screenViewModel;
15 |
16 | const BackgroundDialog({Key? key, this.translation, this.screenViewModel})
17 | : super(key: key);
18 |
19 | @override
20 | _BackgroundDialogState createState() =>
21 | _BackgroundDialogState(translation!, screenViewModel!);
22 | }
23 |
24 | class _BackgroundDialogState extends State {
25 | IntlScreenEditor translation;
26 | ScreenViewModel screenViewModel;
27 |
28 | _BackgroundDialogState(this.translation, this.screenViewModel);
29 |
30 | @override
31 | Widget build(BuildContext context) {
32 | return SimpleDialog(
33 | title: Text(translation.text(ScreenEditorText.backgroundMenu)),
34 | children: [
35 | DialogButton(
36 | icon: Icons.image,
37 | color: Colors.blue,
38 | text: translation.text(ScreenEditorText.backgroundImage),
39 | onPressed: () {
40 | _pickBackgroundImage();
41 | }),
42 | DialogButton(
43 | icon: Icons.color_lens,
44 | color: Colors.green,
45 | text: translation.text(ScreenEditorText.backgroundColor),
46 | onPressed: () {
47 | _pickBackgroundColor();
48 | },
49 | ),
50 | ],
51 | );
52 | }
53 |
54 | void _pickBackgroundImage() async {
55 | await FilePicker.platform.clearTemporaryFiles();
56 | FilePickerResult? result = await FilePicker.platform.pickFiles(
57 | type: FileType.custom,
58 | allowedExtensions: ['jpg', 'png', 'gif'],
59 | );
60 | if (result != null) {
61 | imageCache.clear();
62 | imageCache.clearLiveImages();
63 |
64 | PlatformFile file = result.files.first;
65 | Directory dest = await getApplicationDocumentsDirectory();
66 | String destPath = path.join(
67 | dest.path, "screens", screenViewModel.screenId.toString(), path.basename(file.path!));
68 | if (screenViewModel.backgroundPath != null && File(screenViewModel.backgroundPath!).existsSync())
69 | File(screenViewModel.backgroundPath!).deleteSync();
70 | File newFile = File(file.path!).copySync(destPath);
71 | setState(() {
72 | screenViewModel.backgroundPath = newFile.path;
73 |
74 | Navigator.pop(context, true);
75 | });
76 | }
77 | }
78 |
79 | void _pickedColor(Color color) {
80 | screenViewModel.backgroundColor = color.withAlpha(255);
81 | screenViewModel.backgroundPath = "";
82 | Navigator.pop(context);
83 | }
84 |
85 | void _pickBackgroundColor() {
86 | showDialog(
87 | context: context,
88 | builder: (_) => ColorPickerDialog(
89 | title: translation.text(ScreenEditorText.backgroundColor),
90 | pickerColor: screenViewModel.backgroundColor,
91 | onPressedCallback: _pickedColor,
92 | ));
93 | }
94 | }
95 |
--------------------------------------------------------------------------------
/gic_flutter/lib/src/views/screenEditor/colorPickerDialog.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter_colorpicker/flutter_colorpicker.dart';
3 |
4 | class ColorDialog {
5 | static Color? pickerColor;
6 |
7 | static show(BuildContext context, changeColorCallback, onPressedCallback) {
8 | return showDialog(
9 | context: context,
10 | builder: (BuildContext context) {
11 | return AlertDialog(
12 | title: const Text('Pick a color!'),
13 | content: SingleChildScrollView(
14 | child: ColorPicker(
15 | pickerColor: pickerColor!,
16 | onColorChanged: changeColorCallback,
17 | showLabel: true,
18 | pickerAreaHeightPercent: 0.8,
19 | ),
20 | ),
21 | actions: [
22 | TextButton(
23 | child: const Text('Got it'),
24 | onPressed: onPressedCallback,
25 | ),
26 | ],
27 | );
28 | },
29 | );
30 | }
31 | }
32 |
33 | class ColorPickerDialog extends StatefulWidget {
34 | final Function(Color color)? onPressedCallback;
35 | final String? title;
36 | final Color? pickerColor;
37 |
38 | const ColorPickerDialog(
39 | {Key? key, this.title, this.onPressedCallback, this.pickerColor})
40 | : super(key: key);
41 |
42 | @override
43 | _ColorPickerDialogState createState() => _ColorPickerDialogState(pickerColor!);
44 | }
45 |
46 | class _ColorPickerDialogState extends State {
47 | Color pickerColor;
48 |
49 | _ColorPickerDialogState(this.pickerColor) {
50 |
51 | }
52 |
53 | @override
54 | Widget build(BuildContext context) {
55 | return AlertDialog(
56 | title: Text(widget.title!),
57 | content: SingleChildScrollView(
58 | child: ColorPicker(
59 | pickerColor: pickerColor,
60 | onColorChanged: (Color color) {
61 | setState(() => pickerColor = color);
62 | },
63 | showLabel: true,
64 | enableAlpha: false,
65 | )),
66 | actions: [
67 | TextButton(
68 | child: Text("OK"),
69 | onPressed: () {
70 | widget.onPressedCallback!(pickerColor);
71 | Navigator.pop(context);
72 | }),
73 | ],
74 | );
75 | }
76 | }
77 |
--------------------------------------------------------------------------------
/gic_flutter/lib/src/views/screenEditor/controlDialog/baseTab.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:gic_flutter/src/backend/models/intl/intlScreenEditor.dart';
3 | import 'package:gic_flutter/src/backend/models/screen/controlDefaults.dart';
4 | import 'package:gic_flutter/src/views/screen/gicControl.dart';
5 | import 'package:gic_flutter/src/views/screenEditor/gicEditControl.dart';
6 |
7 | abstract class BaseTab extends StatefulWidget {
8 | final IntlScreenEditor translation;
9 | final GicEditControl gicEditControl;
10 | final int? screenId;
11 | final ControlDefaults? defaultControls;
12 |
13 | BaseTab({Key? key, required this.gicEditControl, required this.translation, required this.screenId, this.defaultControls})
14 | : super(key: key);
15 | }
16 |
17 | abstract class BaseTabState extends State {
18 | @protected
19 | double pixelRatio = 1;
20 |
21 | @protected
22 | Widget preview([BoxConstraints? constraints]) {
23 | return Column(
24 | children: [
25 | Padding(
26 | padding: const EdgeInsets.all(16.0),
27 | child: Text(widget.translation.text(ScreenEditorText.previewHeader),
28 | style: Theme.of(context).textTheme.headlineSmall),
29 | ),
30 | FittedBox(
31 | child: GicControl(
32 | constraints: constraints!,
33 | pixelRatio: pixelRatio,
34 | control: widget.gicEditControl.control,
35 | networkModel: null,
36 | ),
37 | ),
38 | ],
39 | );
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/gic_flutter/lib/src/views/screenEditor/controlDialog/imageDialog.dart:
--------------------------------------------------------------------------------
1 | import 'dart:convert';
2 | import 'dart:io';
3 |
4 | import 'package:flutter/material.dart';
5 | import 'package:flutter/services.dart';
6 | import 'package:path_provider/path_provider.dart';
7 | import 'package:path/path.dart' as path;
8 |
9 | class ImageDialog extends StatefulWidget {
10 | @override
11 | _ImageDialogState createState() => _ImageDialogState();
12 | }
13 |
14 | class _ImageDialogState extends State {
15 | _ImageDialogState();
16 |
17 | @override
18 | Widget build(BuildContext context) {
19 | return Scaffold(
20 | body: CustomScrollView(
21 | slivers: [
22 | SliverAppBar(
23 | title: Text('Pick Image'),
24 | ),
25 | _ImageList(),
26 | ],
27 | ),
28 | );
29 | }
30 |
31 | @override
32 | void initState() {
33 | super.initState();
34 | _ImageServer.loadImages().then((value) => setState(() {}));
35 | }
36 | }
37 |
38 | class _ImageList extends StatelessWidget {
39 | _ImageList();
40 |
41 | @override
42 | Widget build(BuildContext context) {
43 | return SliverList(
44 | delegate: SliverChildBuilderDelegate(
45 | (BuildContext context, int index) {
46 | return Material(
47 | child: InkWell(
48 | onTap: () {
49 | Navigator.pop(context, _ImageServer.getFilenameByIndex(index));
50 | },
51 | child: Container(
52 | child: ClipRRect(
53 | child: _ImageServer.getImageByIndex(index),
54 | ),
55 | ),
56 | ));
57 | },
58 | childCount: _ImageServer.length(),
59 | ),
60 | );
61 | }
62 | }
63 |
64 | /// this class handles the loading of custom and built in images
65 | class _ImageServer {
66 | static List? _images;
67 | static List? _imagePaths;
68 |
69 | static Widget getImageByIndex(int index) {
70 | return _images![index];
71 | }
72 |
73 | static getFilenameByIndex(int index) {
74 | return _imagePaths![index];
75 | }
76 | static int length() => _images!.length;
77 |
78 | static Future loadImages() async {
79 | _images = [];
80 | _imagePaths = [];
81 | //first we load in any custom images
82 | Directory filesDir = await getApplicationSupportDirectory();
83 | await filesDir.list(recursive: false).forEach((element) {
84 | if (element.path.contains("button_")) {
85 | //valid image
86 | _images!.add(Image.file(File(element.path), width: 120.0, height: 80.0));
87 | _imagePaths!.add(element.path);
88 | }
89 | });
90 |
91 | //now load in the defaults
92 | final manifestContent = await rootBundle.loadString('AssetManifest.json');
93 | final Map manifestMap = json.decode(manifestContent);
94 | manifestMap.keys.where((String key) => key.contains('images/controls/')).forEach((element) {
95 | _images!.add(Image(image:AssetImage(element),
96 | width: 120.0, height: 80.0));
97 | File file = File(element);
98 | String basename = path.basenameWithoutExtension(file.path);
99 | _imagePaths!.add(basename);
100 | });
101 | }
102 | }
103 |
--------------------------------------------------------------------------------
/gic_flutter/lib/src/views/screenEditor/gicEditControl.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:gesture_x_detector/gesture_x_detector.dart';
3 | import 'package:gic_flutter/src/views/baseGicControl.dart';
4 |
5 | typedef void SelectedWidgetCallback(int selectedControlIndex);
6 | typedef void DragControl(
7 | double newLeft, double newTop, int selectedControlIndex);
8 |
9 | class GicEditControl extends BaseGicControl {
10 | final SelectedWidgetCallback? onSelected;
11 | final int controlIndex;
12 | final GridSize gridSize;
13 | final bool disableDrag;
14 |
15 | GicEditControl(
16 | {Key? key,
17 | required this.gridSize,
18 | required this.disableDrag,
19 | @required control,
20 | required this.controlIndex,
21 | required this.onSelected,
22 | @required pixelRatio})
23 | : super(
24 | key: key,
25 | control: control,
26 | pixelRatio: pixelRatio,
27 | constraints: null);
28 |
29 | @override
30 | State createState() {
31 | return GicEditControlState(
32 | disableDrag: disableDrag,
33 | gridSize: gridSize,
34 | control: control,
35 | controlIndex: controlIndex,
36 | onSelected: onSelected,
37 | pixelRatio: pixelRatio);
38 | }
39 | }
40 |
41 | class GicEditControlState extends BaseGicControlState {
42 | final SelectedWidgetCallback? onSelected;
43 | final int controlIndex;
44 | final bool disableDrag;
45 | final GridSize gridSize;
46 |
47 | double _originalWidth = 0;
48 | double _originalHeight = 0;
49 |
50 | GicEditControlState(
51 | {required this.gridSize,
52 | required this.disableDrag,
53 | @required control,
54 | required this.controlIndex,
55 | required this.onSelected,
56 | @required pixelRatio})
57 | : super(control: control, pixelRatio: pixelRatio) {
58 | _originalWidth = control.width;
59 | _originalHeight = control.height;
60 | }
61 |
62 | Widget buildControl() {
63 | if (disableDrag) {
64 | return Positioned(
65 | top: control.top / pixelRatio,
66 | left: control.left / pixelRatio,
67 | child: XGestureDetector(
68 | onTap: onLongPress,
69 | bypassTapEventOnDoubleTap: false,
70 | child: buildControlContainer()),
71 | );
72 | }
73 | return Positioned(
74 | top: control.top / pixelRatio,
75 | left: control.left / pixelRatio,
76 | child: XGestureDetector(
77 | longPressTimeConsider: 200,
78 | onLongPress: onLongPress,
79 | onMoveUpdate: onMoveUpdate,
80 | onScaleUpdate: onScaleUpdate,
81 | onScaleEnd: onScaleEnd,
82 | bypassTapEventOnDoubleTap: false,
83 | child: buildControlContainer()),
84 | );
85 | }
86 |
87 | void onLongPress(event) {
88 | onSelected!(controlIndex);
89 | }
90 |
91 | void onScaleUpdate(ScaleEvent event) {
92 | setState(() {
93 | if (event.focalPoint.dx < 0) {
94 | control.width = (_originalWidth / event.scale).roundToDouble();
95 | } else {
96 | control.width = (_originalWidth * event.scale).roundToDouble();
97 | }
98 | if (event.focalPoint.dy < 0) {
99 | control.height = (_originalHeight / event.scale).roundToDouble();
100 | } else {
101 | control.height = (_originalHeight * event.scale).roundToDouble();
102 | }
103 | });
104 | }
105 |
106 | void onScaleEnd() {
107 | _originalHeight = control.height;
108 | _originalWidth = control.width;
109 | }
110 |
111 | void onMoveUpdate(MoveEvent event) {
112 | setState(() {
113 | double adjustedX = _getGridPosition(startPosition: event.position.dx, size: control.width);
114 | double adjustedY = _getGridPosition(startPosition: event.position.dy, size: control.height);
115 | control.left = adjustedX;
116 | control.top = adjustedY;
117 | });
118 | }
119 |
120 | sendCommand(String? commandUrl, int commandIndex, bool provideFeedback) {
121 | setState(() {
122 | onSelected!(controlIndex);
123 | });
124 | }
125 |
126 | /// Determines where to place something, based on the currently set grid value
127 | /// startPosition - the raw position, either X or Y based
128 | /// size - size of the control, on the same axis as startPosition. -1 ignores
129 | double _getGridPosition({double? startPosition, double size = -1}) {
130 | double rawPos = startPosition! * pixelRatio;
131 | if (size > -1) {
132 | rawPos = rawPos - (size / 2);
133 | }
134 | int adjustedSize = gridSize.value;
135 | if (gridSize.value < 1) {
136 | adjustedSize = 1;
137 | }
138 | int gridPos = (rawPos.round() / adjustedSize).round();
139 | return gridPos * adjustedSize.toDouble();
140 | }
141 |
142 | }
143 |
144 | class GridSize {
145 | int _value = 0;
146 |
147 | int get value {
148 | return _value;
149 | }
150 |
151 | void set value(int newValue) {
152 | _value = newValue;
153 | }
154 | }
--------------------------------------------------------------------------------
/gic_flutter/lib/src/views/screenEditor/helpDialog/helpDialog.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:gic_flutter/src/backend/models/intl/intlScreenEditor.dart';
3 | import 'package:gic_flutter/src/views/screenEditor/helpDialog/selectTab.dart';
4 |
5 | class HelpDialog extends StatefulWidget {
6 | final IntlScreenEditor translation;
7 |
8 | HelpDialog({Key? key, required this.translation})
9 | : super(key: key);
10 |
11 | @override
12 | _HelpDialogState createState() => _HelpDialogState(translation);
13 | }
14 |
15 | class _HelpDialogState extends State {
16 | final IntlScreenEditor translation;
17 |
18 | List _tabs = [];
19 | List _tabContents = [];
20 |
21 | _HelpDialogState(this.translation);
22 |
23 | //headers
24 | Widget editTab() => Tab(icon: Icon(Icons.edit));
25 | Widget movingTab() => Tab(icon: Icon(Icons.touch_app));
26 | Widget sizingTab() => Tab(icon: Icon(Icons.photo_size_select_large));
27 | Widget quitTab() => Tab(icon: Icon(Icons.exit_to_app));
28 |
29 | @override
30 | void initState() {
31 | super.initState();
32 | }
33 |
34 | @override
35 | Widget build(BuildContext context) {
36 | buildTabs();
37 | return Dialog(
38 | child: DefaultTabController(
39 | length: _tabs.length,
40 | child: Scaffold(
41 | appBar: AppBar(
42 | title:
43 | Text(translation.text(ScreenEditorText.helpDialogTitle)),
44 | bottom: TabBar(
45 | tabs: _tabs,
46 | ),
47 | ),
48 | body: Padding(
49 | padding: const EdgeInsets.all(16.0),
50 | child: TabBarView(
51 | children: _tabContents,
52 | ),
53 | ),
54 | )));
55 | }
56 |
57 | //sets up the tabs, based on type of control we're editing
58 | //different control types need different tab views
59 | void buildTabs() {
60 | _tabs = [];
61 | _tabContents = [];
62 | _tabs.add(editTab());
63 | _tabContents.add(SimpleTextTab(
64 | title: translation.text(ScreenEditorText.helpEditHeader),
65 | details: translation.text(ScreenEditorText.helpEditDetails),
66 | ));
67 | _tabs.add(movingTab());
68 | _tabContents.add(SimpleTextTab(
69 | title: translation.text(ScreenEditorText.helpMoveHeader),
70 | details: translation.text(ScreenEditorText.helpMoveDetails),
71 | ));
72 | _tabs.add(sizingTab());
73 | _tabContents.add(SimpleTextTab(
74 | title: translation.text(ScreenEditorText.helpSizeHeader),
75 | details: translation.text(ScreenEditorText.helpSizeDetails),
76 | ));
77 | _tabs.add(quitTab());
78 | _tabContents.add(SimpleTextTab(
79 | title: translation.text(ScreenEditorText.helpQuitHeader),
80 | details: translation.text(ScreenEditorText.helpQuitDetails),
81 | ));
82 | }
83 | }
84 |
--------------------------------------------------------------------------------
/gic_flutter/lib/src/views/screenEditor/helpDialog/selectTab.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 |
3 | /// This class shows a very simple tab containing a title and details below it.
4 | class SimpleTextTab extends StatefulWidget {
5 | final String title;
6 | final String details;
7 |
8 | SimpleTextTab({Key? key, required this.title, required this.details}) : super(key: key);
9 |
10 | @override
11 | _SimpleTextTabState createState() => _SimpleTextTabState();
12 | }
13 |
14 | class _SimpleTextTabState extends State {
15 | @override
16 | Widget build(BuildContext context) {
17 | return Container(
18 | child: LayoutBuilder(
19 | builder: (BuildContext ctx, BoxConstraints constraints) {
20 | return Column(
21 | children: [
22 | Text(widget.title,
23 | style: Theme.of(context).textTheme.headlineSmall),
24 | Divider(
25 | height: 10,
26 | thickness: 2,
27 | ),
28 | Text(widget.details, textScaleFactor: 1.2,)
29 | ],
30 | );
31 | }),
32 | );
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/gic_flutter/lib/src/views/screenEditor/settingsDialog/dialogButton.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 |
3 | class DialogButton extends StatelessWidget {
4 | const DialogButton(
5 | {Key? key, required this.icon, required this.color, required this.text, required this.onPressed})
6 | : super(key: key);
7 |
8 | final IconData icon;
9 | final Color color;
10 | final String text;
11 | final VoidCallback onPressed;
12 |
13 | @override
14 | Widget build(BuildContext context) {
15 | return SimpleDialogOption(
16 | onPressed: onPressed,
17 | child: Row(
18 | mainAxisAlignment: MainAxisAlignment.start,
19 | crossAxisAlignment: CrossAxisAlignment.center,
20 | children: [
21 | Icon(icon, size: 36.0, color: color),
22 | Padding(
23 | padding: const EdgeInsetsDirectional.only(start: 16.0),
24 | child: Text(text),
25 | ),
26 | ],
27 | ),
28 | );
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/gic_flutter/lib/src/views/screenEditor/settingsDialog/dialogSlider.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 |
3 | class DialogSlider extends StatefulWidget {
4 | DialogSlider(
5 | {Key? key,
6 | required this.icon,
7 | required this.color,
8 | required this.text,
9 | required this.onChanged,
10 | required this.originalValue})
11 | : super(key: key);
12 |
13 | final IconData icon;
14 | final Color color;
15 | final String text;
16 | final int originalValue;
17 | final void Function(double updated) onChanged;
18 |
19 | @override
20 | _DialogSliderState createState() => _DialogSliderState();
21 | }
22 |
23 | class _DialogSliderState extends State {
24 | late double _value;
25 |
26 | @override
27 | void initState() {
28 | super.initState();
29 | _value = widget.originalValue.toDouble();
30 | }
31 |
32 | @override
33 | Widget build(BuildContext context) {
34 | return Column(
35 | children: [
36 | SimpleDialogOption(
37 | child: Row(
38 | mainAxisAlignment: MainAxisAlignment.start,
39 | crossAxisAlignment: CrossAxisAlignment.center,
40 | children: [
41 | Icon(widget.icon, size: 36.0, color: widget.color),
42 | Padding(
43 | padding: const EdgeInsetsDirectional.only(start: 16.0),
44 | child: Text(widget.text),
45 | ),
46 | ],
47 | ),
48 | ),
49 | Slider(
50 | min: 0,
51 | max: 256,
52 | divisions: 8,
53 | value: _value,
54 | onChanged: (double newValue) {
55 | setState(() {
56 | _value = newValue;
57 | });
58 | widget.onChanged(newValue);
59 | }),
60 | ],
61 | );
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/gic_flutter/lib/src/views/screenEditor/settingsDialog/settingsDialog.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:gic_flutter/src/backend/models/intl/intlScreenEditor.dart';
3 | import 'package:gic_flutter/src/backend/models/screen/viewModels/controlViewModel.dart';
4 | import 'package:gic_flutter/src/views/screenEditor/screenEditor.dart';
5 | import 'package:gic_flutter/src/views/screenEditor/settingsDialog/dialogButton.dart';
6 | import 'package:gic_flutter/src/views/screenEditor/settingsDialog/dialogSlider.dart';
7 |
8 | class SettingsDialog {
9 | static Widget display(
10 | BuildContext context, ScreenEditorState screenEditorState) {
11 | IntlScreenEditor translation = IntlScreenEditor(context);
12 |
13 | return SimpleDialog(
14 | title: Text(translation.text(ScreenEditorText.menu)),
15 | elevation: 5,
16 | children: [
17 | DialogButton(
18 | icon: Icons.smart_button,
19 | color: Colors.orange,
20 | text: translation.text(ScreenEditorText.addButton),
21 | onPressed: () {
22 | screenEditorState.addControl(ControlViewModelType.Button);
23 | Navigator.pop(context, true);
24 | },
25 | ),
26 | DialogButton(
27 | icon: Icons.toggle_off_outlined,
28 | color: Colors.green,
29 | text: translation.text(ScreenEditorText.addToggle),
30 | onPressed: () {
31 | screenEditorState.addControl(ControlViewModelType.Toggle);
32 | Navigator.pop(context, true);
33 | },
34 | ),
35 | DialogButton(
36 | icon: Icons.text_fields,
37 | color: Colors.blue,
38 | text: translation.text(ScreenEditorText.addText),
39 | onPressed: () {
40 | screenEditorState.addControl(ControlViewModelType.Text);
41 | Navigator.pop(context, true);
42 | },
43 | ),
44 | DialogButton(
45 | icon: Icons.image,
46 | color: Colors.red,
47 | text: translation.text(ScreenEditorText.addImage),
48 | onPressed: () {
49 | screenEditorState.addControl(ControlViewModelType.Image);
50 | Navigator.pop(context, true);
51 | },
52 | ),
53 | Divider(
54 | height: 10,
55 | thickness: 5,
56 | indent: 20,
57 | endIndent: 20,
58 | ),
59 | DialogButton(
60 | icon: Icons.color_lens,
61 | color: Colors.yellow,
62 | text: translation.text(ScreenEditorText.setBackground),
63 | onPressed: () {
64 | screenEditorState.showBackgroundDialog();
65 | },
66 | ),
67 | DialogSlider(
68 | icon: Icons.grid_on,
69 | color: Colors.grey,
70 | text: translation.text(ScreenEditorText.setGrid),
71 | originalValue: screenEditorState.gridSize.value,
72 | onChanged: (double newValue) {
73 | screenEditorState.gridChangeListener(newValue);
74 | },
75 | ),
76 | Divider(
77 | height: 10,
78 | thickness: 5,
79 | indent: 20,
80 | endIndent: 20,
81 | ),
82 | DialogButton(
83 | icon: Icons.save,
84 | color: Colors.tealAccent,
85 | text: translation.text(ScreenEditorText.save),
86 | onPressed: () {
87 | screenEditorState.tapSave();
88 | Navigator.pop(context, true);
89 | },
90 | ),
91 | DialogButton(
92 | icon: Icons.help,
93 | color: Colors.amber,
94 | text: translation.text(ScreenEditorText.helpDialogTitle),
95 | onPressed: () {
96 | screenEditorState.tapHelp();
97 | },
98 | ),
99 | DialogButton(
100 | icon: Icons.alt_route,
101 | color: Colors.red,
102 | text: translation.text(ScreenEditorText.altMode),
103 | onPressed: () {
104 | screenEditorState.tapAltMode();
105 | },
106 | ),
107 | ],
108 | );
109 | }
110 | }
111 |
--------------------------------------------------------------------------------
/gic_flutter/pubspec.yaml:
--------------------------------------------------------------------------------
1 | name: gic_flutter
2 | description: Gaming Interface Client
3 |
4 | # The following defines the version and build number for your application.
5 | # A version number is three numbers separated by dots, like 1.2.43
6 | # followed by an optional build number separated by a +.
7 | # Both the version and the builder number may be overridden in flutter
8 | # build by specifying --build-name and --build-number, respectively.
9 | # In Android, build-name is used as versionName while build-number used as versionCode.
10 | # Read more about Android versioning at https://developer.android.com/studio/publish/versioning
11 | # In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion.
12 | # Read more about iOS versioning at
13 | # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
14 | version: 5.4.3+26030090
15 |
16 | environment:
17 | sdk: ">=3.5.0 <4.0.0"
18 |
19 | dependencies:
20 | flutter:
21 | sdk: flutter
22 | flutter_localizations:
23 | sdk: flutter
24 | #flutter_cupertino_localizations: ^1.0.1
25 |
26 | # The following adds the Cupertino Icons font to your application.
27 | # Use with the CupertinoIcons class for iOS style icons.
28 | cupertino_icons: ^1.0.6
29 |
30 | archive: ^3.3.8
31 | audioplayers: ^6.1.0
32 | device_info_plus: ^10.1.2
33 | equatable: ^2.0.3
34 | file_picker: ^8.0.7
35 | flutter_colorpicker: ^1.0.3
36 | flutter_email_sender: ^6.0.3
37 | flutter_linkify: ^6.0.0
38 | get_it: ^8.0.2
39 | http: ^1.2.2
40 | introduction_screen: ^3.1.11
41 | keep_screen_on: ^3.0.0
42 | package_info_plus: ^8.1.1
43 | path_provider: ^2.1.1
44 | permission_handler: ^11.3.1
45 | pointycastle: ^3.7.3
46 | rxdart: ^0.28.0
47 | scrollable_positioned_list: ^0.3.8
48 | #nullable scrollable_positioned_list: ^0.2.0-nullsafety.0
49 | share_plus: ^10.0.0
50 | shared_preferences: ^2.2.1 #'>=0.5.7+3 <2.0.0'
51 | #nullable shared_preferences: ^2.0.6
52 | showcaseview: ^3.0.0
53 | url_launcher: ^6.1.14
54 | gesture_x_detector:
55 | path: ../xgesture_flutter
56 |
57 | #intent: ^1.3.4
58 | # For information on the generic Dart part of this file, see the
59 | # following page: https://www.dartlang.org/tools/pub/pubspec
60 |
61 | dependency_overrides:
62 | win32: ^5.5.4
63 | # The following section is specific to Flutter.
64 | flutter:
65 |
66 | # The following line ensures that the Material Icons font is
67 | # included with your application, so that you can use the icons in
68 | # the material Icons class.
69 | uses-material-design: true
70 |
71 | # To add assets to your application, add an assets section, like this:
72 | assets:
73 | - assets/screens/
74 | - assets/images/icons/
75 | - assets/images/controls/
76 | - assets/audio/flick.wav
77 |
78 | # - images/a_dot_burr.jpeg
79 | # - images/a_dot_ham.jpeg
80 |
81 | # An image asset can refer to one or more resolution-specific "variants", see
82 | # https://flutter.dev/assets-and-images/#resolution-aware.
83 |
84 | # For details regarding adding assets from package dependencies, see
85 | # https://flutter.dev/assets-and-images/#from-packages
86 |
87 | # To add custom fonts to your application, add a fonts section here,
88 | # in this "flutter" section. Each entry in this list should have a
89 | # "family" key with the font family name, and a "fonts" key with a
90 | # list giving the asset and other descriptors for the font. For
91 | # example:
92 | fonts:
93 | - family: Lobster-Regular
94 | fonts:
95 | - asset: assets/fonts/Lobster-Regular.ttf
96 | - family: Nunito-Regular
97 | fonts:
98 | - asset: assets/fonts/Nunito-Regular.ttf
99 | - family: ShareTech-Regular
100 | fonts:
101 | - asset: assets/fonts/ShareTech-Regular.ttf
102 | - family: Righteous-Regular
103 | fonts:
104 | - asset: assets/fonts/Righteous-Regular.ttf
105 | # - family: Trajan Pro
106 | # fonts:
107 | # - asset: fonts/TrajanPro.ttf
108 | # - asset: fonts/TrajanPro_Bold.ttf
109 | # weight: 700
110 | #
111 | # For details regarding fonts from package dependencies,
112 | # see https://flutter.dev/custom-fonts/#from-packages
113 |
--------------------------------------------------------------------------------
/gic_flutter/runbuild.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | echo "Choose your option"
3 | echo " 1) Build for Google Play"
4 | echo " 2) Build for Other"
5 | echo " 3) Run Google Play version"
6 | echo " 4) Run Other version"
7 |
8 | read n
9 | case $n in
10 | 1) flutter build appbundle -v -t lib/main_gplay.dart --flavor gplay;;
11 | 2) flutter build apk --split-per-abi -t lib/main_other.dart --flavor other --target-platform android-arm;;
12 | 3) flutter run --flavor gplay -v -t lib/main_gplay.dart;;
13 | 4) flutter run --flavor other -v -t lib/main_other.dart --target-platform android-arm;;
14 | *) echo "invalid option";;
15 | esac
--------------------------------------------------------------------------------
/gic_flutter/runbuild.win.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | echo "Choose your option"
3 | echo " 1) Build for Google Play"
4 | echo " 2) Build for Other"
5 | echo " 3) Run Google Play version"
6 | echo " 4) Run Other version"
7 |
8 | read n
9 | case $n in
10 | 1) flutter build appbundle -v -t lib/main_gplay.dart --flavor gplay;;
11 | 2) flutter build apk --split-per-abi -t lib/main_other.dart --flavor other --target-platform android-arm;;
12 | 3) flutter run --flavor gplay -v -t lib/main_gplay.dart;;
13 | 4) flutter run --flavor other -v -t lib/main_other.dart --target-platform android-arm;;
14 | *) echo "invalid option";;
15 | esac
--------------------------------------------------------------------------------
/release_notes.txt:
--------------------------------------------------------------------------------
1 | 4.5 alpha
2 | - Updated Network code for the new 2.0 Server
3 | - Shows a loading window while connecting to a server initially
4 | - Added Version check before launching a Screen
5 |
--------------------------------------------------------------------------------
/xgesture_flutter/.metadata:
--------------------------------------------------------------------------------
1 | # This file tracks properties of this Flutter project.
2 | # Used by Flutter tool to assess capabilities and perform upgrades etc.
3 | #
4 | # This file should be version controlled and should not be manually edited.
5 |
6 | version:
7 | revision: be9bc8cb3942bda5d8ef4e44b44616c470625e18
8 | channel: beta
9 |
10 | project_type: package
11 |
--------------------------------------------------------------------------------
/xgesture_flutter/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | ## [0.0.1] - TODO: Add release date.
2 |
3 | ## [0.0.2] - TODO: Update API document and example.
4 |
5 | ## [0.0.3] - TODO: dartfmt
6 |
7 | ## [0.0.4]
8 |
9 | ## [0.0.5]
10 | BREAKING
11 | * add new flag: bypassMoveEventAfterLongPress
12 |
13 | by default it is true, means after receive long press event without release pointer (finger still touch on screen the move event will be ignore.
14 |
15 | set it to false in case you expect move event will be fire after long press event
16 |
17 | * using parameter object instead of naked parameters
18 |
19 | old version
20 | ```dart
21 | @override
22 | Widget build(BuildContext context) {
23 | return XGestureDetector(
24 | child: Text("data"),
25 | onTap: (pointer, localPos, position) => print("localPos: $localPos, pointer: $pointer"),
26 | onScaleUpdate: (changedFocusPoint, scale, rotationAngle) =>
27 | print("focalPoint: $changedFocusPoint, scale: $scale"),
28 | );
29 | }
30 | ```
31 |
32 | new version
33 | ```
34 | Widget build(BuildContext context) {
35 | return XGestureDetector(
36 | child: Text("data"),
37 | onTap: (event) =>
38 | print("localPos: ${event.localPos}, pointer: ${event.pointer}"),
39 | onScaleUpdate: (event) =>
40 | print("focalPoint: ${event.focalPoint}, scale: ${event.scale}"),
41 | );
42 | }
43 | ```
44 | ## [1.0.0-nullsafety.0]
45 | BREAKING: opt into null safety
46 | feat!: upgrade Dart SDK constraints to >=2.12.0-0 <3.0.0
47 |
48 | ## [1.0.0-nullsafety.1]
49 | Support onLongPressEnd
50 |
51 | ## [1.0.0]
52 | sound null safety
--------------------------------------------------------------------------------
/xgesture_flutter/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2020 Viet Nguyen
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
--------------------------------------------------------------------------------
/xgesture_flutter/README.md:
--------------------------------------------------------------------------------
1 | # gesture_x_detector
2 |
3 | A widget that detects gestures.
4 |
5 | Easy to use, lightweight gesture detector for Flutter apps.
6 |
7 | ## Features
8 |
9 | - Detect tap gestures (Tap, DoubleTap, Scale(start, update, end), Long press, Move(start, update, end)
10 | - All callbacks can be used simultaneously
11 | - Customize: ignore tap event on double tap, change duration time to detect double tap or long-press
12 |
13 | ## Getting Started
14 |
15 | ### Installation
16 |
17 | Add to pubspec.yaml:
18 |
19 | ```yaml
20 | dependencies:
21 | gesture_x_detector:
22 | ```
23 |
24 | ### Example
25 |
26 | Checkout the example at https://github.com/taodo2291/xgesture_flutter/tree/master/example/lib/main.dart
27 |
28 | ```dart
29 | import 'package:flutter/material.dart';
30 | import 'package:gesture_x_detector/gesture_x_detector.dart';
31 |
32 | void main() {
33 | runApp(
34 | MaterialApp(
35 | home: XGestureExample(),
36 | ),
37 | );
38 | }
39 |
40 | class XGestureExample extends StatefulWidget {
41 | @override
42 | _XGestureExampleState createState() => _XGestureExampleState();
43 | }
44 |
45 | class _XGestureExampleState extends State {
46 | String lastEventName = 'Tap on screen';
47 |
48 | @override
49 | Widget build(BuildContext context) {
50 | return XGestureDetector(
51 | child: Material(
52 | child: Center(
53 | child: Text(
54 | lastEventName,
55 | style: TextStyle(fontSize: 30),
56 | ),
57 | ),
58 | ),
59 | doubleTapTimeConsider: 300,
60 | longPressTimeConsider: 350,
61 | onTap: onTap,
62 | onDoubleTap: onDoubleTap,
63 | onLongPress: onLongPress,
64 | onLongPressEnd: onLongPressEnd,
65 | onMoveStart: onMoveStart,
66 | onMoveEnd: onMoveEnd,
67 | onMoveUpdate: onMoveUpdate,
68 | onScaleStart: onScaleStart,
69 | onScaleUpdate: onScaleUpdate,
70 | onScaleEnd: onScaleEnd,
71 | bypassTapEventOnDoubleTap: false,
72 | );
73 | }
74 |
75 | void onLongPressEnd() {
76 | setLastEventName('onLongPressEnd');
77 | print('onLongPressEnd');
78 | }
79 |
80 | void onScaleEnd() {
81 | setLastEventName('onScaleEnd');
82 | print('onScaleEnd');
83 | }
84 |
85 | void onScaleUpdate(ScaleEvent event) {
86 | setLastEventName('onScaleUpdate');
87 | print(
88 | 'onScaleUpdate - changedFocusPoint: ${event.focalPoint} ; scale: ${event.scale} ;Rotation: ${event.rotationAngle}');
89 | }
90 |
91 | void onScaleStart(initialFocusPoint) {
92 | setLastEventName('onScaleStart');
93 | print('onScaleStart - initialFocusPoint: $initialFocusPoint');
94 | }
95 |
96 | void onMoveUpdate(MoveEvent event) {
97 | setLastEventName('onMoveUpdate');
98 | print('onMoveUpdate - pos: ${event.localPos} delta: ${event.delta}');
99 | }
100 |
101 | void onMoveEnd(localPos) {
102 | setLastEventName('onMoveEnd');
103 | print('onMoveEnd - pos: $localPos');
104 | }
105 |
106 | void onMoveStart(localPos) {
107 | setLastEventName('onMoveStart');
108 | print('onMoveStart - pos: $localPos');
109 | }
110 |
111 | void onLongPress(TapEvent event) {
112 | setLastEventName('onLongPress');
113 | print('onLongPress - pos: ${event.localPos}');
114 | }
115 |
116 | void onDoubleTap(event) {
117 | setLastEventName('onDoubleTap');
118 | print('onDoubleTap - pos: ' + event.localPos.toString());
119 | }
120 |
121 | void onTap(event) {
122 | setLastEventName('onTap');
123 | print('onTap - pos: ' + event.localPos.toString());
124 | }
125 |
126 | void setLastEventName(String eventName) {
127 | setState(() {
128 | lastEventName = eventName;
129 | });
130 | }
131 | }
132 |
133 | ```
134 |
135 | ### Customize
136 |
137 | - Change DoubleTap and Long press detect
138 |
139 | ```dart
140 | @override
141 | Widget build(BuildContext context) {
142 | return XGestureDetector(
143 | child: child,
144 | doubleTapTimeConsider: 300, //customize double tap time
145 | longPressTimeConsider: 400, //customize long press time
146 | );
147 | }
148 | ```
149 |
150 | - Ignore Tap in case Double Tap dectected
151 |
152 | ```dart
153 | @override
154 | Widget build(BuildContext context) {
155 | return XGestureDetector(
156 | child: child,
157 | bypassTapEventOnDoubleTap: true, // default is false
158 | );
159 | }
160 | ```
161 |
162 | - Allow move event after long press event fired without release pointer
163 |
164 | ```dart
165 | @override
166 | Widget build(BuildContext context) {
167 | return XGestureDetector(
168 | child: child,
169 | bypassMoveEventAfterLongPress: false, // default is true
170 | );
171 | }
172 | ```
173 |
174 | Checkout the Canvas playground example at https://github.com/taodo2291/xgesture_flutter/tree/master/example/lib/canvas_playground.dart
175 |
176 |
177 | ## Author
178 | Viet Nguyen - taodo2291@gmail.com
--------------------------------------------------------------------------------
/xgesture_flutter/pubspec.yaml:
--------------------------------------------------------------------------------
1 | name: gesture_x_detector
2 | description: a lightweight gesture detector that supports multiple types(Tap, DoubleTap, Scale, Long-Press, Move) and all callbacks can be used simultaneously
3 | version: 1.0.0
4 | # author: Viet Nguyen
5 | homepage: https://github.com/taodo2291/xgesture_flutter
6 |
7 | environment:
8 | sdk: ">=2.12.0 <3.0.0"
9 |
10 | dependencies:
11 | flutter:
12 | sdk: flutter
13 | vector_math: ^2.1.0
14 |
15 | dev_dependencies:
16 | flutter_test:
17 | sdk: flutter
18 |
--------------------------------------------------------------------------------
/xgesture_flutter/test/gesture_x_detector_test.dart:
--------------------------------------------------------------------------------
1 | // Import the test package and Counter class
2 | import 'package:flutter_test/flutter_test.dart';
3 |
4 | void main() {
5 | test('just for fun', () {
6 | expect(1, 1);
7 | });
8 | }
9 |
--------------------------------------------------------------------------------