diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index b5ae938b9c..5e47c93130 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -17,9 +17,9 @@ jobs:
shell: powershell
run: |
$wc = New-Object System.Net.WebClient
- $wc.DownloadFile("https://www.panda3d.org/download/panda3d-1.10.4.1/panda3d-1.10.4.1-tools-win64.zip", "thirdparty-tools.zip")
+ $wc.DownloadFile("https://www.panda3d.org/download/panda3d-1.10.5/panda3d-1.10.5-tools-win64.zip", "thirdparty-tools.zip")
Expand-Archive -Path thirdparty-tools.zip
- Move-Item -Path thirdparty-tools/panda3d-1.10.4.1/thirdparty -Destination .
+ Move-Item -Path thirdparty-tools/panda3d-1.10.5/thirdparty -Destination .
- name: Get thirdparty packages (macOS)
if: runner.os == 'macOS'
run: |
@@ -28,6 +28,18 @@ jobs:
mv panda3d-1.10.5/thirdparty thirdparty
rmdir panda3d-1.10.5
(cd thirdparty/darwin-libs-a && rm -rf rocket)
+ - name: Set up Python 3.8
+ uses: actions/setup-python@v1
+ with:
+ python-version: 3.8
+ - name: Build Python 3.8
+ run: |
+ python makepanda/makepanda.py --git-commit=${{github.sha}} --outputdir=built --everything --no-eigen --python-incdir=$pythonLocation/include --python-libdir=$pythonLocation/lib --verbose --threads=4
+ - name: Test Python 3.8
+ shell: bash
+ run: |
+ python -m pip install pytest
+ PYTHONPATH=built LD_LIBRARY_PATH=built/lib DYLD_LIBRARY_PATH=built/lib python -m pytest
- name: Set up Python 3.7
uses: actions/setup-python@v1
with:
diff --git a/direct/src/dist/FreezeTool.py b/direct/src/dist/FreezeTool.py
index 5d12a2fb5c..f7b2ea9b91 100644
--- a/direct/src/dist/FreezeTool.py
+++ b/direct/src/dist/FreezeTool.py
@@ -11,6 +11,7 @@ import struct
import io
import distutils.sysconfig as sysconf
import zipfile
+import importlib
from . import pefile
@@ -2349,12 +2350,36 @@ class PandaModuleFinder(modulefinder.ModuleFinder):
code += b'\n' if isinstance(code, bytes) else '\n'
co = compile(code, pathname, 'exec')
elif type == imp.PY_COMPILED:
- try:
- marshal_data = importlib._bootstrap_external._validate_bytecode_header(fp.read())
- except ImportError as exc:
- self.msgout(2, "raise ImportError: " + str(exc), pathname)
- raise
- co = marshal.loads(marshal_data)
+ if sys.version_info >= (3, 7):
+ try:
+ data = fp.read()
+ importlib._bootstrap_external._classify_pyc(data, fqname, {})
+ except ImportError as exc:
+ self.msgout(2, "raise ImportError: " + str(exc), pathname)
+ raise
+
+ co = marshal.loads(memoryview(data)[16:])
+ elif sys.version_info >= (3, 4):
+ try:
+ if sys.version_info >= (3, 5):
+ marshal_data = importlib._bootstrap_external._validate_bytecode_header(fp.read())
+ else:
+ marshal_data = importlib._bootstrap._validate_bytecode_header(fp.read())
+ except ImportError as exc:
+ self.msgout(2, "raise ImportError: " + str(exc), pathname)
+ raise
+
+ co = marshal.loads(marshal_data)
+ else:
+ if fp.read(4) != imp.get_magic():
+ self.msgout(2, "raise ImportError: Bad magic number", pathname)
+ raise ImportError("Bad magic number in %s" % pathname)
+
+ fp.read(4)
+ if sys.version_info >= (3, 3):
+ fp.read(4)
+
+ co = marshal.load(fp)
else:
co = None
diff --git a/direct/src/dist/commands.py b/direct/src/dist/commands.py
index b1d8422836..b70effdf87 100644
--- a/direct/src/dist/commands.py
+++ b/direct/src/dist/commands.py
@@ -8,7 +8,6 @@ from __future__ import print_function
import collections
import os
-import pip
import plistlib
import sys
import subprocess
@@ -112,6 +111,7 @@ PACKAGE_DATA_DIRS = {
('cefpython3/subprocess*', '', {'PKG_DATA_MAKE_EXECUTABLE'}),
('cefpython3/locals/*', 'locals', {}),
('cefpython3/Chromium Embedded Framework.framework/Resources', 'Chromium Embedded Framework.framework/Resources', {}),
+ ('cefpython3/Chromium Embedded Framework.framework/Chromium Embedded Framework', '', {'PKG_DATA_MAKE_EXECUTABLE'}),
],
}
@@ -392,6 +392,8 @@ class build_apps(setuptools.Command):
directory containing the Python runtime libraries, which will be added
to sys.path."""
+ import pip
+
self.announce('Gathering wheels for platform: {}'.format(platform), distutils.log.INFO)
whldir = os.path.join(self.build_base, '__whl_cache__')
@@ -638,6 +640,28 @@ class build_apps(setuptools.Command):
freezer_modules = set()
freezer_modpaths = set()
ext_suffixes = set()
+
+ def get_search_path_for(source_path):
+ search_path = [os.path.dirname(source_path)]
+ if use_wheels:
+ search_path.append(os.path.join(p3dwhlfn, 'deploy_libs'))
+
+ # If the .whl containing this file has a .libs directory, add
+ # it to the path. This is an auditwheel/numpy convention.
+ if '.whl' + os.sep in source_path:
+ whl, wf = source_path.split('.whl' + os.path.sep)
+ whl += '.whl'
+ rootdir = wf.split(os.path.sep, 1)[0]
+ search_path.append(os.path.join(whl, rootdir, '.libs'))
+
+ # Also look for more specific per-package cases, defined in
+ # PACKAGE_LIB_DIRS at the top of this file.
+ whl_name = os.path.basename(whl).split('-', 1)[0]
+ extra_dirs = PACKAGE_LIB_DIRS.get(whl_name, [])
+ for extra_dir in extra_dirs:
+ search_path.append(os.path.join(whl, extra_dir.replace('/', os.path.sep)))
+ return search_path
+
def create_runtime(appname, mainscript, use_console):
freezer = FreezeTool.Freezer(platform=platform, path=path)
freezer.addModule('__main__', filename=mainscript)
@@ -780,26 +804,8 @@ class build_apps(setuptools.Command):
continue
# If this is a dynamic library, search for dependencies.
- search_path = [os.path.dirname(source_path)]
- if use_wheels:
- search_path.append(os.path.join(p3dwhlfn, 'deploy_libs'))
-
- # If the .whl containing this file has a .libs directory, add
- # it to the path. This is an auditwheel/numpy convention.
- if '.whl' + os.sep in source_path:
- whl, wf = source_path.split('.whl' + os.path.sep)
- whl += '.whl'
- rootdir = wf.split(os.path.sep, 1)[0]
- search_path.append(os.path.join(whl, rootdir, '.libs'))
-
- # Also look for more specific per-package cases, defined in
- # PACKAGE_LIB_DIRS at the top of this file.
- whl_name = os.path.basename(whl).split('-', 1)[0]
- extra_dirs = PACKAGE_LIB_DIRS.get(whl_name, [])
- for extra_dir in extra_dirs:
- search_path.append(os.path.join(whl, extra_dir.replace('/', os.path.sep)))
-
target_path = os.path.join(builddir, basename)
+ search_path = get_search_path_for(source_path)
self.copy_with_dependencies(source_path, target_path, search_path)
# Copy over the tcl directory.
@@ -831,7 +837,7 @@ class build_apps(setuptools.Command):
whlfile = self._get_zip_file(whl)
filenames = whlfile.namelist()
for source_pattern, target_dir, flags in datadesc:
- srcglob = p3d.GlobPattern(source_pattern)
+ srcglob = p3d.GlobPattern(source_pattern.lower())
source_dir = os.path.dirname(source_pattern)
# Relocate the target dir to the build directory.
target_dir = target_dir.replace('/', os.sep)
@@ -845,12 +851,15 @@ class build_apps(setuptools.Command):
relpath = wf[len(source_dir) + 1:]
source_path = os.path.join(whl, wf)
target_path = os.path.join(target_dir, relpath)
- self.copy(source_path, target_path)
if 'PKG_DATA_MAKE_EXECUTABLE' in flags:
+ search_path = get_search_path_for(source_path)
+ self.copy_with_dependencies(source_path, target_path, search_path)
mode = os.stat(target_path).st_mode
mode |= stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH
os.chmod(target_path, mode)
+ else:
+ self.copy(source_path, target_path)
# Copy Game Files
self.announce('Copying game files for platform: {}'.format(platform), distutils.log.INFO)
@@ -1178,18 +1187,20 @@ class build_apps(setuptools.Command):
dylib = dylib.replace('@loader_path/../Frameworks/', '')
elif dylib.startswith('@executable_path/../Frameworks/'):
dylib = dylib.replace('@executable_path/../Frameworks/', '')
- elif dylib.startswith('@loader_path/'):
- dylib = dylib.replace('@loader_path/', '')
+ else:
+ for prefix in ('@loader_path/', '@rpath/'):
+ if dylib.startswith(prefix):
+ dylib = dylib.replace(prefix, '')
- # Do we need to flatten the relative reference?
- if '/' in dylib and flatten:
- new_dylib = '@loader_path/' + os.path.basename(dylib)
- str_size = len(cmd_data) - 16
- if len(new_dylib) < str_size:
- fp.seek(-str_size, os.SEEK_CUR)
- fp.write(new_dylib.encode('ascii').ljust(str_size, b'\0'))
- else:
- self.warn('Unable to rewrite dependency {}'.format(orig))
+ # Do we need to flatten the relative reference?
+ if '/' in dylib and flatten:
+ new_dylib = prefix + os.path.basename(dylib)
+ str_size = len(cmd_data) - 16
+ if len(new_dylib) < str_size:
+ fp.seek(-str_size, os.SEEK_CUR)
+ fp.write(new_dylib.encode('ascii').ljust(str_size, b'\0'))
+ else:
+ self.warn('Unable to rewrite dependency {}'.format(orig))
load_dylibs.append(dylib)
diff --git a/direct/src/gui/DirectSlider.py b/direct/src/gui/DirectSlider.py
index ddcd35d05d..c5823a9efc 100644
--- a/direct/src/gui/DirectSlider.py
+++ b/direct/src/gui/DirectSlider.py
@@ -10,6 +10,7 @@ from panda3d.core import *
from . import DirectGuiGlobals as DGG
from .DirectFrame import *
from .DirectButton import *
+from math import isnan
"""
import DirectSlider
@@ -89,12 +90,15 @@ class DirectSlider(DirectFrame):
def __setValue(self):
# This is the internal function that is called when
# self['value'] is directly assigned.
- self.guiItem.setValue(self['value'])
+ value = self['value']
+ assert not isnan(value)
+ self.guiItem.setValue(value)
def setValue(self, value):
# This is the public function that is meant to be called by a
# user that doesn't like to use (or doesn't understand) the
# preferred interface of self['value'].
+ assert not isnan(value)
self['value'] = value
def getValue(self):
diff --git a/doc/INSTALL b/doc/INSTALL
index 6a9606391e..5ca37886bc 100644
--- a/doc/INSTALL
+++ b/doc/INSTALL
@@ -146,7 +146,6 @@ it will show you the available command-line options:
--use-swscale --no-swscale (enable/disable use of SWSCALE)
--use-swresample --no-swresample (enable/disable use of SWRESAMPLE)
--use-ode --no-ode (enable/disable use of ODE)
- --use-physx --no-physx (enable/disable use of PHYSX)
--use-bullet --no-bullet (enable/disable use of BULLET)
--use-pandaphysics --no-pandaphysics (enable/disable use of PANDAPHYSICS)
--use-speedtree --no-speedtree (enable/disable use of SPEEDTREE)
@@ -193,7 +192,6 @@ it will show you the available command-line options:
--use-mfc --no-mfc (enable/disable use of MFC)
--use-wx --no-wx (enable/disable use of WX)
--use-fltk --no-fltk (enable/disable use of FLTK)
- --use-rocket --no-rocket (enable/disable use of ROCKET)
--use-carbon --no-carbon (enable/disable use of CARBON)
--use-cocoa --no-cocoa (enable/disable use of COCOA)
--use-x11 --no-x11 (enable/disable use of X11)
diff --git a/doc/ReleaseNotes b/doc/ReleaseNotes
index a89062a341..f706d7e495 100644
--- a/doc/ReleaseNotes
+++ b/doc/ReleaseNotes
@@ -11,8 +11,11 @@ This is a recommended bugfix release, especially for macOS users.
* Fix NaN assertions when particles get very large positions (#822)
* Add support for Autodesk Maya 2020
* Fix maya2egg erroring when running from a pip installation (#709)
+* Support DualShock 4 (2nd gen) controller on Windows
* Support .pz and .gz compressed models in deployment system
* Support implicit namespace packages in deployment system (#778)
+* Fix issues when using CEF Python on macOS with deployment system
+* Fix deployment system issues reading .pyc files in some Python versions
* Fix error with distutils package when deploying in a "virtualenv" env (#747)
* Fix "NameError: name 'mdef' is not defined" error when deploying (#721)
* Deployment system now strips weird -psn_* argument passed to macOS GUI apps
diff --git a/makepanda/installer.nsi b/makepanda/installer.nsi
index f96f6f15b9..3ad99e7875 100644
--- a/makepanda/installer.nsi
+++ b/makepanda/installer.nsi
@@ -78,8 +78,6 @@ LangString DESC_SecFMOD ${LANG_ENGLISH} "Support for decoding and playing audio
LangString DESC_SecFFMpeg ${LANG_ENGLISH} "Support for decoding video and audio via the FFMpeg library. Without this option, Panda3D will only be able to play .wav and .ogg audio files."
LangString DESC_SecBullet ${LANG_ENGLISH} "Support for the Bullet physics engine."
LangString DESC_SecODE ${LANG_ENGLISH} "Support for the Open Dynamics Engine to implement physics."
-LangString DESC_SecPhysX ${LANG_ENGLISH} "Support for NVIDIA PhysX to implement physics."
-LangString DESC_SecRocket ${LANG_ENGLISH} "Support for the libRocket GUI library. This is an optional library that offers an HTML/CSS-like approach to creating user interfaces."
LangString DESC_SecTools ${LANG_ENGLISH} "Useful tools and model converters to help with Panda3D development. Recommended."
LangString DESC_SecGroupPython ${LANG_ENGLISH} "Contains modules that provide Python support for Panda3D."
LangString DESC_SecPyShared ${LANG_ENGLISH} "Contains the common Python code used by the Panda3D Python bindings."
@@ -115,8 +113,6 @@ var MANPAGE
!insertmacro !defineifexist HAVE_FFMPEG "${BUILT}\bin\libp3ffmpeg.dll"
!insertmacro !defineifexist HAVE_BULLET "${BUILT}\bin\libpandabullet.dll"
!insertmacro !defineifexist HAVE_ODE "${BUILT}\bin\libpandaode.dll"
-!insertmacro !defineifexist HAVE_PHYSX "${BUILT}\bin\libpandaphysx.dll"
-!insertmacro !defineifexist HAVE_ROCKET "${BUILT}\bin\libp3rocket.dll"
!insertmacro !defineifexist HAVE_SAMPLES "${SOURCE}\samples"
!insertmacro !defineifexist HAVE_MAX_PLUGINS "${BUILT}\plugins\*.dlo"
!insertmacro !defineifexist HAVE_MAYA_PLUGINS "${BUILT}\plugins\*.mll"
@@ -174,22 +170,6 @@ var MANPAGE
SkipODEPyd:
!endif
- !ifdef HAVE_PHYSX
- SectionGetFlags ${SecPhysX} $R0
- IntOp $R0 $R0 & ${SF_SELECTED}
- StrCmp $R0 ${SF_SELECTED} 0 SkipPhysXPyd
- File /nonfatal /r "${BUILT}\panda3d\physx${EXT_SUFFIX}"
- SkipPhysXPyd:
- !endif
-
- !ifdef HAVE_ROCKET
- SectionGetFlags ${SecRocket} $R0
- IntOp $R0 $R0 & ${SF_SELECTED}
- StrCmp $R0 ${SF_SELECTED} 0 SkipRocketPyd
- File /nonfatal /r "${BUILT}\panda3d\rocket${EXT_SUFFIX}"
- SkipRocketPyd:
- !endif
-
SetOutPath $INSTDIR\pandac\input
File /r "${BUILT}\pandac\input\*"
SetOutPath $INSTDIR\Pmw
@@ -329,31 +309,6 @@ SectionGroup "Panda3D Libraries"
File "${BUILT}\bin\libpandaode.dll"
SectionEnd
!endif
-
- !ifdef HAVE_PHYSX
- Section "NVIDIA PhysX" SecPhysX
- ; Only enable in "Full"
- SectionIn 2
-
- SetOutPath "$INSTDIR\bin"
- File "${BUILT}\bin\libpandaphysx.dll"
- File /nonfatal /r "${BUILT}\bin\PhysX*.dll"
- File /nonfatal /r "${BUILT}\bin\NxCharacter*.dll"
- File /nonfatal /r "${BUILT}\bin\cudart*.dll"
- SectionEnd
- !endif
-
- !ifdef HAVE_ROCKET
- Section "libRocket GUI" SecRocket
- SectionIn 1 2
-
- SetOutPath "$INSTDIR\bin"
- File "${BUILT}\bin\libp3rocket.dll"
- File /nonfatal /r "${BUILT}\bin\Rocket*.dll"
- File /nonfatal /r "${BUILT}\bin\_rocket*.pyd"
- File /nonfatal /r "${BUILT}\bin\boost_python*.dll"
- SectionEnd
- !endif
SectionGroupEnd
Section "Tools and utilities" SecTools
@@ -914,12 +869,6 @@ SectionEnd
!ifdef HAVE_ODE
!insertmacro MUI_DESCRIPTION_TEXT ${SecODE} $(DESC_SecODE)
!endif
- !ifdef HAVE_PHYSX
- !insertmacro MUI_DESCRIPTION_TEXT ${SecPhysX} $(DESC_SecPhysX)
- !endif
- !ifdef HAVE_ROCKET
- !insertmacro MUI_DESCRIPTION_TEXT ${SecRocket} $(DESC_SecRocket)
- !endif
!insertmacro MUI_DESCRIPTION_TEXT ${SecTools} $(DESC_SecTools)
!insertmacro MUI_DESCRIPTION_TEXT ${SecGroupPython} $(DESC_SecGroupPython)
!insertmacro MUI_DESCRIPTION_TEXT ${SecPyShared} $(DESC_SecPyShared)
diff --git a/makepanda/makepackage.py b/makepanda/makepackage.py
index 9729f0e3f3..c725317d1e 100755
--- a/makepanda/makepackage.py
+++ b/makepanda/makepackage.py
@@ -610,6 +610,10 @@ def MakeInstallerOSX(version, python_versions=[], installdir=None, **kwargs):
dist.write(' \n')
dist.write(' \n')
dist.write(' %s\n' % ReadFile("doc/LICENSE"))
+ dist.write(' ')
+ dist.write('WARNING: From Panda3D version 1.10.5 onwards, the default installation has been changed from /Developer/Panda3D to /Library/Developer/Panda3D\n')
+ dist.write('This installation script will remove any existing installation in /Developer and if possible create a symbolic link towards /Library/Developer/Panda3D\n')
+ dist.write(' ')
dist.write('
-
-
-
-
-
-
-
-
diff --git a/samples/rocket-console/assets/modenine.nfo b/samples/rocket-console/assets/modenine.nfo
deleted file mode 100644
index c6af4f1f8b..0000000000
--- a/samples/rocket-console/assets/modenine.nfo
+++ /dev/null
@@ -1,18 +0,0 @@
-ModeNine
-
-Based on Andrew Bulhak's ModeSeven, in turn inspired by the screen
-output of the BBC Micro.
-
-copyright:
-(C) 1998 Andrew C. Bulhak
-(C) 2001 Graham H Freeman
-
-Freely Distributable.
-
-All we ask is that this readme file must be included with the font package.
-Impresarios of free font sites and shovelware cd-roms, this means you!
-
-If you think this font is doovy, let us know at fonts@grudnuk.com, and we
-might actually make more fonts.
-
-Another fine Grudnuk Creations produkt | http://grudnuk.com/
\ No newline at end of file
diff --git a/samples/rocket-console/assets/modenine.ttf b/samples/rocket-console/assets/modenine.ttf
deleted file mode 100644
index c0b00462d7..0000000000
Binary files a/samples/rocket-console/assets/modenine.ttf and /dev/null differ
diff --git a/samples/rocket-console/assets/monitor.egg.pz b/samples/rocket-console/assets/monitor.egg.pz
deleted file mode 100644
index 9c9f3675fd..0000000000
Binary files a/samples/rocket-console/assets/monitor.egg.pz and /dev/null differ
diff --git a/samples/rocket-console/assets/monitor.txt b/samples/rocket-console/assets/monitor.txt
deleted file mode 100644
index f2e1f7265e..0000000000
--- a/samples/rocket-console/assets/monitor.txt
+++ /dev/null
@@ -1,12 +0,0 @@
-
-This is an edited version of this file from blendswap.com (http://www.blendswap.com/blends/view/74468).
-
-VERY IMPORTANT LICENSE INFORMATION:
-
-This file has been released by buzo under the following license:
-
- Creative Commons Zero (Public Domain)
-
-You can use this model for any purposes according to the following conditions:
-
- There are no requirements for CC-Zero licensed blends.
\ No newline at end of file
diff --git a/samples/rocket-console/assets/rkt.rcss b/samples/rocket-console/assets/rkt.rcss
deleted file mode 100644
index ebc49f50fb..0000000000
--- a/samples/rocket-console/assets/rkt.rcss
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
-* Default styles for all the basic elements.
-*/
-
-div
-{
- display: block;
-}
-
-p
-{
- display: block;
-}
-
-h1
-{
- display: block;
-}
-
-em
-{
- font-style: italic;
-}
-
-strong
-{
- font-weight: bold;
-}
-
-datagrid
-{
- display: block;
-}
-
-select, dataselect, datacombo
-{
- text-align: left;
-}
-
-tabset tabs
-{
- display: block;
-}
-
diff --git a/samples/rocket-console/assets/takeyga_kb.egg b/samples/rocket-console/assets/takeyga_kb.egg
deleted file mode 100644
index 3085947839..0000000000
--- a/samples/rocket-console/assets/takeyga_kb.egg
+++ /dev/null
@@ -1,316 +0,0 @@
- { Z-up }
- takeyga_kb {
- diffr { 0.800000 }
- diffg { 0.800000 }
- diffb { 0.800000 }
- specr { 0.500000 }
- specg { 0.500000 }
- specb { 0.500000 }
- shininess { 12.5 }
- ambr { 1.000000 }
- ambg { 1.000000 }
- ambb { 1.000000 }
- emitr { 0.000000 }
- emitg { 0.000000 }
- emitb { 0.000000 }
-}
-
- Texture.001 {
- "./tex/takeyga_kb_specular.dds"
- envtype { MODULATE }
- minfilter { LINEAR_MIPMAP_LINEAR }
- magfilter { LINEAR_MIPMAP_LINEAR }
- wrap { REPEAT }
-}
-
- Tex {
- "./tex/takeyga_kb_diffuse.dds"
- envtype { MODULATE }
- minfilter { LINEAR_MIPMAP_LINEAR }
- magfilter { LINEAR_MIPMAP_LINEAR }
- wrap { REPEAT }
-}
-
- Texture {
- "./tex/takeyga_kb_normal.dds"
- envtype { NORMAL }
- minfilter { LINEAR_MIPMAP_LINEAR }
- magfilter { LINEAR_MIPMAP_LINEAR }
- wrap { REPEAT }
-}
-
- Cube.001 {
- {
- {
- 0.08499996364116669 0.0 0.0 0.0
- 0.0 0.23999987542629242 0.0 0.0
- 0.0 0.0 0.02500000037252903 0.0
- 0.0 0.0 0.0 1.0
- }
- }
-
- Cube.001 {
-
- 0 {0.082953 0.240000 -0.025000
- {
- 0.158203125 0.595703125
- }
- }
- 1 {0.082953 -0.240000 -0.025000
- {
- 0.98828125 0.6015625
- }
- }
- 2 {-0.085000 -0.240000 -0.025000
- {
- 0.98828125 0.986328125
- }
- }
- 3 {-0.085000 0.240000 -0.025000
- {
- 0.162109375 0.98828125
- }
- }
- 4 {0.073544 0.227744 -0.005546
- {
- 0.990234375 0.017578125
- }
- }
- 5 {-0.067932 0.223167 0.018996
- {
- 0.98046875 0.46875
- }
- }
- 6 {-0.067932 -0.223167 0.018996
- {
- 0.017578125 0.470703125
- }
- }
- 7 {0.073544 -0.227744 -0.005546
- {
- 0.01953125 0.013671875
- }
- }
- 8 {0.082372 0.237328 -0.015273
- {
- 0.9794921875 0.552734375
- }
- }
- 9 {0.073544 0.227744 -0.005546
- {
- 0.9765625 0.57421875
- }
- }
- 10 {0.073544 -0.227744 -0.005546
- {
- 0.025390625 0.57421875
- }
- }
- 11 {0.082372 -0.237328 -0.015273
- {
- 0.0234375 0.5537109375
- }
- }
- 12 {0.082372 -0.237328 -0.015273
- {
- 0.0703125 0.6123046875
- }
- }
- 13 {0.073544 -0.227744 -0.005546
- {
- 0.095703125 0.615234375
- }
- }
- 14 {-0.067932 -0.223167 0.018996
- {
- 0.13671875 0.97265625
- }
- }
- 15 {-0.080884 -0.235006 0.001122
- {
- 0.07421875 0.982421875
- }
- }
- 16 {-0.080884 -0.235006 0.001122
- {
- 0.0166015625 0.5361328125
- }
- }
- 17 {-0.067932 -0.223167 0.018996
- {
- 0.017578125 0.58203125
- }
- }
- 18 {-0.067932 0.223167 0.018996
- {
- 0.978515625 0.580078125
- }
- }
- 19 {-0.080884 0.235006 0.001122
- {
- 0.984375 0.5341796875
- }
- }
- 20 {0.082372 0.237328 -0.015273
- {
- 0.0703125 0.6123046875
- }
- }
- 21 {0.082953 0.240000 -0.025000
- {
- 0.044921875 0.609375
- }
- }
- 22 {-0.085000 0.240000 -0.025000
- {
- 0.01171875 0.9921875
- }
- }
- 23 {-0.080884 0.235006 0.001122
- {
- 0.07421875 0.982421875
- }
- }
- 24 {0.082953 0.240000 -0.025000
- {
- 0.982421875 0.53125
- }
- }
- 25 {0.082372 0.237328 -0.015273
- {
- 0.9794921875 0.552734375
- }
- }
- 26 {0.082372 -0.237328 -0.015273
- {
- 0.0234375 0.5537109375
- }
- }
- 27 {0.082953 -0.240000 -0.025000
- {
- 0.021484375 0.533203125
- }
- }
- 28 {0.082953 -0.240000 -0.025000
- {
- 0.044921875 0.609375
- }
- }
- 29 {0.082372 -0.237328 -0.015273
- {
- 0.0703125 0.6123046875
- }
- }
- 30 {-0.080884 -0.235006 0.001122
- {
- 0.07421875 0.982421875
- }
- }
- 31 {-0.085000 -0.240000 -0.025000
- {
- 0.01171875 0.9921875
- }
- }
- 32 {-0.085000 -0.240000 -0.025000
- {
- 0.015625 0.490234375
- }
- }
- 33 {-0.080884 -0.235006 0.001122
- {
- 0.0166015625 0.5361328125
- }
- }
- 34 {-0.080884 0.235006 0.001122
- {
- 0.984375 0.5341796875
- }
- }
- 35 {-0.085000 0.240000 -0.025000
- {
- 0.990234375 0.48828125
- }
- }
- 36 {0.073544 0.227744 -0.005546
- {
- 0.095703125 0.615234375
- }
- }
- 37 {0.082372 0.237328 -0.015273
- {
- 0.0703125 0.6123046875
- }
- }
- 38 {-0.080884 0.235006 0.001122
- {
- 0.07421875 0.982421875
- }
- }
- 39 {-0.067932 0.223167 0.018996
- {
- 0.13671875 0.97265625
- }
- }}
-
-
- {
- { Tex }
- { takeyga_kb }
- {0.000000 0.000000 -1.000000}
- { 0 1 2 3 [ { Cube.001 }}
- }
- {
- { Tex }
- { takeyga_kb }
- {0.508027 -0.000000 0.861341}
- { 4 5 6 7 ][ { Cube.001 }}
- }
- {
- { Tex }
- { takeyga_kb }
- {0.966167 -0.000000 0.257917}
- { 8 9 10 11 ][ { Cube.001 }}
- }
- {
- { Tex }
- { takeyga_kb }
- {0.028240 -0.996449 0.079322}
- { 12 13 14 15 ][ { Cube.001 }}
- }
- {
- { Tex }
- { takeyga_kb }
- {-0.978036 0.000000 0.208436}
- { 16 17 18 19 ][ { Cube.001 }}
- }
- {
- { Tex }
- { takeyga_kb }
- {0.001260 0.999752 0.022233}
- { 20 21 22 23 ][ { Cube.001 }}
- }
- {
- { Tex }
- { takeyga_kb }
- {0.999846 -0.000000 0.017550}
- { 24 25 26 27 ][ { Cube.001 }}
- }
- {
- { Tex }
- { takeyga_kb }
- {0.001259 -0.999752 0.022233}
- { 28 29 30 31 ][ { Cube.001 }}
- }
- {
- { Tex }
- { takeyga_kb }
- {-0.998928 0.000000 0.046291}
- { 32 33 34 35 ][ { Cube.001 }}
- }
- {
- { Tex }
- { takeyga_kb }
- {0.028241 0.996449 0.079322}
- { 36 37 38 39 ][ { Cube.001 }}
- }
- }
diff --git a/samples/rocket-console/assets/tex/takeyga_kb_diffuse.dds b/samples/rocket-console/assets/tex/takeyga_kb_diffuse.dds
deleted file mode 100644
index 406e689545..0000000000
Binary files a/samples/rocket-console/assets/tex/takeyga_kb_diffuse.dds and /dev/null differ
diff --git a/samples/rocket-console/assets/tex/takeyga_kb_normal.dds b/samples/rocket-console/assets/tex/takeyga_kb_normal.dds
deleted file mode 100644
index a949e2be69..0000000000
Binary files a/samples/rocket-console/assets/tex/takeyga_kb_normal.dds and /dev/null differ
diff --git a/samples/rocket-console/assets/tex/takeyga_kb_specular.dds b/samples/rocket-console/assets/tex/takeyga_kb_specular.dds
deleted file mode 100644
index a63868f99c..0000000000
Binary files a/samples/rocket-console/assets/tex/takeyga_kb_specular.dds and /dev/null differ
diff --git a/samples/rocket-console/assets/window.rcss b/samples/rocket-console/assets/window.rcss
deleted file mode 100644
index 0e7adcedf9..0000000000
--- a/samples/rocket-console/assets/window.rcss
+++ /dev/null
@@ -1,56 +0,0 @@
-body
-{
- font-family: "MODENINE";
- font-weight: normal;
- font-style: normal;
- font-size: 15;
-
-}
-
-body.window
-{
- padding-top: 43px;
- padding-bottom: 20px;
-
- min-width: 250px;
-
- min-height: 135px;
- max-height: 700px;
-
-}
-
-
-
-div#title_bar
-{
- z-index: 1;
-
- position: absolute;
- top: 0px;
- left: 0px;
-
- text-align: center;
-
- color: #fff;
- background-color: #22f;
-}
-
-
-div#title_bar span
-{
- padding-top: 17px;
- padding-bottom: 48px;
-
- font-size: 32;
- font-weight: bold;
-
- outline-font-effect: outline;
- outline-width: 1px;
- outline-color: black;
-}
-
-div#title_bar_content
-{
- text-align: center;
- color: #cff;
-}
diff --git a/samples/rocket-console/assets/window.rml b/samples/rocket-console/assets/window.rml
deleted file mode 100644
index 47336e7ab2..0000000000
--- a/samples/rocket-console/assets/window.rml
+++ /dev/null
@@ -1,42 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
- ]
-
- Rocket Sample
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/samples/rocket-console/console.py b/samples/rocket-console/console.py
deleted file mode 100644
index e32d2408d4..0000000000
--- a/samples/rocket-console/console.py
+++ /dev/null
@@ -1,153 +0,0 @@
-"""
-Simple console widget for rocket
-"""
-import sys, os.path
-
-# workaround: https://www.panda3d.org/forums/viewtopic.php?t=10062&p=99697#p99054
-#from panda3d import rocket
-import _rocketcore as rocket
-
-from panda3d.rocket import RocketRegion, RocketInputHandler
-
-class Console(object):
- def __init__(self, base, context, cols, rows, commandHandler):
- self.base = base
-
- self.context = context
- self.loadFonts()
- self.cols = cols
- self.rows = rows
- self.commandHandler = commandHandler
-
- self.setupConsole()
- self.allowEditing(True)
-
- def getTextContainer(self):
- return self.textEl
-
- def setPrompt(self, prompt):
- self.consolePrompt = prompt
-
- def allowEditing(self, editMode):
- self.editMode = editMode
- if editMode:
- self.input = ""
- if not self.lastLine:
- self.addLine("")
- self.newEditLine()
-
- def loadFonts(self):
- rocket.LoadFontFace("Perfect DOS VGA 437.ttf")
-
- def setupConsole(self):
- self.document = self.context.LoadDocument("console.rml")
- if not self.document:
- raise AssertionError("did not find console.rml")
-
- el = self.document.GetElementById('content')
-
- self.textEl = el
-
- # roundabout way of accessing the current object through rocket event...
-
- # add attribute to let Rocket know about the receiver
- self.context.console = self
-
- # then reference through the string format (dunno how else to get the event...)
- self.document.AddEventListener(
- 'keydown', 'document.context.console.handleKeyDown(event)', True)
- self.document.AddEventListener(
- 'textinput', 'document.context.console.handleTextInput(event)', True)
-
- self.consolePrompt = "C:\\>"
-
- self.input = ""
- self.lastLine = None
-
- self.blinkState = False
- self.queueBlinkCursor()
-
- self.document.Show()
-
- def queueBlinkCursor(self):
- self.base.taskMgr.doMethodLater(0.2, self.blinkCursor, 'blinkCursor')
-
- def blinkCursor(self, task):
- self.blinkState = not self.blinkState
- if self.editMode:
- self.updateEditLine(self.input)
- self.queueBlinkCursor()
-
- def escape(self, text):
- return text. \
- replace('<', '<'). \
- replace('>', '>'). \
- replace('"', '"')
-
- def addLine(self, text):
- curKids = list(self.textEl.child_nodes)
- while len(curKids) >= self.rows:
- self.textEl.RemoveChild(curKids[0])
- curKids = curKids[1:]
-
- line = self.document.CreateTextNode(self.escape(text) + '\n')
- self.textEl.AppendChild(line)
- self.lastLine = line
-
- def addLines(self, lines):
- for line in lines:
- self.addLine(line)
-
- def updateEditLine(self, newInput=''):
- newText = self.consolePrompt + newInput
- self.lastLine.text = self.escape(newText) + (self.blinkState and '_' or '')
- self.input = newInput
-
- def scroll(self):
- self.blinkState = False
- self.updateEditLine(self.input + '\n')
-
- def handleKeyDown(self, event):
- """
- Handle control keys
- """
- keyId = event.parameters['key_identifier']
- if not self.editMode:
- if keyId == rocket.key_identifier.PAUSE:
- if event.parameters['ctrl_key']:
- self.commandHandler(None)
-
- return
-
- if keyId == rocket.key_identifier.RETURN:
- # emit line without cursor
- self.scroll()
-
- # handle command
- self.commandHandler(self.input)
-
- if self.editMode:
- # start with new "command"
- self.addLine(self.consolePrompt)
- self.updateEditLine("")
-
- elif keyId == rocket.key_identifier.BACK:
- self.updateEditLine(self.input[0:-1])
-
- def handleTextInput(self, event):
- if not self.editMode:
- return
-
- # handle normal text character
- data = event.parameters['data']
- if 32 <= data < 128:
- self.updateEditLine(self.input + chr(data))
-
- def newEditLine(self):
- self.addLine("")
- self.updateEditLine()
-
- def cls(self):
- curKids = list(self.textEl.child_nodes)
- for kid in curKids:
- self.textEl.RemoveChild(kid)
\ No newline at end of file
diff --git a/samples/rocket-console/main.py b/samples/rocket-console/main.py
deleted file mode 100644
index 7269c4b960..0000000000
--- a/samples/rocket-console/main.py
+++ /dev/null
@@ -1,410 +0,0 @@
-"""
-Show how to use libRocket in Panda3D.
-"""
-import sys
-from panda3d.core import loadPrcFile, loadPrcFileData, Point3,Vec4, Mat4, LoaderOptions # @UnusedImport
-from panda3d.core import DirectionalLight, AmbientLight, PointLight
-from panda3d.core import Texture, PNMImage
-from panda3d.core import PandaSystem
-import random
-from direct.interval.LerpInterval import LerpHprInterval, LerpPosInterval, LerpFunc
-from direct.showbase.ShowBase import ShowBase
-
-# workaround: https://www.panda3d.org/forums/viewtopic.php?t=10062&p=99697#p99054
-#from panda3d import rocket
-import _rocketcore as rocket
-
-from panda3d.rocket import RocketRegion, RocketInputHandler
-
-loadPrcFileData("", "model-path $MAIN_DIR/assets")
-
-import console
-
-global globalClock
-
-class MyApp(ShowBase):
-
- def __init__(self):
- ShowBase.__init__(self)
-
- self.win.setClearColor(Vec4(0.2, 0.2, 0.2, 1))
-
- self.disableMouse()
-
- self.render.setShaderAuto()
-
- dlight = DirectionalLight('dlight')
- alight = AmbientLight('alight')
- dlnp = self.render.attachNewNode(dlight)
- alnp = self.render.attachNewNode(alight)
- dlight.setColor((0.8, 0.8, 0.5, 1))
- alight.setColor((0.2, 0.2, 0.2, 1))
- dlnp.setHpr(0, -60, 0)
- self.render.setLight(dlnp)
- self.render.setLight(alnp)
-
- # Put lighting on the main scene
- plight = PointLight('plight')
- plnp = self.render.attachNewNode(plight)
- plnp.setPos(0, 0, 10)
- self.render.setLight(plnp)
- self.render.setLight(alnp)
-
- self.loadRocketFonts()
-
- self.loadingTask = None
-
- #self.startModelLoadingAsync()
- self.startModelLoading()
-
- self.inputHandler = RocketInputHandler()
- self.mouseWatcher.attachNewNode(self.inputHandler)
-
- self.openLoadingDialog()
-
- def loadRocketFonts(self):
- """ Load fonts referenced from e.g. 'font-family' RCSS directives.
-
- Note: the name of the font as used in 'font-family'
- is not always the same as the filename;
- open the font in your OS to see its display name.
- """
- rocket.LoadFontFace("modenine.ttf")
-
-
- def startModelLoading(self):
- self.monitorNP = None
- self.keyboardNP = None
- self.loadingError = False
-
- self.taskMgr.doMethodLater(1, self.loadModels, 'loadModels')
-
- def loadModels(self, task):
- self.monitorNP = self.loader.loadModel("monitor")
- self.keyboardNP = self.loader.loadModel("takeyga_kb")
-
- def startModelLoadingAsync(self):
- """
- NOTE: this seems to invoke a few bugs (crashes, sporadic model
- reading errors, etc) so is disabled for now...
- """
- self.monitorNP = None
- self.keyboardNP = None
- self.loadingError = False
-
- # force the "loading" to take some time after the first run...
- options = LoaderOptions()
- options.setFlags(options.getFlags() | LoaderOptions.LFNoCache)
-
- def gotMonitorModel(model):
- if not model:
- self.loadingError = True
- self.monitorNP = model
-
- self.loader.loadModel("monitor", loaderOptions=options, callback=gotMonitorModel)
-
- def gotKeyboardModel(model):
- if not model:
- self.loadingError = True
- self.keyboardNP = model
-
- self.loader.loadModel("takeyga_kb", loaderOptions=options, callback=gotKeyboardModel)
-
- def openLoadingDialog(self):
- self.userConfirmed = False
-
- self.windowRocketRegion = RocketRegion.make('pandaRocket', self.win)
- self.windowRocketRegion.setActive(1)
-
- self.windowRocketRegion.setInputHandler(self.inputHandler)
-
- self.windowContext = self.windowRocketRegion.getContext()
-
- self.loadingDocument = self.windowContext.LoadDocument("loading.rml")
- if not self.loadingDocument:
- raise AssertionError("did not find loading.rml")
-
- self.loadingDots = 0
- el = self.loadingDocument.GetElementById('loadingLabel')
- self.loadingText = el.first_child
- self.stopLoadingTime = globalClock.getFrameTime() + 3
- self.loadingTask = self.taskMgr.add(self.cycleLoading, 'doc changer')
-
-
- # note: you may encounter errors like 'KeyError: 'document'"
- # when invoking events using methods from your own scripts with this
- # obvious code:
- #
- # self.loadingDocument.AddEventListener('aboutToClose',
- # self.onLoadingDialogDismissed, True)
- #
- # A workaround is to define callback methods in standalone Python
- # files with event, self, and document defined to None.
- #
- # see https://www.panda3d.org/forums/viewtopic.php?f=4&t=16412
- #
-
- # Or, use this indirection technique to work around the problem,
- # by publishing the app into the context, then accessing it through
- # the document's context...
-
- self.windowContext.app = self
- self.loadingDocument.AddEventListener('aboutToClose',
- 'document.context.app.handleAboutToClose()', True)
-
- self.loadingDocument.Show()
-
- def handleAboutToClose(self):
- self.userConfirmed = True
- if self.monitorNP and self.keyboardNP:
- self.onLoadingDialogDismissed()
-
- def attachCustomRocketEvent(self, document, rocketEventName, pandaHandler, once=False):
- # handle custom event
-
- # note: you may encounter errors like 'KeyError: 'document'"
- # when invoking events using methods from your own scripts with this
- # obvious code:
- #
- # self.loadingDocument.AddEventListener('aboutToClose',
- # self.onLoadingDialogDismissed, True)
- #
- # see https://www.panda3d.org/forums/viewtopic.php?f=4&t=16412
-
-
- # this technique converts Rocket events to Panda3D events
-
- pandaEvent = 'panda.' + rocketEventName
-
- document.AddEventListener(
- rocketEventName,
- "messenger.send('" + pandaEvent + "', [event])")
-
- if once:
- self.acceptOnce(pandaEvent, pandaHandler)
- else:
- self.accept(pandaEvent, pandaHandler)
-
-
- def cycleLoading(self, task):
- """
- Update the "loading" text in the initial window until
- the user presses Space, Enter, or Escape or clicks (see loading.rxml)
- or sufficient time has elapsed (self.stopLoadingTime).
- """
- text = self.loadingText
-
- now = globalClock.getFrameTime()
- if self.monitorNP and self.keyboardNP:
- text.text = "Ready"
- if now > self.stopLoadingTime or self.userConfirmed:
- self.onLoadingDialogDismissed()
- return task.done
- elif self.loadingError:
- text.text = "Assets not found"
- else:
- count = 5
- intv = int(now * 4) % count # @UndefinedVariable
- text.text = "Loading" + ("." * (1+intv)) + (" " * (2 - intv))
-
- return task.cont
-
- def onLoadingDialogDismissed(self):
- """ Once a models are loaded, stop 'loading' and proceed to 'start' """
- if self.loadingDocument:
- if self.loadingTask:
- self.taskMgr.remove(self.loadingTask)
- self.loadingTask = None
-
- self.showStarting()
-
- def fadeOut(self, element, time):
- """ Example updating RCSS attributes from code
- by modifying the 'color' RCSS attribute to slowly
- change from solid to transparent.
-
- element: the Rocket element whose style to modify
- time: time in seconds for fadeout
- """
-
- # get the current color from RCSS effective style
- color = element.style.color
- # convert to RGBA form
- prefix = color[:color.rindex(',')+1].replace('rgb(', 'rgba(')
-
- def updateAlpha(t):
- # another way of setting style on a specific element
- attr = 'color: ' + prefix + str(int(t)) +');'
- element.SetAttribute('style', attr)
-
- alphaInterval = LerpFunc(updateAlpha,
- duration=time,
- fromData=255,
- toData=0,
- blendType='easeIn')
-
- return alphaInterval
-
- def showStarting(self):
- """ Models are loaded, so update the dialog,
- fade out, then transition to the console. """
- self.loadingText.text = 'Starting...'
-
- alphaInterval = self.fadeOut(self.loadingText, 0.5)
- alphaInterval.setDoneEvent('fadeOutFinished')
-
- def fadeOutFinished():
- if self.loadingDocument:
- self.loadingDocument.Close()
- self.loadingDocument = None
- self.createConsole()
-
- self.accept('fadeOutFinished', fadeOutFinished)
-
- alphaInterval.start()
-
- def createConsole(self):
- """ Create the in-world console, which displays
- a RocketRegion in a GraphicsBuffer, which appears
- in a Texture on the monitor model. """
-
- self.monitorNP.reparentTo(self.render)
- self.monitorNP.setScale(1.5)
-
- self.keyboardNP.reparentTo(self.render)
- self.keyboardNP.setHpr(-90, 0, 15)
- self.keyboardNP.setScale(20)
-
- self.placeItems()
-
- self.setupRocketConsole()
-
- # re-enable mouse
- mat=Mat4(self.camera.getMat())
- mat.invertInPlace()
- self.mouseInterfaceNode.setMat(mat)
- self.enableMouse()
-
- def placeItems(self):
- self.camera.setPos(0, -20, 0)
- self.camera.setHpr(0, 0, 0)
- self.monitorNP.setPos(0, 0, 1)
- self.keyboardNP.setPos(0, -5, -2.5)
-
-
- def setupRocketConsole(self):
- """
- Place a new rocket window onto a texture
- bound to the front of the monitor.
- """
- self.win.setClearColor(Vec4(0.5, 0.5, 0.8, 1))
-
- faceplate = self.monitorNP.find("**/Faceplate")
- assert faceplate
-
- mybuffer = self.win.makeTextureBuffer("Console Buffer", 1024, 512)
- tex = mybuffer.getTexture()
- tex.setMagfilter(Texture.FTLinear)
- tex.setMinfilter(Texture.FTLinear)
-
- faceplate.setTexture(tex, 1)
-
- self.rocketConsole = RocketRegion.make('console', mybuffer)
- self.rocketConsole.setInputHandler(self.inputHandler)
-
- self.consoleContext = self.rocketConsole.getContext()
- self.console = console.Console(self, self.consoleContext, 40, 13, self.handleCommand)
-
- self.console.addLine("Panda DOS")
- self.console.addLine("type 'help'")
- self.console.addLine("")
-
- self.console.allowEditing(True)
-
- def handleCommand(self, command):
- if command is None:
- # hack for Ctrl-Break
- self.spewInProgress = False
- self.console.addLine("*** break ***")
- self.console.allowEditing(True)
- return
-
- command = command.strip()
- if not command:
- return
-
- tokens = [x.strip() for x in command.split(' ')]
- command = tokens[0].lower()
-
- if command == 'help':
- self.console.addLines([
- "Sorry, this is utter fakery.",
- "You won't get much more",
- "out of this simulation unless",
- "you program it yourself. :)"
- ])
- elif command == 'dir':
- self.console.addLines([
- "Directory of C:\\:",
- "HELP COM 72 05-06-2015 14:07",
- "DIR COM 121 05-06-2015 14:11",
- "SPEW COM 666 05-06-2015 15:02",
- " 2 Files(s) 859 Bytes.",
- " 0 Dirs(s) 7333 Bytes free.",
- ""])
- elif command == 'cls':
- self.console.cls()
- elif command == 'echo':
- self.console.addLine(' '.join(tokens[1:]))
- elif command == 'ver':
- self.console.addLine('Panda DOS v0.01 in Panda3D ' + PandaSystem.getVersionString())
- elif command == 'spew':
- self.startSpew()
- elif command == 'exit':
- self.console.setPrompt("System is shutting down NOW!")
- self.terminateMonitor()
- else:
- self.console.addLine("command not found")
-
- def startSpew(self):
- self.console.allowEditing(False)
- self.console.addLine("LINE NOISE 1.0")
- self.console.addLine("")
-
- self.spewInProgress = True
-
- # note: spewage always occurs in 'doMethodLater';
- # time.sleep() would be pointless since the whole
- # UI would be frozen during the wait.
- self.queueSpew(2)
-
- def queueSpew(self, delay=0.1):
- self.taskMgr.doMethodLater(delay, self.spew, 'spew')
-
- def spew(self, task):
- # generate random spewage, just like on TV!
- if not self.spewInProgress:
- return
-
- def randchr():
- return chr(int(random.random() < 0.25 and 32 or random.randint(32, 127)))
-
- line = ''.join([randchr() for _ in range(40) ])
-
- self.console.addLine(line)
- self.queueSpew()
-
- def terminateMonitor(self):
- alphaInterval = self.fadeOut(self.console.getTextContainer(), 2)
-
- alphaInterval.setDoneEvent('fadeOutFinished')
-
- def fadeOutFinished():
- sys.exit(0)
-
- self.accept('fadeOutFinished', fadeOutFinished)
-
- alphaInterval.start()
-
-app = MyApp()
-app.run()