// Cross-platform. package cfd import ( "fmt" "os" "reflect" ) type FileFilter struct { // The display name of the filter (That is shown to the user) DisplayName string // The filter pattern. Eg. "*.txt;*.png" to select all txt and png files, "*.*" to select any files, etc. Pattern string } // Never obfuscate the FileFilter type. var _ = reflect.TypeOf(FileFilter{}) type DialogConfig struct { // The title of the dialog Title string // The role of the dialog. This is used to derive the dialog's GUID, which the // OS will use to differentiate it from dialogs that are intended for other purposes. // This means that, for example, a dialog with role "Import" will have a different // previous location that it will open to than a dialog with role "Open". Can be any string. Role string // The default folder - the folder that is used the first time the user opens it // (after the first time their last used location is used). DefaultFolder string // The initial folder - the folder that the dialog always opens to if not empty. // If this is not empty, it will override the "default folder" behaviour and // the dialog will always open to this folder. Folder string // The file filters that restrict which types of files the dialog is able to choose. // Ignored by Select Folder Dialog. FileFilters []FileFilter // Sets the initially selected file filter. This is an index of FileFilters. // Ignored by Select Folder Dialog. SelectedFileFilterIndex uint // The initial name of the file (I.E. the text in the file name text box) when the user opens the dialog. // For the Select Folder Dialog, this sets the initial folder name. FileName string // The default extension applied when a user does not provide one as part of the file name. // If the user selects a different file filter, the default extension will be automatically updated to match the new file filter. // For Open / Open Multiple File Dialog, this only has an effect when the user specifies a file name with no extension and a file with the default extension exists. // For Save File Dialog, this extension will be used whenever a user does not specify an extension. // Ignored by Select Folder Dialog. DefaultExtension string // ParentWindowHandle is the handle (HWND) to the parent window of the dialog. // If left as 0 / nil, the dialog will have no parent window. ParentWindowHandle uintptr } var defaultFilters = []FileFilter{ { DisplayName: "All Files (*.*)", Pattern: "*.*", }, } func (config *DialogConfig) apply(dialog Dialog) (err error) { if config.Title != "" { err = dialog.SetTitle(config.Title) if err != nil { return } } if config.Role != "" { err = dialog.SetRole(config.Role) if err != nil { return } } if config.Folder != "" { _, err = os.Stat(config.Folder) if err != nil { return } err = dialog.SetFolder(config.Folder) if err != nil { return } } if config.DefaultFolder != "" { _, err = os.Stat(config.DefaultFolder) if err != nil { return } err = dialog.SetDefaultFolder(config.DefaultFolder) if err != nil { return } } if config.FileName != "" { err = dialog.SetFileName(config.FileName) if err != nil { return } } dialog.SetParentWindowHandle(config.ParentWindowHandle) if dialog, ok := dialog.(FileDialog); ok { var fileFilters []FileFilter if config.FileFilters != nil && len(config.FileFilters) > 0 { fileFilters = config.FileFilters } else { fileFilters = defaultFilters } err = dialog.SetFileFilters(fileFilters) if err != nil { return } if config.SelectedFileFilterIndex != 0 { if config.SelectedFileFilterIndex > uint(len(fileFilters)) { err = fmt.Errorf("selected file filter index out of range") return } err = dialog.SetSelectedFileFilterIndex(config.SelectedFileFilterIndex) if err != nil { return } } if config.DefaultExtension != "" { err = dialog.SetDefaultExtension(config.DefaultExtension) if err != nil { return } } } return }