From 824e1b01ad1148458df854c11e67914ab391d377 Mon Sep 17 00:00:00 2001 From: Alexei Anoshenko <2277098+anoshenko@users.noreply.github.com> Date: Thu, 3 Jul 2025 11:20:53 +0300 Subject: [PATCH] Added CreatePopupFromResources function --- popup.go | 104 ++++++++++++++++++++++++++++++++++++++++++------- resources.go | 1 + viewFactory.go | 32 ++++++++------- 3 files changed, 109 insertions(+), 28 deletions(-) diff --git a/popup.go b/popup.go index 5284f59..c7d4715 100644 --- a/popup.go +++ b/popup.go @@ -1,7 +1,10 @@ package rui import ( + "embed" "fmt" + "os" + "path/filepath" "reflect" "slices" "strings" @@ -783,19 +786,6 @@ func (popup *popupData) animationProperty() AnimationProperty { }) } -/* - func (popup *popupData) AllTags() []PropertyName { - tags := make([]PropertyName, 0, len(popup.properties)+1) - for tag := range popup.properties { - tags = append(tags, tag) - } - if popup.contentView != nil { - tags = append(tags, Content) - } - slices.Sort(tags) - return tags - } -*/ func (popup *popupData) View() View { return popup.contentView } @@ -1310,6 +1300,21 @@ func NewPopup(view View, param Params) Popup { // // If the function fails, it returns nil and an error message is written to the log. func CreatePopupFromObject(session Session, object DataObject, binding any) Popup { + if session == nil { + ErrorLog(`"session" argument is nil`) + return nil + } + + if object == nil { + ErrorLog(`"object" argument is nil`) + return nil + } + + if strings.ToLower(object.Tag()) != "popup" { + ErrorLog(`the object name must be "Popup"`) + return nil + } + popup := new(popupData) popup.session = session popup.properties = map[PropertyName]any{} @@ -1341,6 +1346,79 @@ func CreatePopupFromText(session Session, text string, binding any) Popup { return CreatePopupFromObject(session, data, binding) } +// CreatePopupFromResources create new Popup and initialize it by the content of +// the resource file from "popups" directory. Parameters: +// - session - the session to which the view will be attached (should not be nil); +// - text - file name in the "popups" folder of the application resources (it is not necessary to specify the .rui extension, it is added automatically); +// - binding - object assigned to the Binding property (optional parameter). +// +// If the function fails, it returns nil and an error message is written to the log. +func CreatePopupFromResources(session Session, name string, binding any) Popup { + if strings.ToLower(filepath.Ext(name)) != ".rui" { + name += ".rui" + } + + createEmbed := func(fs *embed.FS, path string) Popup { + if data, err := fs.ReadFile(path); err == nil { + data, err := ParseDataText(string(data)) + if err == nil { + return CreatePopupFromObject(session, data, binding) + } + ErrorLog(err.Error()) + } + return nil + } + + for _, fs := range resources.embedFS { + rootDirs := resources.embedRootDirs(fs) + for _, dir := range rootDirs { + switch dir { + case imageDir, themeDir, rawDir: + // do nothing + + case viewDir: + if result := createEmbed(fs, dir+"/"+name); result != nil { + return result + } + + case popupDir: + if result := createEmbed(fs, dir+"/"+name); result != nil { + return result + } + + default: + if result := createEmbed(fs, dir+"/"+popupDir+"/"+name); result != nil { + return result + } + if result := createEmbed(fs, dir+"/"+viewDir+"/"+name); result != nil { + return result + } + } + } + } + + if resources.path == "" { + return nil + } + + createFromFile := func(path string) Popup { + if data, err := os.ReadFile(path); err == nil { + data, err := ParseDataText(string(data)) + if err == nil { + return CreatePopupFromObject(session, data, binding) + } + ErrorLog(err.Error()) + } + return nil + } + + if result := createFromFile(resources.path + popupDir + "/" + name); result != nil { + return result + } + + return createFromFile(resources.path + viewDir + "/" + name) +} + // ShowPopup creates a new Popup and shows it func ShowPopup(view View, param Params) Popup { popup := NewPopup(view, param) diff --git a/resources.go b/resources.go index 5569b7f..59bb128 100644 --- a/resources.go +++ b/resources.go @@ -16,6 +16,7 @@ const ( imageDir = "images" themeDir = "themes" viewDir = "views" + popupDir = "popups" rawDir = "raw" stringsDir = "strings" ) diff --git a/viewFactory.go b/viewFactory.go index 2017123..8a79ea4 100644 --- a/viewFactory.go +++ b/viewFactory.go @@ -1,6 +1,7 @@ package rui import ( + "embed" "os" "path/filepath" "strings" @@ -133,7 +134,7 @@ func CreateViewFromText(session Session, text string, binding ...any) View { // CreateViewFromResources create new View and initialize it by the content of // the resource file from "views" directory. Parameters: // - session - the session to which the view will be attached (should not be nil); -// - name - file name in the views folder of the application resources (it is not necessary to specify the .rui extension, it is added automatically); +// - name - file name in the "views" directory of the application resources (it is not necessary to specify the .rui extension, it is added automatically); // - binding - object assigned to the Binding property (optional parameter). // // If the function fails, it returns nil and an error message is written to the log. @@ -147,6 +148,17 @@ func CreateViewFromResources(session Session, name string, binding ...any) View b = binding[0] } + createEmbed := func(fs *embed.FS, path string) View { + if data, err := fs.ReadFile(path); err == nil { + data, err := ParseDataText(string(data)) + if err == nil { + return CreateViewFromObject(session, data, b) + } + ErrorLog(err.Error()) + } + return nil + } + for _, fs := range resources.embedFS { rootDirs := resources.embedRootDirs(fs) for _, dir := range rootDirs { @@ -155,23 +167,13 @@ func CreateViewFromResources(session Session, name string, binding ...any) View // do nothing case viewDir: - if data, err := fs.ReadFile(dir + "/" + name); err == nil { - data, err := ParseDataText(string(data)) - if err != nil { - ErrorLog(err.Error()) - } else { - return CreateViewFromObject(session, data, b) - } + if result := createEmbed(fs, dir+"/"+name); result != nil { + return result } default: - if data, err := fs.ReadFile(dir + "/" + viewDir + "/" + name); err == nil { - data, err := ParseDataText(string(data)) - if err != nil { - ErrorLog(err.Error()) - } else { - return CreateViewFromObject(session, data, b) - } + if result := createEmbed(fs, dir+"/"+viewDir+"/"+name); result != nil { + return result } } }