jk_console 0.2024.4.24__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. jk_console-0.2024.4.24/PKG-INFO +196 -0
  2. jk_console-0.2024.4.24/README.md +180 -0
  3. jk_console-0.2024.4.24/jk_console/CharacterBuffer.py +204 -0
  4. jk_console-0.2024.4.24/jk_console/Console.py +1086 -0
  5. jk_console-0.2024.4.24/jk_console/ConsoleBuffer.py +214 -0
  6. jk_console-0.2024.4.24/jk_console/ConsoleBufferRGB.py +264 -0
  7. jk_console-0.2024.4.24/jk_console/ConsoleBufferRGB2.py +479 -0
  8. jk_console-0.2024.4.24/jk_console/ConsoleBufferRGB_Mixins.py +220 -0
  9. jk_console-0.2024.4.24/jk_console/ConsoleBufferWO.py +296 -0
  10. jk_console-0.2024.4.24/jk_console/ConsoleBuffer_Mixins.py +198 -0
  11. jk_console-0.2024.4.24/jk_console/ConsoleGraphics.py +49 -0
  12. jk_console-0.2024.4.24/jk_console/EventCollector.py +142 -0
  13. jk_console-0.2024.4.24/jk_console/FramedBoxSettingsRGB.py +32 -0
  14. jk_console-0.2024.4.24/jk_console/IntRGB.py +139 -0
  15. jk_console-0.2024.4.24/jk_console/RGBColorMapper.py +74 -0
  16. jk_console-0.2024.4.24/jk_console/Rect.py +156 -0
  17. jk_console-0.2024.4.24/jk_console/SimpleTable.py +481 -0
  18. jk_console-0.2024.4.24/jk_console/_Rect.py +130 -0
  19. jk_console-0.2024.4.24/jk_console/__init__.py +23 -0
  20. jk_console-0.2024.4.24/jk_console/demo/Effect1.py +104 -0
  21. jk_console-0.2024.4.24/jk_console/demo/__init__.py +8 -0
  22. jk_console-0.2024.4.24/jk_console/impl/__init__.py +0 -0
  23. jk_console-0.2024.4.24/jk_console/impl/_parseCSS.py +110 -0
  24. jk_console-0.2024.4.24/jk_console/readchar.py +78 -0
  25. jk_console-0.2024.4.24/jk_console/readchar_linux.py +78 -0
  26. jk_console-0.2024.4.24/jk_console/readchar_windows.py +33 -0
  27. jk_console-0.2024.4.24/jk_console/viewport/Rectangle.py +396 -0
  28. jk_console-0.2024.4.24/jk_console/viewport/ViewPort.py +175 -0
  29. jk_console-0.2024.4.24/jk_console/viewport/ViewPortBuffer.py +251 -0
  30. jk_console-0.2024.4.24/jk_console/viewport/ViewPortBuffer2.py +319 -0
  31. jk_console-0.2024.4.24/jk_console/viewport/ViewPortCell.py +33 -0
  32. jk_console-0.2024.4.24/jk_console/viewport/ViewPortRGB.py +97 -0
  33. jk_console-0.2024.4.24/jk_console/viewport/ViewPortRenderer.py +73 -0
  34. jk_console-0.2024.4.24/jk_console/viewport/__init__.py +14 -0
  35. jk_console-0.2024.4.24/pyproject.toml +56 -0
@@ -0,0 +1,196 @@
1
+ Metadata-Version: 2.1
2
+ Name: jk_console
3
+ Version: 0.2024.4.24
4
+ Summary: This python module provides a variety of essential functions for implementing versatile programs using the console. (Please have a look at the documentation for details.)
5
+ Keywords: console,terminal,colors,stdin
6
+ Author-email: Jürgen Knauth <pubsrc@binary-overflow.de>
7
+ Maintainer-email: Jürgen Knauth <pubsrc@binary-overflow.de>
8
+ Requires-Python: >=3.8
9
+ Description-Content-Type: text/markdown
10
+ Classifier: Development Status :: 5 - Production/Stable
11
+ Classifier: License :: OSI Approved :: Apache Software License
12
+ Classifier: Programming Language :: Python :: 3
13
+ Requires-Dist: msvcrt; platform_system=='Windows'
14
+ Requires-Dist: jk_terminal_essentials >= 0.2024.2.2
15
+
16
+ jk_console
17
+ ==========
18
+
19
+ Introduction
20
+ ------------
21
+
22
+ This python module provides a variety of essential functionality for implementing versatile programs using the console. This includes:
23
+
24
+ * reading single key stokes from STDIN
25
+ * modifying cursor color
26
+ * retrieving the dimensions of the console
27
+ * placeing the cursor at (almost) any position within the console
28
+
29
+ Information about this module can be found here:
30
+
31
+ * [github.org](https://github.com/jkpubsrc/python-module-jk-console)
32
+ * [pypi.python.org](https://pypi.python.org/pypi/jk_console)
33
+
34
+ Why this module?
35
+ ----------------
36
+
37
+ If you want to write some more sophisticated command line programs it will get complicated. Python does not provide any support for
38
+ reading single key strokes, colorizing output as well as more detailed control of the cursor is nothing Python takes care of. This
39
+ module fills the gap.
40
+
41
+ Limitations of this module
42
+ --------------------------
43
+
44
+ Special keys like function keys, cursor keys and similar are communicated by console windows using escape codes. Whenever you press these
45
+ keys a sequence of characters is sent by the console.
46
+
47
+ Reading these kind of key strokes from console is therefore based on reading multiple keys. Unfortunately you cannot know how many keys are
48
+ sent. Therefor you need to know how to interpret these sequences as they greatly differ in length.
49
+
50
+ The `Console` class contains a register of these sequences for common key strokes. Whenever such a key is read the class tries to parse it.
51
+ If a known keystroke is encountered it is returned as a complete string. This way `readKey()` will try to always return a single key - even
52
+ if this key is represented by multiple characters.
53
+
54
+ That implies: The `Console` class needs to know about all these character sequences. That means: **All special keys this module should
55
+ recognize must be hard coded into this module.** Whenever a known sequence is encountered it can be read completely and be recognized
56
+ as a single key stroke event. (And if the sequence is not known this mechanism will not work properly.)
57
+
58
+ This module has been adapted to recognize all common special keys a user could press in a standard Linux console window. This has been tested
59
+ on Ubuntu Linux. Please have in mind that this might differ from other platforms or even from other console implementations. At the moment
60
+ of writing these lines I as the author of `Console` have no information about how well other platforms and terminal implementations follow
61
+ these standards. I have no possibility to test this on other platforms at this point in time. So if you encounter any difficulties or have
62
+ more information please contact me. I'll gladly extend this module.
63
+
64
+ How to use this module
65
+ ----------------------
66
+
67
+ ### Import this module
68
+
69
+ Please include this module into your application using the following code:
70
+
71
+ ```python
72
+ from jk_console import Console
73
+ ```
74
+
75
+ ### Reading single key strokes
76
+
77
+ In order to read a single key stroke invoke the following command:
78
+
79
+ ```python
80
+ key = Console.Input.readKey()
81
+ ```
82
+
83
+ The variable `key` will then contain either a single character if a regular key or a set of characters if some specicial key has been pressed.
84
+
85
+ Please note that Ctrl+C is not catched by the application if you invoke `readKey()` but returned as a regular key stroke.
86
+
87
+ Please see *Limitations of this module* for information about when decoding key strokes might fail.
88
+
89
+ ### Converting key strokes to text
90
+
91
+ In order to get a human readable representation of a key stroke use the following code:
92
+
93
+ ```python
94
+ keyStr = Console.Input.ALL_KEYS_TO_KEY_NAME.get(key)
95
+ ```
96
+
97
+ ### Clearing the console screen
98
+
99
+ You can clear the current console screen by invoking the following method:
100
+
101
+ ```python
102
+ Console.clear()
103
+ ```
104
+
105
+ ### Move cursor to a specific position on the console screen
106
+
107
+ You can move the cursor to a specific line and column number in a console using the following code:
108
+
109
+ ```python
110
+ Console.moveCursorTo(lineNo, colNo)
111
+ ```
112
+
113
+ Please note that row and column numbers are **always** counted starting at zero. So `(0, 0)` specifies the upper left corner of the console.
114
+
115
+ ### Print text at a specific position on the console screen
116
+
117
+ You can print some text at a specific line and column number using the following code:
118
+
119
+ ```python
120
+ Console.printAt(lineNo, colNo, someText)
121
+ ```
122
+
123
+ Please note that row and column numbers are **always** counted starting at zero. So `(0, 0)` specifies the upper left corner of the console.
124
+
125
+ Please also note that this command will move the cursor as well. This implies that printing at the very end of a line will cause a wrap around
126
+ and the cursor will be moved to the beginning of the next line. If that happens at the very last character of your console window this will
127
+ cause the console to add a new line and thus scrolling all existing text one line upwards.
128
+
129
+ ### Get current cursor position
130
+
131
+ In order to retrieve the current cursor position invoke `getCursorPosition()`:
132
+
133
+ ```python
134
+ lineNo, colNo = Console.getCursorPosition()
135
+ ```
136
+
137
+ Please note that row and column numbers are **always** counted starting at zero. So `(0, 0)` specifies the upper left corner of the console.
138
+
139
+ ### Get the size of the console
140
+
141
+ In order to retrieve the dimensions of your console view port invoke `getSize()` and/or `width()` and `height()`:
142
+
143
+ ```python
144
+ height, width = Console.getSize()
145
+ ```
146
+
147
+ ### Use color methods
148
+
149
+ You can perfom colorized output using the predefined constants for foreground and background.
150
+
151
+ Example:
152
+
153
+ ```python
154
+ print(Console.ForeGround.CYAN + "Hello World!" + Console.RESET)
155
+ ```
156
+
157
+ Alternatively you can invoke one of these color methods:
158
+
159
+ * `rgb256(r, g, b)` - which will create a text string representing your color using `int` values in the range of [0..255]
160
+ * `rgb1(r, g, b)` - which will create a text string representing your color using `float` values in the range of [0..1]
161
+ * `hsl1(h, s, l)` - which will create a text string representing your color using `float` values in the range of [0..1]
162
+
163
+ Example:
164
+
165
+ ```python
166
+ print(Console.BackGround.rgb256(128, 0, 0) + "Hello World!" + Console.RESET)
167
+ ```
168
+ Please note that the current color settings are valid for all future printing to the console.
169
+
170
+ ### Resetting color
171
+
172
+ In order to reset color settings use the folloiwing code:
173
+
174
+ ```python
175
+ print(Console.RESET)
176
+ ```
177
+
178
+ Contact Information
179
+ -------------------
180
+
181
+ This is Open Source code. That not only gives you the possibility of freely using this code it also
182
+ allows you to contribute. Feel free to contact the author(s) of this software listed below, either
183
+ for comments, collaboration requests, suggestions for improvement or reporting bugs:
184
+
185
+ * Jürgen Knauth: jknauth@uni-goettingen.de, pubsrc@binary-overflow.de
186
+
187
+ License
188
+ -------
189
+
190
+ This software is provided under the following license:
191
+
192
+ * Apache Software License 2.0
193
+
194
+
195
+
196
+
@@ -0,0 +1,180 @@
1
+ jk_console
2
+ ==========
3
+
4
+ Introduction
5
+ ------------
6
+
7
+ This python module provides a variety of essential functionality for implementing versatile programs using the console. This includes:
8
+
9
+ * reading single key stokes from STDIN
10
+ * modifying cursor color
11
+ * retrieving the dimensions of the console
12
+ * placeing the cursor at (almost) any position within the console
13
+
14
+ Information about this module can be found here:
15
+
16
+ * [github.org](https://github.com/jkpubsrc/python-module-jk-console)
17
+ * [pypi.python.org](https://pypi.python.org/pypi/jk_console)
18
+
19
+ Why this module?
20
+ ----------------
21
+
22
+ If you want to write some more sophisticated command line programs it will get complicated. Python does not provide any support for
23
+ reading single key strokes, colorizing output as well as more detailed control of the cursor is nothing Python takes care of. This
24
+ module fills the gap.
25
+
26
+ Limitations of this module
27
+ --------------------------
28
+
29
+ Special keys like function keys, cursor keys and similar are communicated by console windows using escape codes. Whenever you press these
30
+ keys a sequence of characters is sent by the console.
31
+
32
+ Reading these kind of key strokes from console is therefore based on reading multiple keys. Unfortunately you cannot know how many keys are
33
+ sent. Therefor you need to know how to interpret these sequences as they greatly differ in length.
34
+
35
+ The `Console` class contains a register of these sequences for common key strokes. Whenever such a key is read the class tries to parse it.
36
+ If a known keystroke is encountered it is returned as a complete string. This way `readKey()` will try to always return a single key - even
37
+ if this key is represented by multiple characters.
38
+
39
+ That implies: The `Console` class needs to know about all these character sequences. That means: **All special keys this module should
40
+ recognize must be hard coded into this module.** Whenever a known sequence is encountered it can be read completely and be recognized
41
+ as a single key stroke event. (And if the sequence is not known this mechanism will not work properly.)
42
+
43
+ This module has been adapted to recognize all common special keys a user could press in a standard Linux console window. This has been tested
44
+ on Ubuntu Linux. Please have in mind that this might differ from other platforms or even from other console implementations. At the moment
45
+ of writing these lines I as the author of `Console` have no information about how well other platforms and terminal implementations follow
46
+ these standards. I have no possibility to test this on other platforms at this point in time. So if you encounter any difficulties or have
47
+ more information please contact me. I'll gladly extend this module.
48
+
49
+ How to use this module
50
+ ----------------------
51
+
52
+ ### Import this module
53
+
54
+ Please include this module into your application using the following code:
55
+
56
+ ```python
57
+ from jk_console import Console
58
+ ```
59
+
60
+ ### Reading single key strokes
61
+
62
+ In order to read a single key stroke invoke the following command:
63
+
64
+ ```python
65
+ key = Console.Input.readKey()
66
+ ```
67
+
68
+ The variable `key` will then contain either a single character if a regular key or a set of characters if some specicial key has been pressed.
69
+
70
+ Please note that Ctrl+C is not catched by the application if you invoke `readKey()` but returned as a regular key stroke.
71
+
72
+ Please see *Limitations of this module* for information about when decoding key strokes might fail.
73
+
74
+ ### Converting key strokes to text
75
+
76
+ In order to get a human readable representation of a key stroke use the following code:
77
+
78
+ ```python
79
+ keyStr = Console.Input.ALL_KEYS_TO_KEY_NAME.get(key)
80
+ ```
81
+
82
+ ### Clearing the console screen
83
+
84
+ You can clear the current console screen by invoking the following method:
85
+
86
+ ```python
87
+ Console.clear()
88
+ ```
89
+
90
+ ### Move cursor to a specific position on the console screen
91
+
92
+ You can move the cursor to a specific line and column number in a console using the following code:
93
+
94
+ ```python
95
+ Console.moveCursorTo(lineNo, colNo)
96
+ ```
97
+
98
+ Please note that row and column numbers are **always** counted starting at zero. So `(0, 0)` specifies the upper left corner of the console.
99
+
100
+ ### Print text at a specific position on the console screen
101
+
102
+ You can print some text at a specific line and column number using the following code:
103
+
104
+ ```python
105
+ Console.printAt(lineNo, colNo, someText)
106
+ ```
107
+
108
+ Please note that row and column numbers are **always** counted starting at zero. So `(0, 0)` specifies the upper left corner of the console.
109
+
110
+ Please also note that this command will move the cursor as well. This implies that printing at the very end of a line will cause a wrap around
111
+ and the cursor will be moved to the beginning of the next line. If that happens at the very last character of your console window this will
112
+ cause the console to add a new line and thus scrolling all existing text one line upwards.
113
+
114
+ ### Get current cursor position
115
+
116
+ In order to retrieve the current cursor position invoke `getCursorPosition()`:
117
+
118
+ ```python
119
+ lineNo, colNo = Console.getCursorPosition()
120
+ ```
121
+
122
+ Please note that row and column numbers are **always** counted starting at zero. So `(0, 0)` specifies the upper left corner of the console.
123
+
124
+ ### Get the size of the console
125
+
126
+ In order to retrieve the dimensions of your console view port invoke `getSize()` and/or `width()` and `height()`:
127
+
128
+ ```python
129
+ height, width = Console.getSize()
130
+ ```
131
+
132
+ ### Use color methods
133
+
134
+ You can perfom colorized output using the predefined constants for foreground and background.
135
+
136
+ Example:
137
+
138
+ ```python
139
+ print(Console.ForeGround.CYAN + "Hello World!" + Console.RESET)
140
+ ```
141
+
142
+ Alternatively you can invoke one of these color methods:
143
+
144
+ * `rgb256(r, g, b)` - which will create a text string representing your color using `int` values in the range of [0..255]
145
+ * `rgb1(r, g, b)` - which will create a text string representing your color using `float` values in the range of [0..1]
146
+ * `hsl1(h, s, l)` - which will create a text string representing your color using `float` values in the range of [0..1]
147
+
148
+ Example:
149
+
150
+ ```python
151
+ print(Console.BackGround.rgb256(128, 0, 0) + "Hello World!" + Console.RESET)
152
+ ```
153
+ Please note that the current color settings are valid for all future printing to the console.
154
+
155
+ ### Resetting color
156
+
157
+ In order to reset color settings use the folloiwing code:
158
+
159
+ ```python
160
+ print(Console.RESET)
161
+ ```
162
+
163
+ Contact Information
164
+ -------------------
165
+
166
+ This is Open Source code. That not only gives you the possibility of freely using this code it also
167
+ allows you to contribute. Feel free to contact the author(s) of this software listed below, either
168
+ for comments, collaboration requests, suggestions for improvement or reporting bugs:
169
+
170
+ * Jürgen Knauth: jknauth@uni-goettingen.de, pubsrc@binary-overflow.de
171
+
172
+ License
173
+ -------
174
+
175
+ This software is provided under the following license:
176
+
177
+ * Apache Software License 2.0
178
+
179
+
180
+
@@ -0,0 +1,204 @@
1
+
2
+
3
+
4
+
5
+ from .Console import *
6
+ from .ConsoleBuffer import *
7
+ from .Rect import *
8
+
9
+
10
+
11
+
12
+
13
+
14
+ class CharacterBuffer(object):
15
+
16
+ class _Cell(object):
17
+
18
+ def __init__(self, bgColor:str):
19
+ self.col = bgColor
20
+ self.c = " "
21
+ #
22
+
23
+ def clear(self, bgColor:str):
24
+ self.col = bgColor
25
+ self.c = " "
26
+ #
27
+
28
+ #
29
+
30
+ def __init__(self, width:int, height:int, bgColor:str = Console.RESET):
31
+ self.__bgColor = bgColor
32
+ self.__width = width
33
+ self.__height = height
34
+ self.__widthM1 = self.__width - 1
35
+ self.__heightM1 = self.__height - 1
36
+ self.__numberOfCells = self.__width * self.__height
37
+
38
+ self.__lineNumbers = tuple(range(0, self.__height))
39
+ self.__columnNumbers = tuple(range(0, self.__width))
40
+
41
+ self._currentBuffer = [ [CharacterBuffer._Cell(bgColor) for x in self.__columnNumbers] for y in self.__lineNumbers]
42
+ #
43
+
44
+ @property
45
+ def bounds(self):
46
+ return Rect(0, 0, self.__width, self.__height)
47
+ #
48
+
49
+ @property
50
+ def size(self):
51
+ return self.__width, self.__height
52
+ #
53
+
54
+ @property
55
+ def width(self):
56
+ return self.__width
57
+ #
58
+
59
+ @property
60
+ def height(self):
61
+ return self.__height
62
+ #
63
+
64
+ def clear(self):
65
+ bgColor = self.__bgColor
66
+ for y in self.__lineNumbers:
67
+ for x in self.__columnNumbers:
68
+ self._currentBuffer[y][x].clear(bgColor)
69
+ #
70
+
71
+ def set(self, x:int, y:int, color:str, character:str):
72
+ assert len(character) == 1
73
+
74
+ cell = self._currentBuffer[y][x]
75
+ if color != None:
76
+ cell.c = character
77
+ if color != None:
78
+ cell.col = color
79
+ #
80
+
81
+ def fill(self, x:int, y:int, w:int, h:int, color:str, character:str):
82
+ assert len(character) == 1
83
+
84
+ for iy in range(y, y + h):
85
+ row = self._currentBuffer[iy]
86
+ for ix in range(x, x + w):
87
+ cell = row[ix]
88
+ cell.c = character
89
+ if color != None:
90
+ cell.col = color
91
+ #
92
+
93
+ def printText(self, x:int, y:int, color:str, text:str):
94
+ assert len(text) > 0
95
+
96
+ i = 0
97
+ for c in text:
98
+ cell = self._currentBuffer[y][x + i]
99
+ cell.c = c
100
+ if color != None:
101
+ cell.col = color
102
+ i += 1
103
+ #
104
+
105
+ def copyToCharacterBuffer1(self, srcX:int, srcY:int, width:int, height:int, destX:int, destY:int, otherBuffer):
106
+ assert isinstance(otherBuffer, CharacterBuffer)
107
+
108
+ rSrc = Rect(srcX, srcY, width, height)
109
+ assert self.bounds.isOtherRectInRect(rSrc)
110
+ rDest = Rect(destX, destY, width, height)
111
+ assert otherBuffer.bounds.isOtherRectInRect(rDest)
112
+
113
+ deltaX = destX - srcX
114
+ deltaY = destY - srcY
115
+
116
+ # ----------------
117
+
118
+ for srcIY in range(srcY, srcY + height):
119
+ srcRow = self._currentBuffer[srcIY]
120
+ destRow = otherBuffer._currentBuffer[srcIY + deltaY]
121
+ for srcIX in range(srcX, srcX + width):
122
+ srcCell = srcRow[srcIX]
123
+ destCell = destRow[srcIX + deltaX]
124
+ destCell.c = srcCell.c
125
+ destCell.col = srcCell.col
126
+ #
127
+
128
+ def copyToCharacterBuffer0(self, destX:int, destY:int, otherBuffer):
129
+ assert isinstance(otherBuffer, CharacterBuffer)
130
+
131
+ width = self.__width
132
+ height = self.__height
133
+
134
+ rDest = Rect(destX, destY, width, height)
135
+ assert otherBuffer.bounds.isOtherRectInRect(rDest)
136
+
137
+ deltaX = destX
138
+ deltaY = destY
139
+ srcX = 0
140
+ srcY = 0
141
+
142
+ # ----------------
143
+
144
+ for srcIY in range(srcY, srcY + height):
145
+ srcRow = self._currentBuffer[srcIY]
146
+ destRow = otherBuffer._currentBuffer[srcIY + deltaY]
147
+ for srcIX in range(srcX, srcX + width):
148
+ srcCell = srcRow[srcIX]
149
+ destCell = destRow[srcIX + deltaX]
150
+ destCell.c = srcCell.c
151
+ destCell.col = srcCell.col
152
+ #
153
+
154
+ def copyToConsoleBuffer1(self, srcX:int, srcY:int, width:int, height:int, destX:int, destY:int, otherBuffer:ConsoleBuffer):
155
+ rSrc = Rect(srcX, srcY, width, height)
156
+ assert self.bounds.isOtherRectInRect(rSrc)
157
+ rDest = Rect(destX, destY, width, height)
158
+ assert otherBuffer.bounds.isOtherRectInRect(rDest)
159
+
160
+ deltaX = destX - srcX
161
+ deltaY = destY - srcY
162
+
163
+ # ----------------
164
+
165
+ for srcIY in range(srcY, srcY + height):
166
+ srcRow = self._currentBuffer[srcIY]
167
+ destRow = otherBuffer._currentBuffer[srcIY + deltaY]
168
+ for srcIX in range(srcX, srcX + width):
169
+ srcCell = srcRow[srcIX]
170
+ destCell = destRow[srcIX + deltaX]
171
+ destCell.c = srcCell.c
172
+ destCell.col = srcCell.col
173
+ destCell.bChanged = True
174
+ #
175
+
176
+ def copyToConsoleBuffer0(self, destX:int, destY:int, otherBuffer:ConsoleBuffer):
177
+ width = self.__width
178
+ height = self.__height
179
+
180
+ rDest = Rect(destX, destY, width, height)
181
+ assert otherBuffer.bounds.isOtherRectInRect(rDest)
182
+
183
+ deltaX = destX
184
+ deltaY = destY
185
+ srcX = 0
186
+ srcY = 0
187
+
188
+ # ----------------
189
+
190
+ for srcIY in range(srcY, srcY + height):
191
+ srcRow = self._currentBuffer[srcIY]
192
+ destRow = otherBuffer._currentBuffer[srcIY + deltaY]
193
+ for srcIX in range(srcX, srcX + width):
194
+ srcCell = srcRow[srcIX]
195
+ destCell = destRow[srcIX + deltaX]
196
+ destCell.c = srcCell.c
197
+ destCell.col = srcCell.col
198
+ destCell.bChanged = True
199
+ #
200
+
201
+ #
202
+
203
+
204
+