diff --git a/Makefile b/Makefile
index 7845d5c3..176f0797 100644
--- a/Makefile
+++ b/Makefile
@@ -66,7 +66,7 @@ build-internal: prepare-internal
cp ../*.deb /build/;
prepare-internal:
- dch --create -v $(VERSION)-6 --package $(PACKAGE_NAME) empty; \
+ dch --create -v $(VERSION)-9 --package $(PACKAGE_NAME) empty; \
cd $(WORKDIR)/..; \
tar -czf octoscreen_$(VERSION).orig.tar.gz --exclude-vcs OctoScreen
diff --git a/styles/z-bolt/images/actions.svg b/styles/z-bolt/images/actions.svg
new file mode 100644
index 00000000..fdbc7555
--- /dev/null
+++ b/styles/z-bolt/images/actions.svg
@@ -0,0 +1,51 @@
+
+
\ No newline at end of file
diff --git a/styles/z-bolt/style.css b/styles/z-bolt/style.css
index 0dc09271..8bc6fe73 100644
--- a/styles/z-bolt/style.css
+++ b/styles/z-bolt/style.css
@@ -20,7 +20,7 @@ scrollbar slider {
}
progress, trough {
- min-height: 40px;
+ min-height: 20px;
font-size: 50px;
}
@@ -31,8 +31,12 @@ progress {
}
.printing-progress-bar{
- font-size: 70px;
- color: #999;
+ font-size: 60px;
+ color: #00C9B4;
+}
+
+.printing-state {
+ opacity: 0.5;
}
button {
@@ -142,25 +146,8 @@ button.keyboard {
}
.printing-status-label {
- margin-top: 10px;
- /* font-size: 24px; */
-}
-
-/* GtkWindow {
- background-color: green;
- border-width: 3px;
- border-color: blue;
-} */
-
-/* GtkButton {
- background-image: none;
- background-color:#1010FF;
- margin:2px;
- border-radius:0;
-} */
+ padding-top: 5px;
+ padding-bottom: 3px;
-/* button, entry {
- color: #ff00ea;
- font: 12px "Comic Sans";
- background-color: #1010FF;
- } */
\ No newline at end of file
+ font-size: 24px;
+}
diff --git a/ui/common.go b/ui/common.go
index a1d584cf..30b8c089 100644
--- a/ui/common.go
+++ b/ui/common.go
@@ -10,6 +10,7 @@ import (
"github.com/gotk3/gotk3/glib"
"github.com/gotk3/gotk3/gtk"
+ "github.com/mcuadros/go-octoprint"
)
// Set at compilation time.
@@ -89,6 +90,21 @@ func (p *CommonPanel) Scaled(s int) int {
return s * p.UI.scaleFactor
}
+func (m *CommonPanel) arrangeButtons(buttons []gtk.IWidget) {
+
+ row := 4
+
+ for i, k := range buttons {
+ m.Grid().Attach(k, (i%row)+1, i/row, 1, 1)
+ }
+}
+
+func (m *CommonPanel) command(gcode string) error {
+ cmd := &octoprint.CommandRequest{}
+ cmd.Commands = []string{gcode}
+ return cmd.Do(m.UI.Printer)
+}
+
type BackgroundTask struct {
close chan bool
diff --git a/ui/extrude.go b/ui/extrude.go
new file mode 100644
index 00000000..def9a481
--- /dev/null
+++ b/ui/extrude.go
@@ -0,0 +1,196 @@
+package ui
+
+import (
+ "fmt"
+ "strings"
+ "time"
+
+ "github.com/gotk3/gotk3/gtk"
+ "github.com/mcuadros/go-octoprint"
+)
+
+var extrudePanelInstance *extrudePanel
+
+type extrudePanel struct {
+ CommonPanel
+
+ amount *StepButton
+ tool *StepButton
+
+ box *gtk.Box
+ labels map[string]*LabelWithImage
+ previous *octoprint.TemperatureState
+}
+
+func ExtrudePanel(ui *UI, parent Panel) Panel {
+ if extrudePanelInstance == nil {
+ m := &extrudePanel{CommonPanel: NewCommonPanel(ui, parent),
+ labels: map[string]*LabelWithImage{},
+ }
+ m.panelH = 2
+ m.b = NewBackgroundTask(time.Second*5, m.updateTemperatures)
+ m.initialize()
+ extrudePanelInstance = m
+ }
+
+ return extrudePanelInstance
+}
+
+func (m *extrudePanel) initialize() {
+ defer m.Initialize()
+
+ m.Grid().Attach(m.createExtrudeButton("Extrude", "extrude.svg", 1), 1, 0, 1, 1)
+ m.Grid().Attach(m.createExtrudeButton("Retract", "retract.svg", -1), 4, 0, 1, 1)
+
+ m.box = MustBox(gtk.ORIENTATION_VERTICAL, 5)
+ m.box.SetVAlign(gtk.ALIGN_CENTER)
+ m.box.SetHAlign(gtk.ALIGN_CENTER)
+ m.Grid().Attach(m.box, 2, 0, 2, 1)
+
+ m.amount = MustStepButton("move-step.svg", Step{"1mm", 1}, Step{"5mm", 5}, Step{"10mm", 10})
+ m.Grid().Attach(m.amount, 2, 1, 1, 1)
+
+ m.Grid().Attach(m.createToolButton(), 1, 1, 1, 1)
+ m.Grid().Attach(m.createFlowrateButton(), 3, 1, 1, 1)
+}
+
+func (m *extrudePanel) updateTemperatures() {
+ s, err := (&octoprint.ToolStateRequest{
+ History: true,
+ Limit: 1,
+ }).Do(m.UI.Printer)
+
+ if err != nil {
+ Logger.Error(err)
+ return
+ }
+
+ m.loadTemperatureState(s)
+}
+
+func (m *extrudePanel) loadTemperatureState(s *octoprint.TemperatureState) {
+ for tool, current := range s.Current {
+ if _, ok := m.labels[tool]; !ok {
+ m.addNewTool(tool)
+ }
+
+ m.loadTemperatureData(tool, ¤t)
+ }
+
+ m.previous = s
+}
+
+func (m *extrudePanel) addNewTool(tool string) {
+ m.labels[tool] = MustLabelWithImage("extruder.svg", "")
+ m.box.Add(m.labels[tool])
+ m.tool.AddStep(Step{strings.Title(tool), tool})
+
+ Logger.Infof("New tool detected %s", tool)
+}
+
+func (m *extrudePanel) loadTemperatureData(tool string, d *octoprint.TemperatureData) {
+ text := fmt.Sprintf("%s: %.1f°C / %.1f°C", strings.Title(tool), d.Actual, d.Target)
+
+ if m.previous != nil && d.Target > 0 {
+ if p, ok := m.previous.Current[tool]; ok {
+ text = fmt.Sprintf("%s (%.1f°C)", text, d.Actual-p.Actual)
+ }
+ }
+
+ m.labels[tool].Label.SetText(text)
+ m.labels[tool].ShowAll()
+}
+
+func (m *extrudePanel) createToolButton() *StepButton {
+ m.tool = MustStepButton("extruder.svg")
+ m.tool.Callback = func() {
+ cmd := &octoprint.ToolSelectRequest{}
+ cmd.Tool = m.tool.Value().(string)
+
+ Logger.Infof("Changing tool to %s", cmd.Tool)
+ if err := cmd.Do(m.UI.Printer); err != nil {
+ Logger.Error(err)
+ return
+ }
+ }
+
+ return m.tool
+}
+
+func (m *extrudePanel) createFlowrateButton() *StepButton {
+ b := MustStepButton("speed-step.svg", Step{"Slow", 75}, Step{"Normal", 100}, Step{"High", 125})
+ b.Callback = func() {
+ cmd := &octoprint.ToolFlowrateRequest{}
+ cmd.Factor = b.Value().(int)
+
+ Logger.Infof("Changing flowrate to %d%%", cmd.Factor)
+ if err := cmd.Do(m.UI.Printer); err != nil {
+ Logger.Error(err)
+ return
+ }
+ }
+
+ return b
+}
+
+func (m *extrudePanel) createLoadButton() gtk.IWidget {
+ length := 750.0
+
+ if m.UI.Settings != nil {
+ length = m.UI.Settings.FilamentInLength
+ }
+
+ return MustButtonImage("Load", "extrude.svg", func() {
+ cmd := &octoprint.CommandRequest{}
+ cmd.Commands = []string{
+ "G91",
+ fmt.Sprintf("G0 E%.1f F5000", length*0.80),
+ fmt.Sprintf("G0 E%.1f F500", length*0.20),
+ "G90",
+ }
+
+ Logger.Info("Sending filament load request")
+ if err := cmd.Do(m.UI.Printer); err != nil {
+ Logger.Error(err)
+ return
+ }
+ })
+}
+
+func (m *extrudePanel) createUnloadButton() gtk.IWidget {
+
+ length := 800.0
+
+ if m.UI.Settings != nil {
+ length = m.UI.Settings.FilamentOutLength
+ }
+
+ return MustButtonImage("Unload", "retract.svg", func() {
+ cmd := &octoprint.CommandRequest{}
+ cmd.Commands = []string{
+ "G91",
+ fmt.Sprintf("G0 E-%.1f F5000", length),
+ "G90",
+ }
+
+ Logger.Info("Sending filament unload request")
+ if err := cmd.Do(m.UI.Printer); err != nil {
+ Logger.Error(err)
+ return
+ }
+ })
+}
+
+func (m *extrudePanel) createExtrudeButton(label, image string, dir int) gtk.IWidget {
+
+ return MustPressedButton(label, image, func() {
+ cmd := &octoprint.ToolExtrudeRequest{}
+ cmd.Amount = m.amount.Value().(int) * dir
+
+ Logger.Infof("Sending extrude request, with amount %d", cmd.Amount)
+ if err := cmd.Do(m.UI.Printer); err != nil {
+ Logger.Error(err)
+ return
+ }
+ }, 200)
+}
diff --git a/ui/filament.go b/ui/filament.go
index 8c266dbc..32dd89c1 100644
--- a/ui/filament.go
+++ b/ui/filament.go
@@ -14,9 +14,6 @@ var filamentPanelInstance *filamentPanel
type filamentPanel struct {
CommonPanel
- amount *StepButton
- tool *StepButton
-
box *gtk.Box
labels map[string]*LabelWithImage
previous *octoprint.TemperatureState
@@ -39,23 +36,22 @@ func FilamentPanel(ui *UI, parent Panel) Panel {
func (m *filamentPanel) initialize() {
defer m.Initialize()
+ m.Grid().Attach(m.createChangeToolButton(0), 1, 0, 1, 1)
+ m.Grid().Attach(m.createChangeToolButton(1), 2, 0, 1, 1)
+ m.Grid().Attach(m.createChangeToolButton(2), 3, 0, 1, 1)
+ m.Grid().Attach(m.createChangeToolButton(3), 4, 0, 1, 1)
+
m.Grid().Attach(m.createLoadButton(), 1, 1, 1, 1)
m.Grid().Attach(m.createUnloadButton(), 4, 1, 1, 1)
- m.Grid().Attach(m.createExtrudeButton("Extrude", "extrude.svg", 1), 1, 0, 1, 1)
- m.Grid().Attach(m.createExtrudeButton("Retract", "retract.svg", -1), 4, 0, 1, 1)
+ m.Grid().Attach(MustButtonImageStyle("Temperature", "heat-up.svg", "color4", m.showTemperature), 1, 2, 1, 1)
m.box = MustBox(gtk.ORIENTATION_VERTICAL, 5)
m.box.SetVAlign(gtk.ALIGN_CENTER)
m.box.SetHAlign(gtk.ALIGN_CENTER)
- m.Grid().Attach(m.box, 2, 0, 2, 2)
+ m.Grid().Attach(m.box, 2, 1, 2, 2)
- m.amount = MustStepButton("move-step.svg", Step{"1mm", 1}, Step{"5mm", 5}, Step{"10mm", 10})
- m.Grid().Attach(m.amount, 2, 2, 1, 1)
-
- m.Grid().Attach(m.createToolButton(), 1, 2, 1, 1)
- m.Grid().Attach(m.createFlowrateButton(), 3, 2, 1, 1)
}
func (m *filamentPanel) updateTemperatures() {
@@ -87,7 +83,6 @@ func (m *filamentPanel) loadTemperatureState(s *octoprint.TemperatureState) {
func (m *filamentPanel) addNewTool(tool string) {
m.labels[tool] = MustLabelWithImage("extruder.svg", "")
m.box.Add(m.labels[tool])
- m.tool.AddStep(Step{strings.Title(tool), tool})
Logger.Infof("New tool detected %s", tool)
}
@@ -105,38 +100,6 @@ func (m *filamentPanel) loadTemperatureData(tool string, d *octoprint.Temperatur
m.labels[tool].ShowAll()
}
-func (m *filamentPanel) createToolButton() *StepButton {
- m.tool = MustStepButton("extruder.svg")
- m.tool.Callback = func() {
- cmd := &octoprint.ToolSelectRequest{}
- cmd.Tool = m.tool.Value().(string)
-
- Logger.Infof("Changing tool to %s", cmd.Tool)
- if err := cmd.Do(m.UI.Printer); err != nil {
- Logger.Error(err)
- return
- }
- }
-
- return m.tool
-}
-
-func (m *filamentPanel) createFlowrateButton() *StepButton {
- b := MustStepButton("speed-step.svg", Step{"Slow", 75}, Step{"Normal", 100}, Step{"High", 125})
- b.Callback = func() {
- cmd := &octoprint.ToolFlowrateRequest{}
- cmd.Factor = b.Value().(int)
-
- Logger.Infof("Changing flowrate to %d%%", cmd.Factor)
- if err := cmd.Do(m.UI.Printer); err != nil {
- Logger.Error(err)
- return
- }
- }
-
- return b
-}
-
func (m *filamentPanel) createLoadButton() gtk.IWidget {
length := 750.0
@@ -144,7 +107,7 @@ func (m *filamentPanel) createLoadButton() gtk.IWidget {
length = m.UI.Settings.FilamentInLength
}
- return MustButtonImage("Load", "extrude.svg", func() {
+ return MustButtonImageStyle("Load", "extrude.svg", "color3", func() {
cmd := &octoprint.CommandRequest{}
cmd.Commands = []string{
"G91",
@@ -162,14 +125,13 @@ func (m *filamentPanel) createLoadButton() gtk.IWidget {
}
func (m *filamentPanel) createUnloadButton() gtk.IWidget {
-
length := 800.0
if m.UI.Settings != nil {
length = m.UI.Settings.FilamentOutLength
}
- return MustButtonImage("Unload", "retract.svg", func() {
+ return MustButtonImageStyle("Unload", "extrude.svg", "color2", func() {
cmd := &octoprint.CommandRequest{}
cmd.Commands = []string{
"G91",
@@ -185,16 +147,15 @@ func (m *filamentPanel) createUnloadButton() gtk.IWidget {
})
}
-func (m *filamentPanel) createExtrudeButton(label, image string, dir int) gtk.IWidget {
-
- return MustPressedButton(label, image, func() {
- cmd := &octoprint.ToolExtrudeRequest{}
- cmd.Amount = m.amount.Value().(int) * dir
+func (m *filamentPanel) createChangeToolButton(num int) gtk.IWidget {
+ style := fmt.Sprintf("color%d", num+1)
+ name := fmt.Sprintf("Tool%d", num+1)
+ gcode := fmt.Sprintf("T%d", num)
+ return MustButtonImageStyle(name, "extruder.svg", style, func() {
+ m.command(gcode)
+ })
+}
- Logger.Infof("Sending extrude request, with amount %d", cmd.Amount)
- if err := cmd.Do(m.UI.Printer); err != nil {
- Logger.Error(err)
- return
- }
- }, 200)
+func (m *filamentPanel) showTemperature() {
+ m.UI.Add(TemperaturePanel(m.UI, m))
}
diff --git a/ui/idle_action_menu.go b/ui/idle_action_menu.go
new file mode 100644
index 00000000..728dc004
--- /dev/null
+++ b/ui/idle_action_menu.go
@@ -0,0 +1,61 @@
+package ui
+
+import "github.com/gotk3/gotk3/gtk"
+
+var idleActionMenuPanelInstance *idleActionMenuPanel
+
+type idleActionMenuPanel struct {
+ CommonPanel
+}
+
+func IdleActionMenuPanel(ui *UI, parent Panel) Panel {
+ if idleActionMenuPanelInstance == nil {
+ m := &idleActionMenuPanel{CommonPanel: NewCommonPanel(ui, parent)}
+ m.initialize()
+ idleActionMenuPanelInstance = m
+ }
+
+ return idleActionMenuPanelInstance
+}
+
+func (m *idleActionMenuPanel) initialize() {
+ defer m.Initialize()
+
+ var buttons = []gtk.IWidget{
+ MustButtonImageStyle("Move", "move.svg", "color1", m.showMove),
+ MustButtonImageStyle("Extrude", "filament.svg", "color1", m.showExtrude),
+ MustButtonImageStyle("Fan", "fan.svg", "color2", m.showFan),
+ MustButtonImageStyle("Temperature", "heat-up.svg", "color4", m.showTemperature),
+ MustButtonImageStyle("Control", "control.svg", "color4", m.showControl),
+ }
+
+ if m.UI.Settings != nil && m.UI.Settings.ToolChanger {
+ buttons = append(buttons, MustButtonImageStyle("ToolChanger", "toolchanger.svg", "color2", m.showToolchanger))
+ }
+
+ m.arrangeButtons(buttons)
+}
+
+func (m *idleActionMenuPanel) showTemperature() {
+ m.UI.Add(TemperaturePanel(m.UI, m))
+}
+
+func (m *idleActionMenuPanel) showExtrude() {
+ m.UI.Add(ExtrudePanel(m.UI, m))
+}
+
+func (m *idleActionMenuPanel) showControl() {
+ m.UI.Add(ControlPanel(m.UI, m))
+}
+
+func (m *idleActionMenuPanel) showToolchanger() {
+ m.UI.Add(ToolchangerPanel(m.UI, m))
+}
+
+func (m *idleActionMenuPanel) showMove() {
+ m.UI.Add(MovePanel(m.UI, m))
+}
+
+func (m *idleActionMenuPanel) showFan() {
+ m.UI.Add(FanPanel(m.UI, m))
+}
diff --git a/ui/idle_configuration_menu.go b/ui/idle_configuration_menu.go
new file mode 100644
index 00000000..7933712e
--- /dev/null
+++ b/ui/idle_configuration_menu.go
@@ -0,0 +1,48 @@
+package ui
+
+import "github.com/gotk3/gotk3/gtk"
+
+var idleConfigurationMenuPanelInstance *idleConfigurationMenuPanel
+
+type idleConfigurationMenuPanel struct {
+ CommonPanel
+}
+
+func IdleConfigurationMenuPanel(ui *UI, parent Panel) Panel {
+ if idleConfigurationMenuPanelInstance == nil {
+ m := &idleConfigurationMenuPanel{CommonPanel: NewCommonPanel(ui, parent)}
+ m.initialize()
+ idleConfigurationMenuPanelInstance = m
+ }
+
+ return idleConfigurationMenuPanelInstance
+}
+
+func (m *idleConfigurationMenuPanel) initialize() {
+ defer m.Initialize()
+
+ var buttons = []gtk.IWidget{
+ MustButtonImageStyle("Bed Level", "bed-level.svg", "color4", m.showCalibrate),
+ MustButtonImageStyle("ZOffsets", "z-offset-increase.svg", "color2", m.showNozzleCalibration),
+ MustButtonImageStyle("Network", "network.svg", "color1", m.showNetwork),
+ MustButtonImageStyle("System", "info.svg", "color3", m.showSystem),
+ }
+
+ m.arrangeButtons(buttons)
+}
+
+func (m *idleConfigurationMenuPanel) showNetwork() {
+ m.UI.Add(NetworkPanel(m.UI, m))
+}
+
+func (m *idleConfigurationMenuPanel) showSystem() {
+ m.UI.Add(SystemPanel(m.UI, m))
+}
+
+func (m *idleConfigurationMenuPanel) showCalibrate() {
+ m.UI.Add(BedLevelPanel(m.UI, m))
+}
+
+func (m *idleConfigurationMenuPanel) showNozzleCalibration() {
+ m.UI.Add(NozzleCalibrationPanel(m.UI, m))
+}
diff --git a/ui/idle_menu.go b/ui/idle_menu.go
index 72b14d97..47f17522 100644
--- a/ui/idle_menu.go
+++ b/ui/idle_menu.go
@@ -20,12 +20,17 @@ func (m *idleMenuPanel) initialize() {
defer m.Initialize()
m.Grid().Attach(MustButtonImageStyle("Move", "move.svg", "color1", m.showMove), 1, 0, 1, 1)
- m.Grid().Attach(MustButtonImageStyle("ToolChanger", "toolchanger.svg", "color2", m.showToolchanger), 2, 0, 1, 1)
+
+ m.Grid().Attach(MustButtonImageStyle("Fan", "fan.svg", "color2", m.showFan), 2, 0, 1, 1)
+
m.Grid().Attach(MustButtonImageStyle("Control", "control.svg", "color4", m.showControl), 3, 0, 1, 1)
m.Grid().Attach(MustButtonImageStyle("System", "info.svg", "color3", m.showSystem), 4, 0, 1, 1)
m.Grid().Attach(MustButtonImageStyle("Temperature", "heat-up.svg", "color4", m.showTemperature), 1, 1, 1, 1)
m.Grid().Attach(MustButtonImageStyle("Network", "network.svg", "color1", m.showNetwork), 2, 1, 1, 1)
- m.Grid().Attach(MustButtonImageStyle("Fan", "fan.svg", "color2", m.showFan), 3, 1, 1, 1)
+
+ if m.UI.Settings != nil && m.UI.Settings.ToolChanger {
+ m.Grid().Attach(MustButtonImageStyle("ToolChanger", "toolchanger.svg", "color2", m.showToolchanger), 3, 1, 1, 1)
+ }
}
func (m *idleMenuPanel) showTemperature() {
diff --git a/ui/idle_status.go b/ui/idle_status.go
index 0842c66b..157a3a69 100644
--- a/ui/idle_status.go
+++ b/ui/idle_status.go
@@ -37,20 +37,20 @@ func (m *idleStatusPanel) initialize() {
defer m.Initialize()
m.Grid().Attach(MustButtonImageStyle("Home", "home.svg", "color2", m.showHome), 3, 0, 1, 1)
- m.Grid().Attach(MustButtonImageStyle("Bed Level", "bed-level.svg", "color4", m.showCalibrate), 4, 0, 1, 1)
+ m.Grid().Attach(MustButtonImageStyle("Actions", "actions.svg", "color4", m.showActionsMenu), 4, 0, 1, 1)
m.Grid().Attach(MustButtonImageStyle("Filament", "filament.svg", "color3", m.showFilament), 3, 1, 1, 1)
- m.Grid().Attach(MustButtonImageStyle("Menu", "control.svg", "color1", m.showMenu), 4, 1, 1, 1)
+ m.Grid().Attach(MustButtonImageStyle("Configuration", "control.svg", "color1", m.showConfigurationMenu), 4, 1, 1, 1)
m.Grid().Attach(MustButtonImageStyle("Print", "print.svg", "color2", m.showFiles), 3, 2, 2, 1)
m.showTools()
}
-func (m *idleStatusPanel) showCalibrate() {
- m.UI.Add(BedLevelPanel(m.UI, m))
+func (m *idleStatusPanel) showActionsMenu() {
+ m.UI.Add(IdleActionMenuPanel(m.UI, m))
}
-func (m *idleStatusPanel) showMenu() {
- m.UI.Add(IdleMenuPanel(m.UI, m))
+func (m *idleStatusPanel) showConfigurationMenu() {
+ m.UI.Add(IdleConfigurationMenuPanel(m.UI, m))
}
func (m *idleStatusPanel) showHome() {
diff --git a/ui/nozzle_calibration.go b/ui/nozzle_calibration.go
new file mode 100644
index 00000000..d0cbc968
--- /dev/null
+++ b/ui/nozzle_calibration.go
@@ -0,0 +1,188 @@
+package ui
+
+import (
+ "fmt"
+ "math"
+ "time"
+
+ "github.com/gotk3/gotk3/gtk"
+ "github.com/mcuadros/go-octoprint"
+)
+
+var nozzleCalibrationPanelInstance *nozzleCalibrationPanel
+
+type pointCoordinates struct {
+ x float64
+ y float64
+ z float64
+}
+
+type nozzleCalibrationPanel struct {
+ CommonPanel
+ zCalibrationMode bool
+ activeTool int
+ cPoint pointCoordinates
+ zOffset float64
+ labZOffsetLabel *gtk.Label
+}
+
+func NozzleCalibrationPanel(ui *UI, parent Panel) Panel {
+ if nozzleCalibrationPanelInstance == nil {
+ m := &nozzleCalibrationPanel{CommonPanel: NewCommonPanel(ui, parent)}
+ m.panelH = 3
+ m.cPoint = pointCoordinates{x: 20, y: 20, z: 0}
+ m.initialize()
+
+ nozzleCalibrationPanelInstance = m
+ }
+
+ return nozzleCalibrationPanelInstance
+}
+
+func (m *nozzleCalibrationPanel) initialize() {
+ defer m.Initialize()
+ m.Grid().Attach(m.createChangeToolButton(0), 1, 0, 1, 1)
+ m.Grid().Attach(m.createChangeToolButton(1), 2, 0, 1, 1)
+ m.Grid().Attach(m.createChangeToolButton(2), 3, 0, 1, 1)
+ m.Grid().Attach(m.createChangeToolButton(3), 4, 0, 1, 1)
+
+ m.Grid().Attach(m.createIncreaseOffsetButton(), 1, 1, 1, 1)
+ m.Grid().Attach(m.createZOffsetLabel(), 2, 1, 2, 1)
+ m.Grid().Attach(m.createDecreaseOffsetButton(), 4, 1, 1, 1)
+
+ m.Grid().Attach(m.createZCalibrationModeButton(), 1, 2, 1, 1)
+ m.Grid().Attach(m.createAutoZCalibrationButton(), 2, 2, 2, 1)
+
+}
+
+func (m *nozzleCalibrationPanel) createZCalibrationModeButton() gtk.IWidget {
+ b := MustStepButton("z-calibration.svg", Step{"Start Manual\nCalibration", false}, Step{"Stop Manual\nCalibration", true})
+ ctx, _ := b.GetStyleContext()
+ ctx.AddClass("color2")
+
+ b.Callback = func() {
+ m.zCalibrationMode = b.Value().(bool)
+ if m.zCalibrationMode == true {
+ ctx.AddClass("active")
+
+ m.command("G28")
+ m.command("T0")
+ time.Sleep(time.Second * 1)
+ m.command(fmt.Sprintf("G0 X%f Y%f F10000", m.cPoint.x, m.cPoint.y))
+ m.command(fmt.Sprintf("G0 Z10 F2000"))
+ m.command(fmt.Sprintf("G0 Z%f F400", m.cPoint.z))
+
+ m.activeTool = 0
+ m.updateZOffset(0)
+ } else {
+ ctx.RemoveClass("active")
+ m.labZOffsetLabel.SetText("Press \"Z Offset\"\nbutton to start\nZ-Offset calibration")
+ }
+ }
+
+ return b
+}
+
+func (m *nozzleCalibrationPanel) createAutoZCalibrationButton() gtk.IWidget {
+ return MustButtonImageStyle("Auto Z Calibration", "z-calibration.svg", "color3", func() {
+ if m.zCalibrationMode {
+ return
+ }
+
+ cmd := &octoprint.RunZOffsetCalibrationRequest{}
+ if err := cmd.Do(m.UI.Printer); err != nil {
+ Logger.Error(err)
+ }
+ })
+}
+
+func (m *nozzleCalibrationPanel) createIncreaseOffsetButton() gtk.IWidget {
+ return MustButtonImage("Bed Down", "z-offset-increase.svg", func() {
+ if !m.zCalibrationMode {
+ return
+ }
+ m.updateZOffset(m.zOffset + 0.02)
+ })
+}
+
+func (m *nozzleCalibrationPanel) createDecreaseOffsetButton() gtk.IWidget {
+ return MustButtonImage("Bed Up", "z-offset-decrease.svg", func() {
+ if !m.zCalibrationMode {
+ return
+ }
+ m.updateZOffset(m.zOffset - 0.02)
+ })
+}
+
+func (m *nozzleCalibrationPanel) updateZOffset(v float64) {
+ m.zOffset = toFixed(v, 4)
+
+ m.labZOffsetLabel.SetText(fmt.Sprintf("Z-Offset: %.2f", m.zOffset))
+
+ cmd := &octoprint.CommandRequest{}
+ cmd.Commands = []string{
+ fmt.Sprintf("SET_GCODE_OFFSET Z=%f", m.zOffset),
+ "G0 Z0 F100",
+ }
+ if err := cmd.Do(m.UI.Printer); err != nil {
+ Logger.Error(err)
+ }
+
+ cmd2 := &octoprint.SetZOffsetRequest{Value: m.zOffset, Tool: m.activeTool}
+ if err := cmd2.Do(m.UI.Printer); err != nil {
+ Logger.Error(err)
+ }
+}
+
+func (m *nozzleCalibrationPanel) createChangeToolButton(num int) gtk.IWidget {
+ style := fmt.Sprintf("color%d", num+1)
+ name := fmt.Sprintf("Tool%d", num+1)
+ gcode := fmt.Sprintf("T%d", num)
+ return MustButtonImageStyle(name, "extruder.svg", style, func() {
+ if m.zCalibrationMode {
+ m.activeTool = num
+ m.command(fmt.Sprintf("G0 Z%f", 5.0))
+ m.command(gcode)
+ time.Sleep(time.Second * 1)
+ m.command(fmt.Sprintf("G0 X%f Y%f F10000", m.cPoint.x, m.cPoint.y))
+
+ cmd := &octoprint.GetZOffsetRequest{Tool: m.activeTool}
+ response, err := cmd.Do(m.UI.Printer)
+
+ if err != nil {
+ Logger.Error(err)
+ return
+ }
+
+ m.updateZOffset(response.Offset)
+
+ } else {
+ m.command(gcode)
+ }
+ })
+}
+
+func (m *nozzleCalibrationPanel) createZOffsetLabel() gtk.IWidget {
+ m.labZOffsetLabel = MustLabel("---")
+ m.labZOffsetLabel.SetVAlign(gtk.ALIGN_CENTER)
+ m.labZOffsetLabel.SetHAlign(gtk.ALIGN_CENTER)
+ m.labZOffsetLabel.SetVExpand(true)
+ m.labZOffsetLabel.SetHExpand(true)
+ m.labZOffsetLabel.SetLineWrap(true)
+ return m.labZOffsetLabel
+}
+
+func (m *nozzleCalibrationPanel) command(gcode string) error {
+ cmd := &octoprint.CommandRequest{}
+ cmd.Commands = []string{gcode}
+ return cmd.Do(m.UI.Printer)
+}
+
+func round(num float64) int {
+ return int(num + math.Copysign(0.5, num))
+}
+
+func toFixed(num float64, precision int) float64 {
+ output := math.Pow(10, float64(precision))
+ return float64(round(num*output)) / output
+}
diff --git a/ui/print_status.go b/ui/print_status.go
index d9fcd808..81e39233 100644
--- a/ui/print_status.go
+++ b/ui/print_status.go
@@ -2,6 +2,7 @@ package ui
import (
"fmt"
+ "strings"
"time"
"github.com/gotk3/gotk3/gtk"
@@ -16,7 +17,7 @@ type printStatusPanel struct {
pb *gtk.ProgressBar
bed, tool0, tool1, tool2, tool3 *gtk.Button
- file, time, time_left *LabelWithImage
+ file, time, timeLeft *LabelWithImage
complete, pause, stop, menu *gtk.Button
}
@@ -54,7 +55,7 @@ func (m *printStatusPanel) showTools() {
m.tool2 = m.createToolButton(2)
m.tool3 = m.createToolButton(3)
- m.bed = MustButtonImage("", "bed.svg", func() {})
+ m.bed = m.createBedButton()
switch toolsCount {
case 1:
@@ -104,9 +105,15 @@ func (m *printStatusPanel) createProgressBar() *gtk.ProgressBar {
func (m *printStatusPanel) createInfoBox() *gtk.Box {
m.file = MustLabelWithImage("file.svg", "")
+ ctx, _ := m.file.GetStyleContext()
+ ctx.AddClass("printing-status-label")
+
m.time = MustLabelWithImage("speed-step.svg", "")
+ ctx, _ = m.time.GetStyleContext()
+ ctx.AddClass("printing-status-label")
- ctx, _ := m.time.GetStyleContext()
+ m.timeLeft = MustLabelWithImage("speed-step.svg", "")
+ ctx, _ = m.timeLeft.GetStyleContext()
ctx.AddClass("printing-status-label")
info := MustBox(gtk.ORIENTATION_VERTICAL, 5)
@@ -116,6 +123,7 @@ func (m *printStatusPanel) createInfoBox() *gtk.Box {
info.SetVAlign(gtk.ALIGN_CENTER)
info.Add(m.file)
info.Add(m.time)
+ info.Add(m.timeLeft)
return info
}
@@ -123,6 +131,17 @@ func (m *printStatusPanel) createInfoBox() *gtk.Box {
func (m *printStatusPanel) createToolButton(num int) *gtk.Button {
name := fmt.Sprintf("extruder-%d.svg", num+1)
b := MustButtonImage("", name, func() {})
+
+ ctx, _ := b.GetStyleContext()
+ ctx.AddClass("printing-state")
+ return b
+}
+
+func (m *printStatusPanel) createBedButton() *gtk.Button {
+ b := MustButtonImage("", "bed.svg", func() {})
+
+ ctx, _ := b.GetStyleContext()
+ ctx.AddClass("printing-state")
return b
}
@@ -238,26 +257,32 @@ func (m *printStatusPanel) updateJob() {
file := "not-set"
if s.Job.File.Name != "" {
- file = strEllipsis(s.Job.File.Name)
+ file = s.Job.File.Name
+ file = strings.Replace(file, ".gcode", "", -1)
+ file = strEllipsisLen(file, 35)
}
m.file.Label.SetLabel(file)
m.pb.SetFraction(s.Progress.Completion / 100)
- var text string
+ var timeSpent, timeLeft string
switch s.Progress.Completion {
case 100:
- text = fmt.Sprintf("Completed in %s", time.Duration(int64(s.Job.LastPrintTime)*1e9))
+ timeSpent = fmt.Sprintf("Completed in %s", time.Duration(int64(s.Job.LastPrintTime)*1e9))
+ timeLeft = ""
case 0:
- text = "Warming up ..."
+ timeSpent = "Warming up ..."
+ timeLeft = ""
default:
Logger.Info(s.Progress.PrintTime)
e := time.Duration(int64(s.Progress.PrintTime) * 1e9)
r := time.Duration(int64(s.Progress.PrintTimeLeft) * 1e9)
- text = fmt.Sprintf("Time: %s\nTime Left: %s", e, r)
+ timeSpent = fmt.Sprintf("Time: %s", e)
+ timeLeft = fmt.Sprintf("Left: %s", r)
}
- m.time.Label.SetLabel(text)
+ m.time.Label.SetLabel(timeSpent)
+ m.timeLeft.Label.SetLabel(timeLeft)
}
func (m *printStatusPanel) defineToolsCount() int {
diff --git a/ui/temperature.go b/ui/temperature.go
index 81c8c2ee..2b9a89a5 100644
--- a/ui/temperature.go
+++ b/ui/temperature.go
@@ -48,13 +48,13 @@ func (m *temperaturePanel) initialize() {
m.box.SetVAlign(gtk.ALIGN_CENTER)
m.box.SetHAlign(gtk.ALIGN_CENTER)
- m.Grid().Attach(m.box, 2, 0, 2, 1)
+ m.Grid().Attach(m.box, 2, 1, 2, 1)
m.Grid().Attach(m.createToolButton(), 1, 1, 1, 1)
m.amount = MustStepButton("move-step.svg", Step{"10°C", 10.}, Step{"5°C", 5.}, Step{"1°C", 1.})
- m.Grid().Attach(m.amount, 2, 1, 1, 1)
+ m.Grid().Attach(m.amount, 2, 0, 1, 1)
- m.Grid().Attach(MustButtonImage("More", "heat-up.svg", m.profilePanel), 3, 1, 1, 1)
+ m.Grid().Attach(MustButtonImage("More", "heat-up.svg", m.profilePanel), 3, 0, 1, 1)
}
func (m *temperaturePanel) createToolButton() *StepButton {
diff --git a/ui/toolchanger.go b/ui/toolchanger.go
index 8cba07da..1ecfd1d1 100644
--- a/ui/toolchanger.go
+++ b/ui/toolchanger.go
@@ -2,7 +2,6 @@ package ui
import (
"fmt"
- "time"
"github.com/gotk3/gotk3/gtk"
"github.com/mcuadros/go-octoprint"
@@ -10,26 +9,15 @@ import (
var toolchangerPanelInstance *toolchangerPanel
-type pointCoordinates struct {
- x float64
- y float64
- z float64
-}
-
type toolchangerPanel struct {
CommonPanel
- zCalibrationMode bool
- activeTool int
- cPoint pointCoordinates
- zOffset float64
- labZOffsetLabel *gtk.Label
+ activeTool int
}
func ToolchangerPanel(ui *UI, parent Panel) Panel {
if toolchangerPanelInstance == nil {
m := &toolchangerPanel{CommonPanel: NewCommonPanel(ui, parent)}
m.panelH = 3
- m.cPoint = pointCoordinates{x: 20, y: 20, z: 0}
m.initialize()
toolchangerPanelInstance = m
@@ -46,39 +34,16 @@ func (m *toolchangerPanel) initialize() {
m.Grid().Attach(m.createChangeToolButton(3), 4, 0, 1, 1)
m.Grid().Attach(m.createHomeButton(), 1, 1, 1, 1)
- m.Grid().Attach(m.createIncreaseOffsetButton(), 2, 1, 1, 1)
- m.Grid().Attach(m.createZOffsetLabel(), 3, 1, 1, 1)
- m.Grid().Attach(m.createDecreaseOffsetButton(), 4, 1, 1, 1)
- m.Grid().Attach(m.createMagnetOnButton(), 1, 2, 1, 1)
- m.Grid().Attach(m.createMagnetOffButton(), 2, 2, 1, 1)
- m.Grid().Attach(m.createZCalibrationModeButton(), 3, 2, 1, 1)
+ m.Grid().Attach(m.createMagnetOnButton(), 3, 1, 1, 1)
+ m.Grid().Attach(m.createMagnetOffButton(), 4, 1, 1, 1)
+ m.Grid().Attach(m.createZCalibrationButton(), 2, 2, 1, 1)
}
-func (m *toolchangerPanel) createZCalibrationModeButton() gtk.IWidget {
- b := MustStepButton("z-calibration.svg", Step{"Z Offset", false}, Step{"Z Offset", true})
- ctx, _ := b.GetStyleContext()
- ctx.AddClass("color2")
-
- b.Callback = func() {
- m.zCalibrationMode = b.Value().(bool)
- if m.zCalibrationMode == true {
- ctx.AddClass("active")
-
- m.command("G28")
- m.command("T0")
- time.Sleep(time.Second * 1)
- m.command(fmt.Sprintf("G0 X%f Y%f F10000", m.cPoint.x, m.cPoint.y))
- m.command(fmt.Sprintf("G0 Z10 F2000"))
- m.command(fmt.Sprintf("G0 Z%f F400", m.cPoint.z))
-
- m.activeTool = 0
- m.updateZOffset(0)
- } else {
- ctx.RemoveClass("active")
- m.labZOffsetLabel.SetText("Press \"Z Offset\"\nbutton to start\nZ-Offset calibration")
- }
- }
+func (m *toolchangerPanel) createZCalibrationButton() gtk.IWidget {
+ b := MustButtonImageStyle("Z Offsets", "z-calibration.svg", "color2", func() {
+ m.UI.Add(NozzleCalibrationPanel(m.UI, m))
+ })
return b
}
@@ -97,69 +62,12 @@ func (m *toolchangerPanel) createHomeButton() gtk.IWidget {
})
}
-func (m *toolchangerPanel) createIncreaseOffsetButton() gtk.IWidget {
- return MustButtonImage("Bed Down", "z-offset-increase.svg", func() {
- if !m.zCalibrationMode {
- return
- }
- m.updateZOffset(m.zOffset + 0.02)
- })
-}
-
-func (m *toolchangerPanel) createDecreaseOffsetButton() gtk.IWidget {
- return MustButtonImage("Bed Up", "z-offset-decrease.svg", func() {
- if !m.zCalibrationMode {
- return
- }
- m.updateZOffset(m.zOffset - 0.02)
- })
-}
-
-func (m *toolchangerPanel) updateZOffset(v float64) {
- m.zOffset = v
-
- m.labZOffsetLabel.SetText(fmt.Sprintf("Z-Offset: %.2f", m.zOffset))
-
- cmd := &octoprint.CommandRequest{}
- cmd.Commands = []string{
- fmt.Sprintf("SET_GCODE_OFFSET Z=%f", m.zOffset),
- "G0 Z0 F100",
- }
- if err := cmd.Do(m.UI.Printer); err != nil {
- Logger.Error(err)
- }
-
- cmd2 := &octoprint.SetZOffsetRequest{Value: m.zOffset, Tool: m.activeTool}
- if err := cmd2.Do(m.UI.Printer); err != nil {
- Logger.Error(err)
- }
-}
-
func (m *toolchangerPanel) createChangeToolButton(num int) gtk.IWidget {
style := fmt.Sprintf("color%d", num+1)
name := fmt.Sprintf("Tool%d", num+1)
gcode := fmt.Sprintf("T%d", num)
return MustButtonImageStyle(name, "extruder.svg", style, func() {
- if m.zCalibrationMode {
- m.activeTool = num
- m.command(fmt.Sprintf("G0 Z%f", 5.0))
- m.command(gcode)
- time.Sleep(time.Second * 1)
- m.command(fmt.Sprintf("G0 X%f Y%f F10000", m.cPoint.x, m.cPoint.y))
-
- cmd := &octoprint.GetZOffsetRequest{Tool: m.activeTool}
- response, err := cmd.Do(m.UI.Printer)
-
- if err != nil {
- Logger.Error(err)
- return
- }
-
- m.updateZOffset(response.Offset)
-
- } else {
- m.command(gcode)
- }
+ m.command(gcode)
})
}
@@ -188,19 +96,3 @@ func (m *toolchangerPanel) createMagnetOffButton() gtk.IWidget {
}
})
}
-
-func (m *toolchangerPanel) createZOffsetLabel() gtk.IWidget {
- m.labZOffsetLabel = MustLabel("Press \"Z Offset\"\nbutton to start\nZ-Offset calibration")
- m.labZOffsetLabel.SetVAlign(gtk.ALIGN_CENTER)
- m.labZOffsetLabel.SetHAlign(gtk.ALIGN_CENTER)
- m.labZOffsetLabel.SetVExpand(true)
- m.labZOffsetLabel.SetHExpand(true)
- m.labZOffsetLabel.SetLineWrap(true)
- return m.labZOffsetLabel
-}
-
-func (m *toolchangerPanel) command(gcode string) error {
- cmd := &octoprint.CommandRequest{}
- cmd.Commands = []string{gcode}
- return cmd.Do(m.UI.Printer)
-}
diff --git a/ui/ui.go b/ui/ui.go
index 8ff2a327..13bd8901 100644
--- a/ui/ui.go
+++ b/ui/ui.go
@@ -123,7 +123,7 @@ func (ui *UI) verifyConnection() {
ui.sdNotify("WATCHDOG=1")
newUiState := "splash"
- splashMessage := "Initializing printer..."
+ splashMessage := "Loading..."
s, err := (&octoprint.ConnectionRequest{}).Do(ui.Printer)
if err == nil {
diff --git a/vendor/github.com/mcuadros/go-octoprint/zbolt.go b/vendor/github.com/mcuadros/go-octoprint/zbolt.go
index 0f4abee5..e23bf67f 100644
--- a/vendor/github.com/mcuadros/go-octoprint/zbolt.go
+++ b/vendor/github.com/mcuadros/go-octoprint/zbolt.go
@@ -8,6 +8,22 @@ import (
const URIZBoltRequest = "/api/plugin/zbolt"
const URIZBoltOctoScreenRequest = "/api/plugin/zbolt_octoscreen"
+type RunZOffsetCalibrationRequest struct {
+ Command string `json:"command"`
+}
+
+func (cmd *RunZOffsetCalibrationRequest) Do(c *Client) error {
+ cmd.Command = "run_zoffset_calibration"
+
+ b := bytes.NewBuffer(nil)
+ if err := json.NewEncoder(b).Encode(cmd); err != nil {
+ return err
+ }
+
+ _, err := c.doJSONRequest("POST", URIZBoltRequest, b, ConnectionErrors)
+ return err
+}
+
// SettingsRequest retrieves the current configuration of OctoPrint.
type SetZOffsetRequest struct {
Command string `json:"command"`
@@ -94,6 +110,7 @@ type GetSettingsResponse struct {
// Job contains information regarding the target of the current print job.
FilamentInLength float64 `json:"filament_in_length"`
FilamentOutLength float64 `json:"filament_out_length"`
+ ToolChanger bool `json:"toolchanger"`
GCodes struct {
AutoBedLevel string `json:"auto_bed_level"`
} `json:"gcodes"`