diff --git a/CHANGELOG.md b/CHANGELOG.md index 2431e33865..573854f235 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,7 +8,7 @@ More detailed release notes can be found on the [releases page](https://github.c ### Added (highlights) * List (#156), Table (#157) and Tree collection Widgets -* Card, FileItem widgets +* Card, FileItem, Separator widgets * ColorPicker dialog * User selection of primary colour * Container API package to ease using layouts and container widgets @@ -20,6 +20,7 @@ More detailed release notes can be found on the [releases page](https://github.c * Canvas.InteractiveArea() to indicate where widgets should avoid * TextFormatter for ProgressBar * FileDialog.SetLocation() (#821) +* Added dialog.ShowFolderOpen (#941) * Support to install on iOS and android with 'fyne install' * Support asset bundling with go:generate * Add fyne release command for preparing signed apps diff --git a/cmd/fyne/internal/mobile/dex.go b/cmd/fyne/internal/mobile/dex.go index 58c6905994..f26a9eac7f 100644 --- a/cmd/fyne/internal/mobile/dex.go +++ b/cmd/fyne/internal/mobile/dex.go @@ -6,179 +6,183 @@ package mobile -var dexStr = `ZGV4CjAzNQCkZMgHn5+wROpSVVbtY/QUIRR0oPWU53K4IwAAcAAAAHhWNBIAAAAAAAAAAO` + - `giAACzAAAAcAAAAC0AAAA8AwAAOQAAAPADAAASAAAAnAYAAGEAAAAsBwAABgAAADQKAADE` + - `GAAA9AoAAIgUAACKFAAAjxQAAJcUAACrFAAAwhQAANIUAADZFAAA8BQAAPMUAAD4FAAA/h` + - `QAAAMVAAAJFQAADBUAABAVAAAVFQAAGRUAAB4VAAAjFQAAQRUAAGIVAAB9FQAAlxUAALoV` + - `AADfFQAA+BUAAAsWAAAnFgAAPBYAAFIWAABrFgAAhxYAAJsWAADQFgAA8BYAABwXAAAxFw` + - `AAWBcAAG8XAACMFwAAuxcAANYXAAABGAAAJhgAAEYYAABWGAAAcBgAAIcYAACmGAAAuhgA` + - `ANAYAADkGAAA+BgAAA8ZAAA0GQAAWRkAAH4ZAAClGQAAyhkAAO0ZAAADGgAADhoAABcaAA` + - `AxGgAANBoAADgaAAA9GgAARBoAAEoaAABOGgAAUxoAAFoaAABmGgAAaxoAAG4aAAByGgAA` + - `dxoAAIwaAACQGgAAnBoAAKgaAAC0GgAAwBoAAMwaAADYGgAA5RoAAPIaAAACGwAAHRsAAD` + - `UbAABHGwAAXRsAAIIbAACkGwAAxRsAANgbAADmGwAA8BsAAP8bAAAPHAAAHxwAAC8cAAAy` + - `HAAAVRwAAGkcAAB3HAAAfBwAAI0cAACeHAAAqxwAALkcAADCHAAA0BwAANscAADmHAAA+R` + - `wAAAYdAAAbHQAAJB0AAC8dAABBHQAAXR0AAHcdAACSHQAAqx0AALYdAADAHQAAyx0AANsd` + - `AAD5HQAACx4AABMeAAAhHgAAOh4AAEgeAABXHgAAZx4AAHYeAAB8HgAAhB4AAIoeAACXHg` + - `AAqx4AANQeAADfHgAA6R4AAO8eAAD5HgAACx8AABUfAAAlHwAANB8AAD4fAABMHwAAUR8A` + - `AGAfAABvHwAAfR8AAI4fAACXHwAAoB8AAK8fAAC7HwAAyR8AANcfAADmHwAA7R8AAAUgAA` + - `ASIAAAGiAAACIgAAAsIAAAMSAAAFUgAABjIAAAdSAAAHwgAACDIAAACAAAABMAAAAUAAAA` + - `FQAAABYAAAAXAAAAGAAAABkAAAAaAAAAGwAAABwAAAAdAAAAHgAAAB8AAAAgAAAAIQAAAC` + - `IAAAAjAAAAJAAAACUAAAAmAAAAJwAAACgAAAApAAAAKgAAACsAAAAsAAAALQAAAC4AAAAv` + - `AAAAMAAAADEAAAAyAAAAMwAAADQAAAA1AAAANgAAADcAAAA4AAAAOQAAADoAAAA7AAAAQA` + - `AAAEoAAABNAAAACAAAAAAAAAAAAAAACQAAAAAAAACEEwAACgAAAAAAAACMEwAACwAAAAAA` + - `AACYEwAADAAAAAAAAACgEwAADQAAAAIAAAAAAAAADQAAAAQAAAAAAAAAEgAAAAQAAACsEw` + - `AAEAAAAAQAAAC0EwAAEgAAAAQAAAC8EwAAEQAAAAUAAADEEwAADQAAAAYAAAAAAAAADQAA` + - `AAgAAAAAAAAADQAAAAsAAAAAAAAADgAAABAAAADMEwAADQAAABIAAAAAAAAADgAAABIAAA` + - `DMEwAADQAAABQAAAAAAAAADQAAABUAAAAAAAAAEAAAABcAAADUEwAAEgAAABcAAADcEwAA` + - `DQAAABsAAAAAAAAADwAAABwAAACEEwAAEAAAAB8AAAC0EwAADQAAACEAAAAAAAAAEAAAAC` + - `EAAAC0EwAAEAAAACEAAADUEwAAEgAAACEAAADkEwAADQAAACkAAAAAAAAAQAAAACoAAAAA` + - `AAAAQQAAACoAAADMEwAAQgAAACoAAACEEwAAQwAAACoAAADsEwAARAAAACoAAAD4EwAARQ` + - `AAACoAAAAEFAAARgAAACoAAAAMFAAARQAAACoAAAAUFAAARQAAACoAAAAcFAAARQAAACoA` + - `AAAkFAAARQAAACoAAAB8EwAARQAAACoAAAB0EwAASAAAACoAAAAsFAAASQAAACoAAABEFA` + - `AARQAAACoAAABMFAAARQAAACoAAABUFAAARwAAACoAAABcFAAARQAAACoAAABsEwAARQAA` + - `ACoAAAC0EwAARQAAACoAAABoFAAARQAAACoAAADUEwAARgAAACoAAABwFAAASQAAACoAAA` + - `DkEwAASgAAACsAAAAAAAAATAAAACsAAAB4FAAATAAAACsAAACAFAAASwAAACsAAABUFAAA` + - `EAAAACwAAAC0EwAABQAKAJEAAAAHAAAAigAAAAcAAACsAAAACQAAAD4AAAAkACkAqQAAAC` + - `QAAACvAAAAJQApAKkAAAAmACkAqQAAACcAKACqAAAAKAApAKkAAAApAAAAAwAAACkAAAAE` + - `AAAAKQAAAAUAAAApAAAAPAAAACkAAAA/AAAAKQApAIIAAAApABcAkAAAACkAIQCTAAAAAQ` + - `AdAAIAAAABACUAlQAAAAQALwACAAAABAAIAFYAAAAEAAcAYgAAAAQABQBuAAAABAAMAG8A` + - `AAAEAAkAmAAAAAQACACgAAAABgAKAGwAAAAHAB0AAgAAAAcAAACDAAAABwAAALEAAAAIAB` + - `gAqwAAAAoAGQB3AAAADgADAGYAAAAOAAQAZgAAABAAAQBqAAAAEAAOAIwAAAASACgAWAAA` + - `ABIAAABxAAAAEgAPAHQAAAASABIAdQAAABIAAAB+AAAAEgANAIAAAAASACQAgQAAABQADw` + - `BwAAAAFQAAAHkAAAAVAAAAegAAABUAAAB7AAAAFQAAAHwAAAAWADUAhQAAABYANgClAAAA` + - `FwAiAAIAAAAXACcAWQAAABcAHQBgAAAAFwA0AJkAAAAXAB4AnAAAABcAHgCdAAAAFwArAJ` + - `4AAAAXACwAnwAAABcAHgChAAAAGAAfAAIAAAAbABgAawAAABwAAACLAAAAHAAWAKgAAAAc` + - `ABgAqwAAAB8AHQACAAAAIQA3AGEAAAAhAAAAiwAAACEAOACmAAAAIgAvAI0AAAAkADIAAg` + - `AAACQAHQCaAAAAJQAxAAIAAAAlAB0AmgAAACYAMQACAAAAJgApAJYAAAAnADAAAgAAACcA` + - `JgBaAAAAJwAtAF8AAAAnAC0AlwAAACgAMQACAAAAKAAdAJoAAAApAB0AAgAAACkAEwBPAA` + - `AAKQAUAFAAAAApABoAUQAAACkAGwBSAAAAKQAcAFMAAAApADMAVAAAACkAKgBXAAAAKQAd` + - `AGMAAAApAC8AZAAAACkAHgBlAAAAKQAvAGgAAAApABAAaQAAACkAFQBtAAAAKQAGAHIAAA` + - `ApAAsAcwAAACkAAgB2AAAAKQAXAHgAAAApABgAfQAAACkAEQB/AAAAKQAdAIQAAAApACAA` + - `hwAAACkAHQCIAAAAKQAvAIkAAAApAB0AjAAAACkAIQCUAAAAKQAlAJUAAAApAC4AmwAAAC` + - `kAHQCiAAAAKQAvAKMAAAApAB4ApAAAACkAIwCnAAAAKQAdAK4AAAAkAAAAAAAAAB8AAABs` + - `EwAABwAAABwTAAAMIgAAAAAAACUAAAAAAAAAHwAAAGwTAAAHAAAALBMAACAiAAAAAAAAJg` + - `AAAAAAAAAfAAAAdBMAAAcAAAA8EwAAMSIAAAAAAAAnAAAAAAAAAB8AAAB8EwAABwAAAEwT` + - `AABCIgAAAAAAACgAAAAAAAAAHwAAAGwTAAAHAAAAXBMAAFsiAAAAAAAAKQAAAAEAAAABAA` + - `AAAAAAAAcAAAAAAAAAbCIAAP8hAAACAAAA0yEAANohAAACAAAA4yEAANohAAACAAAA6iEA` + - `ANohAAACAAAA8SEAANohAAACAAAA+CEAANohAAADAAMAAQAAAIYgAAAIAAAAWwEEAFkCBQ` + - `BwEC8AAAAOAAYAAQADAAAAjSAAAHgAAAAVAQBAEmISBBQAkAAIAFJTBQArA2UAAAAaAgYA` + - `GgOtAHEgDwAyAFRSBABxEEEAAgAMAm4gJQASAFRRBABxEEEAAQAMAW4gJgABAFRQBAAaAQ` + - `AAcSBEABAAVFAEAHEQQQAAAAwAGgEAAG4gKAAQAFRQBABxEEEAAAAMAG4gKQBAAFRQBABx` + - `EEEAAAAMAG4QIwAAAFRQBABxEEEAAAAMAG4QJAAAAFRQBAAaAYYAbiBRABAADAAfABYAVF` + - `EEAHEQQQABAAwBbjAgABAEDgABISisFACSAAgAASEopwAAAAEDAAAAAAAKAAAAXQAAAF8A` + - `AAACAAIAAQAAAKggAAAGAAAAWwEGAHAQLwAAAA4AAwABAAIAAACuIAAADAAAAFQgBgBxEE` + - `EAAAAMABMBCABuICkAEAAOAAIAAgABAAAAtCAAAAYAAABbAQcAcBAvAAAADgALAAoAAQAA` + - `ALsgAAAGAAAAVBAHAG4QYAAAAA4AAgACAAEAAADLIAAABgAAAFsBCABwEC8AAAAOAAIAAg` + - `AAAAAA0iAAAAEAAAAOAAAABQAFAAAAAADZIAAAAQAAAA4AAAAIAAUAAwAAAOMgAABQAAAA` + - `chAsAAQACgBUMQgAVBEJAHEQQwABAAwBbhAxAAEACgE3EC0AVDAIAFQACQBUMQgAVBEJAH` + - `EQQwABAAwBbhAxAAEACgFyECwABAAKAnIwLQAUAgwBchAuAAEADAFxIEYAEABUMAgAVAAJ` + - `AHIQLgAEAAwBcSBEABAADgByECwABAAKAFQxCABUEQkAcRBDAAEADAFuEDEAAQAKATUQ5P` + - `8o4gIAAgABAAAA9yAAAAYAAABbAQkAcBAvAAAADgAFAAEAAwAAAP4gAABOAAAAEuNUQAkA` + - `IgEXAHEARQAAAAwCcCAhACEAcSBCABAAVEAJAHEQQQAAAAwAEwEIAG4gKQAQAFRACQBxEE` + - `EAAAAMABQBkAAIAG4gJgAQACIAGABwMCoAMANUQQkAcRBBAAEADAFuICcAAQBUQQkAVEIJ` + - `AHEQQQACAAwCbjBHACEAVEAJAHEQQQAAAAwAIgEnAHAgOgBBAG4gIgAQAA4AAgABAAEAAA` + - `ANIQAACgAAAHAQAAABABoAAABbEBEAaQEPAA4AAgABAAAAAAAVIQAAAwAAAFQQEAARAAAA` + - `AgACAAAAAAAbIQAAAwAAAFsBEAARAQAAAgABAAAAAAAiIQAAAwAAAFQQEQARAAAAAgACAA` + - `AAAAAoIQAAAwAAAFsBEQARAQAAAQAAAAAAAAAvIQAAAwAAAGIADwARAAAAAgACAAIAAAA0` + - `IQAABAAAAHAgVwAQAA4ABwADAAMAAQA7IQAAGQAAABLwcRASAAQADAFuMBEAUQYKATkBAw` + - `APAAEQKP4NARoCBgAaA2cAcTAQADIBKPUNASjzAAABAAAABwABAAECDxcdDgAAAQAAAAEA` + - `AABMIQAABgAAAGIADwBuEEgAAAAOAAQAAQADAAEAUiEAADMAAABuEE8AAwAMAG4QTgADAA` + - `wBbhAFAAEADAETAoAAbjAJABACDABUAQAAOQEKABoABgAaAY8AcSAPABAADgBUAAAAGgFb` + - `AG4gDgAQAAwAcRAzAAAAKPQNABoBBgAaAo4AcTAQACEAKOsAAAAAAAApAAEAAQEdKgIAAQ` + - `ACAAAAYyEAAAkAAAAiACgAcCA+ABAAbiBbAAEADgAAAAIAAQACAAAAbCEAAAYAAABiAA8A` + - `biBJABAADgACAAEAAgAAAHQhAAAGAAAAYgAPAG4gSgAQAA4ABAABAAMAAAB7IQAAJAAAAB` + - `oAhgBuIFEAAwAMAB8AFgAUAQIAAgFuIEwAEwAMAW4QFQABAAwBbhAYAAEADAESAm4wHwAQ` + - `AiIAJQBwIDYAMABuIFsAAwAOAAUAAgADAAAAhCEAADkAAAAiAAQAGgFcAHAgAgAQABoBsg` + - `BuIDAAFAAKATgBKABgAQMAEwITADQhIgAaAQEAbiAIABAAGgFeABoCTgBuIDIAJAAMAm4w` + - `BwAQAhoBXQBuIAMAEAAaAT0AcSAEABAADAASEW4wXwADAQ4AbiAIAEAAKO0AAAMAAgADAA` + - `AAkiEAAAkAAAAiACQAcDA0ABACbiBbAAEADgAAAAIAAQABAAAAmyEAAAkAAABuEE0AAQAM` + - `AG4QKwAAAAwAEQAAAAUABAACAAAAoCEAABkAAAASEDICAwAOABLwMgMIABoAAABwIEsAAQ` + - `Ao924QBgAEAAwAbhANAAAADABwIEsAAQAo6wAABAACAAIAAACyIQAAHQAAAHAQWAACAG8g` + - `AQAyAHAQXAACABQAAgACAW4gTAACAAwAbhAVAAAADAAiASYAcCA4ACEAbiATABAADgAAAA` + - `cAAQAFAAEAviEAAGAAAABuEFMABgAMAG4QGgAAAAwAbhAWAAAADAA5AAMADgBuEB4AAAAK` + - `AW4QGwAAAAoCbhAcAAAACgNuEB0AAAAKAHBQVQAWMijsDQAiAAcAcBAKAAAAbhBTAAYADA` + - `FuEBoAAQAMAW4gGQABABQBAgACAW4gTAAWAAwBbhAVAAEADAFSAgIAbhAUAAEACgNuEAsA` + - `AAAKBLFDUgQCALFDUgQBAG4QFwABAAoBbhAMAAAACgWxUVIAAQCRAAEAcFBVACZDKK8AAA` + - `AAIgABAAEBHiP0CgAAAAAAAAAAAAAAAAAAAAsAAAAAAAAAAAAAAAAAAAwLAAAAAAAAAAAA` + - `AAAAAAAYCwAAAAAAAAAAAAAAAAAAJAsAAAAAAAAAAAAAAAAAAAEAAAAgAAAAAQAAABEAAA` + - `ABAAAADQAAAAIAAAAAAAAAAwAAAAAAAAAAAAAAAgAAACEAIQADAAAAIQAhACMAAAACAAAA` + - `BAAcAAEAAAAhAAAAAgAAACEALAACAAAAAgAAAAEAAAAAAAAAAQAAACkAAAACAAAAKQAXAA` + - `IAAAApACEABAAAAAAAAAAAAAAAAwAAAAAAAAAEAAAAAQAAAAMAAAACAAAABAAAAAEAAAAH` + - `AAAAAQAAAAoAAAABAAAADAAAAAkAAAASAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAASABMAAQ` + - `AAABMAAAABAAAAHAAAAAQAAAAcAAAAAAAAAAEAAAAoAAAAAgAAACkAAAACAAAACwAAAAIA` + - `AAASAAAAAAADKi8qAAY8aW5pdD4AEkRFRkFVTFRfSU5QVVRfVFlQRQAVREVGQVVMVF9LRV` + - `lCT0FSRF9DT0RFAA5GSUxFX09QRU5fQ09ERQAFR29Mb2cAFUdvTmF0aXZlQWN0aXZpdHku` + - `amF2YQABSQADSUlJAARJSUlJAANJTEwABElMTEwAAUwAAkxJAANMSUkAAkxMAANMTEkAA0` + - `xMTAAcTGFuZHJvaWQvYXBwL05hdGl2ZUFjdGl2aXR5OwAfTGFuZHJvaWQvY29udGVudC9D` + - `b21wb25lbnROYW1lOwAZTGFuZHJvaWQvY29udGVudC9Db250ZXh0OwAYTGFuZHJvaWQvY2` + - `9udGVudC9JbnRlbnQ7ACFMYW5kcm9pZC9jb250ZW50L3BtL0FjdGl2aXR5SW5mbzsAI0xh` + - `bmRyb2lkL2NvbnRlbnQvcG0vUGFja2FnZU1hbmFnZXI7ABdMYW5kcm9pZC9ncmFwaGljcy` + - `9SZWN0OwARTGFuZHJvaWQvbmV0L1VyaTsAGkxhbmRyb2lkL29zL0J1aWxkJFZFUlNJT047` + - `ABNMYW5kcm9pZC9vcy9CdW5kbGU7ABRMYW5kcm9pZC9vcy9JQmluZGVyOwAXTGFuZHJvaW` + - `QvdGV4dC9FZGl0YWJsZTsAGkxhbmRyb2lkL3RleHQvVGV4dFdhdGNoZXI7ABJMYW5kcm9p` + - `ZC91dGlsL0xvZzsAM0xhbmRyb2lkL3ZpZXcvS2V5Q2hhcmFjdGVyTWFwJFVuYXZhaWxhYm` + - `xlRXhjZXB0aW9uOwAeTGFuZHJvaWQvdmlldy9LZXlDaGFyYWN0ZXJNYXA7ACpMYW5kcm9p` + - `ZC92aWV3L1ZpZXckT25MYXlvdXRDaGFuZ2VMaXN0ZW5lcjsAE0xhbmRyb2lkL3ZpZXcvVm` + - `lldzsAJUxhbmRyb2lkL3ZpZXcvVmlld0dyb3VwJExheW91dFBhcmFtczsAFUxhbmRyb2lk` + - `L3ZpZXcvV2luZG93OwAbTGFuZHJvaWQvdmlldy9XaW5kb3dJbnNldHM7AC1MYW5kcm9pZC` + - `92aWV3L2lucHV0bWV0aG9kL0lucHV0TWV0aG9kTWFuYWdlcjsAGUxhbmRyb2lkL3dpZGdl` + - `dC9FZGl0VGV4dDsAKUxhbmRyb2lkL3dpZGdldC9GcmFtZUxheW91dCRMYXlvdXRQYXJhbX` + - `M7ACNMZGFsdmlrL2Fubm90YXRpb24vRW5jbG9zaW5nTWV0aG9kOwAeTGRhbHZpay9hbm5v` + - `dGF0aW9uL0lubmVyQ2xhc3M7AA5MamF2YS9pby9GaWxlOwAYTGphdmEvbGFuZy9DaGFyU2` + - `VxdWVuY2U7ABVMamF2YS9sYW5nL0V4Y2VwdGlvbjsAHUxqYXZhL2xhbmcvTm9TdWNoTWV0` + - `aG9kRXJyb3I7ABJMamF2YS9sYW5nL09iamVjdDsAFExqYXZhL2xhbmcvUnVubmFibGU7AB` + - `JMamF2YS9sYW5nL1N0cmluZzsAEkxqYXZhL2xhbmcvU3lzdGVtOwAVTGphdmEvbGFuZy9U` + - `aHJvd2FibGU7ACNMb3JnL2dvbGFuZy9hcHAvR29OYXRpdmVBY3Rpdml0eSQxOwAjTG9yZy` + - `9nb2xhbmcvYXBwL0dvTmF0aXZlQWN0aXZpdHkkMjsAI0xvcmcvZ29sYW5nL2FwcC9Hb05h` + - `dGl2ZUFjdGl2aXR5JDM7ACVMb3JnL2dvbGFuZy9hcHAvR29OYXRpdmVBY3Rpdml0eSQ0JD` + - `E7ACNMb3JnL2dvbGFuZy9hcHAvR29OYXRpdmVBY3Rpdml0eSQ0OwAhTG9yZy9nb2xhbmcv` + - `YXBwL0dvTmF0aXZlQWN0aXZpdHk7ABROVU1CRVJfS0VZQk9BUkRfQ09ERQAJT3BlbiBGaW` + - `xlAAdTREtfSU5UABhTSU5HTEVMSU5FX0tFWUJPQVJEX0NPREUAAVYAAlZJAANWSUkABVZJ` + - `SUlJAARWSUlMAAJWTAADVkxJAAVWTElJSQAKVkxJSUlJSUlJSQADVkxMAAFaAAJaTAADWk` + - `xJABNbTGphdmEvbGFuZy9TdHJpbmc7AAJcfAAKYWNjZXNzJDAwMAAKYWNjZXNzJDAwMgAK` + - `YWNjZXNzJDEwMAAKYWNjZXNzJDEwMgAKYWNjZXNzJDIwMAAKYWNjZXNzJDMwMAALYWNjZX` + - `NzRmxhZ3MAC2FkZENhdGVnb3J5AA5hZGRDb250ZW50VmlldwAZYWRkT25MYXlvdXRDaGFu` + - `Z2VMaXN0ZW5lcgAWYWRkVGV4dENoYW5nZWRMaXN0ZW5lcgAQYWZ0ZXJUZXh0Q2hhbmdlZA` + - `AUYW5kcm9pZC5hcHAubGliX25hbWUAI2FuZHJvaWQuaW50ZW50LmFjdGlvbi5PUEVOX0RP` + - `Q1VNRU5UACBhbmRyb2lkLmludGVudC5jYXRlZ29yeS5PUEVOQUJMRQAfYW5kcm9pZC5pbn` + - `RlbnQuZXh0cmEuTUlNRV9UWVBFUwARYmVmb3JlVGV4dENoYW5nZWQADGJyaW5nVG9Gcm9u` + - `dAAIY29udGFpbnMADWNyZWF0ZUNob29zZXIADmRvSGlkZUtleWJvYXJkAA5kb1Nob3dGaW` + - `xlT3BlbgAOZG9TaG93S2V5Ym9hcmQAAWUAIWV4Y2VwdGlvbiByZWFkaW5nIEtleUNoYXJh` + - `Y3Rlck1hcAASZmlsZVBpY2tlclJldHVybmVkAAxmaW5kVmlld0J5SWQAA2dldAAPZ2V0QW` + - `Jzb2x1dGVQYXRoAA9nZXRBY3Rpdml0eUluZm8AC2dldENhY2hlRGlyAAxnZXRDb21wb25l` + - `bnQAB2dldERhdGEADGdldERlY29yVmlldwAJZ2V0SGVpZ2h0AAlnZXRJbnRlbnQAEWdldF` + - `BhY2thZ2VNYW5hZ2VyAAtnZXRSb290VmlldwATZ2V0Um9vdFdpbmRvd0luc2V0cwAHZ2V0` + - `UnVuZQAJZ2V0U3RyaW5nABBnZXRTeXN0ZW1TZXJ2aWNlABpnZXRTeXN0ZW1XaW5kb3dJbn` + - `NldEJvdHRvbQAYZ2V0U3lzdGVtV2luZG93SW5zZXRMZWZ0ABlnZXRTeXN0ZW1XaW5kb3dJ` + - `bnNldFJpZ2h0ABdnZXRTeXN0ZW1XaW5kb3dJbnNldFRvcAAJZ2V0VG1wZGlyAAhnZXRXaW` + - `R0aAAJZ2V0V2luZG93AA5nZXRXaW5kb3dUb2tlbgAcZ2V0V2luZG93VmlzaWJsZURpc3Bs` + - `YXlGcmFtZQAQZ29OYXRpdmVBY3Rpdml0eQAGaGVpZ2h0AAxoaWRlS2V5Ym9hcmQAF2hpZG` + - `VTb2Z0SW5wdXRGcm9tV2luZG93AAxpbnB1dF9tZXRob2QADWluc2V0c0NoYW5nZWQADmtl` + - `eWJvYXJkRGVsZXRlAA1rZXlib2FyZFR5cGVkAARsZWZ0AAZsZW5ndGgABGxvYWQAC2xvYW` + - `RMaWJyYXJ5ABJsb2FkTGlicmFyeSBmYWlsZWQAJ2xvYWRMaWJyYXJ5OiBubyBtYW5pZmVz` + - `dCBtZXRhZGF0YSBmb3VuZAAJbVRleHRFZGl0AAhtZXRhRGF0YQAEbmFtZQAIb2xkU3RhdG` + - `UAEG9uQWN0aXZpdHlSZXN1bHQACG9uQ3JlYXRlAA5vbkxheW91dENoYW5nZQANb25UZXh0` + - `Q2hhbmdlZAAIcHV0RXh0cmEADHJlcXVlc3RGb2N1cwADcnVuAA1ydW5PblVpVGhyZWFkAA` + - `1zZXRJbWVPcHRpb25zAAxzZXRJbnB1dFR5cGUAD3NldExheW91dFBhcmFtcwAHc2V0VGV4` + - `dAAHc2V0VHlwZQANc2V0VmlzaWJpbGl0eQAKc2V0dXBFbnRyeQAMc2hvd0ZpbGVPcGVuAA` + - `xzaG93S2V5Ym9hcmQADXNob3dTb2Z0SW5wdXQABXNwbGl0ABZzdGFydEFjdGl2aXR5Rm9y` + - `UmVzdWx0AAtzdWJTZXF1ZW5jZQAGdGhpcyQwAAZ0aGlzJDEACHRvU3RyaW5nAAN0b3AAIn` + - `Vua25vd24ga2V5Ym9hcmQgdHlwZSwgdXNlIGRlZmF1bHQADHVwZGF0ZUxheW91dAAQdmFs` + - `JGtleWJvYXJkVHlwZQAFdmFsdWUABXdpZHRoAAF8AE4CAAAHDgBRAAd3EAIOWXmWl3i0lp` + - `aXpZYCbSwgSwJ0HQB7AQAHDgB+AAcOtADAAQEABw4AwwEJAAAAAAAAAAAABw5aANUBAQAH` + - `DgDnAQEABw4A4wEEAAAAAAcOANgBBAAAAAAHDgESDwEfE7QCex0AyQEBAAcOAMwBAAcd4b` + - `TEW5a1AhTgAC4ABw44Ti0AGgEABw4AGgIAAAcOABoBAAcOABoCAAAHDgAaAAcOABoCAAAH` + - `DgCVAQMAAAAHHYc0AnssIB6DAHMABw5aAKwBAAcOS6NMS38Cex2HSx4AyQEABw4CIoYAhA` + - `EBAAcOWgBKAQAHDloAdwAHDoe0iIwAiAEBAAcOeOFat1qlGQBOAQAHDgIihgAzAAcOAPAB` + - `AwAAAAcOAgw7AnkdPGxLALsBAQAHDjw8PbSMADgABw7DAg4sAnYdh4VMHlq1tP/QAAIZAb` + - `ABGkoCGgJVBACSAR4CGQGwARpIAhkBsAEaWgIZAbABGj8CGQGwARpcBUSQAAgEAAQBBAIE` + - `AQACAQEEkCABkCA0gIAEsBY1AdAWAAEBAQaQIDaAgATQGDcB7BgAAQEBB5AgOICABJQZOQ` + - `GwGQABAQMIkCA6gIAEzBk7AegZAQH8GQEBkBoAAQEBCZAgPoCABMAbPwHcGwYCEQcKGgEa` + - `ARoBGgEaAQoQAgECQIGABIgdAYggrB0BiCDEHQGIINwdAYgg9B0BiCCMHgGIIKQeBYICAA` + - `UIvB4ECJAfAYICAAGCAgABggIAAQKsHwQCsCABCNQgAQjwIEgAjCEBAOQhAQDoIggAjCMH` + - `BLAjAQH0IwYAwCQRAAAAAAAAAAEAAAAAAAAAAQAAALMAAABwAAAAAgAAAC0AAAA8AwAAAw` + - `AAADkAAADwAwAABAAAABIAAACcBgAABQAAAGEAAAAsBwAABgAAAAYAAAA0CgAAAxAAAAUA` + - `AAD0CgAAASAAACAAAAAwCwAABiAAAAUAAAAcEwAAARAAAB8AAABsEwAAAiAAALMAAACIFA` + - `AAAyAAACAAAACGIAAABCAAAAYAAADTIQAABSAAAAEAAAD/IQAAACAAAAYAAAAMIgAAABAA` + - `AAEAAADoIgAA` + +var dexStr = `ZGV4CjAzNQAClnuWucRCmShMpICNQdPrq7aZEIeogCKMJAAAcAAAAHhWNBIAAAAAAAAAAL` + + `wjAAC3AAAAcAAAAC0AAABMAwAAOwAAAAAEAAASAAAAxAYAAGMAAABUBwAABgAAAGwKAABg` + + `GQAALAsAAAIVAAAEFQAACRUAABEVAAAlFQAAPBUAAEwVAABSFQAAaRUAAGwVAABxFQAAdx` + + `UAAHwVAACCFQAAhRUAAIkVAACOFQAAkhUAAJcVAACcFQAAuhUAANsVAAD2FQAAEBYAADMW` + + `AABYFgAAcRYAAIQWAACgFgAAtRYAAMsWAADkFgAAABcAABQXAABJFwAAaRcAAJUXAACqFw` + + `AA0RcAAOgXAAAFGAAANBgAAE8YAAB6GAAAnxgAAL8YAADPGAAA6RgAAAAZAAAfGQAAMxkA` + + `AEkZAABdGQAAcRkAAIgZAACtGQAA0hkAAPcZAAAeGgAAQxoAAGYaAAB8GgAAhxoAAJAaAA` + + `CqGgAArRoAALEaAAC2GgAAvRoAAMMaAADHGgAAzBoAANMaAADfGgAA5BoAAOcaAADrGgAA` + + `8BoAAAUbAAAJGwAAFRsAACEbAAAtGwAAORsAAEUbAABRGwAAXhsAAGsbAAB7GwAAhRsAAK` + + `AbAAC4GwAAyhsAAOAbAAAFHAAALxwAAFEcAAByHAAAixwAAJ4cAACsHAAAthwAAMUcAADV` + + `HAAA5RwAAPUcAAD4HAAAAB0AACMdAAA3HQAARR0AAEodAABbHQAAbB0AAHkdAACHHQAAkB` + + `0AAJ4dAACpHQAAtB0AAMcdAADUHQAA6R0AAPIdAAD9HQAADx4AACseAABFHgAAYB4AAHke` + + `AACEHgAAjh4AAJkeAACpHgAAxx4AANkeAADhHgAA7x4AAAgfAAAWHwAAJR8AADUfAABEHw` + + `AASh8AAFIfAABYHwAAZR8AAHkfAACiHwAArR8AALcfAAC9HwAAxx8AANkfAADjHwAA8x8A` + + `AAIgAAAMIAAAGiAAAB8gAAAuIAAAPSAAAEsgAABcIAAAZSAAAG4gAAB9IAAAiSAAAJcgAA` + + `ClIAAAtCAAALsgAADTIAAA4CAAAOggAADwIAAA+iAAAP8gAAAjIQAAMSEAAEMhAABKIQAA` + + `USEAAAgAAAATAAAAFAAAABUAAAAWAAAAFwAAABgAAAAZAAAAGgAAABsAAAAcAAAAHQAAAB` + + `4AAAAfAAAAIAAAACEAAAAiAAAAIwAAACQAAAAlAAAAJgAAACcAAAAoAAAAKQAAACoAAAAr` + + `AAAALAAAAC0AAAAuAAAALwAAADAAAAAxAAAAMgAAADMAAAA0AAAANQAAADYAAAA3AAAAOA` + + `AAADkAAAA6AAAAOwAAAEAAAABKAAAATQAAAAgAAAAAAAAAAAAAAAkAAAAAAAAA+BMAAAoA` + + `AAAAAAAAABQAAAsAAAAAAAAADBQAAAwAAAAAAAAAFBQAAA0AAAACAAAAAAAAAA0AAAAEAA` + + `AAAAAAAA4AAAAEAAAAIBQAABIAAAAEAAAAKBQAABAAAAAEAAAAMBQAABIAAAAEAAAAOBQA` + + `ABEAAAAFAAAAQBQAAA0AAAAGAAAAAAAAAA0AAAAIAAAAAAAAAA0AAAALAAAAAAAAAA4AAA` + + `AQAAAAIBQAAA0AAAASAAAAAAAAAA4AAAASAAAAIBQAAA0AAAAUAAAAAAAAAA0AAAAVAAAA` + + `AAAAABAAAAAXAAAASBQAABIAAAAXAAAAUBQAAA0AAAAbAAAAAAAAAA8AAAAcAAAA+BMAAB` + + `AAAAAfAAAAMBQAAA0AAAAhAAAAAAAAABAAAAAhAAAAMBQAABAAAAAhAAAASBQAABIAAAAh` + + `AAAAWBQAAA0AAAApAAAAAAAAAEAAAAAqAAAAAAAAAEEAAAAqAAAAIBQAAEIAAAAqAAAA+B` + + `MAAEMAAAAqAAAAYBQAAEQAAAAqAAAAbBQAAEUAAAAqAAAAeBQAAEYAAAAqAAAAgBQAAEUA` + + `AAAqAAAAiBQAAEUAAAAqAAAAkBQAAEUAAAAqAAAAmBQAAEUAAAAqAAAA8BMAAEUAAAAqAA` + + `AA6BMAAEgAAAAqAAAAoBQAAEkAAAAqAAAAuBQAAEUAAAAqAAAAwBQAAEUAAAAqAAAAyBQA` + + `AEcAAAAqAAAA0BQAAEUAAAAqAAAA4BMAAEUAAAAqAAAAMBQAAEUAAAAqAAAA3BQAAEUAAA` + + `AqAAAASBQAAEYAAAAqAAAA5BQAAEkAAAAqAAAAWBQAAEoAAAArAAAAAAAAAEwAAAArAAAA` + + `7BQAAEwAAAArAAAA9BQAAEsAAAArAAAAyBQAAEsAAAArAAAA/BQAABAAAAAsAAAAMBQAAA` + + `UACgCVAAAABwAAAI4AAAAHAAAAsAAAAAkAAAA+AAAAJAApAK0AAAAkAAAAswAAACUAKQCt` + + `AAAAJgApAK0AAAAnACgArgAAACgAKQCtAAAAKQAAAAMAAAApAAAABAAAACkAAAAFAAAAKQ` + + `AAADwAAAApAAAAPwAAACkAKQCGAAAAKQAXAJQAAAApACEAlwAAAAEAHgACAAAAAQAmAJkA` + + `AAAEADAAAgAAAAQACQBWAAAABAAHAFgAAAAEAAgAZQAAAAQABQByAAAABAANAHMAAAAEAA` + + `oAnAAAAAQACQCkAAAABgALAHAAAAAHAB4AAgAAAAcAAACHAAAABwAAALUAAAAIABkArwAA` + + `AAoAGgB7AAAADgADAGkAAAAOAAQAaQAAABAAAQBuAAAAEAAPAJAAAAASACkAWQAAABIAAA` + + `B1AAAAEgAQAHgAAAASABMAeQAAABIAAACCAAAAEgAOAIQAAAASACUAhQAAABQAEAB0AAAA` + + `FQAAAH0AAAAVAAAAfgAAABUAAAB/AAAAFQAAAIAAAAAWADYAiQAAABYANwCpAAAAFwAjAA` + + `IAAAAXACgAWgAAABcAHgBjAAAAFwA1AJ0AAAAXAB8AoAAAABcAHwChAAAAFwAsAKIAAAAX` + + `AC0AowAAABcAHwClAAAAGAAgAAIAAAAbABkAbwAAABwAAACPAAAAHAAXAKwAAAAcABkArw` + + `AAAB8AHgACAAAAIQA4AGQAAAAhADkAagAAACEAAACPAAAAIQA6AKoAAAAiADAAkQAAACQA` + + `MwACAAAAJAAeAJ4AAAAlADIAAgAAACUAHgCeAAAAJgAyAAIAAAAmACoAmgAAACcAMQACAA` + + `AAJwAnAFsAAAAnAC4AYgAAACcALgCbAAAAKAAyAAIAAAAoAB4AngAAACkAHgACAAAAKQAU` + + `AE8AAAApABUAUAAAACkAGwBRAAAAKQAcAFIAAAApAB0AUwAAACkANABUAAAAKQArAFcAAA` + + `ApAB4AZgAAACkAMABnAAAAKQAfAGgAAAApADAAbAAAACkAEQBtAAAAKQAWAHEAAAApAAYA` + + `dgAAACkADAB3AAAAKQACAHoAAAApABgAfAAAACkAGQCBAAAAKQASAIMAAAApAB4AiAAAAC` + + `kAIQCLAAAAKQAeAIwAAAApADAAjQAAACkAHgCQAAAAKQAiAJgAAAApACYAmQAAACkALwCf` + + `AAAAKQAeAKYAAAApADAApwAAACkAHwCoAAAAKQAkAKsAAAApAB4AsgAAACQAAAAAAAAAHw` + + `AAAOATAAAHAAAAkBMAAOAiAAAAAAAAJQAAAAAAAAAfAAAA4BMAAAcAAACgEwAA9CIAAAAA` + + `AAAmAAAAAAAAAB8AAADoEwAABwAAALATAAAFIwAAAAAAACcAAAAAAAAAHwAAAPATAAAHAA` + + `AAwBMAABYjAAAAAAAAKAAAAAAAAAAfAAAA4BMAAAcAAADQEwAALyMAAAAAAAApAAAAAQAA` + + `AAEAAAAAAAAABwAAAAAAAABAIwAA0yIAAAIAAACnIgAAriIAAAIAAAC3IgAAriIAAAIAAA` + + `C+IgAAriIAAAIAAADFIgAAriIAAAIAAADMIgAAriIAAAMAAwABAAAAVCEAAAgAAABbAQQA` + + `WQIFAHAQMAAAAA4ABgABAAMAAABbIQAAeAAAABUBAEASYhIEFACQAAgAUlMFACsDZQAAAB` + + `oCBgAaA7EAcSAQADIAVFIEAHEQQwACAAwCbiAmABIAVFEEAHEQQwABAAwBbiAnAAEAVFAE` + + `ABoBAABxIEYAEABUUAQAcRBDAAAADAAaAQAAbiApABAAVFAEAHEQQwAAAAwAbiAqAEAAVF` + + `AEAHEQQwAAAAwAbhAkAAAAVFAEAHEQQwAAAAwAbhAlAAAAVFAEABoBigBuIFMAEAAMAB8A` + + `FgBUUQQAcRBDAAEADAFuMCEAEAQOAAEhKKwUAJIACAABISinAAAAAQMAAAAAAAoAAABdAA` + + `AAXwAAAAIAAgABAAAAdiEAAAYAAABbAQYAcBAwAAAADgADAAEAAgAAAHwhAAAMAAAAVCAG` + + `AHEQQwAAAAwAEwEIAG4gKgAQAA4AAgACAAEAAACCIQAABgAAAFsBBwBwEDAAAAAOAAsACg` + + `ABAAAAiSEAAAYAAABUEAcAbhBiAAAADgACAAIAAQAAAJkhAAAGAAAAWwEIAHAQMAAAAA4A` + + `AgACAAAAAACgIQAAAQAAAA4AAAAFAAUAAAAAAKchAAABAAAADgAAAAgABQADAAAAsSEAAF` + + `AAAAByEC0ABAAKAFQxCABUEQkAcRBFAAEADAFuEDMAAQAKATcQLQBUMAgAVAAJAFQxCABU` + + `EQkAcRBFAAEADAFuEDMAAQAKAXIQLQAEAAoCcjAuABQCDAFyEC8AAQAMAXEgSAAQAFQwCA` + + `BUAAkAchAvAAQADAFxIEYAEAAOAHIQLQAEAAoAVDEIAFQRCQBxEEUAAQAMAW4QMwABAAoB` + + `NRDk/yjiAgACAAEAAADFIQAABgAAAFsBCQBwEDAAAAAOAAUAAQADAAAAzCEAAE4AAAAS41` + + `RACQAiARcAcQBHAAAADAJwICIAIQBxIEQAEABUQAkAcRBDAAAADAATAQgAbiAqABAAVEAJ` + + `AHEQQwAAAAwAFAGQAAgAbiAnABAAIgAYAHAwKwAwA1RBCQBxEEMAAQAMAW4gKAABAFRBCQ` + + `BUQgkAcRBDAAIADAJuMEkAIQBUQAkAcRBDAAAADAAiAScAcCA8AEEAbiAjABAADgACAAEA` + + `AQAAANshAAAKAAAAcBAAAAEAGgAAAFsQEQBpAQ8ADgACAAEAAAAAAOMhAAADAAAAVBAQAB` + + `EAAAACAAIAAAAAAOkhAAADAAAAWwEQABEBAAACAAEAAAAAAPAhAAADAAAAVBARABEAAAAC` + + `AAIAAAAAAPYhAAADAAAAWwERABEBAAABAAAAAAAAAP0hAAADAAAAYgAPABEAAAACAAIAAg` + + `AAAAIiAAAEAAAAcCBZABAADgAHAAMAAwABAAkiAAAZAAAAEvBxEBMABAAMAW4wEgBRBgoB` + + `OQEDAA8AARAo/g0BGgIGABoDawBxMBEAMgEo9Q0BKPMAAAEAAAAHAAEAAQIPFx0OAAABAA` + + `AAAQAAABoiAAAGAAAAYgAPAG4QSgAAAA4ABAABAAMAAQAgIgAAMwAAAG4QUQADAAwAbhBQ` + + `AAMADAFuEAYAAQAMARMCgABuMAoAEAIMAFQBAAA5AQoAGgAGABoBkwBxIBAAEAAOAFQAAA` + + `AaAVwAbiAPABAADABxEDUAAAAo9A0AGgEGABoCkgBxMBEAIQAo6wAAAAAAACkAAQABAR0q` + + `AgABAAIAAAAxIgAACQAAACIAKABwIEAAEABuIF0AAQAOAAAAAgABAAIAAAA6IgAABgAAAG` + + `IADwBuIEsAEAAOAAIAAQACAAAAQiIAAAYAAABiAA8AbiBMABAADgAEAAEAAwAAAEkiAAAk` + + `AAAAGgCKAG4gUwADAAwAHwAWABQBAgACAW4gTgATAAwBbhAWAAEADAFuEBkAAQAMARICbj` + + `AgABACIgAlAHAgOAAwAG4gXQADAA4ABgACAAMAAABSIgAAVwAAABITIgAEABoBXQBwIAIA` + + `EAAaAWEAbiAyAFEACgE4ARwAYAEDABMCFQA0IRYAIgAEABoBXgBwIAIAEABuIAQAMAAaAT` + + `0AcSAFABAADABuMGEABAMOABoBtgBuIDEAFQAKATgBHgBgAQMAEwITADQhGAAaAQEAbiAJ` + + `ABAAGgFgABoCTgBuIDQAJQAMAm4wCAAQAhoBXwBuIAMAEAAo024gCQBQABoBXwBuIAMAEA` + + `AoygAAAwACAAMAAABmIgAACQAAACIAJABwMDYAEAJuIF0AAQAOAAAAAgABAAEAAABvIgAA` + + `CQAAAG4QTwABAAwAbhAsAAAADAARAAAABQAEAAIAAAB0IgAAGQAAABIQMgIDAA4AEvAyAw` + + `gAGgAAAHAgTQABACj3bhAHAAQADABuEA4AAAAMAHAgTQABACjrAAAEAAIAAgAAAIYiAAAd` + + `AAAAcBBaAAIAbyABADIAcBBeAAIAFAACAAIBbiBOAAIADABuEBYAAAAMACIBJgBwIDoAIQ` + + `BuIBQAEAAOAAAABwABAAUAAQCSIgAAYAAAAG4QVQAGAAwAbhAbAAAADABuEBcAAAAMADkA` + + `AwAOAG4QHwAAAAoBbhAcAAAACgJuEB0AAAAKA24QHgAAAAoAcFBXABYyKOwNACIABwBwEA` + + `sAAABuEFUABgAMAW4QGwABAAwBbiAaAAEAFAECAAIBbiBOABYADAFuEBYAAQAMAVICAgBu` + + `EBUAAQAKA24QDAAAAAoEsUNSBAIAsUNSBAEAbhAYAAEACgFuEA0AAAAKBbFRUgABAJEAAQ` + + `BwUFcAJkMorwAAAAAiAAEAAQEeIywLAAAAAAAAAAAAAAAAAAA4CwAAAAAAAAAAAAAAAAAA` + + `RAsAAAAAAAAAAAAAAAAAAFALAAAAAAAAAAAAAAAAAABcCwAAAAAAAAAAAAAAAAAAAQAAAC` + + `AAAAABAAAAEQAAAAEAAAANAAAAAgAAAAAAAAADAAAAAAAAAAAAAAACAAAAIQAhAAMAAAAh` + + `ACEAIwAAAAEAAAAAAAAAAgAAAAQAHAABAAAAIQAAAAIAAAAhACwAAgAAAAIAAAABAAAAKQ` + + `AAAAIAAAApABcAAgAAACkAIQAEAAAAAAAAAAAAAAADAAAAAAAAAAQAAAABAAAAAwAAAAIA` + + `AAAEAAAAAQAAAAcAAAABAAAACgAAAAEAAAAMAAAACQAAABIAAAAAAAAAAAAAAAAAAAAAAA` + + `AAAgAAABIAEwABAAAAEwAAAAEAAAAcAAAABAAAABwAAAAAAAAAAQAAACgAAAACAAAAKQAA` + + `AAIAAAALAAAAAgAAABIAAAABAAAAHwAAAAMqLyoABjxpbml0PgASREVGQVVMVF9JTlBVVF` + + `9UWVBFABVERUZBVUxUX0tFWUJPQVJEX0NPREUADkZJTEVfT1BFTl9DT0RFAARGeW5lABVH` + + `b05hdGl2ZUFjdGl2aXR5LmphdmEAAUkAA0lJSQAESUlJSQADSUxMAARJTExMAAFMAAJMSQ` + + `ADTElJAAJMTAADTExJAANMTEwAHExhbmRyb2lkL2FwcC9OYXRpdmVBY3Rpdml0eTsAH0xh` + + `bmRyb2lkL2NvbnRlbnQvQ29tcG9uZW50TmFtZTsAGUxhbmRyb2lkL2NvbnRlbnQvQ29udG` + + `V4dDsAGExhbmRyb2lkL2NvbnRlbnQvSW50ZW50OwAhTGFuZHJvaWQvY29udGVudC9wbS9B` + + `Y3Rpdml0eUluZm87ACNMYW5kcm9pZC9jb250ZW50L3BtL1BhY2thZ2VNYW5hZ2VyOwAXTG` + + `FuZHJvaWQvZ3JhcGhpY3MvUmVjdDsAEUxhbmRyb2lkL25ldC9Vcmk7ABpMYW5kcm9pZC9v` + + `cy9CdWlsZCRWRVJTSU9OOwATTGFuZHJvaWQvb3MvQnVuZGxlOwAUTGFuZHJvaWQvb3MvSU` + + `JpbmRlcjsAF0xhbmRyb2lkL3RleHQvRWRpdGFibGU7ABpMYW5kcm9pZC90ZXh0L1RleHRX` + + `YXRjaGVyOwASTGFuZHJvaWQvdXRpbC9Mb2c7ADNMYW5kcm9pZC92aWV3L0tleUNoYXJhY3` + + `Rlck1hcCRVbmF2YWlsYWJsZUV4Y2VwdGlvbjsAHkxhbmRyb2lkL3ZpZXcvS2V5Q2hhcmFj` + + `dGVyTWFwOwAqTGFuZHJvaWQvdmlldy9WaWV3JE9uTGF5b3V0Q2hhbmdlTGlzdGVuZXI7AB` + + `NMYW5kcm9pZC92aWV3L1ZpZXc7ACVMYW5kcm9pZC92aWV3L1ZpZXdHcm91cCRMYXlvdXRQ` + + `YXJhbXM7ABVMYW5kcm9pZC92aWV3L1dpbmRvdzsAG0xhbmRyb2lkL3ZpZXcvV2luZG93SW` + + `5zZXRzOwAtTGFuZHJvaWQvdmlldy9pbnB1dG1ldGhvZC9JbnB1dE1ldGhvZE1hbmFnZXI7` + + `ABlMYW5kcm9pZC93aWRnZXQvRWRpdFRleHQ7AClMYW5kcm9pZC93aWRnZXQvRnJhbWVMYX` + + `lvdXQkTGF5b3V0UGFyYW1zOwAjTGRhbHZpay9hbm5vdGF0aW9uL0VuY2xvc2luZ01ldGhv` + + `ZDsAHkxkYWx2aWsvYW5ub3RhdGlvbi9Jbm5lckNsYXNzOwAOTGphdmEvaW8vRmlsZTsAGE` + + `xqYXZhL2xhbmcvQ2hhclNlcXVlbmNlOwAVTGphdmEvbGFuZy9FeGNlcHRpb247AB1MamF2` + + `YS9sYW5nL05vU3VjaE1ldGhvZEVycm9yOwASTGphdmEvbGFuZy9PYmplY3Q7ABRMamF2YS` + + `9sYW5nL1J1bm5hYmxlOwASTGphdmEvbGFuZy9TdHJpbmc7ABJMamF2YS9sYW5nL1N5c3Rl` + + `bTsAFUxqYXZhL2xhbmcvVGhyb3dhYmxlOwAjTG9yZy9nb2xhbmcvYXBwL0dvTmF0aXZlQW` + + `N0aXZpdHkkMTsAI0xvcmcvZ29sYW5nL2FwcC9Hb05hdGl2ZUFjdGl2aXR5JDI7ACNMb3Jn` + + `L2dvbGFuZy9hcHAvR29OYXRpdmVBY3Rpdml0eSQzOwAlTG9yZy9nb2xhbmcvYXBwL0dvTm` + + `F0aXZlQWN0aXZpdHkkNCQxOwAjTG9yZy9nb2xhbmcvYXBwL0dvTmF0aXZlQWN0aXZpdHkk` + + `NDsAIUxvcmcvZ29sYW5nL2FwcC9Hb05hdGl2ZUFjdGl2aXR5OwAUTlVNQkVSX0tFWUJPQV` + + `JEX0NPREUACU9wZW4gRmlsZQAHU0RLX0lOVAAYU0lOR0xFTElORV9LRVlCT0FSRF9DT0RF` + + `AAFWAAJWSQADVklJAAVWSUlJSQAEVklJTAACVkwAA1ZMSQAFVkxJSUkAClZMSUlJSUlJSU` + + `kAA1ZMTAABWgACWkwAA1pMSQATW0xqYXZhL2xhbmcvU3RyaW5nOwACXHwACmFjY2VzcyQw` + + `MDAACmFjY2VzcyQwMDIACmFjY2VzcyQxMDAACmFjY2VzcyQxMDIACmFjY2VzcyQyMDAACm` + + `FjY2VzcyQzMDAAC2FjY2Vzc0ZsYWdzAAthZGRDYXRlZ29yeQAOYWRkQ29udGVudFZpZXcA` + + `CGFkZEZsYWdzABlhZGRPbkxheW91dENoYW5nZUxpc3RlbmVyABZhZGRUZXh0Q2hhbmdlZE` + + `xpc3RlbmVyABBhZnRlclRleHRDaGFuZ2VkABRhbmRyb2lkLmFwcC5saWJfbmFtZQAjYW5k` + + `cm9pZC5pbnRlbnQuYWN0aW9uLk9QRU5fRE9DVU1FTlQAKGFuZHJvaWQuaW50ZW50LmFjdG` + + `lvbi5PUEVOX0RPQ1VNRU5UX1RSRUUAIGFuZHJvaWQuaW50ZW50LmNhdGVnb3J5Lk9QRU5B` + + `QkxFAB9hbmRyb2lkLmludGVudC5leHRyYS5NSU1FX1RZUEVTABdhcHBsaWNhdGlvbi94LW` + + `RpcmVjdG9yeQARYmVmb3JlVGV4dENoYW5nZWQADGJyaW5nVG9Gcm9udAAIY29udGFpbnMA` + + `DWNyZWF0ZUNob29zZXIADmRvSGlkZUtleWJvYXJkAA5kb1Nob3dGaWxlT3BlbgAOZG9TaG` + + `93S2V5Ym9hcmQAAWUABmVxdWFscwAhZXhjZXB0aW9uIHJlYWRpbmcgS2V5Q2hhcmFjdGVy` + + `TWFwABJmaWxlUGlja2VyUmV0dXJuZWQADGZpbmRWaWV3QnlJZAADZ2V0AA9nZXRBYnNvbH` + + `V0ZVBhdGgAD2dldEFjdGl2aXR5SW5mbwALZ2V0Q2FjaGVEaXIADGdldENvbXBvbmVudAAH` + + `Z2V0RGF0YQAMZ2V0RGVjb3JWaWV3AAlnZXRIZWlnaHQACWdldEludGVudAARZ2V0UGFja2` + + `FnZU1hbmFnZXIAC2dldFJvb3RWaWV3ABNnZXRSb290V2luZG93SW5zZXRzAAdnZXRSdW5l` + + `AAlnZXRTdHJpbmcAEGdldFN5c3RlbVNlcnZpY2UAGmdldFN5c3RlbVdpbmRvd0luc2V0Qm` + + `90dG9tABhnZXRTeXN0ZW1XaW5kb3dJbnNldExlZnQAGWdldFN5c3RlbVdpbmRvd0luc2V0` + + `UmlnaHQAF2dldFN5c3RlbVdpbmRvd0luc2V0VG9wAAlnZXRUbXBkaXIACGdldFdpZHRoAA` + + `lnZXRXaW5kb3cADmdldFdpbmRvd1Rva2VuABxnZXRXaW5kb3dWaXNpYmxlRGlzcGxheUZy` + + `YW1lABBnb05hdGl2ZUFjdGl2aXR5AAZoZWlnaHQADGhpZGVLZXlib2FyZAAXaGlkZVNvZn` + + `RJbnB1dEZyb21XaW5kb3cADGlucHV0X21ldGhvZAANaW5zZXRzQ2hhbmdlZAAOa2V5Ym9h` + + `cmREZWxldGUADWtleWJvYXJkVHlwZWQABGxlZnQABmxlbmd0aAAEbG9hZAALbG9hZExpYn` + + `JhcnkAEmxvYWRMaWJyYXJ5IGZhaWxlZAAnbG9hZExpYnJhcnk6IG5vIG1hbmlmZXN0IG1l` + + `dGFkYXRhIGZvdW5kAAltVGV4dEVkaXQACG1ldGFEYXRhAARuYW1lAAhvbGRTdGF0ZQAQb2` + + `5BY3Rpdml0eVJlc3VsdAAIb25DcmVhdGUADm9uTGF5b3V0Q2hhbmdlAA1vblRleHRDaGFu` + + `Z2VkAAhwdXRFeHRyYQAMcmVxdWVzdEZvY3VzAANydW4ADXJ1bk9uVWlUaHJlYWQADXNldE` + + `ltZU9wdGlvbnMADHNldElucHV0VHlwZQAPc2V0TGF5b3V0UGFyYW1zAAdzZXRUZXh0AAdz` + + `ZXRUeXBlAA1zZXRWaXNpYmlsaXR5AApzZXR1cEVudHJ5AAxzaG93RmlsZU9wZW4ADHNob3` + + `dLZXlib2FyZAANc2hvd1NvZnRJbnB1dAAFc3BsaXQAFnN0YXJ0QWN0aXZpdHlGb3JSZXN1` + + `bHQAC3N1YlNlcXVlbmNlAAZ0aGlzJDAABnRoaXMkMQAIdG9TdHJpbmcAA3RvcAAidW5rbm` + + `93biBrZXlib2FyZCB0eXBlLCB1c2UgZGVmYXVsdAAMdXBkYXRlTGF5b3V0ABB2YWwka2V5` + + `Ym9hcmRUeXBlAAV2YWx1ZQAFd2lkdGgAAXwATgIAAAcOAFEAB3cQAg5ZeZaXeLSWlpellg` + + `JtLCBLAnQdAHsBAAcOAH4ABw60AMQBAQAHDgDHAQkAAAAAAAAAAAAHDloA2QEBAAcOAOsB` + + `AQAHDgDnAQQAAAAABw4A3AEEAAAAAAcOARIPAR8TtAJ7HQDNAQEABw4A0AEABx3htMRblr` + + `UCFOAALgAHDjhOLQAaAQAHDgAaAgAABw4AGgEABw4AGgIAAAcOABoABw4AGgIAAAcOAJkB` + + `AwAAAAcdhzQCeywgHoMAcwAHDloAsAEABw5Lo0xLfwJ7HYdLHgDNAQAHDgIihgCEAQEABw` + + `5aAEoBAAcOWgB3AAcOh7SIjACIAQEABx144XhElgJ3HeFatGo8AE4BAAcOAiKGADMABw4A` + + `9AEDAAAABw4CDDsCeR08bEsAvwEBAAcOPDw9tIwAOAAHDsMCDiwCdh2HhUweWrW0/9AAAh` + + `kBtAEaTAIaAlUEAJYBHgIZAbQBGkoCGQG0ARpcAhkBtAEaQQIZAbQBGl4FRJAACAQABAEE` + + `AgQBAAIBAQSQIAGQIDaAgAToFjcBiBcAAQEBBpAgOICABIgZOQGkGQABAQEHkCA6gIAEzB` + + `k7AegZAAEBAwiQIDyAgASEGj0BoBoBAbQaAQHIGgABAQEJkCBAgIAE+BtBAZQcBgIRBwoa` + + `ARoBGgEaARoBChACAQJCgYAEwB0BiCDkHQGIIPwdAYgglB4BiCCsHgGIIMQeAYgg3B4Fgg` + + `IABQj0HgQIyB8BggIAAYICAAGCAgABAuQfBALoIAEIjCEBCKghSgDEIQEAnCIBANwjCACA` + + `JAcEpCQBAegkBgC0JREAAAAAAAAAAQAAAAAAAAABAAAAtwAAAHAAAAACAAAALQAAAEwDAA` + + `ADAAAAOwAAAAAEAAAEAAAAEgAAAMQGAAAFAAAAYwAAAFQHAAAGAAAABgAAAGwKAAADEAAA` + + `BQAAACwLAAABIAAAIAAAAGgLAAAGIAAABQAAAJATAAABEAAAIAAAAOATAAACIAAAtwAAAA` + + `IVAAADIAAAIAAAAFQhAAAEIAAABgAAAKciAAAFIAAAAQAAANMiAAAAIAAABgAAAOAiAAAA` + + `EAAAAQAAALwjAAA=` + `` diff --git a/cmd/fyne_demo/screens/window.go b/cmd/fyne_demo/screens/window.go index be99a3b19d..6262b52aa8 100644 --- a/cmd/fyne_demo/screens/window.go +++ b/cmd/fyne_demo/screens/window.go @@ -172,6 +172,18 @@ func loadDialogGroup(win fyne.Window) *widget.Card { fileSaved(writer) }, win) }), + widget.NewButton("Folder Open", func() { + dialog.ShowFolderOpen(func(list fyne.ListableURI, err error) { + if err != nil { + dialog.ShowError(err, win) + return + } + if list == nil { + return + } + dialog.ShowInformation("Folder Open", list.String(), win) + }, win) + }), widget.NewButton("Color Picker", func() { picker := dialog.NewColorPicker("Pick a Color", "What is your favorite color?", func(c color.Color) { colorPicked(c, win) diff --git a/dialog/file.go b/dialog/file.go index 852e98b506..8c8be26d60 100644 --- a/dialog/file.go +++ b/dialog/file.go @@ -120,6 +120,13 @@ func (f *fileDialog) makeUI() fyne.CanvasObject { f.file.onClosedCallback(true) } callback(storage.OpenFileFromURI(f.selected.location)) + } else if f.file.isDirectory() { + callback := f.file.callback.(func(fyne.ListableURI, error)) + f.win.Hide() + if f.file.onClosedCallback != nil { + f.file.onClosedCallback(true) + } + callback(f.dir, nil) } }) f.open.Style = widget.PrimaryButton @@ -136,6 +143,8 @@ func (f *fileDialog) makeUI() fyne.CanvasObject { if f.file.callback != nil { if f.file.save { f.file.callback.(func(fyne.URIWriteCloser, error))(nil, nil) + } else if f.file.isDirectory() { + f.file.callback.(func(fyne.ListableURI, error))(nil, nil) } else { f.file.callback.(func(fyne.URIReadCloser, error))(nil, nil) } @@ -157,7 +166,11 @@ func (f *fileDialog) makeUI() fyne.CanvasObject { scrollBread := widget.NewHScrollContainer(f.breadcrumb) body := fyne.NewContainerWithLayout(layout.NewBorderLayout(scrollBread, nil, nil, nil), scrollBread, f.fileScroll) - header := widget.NewLabelWithStyle(label+" File", fyne.TextAlignLeading, fyne.TextStyle{Bold: true}) + title := label + " File" + if f.file.isDirectory() { + title = label + " Folder" + } + header := widget.NewLabelWithStyle(title, fyne.TextAlignLeading, fyne.TextStyle{Bold: true}) favorites := f.loadFavorites() @@ -215,6 +228,9 @@ func (f *fileDialog) refreshDir(dir fyne.ListableURI) { if isHidden(file) { continue } + if f.file.isDirectory() && !isListable(file) { + continue + } _, err := storage.ListerForURI(file) if err == nil { @@ -273,6 +289,10 @@ func (f *fileDialog) setLocation(dir fyne.ListableURI) error { ) } + if f.file.isDirectory() { + f.fileName.SetText(dir.Name()) + f.open.Enable() + } f.refreshDir(dir) return nil @@ -479,6 +499,10 @@ func (f *FileDialog) SetOnClosed(closed func()) { // SetFilter sets a filter for limiting files that can be chosen in the file dialog. func (f *FileDialog) SetFilter(filter storage.FileFilter) { + if f.isDirectory() { + fyne.LogError("Cannot set a filter for a folder dialog", nil) + return + } f.filter = filter if f.dialog != nil { f.dialog.refreshDir(f.dialog.dir) diff --git a/dialog/file_mobile.go b/dialog/file_mobile.go index eb20771421..dac3dcafce 100644 --- a/dialog/file_mobile.go +++ b/dialog/file_mobile.go @@ -23,7 +23,11 @@ func isHidden(file fyne.URI) bool { } func fileOpenOSOverride(f *FileDialog) bool { - gomobile.ShowFileOpenPicker(f.callback.(func(fyne.URIReadCloser, error)), f.filter) + if f.isDirectory() { + gomobile.ShowFolderOpenPicker(f.callback.(func(fyne.ListableURI, error))) + } else { + gomobile.ShowFileOpenPicker(f.callback.(func(fyne.URIReadCloser, error)), f.filter) + } return true } diff --git a/dialog/file_test.go b/dialog/file_test.go index a53e9b9d81..96bb995f35 100644 --- a/dialog/file_test.go +++ b/dialog/file_test.go @@ -4,7 +4,6 @@ import ( "log" "os" "path/filepath" - "runtime" "strings" "testing" @@ -164,10 +163,18 @@ func TestShowFileOpen(t *testing.T) { var chosen fyne.URIReadCloser var openErr error win := test.NewWindow(widget.NewLabel("Content")) - ShowFileOpen(func(file fyne.URIReadCloser, err error) { + d := NewFileOpen(func(file fyne.URIReadCloser, err error) { chosen = file openErr = err }, win) + testDataPath, _ := filepath.Abs("testdata") + testData := storage.NewFileURI(testDataPath) + dir, err := storage.ListerForURI(testData) + if err != nil { + t.Error("Failed to open testdata dir", err) + } + d.SetLocation(dir) + d.Show() popup := win.Canvas().Overlays().Top().(*widget.PopUp) defer win.Canvas().Overlays().Remove(popup) @@ -184,21 +191,14 @@ func TestShowFileOpen(t *testing.T) { breadcrumb := ui.Objects[3].(*fyne.Container).Objects[0].(*widget.ScrollContainer).Content.(*widget.Box) assert.Greater(t, len(breadcrumb.Children), 0) - home, err := os.UserHomeDir() - if runtime.GOOS == "windows" { - // on windows os.Gethome() returns '\' - home = strings.ReplaceAll(home, "\\", "/") - } - t.Logf("home='%s'", home) assert.Nil(t, err) - components := strings.Split(home, "/") + components := strings.Split(testData.String()[7:], "/") if components[0] == "" { // Splitting a unix path will give a "" at the beginning, but we actually want the path bar to show "/". components[0] = "/" } if assert.Equal(t, len(components), len(breadcrumb.Children)) { for i := range components { - t.Logf("i=%d components[i]='%s' breadcrumb...Text[i]='%s'", i, components[i], breadcrumb.Children[i].(*widget.Button).Text) assert.Equal(t, components[i], breadcrumb.Children[i].(*widget.Button).Text) } } @@ -216,14 +216,7 @@ func TestShowFileOpen(t *testing.T) { target = icon.(*fileDialogItem) } } - - if target == nil { - log.Println("Could not find a file in the default directory to tap :(") - return - } - - // This will only execute if we have a file in the home path. - // Until we have a way to set the directory of an open file dialog. + assert.NotNil(t, target, "Failed to find file in testdata") test.Tap(target) assert.Equal(t, target.location.Name(), nameLabel.Text) assert.False(t, open.Disabled()) diff --git a/dialog/folder.go b/dialog/folder.go new file mode 100644 index 0000000000..880b8ae0b7 --- /dev/null +++ b/dialog/folder.go @@ -0,0 +1,41 @@ +package dialog + +import ( + "fyne.io/fyne" + "fyne.io/fyne/storage" +) + +var folderFilter = storage.NewMimeTypeFileFilter([]string{"application/x-directory"}) + +// NewFolderOpen creates a file dialog allowing the user to choose a folder to open. +// The dialog will appear over the window specified when Show() is called. +func NewFolderOpen(callback func(fyne.ListableURI, error), parent fyne.Window) *FileDialog { + dialog := &FileDialog{} + dialog.callback = callback + dialog.parent = parent + dialog.filter = folderFilter + return dialog +} + +// ShowFolderOpen creates and shows a file dialog allowing the user to choose a folder to open. +// The dialog will appear over the window specified. +func ShowFolderOpen(callback func(fyne.ListableURI, error), parent fyne.Window) { + dialog := NewFolderOpen(callback, parent) + if fileOpenOSOverride(dialog) { + return + } + dialog.Show() +} + +func (f *FileDialog) isDirectory() bool { + return f.filter == folderFilter +} + +func isListable(u fyne.URI) bool { + if _, ok := u.(fyne.ListableURI); ok { + return true + } + + _, err := storage.ListerForURI(u) + return err == nil +} diff --git a/dialog/folder_test.go b/dialog/folder_test.go new file mode 100644 index 0000000000..89b30bb1d1 --- /dev/null +++ b/dialog/folder_test.go @@ -0,0 +1,69 @@ +package dialog + +import ( + "path/filepath" + "testing" + + "github.com/stretchr/testify/assert" + + "fyne.io/fyne" + "fyne.io/fyne/storage" + "fyne.io/fyne/test" + "fyne.io/fyne/widget" +) + +func TestShowFolderOpen(t *testing.T) { + var chosen fyne.ListableURI + var openErr error + win := test.NewWindow(widget.NewLabel("OpenDir")) + d := NewFolderOpen(func(file fyne.ListableURI, err error) { + chosen = file + openErr = err + }, win) + testData, _ := filepath.Abs("testdata") + dir, err := storage.ListerForURI(storage.NewFileURI(testData)) + if err != nil { + t.Error("Failed to open testdata dir", err) + } + d.SetLocation(dir) + d.Show() + + popup := win.Canvas().Overlays().Top().(*widget.PopUp) + defer win.Canvas().Overlays().Remove(popup) + assert.NotNil(t, popup) + + ui := popup.Content.(*fyne.Container) + title := ui.Objects[1].(*widget.Label) + assert.Equal(t, "Open Folder", title.Text) + + nameLabel := ui.Objects[2].(*fyne.Container).Objects[1].(*widget.ScrollContainer).Content.(*widget.Label) + buttons := ui.Objects[2].(*fyne.Container).Objects[0].(*widget.Box) + open := buttons.Children[1].(*widget.Button) + + files := ui.Objects[3].(*fyne.Container).Objects[1].(*widget.ScrollContainer).Content.(*fyne.Container) + assert.Greater(t, len(files.Objects), 0) + + fileName := files.Objects[0].(*fileDialogItem).name + assert.Equal(t, "(Parent)", fileName) + assert.False(t, open.Disabled()) + + var target *fileDialogItem + for _, icon := range files.Objects { + if icon.(*fileDialogItem).dir { + target = icon.(*fileDialogItem) + } else { + t.Error("Folder dialog should not list files") + } + } + + assert.NotNil(t, target, "Failed to find folder in testdata") + test.Tap(target) + assert.Equal(t, target.location.Name(), nameLabel.Text) + assert.False(t, open.Disabled()) + + test.Tap(open) + assert.Nil(t, win.Canvas().Overlays().Top()) + assert.Nil(t, openErr) + + assert.Equal(t, target.location.String(), chosen.String()) +} diff --git a/go.mod b/go.mod index 83ed93816c..864890fcdf 100644 --- a/go.mod +++ b/go.mod @@ -7,7 +7,7 @@ require ( github.com/akavel/rsrc v0.8.0 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/fsnotify/fsnotify v1.4.9 - github.com/fyne-io/mobile v0.0.3-0.20201019162131-a1e87190904e + github.com/fyne-io/mobile v0.0.3-0.20201023100309-6e4995148130 github.com/go-gl/gl v0.0.0-20190320180904-bf2b1f2f34d7 github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200625191551-73d3c3675aa3 github.com/godbus/dbus/v5 v5.0.3 diff --git a/go.sum b/go.sum index 884382d84a..7aa7c19ddf 100644 --- a/go.sum +++ b/go.sum @@ -8,8 +8,8 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= -github.com/fyne-io/mobile v0.0.3-0.20201019162131-a1e87190904e h1:8uXNy4NvCpLlfg1R01TJk0+n5trhDc0vofqbA/S1I48= -github.com/fyne-io/mobile v0.0.3-0.20201019162131-a1e87190904e/go.mod h1:/kOrWrZB6sasLbEy2JIvr4arEzQTXBTZGb3Y96yWbHY= +github.com/fyne-io/mobile v0.0.3-0.20201023100309-6e4995148130 h1:l+E5KcwiFEOR/0y8I+fIlUOpvSskhyNQ/8e2geqRJ6Y= +github.com/fyne-io/mobile v0.0.3-0.20201023100309-6e4995148130/go.mod h1:/kOrWrZB6sasLbEy2JIvr4arEzQTXBTZGb3Y96yWbHY= github.com/go-gl/gl v0.0.0-20190320180904-bf2b1f2f34d7 h1:SCYMcCJ89LjRGwEa0tRluNRiMjZHalQZrVrvTbPh+qw= github.com/go-gl/gl v0.0.0-20190320180904-bf2b1f2f34d7/go.mod h1:482civXOzJJCPzJ4ZOX/pwvXBWSnzD4OKMdH4ClKGbk= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200625191551-73d3c3675aa3 h1:q521PfSp5/z6/sD9FZZOWj4d1MLmfQW8PkRnI9M6PCE= diff --git a/internal/driver/gomobile/file.go b/internal/driver/gomobile/file.go index 38d4939fa0..decd84d8a4 100644 --- a/internal/driver/gomobile/file.go +++ b/internal/driver/gomobile/file.go @@ -74,3 +74,15 @@ func ShowFileOpenPicker(callback func(fyne.URIReadCloser, error), filter storage }, mobileFilter(filter)) } } + +// ShowFolderOpenPicker loads the native folder open dialog and calls back the chosen directory path as a ListableURI. +func ShowFolderOpenPicker(callback func(fyne.ListableURI, error)) { + filter := storage.NewMimeTypeFileFilter([]string{"application/x-directory"}) + drv := fyne.CurrentApp().Driver().(*mobileDriver) + if a, ok := drv.app.(hasPicker); ok { + a.ShowFileOpenPicker(func(uri string, _ func()) { + f, err := drv.ListerForURI(storage.NewURI(uri)) + callback(f, err) + }, mobileFilter(filter)) + } +} diff --git a/vendor/github.com/fyne-io/mobile/app/GoNativeActivity.java b/vendor/github.com/fyne-io/mobile/app/GoNativeActivity.java index 2d052e4f2b..71e3d7cc76 100644 --- a/vendor/github.com/fyne-io/mobile/app/GoNativeActivity.java +++ b/vendor/github.com/fyne-io/mobile/app/GoNativeActivity.java @@ -134,13 +134,17 @@ static void showFileOpen(String mimes) { void doShowFileOpen(String mimes) { Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT); - if (mimes.contains("|") && Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { + if ("application/x-directory".equals(mimes) && Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + intent = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE); // ask for a directory picker if OS supports it + intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); + } else if (mimes.contains("|") && Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { intent.setType("*/*"); intent.putExtra(Intent.EXTRA_MIME_TYPES, mimes.split("\\|")); + intent.addCategory(Intent.CATEGORY_OPENABLE); } else { intent.setType(mimes); + intent.addCategory(Intent.CATEGORY_OPENABLE); } - intent.addCategory(Intent.CATEGORY_OPENABLE); startActivityForResult(Intent.createChooser(intent, "Open File"), FILE_OPEN_CODE); } diff --git a/vendor/github.com/fyne-io/mobile/app/darwin_ios.m b/vendor/github.com/fyne-io/mobile/app/darwin_ios.m index 2a6d44c183..83e1068fe7 100644 --- a/vendor/github.com/fyne-io/mobile/app/darwin_ios.m +++ b/vendor/github.com/fyne-io/mobile/app/darwin_ios.m @@ -299,12 +299,17 @@ void showFileOpenPicker(char* mimes, char *exts) { NSMutableArray *docTypes = [NSMutableArray array]; if (mimes != NULL && strlen(mimes) > 0) { NSString *mimeList = [NSString stringWithUTF8String:mimes]; - NSArray *mimeItems = [mimeList componentsSeparatedByString:@"|"]; - for (NSString *mime in mimeItems) { - CFStringRef UTI = UTTypeCreatePreferredIdentifierForTag(kUTTagClassMIMEType, mime, NULL); + if ([mimeList isEqualToString:@"application/x-directory"]) { + [docTypes addObject:kUTTypeFolder]; + } else { + NSArray *mimeItems = [mimeList componentsSeparatedByString:@"|"]; - [docTypes addObject:UTI]; + for (NSString *mime in mimeItems) { + CFStringRef UTI = UTTypeCreatePreferredIdentifierForTag(kUTTagClassMIMEType, mime, NULL); + + [docTypes addObject:UTI]; + } } } else if (exts != NULL && strlen(exts) > 0) { NSString *extList = [NSString stringWithUTF8String:exts]; diff --git a/vendor/modules.txt b/vendor/modules.txt index 2199788b79..f99f6c99fc 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -8,7 +8,7 @@ github.com/akavel/rsrc/ico github.com/davecgh/go-spew/spew # github.com/fsnotify/fsnotify v1.4.9 github.com/fsnotify/fsnotify -# github.com/fyne-io/mobile v0.0.3-0.20201019162131-a1e87190904e +# github.com/fyne-io/mobile v0.0.3-0.20201023100309-6e4995148130 github.com/fyne-io/mobile/app github.com/fyne-io/mobile/app/internal/callfn github.com/fyne-io/mobile/event/key