re-arrange a bit to make cli scope management easier.

This commit is contained in:
Kelvin Sherlock 2020-08-01 12:47:48 -04:00
parent a1398b74e1
commit 001d67553b
9 changed files with 216 additions and 72 deletions

29
base.py
View File

@ -1,21 +1,12 @@
import struct import struct
from bisect import bisect_left from bisect import bisect_left
from rect import * from rect import *
from utils import *
# helper functions __all__ = ["rObject", "rText", "rTextBlock", "rTextForLETextBox2",
def str_to_bytes(text): "rAlertString", "rErrorString", "rComment", "rPString",
if isinstance(text, str): return text.encode("macroman") "rCString", "rWString", "rC1InputString", "rStringList",
if isinstance(text, bytes): return text "rTwoRects", "rRectList"]
if isinstance(text, bytearray): return bytes(text)
raise TypeError("Bad text type: {}".format(type(text)))
def make_string(text, rType=None):
if not rType: rType = rPString
if type(text) == rType: return text
if type(text) in (str, bytes, bytearray): return rType(text)
raise TypeError("Bad text type: {}".format(type(text)))
#define KeyEquiv array[1]{ char; char; _mybase_ word; _mybase_ word; } #define KeyEquiv array[1]{ char; char; _mybase_ word; _mybase_ word; }
@ -183,6 +174,16 @@ class rTextObject(rObject):
map = rTextObject._map map = rTextObject._map
return "".join([map[x] if x in map else chr(x) for x in bb]) return "".join([map[x] if x in map else chr(x) for x in bb])
@classmethod
def make_string(cls, text):
rType = cls
# if not rType: rType = rPString
if type(text) == rType: return text
if type(text) in (str, bytes, bytearray): return rType(text)
raise TypeError("Bad text type: {}".format(type(text)))
def __init__(self, text, *, id=None, attr=None): def __init__(self, text, *, id=None, attr=None):

38
cli.py
View File

@ -4,18 +4,44 @@ import io
import argparse import argparse
import time import time
from base import * from base import rObject
from window import *
from control import * # from base import *
from menu import * # from window import *
from rect import rect, point, size # from control import *
# from menu import *
# from sound import *
# from rect import rect, point, size
def rez_scope():
import base
import window
import control
import menu
import sound
import rect
scope = {}
for mod in (base, window, control, menu, sound, rect):
if hasattr(mod, '__all__'): keys = mod.__all__
else: keys = [x for x in dir(mod) if x[0] != '_']
for key in keys:
scope[key] = getattr(mod, key)
return scope
def execute(filename): def execute(filename):
scope = rez_scope()
try: try:
with open(filename, 'r', encoding="utf-8") as f: with open(filename, 'r', encoding="utf-8") as f:
src = f.read() src = f.read()
code = compile(src, filename, "exec") code = compile(src, filename, "exec")
exec(code, None, {}) exec(code, {}, scope)
return True return True
pass pass
except Exception as e: except Exception as e:

View File

@ -1,28 +1,28 @@
class Color: class _Color:
__slots__ = ("value") __slots__ = ("value")
def __init__(self, value): def __init__(self, value):
self.value = value self.value = value
# 640 mode colors # 640 mode _colors
Transparent = Color(None) Transparent = _Color(None)
Black = Color(0x00) Black = _Color(0x00)
Blue = Color(0x01) Blue = _Color(0x01)
Olive = Color(0x02) Olive = _Color(0x02)
Gray1 = Color(0x03) Gray1 = _Color(0x03)
Red = Color(0x04) Red = _Color(0x04)
Purple = Color(0x05) Purple = _Color(0x05)
Orange = Color(0x06) Orange = _Color(0x06)
Salmon = Color(0x07) Salmon = _Color(0x07)
Green = Color(0x08) Green = _Color(0x08)
Turquoise = Color(0x09) Turquoise = _Color(0x09)
BrightGreen = Color(0x0a) BrightGreen = _Color(0x0a)
DullGreen = Color(0x0b) DullGreen = _Color(0x0b)
Gray2 = Color(0x0c) Gray2 = _Color(0x0c)
LightBlue = Color(0x0d) LightBlue = _Color(0x0d)
Yellow = Color(0x0e) Yellow = _Color(0x0e)
White = Color(0x0f) White = _Color(0x0f)
# synonyms # synonyms
Grey1 = Gray1 Grey1 = Gray1

View File

@ -1,10 +1,15 @@
from base import * from base import rObject, rList, rPString, rTextForLETextBox2
import struct import struct
from rect import * from rect import *
from colors import * from colors import *
from utils import *
__all__ = [
"rControlTemplate", "rControlList", "rSimpleButton",
"rCheckControl", "rRadioControl", "rThermometerControl",
"rRectangleControl", "rStatTextControl"
]
# /*-------------------------------------------------------*/ # /*-------------------------------------------------------*/
# /* Control List Descriptors # /* Control List Descriptors
@ -25,7 +30,7 @@ from colors import *
# /*-------------------------------------------------------*/ # /*-------------------------------------------------------*/
# #define ctlInvis $0080 # #define ctlInvis $0080
# #define ctlVisible $0000 # #define ctlVisible $0000
# #Define CtlInactive $FF00# # #Define CtlInactive $FF00
# #
# #
# /*-------------------------------------------------------*/ # /*-------------------------------------------------------*/
@ -87,7 +92,7 @@ class rSimpleButton(rControlTemplate):
if title: if title:
moreFlags |= 0x02 # title is resource id moreFlags |= 0x02 # title is resource id
self.title = make_string(title) self.title = rPString.make_string(title)
self.flags = flags self.flags = flags
self.moreFlags = moreFlags self.moreFlags = moreFlags
@ -175,7 +180,7 @@ class rCheckControl(rControlTemplate):
if title: if title:
moreFlags |= 0x02 # title is resource id moreFlags |= 0x02 # title is resource id
self.title = make_string(title) self.title = rPString.make_string(title)
self.flags = flags self.flags = flags
self.moreFlags = moreFlags self.moreFlags = moreFlags
@ -269,7 +274,7 @@ class rRadioControl(rControlTemplate):
if title: if title:
moreFlags |= 0x02 # title is resource id moreFlags |= 0x02 # title is resource id
self.title = make_string(title) self.title = rPString.make_string(title)
self.flags = flags self.flags = flags
self.moreFlags = moreFlags self.moreFlags = moreFlags
@ -577,7 +582,7 @@ class rStatTextControl(rControlTemplate):
elif fullJust: just = 2 elif fullJust: just = 2
elif rightJust: just = -1 elif rightJust: just = -1
self.text = make_string(text, rTextForLETextBox2) self.text = rTextForLETextBox2.make_string(text)
self.flags = flags self.flags = flags
self.moreFlags = moreFlags self.moreFlags = moreFlags

106
menu.py
View File

@ -1,15 +1,44 @@
from base import * from base import *
from utils import *
import struct import struct
__all__ = ['rMenuBar', 'rMenu', 'rMenuItem'] __all__ = [
'rMenuBar',
'rMenu',
'rMenuItem',
def to_char_string(x): 'UndoMenuItem',
'CutMenuItem',
'CopyMenuItem',
'PasteMenuItem',
'ClearMenuItem',
'CloseMenuItem',
'DividerMenuItem'
]
# see:
# Programmer's Reference for System 6 (Ch 13 Menu Manager Update, pg 103+)
# TB Vol 3 Chapter 37
# TB Vol 1 Chapter 13
# TODO - menu item icon support (system 6) rItemStruct
# A menu ID must be unique for each menu; that is, no two menus
# can have the same ID or the system will fall. Similarly, no two
# items can have the same Item ID.
_menu_ids = {}
_menu_item_ids = {}
def _to_char_string(x):
if not x: return '""' if not x: return '""'
if x in (0x0a, 0x0d): return "\\n" if x in (0x0a, 0x0d): return "\\n"
if x == ord('"'): return "\"" if x == ord('"'): return "\""
if x >= 32 and x < 0x7e: return '"' + chr(x) + '"' if x >= 32 and x < 0x7e: return '"' + chr(x) + '"'
return "\\x{:02x}".format(x) return "\\${:02x}".format(x)
class rMenuBar(rObject): class rMenuBar(rObject):
rName = "rMenuBar" rName = "rMenuBar"
@ -39,7 +68,7 @@ class rMenuBar(rObject):
return rv return rv
# valid menu ids: $0001-$fffe
class rMenu(rObject): class rMenu(rObject):
rName = "rMenu" rName = "rMenu"
rType = 0x8009 rType = 0x8009
@ -59,7 +88,7 @@ class rMenu(rObject):
**kwargs **kwargs
): ):
super().__init__(id, attr) super().__init__(id, attr)
self.title = make_string(title, rPString) self.title = rPString.make_string(title)
self.children = children[:] self.children = children[:]
self.menuID = menuID self.menuID = menuID
@ -105,6 +134,16 @@ class rMenu(rObject):
return rv return rv
miUndo = 0xfa
miCut = 0xfb
miCopy = 0xfc
miPaste = 0xfd
miClear = 0xfe
miClose = 0xff
# valid menu item ids: $0100-$fffe
class rMenuItem(rObject): class rMenuItem(rObject):
rName = "rMenuItem" rName = "rMenuItem"
rType = 0x800a rType = 0x800a
@ -130,7 +169,7 @@ class rMenuItem(rObject):
**kwargs): **kwargs):
super().__init__(id, attr) super().__init__(id, attr)
self.title = make_string(title, rPString) self.title = rPString.make_string(title)
flags |= 0x8000 # title ref is resource flags |= 0x8000 # title ref is resource
if kwargs.get("bold"): flags |= 0x0001 if kwargs.get("bold"): flags |= 0x0001
@ -142,6 +181,9 @@ class rMenuItem(rObject):
if kwargs.get("outline"): flags |= 0x0800 if kwargs.get("outline"): flags |= 0x0800
if kwargs.get("shadow"): flags |= 0x1000 if kwargs.get("shadow"): flags |= 0x1000
# bit 15 of flags set if title ref is actually an
# item struct ref.
self.flags = flags self.flags = flags
self.itemChar = 0 self.itemChar = 0
@ -191,10 +233,58 @@ class rMenuItem(rObject):
"\t${:04x} /* title ref */" "\t${:04x} /* title ref */"
).format( ).format(
itemID, itemID,
to_char_string(self.itemChar), _to_char_string(self.itemChar),
to_char_string(self.altItemChar), _to_char_string(self.altItemChar),
self.checkMark, self.checkMark,
self.flags, self.flags,
self.title.get_id() self.title.get_id()
) )
def _singleton(func):
value = None
def inner():
nonlocal value
if not value: value = func()
return value
return inner
def DividerMenuItem():
return rMenuItem("-", flags = 0x0080) # disabled
def EditMenu(*children, **kwargs):
return rMenu(" Edit ",
UndoMenuItem(),
CutMenuItem(),
CopyMenuItem(),
PasteMenuItem(),
ClearMenuItem(),
*children,
**kwargs
)
@ _singleton
def UndoMenuItem():
# normally underlined....
return rMenuItem("Undo", "Zz", itemID = miUndo)
@ _singleton
def CutMenuItem():
return rMenuItem("Cut", "Xx", itemID = miCut)
@ _singleton
def CopyMenuItem():
return rMenuItem("Copy", "Cc", itemID = miCopy)
@ _singleton
def PasteMenuItem():
return rMenuItem("Paste", "Vv", itemID = miPaste)
@ _singleton
def ClearMenuItem():
return rMenuItem("Clear", "", itemID = miClear)
@ _singleton
def CloseMenuItem():
return rMenuItem("Close", "Ww", itemID = miClose)

11
rect.py
View File

@ -1,6 +1,6 @@
# point(h,v) or point(x=.., y=..) # point(h,v) or point(x=.., y=..)
__all__ = ['point', 'rect', 'size', 'format_rect', 'format_point', 'format_size'] __all__ = ['point', 'rect', 'size']
def all_defined(*args): return args.count(None)==0 def all_defined(*args): return args.count(None)==0
def all_none(*args): return args.count(None)==len(args) def all_none(*args): return args.count(None)==len(args)
@ -105,12 +105,3 @@ def rect(*args,
raise ValueError("bad rect parameter") raise ValueError("bad rect parameter")
def format_rect(x):
return "{{ {:d}, {:d}, {:d}, {:d} }}".format(*x)
def format_point(x):
return "{{ {:d}, {:d} }}".format(*x)
def format_size(x):
return "{{ {:d}, {:d} }}".format(*x)

View File

@ -72,14 +72,14 @@ def open_audio(file):
class rSoundSample(rObject): class rSoundSample(rObject):
""" """
filename: input file to read. format is .wav, .au, .aiff, or .aifc filename: input file to read. format is .wav, .au, .aiff, or .aifc
pitch: audio pitch, if this is a note. specify hz (eg 261.63) or name (eg c4) pitch: audio pitch, if this is a note. specify hz (eg 261.63) or name (eg c4)
rate: down/upsample audio to this rate (eg 26320) rate: down/upsample audio to this rate (eg 26320)
channel: stereo channel channel: stereo channel
Native samples are 26320 khz, c4 (261.63 hz) Native samples are 26320 khz, c4 (261.63 hz)
""" """
rName = "rSoundSample" rName = "rSoundSample"
rType = 0x8024 rType = 0x8024

30
utils.py Normal file
View File

@ -0,0 +1,30 @@
# __all__ = ("str_to_bytes", "make_string", "format_rect", "format_point", "format_size")
# helper functions
def str_to_bytes(text):
if isinstance(text, str): return text.encode("macroman")
if isinstance(text, bytes): return text
if isinstance(text, bytearray): return bytes(text)
raise TypeError("Bad text type: {}".format(type(text)))
def format_rect(x):
return "{{ {:d}, {:d}, {:d}, {:d} }}".format(*x)
def format_point(x):
return "{{ {:d}, {:d} }}".format(*x)
def format_size(x):
return "{{ {:d}, {:d} }}".format(*x)
# def make_string(text, rType=None):
# if not rType: rType = rPString
# if type(text) == rType: return text
# if type(text) in (str, bytes, bytearray): return rType(text)
# raise TypeError("Bad text type: {}".format(type(text)))

View File

@ -1,5 +1,6 @@
from base import * from base import *
from control import rControlTemplate, rControlList from control import rControlTemplate, rControlList
from utils import *
import struct import struct
@ -57,7 +58,7 @@ class rWindParam1(rObject):
super().__init__(id=id, attr=attr) super().__init__(id=id, attr=attr)
self.frameBits = frameBits self.frameBits = frameBits
if title: self.title = make_string(title) if title: self.title = rPString.make_string(title)
self.zoomRect=zoomRect self.zoomRect=zoomRect
self.color = None self.color = None
self.origin = origin self.origin = origin