changeset e572abf9735f in joypy/Joypy details: http://hg.osdn.jp/view/joypy/Joypy?cmd=changeset;node=e572abf9735f user: Simon Forman <sform****@hushm*****> date: Sat May 04 06:57:14 2019 -0700 description: Change name from alpha to tmi. changeset 67d17d5ad16a in joypy/Joypy details: http://hg.osdn.jp/view/joypy/Joypy?cmd=changeset;node=67d17d5ad16a user: Simon Forman <sform****@hushm*****> date: Sat May 04 07:53:02 2019 -0700 description: Minor cleanup. changeset dad1d00fd323 in joypy/Joypy details: http://hg.osdn.jp/view/joypy/Joypy?cmd=changeset;node=dad1d00fd323 user: Simon Forman <sform****@hushm*****> date: Mon May 06 12:47:30 2019 -0700 description: See https://www.metalevel.at/acomip/ changeset 5a11d7edb9e1 in joypy/Joypy details: http://hg.osdn.jp/view/joypy/Joypy?cmd=changeset;node=5a11d7edb9e1 user: Simon Forman <sform****@hushm*****> date: Mon May 06 13:07:01 2019 -0700 description: Initial bring over of VUI code. (Won't work yet.) changeset 472d32ed1c08 in joypy/Joypy details: http://hg.osdn.jp/view/joypy/Joypy?cmd=changeset;node=472d32ed1c08 user: Simon Forman <sform****@hushm*****> date: Mon May 06 13:09:45 2019 -0700 description: Some images generated by pyreverse or whatever. changeset b129b1b7c126 in joypy/Joypy details: http://hg.osdn.jp/view/joypy/Joypy?cmd=changeset;node=b129b1b7c126 user: Simon Forman <sform****@hushm*****> date: Mon May 06 13:26:07 2019 -0700 description: Update imports, copyright notices. changeset bdc716271a20 in joypy/Joypy details: http://hg.osdn.jp/view/joypy/Joypy?cmd=changeset;node=bdc716271a20 user: Simon Forman <sform****@hushm*****> date: Mon May 06 13:28:44 2019 -0700 description: Update initial joy home dir contents BLOB. changeset b235310e9ca3 in joypy/Joypy details: http://hg.osdn.jp/view/joypy/Joypy?cmd=changeset;node=b235310e9ca3 user: Simon Forman <sform****@hushm*****> date: Mon May 06 13:32:08 2019 -0700 description: Well, that seems to work. python -m joy.vui With PyGame installed that starts the "VUI" on my system. Neat. The initial joy home (~/.joypy) is not quite compatible with the one set up by the GUI code. One simple way to fix that would be to e,g, make this use ~/.thun instead. diffstat: docs/dep-graphs/classes_Thun.png | Bin docs/dep-graphs/classes_Vui.png | Bin docs/dep-graphs/packages_Thun.png | Bin docs/dep-graphs/packages_Vui.png | Bin joy/vui/Iosevka12.BMP | Bin joy/vui/README.txt | 163 +++++++ joy/vui/__main__.py | 24 + joy/vui/core.py | 220 +++++++++ joy/vui/debug_main.py | 18 + joy/vui/default_joy_home/definitions.txt | 17 + joy/vui/default_joy_home/library.py | 206 +++++++++ joy/vui/default_joy_home/log.txt | 1 + joy/vui/default_joy_home/menu.txt | 51 ++ joy/vui/default_joy_home/scratch.txt | 85 +++ joy/vui/default_joy_home/stack.pickle | 1 + joy/vui/display.py | 471 +++++++++++++++++++++ joy/vui/font_data.py | 167 +++++++ joy/vui/init_joy_home.py | 256 +++++++++++ joy/vui/main.py | 127 +++++ joy/vui/persist_task.py | 204 +++++++++ joy/vui/stack_viewer.py | 69 +++ joy/vui/text_viewer.py | 693 +++++++++++++++++++++++++++++++ joy/vui/viewer.py | 232 ++++++++++ setup.py | 2 +- thun/metalogical.pl | 24 +- 25 files changed, 3019 insertions(+), 12 deletions(-) diffs (truncated from 3160 to 300 lines): diff -r 81f5dd52c508 -r b235310e9ca3 docs/dep-graphs/classes_Thun.png Binary file docs/dep-graphs/classes_Thun.png has changed diff -r 81f5dd52c508 -r b235310e9ca3 docs/dep-graphs/classes_Vui.png Binary file docs/dep-graphs/classes_Vui.png has changed diff -r 81f5dd52c508 -r b235310e9ca3 docs/dep-graphs/packages_Thun.png Binary file docs/dep-graphs/packages_Thun.png has changed diff -r 81f5dd52c508 -r b235310e9ca3 docs/dep-graphs/packages_Vui.png Binary file docs/dep-graphs/packages_Vui.png has changed diff -r 81f5dd52c508 -r b235310e9ca3 joy/vui/Iosevka12.BMP Binary file joy/vui/Iosevka12.BMP has changed diff -r 81f5dd52c508 -r b235310e9ca3 joy/vui/README.txt --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/joy/vui/README.txt Mon May 06 13:32:08 2019 -0700 @@ -0,0 +1,163 @@ +What is it? + +A simple Graphical User Interface for the Joy programming language, +written using Pygame to bypass X11 et. al., modeled on the Oberon OS, and +intended to be just functional enough to support bootstrapping further Joy +development. + +It's basic functionality is more-or-less as a crude text editor along with +a simple Joy runtime (interpreter, stack, and dictionary.) It auto- saves +any named files (in a versioned home directory) and you can write new Joy +primitives in Python and Joy definitions and immediately install and use +them, as well as recording them for reuse (after restarts.) + +How it works now. + +The only dependencies are Pygame and Dulwich (a Python Git library.) + +When the main.py script starts it checks for an environment var "JOY_HOME" +which should point to a directory where you want the system to store the +files ("resources") it will edit and save, this directory defaults to +'~/.joypy'. The first time you run it, it will create some default files +as content. Right click on see_resources to open a viewer with the list +of resources (files), copy a name to the stack and right click on +open_resource_at_good_location to open a viewer on that resource. + +Right now the screen size defaults to windowed 1024x768, but if you pass +the '-f' option to the main.py script the UI will take up the full screen +at the highest available resolution. The window is divided into two (or +three in fullscreen) vertical "tracks", and the number and width of the +tracks are fixed at start up. (Feel free to edit the values in main.py to +play around with different track configurations.) Each track gets divided +horizontally into zero or more "viewers" (like windows in a windowed GUI, +cf. Chapter 4 of "Project Oberon") for a kind of tiled layout. + +Currently, there are only two kinds of (interesting) viewers: TextViewers +and StackViewer. The TextViewers are crude text editors. They provide +just enough functionality to let the user write text and code (Python and +Joy) and execute Joy functions. One important thing they do is +automatically save their content after changes. No more lost work. + +The StackViewer is a specialized TextViewer that shows the contents of the +Joy stack one line per stack item. It's a very handy visual aid to keep +track of what's going on. There's also a log.txt file that gets written +to when commands are executed, and so records the log of user actions and +system events. It tends to fill up quickly so there's a reset_log command +that clears it out. + +Viewers have "grow" and "close" in ther menu bars. These are buttons. +When you right-click on grow a viewer a copy is created that covers that +viewer's entire track. If you grow a viewer that already takes up its +whole track then a copy is created that takes up an additional track, up +to the whole screen. Closing a viewer just deletes that viewer, and when +a track has no more viewers, it is deleted and that exposes any previous +tracks and viewers that were hidden. + +(Note: if you ever close all the viewers and are sitting at a blank screen +with nowhere to type and execute commands, press the Pause/Break key. +This will open a new "trap" viewer which you can then use to recover.) + +Copies of a viewer all share the same model and update their display as it +changes. (If you have two viewers open on the same named resource and edit +one you'll see the other update as you type.) + +UI Guide + +left mouse sets cursor in text, in menu bar resizes viewer interactively +(this is a little buggy in that you can move the mouse quickly and get +outside the menu, leaving the viewer in the "resizing" state. Until I fix +this, the workaround is to just grab the menu bar again and wiggle it a +few pixels and let go. This will reset the machinery.) + +Right mouse executes Joy command (functions), and you can drag with the +right button to highlight (well, underline) commands. Words that aren't +names of Joy commands won't be underlined. Release the button to execute +the command. + +The middle mouse button (usually a wheel these days) scrolls the text but +you can also click and drag any viewer with it to move that viewer to +another track or to a different location in the same track. There's no +direct visual feedback for this (yet) but that dosen't seem to impair its +usefulness. + +F1, F2 - set selection begin and end markers (crude but usable.) + +F3 - copy selected text to the top of the stack. + +Shift-F3 - as copy then run "parse" command on the string. + +F4 - cut selected text to the top of the stack. + +Shift-F4 - as cut then run "pop" (delete selection.) + +Joy + +Pretty much all of the rest of the functionality of the system is provided +by executing Joy commands (aka functions, aka "words" in Forth) by right- +clicking on their names in any text. + +To get help on a Joy function select the name of the function in a +TextViewer using F1 and F2, then press shift-F3 to parse the selection. +The function (really its Symbol) will appear on the stack in brackets (a +"quoted program" such as "[pop]".) Then right-click on the word help in +any TextViewer (if it's not already there, just type it in somewhere.) +This will print the docstring or definition of the word (function) to +stdout. At some point I'll write a thing to send that to the log.txt file +instead, but for now look for output in the terminal. + +I have pre-defined some system-specific commands, like see_stack to open a +StackViewer, and I should really go and add docstrings to those (so they +work with the help command.) + +... inscribe and evaluate for making new Joy and Python, respectively, +commands... + +---- + + +Still to do: +* Return key can orphan a line at the bottom of a viewer. +* Calculator buttons on the numpad? +* System query for most recent selection +* Home/End keys +* Vertical scrolling w/ scrollbar? +* Shift-scroll changes viewer height? +* Horizontal scrolling w/ keys +* Horizontal scrolling w/ scrollbar? +* Pgup/down keys? +* Tab key? +* When moving viewers sometimes a command gets executed from the underlying + viewer. This shouldn't happen. + +Done: +- Redirect stdout to "print" to the log. +- Initial contents for JOY_HOME. +- Pause/Break to open a trap viewer (in case you close them all.) +- "shutdown" signal to tell PT to commit outstanding changes. +- Local library auto-loaded at start-time + - library.py, primitives in Python + - definitions.txt +- Can name and persist a viewer on an unstored string(list). +- Inscribe function +- Reverse video, well, grey background, menu bars +- PT scans JOY_HOME for resource lists +- Capture and display tracebacks +- StackViewer +- Update log when stack changes +- Open a resource list +- Open a viewer on a (unstored) string +- Selecting text +- Copy and Cut +- Paste +- Menu text, commands and name or title +- "print" to e.g. log +- Command evaluation +- Joy integration +- Persistance of data +- Content change notification +- Vertical scrolling w/ keys +- Vertical scrolling w/ mouse wheel +- Enter/return key +- Arrow keys wrap at line ends +- Backspace/delete wrap at line ends + diff -r 81f5dd52c508 -r b235310e9ca3 joy/vui/__main__.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/joy/vui/__main__.py Mon May 06 13:32:08 2019 -0700 @@ -0,0 +1,24 @@ +# -*- coding: utf-8 -*- +# +# Copyright © 2019 Simon Forman +# +# This file is part of Thun +# +# Thun is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Thun is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Thun. If not see <http://www.gnu.org/licenses/>. +# + +import joy.vui.main + + +joy.vui.main.main(*joy.vui.main.init()) diff -r 81f5dd52c508 -r b235310e9ca3 joy/vui/core.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/joy/vui/core.py Mon May 06 13:32:08 2019 -0700 @@ -0,0 +1,220 @@ +# -*- coding: utf-8 -*- +# +# Copyright © 2019 Simon Forman +# +# This file is part of Thun +# +# Thun is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Thun is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Thun. If not see <http://www.gnu.org/licenses/>. +# +from sys import stderr +from traceback import format_exc +import pygame +from joy.joy import run +from joy.utils.stack import stack_to_string + + +COMMITTER = 'Joy <auto-****@examp*****>' + + +BLACK = FOREGROUND = 0, 0, 0 +GREY = 127, 127, 127 +WHITE = BACKGROUND = 255, 255, 255 +BLUE = 100, 100, 255 +GREEN = 70, 200, 70 + + +MOUSE_EVENTS = frozenset({ + pygame.MOUSEMOTION, + pygame.MOUSEBUTTONDOWN, + pygame.MOUSEBUTTONUP + }) + + +ARROW_KEYS = frozenset({ + pygame.K_UP, + pygame.K_DOWN, + pygame.K_LEFT, + pygame.K_RIGHT + }) + + +TASK_EVENTS = tuple(range(pygame.USEREVENT, pygame.NUMEVENTS)) +AVAILABLE_TASK_EVENTS = set(TASK_EVENTS) + + +ALLOWED_EVENTS = [pygame.QUIT, pygame.KEYUP, pygame.KEYDOWN] +ALLOWED_EVENTS.extend(MOUSE_EVENTS) +ALLOWED_EVENTS.extend(TASK_EVENTS) + + +# Message status codes... dunno if this is a good idea or not... +ERROR = -1 +PENDING = 0 +SUCCESS = 1 + + +# messaging support + + +class Message(object): + + def __init__(self, sender): + self.sender = sender + + +class CommandMessage(Message): + + def __init__(self, sender, command): + Message.__init__(self, sender) + self.command = command + + +class ModifyMessage(Message): + + def __init__(self, sender, subject, **details): + Message.__init__(self, sender) + self.subject = subject + self.details = details + + +class OpenMessage(Message):