diff options
author | Aleksei Kvitinskii <aleksei.kvitinskii@gmail.com> | 2019-12-19 23:27:42 +0300 |
---|---|---|
committer | Aleksei Kvitinskii <aleksei.kvitinskii@gmail.com> | 2019-12-19 23:27:42 +0300 |
commit | 7800ce39c5604217ee31851b0f2db2a37abf9a86 (patch) | |
tree | 32d8a57ca9bf457d52087b0e8d20b5ed25bb78da | |
parent | 4e60c339aa17fc35db87a8765174aee0a1c16505 (diff) | |
parent | c20e275e7a62c3f1f146603daa4ed49118147b9b (diff) |
Merge branch 'v2.5'
-rw-r--r-- | Makefile | 5 | ||||
-rw-r--r-- | default_menu.json | 76 | ||||
-rw-r--r-- | styles/z-bolt/style.css | 4 | ||||
-rw-r--r-- | ui/common.go | 41 | ||||
-rw-r--r-- | ui/extrude_multitool.go | 195 | ||||
-rw-r--r-- | ui/filament.go | 108 | ||||
-rw-r--r-- | ui/filament_multitool.go | 161 | ||||
-rw-r--r-- | ui/idle_action_menu.go | 61 | ||||
-rw-r--r-- | ui/idle_configuration_menu.go | 48 | ||||
-rw-r--r-- | ui/idle_menu.go | 62 | ||||
-rw-r--r-- | ui/idle_status.go | 34 | ||||
-rw-r--r-- | ui/menu.go | 67 | ||||
-rw-r--r-- | ui/move.go | 26 | ||||
-rw-r--r-- | ui/splash.go | 26 | ||||
-rw-r--r-- | ui/ui.go | 39 | ||||
-rw-r--r-- | vendor/github.com/mcuadros/go-octoprint/zbolt.go | 15 |
16 files changed, 702 insertions, 266 deletions
@@ -27,8 +27,7 @@ JESSIE_GO_TAGS := gtk_3_14 # Build information #GIT_COMMIT = $(shell git rev-parse HEAD | cut -c1-7) -#DEV_PREFIX := 1.0 -VERSION := 2.4 +VERSION := 2.5 BUILD_DATE ?= $(shell date --utc +%Y%m%d-%H:%M:%S) #BRANCH = $(shell git rev-parse --abbrev-ref HEAD) @@ -66,7 +65,7 @@ build-internal: prepare-internal cp ../*.deb /build/; prepare-internal: - dch --create -v $(VERSION)-9 --package $(PACKAGE_NAME) empty; \ + dch --create -v $(VERSION)-1 --package $(PACKAGE_NAME) empty; \ cd $(WORKDIR)/..; \ tar -czf octoscreen_$(VERSION).orig.tar.gz --exclude-vcs OctoScreen diff --git a/default_menu.json b/default_menu.json new file mode 100644 index 0000000..9e197c0 --- /dev/null +++ b/default_menu.json @@ -0,0 +1,76 @@ +[ + { + "name": "Home", + "icon": "home", + "panel": "home" + }, + { + "name": "Actions", + "icon": "actions", + "panel": "menu", + "items": [ + { + "name": "Move", + "icon": "move", + "panel": "move" + }, + { + "name": "Extrude", + "icon": "filament", + "panel": "extrude" + }, + { + "name": "Fan", + "icon": "fan", + "panel": "fan" + }, + { + "name": "Temperature", + "icon": "heat-up", + "panel": "temperature" + }, + { + "name": "Control", + "icon": "control", + "panel": "control" + }, + { + "name": "ToolChanger", + "icon": "toolchanger", + "panel": "toolchanger" + } + ] + }, + { + "name": "Filament", + "icon": "filament", + "panel": "home" + }, + { + "name": "Configuration", + "icon": "control", + "panel": "menu", + "items": [ + { + "name": "Bed Level", + "icon": "bed-level", + "panel": "bed-level" + }, + { + "name": "ZOffsets", + "icon": "z-offset-increase", + "panel": "nozzle-calibration" + }, + { + "name": "Network", + "icon": "network", + "panel": "network" + }, + { + "name": "System", + "icon": "info", + "panel": "system" + } + ] + } +]
\ No newline at end of file diff --git a/styles/z-bolt/style.css b/styles/z-bolt/style.css index 8bc6fe7..69b2f70 100644 --- a/styles/z-bolt/style.css +++ b/styles/z-bolt/style.css @@ -151,3 +151,7 @@ button.keyboard { font-size: 24px; } + +.hidden { + opacity: 0; +} diff --git a/ui/common.go b/ui/common.go index 30b8c08..5d9d6f1 100644 --- a/ui/common.go +++ b/ui/common.go @@ -1,9 +1,12 @@ package ui import ( + "encoding/json" "fmt" + "io/ioutil" "log" "math" + "os" "strings" "sync" "time" @@ -90,12 +93,18 @@ func (p *CommonPanel) Scaled(s int) int { return s * p.UI.scaleFactor } -func (m *CommonPanel) arrangeButtons(buttons []gtk.IWidget) { +func (m *CommonPanel) arrangeMenuItems(grid *gtk.Grid, items []octoprint.MenuItem, cols int) { + for i, item := range items { + panel := getPanel(m.UI, m, item) - row := 4 + if panel != nil { + color := fmt.Sprintf("color%d", (i%4)+1) + icon := fmt.Sprintf("%s.svg", item.Icon) - for i, k := range buttons { - m.Grid().Attach(k, (i%row)+1, i/row, 1, 1) + grid.Attach(MustButtonImageStyle(item.Name, icon, color, func() { + m.UI.Add(panel) + }), (i%cols)+1, i/cols, 1, 1) + } } } @@ -387,3 +396,27 @@ func MessageDialog(parent *gtk.Window, msg string) { win.Run() } + +func getDeafultMenu() []octoprint.MenuItem { + + jsonFile, err := os.Open("default_menu.json") + // if we os.Open returns an error then handle it + if err != nil { + fmt.Println(err) + } + + defer jsonFile.Close() + + var items []octoprint.MenuItem + + byteValue, err := ioutil.ReadAll(jsonFile) + if err != nil { + fmt.Println("Error in default_menu.json") + fmt.Println(err) + return items + } + + json.Unmarshal(byteValue, &items) + + return items +} diff --git a/ui/extrude_multitool.go b/ui/extrude_multitool.go new file mode 100644 index 0000000..c5a2204 --- /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 32dd89c..277a328 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 0000000..0828aea --- /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/idle_action_menu.go b/ui/idle_action_menu.go deleted file mode 100644 index 728dc00..0000000 --- a/ui/idle_action_menu.go +++ /dev/null @@ -1,61 +0,0 @@ -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 deleted file mode 100644 index 7933712..0000000 --- a/ui/idle_configuration_menu.go +++ /dev/null @@ -1,48 +0,0 @@ -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 deleted file mode 100644 index 47f1752..0000000 --- a/ui/idle_menu.go +++ /dev/null @@ -1,62 +0,0 @@ -package ui - -var idleMenuPanelInstance *idleMenuPanel - -type idleMenuPanel struct { - CommonPanel -} - -func IdleMenuPanel(ui *UI, parent Panel) Panel { - if idleMenuPanelInstance == nil { - m := &idleMenuPanel{CommonPanel: NewCommonPanel(ui, parent)} - m.initialize() - idleMenuPanelInstance = m - } - - return idleMenuPanelInstance -} - -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("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) - - 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() { - m.UI.Add(TemperaturePanel(m.UI, m)) -} - -func (m *idleMenuPanel) showControl() { - m.UI.Add(ControlPanel(m.UI, m)) -} - -func (m *idleMenuPanel) showNetwork() { - m.UI.Add(NetworkPanel(m.UI, m)) -} - -func (m *idleMenuPanel) showToolchanger() { - m.UI.Add(ToolchangerPanel(m.UI, m)) -} - -func (m *idleMenuPanel) showSystem() { - m.UI.Add(SystemPanel(m.UI, m)) -} - -func (m *idleMenuPanel) showMove() { - m.UI.Add(MovePanel(m.UI, m)) -} - -func (m *idleMenuPanel) showFan() { - m.UI.Add(FanPanel(m.UI, m)) -} diff --git a/ui/idle_status.go b/ui/idle_status.go index e3540dd..6bca46c 100644 --- a/ui/idle_status.go +++ b/ui/idle_status.go @@ -36,35 +36,31 @@ func IdleStatusPanel(ui *UI) Panel { 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("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("Configuration", "control.svg", "color1", m.showConfigurationMenu), 4, 1, 1, 1) - m.Grid().Attach(MustButtonImageStyle("Print", "print.svg", "color2", m.showFiles), 3, 2, 2, 1) + var menuItems []octoprint.MenuItem - m.showTools() -} + if m.UI.Settings == nil { + menuItems = getDeafultMenu() + } else { + menuItems = m.UI.Settings.MenuStructure + } + // fmt.Print(m.UI.Settings.MenuStructure) -func (m *idleStatusPanel) showActionsMenu() { - m.UI.Add(IdleActionMenuPanel(m.UI, m)) -} + buttons := MustGrid() + buttons.SetRowHomogeneous(true) + buttons.SetColumnHomogeneous(true) + m.Grid().Attach(buttons, 3, 0, 2, 2) -func (m *idleStatusPanel) showConfigurationMenu() { - m.UI.Add(IdleConfigurationMenuPanel(m.UI, m)) -} + m.arrangeMenuItems(buttons, menuItems, 2) + + m.Grid().Attach(MustButtonImageStyle("Print", "print.svg", "color2", m.showFiles), 3, 2, 2, 1) -func (m *idleStatusPanel) showHome() { - m.UI.Add(HomePanel(m.UI, m)) + m.showTools() } func (m *idleStatusPanel) showFiles() { m.UI.Add(FilesPanel(m.UI, m)) } -func (m *idleStatusPanel) showFilament() { - m.UI.Add(FilamentPanel(m.UI, m)) -} - func (m *idleStatusPanel) update() { m.updateTemperature() } diff --git a/ui/menu.go b/ui/menu.go new file mode 100644 index 0000000..c1148b2 --- /dev/null +++ b/ui/menu.go @@ -0,0 +1,67 @@ +package ui + +import ( + "github.com/mcuadros/go-octoprint" +) + +func getPanel(ui *UI, parent Panel, item octoprint.MenuItem) Panel { + + switch item.Panel { + case "menu": + return MenuPanel(ui, parent, item.Items) + case "home": + return HomePanel(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": + return ControlPanel(ui, parent) + case "network": + return NetworkPanel(ui, parent) + case "move": + return MovePanel(ui, parent) + case "toolchanger": + return ToolchangerPanel(ui, parent) + case "system": + return SystemPanel(ui, parent) + case "fan": + return FanPanel(ui, parent) + case "bed-level": + return BedLevelPanel(ui, parent) + case "nozzle-calibration": + return NozzleCalibrationPanel(ui, parent) + default: + return nil + } +} + +type menuPanel struct { + CommonPanel + items []octoprint.MenuItem +} + +func MenuPanel(ui *UI, parent Panel, items []octoprint.MenuItem) Panel { + m := &menuPanel{ + CommonPanel: NewCommonPanel(ui, parent), + items: items, + } + + m.panelH = 1 + len(items)/4 + + m.initialize() + return m +} + +func (m *menuPanel) initialize() { + defer m.Initialize() + m.arrangeMenuItems(m.g, m.items, 4) +} @@ -16,7 +16,6 @@ func MovePanel(ui *UI, parent Panel) Panel { if movePanelInstance == nil { m := &movePanel{CommonPanel: NewCommonPanel(ui, parent)} m.panelH = 3 - m.panelW = 3 m.initialize() movePanelInstance = m } @@ -26,21 +25,26 @@ func MovePanel(ui *UI, parent Panel) Panel { func (m *movePanel) initialize() { defer m.Initialize() - m.Grid().Attach(m.createMoveButton("X-", "move-x-.svg", octoprint.XAxis, -1), 0, 1, 1, 1) - m.Grid().Attach(m.createMoveButton("X+", "move-x+.svg", octoprint.XAxis, 1), 2, 1, 1, 1) - m.Grid().Attach(m.createMoveButton("Y+", "move-y+.svg", octoprint.YAxis, 1), 1, 0, 1, 1) - m.Grid().Attach(m.createMoveButton("Y-", "move-y-.svg", octoprint.YAxis, -1), 1, 2, 1, 1) - - m.Grid().Attach(m.createMoveButton("Z-", "move-z-.svg", octoprint.ZAxis, -1), 3, 0, 1, 1) - m.Grid().Attach(m.createMoveButton("Z+", "move-z+.svg", octoprint.ZAxis, 1), 3, 1, 1, 1) + m.Grid().Attach(m.createMoveButton("X-", "move-x-.svg", octoprint.XAxis, -1), 1, 1, 1, 1) + m.Grid().Attach(m.createMoveButton("X+", "move-x+.svg", octoprint.XAxis, 1), 3, 1, 1, 1) + m.Grid().Attach(m.createMoveButton("Y+", "move-y+.svg", octoprint.YAxis, 1), 2, 0, 1, 1) + m.Grid().Attach(m.createMoveButton("Y-", "move-y-.svg", octoprint.YAxis, -1), 2, 2, 1, 1) + + if m.UI.Settings != nil && m.UI.Settings.ZAxisInverted { + m.Grid().Attach(m.createMoveButton("Z-", "move-z-.svg", octoprint.ZAxis, -1), 4, 0, 1, 1) + m.Grid().Attach(m.createMoveButton("Z+", "move-z+.svg", octoprint.ZAxis, 1), 4, 1, 1, 1) + } else { + m.Grid().Attach(m.createMoveButton("Z+", "move-z-.svg", octoprint.ZAxis, 1), 4, 0, 1, 1) + m.Grid().Attach(m.createMoveButton("Z-", "move-z+.svg", octoprint.ZAxis, -1), 4, 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) + m.Grid().Attach(m.step, 3, 2, 1, 1) - m.Grid().Attach(m.createHomeButton(), 0, 2, 1, 1) + m.Grid().Attach(m.createHomeButton(), 1, 2, 1, 1) } func (m *movePanel) createMoveButton(label, image string, a octoprint.Axis, dir float64) gtk.IWidget { diff --git a/ui/splash.go b/ui/splash.go index 6114aad..f94f06a 100644 --- a/ui/splash.go +++ b/ui/splash.go @@ -6,7 +6,8 @@ import ( type SplashPanel struct { CommonPanel - Label *gtk.Label + Label *gtk.Label + RetryButton *gtk.Button } func NewSplashPanel(ui *UI) *SplashPanel { @@ -42,6 +43,13 @@ func (m *SplashPanel) createActionBar() gtk.IWidget { bar := MustBox(gtk.ORIENTATION_HORIZONTAL, 5) bar.SetHAlign(gtk.ALIGN_END) + m.RetryButton = MustButtonImageStyle("Retry", "refresh.svg", "color2", m.releaseFromHold) + m.RetryButton.SetProperty("width-request", m.Scaled(100)) + m.RetryButton.SetProperty("visible", true) + bar.Add(m.RetryButton) + ctx, _ := m.RetryButton.GetStyleContext() + ctx.AddClass("hidden") + sys := MustButtonImageStyle("System", "info.svg", "color3", m.showSystem) sys.SetProperty("width-request", m.Scaled(100)) bar.Add(sys) @@ -53,6 +61,22 @@ func (m *SplashPanel) createActionBar() gtk.IWidget { return bar } +func (m *SplashPanel) putOnHold() { + m.RetryButton.Show() + ctx, _ := m.RetryButton.GetStyleContext() + ctx.RemoveClass("hidden") + m.Label.SetText("Cannot connect initialize the printer. Tap \"Retry\" to try again.") +} + +func (m *SplashPanel) releaseFromHold() { + m.RetryButton.Hide() + ctx, _ := m.RetryButton.GetStyleContext() + ctx.AddClass("hidden") + + m.Label.SetText("Loading...") + m.UI.connectionAttempts = 0 +} + func (m *SplashPanel) showNetwork() { m.UI.Add(NetworkPanel(m.UI, m)) } @@ -26,11 +26,12 @@ const ( ) type UI struct { - Current Panel - Printer *octoprint.Client - State octoprint.ConnectionState - Settings *octoprint.GetSettingsResponse - UIState string + Current Panel + Printer *octoprint.Client + State octoprint.ConnectionState + Settings *octoprint.GetSettingsResponse + UIState string + OctoPrintPlugin bool Notifications *Notifications @@ -38,12 +39,12 @@ type UI struct { s *SplashPanel b *BackgroundTask g *gtk.Grid - o *gtk.Overlay w *gtk.Window t time.Time - width, height int - scaleFactor int + width, height int + scaleFactor int + connectionAttempts int sync.Mutex } @@ -95,11 +96,11 @@ func (ui *UI) initialize() { gtk.MainQuit() }) - ui.o = MustOverlay() - ui.w.Add(ui.o) + o := MustOverlay() + ui.w.Add(o) ui.g = MustGrid() - ui.o.Add(ui.g) + o.Add(ui.g) ui.sdNotify("READY=1") } @@ -123,7 +124,7 @@ func (ui *UI) verifyConnection() { ui.sdNotify("WATCHDOG=1") newUiState := "splash" - splashMessage := "Loading..." + splashMessage := "Initializing..." s, err := (&octoprint.ConnectionRequest{}).Do(ui.Printer) if err == nil { @@ -138,7 +139,7 @@ func (ui *UI) verifyConnection() { case s.Current.State.IsOffline(): if err := (&octoprint.ConnectRequest{}).Do(ui.Printer); err != nil { newUiState = "splash" - splashMessage = fmt.Sprintf("Error connecting to printer: %s", err) + splashMessage = "Loading..." } case s.Current.State.IsConnecting(): splashMessage = string(s.Current.State) @@ -193,17 +194,25 @@ func (m *UI) loadSettings() { Logger.Error(err) return } - m.Settings = n } func (m *UI) update() { - m.verifyConnection() + if m.connectionAttempts > 8 { + m.s.putOnHold() + return + } else if m.UIState == "splash" { + m.connectionAttempts += 1 + } else { + m.connectionAttempts = 0 + } if m.OctoPrintPlugin { m.checkNotification() m.loadSettings() } + + m.verifyConnection() } func (ui *UI) sdNotify(m string) { diff --git a/vendor/github.com/mcuadros/go-octoprint/zbolt.go b/vendor/github.com/mcuadros/go-octoprint/zbolt.go index e23bf67..fddf2fc 100644 --- a/vendor/github.com/mcuadros/go-octoprint/zbolt.go +++ b/vendor/github.com/mcuadros/go-octoprint/zbolt.go @@ -108,9 +108,11 @@ type GetSettingsRequest struct { } 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"` + FilamentInLength float64 `json:"filament_in_length"` + FilamentOutLength float64 `json:"filament_out_length"` + ToolChanger bool `json:"toolchanger"` + ZAxisInverted bool `json:"z_axis_inverted"` + MenuStructure []MenuItem `json:"menu_structure"` GCodes struct { AutoBedLevel string `json:"auto_bed_level"` } `json:"gcodes"` @@ -136,3 +138,10 @@ func (cmd *GetSettingsRequest) Do(c *Client) (*GetSettingsResponse, error) { return r, err } + +type MenuItem struct { + Name string `json:"name"` + Icon string `json:"icon"` + Panel string `json:"panel"` + Items []MenuItem `json:"items"` +} |