func (fb *FileBrowser) RenderFile(name, path, img string, depth int) { container, ok := fb.window.ElementById("fileView").(*ui.Container) if ok { onclickName := fmt.Sprintf("onClick_%v", path) fb.assets.AddCallback(onclickName, func(element ui.Element, args ...interface{}) { if len(args) >= 2 && !args[1].(bool) { // not on release fb.selectedFile = path fb.SetFileTextField(path) open, openOk := fb.openFolders[path] fb.openFolders[path] = !openOk || !open fb.UpdateFileSystem() } }) html := fmt.Sprintf("<div onclick=%v><img src=%v></img><p>%v</p></div>", onclickName, img, name) css := fmt.Sprintf(` p { font-size: 12px; width: 80%%; padding: 0 0 0 5px; } img { width: 16px; height: 16px; } div { padding: 0 0 0 %vpx; } div:hover { background-color: #00f2 }`, depth*8) if fb.selectedFile == path { css = fmt.Sprintf("%v div { background-color: #ff5 }", css) } ui.LoadHTML(container, strings.NewReader(html), strings.NewReader(css), fb.assets) } }
func htmlContent(content *ui.Container) []ui.Activatable { html := bytes.NewBufferString(` <body> <div class=content> <h1 id=heading>UI EXAMPLE!</h1> <img src=testImage></img> <input type=text placeholder="this is a placeholder"></input> <input type=password></input> <button onclick=clickButton></button> <div> </body> `) css := bytes.NewBufferString(` .content img { width: 200; } .content input { background-color: #fff; margin: 10 0 0 0; } .content button { padding: 20; margin: 10 0 0 0; background-color: #a00; } .content button:hover { background-color: #e99; } `) // create assets htmlAssets := ui.NewHtmlAssets() // image img, _ := assets.ImportImageCached("resources/cubemap.png") htmlAssets.AddImage("testImage", img) // button click callback htmlAssets.AddCallback("clickButton", func(element ui.Element, args ...interface{}) { if len(args) >= 2 && !args[1].(bool) { // on release content.TextElementById("heading").SetText("release").SetTextColor(color.NRGBA{254, 0, 0, 254}).ReRender() } else { content.TextElementById("heading").SetText("press").SetTextColor(color.NRGBA{0, 254, 0, 254}).ReRender() } }) // Render the html/css code to the content container activatables, err := ui.LoadHTML(content, html, css, htmlAssets) if err != nil { fmt.Println("Error loading html: ", err) } return activatables }
func (e *Editor) openFileBrowser(heading string, callback func(filePath string), filters ...string) { if e.fileBrowserOpen { return } if e.fileBrowser == nil { e.uiAssets.AddCallback("fileBrowserOpen", func(element ui.Element, args ...interface{}) { if len(args) >= 2 && !args[1].(bool) { // not on release e.fileBrowser.callback(e.fileBrowser.GetFileTextField()) } }) e.uiAssets.AddCallback("fileBrowserCancel", func(element ui.Element, args ...interface{}) { e.closeFileBrowser() }) e.uiAssets.AddCallback("fileBrowserScrollup", func(element ui.Element, args ...interface{}) { if len(args) >= 2 && !args[1].(bool) { // not on release if e.fileBrowser.scrollOffset > 0 { e.fileBrowser.scrollOffset = e.fileBrowser.scrollOffset - 1 e.fileBrowser.UpdateFileSystem() } } }) e.uiAssets.AddCallback("fileBrowserScrollDown", func(element ui.Element, args ...interface{}) { if len(args) >= 2 && !args[1].(bool) { // not on release e.fileBrowser.scrollOffset = e.fileBrowser.scrollOffset + 1 e.fileBrowser.UpdateFileSystem() } }) window, container, _ := e.defaultWindow() window.SetTranslation(mgl32.Vec3{100, 100, 1}) window.SetScale(mgl32.Vec3{800, 0, 1}) e.fileBrowserController = ui.NewUiController(window).(glfwController.Controller) window.Tabs, _ = ui.LoadHTML(container, strings.NewReader(fileBrowserHtml), strings.NewReader(globalCss), e.uiAssets) e.fileBrowser = &FileBrowser{ window: window, assets: e.uiAssets, callback: callback, root: ".", scrollOffset: 0, openFolders: make(map[string]bool), } } e.fileBrowser.callback = callback e.fileBrowser.SetHeading(heading) e.fileBrowser.SetFileTextField("") e.fileBrowser.extensionFilter = filters e.gameEngine.AddOrtho(e.fileBrowser.window) e.controllerManager.AddController(e.fileBrowserController) e.fileBrowserOpen = true e.fileBrowser.UpdateFileSystem() }
func (e *Editor) setProgressTime(message string) { container, ok := e.progressBar.ElementById("progressBarMessage").(*ui.Container) if ok { container.RemoveAllChildren() html := fmt.Sprintf("<p>%v</p>", message) css := "p { font-size: 8px; }" ui.LoadHTML(container, strings.NewReader(html), strings.NewReader(css), e.uiAssets) e.progressBar.Render() } }
func (e *Editor) openProgressBar() { if e.progressBar == nil { window := ui.NewWindow() window.SetTranslation(mgl32.Vec3{500, 0, 0}) window.SetScale(mgl32.Vec3{330, 0, 1}) container := ui.NewContainer() container.SetBackgroundColor(200, 200, 200, 255) window.SetElement(container) e.controllerManager.AddController(ui.NewUiController(window).(glfwController.Controller)) ui.LoadHTML(container, strings.NewReader(progressBarHtml), strings.NewReader(globalCss), e.uiAssets) window.Render() e.progressBar = window } e.gameEngine.AddOrtho(e.progressBar) }
func (e *Editor) openNodeEditor(node *editorModels.NodeModel, callback func()) { window, container, _ := e.defaultWindow() window.SetTranslation(mgl32.Vec3{100, 100, 1}) window.SetScale(mgl32.Vec3{500, 0, 1}) uiController := ui.NewUiController(window).(glfwController.Controller) e.uiAssets.AddCallback("nodeEditorOk", func(element ui.Element, args ...interface{}) { if len(args) >= 2 && !args[1].(bool) { // not on release node.Id = window.TextElementById("name").GetText() node.Classes = []string{} for i := 1; i <= 3; i++ { className := window.TextElementById(fmt.Sprintf("class%v", i)).GetText() if len(className) > 0 { node.Classes = append(node.Classes, className) } } e.gameEngine.RemoveSpatial(window, true) e.controllerManager.RemoveController(uiController) callback() } }) e.uiAssets.AddCallback("nodeEditorCancel", func(element ui.Element, args ...interface{}) { if len(args) >= 2 && !args[1].(bool) { // not on release e.gameEngine.RemoveSpatial(window, true) e.controllerManager.RemoveController(uiController) } }) e.controllerManager.AddController(uiController) window.Tabs, _ = ui.LoadHTML(container, strings.NewReader(nodeEditMenuHtml), strings.NewReader(globalCss), e.uiAssets) e.gameEngine.AddOrtho(window) window.TextElementById("name").SetText(node.Id) for i, class := range node.Classes { if i < 3 { window.TextElementById(fmt.Sprintf("class%v", i+1)).SetText(class) } } window.Render() }
func (e *Editor) openMainMenu() { if e.mainMenu == nil { e.uiAssets.AddCallback("open", func(element ui.Element, args ...interface{}) { if len(args) >= 2 && !args[1].(bool) { // not on release e.openFileBrowser("Open", func(filePath string) { e.loadMap(filePath) e.closeFileBrowser() }, ".json") } }) e.uiAssets.AddCallback("save", func(element ui.Element, args ...interface{}) { if len(args) >= 2 && !args[1].(bool) { // not on release e.openFileBrowser("Save", func(filePath string) { e.saveMap(filePath) e.closeFileBrowser() }, ".json") } }) e.uiAssets.AddCallback("exit", func(element ui.Element, args ...interface{}) { os.Exit(0) }) window, container, _ := e.defaultWindow() window.SetTranslation(mgl32.Vec3{200, 200, 1}) window.SetScale(mgl32.Vec3{400, 0, 1}) ui.LoadHTML(container, strings.NewReader(mainMenuHtml), strings.NewReader(globalCss), e.uiAssets) window.Render() e.mainMenuController = ui.NewUiController(window).(glfwController.Controller) e.mainMenu = window } e.gameEngine.AddOrtho(e.mainMenu) e.controllerManager.AddController(e.mainMenuController) }
func (e *Editor) initOverviewMenu() { e.uiAssets.AddCallback("import", func(element ui.Element, args ...interface{}) { if len(args) >= 2 && !args[1].(bool) { // not on release e.openFileBrowser("import", func(filePath string) { e.setGeametry(filePath) e.overviewMenu.updateTree(e.currentMap) e.closeFileBrowser() }, ".obj") } }) e.uiAssets.AddCallback("newGroup", func(element ui.Element, args ...interface{}) { if len(args) >= 2 && !args[1].(bool) { // not on release uniqueIdCounter++ e.createNewGroup(fmt.Sprintf("group_%v", uniqueIdCounter)) e.overviewMenu.updateTree(e.currentMap) e.refreshMap() } }) e.uiAssets.AddCallback("copyGroup", func(element ui.Element, args ...interface{}) { if len(args) >= 2 && !args[1].(bool) { // not on release e.copyNewGroup() e.overviewMenu.updateTree(e.currentMap) e.refreshMap() } }) e.uiAssets.AddCallback("referenceGroup", func(element ui.Element, args ...interface{}) { if len(args) >= 2 && !args[1].(bool) { // not on release e.referenceGroup() e.overviewMenu.updateTree(e.currentMap) e.refreshMap() } }) e.uiAssets.AddCallback("deleteGroup", func(element ui.Element, args ...interface{}) { if len(args) >= 2 && !args[1].(bool) { // not on release e.deleteGroup() e.overviewMenu.updateTree(e.currentMap) e.refreshMap() } }) e.uiAssets.AddCallback("editGroup", func(element ui.Element, args ...interface{}) { if len(args) >= 2 && !args[1].(bool) { // not on release e.editGroup(func() { e.overviewMenu.updateTree(e.currentMap) }) } }) e.uiAssets.AddCallback("scale", func(element ui.Element, args ...interface{}) { e.mouseMode = "scale" }) e.uiAssets.AddCallback("translate", func(element ui.Element, args ...interface{}) { e.mouseMode = "translate" }) e.uiAssets.AddCallback("rotate", func(element ui.Element, args ...interface{}) { e.mouseMode = "rotate" }) e.uiAssets.AddCallback("reset", func(element ui.Element, args ...interface{}) { e.resetGroup() }) window, container, _ := e.defaultWindow() window.SetTranslation(mgl32.Vec3{10, 10, 1}) window.SetScale(mgl32.Vec3{500, 0, 1}) e.controllerManager.AddController(ui.NewUiController(window).(glfwController.Controller)) ui.LoadHTML(container, strings.NewReader(overviewMenuHtml), strings.NewReader(globalCss), e.uiAssets) e.gameEngine.AddOrtho(window) e.overviewMenu = &Overview{ window: window, assets: e.uiAssets, openNodes: make(map[string]bool), } e.overviewMenu.updateTree(e.currentMap) }
func (o *Overview) updateTree(mapModel *editorModels.MapModel) { var updateNode func(model *editorModels.NodeModel, container *ui.Container) updateNode = func(model *editorModels.NodeModel, container *ui.Container) { //TODO: add native html support for selecting deselecting from a list onclickName := fmt.Sprintf("onClickMapNode_%v", model.Id) o.assets.AddCallback(onclickName, func(element ui.Element, args ...interface{}) { if len(args) >= 2 && !args[1].(bool) { // not on release if o.selectedNodeId == model.Id { o.openNodes[model.Id] = !o.openNodes[model.Id] } o.selectedNodeId = model.Id o.updateTree(mapModel) } }) isOpen := o.openNodes[model.Id] iconImg := "planetClosed" if isOpen { iconImg = "planetOpen" } if model.Reference != nil { iconImg = "reference" } html := fmt.Sprintf("<div onclick=%v><img src=%v></img><p>%v", onclickName, iconImg, model.Id) for _, class := range model.Classes { html = fmt.Sprintf("%v :: %v", html, class) } html = fmt.Sprintf("%v</p></div>", html) css := ` p { font-size: 12px; width: 80%; padding: 0 0 0 5px; } img { width: 16px; height: 16px; } div { margin: 0 0 5px 0; } ` if model.Id == o.selectedNodeId { css = fmt.Sprintf("%v div { background-color: #ff5 }", css) } if !isOpen { css = fmt.Sprintf("%v p { color: #999 }", css) } ui.LoadHTML(container, strings.NewReader(html), strings.NewReader(css), o.assets) if isOpen { for _, childModel := range model.Children { nodeContainer := ui.NewContainer() container.AddChildren(nodeContainer) nodeContainer.SetPadding(ui.Margin{0, 0, 0, 20}) updateNode(childModel, nodeContainer) } } } container, ok := o.window.ElementById("overviewTree").(*ui.Container) if ok { container.RemoveAllChildren() updateNode(mapModel.Root, container) o.window.Render() } }