func lookupWidget(p string, w data.Widget) data.Widget { if p == w.TypeName() { return w } switch w := w.(type) { case *data.Text, *data.EditText, *data.Button: return w case *data.Column: s := strings.SplitN(p, "/", 2) if len(s) != 2 { panic("Weird bug: not a nice name") } i, err := strconv.Atoi(s[0]) if err != nil || i >= len(*w) { panic("Weird bug: not a good row") } return lookupWidget(s[1], (*w)[i]) case *data.Table: s := strings.SplitN(p, "/", 3) if len(s) != 3 { panic("Weird bug: not a nice name") } i, err := strconv.Atoi(s[0]) if err != nil || i >= len(*w) { panic("Weird bug: not a good row") } r := (*w)[i] j, err := strconv.Atoi(s[1]) if err != nil || j >= len(r) { panic(fmt.Sprint("Weird bug: not a good column: ", s[1])) } return lookupWidget(s[2], r[j]) default: panic(fmt.Sprintf("Unknown lookupWidget type %#v\n", w)) } return nil }
func WidgetToHtml(parent string, widget data.Widget) (out string) { mypath := path.Join(parent, widget.TypeName()) switch widget := widget.(type) { case *data.Text: return html.EscapeString(widget.String) case *data.EditText: myname := widget.String return `<input type="text" onchange="say('` + mypath + `', 'onchange:'+this.value)" value="` + html.EscapeString(myname) + `" />` case *data.TextArea: myname := widget.String return `<textarea cols="80" rows="5" onchange="say('` + mypath + `', 'onchange:'+this.value)">` + html.EscapeString(myname) + `</textarea>` case *data.Table: out = "<table>\n" for i, r := range *widget { class := "even" // I define classes for even and odd rows switch { // so you can alternate colors if you like. case i == 0: // I also define "even first" as a possible header class = "even first" case i&1 == 1: class = "odd" } out += ` <tr class="` + class + `">` + "\n" for j, w := range r { whtml := WidgetToHtml(path.Join(parent, fmt.Sprint(i, "/", j)), w) out += " <td>" + whtml + "</td>\n" } out += " </tr>\n" } out += "</table>\n" case *data.Column: out = "" for i, w := range *widget { class := "even" // I define classes for even and odd rows switch { // so you can alternate colors if you like. case i == 0: // I also define "even first" as a possible header class = "even first" case i&1 == 1: class = "odd" } whtml := WidgetToHtml(path.Join(parent, fmt.Sprint(i)), w) out += `<p class="` + class + `">` + whtml + "</p>\n" } case *data.Button: myname := widget.String return `<input type="submit" onclick="say('` + mypath + `', 'onclick')" value="` + html.EscapeString(myname) + `" />` case *data.Menu: myname := widget.Options[widget.Value] out = `<select onchange="say('` + mypath + `', 'onchange:'+this.value)" value="` + html.EscapeString(myname) + `">` for i, v := range widget.Options { if i == widget.Value { out += "\n<option value=\"" + v + `" selected='selected'>` + v + "</option>" } else { out += "\n<option value=\"" + v + `">` + v + "</option>" } } out += "\n</select>" // case *data.Window: // return WidgetToHtml(parent, widget.Widget) default: panic(fmt.Sprintf("Unhandled data.Widget type in WidgetToHtml! %T", widget)) } return }