Updated menu system. Move panel working
This commit is contained in:
parent
60b2e65826
commit
a2e979f847
@ -2,6 +2,7 @@
|
||||
{
|
||||
"name": "Home",
|
||||
"icon": "home",
|
||||
"panel": "menu",
|
||||
"items": [
|
||||
{
|
||||
"name": "Home All",
|
||||
@ -30,20 +31,76 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Filament" ,
|
||||
"icon": "filament"
|
||||
},
|
||||
"name": "Actions" ,
|
||||
"icon": "actions",
|
||||
"panel": "menu",
|
||||
"items": [
|
||||
{
|
||||
"name": "Move",
|
||||
"icon": "move"
|
||||
"icon": "move",
|
||||
"panel": "move"
|
||||
},
|
||||
{
|
||||
"name": "Menu",
|
||||
"icon": "actions"
|
||||
"name": "Extrude",
|
||||
"icon": "filament",
|
||||
"panel": "extrude_multitool"
|
||||
},
|
||||
{
|
||||
"name": "Fan",
|
||||
"icon": "fan",
|
||||
"panel": "fan"
|
||||
},
|
||||
{
|
||||
"name": "Temperature",
|
||||
"icon": "heat-up",
|
||||
"panel": "temperature"
|
||||
},
|
||||
{
|
||||
"name": "Control",
|
||||
"icon": "control"
|
||||
"icon": "control",
|
||||
"panel": "control"
|
||||
},
|
||||
{
|
||||
"name": "ToolChanger",
|
||||
"icon": "toolchanger",
|
||||
"panel": "toolchanger"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Filament",
|
||||
"icon": "filament"
|
||||
},
|
||||
{
|
||||
"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"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Print",
|
||||
"icon": "print"
|
||||
}
|
||||
|
||||
]
|
||||
|
62
KlippyGtk.py
62
KlippyGtk.py
@ -1,7 +1,8 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
import gi
|
||||
|
||||
gi.require_version("Gtk", "3.0")
|
||||
from gi.repository import Gtk, Gdk, GLib
|
||||
from gi.repository import Gtk, Gdk, GdkPixbuf, GLib
|
||||
|
||||
class KlippyGtk:
|
||||
labels = {}
|
||||
@ -9,16 +10,36 @@ class KlippyGtk:
|
||||
#def __init__ (self):
|
||||
|
||||
@staticmethod
|
||||
def ImageLabel(image_name, text):
|
||||
box1 = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, relief=2)
|
||||
def ImageLabel(image_name, text, size=20, style=False):
|
||||
box1 = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=15)
|
||||
image = Gtk.Image()
|
||||
#TODO: update file reference
|
||||
image.set_from_file("/opt/printer/OctoScreen/styles/z-bolt/images/" + str(image_name) + ".svg")
|
||||
|
||||
pixbuf = GdkPixbuf.Pixbuf.new_from_file_at_scale("/opt/printer/OctoScreen/styles/z-bolt/images/" + str(image_name) + ".svg", 20, 20, True)
|
||||
image.set_from_pixbuf(pixbuf)
|
||||
|
||||
label = Gtk.Label()
|
||||
label.set_text(text)
|
||||
box1.add(image)
|
||||
box1.add(image) #, size, size)
|
||||
box1.add(label)
|
||||
return box1
|
||||
|
||||
if style != False:
|
||||
ctx = box1.get_style_context()
|
||||
ctx.add_class(style)
|
||||
|
||||
return {"l": label, "b": box1}
|
||||
|
||||
@staticmethod
|
||||
def ProgressBar(style=False):
|
||||
bar = Gtk.ProgressBar()
|
||||
|
||||
if style != False:
|
||||
print "Styling bar " + style
|
||||
ctx = bar.get_style_context()
|
||||
ctx.add_class(style)
|
||||
|
||||
return bar
|
||||
|
||||
@staticmethod
|
||||
def ButtonImage(image_name, label, style=False):
|
||||
@ -32,6 +53,7 @@ class KlippyGtk:
|
||||
b.set_can_focus(False)
|
||||
b.set_image_position(Gtk.PositionType.TOP)
|
||||
b.set_always_show_image(True)
|
||||
b.props.relief = Gtk.ReliefStyle.NONE
|
||||
|
||||
if style != False:
|
||||
ctx = b.get_style_context()
|
||||
@ -39,8 +61,34 @@ class KlippyGtk:
|
||||
|
||||
return b
|
||||
|
||||
@staticmethod
|
||||
def ToggleButton(text):
|
||||
b = Gtk.ToggleButton(text)
|
||||
b.props.relief = Gtk.ReliefStyle.NONE
|
||||
b.set_hexpand(True)
|
||||
b.set_vexpand(True)
|
||||
return b
|
||||
|
||||
@staticmethod
|
||||
def formatFileName(name):
|
||||
name = name.split('/')[-1] if "/" in name else name
|
||||
name = name.split('.gcod')[0] if ".gcode" in name else name
|
||||
if len(name) > 25:
|
||||
return name[0:25] + "\n" + name[25:50]
|
||||
return name
|
||||
|
||||
|
||||
@staticmethod
|
||||
def formatTimeString(seconds):
|
||||
time = int(seconds)
|
||||
text = ""
|
||||
if time/3600 !=0:
|
||||
text += str(time/3600)+"h "
|
||||
text += str(time/60%60)+"m "+str(time%60)+"s"
|
||||
return text
|
||||
|
||||
@staticmethod
|
||||
def formatTemperatureString(temp, target):
|
||||
if (target > temp-2 and target < temp+2) or round(target,0) == 0:
|
||||
return str(round(temp,2)) + "C"
|
||||
return str(round(temp,2)) + "C -> " + str(round(target,2)) + "C"
|
||||
return str(round(temp,2)) + "°C" #°C →"
|
||||
return str(round(temp,2)) + "°C → " + str(round(target,2)) + "°C"
|
||||
|
@ -56,7 +56,7 @@ class KlippyWebsocket(threading.Thread):
|
||||
|
||||
def on_message(self, message):
|
||||
result = json.loads(message)
|
||||
print json.dumps(result, indent=2)
|
||||
#print json.dumps(result, indent=2)
|
||||
GLib.idle_add(self._callback, result['method'], result['params'][0])
|
||||
|
||||
def send_method(self, method, params):
|
||||
|
125
README.md
125
README.md
@ -1,2 +1,125 @@
|
||||
Repository for Klipper Screen
|
||||
# OctoScreen [](https://github.com/Z-Bolt/OctoScreen/releases) []()
|
||||
|
||||
_OctoScreen_, LCD touch interface for our Octoprint based on GTK+3, that allows you to control your 3D Printer, like you can do with any [LCD panel](http://reprap.org/wiki/RepRapTouch), but using _OctoPrint_ and a Raspberry Pi. It's a _X application_ to be executed directly in the X Server without any windows
|
||||
manager or browser, as _frontend of a [OctoPrint](http://octoprint.org) server_ in a Raspberry Pi
|
||||
equipped with any [Touch Screen](https://www.waveshare.com/wiki/4.3inch_HDMI_LCD_(B)).
|
||||
|
||||
<img width="480" src="https://user-images.githubusercontent.com/390214/60487814-ef9d1a00-9ca8-11e9-9c48-31bf54a5488d.png" />
|
||||
<img width="240" src="https://user-images.githubusercontent.com/390214/60277300-f4a74580-9905-11e9-8b88-f6cc35533c2a.png" /><img width="240" src="https://user-images.githubusercontent.com/390214/60277572-84e58a80-9906-11e9-8334-202544f0191d.png" />
|
||||
|
||||
### These are some of the functionalities supported:
|
||||
|
||||
- Print jobs monitoring.
|
||||
- Temperature and Filament management.
|
||||
- Jogging operations.
|
||||
- Wifi connection management
|
||||
- Toolchanger management tools
|
||||
|
||||
### How this is different from TouchUI?
|
||||
|
||||
[TouchUI](http://plugins.octoprint.org/plugins/touchui/), is an amazing plugin
|
||||
for Octoprint, was created as a responsive design for access to OctoPrint,
|
||||
from low resolution devices, such as smartphones, tablets, etc.
|
||||
|
||||
Executing TouchUI under a RPi w/TFT modules, presents two big problems,
|
||||
first isn't optimized to be used with resistive touch screens with low resolutions
|
||||
like 480x320 and second requires a browser to be access, consuming a lot of
|
||||
resources.
|
||||
|
||||
This is the main reason because I develop this X application to be executed
|
||||
in my 3d printer.
|
||||
|
||||
## [Roadmap](https://github.com/Z-Bolt/OctoScreen/projects/2)
|
||||
|
||||
Installation
|
||||
------------
|
||||
|
||||
### Dependencies
|
||||
|
||||
*OctoScreen* is based on [Golang](golang.org), usually this means that is
|
||||
dependency-less, but in this case [GTK+3](https://developer.gnome.org/gtk3/3.0/gtk.html)
|
||||
is used, this means that GTK+3 libraries are required to be installed on
|
||||
the system. Be sure that graphical environment is additionally installed.
|
||||
|
||||
If you are using `Raspbian` or any other `Debian` based distribution, required packages can
|
||||
be installed using:
|
||||
|
||||
```sh
|
||||
sudo apt-get install libgtk-3-0 xserver-xorg xinit x11-xserver-utils
|
||||
```
|
||||
Also you may need to install video drive, usually **no screens found** error indicates this. Please find manual here:
|
||||
[https://github.com/ssvb/xf86-video-fbturbo/wiki/Installation](https://github.com/ssvb/xf86-video-fbturbo/wiki/Installation)
|
||||
|
||||
|
||||
### Install from .deb package
|
||||
|
||||
The recommended way to install *OctoScreen* is use the `.deb` packages
|
||||
from the [Releases](https://github.com/Z-Bolt/OctoScreen/releases) page. The packages
|
||||
are available for Debian Stretch based distributions such as Raspbian and OctoPi.
|
||||
|
||||
For example for a Raspbian Stretch:
|
||||
```sh
|
||||
wget https://github.com/Z-Bolt/OctoScreen/releases/download/v2.5.1/octoscreen_2.5-1_armhf.deb
|
||||
sudo dpkg -i octoscreen_2.5-1_armhf.deb
|
||||
```
|
||||
|
||||
### Install from source
|
||||
|
||||
The compilation and packaging tasks are managed by the [`Makefile`](Makefile)
|
||||
and backed on [Docker](Dockerfile). Docker is used to avoid installing any other
|
||||
dependencies since all the operations are done inside of the container.
|
||||
|
||||
If you need to install docker inside `Raspbian` or any other linux distrubution
|
||||
just run:
|
||||
|
||||
```sh
|
||||
curl -fsSL get.docker.com -o get-docker.sh
|
||||
sh get-docker.sh
|
||||
```
|
||||
|
||||
> You can read more about this at [`docker-install`](https://github.com/docker/docker-install)
|
||||
|
||||
To compile the project, assuming that you already cloned this repository, just
|
||||
execute the `build` target, this will generate in `build` folder all the binaries
|
||||
and debian packages:
|
||||
|
||||
```sh
|
||||
> make build
|
||||
> ls -1 build/
|
||||
```
|
||||
|
||||
If you are using `Raspbian` you can install any of the `.deb` generated packages.
|
||||
If not, just use the compiled binary.
|
||||
|
||||
Configuration
|
||||
-------------
|
||||
|
||||
### Basic Configuration
|
||||
|
||||
The basic configuration is handled via environment variables, if you are using
|
||||
the `.deb` package you can configure it at `/etc/octoscreen/config`.
|
||||
|
||||
- `OCTOPRINT_CONFIG_FILE` - Location of the OctoPrint's config.yaml file. If empty the file will be searched at the `pi` home folder or the current user. Only used for locally installed OctoPrint servers.
|
||||
|
||||
- `OCTOPRINT_HOST` - OctoPrint HTTP address, example `http://localhost:5000`, if OctoPrint is locally installed will be read from the config file.
|
||||
|
||||
- `OCTOPRINT_APIKEY` - OctoScreen expects an [API key]( http://docs.octoprint.org/en/master/api/general.html) to be supplied. This API key can be either the globally configured one or a user specific one if “Access Control”. if OctoPrint is locally installed will be read from the config file.
|
||||
|
||||
- `OCTOSCREEN_STYLE_PATH` - Several themes are supported, and style configurations can be done through CSS. This variable defines the location of the application theme.
|
||||
|
||||
- `OCTOSCREEN_RESOLUTION` - Resolution of the application, should be configured to the resolution of your screen. Optimal resolution for OctoScreen is no less than 800x480, so if the physical resolution of your screen is 480x320, it's recommended to set the software resolution 800x533. If you are using Raspbian you can do it by changing [`hdmi_cvt`](https://www.raspberrypi.org/documentation/configuration/config-txt/video.md) param in `/boot/config.txt` file.
|
||||
|
||||
### [Menu Configuration](https://github.com/Z-Bolt/OctoScreen/blob/master/docs/README.md)
|
||||
|
||||
### Custom controls and commands
|
||||
|
||||
Custom [controls](http://docs.octoprint.org/en/master/configuration/config_yaml.html#controls) to execute GCODE instructions and [commands](http://docs.octoprint.org/en/master/configuration/config_yaml.html#system) to execute shell commands can be defined in the `config.yaml` file.
|
||||
|
||||
The controls are limit to static controls without `inputs`.
|
||||
|
||||
License
|
||||
-------
|
||||
|
||||
GNU Affero General Public License v3.0, see [LICENSE](LICENSE)
|
||||
|
||||
This project is a hard fork from [Octiprint-TFT](https://github.com/mcuadros/OctoPrint-TFT) created by [@mcuadros](https://github.com/mcuadros/OctoPrint-TFT)
|
||||
|
@ -1 +1,6 @@
|
||||
from idle_status import *
|
||||
from job_status import *
|
||||
from main_menu import *
|
||||
from menu import *
|
||||
from move import *
|
||||
from splash_screen import *
|
||||
from temperature import *
|
||||
|
21
panels/example.py
Normal file
21
panels/example.py
Normal file
@ -0,0 +1,21 @@
|
||||
import gi
|
||||
|
||||
gi.require_version("Gtk", "3.0")
|
||||
from gi.repository import Gtk, Gdk, GLib
|
||||
|
||||
from KlippyGtk import KlippyGtk
|
||||
|
||||
class ExamplePanel:
|
||||
_screen = None
|
||||
labels = {}
|
||||
|
||||
def __init__(self, screen):
|
||||
self._screen = screen
|
||||
|
||||
|
||||
def initialize(self, menu):
|
||||
# Create gtk items here
|
||||
|
||||
def get(self):
|
||||
# Return gtk item
|
||||
return self.grid
|
@ -1,48 +0,0 @@
|
||||
import gi
|
||||
|
||||
gi.require_version("Gtk", "3.0")
|
||||
from gi.repository import Gtk, Gdk, GLib
|
||||
|
||||
from KlippyGtk import KlippyGtk
|
||||
|
||||
class IdleStatusPanel:
|
||||
_screen = None
|
||||
labels = {}
|
||||
|
||||
def __init__(self, screen):
|
||||
self._screen = screen
|
||||
print "init"
|
||||
|
||||
|
||||
# def initialize(self):
|
||||
# box1 = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
|
||||
# image = Gtk.Image()
|
||||
# #TODO: update file reference
|
||||
# image.set_from_file("/opt/printer/OctoScreen/styles/z-bolt/images/bed.svg")
|
||||
# label = Gtk.Label()
|
||||
# label.set_text("0C / 0C")
|
||||
# self.bed_temp_label = label
|
||||
# box1.add(image)
|
||||
# box1.add(self.bed_temp_label)
|
||||
#
|
||||
# return box1
|
||||
def initialize(self):
|
||||
box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL)
|
||||
grid = Gtk.Grid()
|
||||
grid.set_row_homogeneous(True)
|
||||
grid.set_column_homogeneous(True)
|
||||
|
||||
for i in range(self._screen.number_tools):
|
||||
self.labels["tool" + str(i)] = KlippyGtk.ButtonImage("extruder-"+str(i+1), "0C / 0C")
|
||||
grid.attach(self.labels["tool" + str(i)], 0, 0, 1, 1)
|
||||
|
||||
self.labels['bed'] = KlippyGtk.ButtonImage("bed", "0C / 0C")
|
||||
grid.attach(self.labels['bed'], 0, 1, 1, 1)
|
||||
#box.add(KlippyGtk.ButtonImage("bed", "0C / 0C"))
|
||||
|
||||
box.add(grid)
|
||||
return box
|
||||
|
||||
def update_temp(self, dev, temp, target):
|
||||
if self.labels.has_key(dev):
|
||||
self.labels[dev].set_label(KlippyGtk.formatTemperatureString(temp, target))
|
100
panels/job_status.py
Normal file
100
panels/job_status.py
Normal file
@ -0,0 +1,100 @@
|
||||
import gi
|
||||
|
||||
gi.require_version("Gtk", "3.0")
|
||||
from gi.repository import Gtk, Gdk, GLib
|
||||
|
||||
from KlippyGtk import KlippyGtk
|
||||
|
||||
class JobStatusPanel:
|
||||
_screen = None
|
||||
labels = {}
|
||||
|
||||
def __init__ (self, screen):
|
||||
self._screen = screen
|
||||
|
||||
def initialize(self):
|
||||
grid = Gtk.Grid()
|
||||
grid.set_row_homogeneous(True)
|
||||
grid.set_column_homogeneous(True)
|
||||
|
||||
self.labels['progress'] = KlippyGtk.ProgressBar("printing-progress-bar")
|
||||
self.labels['progress'].set_vexpand(True)
|
||||
self.labels['progress'].set_valign(Gtk.Align.CENTER)
|
||||
self.labels['progress'].set_show_text(True)
|
||||
self.labels['progress'].set_margin_top(10)
|
||||
self.labels['progress'].set_margin_end(20)
|
||||
|
||||
self.labels['file'] = KlippyGtk.ImageLabel("file","",20,"printing-status-label")
|
||||
self.labels['time'] = KlippyGtk.ImageLabel("speed-step","time",20,"printing-status-label")
|
||||
self.labels['time_left'] = KlippyGtk.ImageLabel("speed-step","time_left",20,"printing-status-label")
|
||||
info = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
|
||||
info.props.valign = Gtk.Align.CENTER
|
||||
info.set_hexpand(True)
|
||||
info.set_vexpand(True)
|
||||
info.add(self.labels['file']['b'])
|
||||
info.add(self.labels['time']['b'])
|
||||
#info.add(self.labels['time_left']['b'])
|
||||
|
||||
grid.attach(info,2,0,2,1)
|
||||
|
||||
grid.attach(self.labels['progress'], 2, 1, 2, 1)
|
||||
|
||||
self.labels['tool0'] = KlippyGtk.ButtonImage("extruder-1", KlippyGtk.formatTemperatureString(0, 0))
|
||||
self.labels['tool0'].set_sensitive(False)
|
||||
grid.attach(self.labels['tool0'], 0, 0, 1, 1)
|
||||
#self.labels['tool1'] = KlippyGtk.ButtonImage("extruder-2", KlippyGtk.formatTemperatureString(0, 0))
|
||||
#self.labels['tool1'].set_sensitive(False)
|
||||
#grid.attach(self.labels['tool1'], 1, 0, 1, 1)
|
||||
self.labels['bed'] = KlippyGtk.ButtonImage("bed", KlippyGtk.formatTemperatureString(0, 0))
|
||||
self.labels['bed'].set_sensitive(False)
|
||||
grid.attach(self.labels['bed'], 0, 2, 1, 1)
|
||||
|
||||
self.labels['resume'] = KlippyGtk.ButtonImage("resume","Resume","color1")
|
||||
self.labels['resume'].connect("clicked",self.resume)
|
||||
#grid.attach(self.labels['play'], 1, 2, 1, 1)
|
||||
self.labels['pause'] = KlippyGtk.ButtonImage("pause","Pause","color1" )
|
||||
self.labels['pause'].connect("clicked",self.pause)
|
||||
grid.attach(self.labels['pause'], 1, 2, 1, 1)
|
||||
self.labels['stop'] = KlippyGtk.ButtonImage("stop","Stop","color2")
|
||||
grid.attach(self.labels['stop'], 2, 2, 1, 1)
|
||||
self.labels['control'] = KlippyGtk.ButtonImage("control","Control","color3")
|
||||
grid.attach(self.labels['control'], 3, 2, 1, 1)
|
||||
|
||||
self.grid = grid
|
||||
|
||||
return self.grid
|
||||
#m.Grid().Attach(m.createInfoBox(), 3, 0, 2, 1)
|
||||
#m.Grid().Attach(m.createProgressBar(), 3, 1, 2, 1)
|
||||
#m.Grid().Attach(m.createPauseButton(), 2, 2, 1, 1)
|
||||
#m.Grid().Attach(m.createStopButton(), 3, 2, 1, 1)
|
||||
#m.Grid().Attach(m.createMenuButton(), 4, 2, 1, 1)
|
||||
#m.Grid().Attach(m.createCompleteButton(), 2, 2, 3, 1)
|
||||
|
||||
def get(self):
|
||||
return self.grid
|
||||
|
||||
def resume(self, widget):
|
||||
self.grid.attach(self.labels['pause'], 1, 2, 1, 1)
|
||||
self.grid.remove(self.labels['resume'])
|
||||
self._screen.show_all()
|
||||
|
||||
def pause(self, widget):
|
||||
self.grid.attach(self.labels['resume'], 1, 2, 1, 1)
|
||||
self.grid.remove(self.labels['pause'])
|
||||
self._screen.show_all()
|
||||
|
||||
|
||||
def update_image_text(self, label, text):
|
||||
if label in self.labels and 'l' in self.labels[label]:
|
||||
self.labels[label]['l'].set_text(text)
|
||||
|
||||
def update_progress (self, progress):
|
||||
#progress = round(progress,2)
|
||||
#whole = (progress%1) * 100
|
||||
|
||||
self.labels['progress'].set_fraction(progress)
|
||||
#self.labels['progress'].set_text(str(int(whole)) + "%")
|
||||
|
||||
def update_temp(self, dev, temp, target):
|
||||
if self.labels.has_key(dev):
|
||||
self.labels[dev].set_label(KlippyGtk.formatTemperatureString(temp, target))
|
34
panels/main_menu.py
Normal file
34
panels/main_menu.py
Normal file
@ -0,0 +1,34 @@
|
||||
import gi
|
||||
|
||||
gi.require_version("Gtk", "3.0")
|
||||
from gi.repository import Gtk, Gdk, GLib
|
||||
|
||||
from KlippyGtk import KlippyGtk
|
||||
from menu import MenuPanel
|
||||
|
||||
class MainPanel(MenuPanel):
|
||||
|
||||
def initialize(self, items):
|
||||
print "### Making MainMenu"
|
||||
grid = Gtk.Grid()
|
||||
grid.set_row_homogeneous(True)
|
||||
grid.set_column_homogeneous(True)
|
||||
|
||||
# Create Extruders and bed icons
|
||||
eq_grid = Gtk.Grid()
|
||||
eq_grid.set_row_homogeneous(True)
|
||||
eq_grid.set_column_homogeneous(True)
|
||||
|
||||
for i in range(self._screen.number_tools):
|
||||
self.labels["tool" + str(i)] = KlippyGtk.ButtonImage("extruder-"+str(i+1), KlippyGtk.formatTemperatureString(0, 0))
|
||||
eq_grid.attach(self.labels["tool" + str(i)], 0, 0, 1, 1)
|
||||
|
||||
self.labels['bed'] = KlippyGtk.ButtonImage("bed", KlippyGtk.formatTemperatureString(0, 0))
|
||||
eq_grid.attach(self.labels['bed'], 0, 1, 1, 1)
|
||||
|
||||
grid.attach(eq_grid, 0, 0, 1, 1)
|
||||
grid.attach(self.arrangeMenuItems(items, 2, True), 1, 0, 1, 1)
|
||||
self.grid = grid
|
||||
|
||||
#def get(self):
|
||||
# return self.grid
|
69
panels/menu.py
Normal file
69
panels/menu.py
Normal file
@ -0,0 +1,69 @@
|
||||
import gi
|
||||
|
||||
gi.require_version("Gtk", "3.0")
|
||||
from gi.repository import Gtk, Gdk, GLib
|
||||
|
||||
from KlippyGtk import KlippyGtk
|
||||
|
||||
class MenuPanel:
|
||||
_screen = None
|
||||
labels = {}
|
||||
|
||||
def __init__(self, screen):
|
||||
self._screen = screen
|
||||
|
||||
|
||||
def initialize(self, items):
|
||||
print "### Making a new menu"
|
||||
|
||||
grid = self.arrangeMenuItems(items, 4)
|
||||
|
||||
b = KlippyGtk.ButtonImage('back', 'Back')
|
||||
b.connect("clicked", self._screen._menu_go_back)
|
||||
grid.attach(b, 3, 1, 1, 1)
|
||||
|
||||
self.grid = grid
|
||||
|
||||
def get(self):
|
||||
return self.grid
|
||||
|
||||
def arrangeMenuItems (self, items, columns, expandLast=False):
|
||||
grid = Gtk.Grid()
|
||||
grid.set_row_homogeneous(True)
|
||||
grid.set_column_homogeneous(True)
|
||||
|
||||
l = len(items)
|
||||
i = 0
|
||||
for i in range(l):
|
||||
col = i % columns
|
||||
row = round(i/columns, 0)
|
||||
width = 1
|
||||
if expandLast == True and i+1 == l and l%2 == 1:
|
||||
width = 2
|
||||
b = KlippyGtk.ButtonImage(
|
||||
items[i]['icon'], items[i]['name'], "color"+str((i%4)+1)
|
||||
)
|
||||
|
||||
if "panel" in items[i]:
|
||||
b.connect("clicked", self.menu_item_clicked, items[i]['panel'], items[i])
|
||||
elif "items" in items[i]:
|
||||
b.connect("clicked", self._screen._go_to_submenu, items[i]['name'])
|
||||
elif "method" in items[i]:
|
||||
params = items[i]['params'] if "params" in items[i] else {}
|
||||
b.connect("clicked", self._screen._send_action, items[i]['method'], params)
|
||||
|
||||
grid.attach(b, col, row, width, 1)
|
||||
|
||||
i += 1
|
||||
print b.get_style_context()
|
||||
print b.get_default_style()
|
||||
|
||||
return grid
|
||||
|
||||
def menu_item_clicked(self, widget, panel, item):
|
||||
print "### Creating panel "+ item['panel']
|
||||
if "items" in item:
|
||||
self._screen.show_panel("_".join(self._screen._cur_panels) + '_' + item['name'], item['panel'], 1, False, items=item['items'])
|
||||
return
|
||||
self._screen.show_panel("_".join(self._screen._cur_panels) + '_' + item['name'], item['panel'], 1, False)
|
||||
return
|
112
panels/move.py
Normal file
112
panels/move.py
Normal file
@ -0,0 +1,112 @@
|
||||
import gi
|
||||
|
||||
gi.require_version("Gtk", "3.0")
|
||||
from gi.repository import Gtk, Gdk, GLib
|
||||
|
||||
from KlippyGtk import KlippyGtk
|
||||
|
||||
class MovePanel:
|
||||
_screen = None
|
||||
labels = {}
|
||||
distance = 1
|
||||
distances = ['.1','1','5','10']
|
||||
|
||||
|
||||
def __init__(self, screen):
|
||||
self._screen = screen
|
||||
|
||||
|
||||
def initialize(self):
|
||||
|
||||
grid = Gtk.Grid()
|
||||
grid.set_column_homogeneous(True)
|
||||
grid.set_row_homogeneous(True)
|
||||
|
||||
self.labels['x+'] = KlippyGtk.ButtonImage("move-x+", "X+", "color1")
|
||||
self.labels['x+'].connect("clicked", self.move, "X", "+")
|
||||
self.labels['x-'] = KlippyGtk.ButtonImage("move-x-", "X-", "color1")
|
||||
self.labels['x-'].connect("clicked", self.move, "X", "-")
|
||||
|
||||
self.labels['y+'] = KlippyGtk.ButtonImage("move-y+", "Y+", "color2")
|
||||
self.labels['y+'].connect("clicked", self.move, "Y", "+")
|
||||
self.labels['y-'] = KlippyGtk.ButtonImage("move-y-", "Y-", "color2")
|
||||
self.labels['y-'].connect("clicked", self.move, "Y", "-")
|
||||
|
||||
self.labels['z+'] = KlippyGtk.ButtonImage("move-z-", "Z+", "color3")
|
||||
self.labels['z+'].connect("clicked", self.move, "Z", "+")
|
||||
self.labels['z-'] = KlippyGtk.ButtonImage("move-z+", "Z-", "color3")
|
||||
self.labels['z-'].connect("clicked", self.move, "Z", "-")
|
||||
|
||||
self.labels['home'] = KlippyGtk.ButtonImage("home", "Home All")
|
||||
self.labels['home'].connect("clicked", self.home)
|
||||
|
||||
|
||||
grid.attach(self.labels['x+'], 0, 1, 1, 1)
|
||||
grid.attach(self.labels['x-'], 2, 1, 1, 1)
|
||||
grid.attach(self.labels['y+'], 1, 0, 1, 1)
|
||||
grid.attach(self.labels['y-'], 1, 2, 1, 1)
|
||||
grid.attach(self.labels['z+'], 0, 0, 1, 1)
|
||||
grid.attach(self.labels['z-'], 2, 0, 1, 1)
|
||||
|
||||
grid.attach(self.labels['home'], 0, 2, 1, 1)
|
||||
|
||||
distgrid = Gtk.Grid(row_spacing=0)
|
||||
j = 0;
|
||||
for i in self.distances:
|
||||
self.labels[i] = KlippyGtk.ToggleButton(i+"mm")
|
||||
self.labels[i].connect("clicked", self.change_distance, i)
|
||||
ctx = self.labels[i].get_style_context()
|
||||
if j == 0:
|
||||
ctx.add_class("distbutton_top")
|
||||
elif j == len(self.distances)-1:
|
||||
ctx.add_class("distbutton_bottom")
|
||||
else:
|
||||
ctx.add_class("distbutton")
|
||||
if i == "1":
|
||||
ctx.add_class("distbutton_active")
|
||||
distgrid.attach(self.labels[i], 0, j, 1, 1)
|
||||
j += 1
|
||||
|
||||
self.labels["1"].set_active(True)
|
||||
|
||||
grid.set_row_spacing(0)
|
||||
grid.attach(distgrid, 3, 0, 1, 2)
|
||||
|
||||
|
||||
|
||||
b = KlippyGtk.ButtonImage('back', 'Back')
|
||||
b.connect("clicked", self._screen._menu_go_back)
|
||||
grid.attach(b, 3, 2, 1, 1)
|
||||
|
||||
self.grid = grid
|
||||
|
||||
def get(self):
|
||||
return self.grid
|
||||
|
||||
def home(self, widget):
|
||||
self._screen._ws.send_method("post_printer_gcode", {"script": "G28"})
|
||||
|
||||
def change_distance(self, widget, distance):
|
||||
if self.distance == distance:
|
||||
return
|
||||
print "### Distance " + str(distance)
|
||||
|
||||
ctx = self.labels[str(self.distance)].get_style_context()
|
||||
ctx.remove_class("distbutton_active")
|
||||
|
||||
self.distance = distance
|
||||
ctx = self.labels[self.distance].get_style_context()
|
||||
ctx.add_class("distbutton_active")
|
||||
for i in self.distances:
|
||||
if i == self.distance:
|
||||
continue
|
||||
self.labels[str(i)].set_active(False)
|
||||
|
||||
def move(self, widget, axis, dir):
|
||||
dist = str(self.distance) if dir == "+" else "-" + str(self.distance)
|
||||
print "# Moving " + axis + " " + dist + "mm"
|
||||
|
||||
|
||||
self._screen._ws.send_method("post_printer_gcode", {"script": "G91"})
|
||||
print "G1 "+axis+dist
|
||||
#self._screen._ws.send_method("post_printer_gcode", {"script": "G1 "+axis+dist})
|
37
panels/splash_screen.py
Normal file
37
panels/splash_screen.py
Normal file
@ -0,0 +1,37 @@
|
||||
import gi
|
||||
|
||||
gi.require_version("Gtk", "3.0")
|
||||
from gi.repository import Gtk, Gdk, GLib
|
||||
|
||||
from KlippyGtk import KlippyGtk
|
||||
|
||||
class SplashScreenPanel:
|
||||
_screen = None
|
||||
labels = {}
|
||||
box = None
|
||||
|
||||
def __init__(self, screen):
|
||||
self._screen = screen
|
||||
|
||||
|
||||
def initialize(self):
|
||||
image = Gtk.Image()
|
||||
#TODO: update file reference
|
||||
image.set_from_file("/opt/printer/OctoScreen/styles/z-bolt/images/logo.png")
|
||||
|
||||
label = Gtk.Label()
|
||||
label.set_text("Initializing printer...")
|
||||
#label = Gtk.Button(label="Initializing printer...")
|
||||
#label.connect("clicked", self.printer_initialize)
|
||||
|
||||
main = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=15)
|
||||
main.pack_start(image, True, True, 10)
|
||||
main.pack_end(label, True, True, 10)
|
||||
|
||||
box = Gtk.VBox()
|
||||
box.add(main)
|
||||
|
||||
self.box = box
|
||||
|
||||
def get(self):
|
||||
return self.box
|
32
panels/temperature.py
Normal file
32
panels/temperature.py
Normal file
@ -0,0 +1,32 @@
|
||||
import gi
|
||||
|
||||
gi.require_version("Gtk", "3.0")
|
||||
from gi.repository import Gtk, Gdk, GLib
|
||||
|
||||
from KlippyGtk import KlippyGtk
|
||||
|
||||
class TemperaturePanel:
|
||||
_screen = None
|
||||
labels = {}
|
||||
|
||||
def __init__(self, screen):
|
||||
self._screen = screen
|
||||
|
||||
|
||||
def initialize(self):
|
||||
grid = Gtk.Grid()
|
||||
grid.set_column_homogeneous(True)
|
||||
grid.set_row_homogeneous(True)
|
||||
|
||||
|
||||
|
||||
|
||||
b = KlippyGtk.ButtonImage('back', 'Back')
|
||||
b.connect("clicked", self._screen._menu_go_back)
|
||||
grid.attach(b, 3, 2, 1, 1)
|
||||
|
||||
self.grid = grid
|
||||
|
||||
def get(self):
|
||||
# Return gtk item
|
||||
return self.grid
|
159
screen.py
159
screen.py
@ -13,7 +13,7 @@ from gi.repository import Gtk, Gdk, GLib
|
||||
|
||||
from KlippyWebsocket import KlippyWebsocket
|
||||
from KlippyGtk import KlippyGtk
|
||||
from panels import IdleStatusPanel
|
||||
from panels import *
|
||||
|
||||
config = "/opt/printer/KlipperScreen/KlipperScreen.config"
|
||||
|
||||
@ -25,6 +25,7 @@ class KlipperScreen(Gtk.Window):
|
||||
|
||||
panels = {}
|
||||
_cur_panels = []
|
||||
filename = ""
|
||||
|
||||
def __init__(self):
|
||||
self.read_config()
|
||||
@ -32,22 +33,71 @@ class KlipperScreen(Gtk.Window):
|
||||
Gtk.Window.__init__(self)
|
||||
|
||||
self.set_default_size(Gdk.Screen.get_width(Gdk.Screen.get_default()), Gdk.Screen.get_height(Gdk.Screen.get_default()))
|
||||
print str(Gdk.Screen.get_width(Gdk.Screen.get_default()))+"x"+str(Gdk.Screen.get_height(Gdk.Screen.get_default()))
|
||||
|
||||
self.show_panel('splash_screen', "SplashScreenPanel")
|
||||
|
||||
ready = False
|
||||
|
||||
while ready == False:
|
||||
r = requests.get("http://127.0.0.1:7125/printer/info") #, headers={"x-api-key":api_key})
|
||||
if r.status_code != 200:
|
||||
self.printer_initializing()
|
||||
self.create_websocket()
|
||||
return
|
||||
time.sleep(1)
|
||||
continue
|
||||
|
||||
data = json.loads(r.content)
|
||||
|
||||
if data['result']['is_ready'] != True:
|
||||
self.printer_initializing()
|
||||
self.create_websocket()
|
||||
return
|
||||
time.sleep(1)
|
||||
continue
|
||||
ready = True
|
||||
|
||||
r = requests.get("http://127.0.0.1:7125/printer/status?toolhead")
|
||||
self.create_websocket()
|
||||
self.main_panel()
|
||||
|
||||
#TODO: Check that we get good data
|
||||
data = json.loads(r.content)
|
||||
|
||||
if data['result']['toolhead']['status'] == "Printing":
|
||||
self.show_panel('job_status',"JobStatusPanel")
|
||||
else:
|
||||
self.show_panel('main_panel',"MainPanel",2,items=self._config)
|
||||
|
||||
|
||||
def show_panel(self, panel_name, type, remove=None, pop=True, **kwargs):
|
||||
if remove == 2:
|
||||
self._remove_all_panels()
|
||||
elif remove == 1:
|
||||
self._remove_current_panel(pop)
|
||||
if panel_name not in self.panels:
|
||||
if type == "SplashScreenPanel":
|
||||
self.panels[panel_name] = SplashScreenPanel(self)
|
||||
elif type == "MainPanel":
|
||||
self.panels[panel_name] = MainPanel(self)
|
||||
elif type == "menu":
|
||||
self.panels[panel_name] = MenuPanel(self)
|
||||
print panel_name
|
||||
elif type == "JobStatusPanel":
|
||||
self.panels[panel_name] = JobStatusPanel(self)
|
||||
elif type == "move":
|
||||
self.panels[panel_name] = MovePanel(self)
|
||||
elif type == "temperature":
|
||||
self.panels[panel_name] = TemperaturePanel(self)
|
||||
#Temporary for development
|
||||
else:
|
||||
self.panels[panel_name] = MovePanel(self)
|
||||
|
||||
if kwargs != {}:
|
||||
print self.panels
|
||||
print kwargs
|
||||
self.panels[panel_name].initialize(**kwargs)
|
||||
else :
|
||||
self.panels[panel_name].initialize()
|
||||
|
||||
self.add(self.panels[panel_name].get())
|
||||
self.show_all()
|
||||
self._cur_panels.append(panel_name)
|
||||
print self._cur_panels
|
||||
|
||||
|
||||
def read_config (self):
|
||||
@ -67,24 +117,10 @@ class KlipperScreen(Gtk.Window):
|
||||
|
||||
def splash_screen(self):
|
||||
if "splash_screen" not in self.panels:
|
||||
image = Gtk.Image()
|
||||
#TODO: update file reference
|
||||
image.set_from_file("/opt/printer/OctoScreen/styles/z-bolt/images/logo.png")
|
||||
self.panels['splash_screen'] = SplashScreenPanel(self)
|
||||
self.panels['splash_screen'].initialize()
|
||||
|
||||
label = Gtk.Label()
|
||||
label.set_text("Initializing printer...")
|
||||
#label = Gtk.Button(label="Initializing printer...")
|
||||
#label.connect("clicked", self.printer_initialize)
|
||||
|
||||
main = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=15)
|
||||
main.pack_start(image, True, True, 10)
|
||||
main.pack_end(label, True, True, 10)
|
||||
|
||||
box = Gtk.VBox()
|
||||
box.add(main)
|
||||
self.panels['splash_screen'] = box
|
||||
|
||||
self.add(self.panels['splash_screen'])
|
||||
self.add(self.panels['splash_screen'].get())
|
||||
self.show_all()
|
||||
self._cur_panels = ['splash_screen']
|
||||
|
||||
@ -93,38 +129,18 @@ class KlipperScreen(Gtk.Window):
|
||||
self._ws.connect()
|
||||
self._curr = 0
|
||||
|
||||
def main_panel (self):
|
||||
if "main_panel" not in self.panels:
|
||||
box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL)
|
||||
|
||||
grid = Gtk.Grid()
|
||||
grid.set_row_homogeneous(True)
|
||||
grid.set_column_homogeneous(True)
|
||||
|
||||
self.panels['idle_status'] = IdleStatusPanel(self)
|
||||
|
||||
|
||||
grid.attach(self.panels['idle_status'].initialize(), 0, 0, 1, 1)
|
||||
#grid.attach(box2, 1, 0, 1, 1)
|
||||
|
||||
|
||||
grid.attach(self.arrangeMenuItems(self._config,2), 1, 0, 1, 1)
|
||||
|
||||
self.panels['main_screen'] = grid
|
||||
|
||||
print ("### Adding main panel")
|
||||
self.add(self.panels['main_screen'])
|
||||
self.show_all()
|
||||
self._cur_panels.append("main_screen")
|
||||
|
||||
def _go_to_submenu(self, widget, menu):
|
||||
print "#### Go to submenu " + str(menu)
|
||||
self._remove_current_panel(False)
|
||||
def _go_to_submenu(self, widget, name):
|
||||
print "#### Go to submenu " + str(name)
|
||||
#self._remove_current_panel(False)
|
||||
|
||||
# Find current menu item
|
||||
panels = list(self._cur_panels)
|
||||
cur_item = self._find_current_menu_item(menu, self._config, panels.pop(0))
|
||||
cur_item = self._find_current_menu_item(name, self._config, panels.pop(0))
|
||||
menu = cur_item['items']
|
||||
print menu
|
||||
self.show_panel("_".join(self._cur_panels) + '_' + name, "menu", 1, False, menu=menu)
|
||||
return
|
||||
|
||||
grid = self.arrangeMenuItems(menu, 4)
|
||||
|
||||
@ -140,9 +156,10 @@ class KlipperScreen(Gtk.Window):
|
||||
|
||||
|
||||
def _find_current_menu_item(self, menu, items, names):
|
||||
# TODO: Make recursive
|
||||
return items[menu]
|
||||
|
||||
for item in items:
|
||||
if item['name'] == menu:
|
||||
return item
|
||||
#TODO: Add error check
|
||||
|
||||
def _remove_all_panels(self):
|
||||
while len(self._cur_panels) > 0:
|
||||
@ -155,13 +172,13 @@ class KlipperScreen(Gtk.Window):
|
||||
self.remove(
|
||||
self.panels[
|
||||
self._cur_panels[-1]
|
||||
]
|
||||
].get()
|
||||
)
|
||||
if pop == True:
|
||||
print "Popping _cur_panels"
|
||||
self._cur_panels.pop()
|
||||
if len(self._cur_panels) > 0:
|
||||
self.add(self.panels[self._cur_panels[-1]])
|
||||
self.add(self.panels[self._cur_panels[-1]].get())
|
||||
self.show_all()
|
||||
|
||||
def _menu_go_back (self, widget):
|
||||
@ -192,6 +209,32 @@ class KlipperScreen(Gtk.Window):
|
||||
round(data['extruder']['temperature'],1),
|
||||
round(data['extruder']['target'],1)
|
||||
)
|
||||
if "job_status" in self.panels:
|
||||
#print json.dumps(data, indent=2)
|
||||
if "heater_bed" in data:
|
||||
self.panels['job_status'].update_temp(
|
||||
"bed",
|
||||
round(data['heater_bed']['temperature'],1),
|
||||
round(data['heater_bed']['target'],1)
|
||||
)
|
||||
if "extruder" in data and data['extruder'] != "extruder":
|
||||
self.panels['job_status'].update_temp(
|
||||
"tool0",
|
||||
round(data['extruder']['temperature'],1),
|
||||
round(data['extruder']['target'],1)
|
||||
)
|
||||
if "virtual_sdcard" in data:
|
||||
print data['virtual_sdcard']
|
||||
if "current_file" in data['virtual_sdcard'] and self.filename != data['virtual_sdcard']['current_file']:
|
||||
if data['virtual_sdcard']['current_file'] != "":
|
||||
file = KlippyGtk.formatFileName(data['virtual_sdcard']['current_file'])
|
||||
else:
|
||||
file = "Unknown"
|
||||
#self.panels['job_status'].update_image_text("file", file)
|
||||
if "print_duration" in data['virtual_sdcard']:
|
||||
self.panels['job_status'].update_image_text("time", "Time: " +KlippyGtk.formatTimeString(data['virtual_sdcard']['print_duration']))
|
||||
if "progress" in data['virtual_sdcard']:
|
||||
self.panels['job_status'].update_progress(data['virtual_sdcard']['progress'])
|
||||
|
||||
|
||||
def set_bed_temp (self, num, target):
|
||||
@ -239,7 +282,7 @@ class KlipperScreen(Gtk.Window):
|
||||
|
||||
def printer_ready(self):
|
||||
self._remove_all_panels()
|
||||
self.main_panel()
|
||||
self.show_panel('main_panel',"MainPanel",2,items=self._config)
|
||||
|
||||
def on_button1_clicked(self, widget):
|
||||
print("Hello")
|
||||
|
11
scripts/disablescreenblank.sh
Executable file
11
scripts/disablescreenblank.sh
Executable file
@ -0,0 +1,11 @@
|
||||
#!/bin/bash
|
||||
|
||||
screen=${1:-0}
|
||||
|
||||
# wait 10s for the display manager service to start and attach to screen
|
||||
sleep 5
|
||||
|
||||
/usr/bin/xset -display :$screen s off # deactivate screen saver
|
||||
/usr/bin/xset -display :$screen -dpms # disable DPMS
|
||||
/usr/bin/xset -display :$screen s noblank # disable screen blanking
|
||||
|
44
style.css
44
style.css
@ -20,8 +20,11 @@ scrollbar slider {
|
||||
}
|
||||
|
||||
progress, trough {
|
||||
min-height: 20px;
|
||||
min-height: 40px;
|
||||
font-size: 50px;
|
||||
background-color: #404E57;
|
||||
color: #404E57;
|
||||
border: #000 1px solid;
|
||||
}
|
||||
|
||||
progress {
|
||||
@ -30,11 +33,16 @@ progress {
|
||||
font-weight: lighter;
|
||||
}
|
||||
|
||||
.printing-progress-bar{
|
||||
font-size: 60px;
|
||||
.printing-progress-bar {
|
||||
font-size: 25px;
|
||||
color: #00C9B4;
|
||||
}
|
||||
|
||||
.printing-progress-bar text {
|
||||
font-size: 25px;
|
||||
color: #404e57;
|
||||
}
|
||||
|
||||
.printing-state {
|
||||
opacity: 0.5;
|
||||
}
|
||||
@ -78,6 +86,34 @@ button.file-list {
|
||||
margin: 0px;
|
||||
}
|
||||
|
||||
.distbutton_top {
|
||||
border: 3px solid #fff;
|
||||
border-bottom: 0px;
|
||||
border-top-right-radius: 15px;
|
||||
border-top-left-radius: 15px;
|
||||
margin-bottom: 0px;
|
||||
}
|
||||
|
||||
.distbutton {
|
||||
border: 3px solid #fff;
|
||||
border-top: 3px solid #ccc;
|
||||
border-bottom: 0px;
|
||||
margin-top: 0;
|
||||
margin-bottom: 0px;
|
||||
}
|
||||
|
||||
.distbutton_bottom {
|
||||
border: 3px solid #fff;
|
||||
border-top: 3px solid #ccc;
|
||||
border-bottom-right-radius: 20px;
|
||||
border-bottom-left-radius: 20px;
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
.distbutton_active {
|
||||
background-color: #20303D;
|
||||
}
|
||||
|
||||
entry {
|
||||
font-size: 30px;
|
||||
background-color: #20292F;
|
||||
@ -149,7 +185,7 @@ button.keyboard {
|
||||
.printing-status-label {
|
||||
padding-top: 5px;
|
||||
padding-bottom: 3px;
|
||||
|
||||
color: #ccc;
|
||||
font-size: 24px;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user