Updated menu system. Move panel working

This commit is contained in:
jruthe 2020-07-14 08:13:35 -04:00
parent 60b2e65826
commit a2e979f847
16 changed files with 813 additions and 133 deletions

View File

@ -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"
}
]

View File

@ -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"

View File

@ -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
View File

@ -1,2 +1,125 @@
Repository for Klipper Screen
# OctoScreen [![GitHub release](https://img.shields.io/github/release/Z-Bolt/OctoScreen.svg)](https://github.com/Z-Bolt/OctoScreen/releases) [![license](https://img.shields.io/github/license/Z-Bolt/OctoScreen.svg)]()
_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)

View File

@ -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
View 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

View File

@ -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
View 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
View 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
View 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
View 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
View 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
View 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
View File

@ -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
View 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

View File

@ -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;
}