109 lines
3.7 KiB
Python

import logging
import gi
gi.require_version("Gtk", "3.0")
from gi.repository import Gtk, Gdk
class Prompt:
def __init__(self, screen):
self.screen = screen
self.gtk = screen.gtk
self.window_title = 'KlipperScreen'
self.text = self.header = ""
self.buttons = []
self.id = 1
self.prompt = None
def _key_press_event(self, widget, event):
keyval_name = Gdk.keyval_name(event.keyval)
if keyval_name in ["Escape", "BackSpace"]:
self.close()
def decode(self, data):
logging.info(f'{data}')
if data.startswith('prompt_begin'):
self.header = data.replace('prompt_begin', '')
if self.header:
self.window_title = self.header
self.text = ""
self.buttons = []
return
elif data.startswith('prompt_text'):
self.text = data.replace('prompt_text ', '')
return
elif data.startswith('prompt_button ') or data.startswith('prompt_footer_button'):
data = data.replace('prompt_button ', '')
data = data.replace('prompt_footer_button ', '')
params = data.split('|')
if len(params) == 1:
params.append(self.text)
if len(params) > 3:
logging.error('Unexpected number of parameters on the button')
return
self.set_button(*params)
return
elif data == 'prompt_show':
if not self.prompt:
self.show()
return
elif data == 'prompt_end':
self.end()
else:
# Not implemented:
# prompt_button_group_start
# prompt_button_group_end
logging.debug(f'Unknown option {data}')
def set_button(self, name, gcode, style='default'):
logging.info(f'{name} {self.id} {gcode} {style}')
self.buttons.append(
{"name": name, "response": self.id, 'gcode': gcode, 'style': f'dialog-{style}'}
)
self.id += 1
def show(self):
logging.info(f'Prompt {self.header} {self.text} {self.buttons}')
title = Gtk.Label(wrap=True, hexpand=True, vexpand=False, halign=Gtk.Align.CENTER, label=self.header)
close = self.gtk.Button("cancel", scale=self.gtk.bsidescale)
close.set_hexpand(False)
close.set_vexpand(False)
close.connect("clicked", self.close)
scroll = self.gtk.ScrolledWindow(steppers=False)
scroll.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC)
scroll.add(Gtk.Label(label=self.text, wrap=True, hexpand=True, vexpand=True))
content = Gtk.Grid()
if not self.screen.windowed:
content.attach(title, 0, 0, 1, 1)
content.attach(close, 1, 0, 1, 1)
content.attach(scroll, 0, 1, 2, 1)
self.prompt = self.gtk.Dialog(
self.window_title,
self.buttons,
content,
self.response,
)
self.prompt.connect("key-press-event", self._key_press_event)
self.prompt.connect("delete-event", self.close)
self.screen.wake_screen()
def response(self, dialog, response_id):
for button in self.buttons:
if button['response'] == response_id:
self.screen._send_action(None, "printer.gcode.script", {'script': button['gcode']})
def close(self, *args):
script = {'script': 'RESPOND type="command" msg="action:prompt_end"'}
self.screen._send_action(None, "printer.gcode.script", script)
def end(self):
if self.prompt is not None:
self.gtk.remove_dialog(self.prompt)
self.prompt = None
self.screen.prompt = None