Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F4430
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
17 KB
Referenced Files
None
Subscribers
None
View Options
diff --git a/CHANGELOG b/CHANGELOG
index e7469f9..7dcd039 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,61 +1,63 @@
Copyright (C) 2022 LANNOCC (Shawn A. Wilson [lannocc@yahoo.com])
@%@~LICENSE:MIT~@%@
+saw_080822_1 - Big font option.
+
saw_080322_1 - Update README.
saw_080222_3 - Fix curses screen refresh. Add some debugging.
saw_080222_2 - New matrix method mostly working now.
saw_080222_1 - Working on new matrix-based universal screen mapping.
saw_080122_3 - Start to play with multiple windows.
saw_080122_2 - Let run() be wrapped. User setup should happen in init().
saw_080122_1 - Fix for python 3.8.
saw_073122_3 - Fix ctrl-c interrupt on Windows.
saw_073122_2 - Tested and working on Linux and Win7.
saw_073122_1 - Text scrolling and justification, window resizing.
saw_073022_10 - Linux: Improved mouse responsiveness.
saw_073022_9 - Windows: Fix unreliable mouse position while scrolling.
saw_073022_8 - Version bump: tested on Linux and Win7.
saw_073022_7 - Window movement (Windows).
saw_073022_6 - Window movement (Linux).
saw_073022_5 - Version bump: tested on Linux and Win7.
saw_073022_4 - Print containment on Windows.
saw_073022_3 - Normalized mouse input across platforms.
saw_073022_2 - Mouse input on Windows.
saw_073022_1 - Input wrangling and exception propagation.
saw_072922_3 - Version bump: tested on Linux and Win7.
saw_072922_2 - Beginning Windows backend.
saw_072922_1 - A possible approach to multiple backends.
saw_072822_6 - Some window fun.
saw_072822_5 - Bump version for pip platform dependency test.
saw_072822_4 - Test commit (turned on GPG sign in Windows).
saw_072822_3 - Add Windows support to mouse test script.
saw_072822_2 - Add a mouse test script.
saw_072822_1 - Initial commit (just termio.py from my vipy project).
diff --git a/appscii/__main__.py b/appscii/__main__.py
index d69f24f..04b0378 100644
--- a/appscii/__main__.py
+++ b/appscii/__main__.py
@@ -1,43 +1,47 @@
from . import *
def run():
app = Application()
try:
win1 = Window(app, 30, 5, 42, 9)
win1.text.word_wrap()
win1.text.top()
win1.text.print('ESC to quit.')
win1.text.print('Click drag and scroll to test mouse.')
win1.text.print()
win1.text.print("Here's something. ", enter=False)
win1.text.print('And this continues the previous print and also wraps.')
for i in range(1, 11):
win1.text.print()
win1.text.print(i, enter=False)
win1.text.print('. This is a line of text that goes and continues' \
+ ' and keeps going some more just to see how it all works.')
win2 = Window(app, 3, 3, 22, 3)
win2.text.print('something else')
+ win3 = Window(app, 9, 18, 63, 7)
+ win3.text.big()
+ win3.text.print('Big Font Style')
+
def on_run():
while app.go:
app.sleep(1)
win1.text.center()
app.sleep(1)
win1.text.right()
app.sleep(1)
win1.text.left()
app.on_run = on_run
#raise RuntimeError('__main__ test')
app.run()
finally:
app.exit()
if __name__ == '__main__':
run()
diff --git a/appscii/backend/common.py b/appscii/backend/common.py
index df8e24f..acbf9ec 100644
--- a/appscii/backend/common.py
+++ b/appscii/backend/common.py
@@ -1,70 +1,72 @@
from .matrix import CharMap
class Window:
def __init__(self, app, x, y, w, h):
assert x >= 0 and x + w <= app.w
assert y >= 0 and y + h <= app.h
assert w >= 2
assert h >= 2
self.app = app
self.x = x
self.y = y
self.w = w
self.h = h
self.matrix = CharMap(w, h)
def set_pos(self, x, y):
assert x >= 0 and x + self.w <= self.app.w
assert y >= 0 and y + self.h <= self.app.h
self.x = x
self.y = y
def set_size(self, w, h):
if w == self.w and h == self.h: return
assert w >= 2
assert h >= 2
self.w = w
self.h = h
self.matrix.set_size(w, h)
def frame(self, active=True):
tl = '\u2554' if active else '\u250c'
t = '\u2550' if active else '\u2500'
tr = '\u2557' if active else '\u2510'
l = '\u2551' if active else '\u2502'
r = '\u2551' if active else '\u2502'
bl = '\u255a' if active else '\u2514'
b = '\u2550' if active else '\u2500'
br = '\u255d' if active else '\u2518'
self.matrix.set(tl, 0, 0)
self.matrix.fill(t, 1, 0, self.w - 2, 1)
self.matrix.set(tr, self.w - 1, 0)
self.matrix.fill(l, 0, 1, 1, self.h - 2)
self.matrix.fill(r, self.w - 1, 1, 1, self.h - 2)
self.matrix.set(bl, 0, self.h - 1)
self.matrix.fill(b, 1, self.h - 1, self.w -2, 1)
self.matrix.set(br, self.w - 1, self.h - 1)
def write(self, x, y, txt):
assert x >= 0 and x + len(txt) <= self.w
assert y >= 0 and y < self.h
+ # FIXME: what about \n or \t ?
+
for tx, c in enumerate(txt):
self.matrix.set(c, x + tx, y)
def write_all(self, x, y, lines):
assert x >= 0 and x < self.w
assert y >= 0 and y < self.h
assert y + len(lines) < self.h
for line in lines:
self.write(x, y, line)
y += 1
diff --git a/appscii/backend/matrix.py b/appscii/backend/matrix.py
index 7a755bb..b40ace3 100644
--- a/appscii/backend/matrix.py
+++ b/appscii/backend/matrix.py
@@ -1,96 +1,100 @@
class CharMap:
def __init__(self, w, h, fill=' '):
assert w >= 0
assert h >= 0
assert fill is None or (isinstance(fill, str) and len(fill) == 1)
self.w = w
self.h = h
self.chars = [ [ fill for x in range(w) ] for y in range(h) ]
self.changes = [ [ True for x in range(w) ] for y in range(h) ]
def set_size(self, w, h, fill=' '):
if w == self.w and h == self.h: return
assert w >= 0 and h >= 0
if h > self.h:
self.chars.extend(
[ [ fill for x in range(w) ] for y in range(self.h, h) ])
self.changes.extend(
[ [ True for x in range(w) ] for y in range(self.h, h) ])
elif h < self.h:
self.chars = self.chars[:h]
self.changes = self.changes[:h]
if w > self.w:
for row in self.chars[:min(self.h, h)]:
row.extend([ fill for x in range(self.w, w) ])
for row in self.changes[:min(self.h, h)]:
row.extend([ True for x in range(self.w, w) ])
elif w < self.w:
for row in self.chars[:min(self.h, h)]:
del row[w:]
for row in self.changes[:min(self.h, h)]:
del row[w:]
self.w = w
self.h = h
def set(self, c, x, y):
assert c is None or (isinstance(c, str) and len(c) == 1)
assert x >= 0 and x < self.w
assert y >= 0 and y < self.h
if self.chars[y][x] == c: return
+ # FIXME: what about \n or \t ?
+
self.chars[y][x] = c
self.changes[y][x] = True
def fill(self, c, x, y, w, h):
assert c is None or (isinstance(c, str) and len(c) == 1)
assert x >= 0 and x + w <= self.w
assert y >= 0 and y + h <= self.h
+ # FIXME: what about \n or \t ?
+
for cy in range(y, y + h):
chars = self.chars[cy]
changes = self.changes[cy]
for cx in range(x, x + w):
if chars[cx] != c:
chars[cx] = c
changes[cx] = True
def merge(self, matrix, x=0, y=0):
assert x >= 0 and x + matrix.w <= self.w
assert y >= 0 and y + matrix.h <= self.h
# FIXME: consider only changed items of matrix then clear changes?
for cy in range(y, y + matrix.h):
chars = self.chars[cy]
changes = self.changes[cy]
mchars = matrix.chars[cy - y]
for cx in range(x, x + matrix.w):
mchar = mchars[cx - x]
if mchar is not None and chars[cx] != mchar:
chars[cx] = mchar
changes[cx] = True
def debug_chars(self):
return '\n'.join([
''.join([ c for c in line ])
for line in self.chars
])
def debug_changes(self):
return '\n'.join([
''.join([ '#' if c else '.' for c in line ])
for line in self.changes
])
diff --git a/appscii/font/__init__.py b/appscii/font/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/appscii/font/big.py b/appscii/font/big.py
new file mode 100644
index 0000000..1a391ab
--- /dev/null
+++ b/appscii/font/big.py
@@ -0,0 +1,64 @@
+# limit to codepage 437 symbols:
+
+matrix = [
+ "┌─┐ ┌─┐ ┌─ ┌─. ┌─ ┌─ ┌─ │ │ ─┬─ ─┐ │ / │ ┌┐ ┌┐ ┌┐ │ ┌─┐ ┌─┐ ┌─┐ ┌─┐ ┌─┐ ─┬─ │ │ \ / │ │ \ / \ / ──┐ ",
+ "├─┤ ├<[ │ │ │ ├─ ├─ ├─┐ ├─┤ │ │ ├< │ │ \/ │ │ \ │ │ │ ├─┘ │ │ ├┌┘ └─┐ │ │ │ \ / │┌┐│ x └┬┘ / ",
+ "│ │ └─┘ └─ └─' └─ │ └─┘ │ │ ─┴─ └─┘ │ \ └── │ │ │ └┘ └─┘ │ └─\ │ \ └─┘ │ └─┘ v └┘└┘ / \ │ └── ",
+]
+
+chars = {
+ 'a': (0,3),
+ 'A': (0,3),
+ 'b': (4,3),
+ 'B': (4,3),
+ 'c': (8,3),
+ 'C': (8,3),
+ 'd': (11,3),
+ 'D': (11,3),
+ 'e': (15,2),
+ 'E': (15,2),
+ 'f': (18,2),
+ 'F': (18,2),
+ 'g': (21,3),
+ 'G': (21,3),
+ 'h': (25,3),
+ 'H': (25,3),
+ 'i': (29,3),
+ 'I': (29,3),
+ 'j': (33,3),
+ 'J': (33,3),
+ 'k': (37,3),
+ 'K': (37,3),
+ 'l': (41,3),
+ 'L': (41,3),
+ 'm': (45,6),
+ 'M': (45,6),
+ 'n': (52,5),
+ 'N': (52,5),
+ 'o': (58,3),
+ 'O': (58,3),
+ 'p': (62,3),
+ 'P': (62,3),
+ 'q': (66,3),
+ 'Q': (66,3),
+ 'r': (70,3),
+ 'R': (70,3),
+ 's': (74,3),
+ 'S': (74,3),
+ 't': (78,3),
+ 'T': (78,3),
+ 'u': (82,3),
+ 'U': (82,3),
+ 'v': (85,5),
+ 'V': (85,5),
+ 'w': (92,4),
+ 'W': (92,4),
+ 'x': (97,3),
+ 'X': (97,3),
+ 'y': (101,5),
+ 'Y': (101,5),
+ 'z': (107,3),
+ 'Z': (107,3),
+ ' ': (111,3),
+}
+
diff --git a/appscii/helper.py b/appscii/helper.py
index 4abaf6a..62d6d31 100644
--- a/appscii/helper.py
+++ b/appscii/helper.py
@@ -1,190 +1,223 @@
+from .font import big as big_font
class FlowText:
- def __init__(self, w, h, notify=None, words=False, align=-1):
+ def __init__(self, w, h, notify=None, words=False, align=-1, big=False):
assert w >= 0 and h >= 0
self.w = w
self.h = h
self.notify = notify
self.words = words
self.align = align
+ self.font = 1 if big else 0
self.prints = [ ]
self.enter = True
self.lines = [ ]
self.scroll = -1
self.flow = (0, 0)
def resize(self, w, h):
assert w >= 0 and h >= 0
if w == self.w and h == self.h: return
self.h = h
if w != self.w:
self.w = w
self.reflow(True)
else:
if self.notify: self.notify(self)
def word_wrap(self, words=None):
if words is None:
self.words = not self.words
self.reflow(True)
elif words != self.words:
self.words = words
self.reflow(True)
def left(self):
if self.align == -1: return
self.align = -1
if self.notify: self.notify(self)
def center(self):
if self.align == 0: return
self.align = 0
if self.notify: self.notify(self)
def right(self):
if self.align == 1: return
self.align = 1
if self.notify: self.notify(self)
def top(self):
if self.scroll == 0: return
self.scroll = 0
if self.notify: self.notify(self)
def bottom(self):
if self.scroll < 0: return
self.scroll = -1
if self.notify: self.notify(self)
def up(self, lines=1):
assert lines > 0
if self.scroll == 0: return
diff = len(self.lines) - self.h
if diff > 0:
self.scroll -= lines
if self.scroll > diff:
self.scroll = diff
elif self.scroll < 0:
self.scroll = 0
else:
self.scroll = 0
if self.notify: self.notify(self)
def down(self, lines=1):
assert lines > 0
if self.scroll < 0: return
diff = len(self.lines) - self.h
if diff > 0:
self.scroll += lines
if self.scroll > diff:
self.scroll = diff
else:
self.scroll = -1
if self.notify: self.notify(self)
+ def big(self, big=True):
+ font = 1 if big else 0
+ if self.font == font: return
+
+ self.font = font
+
def print(self, txt='', enter=True):
if not isinstance(txt, str):
txt = f'{txt}'
prints = [ ]
while '\n' in txt:
idx = txt.index('\n')
prints.append(txt[:idx])
txt = txt[idx+1:]
prints.append(txt)
+ if self.font == 1:
+ fprints = [ ]
+ h = len(big_font.matrix)
+
+ for line in prints:
+ fprints.extend([ '' for y in big_font.matrix ])
+
+ for c in line:
+ if c in big_font.chars:
+ if fprints[-1]:
+ for y in range(h):
+ fprints[-(h-y)] += ' '
+
+ x, w = big_font.chars[c]
+ for y, row in enumerate(big_font.matrix):
+ fprints[-(h-y)] += row[x:x+w]
+
+ else:
+ for y in range(h-1):
+ fprints[-(h-y)] += ' '
+
+ fprints[-1] += c
+
+ prints = fprints
+
if self.enter:
self.prints.extend(prints)
else:
self.prints[-1] += prints[0]
self.prints.extend(prints[1:])
self.enter = enter
self.reflow()
def reflow(self, reset=False):
if reset:
self.flow = (0, 0)
if self.w < 1 or self.h < 1:
return
if self.flow[0] and self.flow[1]:
self.lines = self.lines[:self.flow[1]]
elif self.lines:
self.lines = [ ]
for entry in self.prints[self.flow[0]:]:
while len(entry) > self.w:
chunk = entry[:self.w]
if self.words and entry[self.w] != ' ' and chunk[-1] != ' ' \
and ' ' in chunk:
idx = chunk.rindex(' ')
chunk = entry[:idx]
entry = entry[idx+1:]
else:
entry = entry[self.w:]
self.lines.append(chunk)
self.lines.append(entry)
if self.enter:
self.flow = (len(self.prints), len(self.lines))
else:
self.flow = (len(self.prints) - 1, len(self.lines) - 1)
if self.notify:
self.notify(self)
def view(self):
if self.w < 1 or self.h < 1:
return None
if self.scroll < 0:
showing = self.lines[-self.h:]
else:
showing = self.lines[self.scroll:self.scroll+self.h]
while len(showing) < self.h:
showing.append('')
if self.align < 0: # left
return [ line + ' ' * (self.w - len(line)) for line in showing ]
elif self.align > 0: # right
return [ ' ' * (self.w - len(line)) + line for line in showing ]
else: # center
view = [ ]
lpad = True
for line in showing:
diff = self.w - len(line)
if diff:
left = ' ' * (diff // 2)
right = left
if diff % 2:
if lpad: left += ' '
else: right += ' '
lpad = not lpad
view.append(left + line + right)
else:
view.append(line)
return view
diff --git a/big_font.txt b/big_font.txt
new file mode 100644
index 0000000..78cd638
--- /dev/null
+++ b/big_font.txt
@@ -0,0 +1,10 @@
+limit to codepage 437 symbols:
+
+┌─┐ ┌─┐ ┌─ ┌─. ┌─ ┌─ ┌─ │ │ ─┬─ ─┐ │ / │ ┌┐ ┌┐ ┌┐ │ ┌─┐ ┌─┐ ┌─┐ ┌─┐ ┌─┐
+├─┤ ├<[ │ │ │ ├─ ├─ ├─┐ ├─┤ │ │ ├< │ │ \/ │ │ \ │ │ │ ├─┘ │ │ ├┌┘ └─┐
+│ │ └─┘ └─ └─' └─ │ └─┘ │ │ ─┴─ └─┘ │ \ └── │ │ │ └┘ └─┘ │ └─\ │ \ └─┘
+
+─┬─ │ │ \ / │ │ \ / \ / ──┐
+ │ │ │ \ / │┌┐│ x └┬┘ /
+ │ └─┘ v └┘└┘ / \ │ └──
+
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Mon, Sep 14, 10:21 PM (2 w, 1 d ago)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
3652
Default Alt Text
(17 KB)
Attached To
Mode
rAPPSCII Terminal Framework
Attached
Detach File
Event Timeline
Log In to Comment