From 0f1d264544264bf553feb352150fc9bd179607c6 Mon Sep 17 00:00:00 2001 From: Aleksei Kvitinskii Date: Thu, 19 Dec 2019 23:03:52 +0300 Subject: [PATCH] added new extrusion screen for for toolchanger and returned universal filament screen --- ui/extrude_multitool.go | 195 +++++++++++++++++++++++++++++++++++++++ ui/filament.go | 108 ++++++++++++++-------- ui/filament_multitool.go | 161 ++++++++++++++++++++++++++++++++ ui/menu.go | 12 ++- ui/move.go | 2 +- 5 files changed, 434 insertions(+), 44 deletions(-) create mode 100644 ui/extrude_multitool.go create mode 100644 ui/filament_multitool.go diff --git a/ui/extrude_multitool.go b/ui/extrude_multitool.go new file mode 100644 index 00000000..c5a22045 --- /dev/null +++ b/ui/extrude_multitool.go @@ -0,0 +1,195 @@ +package ui + +import ( + "fmt" + "strings" + "time" + + "github.com/gotk3/gotk3/gtk" + "github.com/mcuadros/go-octoprint" +) + +var extrudeMultitoolPanelInstance *extrudeMultitoolPanel + +type extrudeMultitoolPanel struct { + CommonPanel + + amount *StepButton + + box *gtk.Box + labels map[string]*LabelWithImage + previous *octoprint.TemperatureState +} + +func ExtrudeMultitoolPanel(ui *UI, parent Panel) Panel { + if extrudeMultitoolPanelInstance == nil { + m := &extrudeMultitoolPanel{CommonPanel: NewCommonPanel(ui, parent), + labels: map[string]*LabelWithImage{}, + } + m.panelH = 3 + m.b = NewBackgroundTask(time.Second*5, m.updateTemperatures) + m.initialize() + extrudeMultitoolPanelInstance = m + } + + return extrudeMultitoolPanelInstance +} + +func (m *extrudeMultitoolPanel) 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.createExtrudeButton("Extrude", "extrude.svg", 1), 1, 1, 1, 1) + m.Grid().Attach(m.createExtrudeButton("Retract", "retract.svg", -1), 4, 1, 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, 1, 2, 1) + + m.Grid().Attach(MustButtonImageStyle("Temperature", "heat-up.svg", "color4", m.showTemperature), 1, 2, 1, 1) + 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.createFlowrateButton(), 3, 2, 1, 1) +} + +func (m *extrudeMultitoolPanel) 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 *extrudeMultitoolPanel) 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 *extrudeMultitoolPanel) addNewTool(tool string) { + m.labels[tool] = MustLabelWithImage("extruder.svg", "") + m.box.Add(m.labels[tool]) + + Logger.Infof("New tool detected %s", tool) +} + +func (m *extrudeMultitoolPanel) 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 *extrudeMultitoolPanel) 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 *extrudeMultitoolPanel) 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 *extrudeMultitoolPanel) 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 *extrudeMultitoolPanel) 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) +} + +func (m *extrudeMultitoolPanel) 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) + }) +} + +func (m *extrudeMultitoolPanel) showTemperature() { + m.UI.Add(TemperaturePanel(m.UI, m)) +} diff --git a/ui/filament.go b/ui/filament.go index 32dd89c1..277a3286 100644 --- a/ui/filament.go +++ b/ui/filament.go @@ -14,6 +14,9 @@ var filamentPanelInstance *filamentPanel type filamentPanel struct { CommonPanel + amount *StepButton + tool *StepButton + box *gtk.Box labels map[string]*LabelWithImage previous *octoprint.TemperatureState @@ -36,22 +39,23 @@ 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(MustButtonImageStyle("Temperature", "heat-up.svg", "color4", m.showTemperature), 1, 2, 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.box = MustBox(gtk.ORIENTATION_VERTICAL, 5) m.box.SetVAlign(gtk.ALIGN_CENTER) m.box.SetHAlign(gtk.ALIGN_CENTER) - m.Grid().Attach(m.box, 2, 1, 2, 2) + m.Grid().Attach(m.box, 2, 0, 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() { @@ -83,6 +87,7 @@ 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) } @@ -100,21 +105,43 @@ func (m *filamentPanel) loadTemperatureData(tool string, d *octoprint.Temperatur m.labels[tool].ShowAll() } -func (m *filamentPanel) createLoadButton() gtk.IWidget { - length := 750.0 +func (m *filamentPanel) createToolButton() *StepButton { + m.tool = MustStepButton("extruder.svg") + m.tool.Callback = func() { + cmd := &octoprint.ToolSelectRequest{} + cmd.Tool = m.tool.Value().(string) - if m.UI.Settings != nil { - length = m.UI.Settings.FilamentInLength + Logger.Infof("Changing tool to %s", cmd.Tool) + if err := cmd.Do(m.UI.Printer); err != nil { + Logger.Error(err) + return + } } - return MustButtonImageStyle("Load", "extrude.svg", "color3", 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", + 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 { + + return MustButtonImage("Load", "extrude.svg", func() { + cmd := &octoprint.CommandRequest{} + cmd.Commands = []string{"G91", "G0 E600 F5000", "G0 E120 F500", "G90"} Logger.Info("Sending filament load request") if err := cmd.Do(m.UI.Printer); err != nil { @@ -125,19 +152,10 @@ 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 MustButtonImageStyle("Unload", "extrude.svg", "color2", func() { + return MustButtonImage("Unload", "retract.svg", func() { cmd := &octoprint.CommandRequest{} - cmd.Commands = []string{ - "G91", - fmt.Sprintf("G0 E-%.1f F5000", length), - "G90", - } + cmd.Commands = []string{"G91", "G0 E-800 F5000", "G90"} Logger.Info("Sending filament unload request") if err := cmd.Do(m.UI.Printer); err != nil { @@ -147,15 +165,27 @@ func (m *filamentPanel) createUnloadButton() gtk.IWidget { }) } -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) - }) -} +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) showTemperature() { - m.UI.Add(TemperaturePanel(m.UI, m)) + Logger.Infof("Sending extrude request, with amount %d", cmd.Amount) + if err := cmd.Do(m.UI.Printer); err != nil { + Logger.Error(err) + return + } + }, 200) + + // return MustButtonImage(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 + // } + // }) } diff --git a/ui/filament_multitool.go b/ui/filament_multitool.go new file mode 100644 index 00000000..0828aeac --- /dev/null +++ b/ui/filament_multitool.go @@ -0,0 +1,161 @@ +package ui + +import ( + "fmt" + "strings" + "time" + + "github.com/gotk3/gotk3/gtk" + "github.com/mcuadros/go-octoprint" +) + +var filamentMultitoolPanelInstance *filamentMultitoolPanel + +type filamentMultitoolPanel struct { + CommonPanel + + box *gtk.Box + labels map[string]*LabelWithImage + previous *octoprint.TemperatureState +} + +func FilamentMultitoolPanel(ui *UI, parent Panel) Panel { + if filamentMultitoolPanelInstance == nil { + m := &filamentMultitoolPanel{CommonPanel: NewCommonPanel(ui, parent), + labels: map[string]*LabelWithImage{}, + } + m.panelH = 3 + m.b = NewBackgroundTask(time.Second*5, m.updateTemperatures) + m.initialize() + filamentMultitoolPanelInstance = m + } + + return filamentMultitoolPanelInstance +} + +func (m *filamentMultitoolPanel) 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(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, 1, 2, 2) + +} + +func (m *filamentMultitoolPanel) 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 *filamentMultitoolPanel) 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 *filamentMultitoolPanel) addNewTool(tool string) { + m.labels[tool] = MustLabelWithImage("extruder.svg", "") + m.box.Add(m.labels[tool]) + + Logger.Infof("New tool detected %s", tool) +} + +func (m *filamentMultitoolPanel) 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 *filamentMultitoolPanel) createLoadButton() gtk.IWidget { + length := 750.0 + + if m.UI.Settings != nil { + length = m.UI.Settings.FilamentInLength + } + + return MustButtonImageStyle("Load", "extrude.svg", "color3", 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 *filamentMultitoolPanel) createUnloadButton() gtk.IWidget { + length := 800.0 + + if m.UI.Settings != nil { + length = m.UI.Settings.FilamentOutLength + } + + return MustButtonImageStyle("Unload", "extrude.svg", "color2", 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 *filamentMultitoolPanel) 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) + }) +} + +func (m *filamentMultitoolPanel) showTemperature() { + m.UI.Add(TemperaturePanel(m.UI, m)) +} diff --git a/ui/menu.go b/ui/menu.go index c02ae341..c1148b23 100644 --- a/ui/menu.go +++ b/ui/menu.go @@ -11,10 +11,16 @@ func getPanel(ui *UI, parent Panel, item octoprint.MenuItem) Panel { return MenuPanel(ui, parent, item.Items) case "home": return HomePanel(ui, parent) - case "files": - return FilesPanel(ui, parent) case "filament": return FilamentPanel(ui, parent) + case "filament_multitool": + return FilamentMultitoolPanel(ui, parent) + case "extrude": + return ExtrudePanel(ui, parent) + case "extrude_multitool": + return ExtrudeMultitoolPanel(ui, parent) + case "files": + return FilesPanel(ui, parent) case "temperature": return TemperaturePanel(ui, parent) case "control": @@ -29,8 +35,6 @@ func getPanel(ui *UI, parent Panel, item octoprint.MenuItem) Panel { return SystemPanel(ui, parent) case "fan": return FanPanel(ui, parent) - case "extrude": - return ExtrudePanel(ui, parent) case "bed-level": return BedLevelPanel(ui, parent) case "nozzle-calibration": diff --git a/ui/move.go b/ui/move.go index 2daab7a4..a6177c7e 100644 --- a/ui/move.go +++ b/ui/move.go @@ -35,7 +35,7 @@ func (m *movePanel) initialize() { m.Grid().Attach(m.createMoveButton("Z+", "move-z+.svg", octoprint.ZAxis, 1), 3, 1, 1, 1) m.step = MustStepButton("move-step.svg", - Step{"5mm", 5.0}, Step{"10mm", 10.0}, Step{"1mm", 1.0}, Step{"0.1mm", 0.1}, + Step{"10mm", 10.0}, Step{"1mm", 1.0}, Step{"0.1mm", 0.1}, Step{"0.02mm", 0.02}, ) m.Grid().Attach(m.step, 2, 2, 1, 1)