Page MenuHomePhorge

No OneTemporary

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

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)

Event Timeline