├── .gitignore ├── .build └── .gitignore ├── assets └── icon.png ├── config.json ├── README.md └── main.go /.gitignore: -------------------------------------------------------------------------------- 1 | .idea/ 2 | *.so 3 | -------------------------------------------------------------------------------- /.build/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /assets/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marceloneppel/flutter-desktop-template/HEAD/assets/icon.png -------------------------------------------------------------------------------- /config.json: -------------------------------------------------------------------------------- 1 | { 2 | "FlutterPath": "/media/marcelo/Arquivos/Projetos/Flutter/flutter/", 3 | "FlutterProjectPath": "/media/marcelo/Arquivos/Projetos/Flutter/template", 4 | "IconPath": "assets/icon.png", 5 | "ScreenHeight": 768, 6 | "ScreenWidth": 1024 7 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Flutter Desktop Template 2 | 3 | Template for Go Flutter desktop embedder. 4 | 5 | Check the Medium story for how to use this project: Flutter: from Mobile to Desktop (english version) 6 | 7 | ___ 8 | 9 | Template para o projeto Go Flutter desktop embedder. 10 | 11 | Confira o artigo no Medium para como utilizar este projeto: Flutter: do Mobile para o Desktop (versão em português) -------------------------------------------------------------------------------- /main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "image" 5 | _ "image/png" 6 | "log" 7 | "os" 8 | 9 | "github.com/Drakirus/go-flutter-desktop-embedder" 10 | 11 | "path/filepath" 12 | 13 | "encoding/json" 14 | 15 | "runtime" 16 | 17 | "errors" 18 | 19 | "github.com/go-gl/glfw/v3.2/glfw" 20 | ) 21 | 22 | const configurationFilename = "config.json" 23 | 24 | type configuration struct { 25 | FlutterPath string 26 | FlutterProjectPath string 27 | IconPath string 28 | ScreenHeight int 29 | ScreenWidth int 30 | } 31 | 32 | func buildAssetPath(flutterProjectPath string, assetPath string) (string, error) { 33 | if flutterProjectPath == "" { 34 | var ( 35 | path string 36 | err error 37 | ) 38 | path, err = os.Executable() 39 | if err != nil { 40 | return "", err 41 | } 42 | return filepath.Join(filepath.Dir(path), "flutter_assets"), nil 43 | } 44 | return filepath.Join(flutterProjectPath, assetPath), nil 45 | } 46 | 47 | func buildICUDataPath(flutterPath string, icuDataPath string) (string, error) { 48 | if flutterPath == "" { 49 | var ( 50 | path string 51 | err error 52 | ) 53 | path, err = os.Executable() 54 | if err != nil { 55 | return "", err 56 | } 57 | return filepath.Join(filepath.Dir(path), "icudtl.dat"), nil 58 | } 59 | return filepath.Join(flutterPath, icuDataPath), nil 60 | } 61 | 62 | func getConfig() (configuration, error) { 63 | var config configuration 64 | var err error 65 | var file *os.File 66 | var path string 67 | path, err = os.Executable() 68 | if err != nil { 69 | return config, err 70 | } 71 | var configFilename = filepath.Join(filepath.Dir(path), configurationFilename) 72 | file, err = os.Open(configFilename) 73 | if err != nil { 74 | return config, err 75 | } 76 | var decoder = json.NewDecoder(file) 77 | err = decoder.Decode(&config) 78 | if err != nil { 79 | return config, err 80 | } 81 | return config, nil 82 | } 83 | 84 | func getPaths() (string, string, error) { 85 | var assetPath string 86 | var icuDataPath string 87 | var err error 88 | switch runtime.GOOS { 89 | case "darwin": 90 | assetPath = "build/flutter_assets" 91 | icuDataPath = "bin/cache/artifacts/engine/darwin-x64/icudtl.dat" 92 | break 93 | case "linux": 94 | assetPath = "build/flutter_assets" 95 | icuDataPath = "bin/cache/artifacts/engine/linux-x64/icudtl.dat" 96 | break 97 | case "windows": 98 | assetPath = "build\\flutter_assets" 99 | icuDataPath = "bin\\cache\\artifacts\\engine\\windows-x64\\icudtl.dat" 100 | break 101 | default: 102 | err = errors.New("invalid operating system") 103 | break 104 | } 105 | return assetPath, icuDataPath, err 106 | } 107 | 108 | func handleError(err error) { 109 | log.Fatalln(err) 110 | } 111 | 112 | func main() { 113 | var ( 114 | config configuration 115 | err error 116 | ) 117 | config, err = getConfig() 118 | if err != nil { 119 | handleError(err) 120 | } else { 121 | var setIcon = func(window *glfw.Window) error { 122 | var ( 123 | imgFile *os.File 124 | err error 125 | ) 126 | var iconPath = config.IconPath 127 | if string(iconPath[0]) != "/" { 128 | var path string 129 | path, err = os.Executable() 130 | if err != nil { 131 | return err 132 | } 133 | iconPath = filepath.Join(filepath.Dir(path), iconPath) 134 | } 135 | imgFile, err = os.Open(iconPath) 136 | if err != nil { 137 | return err 138 | } 139 | var img image.Image 140 | img, _, err = image.Decode(imgFile) 141 | if err != nil { 142 | return err 143 | } 144 | window.SetIcon([]image.Image{img}) 145 | return nil 146 | } 147 | var ( 148 | assetPath string 149 | icuDataPath string 150 | ) 151 | assetPath, icuDataPath, err = getPaths() 152 | if err != nil { 153 | handleError(err) 154 | } else { 155 | var builtAssetPath string 156 | builtAssetPath, err = buildAssetPath(config.FlutterProjectPath, assetPath) 157 | if err != nil { 158 | handleError(err) 159 | } else { 160 | var builtICUDataPath string 161 | builtICUDataPath, err = buildICUDataPath(config.FlutterPath, icuDataPath) 162 | if err != nil { 163 | handleError(err) 164 | } else { 165 | var options = []gutter.Option{ 166 | gutter.OptionAssetPath(builtAssetPath), 167 | gutter.OptionICUDataPath(builtICUDataPath), 168 | gutter.OptionWindowInitializer(setIcon), 169 | gutter.OptionWindowDimension(config.ScreenWidth, config.ScreenHeight), 170 | gutter.OptionWindowInitializer(setIcon), 171 | gutter.OptionPixelRatio(1.9), 172 | gutter.OptionVmArguments([]string{"--dart-non-checked-mode", "--observatory-port=50300"}), 173 | } 174 | err = gutter.Run(options...) 175 | if err != nil { 176 | handleError(err) 177 | } 178 | } 179 | } 180 | } 181 | } 182 | } 183 | --------------------------------------------------------------------------------