--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/controls/CustomIntCtrl.py Fri Sep 15 20:01:21 2017 +0300
@@ -0,0 +1,88 @@
+# This file is part of Beremiz, a Integrated Development Environment for +# programming IEC 61131-3 automates supporting plcopen standard and CanFestival. +# Copyright (C) 2017: Andrey Skvortsov +# See COPYING file for copyrights details. +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +from wx.lib.intctrl import IntCtrl +class CustomIntUpdatedEvent(wx.PyCommandEvent): + def __init__(self, id, value=0, object=None): + wx.PyCommandEvent.__init__(self, CustomIntCtrl.wxEVT_COMMAND_CUSTOM_INT_UPDATED, id) + self.SetEventObject(object) + """Retrieve the value of the control at the time + this event was generated.""" +class CustomIntCtrl(wx.lib.intctrl.IntCtrl): + This class provides a control that takes and returns long as + value, and provides bounds support and optional value limiting. + It handles entering negative numbers more user-friendly than + original wx.lib.intctrl.IntCtrl. + It applies limits as focus is changed to other control and + sends event afterwards to signal that editing is done. + # Used to trap events indicating that the current + # integer value of the control has been changed. + wxEVT_COMMAND_CUSTOM_INT_UPDATED = wx.NewEventType() + EVT_CUSTOM_INT = wx.PyEventBinder(wxEVT_COMMAND_CUSTOM_INT_UPDATED, 1) + def __init__(self, *args, **kwargs): + wx.lib.intctrl.IntCtrl.__init__(self, *args, **kwargs) + self.Bind(wx.EVT_KILL_FOCUS, self.UpdateValue) + self.SetLongAllowed(True) + Returns integer (long) value of the control, + but handles entering negative numbers + s = wx.TextCtrl.GetValue(self) + return self._fromGUI(s) + """Returns string value of TextCtrl""" + return wx.TextCtrl.GetValue(self) + def UpdateValue(self, event): + self.GetEventHandler().ProcessEvent( + CustomIntUpdatedEvent(self.GetId(), self.GetValue(), self)) --- a/controls/__init__.py Fri Sep 15 19:53:49 2017 +0300
+++ b/controls/__init__.py Fri Sep 15 20:01:21 2017 +0300
@@ -28,6 +28,7 @@
from CustomGrid import CustomGrid
from CustomTable import CustomTable
from CustomTree import CustomTree
+from CustomIntCtrl import CustomIntCtrl from DebugVariablePanel import DebugVariablePanel
from DurationCellEditor import DurationCellEditor
from LibraryPanel import LibraryPanel
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/tools/test_CustomIntCtrl.py Fri Sep 15 20:01:21 2017 +0300
@@ -0,0 +1,136 @@
+# This file is part of Beremiz, a Integrated Development Environment for +# programming IEC 61131-3 automates supporting plcopen standard and CanFestival. +# Copyright (C) 2017: Andrey Skvortsov +# See COPYING file for copyrights details. +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +import controls.CustomIntCtrl +class TestCustomIntCtrl(unittest.TestCase): + self.frame = wx.Frame(None) + wx.CallAfter(self.app.Exit) + def testMaxLimit(self): + """Test working upper bound""" + self.int_ctrl.SetValue(self.max_val + 100) + self.txt_ctrl.SetFocus() + self.assertEqual(self.int_ctrl.GetValue(), self.max_val) + def testMinLimit(self): + """Test working lower bound""" + self.int_ctrl.SetValue(self.min_val - 100) + self.txt_ctrl.SetFocus() + self.assertEqual(self.int_ctrl.GetValue(), self.min_val) + def testCorrectValue(self): + """Test case if no limiting is necessary""" + val = (self.max_val + self.min_val) / 2 + self.int_ctrl.SetValue(val) + self.txt_ctrl.SetFocus() + self.assertEqual(self.int_ctrl.GetValue(), val) + def testEventBinding(self): + """Test event sending after edit and bound checks are done""" + self.event_happend = False + def EventHandler(event): + self.event_happend = True + self.int_ctrl.Bind(controls.CustomIntCtrl.EVT_CUSTOM_INT, EventHandler) + val = (self.max_val + self.min_val) / 2 + self.int_ctrl.SetValue(val) + self.txt_ctrl.SetFocus() + self.txt_ctrl.SetFocus() + self.assertEqual(self.int_ctrl.GetValue(), val) + self.assertTrue(self.event_happend) + def testLongNumbers(self): + """Test support of long integer""" + self.int_ctrl.SetMax(val) + self.int_ctrl.SetValue(val) + self.txt_ctrl.SetFocus() + self.assertEqual(val, val) + def ProcessEvents(self): + vs = wx.BoxSizer(wx.VERTICAL) + self.int_ctrl = controls.CustomIntCtrl(self.frame) + self.txt_ctrl = wx.TextCtrl(self.frame) + vs.Add(self.int_ctrl, 0, wx.ALIGN_CENTRE | wx.ALL, 5) + vs.Add(self.txt_ctrl, 0, wx.ALIGN_CENTRE | wx.ALL, 5) + self.frame.SetSizer(vs) + self.int_ctrl.SetBounds(self.min_val, self.max_val) +if __name__ == '__main__':