Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F4236
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
9 KB
Referenced Files
None
Subscribers
None
View Options
diff --git a/CHANGELOG b/CHANGELOG
index 9efd64e..203f309 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,25 +1,27 @@
Copyright (C) 2022 LANNOCC (Shawn A. Wilson [lannocc@yahoo.com])
@%@~LICENSE:MIT~@%@
+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 369006b..e9d0604 100644
--- a/appscii/__main__.py
+++ b/appscii/__main__.py
@@ -1,26 +1,21 @@
from . import *
def run():
app = Application()
try:
win = Window(app, 30, 5, 42, 9)
win.print('ESC to quit.')
- win.print('Hold click and drag to move me.')
- #win.print('Scroll wheel to scroll me.')
- #for i in range(10):
- # win.print(f'{i+1}. This is a line of text.')
- #win.scroll(-3)
+ win.print('Click drag and scroll test mouse.')
#raise RuntimeError('oopsie')
app.run()
finally:
app.exit()
- #print('clean exit')
if __name__ == '__main__':
run()
diff --git a/appscii/app.py b/appscii/app.py
index 1fe3182..a69e8ea 100644
--- a/appscii/app.py
+++ b/appscii/app.py
@@ -1,91 +1,85 @@
from .backend import core
from threading import Thread, current_thread
class Application:
def __init__(self):
self.go = False
self.error = None
self.core = core.Application(self)
self.windows = [ ]
def exit(self):
self.core.exit()
if self.error:
raise self.error
def run(self):
self.go = True
self.inputs = Thread(target=self.wrap(self.core.inputs),
name='inputs', daemon=True)
self.inputs.start()
self.refresh_all()
self.on_run()
def stop(self, error=None):
if error:
if self.error:
- #try: raise error from self.error
- #except Exception as e: self.error = e
try:
raise self.error
except Exception as e:
try:
raise error
except Exception as e:
self.error = e
else:
self.error = error
self.go = False
def wrap(self, fn):
def wrapped():
try:
fn()
except Exception as e:
try: raise ThreadException() from e
except Exception as e: self.stop(e)
return wrapped
def refresh(self):
self.core.refresh()
def refresh_all(self):
self.refresh()
for win in self.windows:
win.refresh()
def on_run(self):
#raise RuntimeError('yikes')
self.inputs.join()
- #from time import sleep
- #sleep(3)
def on_key(self, key):
- #if key == 27 or key == 3: # escape or ctrl+c
if key == 27: # escape
self.stop()
def on_mouse(self, x, y, left, mid, right, scroll):
- #def on_mouse(self, flags, btn, pos):
+ # this is just for testing:
self.windows[0].print(f'{x},{y}: {left},{mid},{right},{scroll}')
- #self.windows[0].print(f'{flags} | {btn} | {pos}')
self.windows[0].refresh()
#self.refresh_all()
class ThreadException(Exception):
def __init__(self):
t = current_thread()
super().__init__('from thread ' \
+ f'"{t.name}"' if t.name else f'{t.ident}')
diff --git a/appscii/backend/curses.py b/appscii/backend/curses.py
index 2b0f9ea..8e61cf0 100644
--- a/appscii/backend/curses.py
+++ b/appscii/backend/curses.py
@@ -1,85 +1,114 @@
import curses
class Application:
def __init__(self, shell):
self.shell = shell
self.screen = curses.initscr()
curses.flushinp()
curses.curs_set(0)
curses.noecho()
curses.cbreak()
self.screen.keypad(True)
- curses.set_escdelay(100)
+ curses.set_escdelay(99)
curses.mousemask(curses.ALL_MOUSE_EVENTS | curses.REPORT_MOUSE_POSITION)
+ self.mbtns = [False, False, False] # mouse buttons (left, mid, right)
+
def exit(self):
self.screen.keypad(False)
curses.nocbreak()
curses.echo()
curses.curs_set(1)
curses.flushinp()
curses.endwin()
def refresh(self):
self.screen.refresh()
def inputs(self):
- #from time import sleep
while self.shell.go:
- #sleep(1)
#raise RuntimeError('my bad')
key = self.screen.getch()
if key == curses.KEY_MOUSE:
_, x, y, _, btn = curses.getmouse()
- self.shell.on_mouse(x, y,
- 1 if btn & curses.BUTTON1_PRESSED else \
- 2 if btn & curses.BUTTON1_RELEASED else \
- 3 if btn & curses.BUTTON1_CLICKED else \
- 4 if btn & curses.BUTTON1_DOUBLE_CLICKED else \
- 0,
- 1 if btn & curses.BUTTON2_PRESSED else \
- 2 if btn & curses.BUTTON2_RELEASED else \
- 3 if btn & curses.BUTTON2_CLICKED else \
- 4 if btn & curses.BUTTON2_DOUBLE_CLICKED else \
- 0,
- 1 if btn & curses.BUTTON3_PRESSED else \
- 2 if btn & curses.BUTTON3_RELEASED else \
- 3 if btn & curses.BUTTON3_CLICKED else \
- 4 if btn & curses.BUTTON3_DOUBLE_CLICKED else \
- 0,
- 1 if btn & curses.BUTTON4_PRESSED else \
- -1 if btn & 2097152 else \
- 0
- )
+ mbtns = self.mbtns
+
+ if btn & curses.BUTTON1_PRESSED:
+ mbtns[0] = True
+ elif btn & curses.BUTTON1_RELEASED:
+ mbtns[0] = False
+
+ if btn & curses.BUTTON2_PRESSED:
+ mbtns[1] = True
+ elif btn & curses.BUTTON2_RELEASED:
+ mbtns[1] = False
+
+ if btn & curses.BUTTON3_PRESSED:
+ mbtns[2] = True
+ elif btn & curses.BUTTON3_RELEASED:
+ mbtns[2] = False
+
+ if btn & curses.BUTTON1_CLICKED \
+ or btn & curses.BUTTON1_DOUBLE_CLICKED:
+ self.shell.on_mouse(x, y, True, mbtns[1], mbtns[2], 0)
+ self.shell.on_mouse(x, y, False, mbtns[1], mbtns[2], 0)
+
+ if btn & curses.BUTTON1_DOUBLE_CLICKED:
+ self.shell.on_mouse(x, y, True, mbtns[1], mbtns[2], 0)
+ self.shell.on_mouse(x, y, False, mbtns[1], mbtns[2], 0)
+
+ elif btn & curses.BUTTON2_CLICKED \
+ or btn & curses.BUTTON2_DOUBLE_CLICKED:
+ self.shell.on_mouse(x, y, mbtns[0], True, mbtns[2], 0)
+ self.shell.on_mouse(x, y, mbtns[0], False, mbtns[2], 0)
+
+ if btn & curses.BUTTON2_DOUBLE_CLICKED:
+ self.shell.on_mouse(x, y, mbtns[0], True, mbtns[2], 0)
+ self.shell.on_mouse(x, y, mbtns[0], False, mbtns[2], 0)
+
+ elif btn & curses.BUTTON3_CLICKED \
+ or btn & curses.BUTTON3_DOUBLE_CLICKED:
+ self.shell.on_mouse(x, y, mbtns[0], mbtns[1], True, 0)
+ self.shell.on_mouse(x, y, mbtns[0], mbtns[1], False, 0)
+
+ if btn & curses.BUTTON3_DOUBLE_CLICKED:
+ self.shell.on_mouse(x, y, mbtns[0], mbtns[1], True, 0)
+ self.shell.on_mouse(x, y, mbtns[0], mbtns[1], False, 0)
+
+ elif btn & curses.BUTTON4_PRESSED:
+ self.shell.on_mouse(x, y, mbtns[0], mbtns[1], mbtns[2], 1)
+
+ elif btn & 2097152:
+ self.shell.on_mouse(x, y, mbtns[0], mbtns[1], mbtns[2], -1)
+
+ else:
+ self.shell.on_mouse(x, y, mbtns[0], mbtns[1], mbtns[2], 0)
else:
self.shell.on_key(key)
class Window:
def __init__(self, app, x, y, w, h):
win = curses.newwin(h, w, y, x)
win.keypad(True)
win.box()
self.border = win
win = win.derwin(h - 2, w - 2, 1, 1)
win.keypad(True)
win.scrollok(True)
self.content = win
self.newline = ''
def print(self, txt, end):
self.content.addstr(f'{self.newline}{txt}')
self.newline = '\n' if end else ''
def refresh(self):
self.border.refresh()
self.content.refresh()
- #def scroll(self, lines):
- # self.content.scroll(lines)
-
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Sun, Sep 13, 11:33 AM (1 w, 1 d ago)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
3511
Default Alt Text
(9 KB)
Attached To
Mode
rAPPSCII Terminal Framework
Attached
Detach File
Event Timeline
Log In to Comment