boacon 0.0.1__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.
- boacon-0.0.1/.gitignore +1 -0
- boacon-0.0.1/LICENSE +21 -0
- boacon-0.0.1/PKG-INFO +145 -0
- boacon-0.0.1/README.md +130 -0
- boacon-0.0.1/pyproject.toml +49 -0
- boacon-0.0.1/src/boacon/__init__.py +360 -0
- boacon-0.0.1/src/boacon/c_BCChar.py +140 -0
- boacon-0.0.1/src/boacon/c_BCCoord.py +185 -0
- boacon-0.0.1/src/boacon/c_BCCursesAttrFunc.py +14 -0
- boacon-0.0.1/src/boacon/c_BCError.py +7 -0
- boacon-0.0.1/src/boacon/c_BCPane.py +93 -0
- boacon-0.0.1/src/boacon/c_BCPostDrawArgs.py +50 -0
- boacon-0.0.1/src/boacon/c_BCSetChrFunc.py +19 -0
- boacon-0.0.1/src/boacon/c_BCSignal.py +39 -0
- boacon-0.0.1/src/boacon/c_BCSignalEmitter.py +47 -0
- boacon-0.0.1/src/boacon/c_BCState.py +14 -0
- boacon-0.0.1/src/boacon/c_BCStr.py +307 -0
- boacon-0.0.1/src/boacon/g_attr.py +42 -0
- boacon-0.0.1/src/boacon/g_key.py +731 -0
- boacon-0.0.1/src/boacon/p_BCConsolePane.py +175 -0
boacon-0.0.1/.gitignore
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
**/__pycache__
|
boacon-0.0.1/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Zachary Aaron Combs
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
boacon-0.0.1/PKG-INFO
ADDED
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: boacon
|
|
3
|
+
Version: 0.0.1
|
|
4
|
+
Project-URL: Homepage, https://github.com/blackrookgames/boacon
|
|
5
|
+
Project-URL: Issues, https://github.com/blackrookgames/boacon/issues
|
|
6
|
+
Author-email: Black Rook Games <blackrookgames@gmail.com>
|
|
7
|
+
License-Expression: MIT
|
|
8
|
+
License-File: LICENSE
|
|
9
|
+
Classifier: Operating System :: OS Independent
|
|
10
|
+
Classifier: Programming Language :: Python :: 3
|
|
11
|
+
Requires-Python: >=3.13
|
|
12
|
+
Requires-Dist: numpy>=2.4.1
|
|
13
|
+
Requires-Dist: windows-curses>=2.4.1; sys_platform == 'win32'
|
|
14
|
+
Description-Content-Type: text/markdown
|
|
15
|
+
|
|
16
|
+
<a id="boacon"></a>
|
|
17
|
+
|
|
18
|
+
# boacon
|
|
19
|
+
|
|
20
|
+
<a id="boacon.init"></a>
|
|
21
|
+
|
|
22
|
+
#### init
|
|
23
|
+
|
|
24
|
+
```python
|
|
25
|
+
def init()
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
<a id="boacon.final"></a>
|
|
29
|
+
|
|
30
|
+
#### final
|
|
31
|
+
|
|
32
|
+
```python
|
|
33
|
+
def final()
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
<a id="boacon.state"></a>
|
|
37
|
+
|
|
38
|
+
#### state
|
|
39
|
+
|
|
40
|
+
```python
|
|
41
|
+
def state()
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
State of the boacon system
|
|
45
|
+
|
|
46
|
+
<a id="boacon.panes"></a>
|
|
47
|
+
|
|
48
|
+
#### panes
|
|
49
|
+
|
|
50
|
+
```python
|
|
51
|
+
def panes()
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
Panes that are being displayed
|
|
55
|
+
|
|
56
|
+
:raise BCError:
|
|
57
|
+
boacon system is not currently running
|
|
58
|
+
|
|
59
|
+
<a id="boacon.on_init"></a>
|
|
60
|
+
|
|
61
|
+
#### on\_init
|
|
62
|
+
|
|
63
|
+
```python
|
|
64
|
+
def on_init()
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
Emitted after the boacon system is initialized
|
|
68
|
+
|
|
69
|
+
<a id="boacon.on_final"></a>
|
|
70
|
+
|
|
71
|
+
#### on\_final
|
|
72
|
+
|
|
73
|
+
```python
|
|
74
|
+
def on_final()
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
Emitted before the boacon system is finalized
|
|
78
|
+
|
|
79
|
+
<a id="boacon.postdraw"></a>
|
|
80
|
+
|
|
81
|
+
#### postdraw
|
|
82
|
+
|
|
83
|
+
```python
|
|
84
|
+
def postdraw()
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
Emitted after drawing the panes and right before the screen is refreshed
|
|
88
|
+
|
|
89
|
+
:raise BCError:
|
|
90
|
+
boacon system is not currently running
|
|
91
|
+
|
|
92
|
+
<a id="boacon.refresh"></a>
|
|
93
|
+
|
|
94
|
+
#### refresh
|
|
95
|
+
|
|
96
|
+
```python
|
|
97
|
+
def refresh()
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
Refreshes the screen
|
|
101
|
+
|
|
102
|
+
:raise BCError:
|
|
103
|
+
boacon system is not currently running
|
|
104
|
+
|
|
105
|
+
<a id="boacon.getch"></a>
|
|
106
|
+
|
|
107
|
+
#### getch
|
|
108
|
+
|
|
109
|
+
```python
|
|
110
|
+
def getch()
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
Gets a character code from the keyboard
|
|
114
|
+
|
|
115
|
+
:return:
|
|
116
|
+
Character code (or -1 if no character is pressed)
|
|
117
|
+
:raise BCError:
|
|
118
|
+
boacon system is not currently running
|
|
119
|
+
|
|
120
|
+
<a id="boacon.get_border"></a>
|
|
121
|
+
|
|
122
|
+
#### get\_border
|
|
123
|
+
|
|
124
|
+
```python
|
|
125
|
+
def get_border()
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
Gets whether or not pane borders are enabled
|
|
129
|
+
|
|
130
|
+
:raise BCError:
|
|
131
|
+
boacon system is not currently running
|
|
132
|
+
|
|
133
|
+
<a id="boacon.set_border"></a>
|
|
134
|
+
|
|
135
|
+
#### set\_border
|
|
136
|
+
|
|
137
|
+
```python
|
|
138
|
+
def set_border(value: bool)
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
Sets whether or not pane borders are enabled
|
|
142
|
+
|
|
143
|
+
:raise BCError:
|
|
144
|
+
boacon system is not currently running
|
|
145
|
+
|
boacon-0.0.1/README.md
ADDED
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
<a id="boacon"></a>
|
|
2
|
+
|
|
3
|
+
# boacon
|
|
4
|
+
|
|
5
|
+
<a id="boacon.init"></a>
|
|
6
|
+
|
|
7
|
+
#### init
|
|
8
|
+
|
|
9
|
+
```python
|
|
10
|
+
def init()
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
<a id="boacon.final"></a>
|
|
14
|
+
|
|
15
|
+
#### final
|
|
16
|
+
|
|
17
|
+
```python
|
|
18
|
+
def final()
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
<a id="boacon.state"></a>
|
|
22
|
+
|
|
23
|
+
#### state
|
|
24
|
+
|
|
25
|
+
```python
|
|
26
|
+
def state()
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
State of the boacon system
|
|
30
|
+
|
|
31
|
+
<a id="boacon.panes"></a>
|
|
32
|
+
|
|
33
|
+
#### panes
|
|
34
|
+
|
|
35
|
+
```python
|
|
36
|
+
def panes()
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
Panes that are being displayed
|
|
40
|
+
|
|
41
|
+
:raise BCError:
|
|
42
|
+
boacon system is not currently running
|
|
43
|
+
|
|
44
|
+
<a id="boacon.on_init"></a>
|
|
45
|
+
|
|
46
|
+
#### on\_init
|
|
47
|
+
|
|
48
|
+
```python
|
|
49
|
+
def on_init()
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
Emitted after the boacon system is initialized
|
|
53
|
+
|
|
54
|
+
<a id="boacon.on_final"></a>
|
|
55
|
+
|
|
56
|
+
#### on\_final
|
|
57
|
+
|
|
58
|
+
```python
|
|
59
|
+
def on_final()
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
Emitted before the boacon system is finalized
|
|
63
|
+
|
|
64
|
+
<a id="boacon.postdraw"></a>
|
|
65
|
+
|
|
66
|
+
#### postdraw
|
|
67
|
+
|
|
68
|
+
```python
|
|
69
|
+
def postdraw()
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
Emitted after drawing the panes and right before the screen is refreshed
|
|
73
|
+
|
|
74
|
+
:raise BCError:
|
|
75
|
+
boacon system is not currently running
|
|
76
|
+
|
|
77
|
+
<a id="boacon.refresh"></a>
|
|
78
|
+
|
|
79
|
+
#### refresh
|
|
80
|
+
|
|
81
|
+
```python
|
|
82
|
+
def refresh()
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
Refreshes the screen
|
|
86
|
+
|
|
87
|
+
:raise BCError:
|
|
88
|
+
boacon system is not currently running
|
|
89
|
+
|
|
90
|
+
<a id="boacon.getch"></a>
|
|
91
|
+
|
|
92
|
+
#### getch
|
|
93
|
+
|
|
94
|
+
```python
|
|
95
|
+
def getch()
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
Gets a character code from the keyboard
|
|
99
|
+
|
|
100
|
+
:return:
|
|
101
|
+
Character code (or -1 if no character is pressed)
|
|
102
|
+
:raise BCError:
|
|
103
|
+
boacon system is not currently running
|
|
104
|
+
|
|
105
|
+
<a id="boacon.get_border"></a>
|
|
106
|
+
|
|
107
|
+
#### get\_border
|
|
108
|
+
|
|
109
|
+
```python
|
|
110
|
+
def get_border()
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
Gets whether or not pane borders are enabled
|
|
114
|
+
|
|
115
|
+
:raise BCError:
|
|
116
|
+
boacon system is not currently running
|
|
117
|
+
|
|
118
|
+
<a id="boacon.set_border"></a>
|
|
119
|
+
|
|
120
|
+
#### set\_border
|
|
121
|
+
|
|
122
|
+
```python
|
|
123
|
+
def set_border(value: bool)
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
Sets whether or not pane borders are enabled
|
|
127
|
+
|
|
128
|
+
:raise BCError:
|
|
129
|
+
boacon system is not currently running
|
|
130
|
+
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["hatchling"]
|
|
3
|
+
build-backend = "hatchling.build"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "boacon"
|
|
7
|
+
version = "0.0.1"
|
|
8
|
+
description = ""
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.13"
|
|
11
|
+
license = "MIT"
|
|
12
|
+
license-files = ["LICEN[CS]E*"]
|
|
13
|
+
authors = [
|
|
14
|
+
{ name = "Black Rook Games", email = "blackrookgames@gmail.com" },
|
|
15
|
+
]
|
|
16
|
+
classifiers = [
|
|
17
|
+
"Programming Language :: Python :: 3",
|
|
18
|
+
"Operating System :: OS Independent",
|
|
19
|
+
]
|
|
20
|
+
dependencies = [
|
|
21
|
+
"numpy >= 2.4.1",
|
|
22
|
+
"windows_curses >= 2.4.1 ; sys_platform == 'win32'",
|
|
23
|
+
]
|
|
24
|
+
|
|
25
|
+
[project.urls]
|
|
26
|
+
Homepage = "https://github.com/blackrookgames/boacon"
|
|
27
|
+
Issues = "https://github.com/blackrookgames/boacon/issues"
|
|
28
|
+
|
|
29
|
+
[tool.hatch.build]
|
|
30
|
+
exclude = [
|
|
31
|
+
"*.code-workspace",
|
|
32
|
+
".git/",
|
|
33
|
+
"/misc/",
|
|
34
|
+
"/tests/",
|
|
35
|
+
"/README.py",
|
|
36
|
+
]
|
|
37
|
+
|
|
38
|
+
[[tool.pydoc-markdown.loaders]]
|
|
39
|
+
type = "python"
|
|
40
|
+
search_path = [ "src" ]
|
|
41
|
+
modules = [ "boacon" ]
|
|
42
|
+
|
|
43
|
+
[[tool.pydoc-markdown.processors]]
|
|
44
|
+
type = "filter"
|
|
45
|
+
expression = "(name == '__init__' or (len(name) > 0 and name[0].isalpha())) and default()"
|
|
46
|
+
documented_only = false
|
|
47
|
+
|
|
48
|
+
[tool.pydoc-markdown.renderer]
|
|
49
|
+
type = "markdown"
|
|
@@ -0,0 +1,360 @@
|
|
|
1
|
+
from .c_BCChar import *
|
|
2
|
+
from .c_BCCoord import *
|
|
3
|
+
from .c_BCError import *
|
|
4
|
+
from .c_BCPane import *
|
|
5
|
+
from .c_BCPostDrawArgs import *
|
|
6
|
+
from .c_BCSetChrFunc import *
|
|
7
|
+
from .c_BCSignal import *
|
|
8
|
+
from .c_BCSignalEmitter import *
|
|
9
|
+
from .c_BCState import *
|
|
10
|
+
from .c_BCStr import *
|
|
11
|
+
from .g_attr import *
|
|
12
|
+
from .g_key import *
|
|
13
|
+
from .p_BCConsolePane import *
|
|
14
|
+
|
|
15
|
+
import curses as _curses
|
|
16
|
+
import numpy as _np
|
|
17
|
+
import numpy.typing as _npt
|
|
18
|
+
|
|
19
|
+
#region const
|
|
20
|
+
|
|
21
|
+
_C_BORDERCHARS = [\
|
|
22
|
+
0xFF, 0x50, 0x50, 0x50, 0x51, 0x54, 0x5A, 0x50, 0x51, 0x57, 0x5D, 0x50, 0x51, 0x51, 0x51, 0xA1,\
|
|
23
|
+
0x5D, 0x50, 0x69, 0x50, 0x51, 0x54, 0x5A, 0x50, 0x63, 0x57, 0x5D, 0x50, 0x51, 0x51, 0x51, 0xA1,\
|
|
24
|
+
0x5A, 0x50, 0x69, 0x50, 0x60, 0x54, 0x5A, 0x50, 0x51, 0x57, 0x5D, 0x50, 0x51, 0x51, 0x51, 0xA1,\
|
|
25
|
+
0x69, 0x50, 0x69, 0x50, 0x60, 0x54, 0x5A, 0x50, 0x63, 0x57, 0x5D, 0x50, 0x51, 0x51, 0x51, 0xA1,\
|
|
26
|
+
0x57, 0x66, 0x50, 0x50, 0x51, 0x54, 0x5A, 0x50, 0x63, 0x57, 0x5D, 0x50, 0x51, 0x51, 0x51, 0xA1,\
|
|
27
|
+
0x63, 0x66, 0x69, 0x50, 0x51, 0x54, 0x5A, 0x50, 0x63, 0x57, 0x5D, 0x50, 0x51, 0x51, 0x51, 0xA1,\
|
|
28
|
+
0x6C, 0x66, 0x69, 0x50, 0x60, 0x54, 0x5A, 0x50, 0x63, 0x57, 0x5D, 0x50, 0x51, 0x51, 0x51, 0xA1,\
|
|
29
|
+
0x6C, 0x66, 0x69, 0x50, 0x60, 0x54, 0x5A, 0x50, 0x63, 0x57, 0x5D, 0x50, 0x51, 0x51, 0x51, 0xA1,\
|
|
30
|
+
0x54, 0x66, 0x50, 0x50, 0x60, 0x54, 0x5A, 0x50, 0x51, 0x57, 0x5D, 0x50, 0x51, 0x51, 0x51, 0xA1,\
|
|
31
|
+
0x6C, 0x66, 0x69, 0x50, 0x60, 0x54, 0x5A, 0x50, 0x63, 0x57, 0x5D, 0x50, 0x51, 0x51, 0x51, 0xA1,\
|
|
32
|
+
0x60, 0x66, 0x69, 0x50, 0x60, 0x54, 0x5A, 0x50, 0x51, 0x57, 0x5D, 0x50, 0x51, 0x51, 0x51, 0xA1,\
|
|
33
|
+
0x6C, 0x66, 0x69, 0x50, 0x60, 0x54, 0x5A, 0x50, 0x63, 0x57, 0x5D, 0x50, 0x51, 0x51, 0x51, 0xA1,\
|
|
34
|
+
0x66, 0x66, 0x50, 0x50, 0x60, 0x54, 0x5A, 0x50, 0x63, 0x57, 0x5D, 0x50, 0x51, 0x51, 0x51, 0xA1,\
|
|
35
|
+
0x6C, 0x66, 0x69, 0x50, 0x60, 0x54, 0x5A, 0x50, 0x63, 0x57, 0x5D, 0x50, 0x51, 0x51, 0x51, 0xA1,\
|
|
36
|
+
0x6C, 0x66, 0x69, 0x50, 0x60, 0x54, 0x5A, 0x50, 0x63, 0x57, 0x5D, 0x50, 0x51, 0x51, 0x51, 0xA1,\
|
|
37
|
+
0x6C, 0x66, 0x69, 0x50, 0x60, 0x54, 0x5A, 0x50, 0x63, 0x57, 0x5D, 0x50, 0x51, 0x51, 0x51, 0xA1,]
|
|
38
|
+
|
|
39
|
+
#endregion
|
|
40
|
+
|
|
41
|
+
#region variables
|
|
42
|
+
|
|
43
|
+
_f_state = BCState.NORUN
|
|
44
|
+
_f_win:None|_curses.window = None
|
|
45
|
+
_f_win_ok = False
|
|
46
|
+
_f_win_w = 0
|
|
47
|
+
_f_win_h = 0
|
|
48
|
+
_f_color = False
|
|
49
|
+
_f_panes:None|list[BCPane] = None
|
|
50
|
+
_f_bgbuffer:None|_npt.NDArray[_np.bool_] = None
|
|
51
|
+
|
|
52
|
+
_f_border = False
|
|
53
|
+
|
|
54
|
+
_s_on_init_emitter = BCSignalEmitter[()]()
|
|
55
|
+
_s_on_init = BCSignal(_s_on_init_emitter)
|
|
56
|
+
_s_on_final_emitter = BCSignalEmitter[()]()
|
|
57
|
+
_s_on_final = BCSignal(_s_on_final_emitter)
|
|
58
|
+
|
|
59
|
+
_s_postdraw_emitter:None|BCSignalEmitter[BCPostDrawArgs] = None
|
|
60
|
+
_s_postdraw:None|BCSignal[BCPostDrawArgs] = None
|
|
61
|
+
|
|
62
|
+
#endregion
|
|
63
|
+
|
|
64
|
+
#region helper
|
|
65
|
+
|
|
66
|
+
def _m_verify_run():
|
|
67
|
+
global _f_state
|
|
68
|
+
if _f_state == BCState.RUN: return
|
|
69
|
+
raise BCError("boacon system is not currently running.")
|
|
70
|
+
|
|
71
|
+
def _m_setcursor(visible:bool):
|
|
72
|
+
global _f_win, _f_win_ok
|
|
73
|
+
assert _f_win is not None
|
|
74
|
+
# Try to hide normally
|
|
75
|
+
if not _f_win_ok:
|
|
76
|
+
try: _curses.curs_set(1 if visible else 0)
|
|
77
|
+
except _curses.error: _f_win_ok = True
|
|
78
|
+
# Try to hide alternatively
|
|
79
|
+
if _f_win_ok: # Do NOT change to else or elif
|
|
80
|
+
try: _f_win.leaveok(not visible)
|
|
81
|
+
except _curses.error: pass
|
|
82
|
+
|
|
83
|
+
def _m_cursesattr_color(attr:int):
|
|
84
|
+
cattr = _curses.A_STANDOUT if attr_emp(attr) else _curses.A_NORMAL
|
|
85
|
+
return cattr | _curses.color_pair(0b111 ^ attr_color(attr))
|
|
86
|
+
|
|
87
|
+
def _m_cursesattr_nocolor(attr:int):
|
|
88
|
+
return _curses.A_STANDOUT if attr_emp(attr) else _curses.A_NORMAL
|
|
89
|
+
|
|
90
|
+
def _m_setchr_color(x:int, y:int, char:BCChar):
|
|
91
|
+
global _f_win, _f_bgbuffer, _f_win_w
|
|
92
|
+
assert _f_win is not None
|
|
93
|
+
assert _f_bgbuffer is not None
|
|
94
|
+
attr = _m_cursesattr_color(char.attr)
|
|
95
|
+
try:
|
|
96
|
+
_f_win.addch(y, x, chr(char.ord), attr)
|
|
97
|
+
_f_bgbuffer[y * _f_win_w + x] = True
|
|
98
|
+
except: pass
|
|
99
|
+
|
|
100
|
+
def _m_setchr_nocolor(x:int, y:int, char:BCChar):
|
|
101
|
+
global _f_win, _f_bgbuffer, _f_win_w
|
|
102
|
+
assert _f_win is not None
|
|
103
|
+
assert _f_bgbuffer is not None
|
|
104
|
+
attr = _m_cursesattr_nocolor(char.attr)
|
|
105
|
+
try:
|
|
106
|
+
_f_win.addch(y, x, chr(char.ord), attr)
|
|
107
|
+
_f_bgbuffer[y * _f_win_w + x] = True
|
|
108
|
+
except: pass
|
|
109
|
+
|
|
110
|
+
def _m_borderchar(x:int, y:int):
|
|
111
|
+
global _f_win_w, _f_win_h, _f_bgbuffer
|
|
112
|
+
assert _f_bgbuffer is not None
|
|
113
|
+
# Examine neighbors
|
|
114
|
+
index = y * _f_win_w + x
|
|
115
|
+
index_t = index - _f_win_w
|
|
116
|
+
index_b = index + _f_win_w
|
|
117
|
+
notedge_t = y > 0
|
|
118
|
+
notedge_b = (y + 1) < _f_win_h
|
|
119
|
+
notedge_l = x > 0
|
|
120
|
+
notedge_r = (x + 1) < _f_win_w
|
|
121
|
+
if notedge_t:
|
|
122
|
+
neighbor_t = _f_bgbuffer[index_t]
|
|
123
|
+
neighbor_tl = notedge_l and _f_bgbuffer[index_t - 1]
|
|
124
|
+
neighbor_tr = notedge_r and _f_bgbuffer[index_t + 1]
|
|
125
|
+
else:
|
|
126
|
+
neighbor_t = False
|
|
127
|
+
neighbor_tl = False
|
|
128
|
+
neighbor_tr = False
|
|
129
|
+
if notedge_b:
|
|
130
|
+
neighbor_b = _f_bgbuffer[index_b]
|
|
131
|
+
neighbor_bl = notedge_l and _f_bgbuffer[index_b - 1]
|
|
132
|
+
neighbor_br = notedge_r and _f_bgbuffer[index_b + 1]
|
|
133
|
+
else:
|
|
134
|
+
neighbor_b = False
|
|
135
|
+
neighbor_bl = False
|
|
136
|
+
neighbor_br = False
|
|
137
|
+
neighbor_l = notedge_l and _f_bgbuffer[index - 1]
|
|
138
|
+
neighbor_r = notedge_r and _f_bgbuffer[index + 1]
|
|
139
|
+
# Determine character
|
|
140
|
+
index = 0
|
|
141
|
+
if neighbor_t: index |= 0b00000001
|
|
142
|
+
if neighbor_b: index |= 0b00000010
|
|
143
|
+
if neighbor_l: index |= 0b00000100
|
|
144
|
+
if neighbor_r: index |= 0b00001000
|
|
145
|
+
if neighbor_tl: index |= 0b00010000
|
|
146
|
+
if neighbor_tr: index |= 0b00100000
|
|
147
|
+
if neighbor_bl: index |= 0b01000000
|
|
148
|
+
if neighbor_br: index |= 0b10000000
|
|
149
|
+
raw = _C_BORDERCHARS[index]
|
|
150
|
+
return ' ' if (raw == 0xFF) else chr(0x2500 | raw)
|
|
151
|
+
|
|
152
|
+
#endregion
|
|
153
|
+
|
|
154
|
+
#region init/final
|
|
155
|
+
|
|
156
|
+
def init():
|
|
157
|
+
global _f_state
|
|
158
|
+
if _f_state != BCState.NORUN: return
|
|
159
|
+
_f_state = BCState.INIT
|
|
160
|
+
# Global vars
|
|
161
|
+
global _f_win, _f_win_w, _f_win_h, _f_color, _f_panes
|
|
162
|
+
global _f_border
|
|
163
|
+
# Initialize window
|
|
164
|
+
_f_win = _curses.initscr()
|
|
165
|
+
_f_win.keypad(True)
|
|
166
|
+
_f_win.nodelay(True)
|
|
167
|
+
_f_win_w = 0
|
|
168
|
+
_f_win_h = 0
|
|
169
|
+
# Initialize curses
|
|
170
|
+
_curses.noecho()
|
|
171
|
+
_curses.cbreak()
|
|
172
|
+
_m_setcursor(False)
|
|
173
|
+
# Initialize color
|
|
174
|
+
_curses.start_color()
|
|
175
|
+
if _curses.has_colors() and _curses.COLOR_PAIRS >= 8:
|
|
176
|
+
_curses.use_default_colors()
|
|
177
|
+
_curses.init_pair(0b001, _curses.COLOR_CYAN, -1)
|
|
178
|
+
_curses.init_pair(0b010, _curses.COLOR_MAGENTA, -1)
|
|
179
|
+
_curses.init_pair(0b011, _curses.COLOR_BLUE, -1)
|
|
180
|
+
_curses.init_pair(0b100, _curses.COLOR_YELLOW, -1)
|
|
181
|
+
_curses.init_pair(0b101, _curses.COLOR_GREEN, -1)
|
|
182
|
+
_curses.init_pair(0b110, _curses.COLOR_RED, -1)
|
|
183
|
+
_curses.init_pair(0b111, _curses.COLOR_BLACK, -1)
|
|
184
|
+
_f_color = True
|
|
185
|
+
else:
|
|
186
|
+
_f_color = False
|
|
187
|
+
# Initialize panes
|
|
188
|
+
_f_panes = []
|
|
189
|
+
# Initialize border
|
|
190
|
+
_f_border = True
|
|
191
|
+
# Initialize signals
|
|
192
|
+
global _s_postdraw, _s_postdraw_emitter
|
|
193
|
+
_s_postdraw_emitter = BCSignalEmitter[BCPostDrawArgs]()
|
|
194
|
+
_s_postdraw = BCSignal[BCPostDrawArgs](_s_postdraw_emitter)
|
|
195
|
+
# Success!!!
|
|
196
|
+
_f_state = BCState.RUN
|
|
197
|
+
_s_on_init_emitter.emit(())
|
|
198
|
+
|
|
199
|
+
def final():
|
|
200
|
+
global _f_state
|
|
201
|
+
if _f_state != BCState.RUN: return
|
|
202
|
+
_s_on_final_emitter.emit(())
|
|
203
|
+
_f_state = BCState.FINAL
|
|
204
|
+
# Global vars
|
|
205
|
+
global _f_win, _panes
|
|
206
|
+
assert _f_win is not None
|
|
207
|
+
# Finalize curses
|
|
208
|
+
_curses.nocbreak()
|
|
209
|
+
_curses.echo()
|
|
210
|
+
_curses.endwin()
|
|
211
|
+
# Finalize window
|
|
212
|
+
_m_setcursor(True)
|
|
213
|
+
_f_win.nodelay(False)
|
|
214
|
+
_f_win.keypad(False)
|
|
215
|
+
# Success!!!
|
|
216
|
+
_f_state = BCState.NORUN
|
|
217
|
+
|
|
218
|
+
#endregion
|
|
219
|
+
|
|
220
|
+
#region "properties"
|
|
221
|
+
|
|
222
|
+
def state():
|
|
223
|
+
"""
|
|
224
|
+
State of the boacon system
|
|
225
|
+
"""
|
|
226
|
+
global _f_state
|
|
227
|
+
return _f_state
|
|
228
|
+
|
|
229
|
+
def panes():
|
|
230
|
+
"""
|
|
231
|
+
Panes that are being displayed
|
|
232
|
+
|
|
233
|
+
:raise BCError:
|
|
234
|
+
boacon system is not currently running
|
|
235
|
+
"""
|
|
236
|
+
_m_verify_run()
|
|
237
|
+
global _f_panes
|
|
238
|
+
assert _f_panes is not None
|
|
239
|
+
return _f_panes
|
|
240
|
+
|
|
241
|
+
def on_init():
|
|
242
|
+
"""
|
|
243
|
+
Emitted after the boacon system is initialized
|
|
244
|
+
"""
|
|
245
|
+
global _s_on_init
|
|
246
|
+
return _s_on_init
|
|
247
|
+
|
|
248
|
+
def on_final():
|
|
249
|
+
"""
|
|
250
|
+
Emitted before the boacon system is finalized
|
|
251
|
+
"""
|
|
252
|
+
global _s_on_final
|
|
253
|
+
return _s_on_final
|
|
254
|
+
|
|
255
|
+
def postdraw():
|
|
256
|
+
"""
|
|
257
|
+
Emitted after drawing the panes and right before the screen is refreshed
|
|
258
|
+
|
|
259
|
+
:raise BCError:
|
|
260
|
+
boacon system is not currently running
|
|
261
|
+
"""
|
|
262
|
+
_m_verify_run()
|
|
263
|
+
global _s_postdraw
|
|
264
|
+
assert _s_postdraw is not None
|
|
265
|
+
return _s_postdraw
|
|
266
|
+
|
|
267
|
+
#endregion
|
|
268
|
+
|
|
269
|
+
#region functions
|
|
270
|
+
|
|
271
|
+
def refresh():
|
|
272
|
+
"""
|
|
273
|
+
Refreshes the screen
|
|
274
|
+
|
|
275
|
+
:raise BCError:
|
|
276
|
+
boacon system is not currently running
|
|
277
|
+
"""
|
|
278
|
+
_m_verify_run()
|
|
279
|
+
global _f_win, _f_win_w, _f_win_h, _f_color, _f_panes, _f_bgbuffer
|
|
280
|
+
global _f_border
|
|
281
|
+
assert _f_win is not None
|
|
282
|
+
assert _f_panes is not None
|
|
283
|
+
global _s_postdraw_emitter
|
|
284
|
+
assert _s_postdraw_emitter is not None
|
|
285
|
+
# Determine functions
|
|
286
|
+
_func_cursesattr = _m_cursesattr_color if _f_color else _m_cursesattr_nocolor
|
|
287
|
+
_func_setchr = _m_setchr_color if _f_color else _m_setchr_nocolor
|
|
288
|
+
# Update size
|
|
289
|
+
_new_h, _new_w = _f_win.getmaxyx()
|
|
290
|
+
if _f_win_w != _new_w or _f_win_h != _new_h:
|
|
291
|
+
_f_win_w = _new_w
|
|
292
|
+
_f_win_h = _new_h
|
|
293
|
+
_f_bgbuffer = _np.zeros(_f_win_w * _f_win_h, dtype = bool)
|
|
294
|
+
resized = True
|
|
295
|
+
else:
|
|
296
|
+
assert _f_bgbuffer is not None
|
|
297
|
+
resized = False
|
|
298
|
+
# Resolve pane dimensions
|
|
299
|
+
redrawbg = resized
|
|
300
|
+
for _pane in _f_panes:
|
|
301
|
+
if _pane._m_resolve(resized, _f_win_w, _f_win_h):
|
|
302
|
+
redrawbg = True
|
|
303
|
+
if redrawbg:
|
|
304
|
+
_f_bgbuffer.fill(False)
|
|
305
|
+
# Update panes
|
|
306
|
+
for _pane in _f_panes:
|
|
307
|
+
_pane._m_refresh(redrawbg, _func_setchr)
|
|
308
|
+
# Draw background
|
|
309
|
+
if redrawbg:
|
|
310
|
+
for _y in range(_f_win_h):
|
|
311
|
+
for _x in range(_f_win_w):
|
|
312
|
+
_i = _y * _f_win_w + _x
|
|
313
|
+
if _f_bgbuffer[_i]: continue
|
|
314
|
+
# Determine character
|
|
315
|
+
_chr = _m_borderchar(_x, _y) if _f_border else ' '
|
|
316
|
+
# Set character
|
|
317
|
+
try: _f_win.addch(_y, _x, _chr)
|
|
318
|
+
except: pass
|
|
319
|
+
# Post draw
|
|
320
|
+
_s_postdraw_emitter.emit((BCPostDrawArgs(_f_win, _func_cursesattr, _func_setchr),))
|
|
321
|
+
# Success!!!
|
|
322
|
+
_f_win.refresh()
|
|
323
|
+
|
|
324
|
+
def getch():
|
|
325
|
+
"""
|
|
326
|
+
Gets a character code from the keyboard
|
|
327
|
+
|
|
328
|
+
:return:
|
|
329
|
+
Character code (or -1 if no character is pressed)
|
|
330
|
+
:raise BCError:
|
|
331
|
+
boacon system is not currently running
|
|
332
|
+
"""
|
|
333
|
+
_m_verify_run()
|
|
334
|
+
global _f_win
|
|
335
|
+
assert _f_win is not None
|
|
336
|
+
return _f_win.getch()
|
|
337
|
+
|
|
338
|
+
def get_border():
|
|
339
|
+
"""
|
|
340
|
+
Gets whether or not pane borders are enabled
|
|
341
|
+
|
|
342
|
+
:raise BCError:
|
|
343
|
+
boacon system is not currently running
|
|
344
|
+
"""
|
|
345
|
+
_m_verify_run()
|
|
346
|
+
global _f_border
|
|
347
|
+
return _f_border
|
|
348
|
+
|
|
349
|
+
def set_border(value:bool):
|
|
350
|
+
"""
|
|
351
|
+
Sets whether or not pane borders are enabled
|
|
352
|
+
|
|
353
|
+
:raise BCError:
|
|
354
|
+
boacon system is not currently running
|
|
355
|
+
"""
|
|
356
|
+
_m_verify_run()
|
|
357
|
+
global _f_border
|
|
358
|
+
_f_border = value
|
|
359
|
+
|
|
360
|
+
#endregion
|