Files

177 lines
4.2 KiB
Go

package assets
import (
"image"
"path"
"strconv"
"aego/core/errs"
"aego/core/ids"
"aego/editor/core/assetops"
"aego/editor/core/context"
"aego/platform/clip"
)
type cutSet struct {
list []ids.AssetID
paths []string
}
func (p *Panel) selectList(list []ids.AssetID) {
clear(p.sel)
for _, id := range list {
p.sel[id] = true
}
if n := len(list); n > 0 {
p.active, p.anchor, p.scrollTo = list[n-1], list[0], list[0]
}
}
func (p *Panel) CopySelected() error {
p.cut = cutSet{}
if paths := p.d.Files.CopyAssets(p.Selection()); len(paths) > 0 {
p.d.Notices.Notify(context.LevelInfo, "Copied "+strconv.Itoa(len(paths))+" asset(s)")
}
return nil
}
func (p *Panel) CutSelected() error {
list := p.Selection()
paths := p.d.Files.CopyAssets(list)
p.cut = cutSet{}
if len(paths) == 0 {
return nil
}
p.cut = cutSet{list: list, paths: paths}
p.d.Notices.Notify(context.LevelInfo, "Cut "+strconv.Itoa(len(paths))+" asset(s), paste into another folder to move them")
return nil
}
func (p *Panel) PasteHere() error {
return p.Paste(p.folder)
}
func (p *Panel) Paste(dir string) error {
if p.d.Files.Clipboard() == nil || p.d.Pipeline == nil {
return nil
}
if files, ok := clip.Files(p.d.Files.Clipboard()); ok {
if len(p.cut.paths) > 0 && assetops.SamePaths(files, p.cut.paths) {
return p.pasteCut(dir)
}
return p.pasteFiles(files, dir)
}
if img, ok := clip.Image(p.d.Files.Clipboard()); ok {
return p.pasteImage(img, dir)
}
p.d.Notices.Notify(context.LevelInfo, "The clipboard has no image or files to paste")
return nil
}
func (p *Panel) pasteCut(dir string) error {
var items []context.AssetPayload
for _, id := range p.cut.list {
if e, ok := p.d.Pipeline.Entry(id); ok && !e.Missing {
items = append(items, context.AssetPayload{ID: id, Kind: e.Kind, Name: e.Name})
}
}
p.cut = cutSet{}
if len(items) == 0 {
return nil
}
p.moveInto(items, nil, dir)
moved := make([]ids.AssetID, len(items))
for i, it := range items {
moved[i] = it.ID
}
if paths := p.d.Files.AbsPaths(moved); len(paths) > 0 {
clip.SetFiles(p.d.Files.Clipboard(), paths)
}
p.folder, p.search = dir, ""
p.expanded[path.Dir(dir)] = true
p.selectList(moved)
return nil
}
func (p *Panel) copyInto(id ids.AssetID, dir string) (ids.AssetID, error) {
orig, ok := p.d.Pipeline.PathOf(id)
if !ok {
return ids.AssetID{}, errs.New(errs.EditorDocument, "the copied asset no longer exists")
}
dup, err := p.d.Files.Duplicate(id)
if err != nil || path.Dir(orig) == dir {
return dup, err
}
rel, ok := p.d.Pipeline.PathOf(dup)
if !ok {
return dup, nil
}
return dup, p.d.Files.MoveFile(dup, rel, p.d.Files.UniqueFile(dir, assetops.Stem(orig), path.Ext(orig)))
}
func (p *Panel) pasteFiles(files []string, dir string) error {
var outside []string
var made []ids.AssetID
var first error
keep := func(err error) {
if err != nil && first == nil {
first = err
}
}
for _, f := range files {
rel, inside := assetops.RelIn(p.d.Pipeline, f)
if !inside {
outside = append(outside, f)
continue
}
id, ok := p.d.Pipeline.Lookup(rel)
if !ok {
keep(errs.New(errs.EditorDocument, rel+" is not an asset, folders are moved by dragging"))
continue
}
dup, err := p.copyInto(id, dir)
keep(err)
if !dup.IsZero() {
made = append(made, dup)
}
}
if len(outside) > 0 {
created, err := p.d.Files.ImportExternal(outside, dir)
keep(err)
made = append(made, created...)
}
if len(made) > 0 {
p.folder, p.search = dir, ""
p.expanded[path.Dir(dir)] = true
p.selectList(made)
p.d.Notices.Notify(context.LevelInfo, "Pasted "+strconv.Itoa(len(made))+" file(s) into "+dir)
}
p.invalidate()
return first
}
func (p *Panel) pasteImage(img image.Image, dir string) error {
rel := p.d.Files.NextNumbered(dir, assetops.PastedName, " ", ".png")
if _, err := p.d.Files.CreatePNG(rel, img); err != nil {
return err
}
p.created(rel)
p.StartRename()
return nil
}
func (p *Panel) scrollToTile(cols int, tileH, h float32) {
if p.scrollTo.IsZero() {
return
}
k := p.viewIndex(p.scrollTo)
p.scrollTo = ids.AssetID{}
if k < 0 {
return
}
top := float32((k+len(p.subdirs))/cols) * tileH
if top < p.gridScroll || top+tileH > p.gridScroll+h {
p.gridScroll = max(0, top-(h-tileH)/2)
}
}