Example #1
0
func trViewExpose(tv sparta.Widget, e interface{}) bool {
	dt := tv.Property(sparta.Data)
	if dt == nil {
		return false
	}
	data := dt.(*trData)
	draw := tv.(*widget.Canvas)
	for _, n := range data.node {
		draw.Draw(n.ancLine)
		if n.level > 0 {
			draw.Draw(n.descLine)
		} else if len(n.name.Text) > 0 {
			draw.Draw(n.name)
		}
	}
	if n := data.sel; n != nil {
		rect := widget.Rectangle{
			Rect: image.Rect(n.pos.X-3, n.pos.Y-3, n.pos.X+3, n.pos.Y+3),
		}
		draw.Draw(rect)
		rect.Rect = image.Rect(n.pos.X-2, n.pos.Y-2, n.pos.X+2, n.pos.Y+2)
		rect.Fill = true
		draw.SetColor(sparta.Foreground, color.RGBA{G: 255})
		draw.Draw(rect)
	}
	return false
}
Example #2
0
// TxKey gets keyboard events.
func txKey(tx sparta.Widget, e interface{}) bool {
	data := tx.Property(sparta.Data).(*pageData)
	ev := e.(sparta.KeyEvent)
	switch ev.Key {
	case sparta.KeyDown:
		if (data.pos + 1) < (len(poem) - data.page + 1) {
			data.pos++
		}
		tx.Update()
	case sparta.KeyUp:
		if (data.pos - 1) >= 0 {
			data.pos--
		}
		tx.Update()
	case sparta.KeyPageUp:
		if data.pos == 0 {
			break
		}
		data.pos -= data.page
		if data.pos < 0 {
			data.pos = 0
		}
		tx.Update()
	case sparta.KeyPageDown:
		if data.pos == (len(poem) - data.page) {
			break
		}
		data.pos += data.page
		if data.pos > (len(poem) - data.page + 1) {
			data.pos = len(poem) - data.page
		}
		tx.Update()
	}
	return true
}
Example #3
0
// pgExpose draws the polygons.
func pgExpose(pg sparta.Widget, e interface{}) bool {
	data := pg.Property(sparta.Data).([]widget.Polygon)
	c := pg.(*widget.Canvas)
	c.Draw(data[0])
	c.Draw(data[1])
	return false
}
Example #4
0
func txEdInitList(m, l sparta.Widget, data *txList, i int, syns bool) {
	if data == nil {
		data = newTxList(nil, localDB, syns)
	} else {
		d := newTxList(data.desc[i], data.db, syns)
		if len(d.desc) == 0 {
			if l.Property(sparta.Name).(string) == "validList" {
				data.sels = []int{i}
			} else {
				sel := false
				for _, s := range data.sels {
					if s == i {
						sel = true
						break
					}
				}
				if !sel {
					data.sels = append(data.sels, i)
				}
			}
		} else {
			data = d
		}
	}
	if l.Property(sparta.Name).(string) == "taxonList" {
		m.SetProperty(sparta.Data, data)
	}
	l.SetProperty(widget.ListList, data)
}
Example #5
0
func txNavInfoExpose(tx sparta.Widget, e interface{}) bool {
	d := tx.Property(sparta.Data)
	if d == nil {
		return false
	}
	data := d.(*txTaxAnc)
	c := tx.(*widget.Canvas)
	txt := widget.Text{}
	txt.Pos.X = 2
	txt.Pos.Y = 2
	txt.Text = "Id: " + data.tax.Id
	c.Draw(txt)
	txt.Pos.Y += sparta.HeightUnit
	txt.Text = data.tax.Name
	c.Draw(txt)
	txt.Pos.Y += sparta.HeightUnit
	txt.Text = data.tax.Authority
	c.Draw(txt)
	txt.Pos.Y += sparta.HeightUnit
	txt.Text = data.tax.Rank.String()
	c.Draw(txt)
	txt.Pos.Y += sparta.HeightUnit
	if data.tax.IsValid {
		txt.Text = "Valid"
		c.Draw(txt)
		if data.anc != nil {
			txt.Pos.Y += sparta.HeightUnit
			txt.Text = "Parent: " + data.anc.Name
			c.Draw(txt)

		}
	} else {
		txt.Text = "Synonym of " + data.anc.Name
		c.Draw(txt)

	}
	if len(data.tax.Extern) > 0 {
		txt.Pos.Y += sparta.HeightUnit
		txt.Text = "Extern ids:"
		c.Draw(txt)
		for _, e := range data.tax.Extern {
			txt.Pos.Y += sparta.HeightUnit
			txt.Text = "    " + e
			c.Draw(txt)
		}
	}
	if len(data.tax.Comment) > 0 {
		txt.Pos.Y += sparta.HeightUnit
		txt.Text = "Comments:"
		c.Draw(txt)
		cmt := strings.Split(data.tax.Comment, "\n")
		for _, e := range cmt {
			txt.Pos.Y += sparta.HeightUnit
			txt.Text = "  " + e
			c.Draw(txt)
		}
	}
	return false
}
Example #6
0
// SnConf sets the new values of the sine function points
func snConf(sn sparta.Widget, e interface{}) bool {
	ev := e.(sparta.ConfigureEvent)

	// Get data from the widget.
	data := sn.Property(sparta.Data).([]image.Point)
	sine(data, ev.Rect.Dx(), ev.Rect.Dy())
	return false
}
Example #7
0
func txEdSetCaption(m sparta.Widget) {
	d := m.Property(sparta.Data)
	if d == nil {
		m.SetProperty(sparta.Caption, "no data")
		return
	}
	dt := d.(*txList)
	title := fmt.Sprintf("%s: %s [id: %s]", cmd.Name, dt.tax.Name, dt.tax.Id)
	m.SetProperty(sparta.Caption, title)
}
Example #8
0
func txNavComm(m sparta.Widget, e interface{}) bool {
	d := m.Property(sparta.Data)
	if d == nil {
		return true
	}
	data := d.(*txList)
	ev := e.(sparta.CommandEvent)
	switch ev.Source.Property(sparta.Name).(string) {
	case "taxonList":
		if ev.Value < 0 {
			i := -ev.Value - 1
			if i >= len(data.desc) {
				break
			}
			title := fmt.Sprintf("%s: please wait", cmd.Name)
			m.SetProperty(sparta.Caption, title)
			ev.Source.SetProperty(widget.ListList, nil)
			tx := wnd["info"]
			tx.SetProperty(sparta.Data, nil)
			tx.Update()
			sparta.Block(nil)
			go txNavInitList(m, ev.Source, data.db, data, i)
			break
		}
		if data.IsSel(ev.Value) {
			data.sels = nil
		} else {
			data.sels = []int{ev.Value}
		}
		tx := wnd["info"]
		tx.SetProperty(sparta.Data, nil)
		tx.Update()
		ev.Source.Update()
		sparta.Block(nil)
		go func() {
			txNavInfo(tx, data)
			sparta.Unblock(nil)
		}()
	case "upTax":
		if data.tax.Id == "0" {
			break
		}
		title := fmt.Sprintf("%s: please wait", cmd.Name)
		m.SetProperty(sparta.Caption, title)
		l := wnd["taxonList"]
		l.SetProperty(widget.ListList, nil)
		tx := wnd["info"]
		tx.SetProperty(sparta.Data, nil)
		sparta.Block(nil)
		go txNavAncList(m, l, data.db, data.tax)
	}
	return true
}
Example #9
0
func trViewInitTree(m, tv sparta.Widget) {
	d := m.Property(sparta.Data).(*trList)
	if d.pos >= len(d.phyLs) {
		return
	}
	title := fmt.Sprintf("%s: %s [id: %s]", cmd.Name, d.phyLs[d.pos].Name, d.phyLs[d.pos].Id)
	m.SetProperty(sparta.Caption, title)
	rect := tv.Property(sparta.Geometry).(image.Rectangle)
	curTree := setTree(d.phyLs[d.pos], rect)
	curTree.putOnScreen()
	tv.SetProperty(sparta.Data, curTree)
	tv.Update()
}
Example #10
0
func propagateWheel(w sparta.Widget, pt image.Point) sparta.Widget {
	rect := w.Property(sparta.Geometry).(image.Rectangle)
	childs := w.Property(sparta.Childs)
	if childs == nil {
		return w
	}
	for _, ch := range childs.([]sparta.Widget) {
		rect = ch.Property(sparta.Geometry).(image.Rectangle)
		if pt.In(rect) {
			return propagateWheel(ch, pt.Add(rect.Min))
		}
	}
	return w
}
Example #11
0
// ObExpose draws the objects.
func obExpose(ob sparta.Widget, e interface{}) bool {
	data := ob.Property(sparta.Data).(*objData)
	c := ob.(*widget.Canvas)
	// Set color sets a color temporalely for the following dawing
	// operations. Contrast this with the property sparta.Background
	// and sparta.Foreground.
	c.SetColor(sparta.Foreground, color.RGBA{255, 0, 0, 0})
	c.Draw(widget.Rectangle{Rect: data.arc.Rect})
	c.SetColor(sparta.Foreground, color.RGBA{0, 255, 0, 0})
	c.Draw(data.l1)
	c.Draw(data.l2)
	c.SetColor(sparta.Foreground, color.RGBA{0, 0, 255, 0})
	c.Draw(data.arc)
	return false
}
Example #12
0
// NewWindow creates a new window and assigns it to a widget.
func newWindow(w sparta.Widget) {
	var win *window
	rect := w.Property(sparta.Geometry).(image.Rectangle)
	if p := w.Property(sparta.Parent); p != nil {
		pW := p.(sparta.Widget)
		pWin := pW.Window().(*window)
		win = &window{
			w:    w,
			back: pWin.back,
			fore: pWin.fore,
			pos:  rect.Min,
		}
		count := len(pW.Property(sparta.Childs).([]sparta.Widget))
		pW.SetProperty(sparta.Childs, w)
		win.id = w32.CreateWindowEx(0, stringToUTF16(childClass), nil,
			uint(w32.WS_CHILDWINDOW|w32.WS_VISIBLE),
			rect.Min.X, rect.Min.Y, rect.Dx(), rect.Dy(),
			pWin.id, w32.HMENU(count),
			w32.HINSTANCE(w32.GetWindowLong(pWin.id, w32.GWL_HINSTANCE)), nil)
		if win.id == 0 {
			log.Printf("w32: error: %v\n", getLastError())
			os.Exit(1)
		}
	} else {
		win = &window{
			w:    w,
			back: bkGround,
			fore: frGround,
		}
		win.id = w32.CreateWindowEx(uint(w32.WS_EX_CLIENTEDGE),
			stringToUTF16(baseClass), stringToUTF16(""),
			uint(w32.WS_OVERLAPPEDWINDOW),
			150, 150, rect.Dx()+extraX, rect.Dy()+extraY,
			0, 0, instance, nil)
		if win.id == 0 {
			log.Printf("w32: error: %v\n", getLastError())
			os.Exit(1)
		}
	}
	widgetTable[win.id] = w
	w.SetWindow(win)

	w32.ShowWindow(win.id, w32.SW_SHOWDEFAULT)
	if !w32.UpdateWindow(win.id) {
		log.Printf("w32: error: %v\n", getLastError())
		os.Exit(1)
	}
}
Example #13
0
func txEdUpdateList(m, l sparta.Widget, data *txList, syns bool) {
	if data == nil {
		data = newTxList(nil, localDB, syns)
	} else {
		d := newTxList(data.tax, data.db, syns)
		if len(d.desc) == 0 {
			txEdAncList(m, l, data.tax, syns)
			return
		}
		data = d
	}
	if l.Property(sparta.Name).(string) == "taxonList" {
		m.SetProperty(sparta.Data, data)
	}
	l.SetProperty(widget.ListList, data)
}
Example #14
0
// SnExpose draw the sine function.
func snExpose(sn sparta.Widget, e interface{}) bool {
	// get point data.
	data := sn.Property(sparta.Data).([]image.Point)
	// get widget geometry
	geo := sn.Property(sparta.Geometry).(image.Rectangle)

	c := sn.(*widget.Canvas)
	// The widget canvas ruses the function Draw to draw particular
	// objects, it depends on the data type to decide what to draw.
	// Here a line (the "x" axis), is draw.
	c.Draw([]image.Point{image.Pt(0, geo.Dy()/2), image.Pt(geo.Dx(), geo.Dy()/2)})
	// Then the sine function is draw.
	c.Draw(data)

	return false
}
Example #15
0
func spNavInitSpeList(m, s sparta.Widget) {
	d := m.Property(sparta.Data)
	l := wnd["speList"]
	if d == nil {
		l.SetProperty(widget.ListList, nil)
		return
	}
	data := d.(*txList)
	if len(data.sels) == 0 {
		l.SetProperty(widget.ListList, nil)
		return
	}
	tax := data.desc[data.sels[0]]
	ls := newSpList(tax, data.db)
	l.SetProperty(widget.ListList, ls)
}
Example #16
0
// TxMouse gets mouse events.
func txMouse(tx sparta.Widget, e interface{}) bool {
	data := tx.Property(sparta.Data).(*pageData)
	ev := e.(sparta.MouseEvent)
	switch ev.Button {
	case sparta.MouseLeft, -sparta.MouseWheel:
		if (data.pos + 1) < (len(poem) - data.page + 1) {
			data.pos++
		}
		tx.Update()
	case sparta.MouseRight, sparta.MouseWheel:
		if (data.pos - 1) >= 0 {
			data.pos--
		}
		tx.Update()
	}
	return true
}
Example #17
0
// TxExpose draws the poem.
func txExpose(tx sparta.Widget, e interface{}) bool {
	data := tx.Property(sparta.Data).(*pageData)
	rect := tx.Property(sparta.Geometry).(image.Rectangle)
	c := tx.(*widget.Canvas)

	// Text store the text to be drawing
	txt := widget.Text{}
	txt.Pos.X = 2
	for i, ln := range poem[data.pos:] {
		// The position of the text is the top-right corner of
		// the rectange that enclose the text.
		txt.Pos.Y = (i * sparta.HeightUnit) + 2
		if txt.Pos.Y > rect.Dy() {
			break
		}
		txt.Text = ln
		c.Draw(txt)
	}
	return false
}
Example #18
0
func mConf(m sparta.Widget, e interface{}) bool {
	// the sparta.Childs property return the children of a widget.
	ch := m.Property(sparta.Childs).([]sparta.Widget)
	ev := e.(sparta.ConfigureEvent)
	for _, c := range ch {
		// We check the name propery of each widget and use it
		// to set the new geometry of each widget.
		switch nm := c.Property(sparta.Name).(string); nm {
		case "sine":
			c.SetProperty(sparta.Geometry, image.Rect(0, 0, ev.Rect.Dx()/2, ev.Rect.Dy()/2))
		case "polygon":
			c.SetProperty(sparta.Geometry, image.Rect(ev.Rect.Dx()/2, 0, ev.Rect.Dx(), ev.Rect.Dy()/2))
		case "objects":
			c.SetProperty(sparta.Geometry, image.Rect(0, ev.Rect.Dy()/2, ev.Rect.Dx()/2, ev.Rect.Dy()))
		case "poem":
			c.SetProperty(sparta.Geometry, image.Rect(ev.Rect.Dx()/2, ev.Rect.Dy()/2, ev.Rect.Dx(), ev.Rect.Dy()))
		}
	}
	return false
}
Example #19
0
func txEdAncList(m, l sparta.Widget, tax *jdh.Taxon, syns bool) {
	var p *jdh.Taxon
	if len(tax.Parent) > 0 {
		p = taxon(cmd, localDB, tax.Parent)
		if len(p.Id) == 0 {
			p = nil
		}
	}
	data := newTxList(p, localDB, syns)
	for i, d := range data.desc {
		if d.Id == tax.Id {
			data.sels = []int{i}
			break
		}
	}
	if l.Property(sparta.Name).(string) == "taxonList" {
		m.SetProperty(sparta.Data, data)
	}
	l.SetProperty(widget.ListList, data)
}
Example #20
0
// NewWindow creates a new window and assigns it to a widget.
func newWindow(w sparta.Widget) {
	s := xwin.DefaultScreen()
	pId := s.Root
	win := &window{
		id:   xwin.NewId(),
		w:    w,
		gc:   xwin.NewId(),
		back: s.WhitePixel,
		fore: s.BlackPixel,
	}
	if p := w.Property(sparta.Parent); p != nil {
		pw := p.(sparta.Widget)
		pWin := pw.Window().(*window)
		win.back = pWin.back
		win.fore = pWin.fore
		pId = pWin.id
		pw.SetProperty(sparta.Childs, w)
	}
	widgetTable[win.id] = w
	w.SetWindow(win)
	r := w.Property(sparta.Geometry).(image.Rectangle)
	xwin.CreateWindow(0, win.id, pId,
		int16(r.Min.X), int16(r.Min.Y), uint16(r.Dx()), uint16(r.Dy()), 0,
		xgb.WindowClassInputOutput, s.RootVisual, 0, nil)
	xwin.ChangeWindowAttributes(win.id, xgb.CWBackPixel|xgb.CWEventMask,
		[]uint32{
			win.back,
			allEventMask,
		})
	font := xwin.NewId()
	xwin.OpenFont(font, fixed)
	xwin.CreateGC(win.gc, win.id, xgb.GCBackground|xgb.GCForeground|xgb.GCFont,
		[]uint32{
			win.fore,
			win.back,
			uint32(font),
		})
	xwin.CloseFont(font)
	xwin.MapWindow(win.id)
	xwin.ChangeProperty(xgb.PropModeReplace, win.id, wmProtocols, atomType, 32, wmDelete)
}
Example #21
0
func trViewMouse(tv sparta.Widget, e interface{}) bool {
	dt := tv.Property(sparta.Data)
	if dt == nil {
		return true
	}
	data := dt.(*trData)
	ev := e.(sparta.MouseEvent)
	switch ev.Button {
	case sparta.MouseRight:
		if !setFlag {
			return true
		}
		if data.sel == nil {
			return true
		}
		sel := trViewNearestNode(ev.Loc, data.node)
		if sel == nil {
			return true
		}
		x, y, pos := data.x, data.y, data.pos
		p := tv.Property(sparta.Parent).(sparta.Widget)
		d := p.Property(sparta.Data).(*trList)
		if sel == data.sel {
			vals := new(jdh.Values)
			vals.Add(jdh.NodCollapse, sel.id)
			localDB.Exec(jdh.Delete, jdh.Nodes, vals)
			localDB.Exec(jdh.Commit, "", nil)
		} else if !sel.isValidSis(data.sel) {
			return true
		} else {
			vals := new(jdh.Values)
			vals.Add(jdh.KeyId, data.sel.id)
			vals.Add(jdh.NodSister, sel.id)
			localDB.Exec(jdh.Set, jdh.Nodes, vals)
			localDB.Exec(jdh.Commit, "", nil)
		}
		rect := tv.Property(sparta.Geometry).(image.Rectangle)
		data = setTree(d.phyLs[d.pos], rect)
		data.x, data.y, data.pos = x, y, pos
		tv.SetProperty(sparta.Data, data)
		data.putOnScreen()
		tv.Update()
	case sparta.MouseLeft:
		data.sel = trViewNearestNode(ev.Loc, data.node)
		tv.Update()
	case -sparta.MouseWheel:
		data.pos.Y -= 5
		data.putOnScreen()
		tv.Update()
	case sparta.MouseWheel:
		data.pos.Y += 5
		data.putOnScreen()
		tv.Update()
	}
	return true
}
Example #22
0
// PgConf sets the new values of the polygon points.
func pgConf(pg sparta.Widget, e interface{}) bool {
	ev := e.(sparta.ConfigureEvent)
	data := pg.Property(sparta.Data).([]widget.Polygon)
	setPoly(data, ev.Rect.Dx(), ev.Rect.Dy())
	return false
}
Example #23
0
// obConf sets the new values of the objects points.
func obConf(ob sparta.Widget, e interface{}) bool {
	ev := e.(sparta.ConfigureEvent)
	data := ob.Property(sparta.Data).(*objData)
	setObj(data, ev.Rect.Dx(), ev.Rect.Dy())
	return false
}
Example #24
0
// TxConf sets the txt data values.
func txConf(tx sparta.Widget, e interface{}) bool {
	ev := e.(sparta.ConfigureEvent)
	data := tx.Property(sparta.Data).(*pageData)
	data.page = ev.Rect.Dy() / sparta.HeightUnit
	return false
}
Example #25
0
func spNavInfoExpose(tx sparta.Widget, e interface{}) bool {
	d := tx.Property(sparta.Data)
	if d == nil {
		return false
	}
	data := d.(*spInfo)
	c := tx.(*widget.Canvas)
	txt := widget.Text{}
	txt.Pos.X = 2
	txt.Pos.Y = 2
	txt.Text = "Id: " + data.spe.Id
	c.Draw(txt)
	txt.Pos.Y += sparta.HeightUnit
	txt.Text = "Taxon: " + data.tax.Name
	c.Draw(txt)
	txt.Pos.Y += sparta.HeightUnit
	txt.Text = "Basis: " + data.spe.Basis.String()
	c.Draw(txt)
	if len(data.spe.Reference) > 0 {
		txt.Pos.Y += sparta.HeightUnit
		txt.Text = "Ref: " + data.spe.Reference
		c.Draw(txt)
	}
	if data.set != nil {
		txt.Pos.Y += sparta.HeightUnit
		txt.Text = "Dataset: " + data.set.Title
		c.Draw(txt)
	}
	if len(data.spe.Catalog) > 0 {
		txt.Pos.Y += sparta.HeightUnit
		txt.Text = "Catalog: " + data.spe.Catalog
		c.Draw(txt)
	}
	if len(data.spe.Determiner) > 0 {
		txt.Pos.Y += sparta.HeightUnit
		txt.Text = "Determiner: " + data.spe.Determiner
		c.Draw(txt)
	}
	if len(data.spe.Collector) > 0 {
		txt.Pos.Y += sparta.HeightUnit
		txt.Text = "Taxon: " + data.spe.Collector
		c.Draw(txt)
	}
	if !data.spe.Date.IsZero() {
		txt.Pos.Y += sparta.HeightUnit
		txt.Text = "Date:: " + data.spe.Date.Format(jdh.Iso8601)
		c.Draw(txt)
	}
	if len(data.spe.Geography.Country) > 0 {
		txt.Pos.Y += sparta.HeightUnit
		txt.Text = "Country: " + data.spe.Geography.Country.Name()
		c.Draw(txt)
	}
	if len(data.spe.Geography.State) > 0 {
		txt.Pos.Y += sparta.HeightUnit
		txt.Text = "State: " + data.spe.Geography.State
		c.Draw(txt)
	}
	if len(data.spe.Locality) > 0 {
		txt.Pos.Y += sparta.HeightUnit
		txt.Text = "Locality: " + data.spe.Locality
		c.Draw(txt)
	}
	if data.spe.Georef.IsValid() {
		txt.Pos.Y += sparta.HeightUnit
		txt.Text = fmt.Sprintf("LonLat: %.3f,%.3f", data.spe.Georef.Point.Lon, data.spe.Georef.Point.Lat)
		c.Draw(txt)
		if data.spe.Georef.Uncertainty != 0 {
			txt.Pos.Y += sparta.HeightUnit
			txt.Text = fmt.Sprintf("Uncert: %d", data.spe.Georef.Uncertainty)
			c.Draw(txt)
		}
		if len(data.spe.Georef.Source) > 0 {
			txt.Pos.Y += sparta.HeightUnit
			txt.Text = "Source: " + data.spe.Georef.Source
			c.Draw(txt)
		}
		if len(data.spe.Georef.Validation) > 0 {
			txt.Pos.Y += sparta.HeightUnit
			txt.Text = "Val: " + data.spe.Georef.Validation
			c.Draw(txt)
		}
	}
	if len(data.spe.Extern) > 0 {
		txt.Pos.Y += sparta.HeightUnit
		txt.Text = "Extern ids:"
		c.Draw(txt)
		for _, e := range data.spe.Extern {
			txt.Pos.Y += sparta.HeightUnit
			txt.Text = "    " + e
			c.Draw(txt)
		}
	}
	if len(data.spe.Comment) > 0 {
		txt.Pos.Y += sparta.HeightUnit
		txt.Text = "Comments:"
		c.Draw(txt)
		cmt := strings.Split(data.spe.Comment, "\n")
		for _, e := range cmt {
			txt.Pos.Y += sparta.HeightUnit
			txt.Text = "  " + e
			c.Draw(txt)
		}
	}
	if data.set != nil {
		if len(data.set.Citation) > 0 {
			txt.Pos.Y += sparta.HeightUnit
			txt.Text = "Citation: " + data.set.Citation
			c.Draw(txt)
		}
		if len(data.set.License) > 0 {
			txt.Pos.Y += sparta.HeightUnit
			txt.Text = "License: " + data.set.License
			c.Draw(txt)
		}
	}
	return false
}
Example #26
0
func trViewKey(tv sparta.Widget, e interface{}) bool {
	dt := tv.Property(sparta.Data)
	if dt == nil {
		return true
	}
	data := dt.(*trData)
	rect := tv.Property(sparta.Geometry).(image.Rectangle)
	ev := e.(sparta.KeyEvent)
	switch ev.Key {
	case sparta.KeyDown:
		data.pos.Y -= 5
	case sparta.KeyUp:
		data.pos.Y += 5
	case sparta.KeyLeft:
		data.pos.X -= 5
	case sparta.KeyRight:
		data.pos.X += 5
	case sparta.KeyHome:
		data.pos = image.Pt(0, 0)
	case sparta.KeyPageUp:
		data.pos.Y += rect.Dy() - sparta.HeightUnit
	case sparta.KeyPageDown:
		data.pos.Y -= rect.Dy() - sparta.HeightUnit
	case ' ', sparta.KeyReturn:
		p := tv.Property(sparta.Parent).(sparta.Widget)
		d := p.Property(sparta.Data).(*trList)
		if (d.pos + 1) >= len(d.phyLs) {
			return false
		}
		d.pos++
		title := fmt.Sprintf("%s: please wait", cmd.Name)
		p.SetProperty(sparta.Caption, title)
		tv.SetProperty(sparta.Data, nil)
		go trViewInitTree(p, tv)
	case sparta.KeyBackSpace:
		p := tv.Property(sparta.Parent).(sparta.Widget)
		d := p.Property(sparta.Data).(*trList)
		if (d.pos - 1) < 0 {
			return false
		}
		d.pos--
		tv.SetProperty(sparta.Data, nil)
		title := fmt.Sprintf("%s: please wait", cmd.Name)
		p.SetProperty(sparta.Caption, title)
		go trViewInitTree(p, tv)
	case '+':
		data.y = data.y * 5 / 4
	case '-':
		data.y = data.y * 4 / 5
	case '*':
		data.x = data.x * 5 / 4
	case '/':
		data.x = data.x * 4 / 5
	case '#':
		root := data.node[0]
		data.y = float32(rect.Dy()-10) / float32(root.terms+2)
		data.x = float32(rect.Dx()-10-(sparta.WidthUnit*32)) / float32(root.level)
	case '=':
		data.y = float32(sparta.HeightUnit)
		data.x = float32(sparta.WidthUnit * 2)
	case '>':
		if !data.aln {
			return false
		}
		data.aln = false
	case '<':
		if data.aln {
			return false
		}
		data.aln = true
	default:
		return true
	}
	data.putOnScreen()
	tv.Update()
	return false
}