mirror of
https://github.com/kovidgoyal/kitty
synced 2026-06-08 14:18:26 +02:00
More work on image previews
This commit is contained in:
@@ -21,21 +21,89 @@ var preview_cache = sync.OnceValues(func() (*disk_cache.DiskCache, error) {
|
|||||||
return disk_cache.NewDiskCache(cdir, dc_size.Load())
|
return disk_cache.NewDiskCache(cdir, dc_size.Load())
|
||||||
})
|
})
|
||||||
|
|
||||||
|
type PreviewRenderer interface {
|
||||||
|
Render(string) (map[string][]byte, error)
|
||||||
|
Show(h *Handler, abspath string, metadata fs.FileInfo, x, y, width, height int, cached_data map[string]string)
|
||||||
|
}
|
||||||
|
|
||||||
|
type render_data struct {
|
||||||
|
cached_data map[string]string
|
||||||
|
err error
|
||||||
|
}
|
||||||
|
|
||||||
type ImagePreview struct {
|
type ImagePreview struct {
|
||||||
abspath, cache_key string
|
abspath, cache_key string
|
||||||
disk_cache *disk_cache.DiskCache
|
metadata fs.FileInfo
|
||||||
|
disk_cache *disk_cache.DiskCache
|
||||||
|
cached_data map[string]string
|
||||||
|
render_err Preview
|
||||||
|
render_channel chan render_data
|
||||||
|
renderer PreviewRenderer
|
||||||
|
file_metadata_preview Preview
|
||||||
|
WakeupMainThread func() bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p ImagePreview) IsValidForColorScheme(bool) bool { return true }
|
func (p ImagePreview) IsValidForColorScheme(bool) bool { return true }
|
||||||
|
|
||||||
func (p ImagePreview) Render(h *Handler, x, y, width, height int) {
|
func (p ImagePreview) Render(h *Handler, x, y, width, height int) {
|
||||||
offset := 0
|
if p.render_channel == nil {
|
||||||
offset += h.render_wrapped_text_in_region("Rendering image, please wait...", x, y, width, height, true)
|
if p.render_err == nil {
|
||||||
|
p.renderer.Show(h, p.abspath, p.metadata, x, y, width, height, p.cached_data)
|
||||||
|
} else {
|
||||||
|
p.render_err.Render(h, x, y, width, height)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
select {
|
||||||
|
case hd := <-p.render_channel:
|
||||||
|
p.render_channel = nil
|
||||||
|
p.cached_data = hd.cached_data
|
||||||
|
p.render_err = NewErrorPreview(fmt.Errorf("Failed to render the preview with error: %w", hd.err))
|
||||||
|
p.Render(h, x, y, width, height)
|
||||||
|
return
|
||||||
|
default:
|
||||||
|
}
|
||||||
|
if p.file_metadata_preview == nil {
|
||||||
|
p.file_metadata_preview = NewFileMetadataPreview(p.abspath, p.metadata)
|
||||||
|
}
|
||||||
|
p.file_metadata_preview.Render(h, x, y, width, height)
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewImagePreview(abspath string, metadata fs.FileInfo, opts Settings) (Preview, error) {
|
func (p *ImagePreview) start_rendering() {
|
||||||
|
defer func() {
|
||||||
|
p.WakeupMainThread()
|
||||||
|
}()
|
||||||
|
ans := p.disk_cache.Get(p.cache_key)
|
||||||
|
if len(ans) > 0 {
|
||||||
|
p.render_channel <- render_data{ans, nil}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
rdata, err := p.renderer.Render(p.abspath)
|
||||||
|
if err != nil {
|
||||||
|
p.render_channel <- render_data{nil, err}
|
||||||
|
} else {
|
||||||
|
ans, err = p.disk_cache.Add(p.cache_key, rdata)
|
||||||
|
p.render_channel <- render_data{utils.IfElse(err == nil, ans, nil), err}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type ImagePreviewRenderer uint
|
||||||
|
|
||||||
|
func (p ImagePreviewRenderer) Render(abspath string) (ans map[string][]byte, err error) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p ImagePreviewRenderer) Show(h *Handler, abspath string, metadata fs.FileInfo, x, y, width, height int, cached_data map[string]string) {
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewImagePreview(
|
||||||
|
abspath string, metadata fs.FileInfo, opts Settings, WakeupMainThread func() bool, r PreviewRenderer,
|
||||||
|
) (Preview, error) {
|
||||||
dc_size.Store(opts.DiskCacheSize())
|
dc_size.Store(opts.DiskCacheSize())
|
||||||
ans := &ImagePreview{abspath: abspath}
|
ans := &ImagePreview{
|
||||||
|
abspath: abspath, metadata: metadata, render_channel: make(chan render_data),
|
||||||
|
WakeupMainThread: WakeupMainThread, renderer: r,
|
||||||
|
}
|
||||||
if dc, err := preview_cache(); err != nil {
|
if dc, err := preview_cache(); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
} else {
|
} else {
|
||||||
@@ -46,5 +114,6 @@ func NewImagePreview(abspath string, metadata fs.FileInfo, opts Settings) (Previ
|
|||||||
} else {
|
} else {
|
||||||
ans.cache_key = key
|
ans.cache_key = key
|
||||||
}
|
}
|
||||||
|
go ans.start_rendering()
|
||||||
return ans, nil
|
return ans, nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -298,11 +298,12 @@ func (pm *PreviewManager) preview_for(abspath string, ftype fs.FileMode) (ans Pr
|
|||||||
return NewTextFilePreview(abspath, s, ch, pm.highlighter.Sanitize)
|
return NewTextFilePreview(abspath, s, ch, pm.highlighter.Sanitize)
|
||||||
}
|
}
|
||||||
if strings.HasPrefix(mt, "image/") {
|
if strings.HasPrefix(mt, "image/") {
|
||||||
ans, err := NewImagePreview(abspath, s, pm.settings)
|
var r ImagePreviewRenderer
|
||||||
if err != nil {
|
if ans, err := NewImagePreview(abspath, s, pm.settings, pm.WakeupMainThread, r); err == nil {
|
||||||
|
return ans
|
||||||
|
} else {
|
||||||
return NewErrorPreview(err)
|
return NewErrorPreview(err)
|
||||||
}
|
}
|
||||||
return ans
|
|
||||||
}
|
}
|
||||||
return NewFileMetadataPreview(abspath, s)
|
return NewFileMetadataPreview(abspath, s)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user