whispervis/widgets/force_editor.go

89 lines
2.0 KiB
Go
Raw Normal View History

2018-09-06 16:54:35 +03:00
package widgets
import (
"github.com/divan/graphx/layout"
"github.com/gopherjs/vecty"
"github.com/gopherjs/vecty/elem"
2018-10-19 22:10:56 +02:00
"github.com/gopherjs/vecty/event"
2018-09-06 16:54:35 +03:00
)
2018-09-20 20:43:43 +03:00
// DefaultForcesConfig specifies default configuration for physics simulation.
var DefaultForcesConfig = ForcesConfig{
Config: layout.DefaultConfig,
Steps: 10,
2018-09-20 20:43:43 +03:00
}
2018-09-17 22:11:04 +03:00
// ForceEditor represents forces and physics simulation configuration widget.
2018-09-06 16:54:35 +03:00
type ForceEditor struct {
vecty.Core
2018-09-17 22:11:04 +03:00
config ForcesConfig
2018-09-06 20:07:24 +03:00
2018-10-20 19:39:28 +02:00
repelling *ForceInput
spring *ForceInput
drag *ForceInput
steps *Range
collapsable *Collapsable
2018-10-19 22:10:56 +02:00
apply func()
2018-09-06 16:54:35 +03:00
}
2018-09-17 22:11:04 +03:00
// ForcesConfig represents physics simulation configuration.
type ForcesConfig struct {
layout.Config
Steps int
}
2018-09-19 12:45:54 +03:00
// NewForceEditor creates a new ForceEditor widget.
2018-10-19 22:10:56 +02:00
func NewForceEditor(apply func()) *ForceEditor {
2018-10-20 19:39:28 +02:00
f := &ForceEditor{}
f.config = DefaultForcesConfig
f.repelling = NewForceInput("Gravity:", f.config.Repelling)
f.spring = NewForceInput("Spring:", f.config.SpringStiffness)
f.drag = NewForceInput("Drag:", f.config.DragCoeff)
f.steps = NewRange("Steps:", f.config.Steps)
2018-10-20 19:42:05 +02:00
f.collapsable = NewCollapsable("Layout forces:", false,
2018-10-20 19:39:28 +02:00
f.applyButton,
f.repelling,
f.spring,
f.drag,
f.steps,
)
f.apply = apply
return f
2018-09-06 16:54:35 +03:00
}
2018-10-19 22:10:56 +02:00
// Render implements vecty's Component interface for ForceEditor.
func (f *ForceEditor) Render() vecty.ComponentOrHTML {
2018-10-20 14:47:19 +02:00
return Widget(
2018-10-20 19:39:28 +02:00
f.collapsable,
2018-10-19 22:10:56 +02:00
)
}
2018-09-17 22:11:04 +03:00
// Config returns current forces & simulation configuration, getting values from UI.
2018-10-19 22:10:56 +02:00
func (f *ForceEditor) Config() ForcesConfig {
2018-09-17 22:11:04 +03:00
return ForcesConfig{
2018-10-19 22:10:56 +02:00
Steps: f.steps.Value(),
2018-09-17 22:11:04 +03:00
Config: layout.Config{
2018-10-19 22:10:56 +02:00
Repelling: f.repelling.Value(),
SpringStiffness: f.spring.Value(),
SpringLen: f.config.SpringLen,
DragCoeff: f.drag.Value(),
2018-09-17 22:11:04 +03:00
},
2018-09-06 20:07:24 +03:00
}
2018-09-06 16:54:35 +03:00
}
2018-10-19 22:10:56 +02:00
2018-10-20 19:39:28 +02:00
func (f *ForceEditor) applyButton() vecty.ComponentOrHTML {
return elem.Button(
vecty.Markup(
vecty.Class("button", "is-info", "is-small"),
event.Click(f.onClick),
2018-10-19 22:10:56 +02:00
),
2018-10-20 19:39:28 +02:00
vecty.Text("Apply"),
2018-10-19 22:10:56 +02:00
)
}
func (f *ForceEditor) onClick(e *vecty.Event) {
go f.apply()
}