| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131 |
- package giu
- import (
- "image"
- "image/color"
- "net/http"
- "strings"
- "time"
- "github.com/AllenDang/imgui-go"
- "github.com/faiface/mainthread"
- )
- // MarkdownWidget implements DearImGui markdown extension
- // https://github.com/juliettef/imgui_markdown
- // It is like LabelWidget but with md formatting.
- type MarkdownWidget struct {
- md *string
- linkCb func(url string)
- headers []imgui.MarkdownHeaderData
- }
- // Markdown creates new markdown widget.
- func Markdown(md *string) *MarkdownWidget {
- return &MarkdownWidget{
- md: md,
- linkCb: OpenURL,
- }
- }
- // OnLink sets another than default link callback.
- func (m *MarkdownWidget) OnLink(cb func(url string)) *MarkdownWidget {
- m.linkCb = cb
- return m
- }
- // Header sets header formatting
- // NOTE: level (counting from 0!) is header level. (for instance, header `# H1` will have level 0).
- func (m *MarkdownWidget) Header(level int, font *FontInfo, separator bool) *MarkdownWidget {
- // ensure if header data are at least as long as level
- if m.headers == nil {
- m.headers = make([]imgui.MarkdownHeaderData, level)
- }
- if level <= len(m.headers) {
- m.headers = append(m.headers, make([]imgui.MarkdownHeaderData, len(m.headers)-level+1)...)
- }
- if font != nil {
- if f, ok := extraFontMap[font.String()]; ok {
- m.headers[level].Font = *f
- }
- }
- m.headers[level].HasSeparator = separator
- return m
- }
- // Build implements Widget interface.
- func (m *MarkdownWidget) Build() {
- imgui.Markdown(tStrPtr(m.md), m.linkCb, loadImage, m.headers)
- }
- func loadImage(path string) imgui.MarkdownImageData {
- var img *image.RGBA
- var err error
- switch {
- case strings.HasPrefix(path, "http://") || strings.HasPrefix(path, "https://"):
- // Load image from url
- client := &http.Client{Timeout: 5 * time.Second}
- resp, respErr := client.Get(path)
- if respErr != nil {
- return imgui.MarkdownImageData{}
- }
- defer func() {
- closeErr := resp.Body.Close()
- Assert((closeErr == nil), "MarkdownWidget", "loadImage", "Could not close http request!")
- }()
- rgba, _, imgErr := image.Decode(resp.Body)
- if imgErr != nil {
- return imgui.MarkdownImageData{}
- }
- img = ImageToRgba(rgba)
- default:
- img, err = LoadImage(path)
- if err != nil {
- return imgui.MarkdownImageData{}
- }
- }
- size := img.Bounds()
- // nolint:gocritic // TODO/BUG: figure out, why it doesn't work as expected and consider
- // if current workaround is save
- /*
- tex := &Texture{}
- NewTextureFromRgba(img, func(t *Texture) {
- fmt.Println("creating texture")
- tex.id = t.id
- })
- */
- var id imgui.TextureID
- mainthread.Call(func() {
- var err error
- id, err = Context.renderer.LoadImage(img)
- if err != nil {
- return
- }
- })
- return imgui.MarkdownImageData{
- TextureID: &id,
- Scale: true,
- Size: imgui.Vec2{
- X: float32(size.Dx()),
- Y: float32(size.Dy()),
- },
- UseLinkCallback: true,
- // default values
- Uv0: ToVec2(image.Point{0, 0}),
- Uv1: ToVec2(image.Point{1, 1}),
- TintColor: ToVec4Color(color.RGBA{255, 255, 255, 255}),
- BorderColor: ToVec4Color(color.RGBA{0, 0, 0, 0}),
- }
- }
|