504 lines
16 KiB
Go
504 lines
16 KiB
Go
|
package test
|
|||
|
|
|||
|
import (
|
|||
|
"fmt"
|
|||
|
"image/color"
|
|||
|
"reflect"
|
|||
|
"sort"
|
|||
|
"strings"
|
|||
|
"unsafe"
|
|||
|
|
|||
|
"fyne.io/fyne/v2"
|
|||
|
"fyne.io/fyne/v2/canvas"
|
|||
|
col "fyne.io/fyne/v2/internal/color"
|
|||
|
"fyne.io/fyne/v2/internal/driver"
|
|||
|
"fyne.io/fyne/v2/layout"
|
|||
|
"fyne.io/fyne/v2/theme"
|
|||
|
)
|
|||
|
|
|||
|
type markupRenderer struct {
|
|||
|
indentation int
|
|||
|
w strings.Builder
|
|||
|
}
|
|||
|
|
|||
|
// snapshot creates a new snapshot of the current render tree.
|
|||
|
func snapshot(c fyne.Canvas) string {
|
|||
|
r := markupRenderer{}
|
|||
|
r.writeCanvas(c)
|
|||
|
return r.w.String()
|
|||
|
}
|
|||
|
|
|||
|
func (r *markupRenderer) setAlignmentAttr(attrs map[string]*string, name string, a fyne.TextAlign) {
|
|||
|
var value string
|
|||
|
switch a {
|
|||
|
case fyne.TextAlignLeading:
|
|||
|
// default mode, don’t add an attr
|
|||
|
case fyne.TextAlignCenter:
|
|||
|
value = "center"
|
|||
|
case fyne.TextAlignTrailing:
|
|||
|
value = "trailing"
|
|||
|
default:
|
|||
|
value = fmt.Sprintf("unknown alignment: %d", a)
|
|||
|
}
|
|||
|
r.setStringAttr(attrs, name, value)
|
|||
|
}
|
|||
|
|
|||
|
func (r *markupRenderer) setBoolAttr(attrs map[string]*string, name string, b bool) {
|
|||
|
if !b {
|
|||
|
return
|
|||
|
}
|
|||
|
attrs[name] = nil
|
|||
|
}
|
|||
|
|
|||
|
func (r *markupRenderer) setColorAttr(attrs map[string]*string, name string, c color.Color) {
|
|||
|
r.setColorAttrWithDefault(attrs, name, c, color.Transparent)
|
|||
|
}
|
|||
|
|
|||
|
func (r *markupRenderer) setColorAttrWithDefault(attrs map[string]*string, name string, c color.Color, d color.Color) {
|
|||
|
if c == nil || c == d {
|
|||
|
return
|
|||
|
}
|
|||
|
|
|||
|
if value := knownColor(c); value != "" {
|
|||
|
r.setStringAttr(attrs, name, value)
|
|||
|
return
|
|||
|
}
|
|||
|
|
|||
|
for _, n := range theme.PrimaryColorNames() {
|
|||
|
if c == theme.PrimaryColorNamed(n) {
|
|||
|
r.setStringAttr(attrs, name, n)
|
|||
|
return
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
rd, g, b, a := col.ToNRGBA(c)
|
|||
|
r.setStringAttr(attrs, name, fmt.Sprintf("rgba(%d,%d,%d,%d)", uint8(rd), uint8(g), uint8(b), uint8(a)))
|
|||
|
}
|
|||
|
|
|||
|
func (r *markupRenderer) setFillModeAttr(attrs map[string]*string, name string, m canvas.ImageFill) {
|
|||
|
var fillMode string
|
|||
|
switch m {
|
|||
|
case canvas.ImageFillStretch:
|
|||
|
// default mode, don’t add an attr
|
|||
|
case canvas.ImageFillContain:
|
|||
|
fillMode = "contain"
|
|||
|
case canvas.ImageFillOriginal:
|
|||
|
fillMode = "original"
|
|||
|
default:
|
|||
|
fillMode = fmt.Sprintf("unknown fill mode: %d", m)
|
|||
|
}
|
|||
|
r.setStringAttr(attrs, name, fillMode)
|
|||
|
}
|
|||
|
|
|||
|
func (r *markupRenderer) setFloatAttr(attrs map[string]*string, name string, f float64) {
|
|||
|
r.setFloatAttrWithDefault(attrs, name, f, 0)
|
|||
|
}
|
|||
|
|
|||
|
func (r *markupRenderer) setFloatAttrWithDefault(attrs map[string]*string, name string, f float64, d float64) {
|
|||
|
if f == d {
|
|||
|
return
|
|||
|
}
|
|||
|
value := fmt.Sprintf("%g", f)
|
|||
|
attrs[name] = &value
|
|||
|
}
|
|||
|
|
|||
|
func (r *markupRenderer) setFloatPosAttr(attrs map[string]*string, name string, x, y float64) {
|
|||
|
if x == 0 && y == 0 {
|
|||
|
return
|
|||
|
}
|
|||
|
value := fmt.Sprintf("%g,%g", x, y)
|
|||
|
attrs[name] = &value
|
|||
|
}
|
|||
|
|
|||
|
func (r *markupRenderer) setSizeAttrWithDefault(attrs map[string]*string, name string, i float32, d float32) {
|
|||
|
if int(i) == int(d) {
|
|||
|
return
|
|||
|
}
|
|||
|
value := fmt.Sprintf("%d", int(i))
|
|||
|
attrs[name] = &value
|
|||
|
}
|
|||
|
|
|||
|
func (r *markupRenderer) setPosAttr(attrs map[string]*string, name string, pos fyne.Position) {
|
|||
|
if int(pos.X) == 0 && int(pos.Y) == 0 {
|
|||
|
return
|
|||
|
}
|
|||
|
value := fmt.Sprintf("%d,%d", int(pos.X), int(pos.Y))
|
|||
|
attrs[name] = &value
|
|||
|
}
|
|||
|
|
|||
|
func (r *markupRenderer) setResourceAttr(attrs map[string]*string, name string, rsc fyne.Resource) {
|
|||
|
if rsc == nil {
|
|||
|
return
|
|||
|
}
|
|||
|
|
|||
|
if value := knownResource(rsc); value != "" {
|
|||
|
r.setStringAttr(attrs, name, value)
|
|||
|
return
|
|||
|
}
|
|||
|
|
|||
|
var variant string
|
|||
|
switch t := rsc.(type) {
|
|||
|
case *theme.DisabledResource:
|
|||
|
variant = "disabled"
|
|||
|
case *theme.ErrorThemedResource:
|
|||
|
variant = "error"
|
|||
|
case *theme.InvertedThemedResource:
|
|||
|
variant = "inverted"
|
|||
|
case *theme.PrimaryThemedResource:
|
|||
|
variant = "primary"
|
|||
|
case *theme.ThemedResource:
|
|||
|
variant = string(t.ColorName)
|
|||
|
if variant == "" {
|
|||
|
variant = "default"
|
|||
|
}
|
|||
|
default:
|
|||
|
r.setStringAttr(attrs, name, rsc.Name())
|
|||
|
return
|
|||
|
}
|
|||
|
|
|||
|
// That’s some magic to access the private `source` field of the themed resource.
|
|||
|
v := reflect.ValueOf(rsc).Elem().Field(0)
|
|||
|
src := reflect.NewAt(v.Type(), unsafe.Pointer(v.UnsafeAddr())).Elem().Interface().(fyne.Resource)
|
|||
|
r.setResourceAttr(attrs, name, src)
|
|||
|
r.setStringAttr(attrs, "themed", variant)
|
|||
|
}
|
|||
|
|
|||
|
func (r *markupRenderer) setScaleModeAttr(attrs map[string]*string, name string, m canvas.ImageScale) {
|
|||
|
var scaleMode string
|
|||
|
switch m {
|
|||
|
case canvas.ImageScaleSmooth:
|
|||
|
// default mode, don’t add an attr
|
|||
|
case canvas.ImageScalePixels:
|
|||
|
scaleMode = "pixels"
|
|||
|
default:
|
|||
|
scaleMode = fmt.Sprintf("unknown scale mode: %d", m)
|
|||
|
}
|
|||
|
r.setStringAttr(attrs, name, scaleMode)
|
|||
|
}
|
|||
|
|
|||
|
func (r *markupRenderer) setSizeAttr(attrs map[string]*string, name string, size fyne.Size) {
|
|||
|
value := fmt.Sprintf("%dx%d", int(size.Width), int(size.Height))
|
|||
|
attrs[name] = &value
|
|||
|
}
|
|||
|
|
|||
|
func (r *markupRenderer) setStringAttr(attrs map[string]*string, name string, s string) {
|
|||
|
if s == "" {
|
|||
|
return
|
|||
|
}
|
|||
|
attrs[name] = &s
|
|||
|
}
|
|||
|
|
|||
|
func (r *markupRenderer) writeCanvas(c fyne.Canvas) {
|
|||
|
attrs := map[string]*string{}
|
|||
|
r.setSizeAttr(attrs, "size", c.Size())
|
|||
|
if tc, ok := c.(WindowlessCanvas); ok {
|
|||
|
r.setBoolAttr(attrs, "padded", tc.Padded())
|
|||
|
}
|
|||
|
r.writeTag("canvas", false, attrs)
|
|||
|
r.w.WriteRune('\n')
|
|||
|
r.indentation++
|
|||
|
r.writeTag("content", false, nil)
|
|||
|
r.w.WriteRune('\n')
|
|||
|
r.indentation++
|
|||
|
driver.WalkVisibleObjectTree(c.Content(), r.writeCanvasObject, r.writeCloseCanvasObject)
|
|||
|
r.indentation--
|
|||
|
r.writeIndent()
|
|||
|
r.writeCloseTag("content")
|
|||
|
for _, o := range c.Overlays().List() {
|
|||
|
r.writeTag("overlay", false, nil)
|
|||
|
r.w.WriteRune('\n')
|
|||
|
r.indentation++
|
|||
|
driver.WalkVisibleObjectTree(o, r.writeCanvasObject, r.writeCloseCanvasObject)
|
|||
|
r.indentation--
|
|||
|
r.writeIndent()
|
|||
|
r.writeCloseTag("overlay")
|
|||
|
}
|
|||
|
r.indentation--
|
|||
|
r.writeIndent()
|
|||
|
r.writeCloseTag("canvas")
|
|||
|
}
|
|||
|
|
|||
|
func (r *markupRenderer) writeCanvasObject(obj fyne.CanvasObject, _, _ fyne.Position, _ fyne.Size) bool {
|
|||
|
attrs := map[string]*string{}
|
|||
|
r.setPosAttr(attrs, "pos", obj.Position())
|
|||
|
r.setSizeAttr(attrs, "size", obj.Size())
|
|||
|
switch o := obj.(type) {
|
|||
|
case *canvas.Circle:
|
|||
|
r.writeCircle(o, attrs)
|
|||
|
case *canvas.Image:
|
|||
|
r.writeImage(o, attrs)
|
|||
|
case *canvas.Line:
|
|||
|
r.writeLine(o, attrs)
|
|||
|
case *canvas.LinearGradient:
|
|||
|
r.writeLinearGradient(o, attrs)
|
|||
|
case *canvas.RadialGradient:
|
|||
|
r.writeRadialGradient(o, attrs)
|
|||
|
case *canvas.Raster:
|
|||
|
r.writeRaster(o, attrs)
|
|||
|
case *canvas.Rectangle:
|
|||
|
r.writeRectangle(o, attrs)
|
|||
|
case *canvas.Text:
|
|||
|
r.writeText(o, attrs)
|
|||
|
case *fyne.Container:
|
|||
|
r.writeContainer(o, attrs)
|
|||
|
case fyne.Widget:
|
|||
|
r.writeWidget(o, attrs)
|
|||
|
case *layout.Spacer:
|
|||
|
r.writeSpacer(o, attrs)
|
|||
|
default:
|
|||
|
panic(fmt.Sprint("please add support for", reflect.TypeOf(o)))
|
|||
|
}
|
|||
|
|
|||
|
return false
|
|||
|
}
|
|||
|
|
|||
|
func (r *markupRenderer) writeCircle(c *canvas.Circle, attrs map[string]*string) {
|
|||
|
r.setColorAttr(attrs, "fillColor", c.FillColor)
|
|||
|
r.setColorAttr(attrs, "strokeColor", c.StrokeColor)
|
|||
|
r.setFloatAttr(attrs, "strokeWidth", float64(c.StrokeWidth))
|
|||
|
r.writeTag("circle", true, attrs)
|
|||
|
}
|
|||
|
|
|||
|
func (r *markupRenderer) writeCloseCanvasObject(o fyne.CanvasObject, _ fyne.Position, _ fyne.CanvasObject) {
|
|||
|
switch o.(type) {
|
|||
|
case *fyne.Container:
|
|||
|
r.indentation--
|
|||
|
r.writeIndent()
|
|||
|
r.writeCloseTag("container")
|
|||
|
case fyne.Widget:
|
|||
|
r.indentation--
|
|||
|
r.writeIndent()
|
|||
|
r.writeCloseTag("widget")
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
func (r *markupRenderer) writeCloseTag(name string) {
|
|||
|
r.w.WriteString("</")
|
|||
|
r.w.WriteString(name)
|
|||
|
r.w.WriteString(">\n")
|
|||
|
}
|
|||
|
|
|||
|
func (r *markupRenderer) writeContainer(c *fyne.Container, attrs map[string]*string) {
|
|||
|
r.writeTag("container", false, attrs)
|
|||
|
r.w.WriteRune('\n')
|
|||
|
r.indentation++
|
|||
|
}
|
|||
|
|
|||
|
func (r *markupRenderer) writeIndent() {
|
|||
|
for i := 0; i < r.indentation; i++ {
|
|||
|
r.w.WriteRune('\t')
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
func (r *markupRenderer) writeImage(i *canvas.Image, attrs map[string]*string) {
|
|||
|
r.setStringAttr(attrs, "file", i.File)
|
|||
|
r.setResourceAttr(attrs, "rsc", i.Resource)
|
|||
|
if i.File == "" && i.Resource == nil {
|
|||
|
r.setBoolAttr(attrs, "img", i.Image != nil)
|
|||
|
}
|
|||
|
r.setFloatAttr(attrs, "translucency", i.Translucency)
|
|||
|
r.setFillModeAttr(attrs, "fillMode", i.FillMode)
|
|||
|
r.setScaleModeAttr(attrs, "scaleMode", i.ScaleMode)
|
|||
|
if i.Size().Width == theme.IconInlineSize() && i.Size().Height == i.Size().Width {
|
|||
|
r.setStringAttr(attrs, "size", "iconInlineSize")
|
|||
|
}
|
|||
|
r.writeTag("image", true, attrs)
|
|||
|
}
|
|||
|
|
|||
|
func (r *markupRenderer) writeLine(l *canvas.Line, attrs map[string]*string) {
|
|||
|
r.setColorAttr(attrs, "strokeColor", l.StrokeColor)
|
|||
|
r.setFloatAttrWithDefault(attrs, "strokeWidth", float64(l.StrokeWidth), 1)
|
|||
|
r.writeTag("line", true, attrs)
|
|||
|
}
|
|||
|
|
|||
|
func (r *markupRenderer) writeLinearGradient(g *canvas.LinearGradient, attrs map[string]*string) {
|
|||
|
r.setColorAttr(attrs, "startColor", g.StartColor)
|
|||
|
r.setColorAttr(attrs, "endColor", g.EndColor)
|
|||
|
r.setFloatAttr(attrs, "angle", g.Angle)
|
|||
|
r.writeTag("linearGradient", true, attrs)
|
|||
|
}
|
|||
|
|
|||
|
func (r *markupRenderer) writeRadialGradient(g *canvas.RadialGradient, attrs map[string]*string) {
|
|||
|
r.setColorAttr(attrs, "startColor", g.StartColor)
|
|||
|
r.setColorAttr(attrs, "endColor", g.EndColor)
|
|||
|
r.setFloatPosAttr(attrs, "centerOffset", g.CenterOffsetX, g.CenterOffsetY)
|
|||
|
r.writeTag("radialGradient", true, attrs)
|
|||
|
}
|
|||
|
|
|||
|
func (r *markupRenderer) writeRaster(rst *canvas.Raster, attrs map[string]*string) {
|
|||
|
r.setFloatAttr(attrs, "translucency", rst.Translucency)
|
|||
|
r.writeTag("raster", true, attrs)
|
|||
|
}
|
|||
|
|
|||
|
func (r *markupRenderer) writeRectangle(rct *canvas.Rectangle, attrs map[string]*string) {
|
|||
|
r.setColorAttr(attrs, "fillColor", rct.FillColor)
|
|||
|
r.setColorAttr(attrs, "strokeColor", rct.StrokeColor)
|
|||
|
r.setFloatAttr(attrs, "strokeWidth", float64(rct.StrokeWidth))
|
|||
|
r.setFloatAttr(attrs, "radius", float64(rct.CornerRadius))
|
|||
|
r.writeTag("rectangle", true, attrs)
|
|||
|
}
|
|||
|
|
|||
|
func (r *markupRenderer) writeSpacer(_ *layout.Spacer, attrs map[string]*string) {
|
|||
|
r.writeTag("spacer", true, attrs)
|
|||
|
}
|
|||
|
|
|||
|
func (r *markupRenderer) writeTag(name string, isEmpty bool, attrs map[string]*string) {
|
|||
|
r.writeIndent()
|
|||
|
r.w.WriteRune('<')
|
|||
|
r.w.WriteString(name)
|
|||
|
for _, key := range sortedKeys(attrs) {
|
|||
|
r.w.WriteRune(' ')
|
|||
|
r.w.WriteString(key)
|
|||
|
if attrs[key] != nil {
|
|||
|
r.w.WriteString("=\"")
|
|||
|
r.w.WriteString(*attrs[key])
|
|||
|
r.w.WriteRune('"')
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
if isEmpty {
|
|||
|
r.w.WriteString("/>\n")
|
|||
|
} else {
|
|||
|
r.w.WriteRune('>')
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
func (r *markupRenderer) writeText(t *canvas.Text, attrs map[string]*string) {
|
|||
|
r.setColorAttrWithDefault(attrs, "color", t.Color, theme.ForegroundColor())
|
|||
|
r.setAlignmentAttr(attrs, "alignment", t.Alignment)
|
|||
|
r.setSizeAttrWithDefault(attrs, "textSize", t.TextSize, theme.TextSize())
|
|||
|
r.setBoolAttr(attrs, "bold", t.TextStyle.Bold)
|
|||
|
r.setBoolAttr(attrs, "italic", t.TextStyle.Italic)
|
|||
|
r.setBoolAttr(attrs, "monospace", t.TextStyle.Monospace)
|
|||
|
r.writeTag("text", false, attrs)
|
|||
|
r.w.WriteString(t.Text)
|
|||
|
r.writeCloseTag("text")
|
|||
|
}
|
|||
|
|
|||
|
func (r *markupRenderer) writeWidget(w fyne.Widget, attrs map[string]*string) {
|
|||
|
r.setStringAttr(attrs, "type", reflect.TypeOf(w).String())
|
|||
|
r.writeTag("widget", false, attrs)
|
|||
|
r.w.WriteRune('\n')
|
|||
|
r.indentation++
|
|||
|
}
|
|||
|
|
|||
|
func nrgbaColor(c color.Color) color.NRGBA {
|
|||
|
// using ColorToNRGBA to avoid problems with colors with 16-bit components or alpha values that aren't 0 or the maximum possible alpha value
|
|||
|
r, g, b, a := col.ToNRGBA(c)
|
|||
|
return color.NRGBA{R: uint8(r), G: uint8(g), B: uint8(b), A: uint8(a)}
|
|||
|
}
|
|||
|
|
|||
|
func knownColor(c color.Color) string {
|
|||
|
return map[color.Color]string{
|
|||
|
nrgbaColor(theme.BackgroundColor()): "background",
|
|||
|
nrgbaColor(theme.ButtonColor()): "button",
|
|||
|
nrgbaColor(theme.DisabledButtonColor()): "disabled button",
|
|||
|
nrgbaColor(theme.DisabledColor()): "disabled",
|
|||
|
nrgbaColor(theme.ErrorColor()): "error",
|
|||
|
nrgbaColor(theme.FocusColor()): "focus",
|
|||
|
nrgbaColor(theme.ForegroundColor()): "foreground",
|
|||
|
nrgbaColor(theme.HoverColor()): "hover",
|
|||
|
nrgbaColor(theme.InputBackgroundColor()): "inputBackground",
|
|||
|
nrgbaColor(theme.InputBorderColor()): "inputBorder",
|
|||
|
nrgbaColor(theme.MenuBackgroundColor()): "menuBackground",
|
|||
|
nrgbaColor(theme.OverlayBackgroundColor()): "overlayBackground",
|
|||
|
nrgbaColor(theme.PlaceHolderColor()): "placeholder",
|
|||
|
nrgbaColor(theme.PrimaryColor()): "primary",
|
|||
|
nrgbaColor(theme.ScrollBarColor()): "scrollbar",
|
|||
|
nrgbaColor(theme.SelectionColor()): "selection",
|
|||
|
nrgbaColor(theme.ShadowColor()): "shadow",
|
|||
|
}[nrgbaColor(c)]
|
|||
|
}
|
|||
|
|
|||
|
func knownResource(rsc fyne.Resource) string {
|
|||
|
return map[fyne.Resource]string{
|
|||
|
theme.CancelIcon(): "cancelIcon",
|
|||
|
theme.CheckButtonCheckedIcon(): "checkButtonCheckedIcon",
|
|||
|
theme.CheckButtonIcon(): "checkButtonIcon",
|
|||
|
theme.ColorAchromaticIcon(): "colorAchromaticIcon",
|
|||
|
theme.ColorChromaticIcon(): "colorChromaticIcon",
|
|||
|
theme.ColorPaletteIcon(): "colorPaletteIcon",
|
|||
|
theme.ComputerIcon(): "computerIcon",
|
|||
|
theme.ConfirmIcon(): "confirmIcon",
|
|||
|
theme.ContentAddIcon(): "contentAddIcon",
|
|||
|
theme.ContentClearIcon(): "contentClearIcon",
|
|||
|
theme.ContentCopyIcon(): "contentCopyIcon",
|
|||
|
theme.ContentCutIcon(): "contentCutIcon",
|
|||
|
theme.ContentPasteIcon(): "contentPasteIcon",
|
|||
|
theme.ContentRedoIcon(): "contentRedoIcon",
|
|||
|
theme.ContentRemoveIcon(): "contentRemoveIcon",
|
|||
|
theme.ContentUndoIcon(): "contentUndoIcon",
|
|||
|
theme.DeleteIcon(): "deleteIcon",
|
|||
|
theme.DocumentCreateIcon(): "documentCreateIcon",
|
|||
|
theme.DocumentIcon(): "documentIcon",
|
|||
|
theme.DocumentPrintIcon(): "documentPrintIcon",
|
|||
|
theme.DocumentSaveIcon(): "documentSaveIcon",
|
|||
|
theme.DownloadIcon(): "downloadIcon",
|
|||
|
theme.ErrorIcon(): "errorIcon",
|
|||
|
theme.FileApplicationIcon(): "fileApplicationIcon",
|
|||
|
theme.FileAudioIcon(): "fileAudioIcon",
|
|||
|
theme.FileIcon(): "fileIcon",
|
|||
|
theme.FileImageIcon(): "fileImageIcon",
|
|||
|
theme.FileTextIcon(): "fileTextIcon",
|
|||
|
theme.FileVideoIcon(): "fileVideoIcon",
|
|||
|
theme.FolderIcon(): "folderIcon",
|
|||
|
theme.FolderNewIcon(): "folderNewIcon",
|
|||
|
theme.FolderOpenIcon(): "folderOpenIcon",
|
|||
|
theme.FyneLogo(): "fyneLogo",
|
|||
|
theme.HelpIcon(): "helpIcon",
|
|||
|
theme.HistoryIcon(): "historyIcon",
|
|||
|
theme.HomeIcon(): "homeIcon",
|
|||
|
theme.InfoIcon(): "infoIcon",
|
|||
|
theme.MailAttachmentIcon(): "mailAttachementIcon",
|
|||
|
theme.MailComposeIcon(): "mailComposeIcon",
|
|||
|
theme.MailForwardIcon(): "mailForwardIcon",
|
|||
|
theme.MailReplyAllIcon(): "mailReplyAllIcon",
|
|||
|
theme.MailReplyIcon(): "mailReplyIcon",
|
|||
|
theme.MailSendIcon(): "mailSendIcon",
|
|||
|
theme.MediaFastForwardIcon(): "mediaFastForwardIcon",
|
|||
|
theme.MediaFastRewindIcon(): "mediaFastRewindIcon",
|
|||
|
theme.MediaPauseIcon(): "mediaPauseIcon",
|
|||
|
theme.MediaPlayIcon(): "mediaPlayIcon",
|
|||
|
theme.MediaRecordIcon(): "mediaRecordIcon",
|
|||
|
theme.MediaReplayIcon(): "mediaReplayIcon",
|
|||
|
theme.MediaSkipNextIcon(): "mediaSkipNextIcon",
|
|||
|
theme.MediaSkipPreviousIcon(): "mediaSkipPreviousIcon",
|
|||
|
theme.MenuDropDownIcon(): "menuDropDownIcon",
|
|||
|
theme.MenuDropUpIcon(): "menuDropUpIcon",
|
|||
|
theme.MenuExpandIcon(): "menuExpandIcon",
|
|||
|
theme.MenuIcon(): "menuIcon",
|
|||
|
theme.MoveDownIcon(): "moveDownIcon",
|
|||
|
theme.MoveUpIcon(): "moveUpIcon",
|
|||
|
theme.NavigateBackIcon(): "navigateBackIcon",
|
|||
|
theme.NavigateNextIcon(): "navigateNextIcon",
|
|||
|
theme.QuestionIcon(): "questionIcon",
|
|||
|
theme.RadioButtonCheckedIcon(): "radioButtonCheckedIcon",
|
|||
|
theme.RadioButtonIcon(): "radioButtonIcon",
|
|||
|
theme.SearchIcon(): "searchIcon",
|
|||
|
theme.SearchReplaceIcon(): "searchReplaceIcon",
|
|||
|
theme.SettingsIcon(): "settingsIcon",
|
|||
|
theme.StorageIcon(): "storageIcon",
|
|||
|
theme.ViewFullScreenIcon(): "viewFullScreenIcon",
|
|||
|
theme.ViewRefreshIcon(): "viewRefreshIcon",
|
|||
|
theme.ViewRestoreIcon(): "viewRestoreIcon",
|
|||
|
theme.VisibilityIcon(): "visibilityIcon",
|
|||
|
theme.VisibilityOffIcon(): "visibilityOffIcon",
|
|||
|
theme.VolumeDownIcon(): "volumeDownIcon",
|
|||
|
theme.VolumeMuteIcon(): "volumeMuteIcon",
|
|||
|
theme.VolumeUpIcon(): "volumeUpIcon",
|
|||
|
theme.WarningIcon(): "warningIcon",
|
|||
|
theme.ZoomFitIcon(): "zoomFitIcon",
|
|||
|
theme.ZoomInIcon(): "zoomInIcon",
|
|||
|
theme.ZoomOutIcon(): "zoomOutIcon",
|
|||
|
}[rsc]
|
|||
|
}
|
|||
|
|
|||
|
func sortedKeys(m map[string]*string) []string {
|
|||
|
keys := make([]string, 0, len(m))
|
|||
|
for k := range m {
|
|||
|
keys = append(keys, k)
|
|||
|
}
|
|||
|
sort.Strings(keys)
|
|||
|
return keys
|
|||
|
}
|