Files
SCam/mathentry.py
2023-10-07 20:29:33 +02:00

101 lines
2.2 KiB
Python

import wx
from eval import arithmetic_eval
from utils import typename
class MathEntry(wx.TextCtrl):
def __init__(self, *args, value="", **kwargs):
if "style" in kwargs:
kwargs["style"] |= wx.TE_PROCESS_ENTER
else:
kwargs["style"] = wx.TE_PROCESS_ENTER
self.value_type = type(value)
value = str(value)
wx.TextCtrl.__init__(self, *args, value=value, **kwargs)
self._alarm = False
self._last_good_value = self.GetValue()
self.Bind(wx.EVT_TEXT_ENTER, self.on_enter)
self.Bind(wx.EVT_KEY_UP, self.on_escape)
def GetValue(self):
val = super().GetValue()
if val == "": #TODO?
return None
if val == "None": #TODO?
return None
try:
val = self.value_type(val)
except (ValueError, TypeError) as e:
print(e)
return val
def SetValue(self, val):
self.value_type = type(val)
val = str(val)
super().SetValue(val)
def on_enter(self, event):
val = super().GetValue()
self._unset_alarm()
try:
val = arithmetic_eval(val)
self.value_type = type(val)
except SyntaxError as e:
en = typename(e)
msg = e.args[0]
msg = f"{en}: {msg}"
self._set_alarm(msg)
self.SetInsertionPoint(e.offset)
except Exception as e:
en = typename(e)
msg = f"{en}: {e}"
self._set_alarm(msg)
self.SetInsertionPointEnd()
else:
self.SetValue(val)
self._last_good_value = val
event.Skip()
def on_escape(self, event):
code = event.GetKeyCode()
if code != wx.WXK_ESCAPE:
event.Skip()
return
if self._alarm:
self.SetValue(self._last_good_value)
self._unset_alarm()
def _set_alarm(self, msg):
self._alarm = True
self.SetToolTip(msg)
self.SetForegroundColour(wx.RED)
def _unset_alarm(self):
self._alarm = False
self.SetToolTip(None)
self.SetForegroundColour(wx.NullColour)
def clear(self):
super().SetValue("")