2018-09-06 13:54:35 +00:00
|
|
|
package widgets
|
|
|
|
|
|
|
|
import (
|
|
|
|
"github.com/divan/graphx/layout"
|
|
|
|
"github.com/gopherjs/vecty"
|
|
|
|
"github.com/gopherjs/vecty/elem"
|
|
|
|
)
|
|
|
|
|
2018-09-20 17:43:43 +00:00
|
|
|
// DefaultForcesConfig specifies default configuration for physics simulation.
|
|
|
|
var DefaultForcesConfig = ForcesConfig{
|
|
|
|
Config: layout.DefaultConfig,
|
2018-10-19 14:41:16 +00:00
|
|
|
Steps: 10,
|
2018-09-20 17:43:43 +00:00
|
|
|
}
|
|
|
|
|
2018-09-17 19:11:04 +00:00
|
|
|
// ForceEditor represents forces and physics simulation configuration widget.
|
2018-09-06 13:54:35 +00:00
|
|
|
type ForceEditor struct {
|
|
|
|
vecty.Core
|
|
|
|
|
2018-09-17 19:11:04 +00:00
|
|
|
config ForcesConfig
|
2018-09-06 17:07:24 +00:00
|
|
|
|
|
|
|
repelling *ForceInput
|
|
|
|
spring *ForceInput
|
|
|
|
drag *ForceInput
|
2018-09-17 19:11:04 +00:00
|
|
|
steps *Range
|
2018-09-06 13:54:35 +00:00
|
|
|
}
|
|
|
|
|
2018-09-17 19:11:04 +00:00
|
|
|
// ForcesConfig represents physics simulation configuration.
|
|
|
|
type ForcesConfig struct {
|
|
|
|
layout.Config
|
|
|
|
Steps int
|
|
|
|
}
|
|
|
|
|
|
|
|
// Render implements vecty's Component interface for ForceEditor.
|
2018-09-06 13:54:35 +00:00
|
|
|
func (l *ForceEditor) Render() vecty.ComponentOrHTML {
|
|
|
|
return elem.Div(
|
|
|
|
elem.Heading3(
|
|
|
|
vecty.Text("Layout forces:"),
|
|
|
|
),
|
|
|
|
elem.Form(
|
|
|
|
vecty.Markup(
|
|
|
|
vecty.Class("pure-form"),
|
|
|
|
),
|
2018-09-06 17:07:24 +00:00
|
|
|
l.repelling,
|
|
|
|
l.spring,
|
|
|
|
l.drag,
|
2018-09-17 19:11:04 +00:00
|
|
|
l.steps,
|
2018-09-06 13:54:35 +00:00
|
|
|
),
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
2018-09-19 09:45:54 +00:00
|
|
|
// NewForceEditor creates a new ForceEditor widget.
|
2018-09-06 13:54:35 +00:00
|
|
|
func NewForceEditor() *ForceEditor {
|
2018-09-17 19:11:04 +00:00
|
|
|
config := DefaultForcesConfig
|
2018-09-06 17:07:24 +00:00
|
|
|
repelling := NewForceInput("Gravity force:", config.Repelling)
|
|
|
|
spring := NewForceInput("Spring force:", config.SpringStiffness)
|
|
|
|
drag := NewForceInput("Drag force:", config.DragCoeff)
|
2018-09-17 19:11:04 +00:00
|
|
|
steps := NewRange("Steps:", config.Steps)
|
2018-09-06 13:54:35 +00:00
|
|
|
return &ForceEditor{
|
2018-09-06 17:07:24 +00:00
|
|
|
config: config,
|
|
|
|
repelling: repelling,
|
|
|
|
spring: spring,
|
|
|
|
drag: drag,
|
2018-09-17 19:11:04 +00:00
|
|
|
steps: steps,
|
2018-09-06 13:54:35 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-09-17 19:11:04 +00:00
|
|
|
// Config returns current forces & simulation configuration, getting values from UI.
|
|
|
|
func (l *ForceEditor) Config() ForcesConfig {
|
|
|
|
return ForcesConfig{
|
|
|
|
Steps: l.steps.Value(),
|
|
|
|
Config: layout.Config{
|
|
|
|
Repelling: l.repelling.Value(),
|
|
|
|
SpringStiffness: l.spring.Value(),
|
|
|
|
SpringLen: l.config.SpringLen,
|
|
|
|
DragCoeff: l.drag.Value(),
|
|
|
|
},
|
2018-09-06 17:07:24 +00:00
|
|
|
}
|
2018-09-06 13:54:35 +00:00
|
|
|
}
|