Skip to content

Commit

Permalink
markdown: partially re-enable markdown
Browse files Browse the repository at this point in the history
now it at least renders something

By something I mean the following works:
- plain text
- bullet points
- indent
  • Loading branch information
gucio321 committed Nov 11, 2024
1 parent 96a0cec commit 8d58a75
Show file tree
Hide file tree
Showing 3 changed files with 144 additions and 92 deletions.
230 changes: 140 additions & 90 deletions Markdown.go
Original file line number Diff line number Diff line change
@@ -1,20 +1,55 @@
//nolint:gocritic,govet,wsl,revive // this file is TODO. We don't want commentedOutCode lint issues here.
package giu

import (
"image"
"net/http"
"strings"
"time"

"github.com/AllenDang/cimgui-go/imgui"
"github.com/AllenDang/cimgui-go/immarkdown"
)

type markdownState struct {
cfg immarkdown.MarkdownConfig
}

func (m *markdownState) Dispose() {
// noop
}

func (m *MarkdownWidget) getState() *markdownState {
if s := GetState[markdownState](Context, m.id); s != nil {
return s
}

newState := m.newState()
SetState[markdownState](Context, m.id, newState)
return newState
}

func (m *MarkdownWidget) newState() *markdownState {
cfg := immarkdown.NewMarkdownConfigEmpty()
fmtCb := immarkdown.MarkdownFormalCallback(mdFormatCallback)
cfg.SetFormatCallback(&fmtCb)
return &markdownState{
cfg: *cfg,
}
}

// MarkdownWidget implements DearImGui markdown extension
// https://github.com/juliettef/imgui_markdown
// It is like LabelWidget but with md formatting.
// TODO: re-implement this.
type MarkdownWidget struct {
md *string
linkCb func(url string)
// headers []imgui.MarkdownHeaderData
md string
id ID
linkCb func(url string)
headers []immarkdown.MarkdownHeadingFormat
}

// Markdown creates new markdown widget.
func Markdown(md *string) *MarkdownWidget {
panic("MarkdownWidget is not implemented yet!")

func Markdown(md string) *MarkdownWidget {
return &MarkdownWidget{
md: md,
linkCb: OpenURL,
Expand All @@ -31,97 +66,112 @@ func (m *MarkdownWidget) OnLink(cb func(url string)) *MarkdownWidget {
// 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 m.headers == nil {
m.headers = make([]immarkdown.MarkdownHeadingFormat, level)
}

// if level <= len(m.headers) {
// m.headers = append(m.headers, make([]imgui.MarkdownHeaderData, len(m.headers)-level+1)...)
//}
if level <= len(m.headers) {
m.headers = append(m.headers, make([]immarkdown.MarkdownHeadingFormat, len(m.headers)-level+1)...)
}

// if font != nil {
// if f, ok := Context.FontAtlas.extraFontMap[font.String()]; ok {
// m.headers[level].Font = *f
// }
//}
m.headers[level] = *immarkdown.NewMarkdownHeadingFormatEmpty()
if font != nil {
if f, ok := Context.FontAtlas.extraFontMap[font.String()]; ok {
m.headers[level].SetFont(f)
}
}

// m.headers[level].HasSeparator = separator
m.headers[level].SetSeparator(separator)

return m
}

// Build implements Widget interface.
func (m *MarkdownWidget) Build() {
// imgui.Markdown(Context.FontAtlas.RegisterStringPointer(m.md), m.linkCb, loadImage, m.headers)
state := m.getState()
immarkdown.Markdown(
Context.FontAtlas.RegisterString(m.md),
uint64(len(m.md)),
state.cfg,
)
// 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}),
//}
//}
func loadImage(path string) immarkdown.MarkdownImageData {
var (
img *image.RGBA
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 *immarkdown.NewMarkdownImageDataEmpty()
}

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 *immarkdown.NewMarkdownImageDataEmpty()
}

img = ImageToRgba(rgba)
default:
img, err = LoadImage(path)
if err != nil {
return *immarkdown.NewMarkdownImageDataEmpty()
}
}

size := img.Bounds()

// if current workaround is save
/*
tex := &Texture{}
NewTextureFromRgba(img, func(t *Texture) {
fmt.Println("creating texture")
tex.id = t.id
})
*/

var id imgui.TextureID

mainthreadCallPlatform(func() {
// TODO: actually load this hehe
/*
var err error
id, err = Context.renderer.LoadImage(img)
if err != nil {
return
}
*/
})

result := immarkdown.NewMarkdownImageDataEmpty()
result.SetUsertextureid(id)
// Scale: true,
result.SetSize(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}),
return *result
}

func mdFormatCallback(f immarkdown.MarkdownFormatInfo, start bool) {
// noop
}
4 changes: 2 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
module github.com/AllenDang/giu

go 1.23.2
go 1.23.3

require (
github.com/AllenDang/cimgui-go v1.1.1-0.20241105214716-82a5c1ae9712
github.com/AllenDang/cimgui-go v1.1.1-0.20241110184948-72c467a7f306
github.com/AllenDang/go-findfont v0.0.0-20200702051237-9f180485aeb8
github.com/faiface/mainthread v0.0.0-20171120011319-8b78f0a41ae3
github.com/gucio321/glm-go v0.0.0-20241029220517-e1b5a3e011c8
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
github.com/AllenDang/cimgui-go v1.1.1-0.20241105214716-82a5c1ae9712 h1:Qog9ZG14NbkuzbqzwT7zX9u+yi1fTU8ZIlesefYmc40=
github.com/AllenDang/cimgui-go v1.1.1-0.20241105214716-82a5c1ae9712/go.mod h1:/gM0PosnwlgK0Fc3UFALXWPEIu+cW2DC3YU0Z4EwV2Y=
github.com/AllenDang/cimgui-go v1.1.1-0.20241110184948-72c467a7f306 h1:B0zIFc0Y0kp5kYlI0gtZXh10bIhtWy0ClDzexJlCnxY=
github.com/AllenDang/cimgui-go v1.1.1-0.20241110184948-72c467a7f306/go.mod h1:/gM0PosnwlgK0Fc3UFALXWPEIu+cW2DC3YU0Z4EwV2Y=
github.com/AllenDang/go-findfont v0.0.0-20200702051237-9f180485aeb8 h1:dKZMqib/yUDoCFigmz2agG8geZ/e3iRq304/KJXqKyw=
github.com/AllenDang/go-findfont v0.0.0-20200702051237-9f180485aeb8/go.mod h1:b4uuDd0s6KRIPa84cEEchdQ9ICh7K0OryZHbSzMca9k=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
Expand Down

0 comments on commit 8d58a75

Please sign in to comment.