使用Go的exp/shiny时,如何绘制底层小部件?

huangapple go评论96阅读模式
英文:

How does one paint underlying widgets when using go's exp/shiny?

问题

假设以下是要翻译的内容:

#假设以下是小部件布局

    type myLeaf struct {
    	node.LeafEmbed
    	// 其他一些字段
    }
        
    func NewMyLeaf() *myLeaf {
    	w := &myLeaf{}
    	w.Wrapper = w
    	return w
    }
    
    func (w *myLeaf) Paint(ctx *node.PaintContext, origin image.Point) error {
    	w.Marks.UnmarkNeedsPaint()
    	// 在ctx上绘制...
    }

#`driver.Main()`内部

    leafA := NewMyLeaf()
    leafB := NewMyLeaf()
    
    w := widget.NewFlow(widget.AxisVertical,
    	widget.NewSheet(leafA),
    	widget.NewSheet(leafB),
    )
    
    if err := widget.RunWindow(s, w, &widget.RunWindowOptions{
    	NewWindowOptions: screen.NewWindowOptions{},
    }); err != nil {
    	log.Fatal(err)
    }

如何在`driver.Main()`之外执行`func (w *myLeaf) Paint(...) error`对于每个叶子`myLeaf`的小部件树

同时对于`leafA``leafB``w`使用指针是可能的

以下是翻译的结果:

#假设以下是小部件布局

    type myLeaf struct {
    	node.LeafEmbed
    	// 其他一些字段
    }
        
    func NewMyLeaf() *myLeaf {
    	w := &myLeaf{}
    	w.Wrapper = w
    	return w
    }
    
    func (w *myLeaf) Paint(ctx *node.PaintContext, origin image.Point) error {
    	w.Marks.UnmarkNeedsPaint()
    	// 在ctx上绘制...
    }

#`driver.Main()`内部

    leafA := NewMyLeaf()
    leafB := NewMyLeaf()
    
    w := widget.NewFlow(widget.AxisVertical,
    	widget.NewSheet(leafA),
    	widget.NewSheet(leafB),
    )
    
    if err := widget.RunWindow(s, w, &widget.RunWindowOptions{
    	NewWindowOptions: screen.NewWindowOptions{},
    }); err != nil {
    	log.Fatal(err)
    }

如何在`driver.Main()`之外执行`func (w *myLeaf) Paint(...) error`对于每个叶子`myLeaf`的小部件树

同时对于`leafA``leafB``w`使用指针是可能的
英文:

#Asuming the folowing widget layout:

type myLeaf struct {
	node.LeafEmbed
	// some other fields
}
    
func NewMyLeaf() *myLeaf {
	w := &myLeaf{}
	w.Wrapper = w
	return w
}

func (w *myLeaf) Paint(ctx *node.PaintContext, origin image.Point) error {
	w.Marks.UnmarkNeedsPaint()
	// draw to ctx ...
}

#Inside driver.Main():

leafA := NewMyLeaf()
leafB := NewMyLeaf()

w := widget.NewFlow(widget.AxisVertical,
	widget.NewSheet(leafA),
	widget.NewSheet(leafB),
)

if err := widget.RunWindow(s, w, &widget.RunWindowOptions{
	NewWindowOptions: screen.NewWindowOptions{},
}); err != nil {
	log.Fatal(err)
}

How does one execute func (w *myLeaf) Paint(...) error on the widget tree for each leaf (myLeaf) from outside driver.Main()?

Also using pointers for leafA, leafB and w is possible.

答案1

得分: 0

当我们查看这里时,我们发现widget.RunWindow( ... )不能处理来自调用者的外部请求。

一个解决方法是实现一个类似的函数MyRunWindow( ... )并将Window分配给一个全局接口。像这样:

func MyRunWindow(s screen.Screen, root node.Node, opts *RunWindowOptions) (err error) {
    var nwo *screen.NewWindowOptions

    // ... 分配窗口选项 ...

    if MyWindow, err = s.NewWindow(nwo); err != nil {
        return err
    }

    // 事件循环,处理 'lifecycle.Event','input.Event' 等
    // 你可以在类型开关中处理自己的 'Events'
    for {
        e := MyWindow.NextEvent()

        if e = gef.Filter(e); e == nil {
            continue
        }

        switch e := e.(type) {
        case MyEvent:
            // ... 在这里调用 'root'
        }
    }
}

在调用者的一侧,你可以像这样使用全局的Interface

MyWindow.Send(paint.Event{}) // 用于调用 root.Paint()
MyWindow.Send(MyEvent{})     // 用于处理自定义事件
英文:

When we look up here we see that widget.RunWindow( ... ) doesn't handle such external requests from the caller.

A workaraound could be to implement an analogous function MyRunWindow( ... ) and assign the Window to an global Interface. Like this:

func MyRunWindow(s screen.Screen, root node.Node, opts *RunWindowOptions) (err error) {
	var nwo *screen.NewWindowOptions

	// ... assign window options ...

	if MyWindow, err = s.NewWindow(nwo); err != nil {
		return err
	}

	// event loop, processing 'lifecycle.Event', 'input.Event', etc.
	// and you can process own 'Events' in a type switch
	for {
		e := MyWindow.NextEvent()

		if e = gef.Filter(e); e == nil {
			continue
		}

		switch e := e.(type) {
		case MyEvent:
		// ... call on 'root' here
		}
	}

On the caller side you can use your global Interface like this:

MyWindow.Send(paint.Event{}) // for a needed call to root.Paint()
MyWindow.Send(MyEvent{})     // for your own event to be processed

huangapple
  • 本文由 发表于 2017年8月8日 19:55:32
  • 转载请务必保留本文链接:https://go.coder-hub.com/45567710.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定