101 lines
2.2 KiB
Python
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("")
|
|
|
|
|
|
|