Merge recent wxPython changes from 2.8 branch to HEAD
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@46675 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -200,6 +200,10 @@ WXDLLVER = '%d%d' % (VER_MAJOR, VER_MINOR)
|
|||||||
WXPY_SRC = '.' # Assume we're in the source tree already, but allow the
|
WXPY_SRC = '.' # Assume we're in the source tree already, but allow the
|
||||||
# user to change it, particularly for extension building.
|
# user to change it, particularly for extension building.
|
||||||
|
|
||||||
|
ARCH = '' # If this is set, add an -arch XXX flag to cflags
|
||||||
|
# Only tested (and presumably, needed) for OS X universal
|
||||||
|
# binary builds created using lipo.
|
||||||
|
|
||||||
|
|
||||||
#----------------------------------------------------------------------
|
#----------------------------------------------------------------------
|
||||||
|
|
||||||
@@ -271,7 +275,7 @@ for flag in [ 'BUILD_ACTIVEX', 'BUILD_DLLWIDGET',
|
|||||||
# String options
|
# String options
|
||||||
for option in ['WX_CONFIG', 'SYS_WX_CONFIG', 'WXDLLVER', 'BUILD_BASE',
|
for option in ['WX_CONFIG', 'SYS_WX_CONFIG', 'WXDLLVER', 'BUILD_BASE',
|
||||||
'WXPORT', 'SWIG', 'CONTRIBS_INC', 'WXPY_SRC', 'FLAVOUR',
|
'WXPORT', 'SWIG', 'CONTRIBS_INC', 'WXPY_SRC', 'FLAVOUR',
|
||||||
'VER_FLAGS',
|
'VER_FLAGS', 'ARCH',
|
||||||
]:
|
]:
|
||||||
for x in range(len(sys.argv)):
|
for x in range(len(sys.argv)):
|
||||||
if sys.argv[x].find(option) == 0:
|
if sys.argv[x].find(option) == 0:
|
||||||
@@ -483,7 +487,10 @@ class wx_install_headers(distutils.command.install_headers.install_headers):
|
|||||||
return
|
return
|
||||||
|
|
||||||
root = self.root
|
root = self.root
|
||||||
if root is None or WXPREFIX.startswith(root):
|
#print "WXPREFIX is %s, root is %s" % (WXPREFIX, root)
|
||||||
|
# hack for universal builds, which append i386/ppc
|
||||||
|
# to the root
|
||||||
|
if root is None or WXPREFIX.startswith(os.path.dirname(root)):
|
||||||
root = ''
|
root = ''
|
||||||
for header, location in headers:
|
for header, location in headers:
|
||||||
install_dir = os.path.normpath(root +
|
install_dir = os.path.normpath(root +
|
||||||
@@ -600,9 +607,9 @@ def adjustLFLAGS(lflags, libdirs, libs):
|
|||||||
|
|
||||||
# remove any flags for universal binaries, we'll get those from
|
# remove any flags for universal binaries, we'll get those from
|
||||||
# distutils instead
|
# distutils instead
|
||||||
return [flag for flag in newLFLAGS
|
return newLFLAGS #[flag for flag in newLFLAGS
|
||||||
if flag not in ['-isysroot', '-arch', 'ppc', 'i386'] and
|
# if flag not in ['-isysroot', '-arch', 'ppc', 'i386'] and
|
||||||
not flag.startswith('/Developer') ]
|
# not flag.startswith('/Developer') ]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -789,6 +796,14 @@ elif os.name == 'posix':
|
|||||||
GENDIR = 'mac'
|
GENDIR = 'mac'
|
||||||
libs = ['stdc++']
|
libs = ['stdc++']
|
||||||
NO_SCRIPTS = 1
|
NO_SCRIPTS = 1
|
||||||
|
if not ARCH == "":
|
||||||
|
cflags.append("-arch")
|
||||||
|
cflags.append(ARCH)
|
||||||
|
lflags.append("-arch")
|
||||||
|
lflags.append(ARCH)
|
||||||
|
#if ARCH == "ppc":
|
||||||
|
# cflags.append("-isysroot")
|
||||||
|
# cflags.append("/Developer/SDKs/MacOSX10.3.9.sdk")
|
||||||
|
|
||||||
|
|
||||||
else:
|
else:
|
||||||
|
@@ -1442,7 +1442,10 @@ class wxPythonDemo(wx.Frame):
|
|||||||
menu = wx.Menu()
|
menu = wx.Menu()
|
||||||
findItem = wx.MenuItem(menu, -1, '&Find\tCtrl-F', 'Find in the Demo Code')
|
findItem = wx.MenuItem(menu, -1, '&Find\tCtrl-F', 'Find in the Demo Code')
|
||||||
findItem.SetBitmap(images.catalog['find'].getBitmap())
|
findItem.SetBitmap(images.catalog['find'].getBitmap())
|
||||||
findNextItem = wx.MenuItem(menu, -1, 'Find &Next\tF3', 'Find Next')
|
if 'wxMac' not in wx.PlatformInfo:
|
||||||
|
findNextItem = wx.MenuItem(menu, -1, 'Find &Next\tF3', 'Find Next')
|
||||||
|
else:
|
||||||
|
findNextItem = wx.MenuItem(menu, -1, 'Find &Next\tCtrl-G', 'Find Next')
|
||||||
findNextItem.SetBitmap(images.catalog['findnext'].getBitmap())
|
findNextItem.SetBitmap(images.catalog['findnext'].getBitmap())
|
||||||
menu.AppendItem(findItem)
|
menu.AppendItem(findItem)
|
||||||
menu.AppendItem(findNextItem)
|
menu.AppendItem(findNextItem)
|
||||||
@@ -1456,7 +1459,8 @@ class wxPythonDemo(wx.Frame):
|
|||||||
'A tool that lets you browse the live widgets and sizers in an application')
|
'A tool that lets you browse the live widgets and sizers in an application')
|
||||||
inspToolItem.SetBitmap(images.catalog['inspect'].getBitmap())
|
inspToolItem.SetBitmap(images.catalog['inspect'].getBitmap())
|
||||||
menu.AppendItem(inspToolItem)
|
menu.AppendItem(inspToolItem)
|
||||||
menu.AppendSeparator()
|
if 'wxMac' not in wx.PlatformInfo:
|
||||||
|
menu.AppendSeparator()
|
||||||
helpItem = menu.Append(-1, '&About wxPython Demo', 'wxPython RULES!!!')
|
helpItem = menu.Append(-1, '&About wxPython Demo', 'wxPython RULES!!!')
|
||||||
wx.App.SetMacAboutMenuItemId(helpItem.GetId())
|
wx.App.SetMacAboutMenuItemId(helpItem.GetId())
|
||||||
|
|
||||||
|
@@ -176,15 +176,17 @@ class RichTextFrame(wx.Frame):
|
|||||||
|
|
||||||
|
|
||||||
def OnFileOpen(self, evt):
|
def OnFileOpen(self, evt):
|
||||||
# TODO: Use RichTextBuffer.GetExtWildcard to get the wildcard string
|
# This gives us a string suitable for the file dialog based on
|
||||||
|
# the file handlers that are loaded
|
||||||
|
wildcard, types = rt.RichTextBuffer.GetExtWildcard(save=False)
|
||||||
dlg = wx.FileDialog(self, "Choose a filename",
|
dlg = wx.FileDialog(self, "Choose a filename",
|
||||||
wildcard="All files (*.*)|*.*",
|
wildcard=wildcard,
|
||||||
style=wx.OPEN)
|
style=wx.OPEN)
|
||||||
if dlg.ShowModal() == wx.ID_OK:
|
if dlg.ShowModal() == wx.ID_OK:
|
||||||
path = dlg.GetPath()
|
path = dlg.GetPath()
|
||||||
if path:
|
if path:
|
||||||
# TODO: use the filter index to determine what file type to use
|
fileType = types[dlg.GetFilterIndex()]
|
||||||
self.rtc.LoadFile(path, rt.RICHTEXT_TYPE_TEXT)
|
self.rtc.LoadFile(path, fileType)
|
||||||
dlg.Destroy()
|
dlg.Destroy()
|
||||||
|
|
||||||
|
|
||||||
@@ -194,19 +196,52 @@ class RichTextFrame(wx.Frame):
|
|||||||
return
|
return
|
||||||
self.rtc.SaveFile()
|
self.rtc.SaveFile()
|
||||||
|
|
||||||
|
|
||||||
def OnFileSaveAs(self, evt):
|
def OnFileSaveAs(self, evt):
|
||||||
# TODO: Use RichTextBuffer.GetExtWildcard to get the wildcard string
|
wildcard, types = rt.RichTextBuffer.GetExtWildcard(save=True)
|
||||||
|
|
||||||
dlg = wx.FileDialog(self, "Choose a filename",
|
dlg = wx.FileDialog(self, "Choose a filename",
|
||||||
wildcard="All files (*.*)|*.*",
|
wildcard=wildcard,
|
||||||
style=wx.SAVE)
|
style=wx.SAVE)
|
||||||
if dlg.ShowModal() == wx.ID_OK:
|
if dlg.ShowModal() == wx.ID_OK:
|
||||||
path = dlg.GetPath()
|
path = dlg.GetPath()
|
||||||
if path:
|
if path:
|
||||||
self.rtc.SaveFile(path)
|
fileType = types[dlg.GetFilterIndex()]
|
||||||
|
ext = rt.RichTextBuffer.FindHandlerByType(fileType).GetExtension()
|
||||||
|
if not path.endswith(ext):
|
||||||
|
path += '.' + ext
|
||||||
|
self.rtc.SaveFile(path, fileType)
|
||||||
dlg.Destroy()
|
dlg.Destroy()
|
||||||
|
|
||||||
|
|
||||||
def OnFileViewHTML(self, evt): pass
|
def OnFileViewHTML(self, evt):
|
||||||
|
# Get an instance of the html file handler, use it to save the
|
||||||
|
# document to a StringIO stream, and then display the
|
||||||
|
# resulting html text in a dialog with a HtmlWindow.
|
||||||
|
handler = rt.RichTextHTMLHandler()
|
||||||
|
handler.SetFlags(rt.RICHTEXT_HANDLER_SAVE_IMAGES_TO_MEMORY)
|
||||||
|
handler.SetFontSizeMapping([7,9,11,12,14,22,100])
|
||||||
|
|
||||||
|
import cStringIO
|
||||||
|
stream = cStringIO.StringIO()
|
||||||
|
if not handler.SaveStream(self.rtc.GetBuffer(), stream):
|
||||||
|
return
|
||||||
|
|
||||||
|
import wx.html
|
||||||
|
dlg = wx.Dialog(self, title="HTML", style=wx.DEFAULT_DIALOG_STYLE|wx.RESIZE_BORDER)
|
||||||
|
html = wx.html.HtmlWindow(dlg, size=(500,400), style=wx.BORDER_SUNKEN)
|
||||||
|
html.SetPage(stream.getvalue())
|
||||||
|
btn = wx.Button(dlg, wx.ID_CANCEL)
|
||||||
|
sizer = wx.BoxSizer(wx.VERTICAL)
|
||||||
|
sizer.Add(html, 1, wx.ALL|wx.EXPAND, 5)
|
||||||
|
sizer.Add(btn, 0, wx.ALL|wx.CENTER, 10)
|
||||||
|
dlg.SetSizer(sizer)
|
||||||
|
sizer.Fit(dlg)
|
||||||
|
|
||||||
|
dlg.ShowModal()
|
||||||
|
|
||||||
|
handler.DeleteTemporaryImages()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def OnFileExit(self, evt):
|
def OnFileExit(self, evt):
|
||||||
@@ -533,6 +568,7 @@ class RichTextFrame(wx.Frame):
|
|||||||
|
|
||||||
#----------------------------------------------------------------------
|
#----------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
class TestPanel(wx.Panel):
|
class TestPanel(wx.Panel):
|
||||||
def __init__(self, parent, log):
|
def __init__(self, parent, log):
|
||||||
self.log = log
|
self.log = log
|
||||||
@@ -541,6 +577,30 @@ class TestPanel(wx.Panel):
|
|||||||
b = wx.Button(self, -1, "Show the RichTextCtrl sample", (50,50))
|
b = wx.Button(self, -1, "Show the RichTextCtrl sample", (50,50))
|
||||||
self.Bind(wx.EVT_BUTTON, self.OnButton, b)
|
self.Bind(wx.EVT_BUTTON, self.OnButton, b)
|
||||||
|
|
||||||
|
self.AddRTCHandlers()
|
||||||
|
|
||||||
|
|
||||||
|
def AddRTCHandlers(self):
|
||||||
|
# make sure we haven't already added them.
|
||||||
|
if rt.RichTextBuffer.FindHandlerByType(rt.RICHTEXT_TYPE_HTML) is not None:
|
||||||
|
return
|
||||||
|
|
||||||
|
# This would normally go in your app's OnInit method. I'm
|
||||||
|
# not sure why these file handlers are not loaded by
|
||||||
|
# default by the C++ richtext code, I guess it's so you
|
||||||
|
# can change the name or extension if you wanted...
|
||||||
|
rt.RichTextBuffer.AddHandler(rt.RichTextHTMLHandler())
|
||||||
|
rt.RichTextBuffer.AddHandler(rt.RichTextXMLHandler())
|
||||||
|
|
||||||
|
# ...like this
|
||||||
|
rt.RichTextBuffer.AddHandler(rt.RichTextXMLHandler(name="Other XML",
|
||||||
|
ext="ox",
|
||||||
|
type=99))
|
||||||
|
|
||||||
|
# This is needed for the view as HTML option since we tell it
|
||||||
|
# to store the images in the memory file system.
|
||||||
|
wx.FileSystem.AddHandler(wx.MemoryFSHandler())
|
||||||
|
|
||||||
|
|
||||||
def OnButton(self, evt):
|
def OnButton(self, evt):
|
||||||
win = RichTextFrame(self, -1, "wx.richtext.RichTextCtrl",
|
win = RichTextFrame(self, -1, "wx.richtext.RichTextCtrl",
|
||||||
@@ -548,10 +608,12 @@ class TestPanel(wx.Panel):
|
|||||||
style = wx.DEFAULT_FRAME_STYLE)
|
style = wx.DEFAULT_FRAME_STYLE)
|
||||||
win.Show(True)
|
win.Show(True)
|
||||||
|
|
||||||
# give easy access to PyShell if it's running
|
# give easy access to the demo's PyShell if it's running
|
||||||
self.rtfrm = win
|
self.rtfrm = win
|
||||||
self.rtc = win.rtc
|
self.rtc = win.rtc
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#----------------------------------------------------------------------
|
#----------------------------------------------------------------------
|
||||||
|
|
||||||
def runTest(frame, nb, log):
|
def runTest(frame, nb, log):
|
||||||
|
@@ -9,6 +9,7 @@ class TestPanel(wx.Panel):
|
|||||||
wx.Panel.__init__(self, parent, -1)
|
wx.Panel.__init__(self, parent, -1)
|
||||||
|
|
||||||
sizer = wx.FlexGridSizer(0, 3, 5, 5)
|
sizer = wx.FlexGridSizer(0, 3, 5, 5)
|
||||||
|
sizer.AddGrowableCol(1)
|
||||||
box = wx.BoxSizer(wx.VERTICAL)
|
box = wx.BoxSizer(wx.VERTICAL)
|
||||||
fs = self.GetFont().GetPointSize()
|
fs = self.GetFont().GetPointSize()
|
||||||
bf = wx.Font(fs+4, wx.SWISS, wx.NORMAL, wx.BOLD)
|
bf = wx.Font(fs+4, wx.SWISS, wx.NORMAL, wx.BOLD)
|
||||||
@@ -38,7 +39,7 @@ class TestPanel(wx.Panel):
|
|||||||
0, wx.ALIGN_RIGHT|wx.ALIGN_CENTER_VERTICAL)
|
0, wx.ALIGN_RIGHT|wx.ALIGN_CENTER_VERTICAL)
|
||||||
sizer.Add(wx.TextCtrl(self, -1, func(*args),
|
sizer.Add(wx.TextCtrl(self, -1, func(*args),
|
||||||
size=(275,-1), style=wx.TE_READONLY),
|
size=(275,-1), style=wx.TE_READONLY),
|
||||||
0, wx.ALIGN_RIGHT|wx.ALIGN_CENTER_VERTICAL)
|
0, wx.EXPAND|wx.ALIGN_CENTER_VERTICAL)
|
||||||
|
|
||||||
btn = wx.Button(self, wx.ID_HELP)
|
btn = wx.Button(self, wx.ID_HELP)
|
||||||
sizer.Add(btn)
|
sizer.Add(btn)
|
||||||
@@ -64,7 +65,8 @@ class TestPanel(wx.Panel):
|
|||||||
wx.StandardPaths.ResourceCat_Messages )
|
wx.StandardPaths.ResourceCat_Messages )
|
||||||
|
|
||||||
self.Bind(wx.EVT_BUTTON, self.OnShowDoc, id=wx.ID_HELP)
|
self.Bind(wx.EVT_BUTTON, self.OnShowDoc, id=wx.ID_HELP)
|
||||||
box.Add(sizer, 0, wx.CENTER|wx.ALL, 10)
|
|
||||||
|
box.Add(sizer, 0, wx.CENTER|wx.EXPAND|wx.ALL, 20)
|
||||||
self.SetSizer(box)
|
self.SetSizer(box)
|
||||||
|
|
||||||
|
|
||||||
|
@@ -211,10 +211,13 @@ class TestPanel(wx.Panel):
|
|||||||
|
|
||||||
|
|
||||||
def OnButton(self, evt):
|
def OnButton(self, evt):
|
||||||
win = TestFrame(self, self.log)
|
self.win = TestFrame(self, self.log)
|
||||||
win.Show(True)
|
self.win.Show(True)
|
||||||
|
|
||||||
|
|
||||||
|
def ShutdownDemo(self):
|
||||||
|
self.win.Close()
|
||||||
|
|
||||||
#---------------------------------------------------------------------------
|
#---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
@@ -5,7 +5,7 @@ debug=no
|
|||||||
reswig=no
|
reswig=no
|
||||||
all=no
|
all=no
|
||||||
|
|
||||||
if [ "$1" = "all" ]; then
|
if [ "$1" = all ]; then
|
||||||
all=yes
|
all=yes
|
||||||
else
|
else
|
||||||
PY_VERSION=$1
|
PY_VERSION=$1
|
||||||
@@ -99,7 +99,7 @@ if [ "$OSTYPE" = "cygwin" ]; then
|
|||||||
$WXWIN/wxPython/distrib/makedemo
|
$WXWIN/wxPython/distrib/makedemo
|
||||||
|
|
||||||
$TOOLS/Python$PY_VERSION/python `cygpath -d $WXWIN/wxPython/distrib/make_installer_inno4.py` $UNICODE_FLAG
|
$TOOLS/Python$PY_VERSION/python `cygpath -d $WXWIN/wxPython/distrib/make_installer_inno4.py` $UNICODE_FLAG
|
||||||
elif [ "$OSTYPE" = "darwin" ]; then
|
elif [ "${OSTYPE:0:6}" = "darwin" ]; then
|
||||||
OSX_VERSION=`sw_vers -productVersion`
|
OSX_VERSION=`sw_vers -productVersion`
|
||||||
echo "OS X Version: ${OSX_VERSION:0:4}"
|
echo "OS X Version: ${OSX_VERSION:0:4}"
|
||||||
cd $WXWIN/wxPython
|
cd $WXWIN/wxPython
|
||||||
|
@@ -276,7 +276,10 @@ if [ $skipbuild != yes ]; then
|
|||||||
export WXROOT
|
export WXROOT
|
||||||
export BUILDPREFIX=$PREFIX
|
export BUILDPREFIX=$PREFIX
|
||||||
export INSTALLDIR=$INSTALLROOT$PREFIX
|
export INSTALLDIR=$INSTALLROOT$PREFIX
|
||||||
$WXDIR/distrib/scripts/mac/macbuild wxpython universal $CHARTYPE
|
$WXDIR/distrib/scripts/mac/macbuild-lipo wxpython $CHARTYPE
|
||||||
|
if [ $? != 0 ]; then
|
||||||
|
exit $?
|
||||||
|
fi
|
||||||
else
|
else
|
||||||
make $MAKEJOBS
|
make $MAKEJOBS
|
||||||
make $MAKEJOBS -C contrib/src/gizmos
|
make $MAKEJOBS -C contrib/src/gizmos
|
||||||
@@ -289,20 +292,60 @@ if [ $skipbuild != yes ]; then
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
# Build wxPython
|
# Build wxPython
|
||||||
|
if [ $universal = yes ]; then
|
||||||
|
# build ppc, then i386, then lipo them together
|
||||||
|
ARCH=ppc
|
||||||
|
export CXX="g++-3.3 -DMAC_OS_X_VERSION_MAX_ALLOWED=1030"
|
||||||
|
export CC="gcc-3.3 -DMAC_OS_X_VERSION_MAX_ALLOWED=1030"
|
||||||
|
export MACOSX_DEPLOYMENT_TARGET=10.3
|
||||||
|
mkdir -p $INSTALLROOT/$ARCH
|
||||||
|
mkdir -p $WXBLD/$ARCH
|
||||||
|
|
||||||
|
echo "Building wxPython for PPC..."
|
||||||
|
cd $WXROOT/wxPython
|
||||||
|
$PYTHON setup.py \
|
||||||
|
UNICODE=$PYUNICODEOPT \
|
||||||
|
NO_SCRIPTS=1 \
|
||||||
|
EP_ADD_OPTS=1 \
|
||||||
|
WX_CONFIG="$INSTALLROOT/$PREFIX/bin/wx-config --prefix=$INSTALLROOT$PREFIX" \
|
||||||
|
BUILD_BASE=$WXBLD/$ARCH/wxPython \
|
||||||
|
ARCH="$ARCH" \
|
||||||
|
build
|
||||||
|
|
||||||
|
ARCH=i386
|
||||||
|
export CXX="g++-4.0 -arch i386"
|
||||||
|
export CC="gcc-4.0 -arch i386"
|
||||||
|
export MACOSX_DEPLOYMENT_TARGET=10.4
|
||||||
|
mkdir -p $INSTALLROOT/$ARCH
|
||||||
|
mkdir -p $WXBLD/$ARCH
|
||||||
|
|
||||||
|
echo "Building wxPython for Intel..."
|
||||||
|
|
||||||
cd $WXROOT/wxPython
|
cd $WXROOT/wxPython
|
||||||
$PYTHON setup.py \
|
$PYTHON setup.py \
|
||||||
UNICODE=$PYUNICODEOPT \
|
UNICODE=$PYUNICODEOPT \
|
||||||
NO_SCRIPTS=1 \
|
NO_SCRIPTS=1 \
|
||||||
EP_ADD_OPTS=1 \
|
EP_ADD_OPTS=1 \
|
||||||
|
WX_CONFIG="$INSTALLROOT/$PREFIX/bin/wx-config --prefix=$INSTALLROOT$PREFIX" \
|
||||||
|
BUILD_BASE=$WXBLD/$ARCH/wxPython \
|
||||||
|
ARCH="$ARCH" \
|
||||||
|
build
|
||||||
|
|
||||||
|
else
|
||||||
|
cd $WXROOT/wxPython
|
||||||
|
$PYTHON setup.py \
|
||||||
|
UNICODE=$PYUNICODEOPT \
|
||||||
|
NO_SCRIPTS=1 \
|
||||||
|
EP_ADD_OPTS=1 \
|
||||||
WX_CONFIG="$WXBLD_CONFIG --inplace" \
|
WX_CONFIG="$WXBLD_CONFIG --inplace" \
|
||||||
BUILD_BASE=$WXBLD/wxPython \
|
BUILD_BASE=$WXBLD/wxPython \
|
||||||
SWIG=$SWIGBIN \
|
SWIG=$SWIGBIN \
|
||||||
USE_SWIG=$SWIGIT \
|
USE_SWIG=$SWIGIT \
|
||||||
build
|
build
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
#----------------------------------------------------------------------
|
#----------------------------------------------------------------------
|
||||||
|
|
||||||
if [ $skipinstall != yes ]; then
|
if [ $skipinstall != yes ]; then
|
||||||
# Install wxWidgets
|
# Install wxWidgets
|
||||||
cd $WXBLD
|
cd $WXBLD
|
||||||
@@ -317,17 +360,51 @@ if [ $skipinstall != yes ]; then
|
|||||||
rm wx-config
|
rm wx-config
|
||||||
ln -s ../lib/wx/config/* wx-config
|
ln -s ../lib/wx/config/* wx-config
|
||||||
|
|
||||||
# and wxPython
|
if [ $universal == yes ]; then
|
||||||
|
ARCH=ppc
|
||||||
|
export CXX="g++-3.3 -DMAC_OS_X_VERSION_MAX_ALLOWED=1030"
|
||||||
|
export CC="gcc-3.3 -DMAC_OS_X_VERSION_MAX_ALLOWED=1030"
|
||||||
|
export MACOSX_DEPLOYMENT_TARGET=10.3
|
||||||
cd $WXROOT/wxPython
|
cd $WXROOT/wxPython
|
||||||
$PYTHON setup.py \
|
$PYTHON setup.py \
|
||||||
UNICODE=$PYUNICODEOPT \
|
UNICODE=$PYUNICODEOPT \
|
||||||
NO_SCRIPTS=1 \
|
NO_SCRIPTS=1 \
|
||||||
EP_ADD_OPTS=1 \
|
EP_ADD_OPTS=1 \
|
||||||
WX_CONFIG="$INSTALLROOT$PREFIX/bin/wx-config --prefix=$INSTALLROOT$PREFIX" \
|
WX_CONFIG="$INSTALLROOT$PREFIX/bin/wx-config --prefix=$INSTALLROOT$PREFIX" \
|
||||||
|
BUILD_BASE=$WXBLD/$ARCH/wxPython \
|
||||||
|
install \
|
||||||
|
--root=$INSTALLROOT/$ARCH
|
||||||
|
|
||||||
|
ARCH=i386
|
||||||
|
export CXX="g++-4.0 -arch i386"
|
||||||
|
export CC="gcc-4.0 -arch i386"
|
||||||
|
export MACOSX_DEPLOYMENT_TARGET=10.4
|
||||||
|
cd $WXROOT/wxPython
|
||||||
|
$PYTHON setup.py \
|
||||||
|
UNICODE=$PYUNICODEOPT \
|
||||||
|
NO_SCRIPTS=1 \
|
||||||
|
EP_ADD_OPTS=1 \
|
||||||
|
WX_CONFIG="$INSTALLROOT$PREFIX/bin/wx-config --prefix=$INSTALLROOT$PREFIX" \
|
||||||
|
BUILD_BASE=$WXBLD/$ARCH/wxPython \
|
||||||
|
install \
|
||||||
|
--root=$INSTALLROOT/$ARCH
|
||||||
|
|
||||||
|
echo "Lipoing $INSTALLROOT/ppc and $INSTALLROOT/i386..."
|
||||||
|
$PYTHON $WXROOT/distrib/scripts/mac/lipo-dir.py $INSTALLROOT/ppc $INSTALLROOT/i386 $INSTALLROOT
|
||||||
|
|
||||||
|
rm -rf $INSTALLROOT/ppc $INSTALLROOT/i386
|
||||||
|
|
||||||
|
else
|
||||||
|
cd $WXROOT/wxPython
|
||||||
|
$PYTHON setup.py \
|
||||||
|
UNICODE=$PYUNICODEOPT \
|
||||||
|
NO_SCRIPTS=1 \
|
||||||
|
EP_ADD_OPTS=1 \
|
||||||
|
WX_CONFIG="$INSTALLROOT$PREFIX/bin/wx-config --prefix=$INSTALLROOT$PREFIX" \
|
||||||
BUILD_BASE=$WXBLD/wxPython \
|
BUILD_BASE=$WXBLD/wxPython \
|
||||||
install \
|
install \
|
||||||
--root=$INSTALLROOT
|
--root=$INSTALLROOT
|
||||||
|
fi
|
||||||
|
|
||||||
# Apple's Python Framework (such as what comes with Panther)
|
# Apple's Python Framework (such as what comes with Panther)
|
||||||
# sym-links the site-packages dir in the framework to
|
# sym-links the site-packages dir in the framework to
|
||||||
|
@@ -14,7 +14,7 @@
|
|||||||
#define __PYISTREAM__
|
#define __PYISTREAM__
|
||||||
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
// Handling of wxInputStreams by Joerg Baumann
|
// Handling of wxInputStreams by Joerg Baumann
|
||||||
// See stream.i for implementations
|
// See stream.i for implementations
|
||||||
|
|
||||||
@@ -34,19 +34,22 @@ public:
|
|||||||
void close();
|
void close();
|
||||||
void flush();
|
void flush();
|
||||||
bool eof();
|
bool eof();
|
||||||
PyObject* read(int size=-1);
|
|
||||||
PyObject* readline(int size=-1);
|
|
||||||
PyObject* readlines(int sizehint=-1);
|
|
||||||
void seek(int offset, int whence=0);
|
void seek(int offset, int whence=0);
|
||||||
int tell();
|
int tell();
|
||||||
|
|
||||||
/* do these later?
|
PyObject* read(int size=-1);
|
||||||
bool isatty();
|
PyObject* readline(int size=-1);
|
||||||
int fileno();
|
PyObject* readlines(int sizehint=-1);
|
||||||
void truncate(int size=-1);
|
|
||||||
void write(wxString data);
|
// do these later?
|
||||||
void writelines(wxStringPtrList);
|
//bool isatty();
|
||||||
*/
|
//int fileno();
|
||||||
|
//void truncate(int size=-1);
|
||||||
|
//PyObject* next();
|
||||||
|
|
||||||
|
// It's an input stream, can't write to it.
|
||||||
|
//void write(wxString data);
|
||||||
|
//void writelines(wxStringPtrList);
|
||||||
|
|
||||||
// wxInputStream methods that may come in handy...
|
// wxInputStream methods that may come in handy...
|
||||||
|
|
||||||
@@ -86,14 +89,82 @@ protected:
|
|||||||
virtual wxFileOffset OnSysSeek(wxFileOffset off, wxSeekMode mode);
|
virtual wxFileOffset OnSysSeek(wxFileOffset off, wxSeekMode mode);
|
||||||
virtual wxFileOffset OnSysTell() const;
|
virtual wxFileOffset OnSysTell() const;
|
||||||
|
|
||||||
// helper
|
|
||||||
static PyObject* getMethod(PyObject* py, char* name);
|
|
||||||
|
|
||||||
PyObject* m_read;
|
PyObject* m_read;
|
||||||
PyObject* m_seek;
|
PyObject* m_seek;
|
||||||
PyObject* m_tell;
|
PyObject* m_tell;
|
||||||
bool m_block;
|
bool m_block;
|
||||||
};
|
};
|
||||||
|
|
||||||
//----------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// C++ class wxPyOutputStream to act as base for python class wxOutputStream
|
||||||
|
// You can use it in python like a python file object.
|
||||||
|
class wxPyOutputStream {
|
||||||
|
public:
|
||||||
|
// underlying wxOutputStream
|
||||||
|
wxOutputStream* m_wxos;
|
||||||
|
|
||||||
|
public:
|
||||||
|
wxPyOutputStream(wxOutputStream* wxos) : m_wxos(wxos) {}
|
||||||
|
~wxPyOutputStream();
|
||||||
|
|
||||||
|
void close();
|
||||||
|
void flush();
|
||||||
|
bool eof();
|
||||||
|
void seek(int offset, int whence=0);
|
||||||
|
int tell();
|
||||||
|
|
||||||
|
// it's an output stream, can't read from it.
|
||||||
|
//PyObject* read(int size=-1);
|
||||||
|
//PyObject* readline(int size=-1);
|
||||||
|
//PyObject* readlines(int sizehint=-1);
|
||||||
|
|
||||||
|
// do these later?
|
||||||
|
//bool isatty();
|
||||||
|
//int fileno();
|
||||||
|
//void truncate(int size=-1);
|
||||||
|
|
||||||
|
void write(PyObject* data);
|
||||||
|
//void writelines(wxStringArray& arr);
|
||||||
|
|
||||||
|
|
||||||
|
// wxOutputStream methods that may come in handy...
|
||||||
|
void PutC(char c) { if (m_wxos) m_wxos->PutC(c); }
|
||||||
|
size_t LastWrite() { if (m_wxos) return m_wxos->LastWrite(); }
|
||||||
|
unsigned long SeekO(unsigned long pos, wxSeekMode mode = wxFromStart)
|
||||||
|
{ if (m_wxos) return m_wxos->SeekO(pos, mode); else return 0; }
|
||||||
|
unsigned long TellO() { if (m_wxos) return m_wxos->TellO(); else return 0; }
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// This is a wxOutputStream that wraps a Python file-like
|
||||||
|
// object and calls the Python methods as needed.
|
||||||
|
class wxPyCBOutputStream : public wxOutputStream {
|
||||||
|
public:
|
||||||
|
~wxPyCBOutputStream();
|
||||||
|
virtual wxFileOffset GetLength() const;
|
||||||
|
|
||||||
|
// factory function
|
||||||
|
static wxPyCBOutputStream* create(PyObject *py, bool block=true);
|
||||||
|
|
||||||
|
wxPyCBOutputStream(const wxPyCBOutputStream& other);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
// can only be created via the factory
|
||||||
|
wxPyCBOutputStream(PyObject *w, PyObject *s, PyObject *t, bool block);
|
||||||
|
|
||||||
|
// wxStreamBase methods
|
||||||
|
virtual size_t OnSysRead(void *buffer, size_t bufsize);
|
||||||
|
virtual size_t OnSysWrite(const void *buffer, size_t bufsize);
|
||||||
|
virtual wxFileOffset OnSysSeek(wxFileOffset off, wxSeekMode mode);
|
||||||
|
virtual wxFileOffset OnSysTell() const;
|
||||||
|
|
||||||
|
PyObject* m_write;
|
||||||
|
PyObject* m_seek;
|
||||||
|
PyObject* m_tell;
|
||||||
|
bool m_block;
|
||||||
|
};
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
#endif
|
#endif
|
||||||
|
@@ -124,6 +124,8 @@ inline wxPyCoreAPI* wxPyGetCoreAPIPtr()
|
|||||||
#define wxRect2D_helper(a,b) (wxPyGetCoreAPIPtr()->p_wxRect2D_helper(a,b))
|
#define wxRect2D_helper(a,b) (wxPyGetCoreAPIPtr()->p_wxRect2D_helper(a,b))
|
||||||
#define wxPosition_helper(a,b) (wxPyGetCoreAPIPtr()->p_wxPosition_helper(a,b))
|
#define wxPosition_helper(a,b) (wxPyGetCoreAPIPtr()->p_wxPosition_helper(a,b))
|
||||||
|
|
||||||
|
#define wxPyCBOutputStream_create(a, b) (wxPyGetCoreAPIPtr()->p_wxPyCBOutputStream_create(a, b))
|
||||||
|
#define wxPyCBOutputStream_copy(a) (wxPyGetCoreAPIPtr()->p_wxPyCBOutputStream_copy(a))
|
||||||
|
|
||||||
//----------------------------------------------------------------------
|
//----------------------------------------------------------------------
|
||||||
#endif
|
#endif
|
||||||
|
@@ -353,6 +353,7 @@ class wxPyClientData;
|
|||||||
class wxPyUserData;
|
class wxPyUserData;
|
||||||
class wxPyOORClientData;
|
class wxPyOORClientData;
|
||||||
class wxPyCBInputStream;
|
class wxPyCBInputStream;
|
||||||
|
class wxPyCBOutputStream;
|
||||||
|
|
||||||
void wxPyClientData_dtor(wxPyClientData* self);
|
void wxPyClientData_dtor(wxPyClientData* self);
|
||||||
void wxPyUserData_dtor(wxPyUserData* self);
|
void wxPyUserData_dtor(wxPyUserData* self);
|
||||||
@@ -360,6 +361,9 @@ void wxPyOORClientData_dtor(wxPyOORClientData* self);
|
|||||||
wxPyCBInputStream* wxPyCBInputStream_create(PyObject *py, bool block);
|
wxPyCBInputStream* wxPyCBInputStream_create(PyObject *py, bool block);
|
||||||
wxPyCBInputStream* wxPyCBInputStream_copy(wxPyCBInputStream* other);
|
wxPyCBInputStream* wxPyCBInputStream_copy(wxPyCBInputStream* other);
|
||||||
|
|
||||||
|
wxPyCBOutputStream* wxPyCBOutputStream_create(PyObject *py, bool block);
|
||||||
|
wxPyCBOutputStream* wxPyCBOutputStream_copy(wxPyCBOutputStream* other);
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
// Export a C API in a struct. Other modules will be able to load this from
|
// Export a C API in a struct. Other modules will be able to load this from
|
||||||
// the wx.core module and will then have safe access to these functions, even if
|
// the wx.core module and will then have safe access to these functions, even if
|
||||||
@@ -437,6 +441,8 @@ struct wxPyCoreAPI {
|
|||||||
bool (*p_wxRect2D_helper)(PyObject* source, wxRect2D** obj);
|
bool (*p_wxRect2D_helper)(PyObject* source, wxRect2D** obj);
|
||||||
bool (*p_wxPosition_helper)(PyObject* source, wxPosition** obj);
|
bool (*p_wxPosition_helper)(PyObject* source, wxPosition** obj);
|
||||||
|
|
||||||
|
wxPyCBOutputStream* (*p_wxPyCBOutputStream_create)(PyObject *py, bool block);
|
||||||
|
wxPyCBOutputStream* (*p_wxPyCBOutputStream_copy)(wxPyCBOutputStream* other);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
File diff suppressed because it is too large
Load Diff
@@ -25,13 +25,18 @@ class TextDocument(wx.lib.docview.Document):
|
|||||||
|
|
||||||
def SaveObject(self, fileObject):
|
def SaveObject(self, fileObject):
|
||||||
view = self.GetFirstView()
|
view = self.GetFirstView()
|
||||||
fileObject.write(view.GetTextCtrl().GetValue())
|
val = view.GetTextCtrl().GetValue()
|
||||||
|
if wx.USE_UNICODE:
|
||||||
|
val = val.encode('utf-8')
|
||||||
|
fileObject.write(val)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
def LoadObject(self, fileObject):
|
def LoadObject(self, fileObject):
|
||||||
view = self.GetFirstView()
|
view = self.GetFirstView()
|
||||||
data = fileObject.read()
|
data = fileObject.read()
|
||||||
|
if wx.USE_UNICODE:
|
||||||
|
data = data.decode('utf-8')
|
||||||
view.GetTextCtrl().SetValue(data)
|
view.GetTextCtrl().SetValue(data)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
@@ -93,7 +98,7 @@ class TextView(wx.lib.docview.View):
|
|||||||
wordWrapStyle = wx.TE_WORDWRAP
|
wordWrapStyle = wx.TE_WORDWRAP
|
||||||
else:
|
else:
|
||||||
wordWrapStyle = wx.TE_DONTWRAP
|
wordWrapStyle = wx.TE_DONTWRAP
|
||||||
textCtrl = wx.TextCtrl(parent, -1, pos = wx.DefaultPosition, size = parent.GetClientSize(), style = wx.TE_MULTILINE | wordWrapStyle)
|
textCtrl = wx.TextCtrl(parent, -1, pos = wx.DefaultPosition, size = parent.GetClientSize(), style = wx.TE_MULTILINE | wx.TE_RICH | wordWrapStyle)
|
||||||
textCtrl.SetFont(font)
|
textCtrl.SetFont(font)
|
||||||
textCtrl.SetForegroundColour(color)
|
textCtrl.SetForegroundColour(color)
|
||||||
textCtrl.SetValue(value)
|
textCtrl.SetValue(value)
|
||||||
@@ -521,7 +526,7 @@ class TextOptionsPanel(wx.Panel):
|
|||||||
nativeFont.FromString(self._textFont.GetNativeFontInfoDesc())
|
nativeFont.FromString(self._textFont.GetNativeFontInfoDesc())
|
||||||
font = wx.NullFont
|
font = wx.NullFont
|
||||||
font.SetNativeFontInfo(nativeFont)
|
font.SetNativeFontInfo(nativeFont)
|
||||||
font.SetPointSize(self._sampleTextCtrl.GetFont().GetPointSize()) # Use the standard point size
|
#font.SetPointSize(self._sampleTextCtrl.GetFont().GetPointSize()) # Use the standard point size
|
||||||
self._sampleTextCtrl.SetFont(font)
|
self._sampleTextCtrl.SetFont(font)
|
||||||
self._sampleTextCtrl.SetForegroundColour(self._textColor)
|
self._sampleTextCtrl.SetForegroundColour(self._textColor)
|
||||||
self._sampleTextCtrl.SetValue(_("%d pt. %s") % (self._textFont.GetPointSize(), self._textFont.GetFaceName()))
|
self._sampleTextCtrl.SetValue(_("%d pt. %s") % (self._textFont.GetPointSize(), self._textFont.GetFaceName()))
|
||||||
|
372
wxPython/samples/roses/clroses.py
Normal file
372
wxPython/samples/roses/clroses.py
Normal file
@@ -0,0 +1,372 @@
|
|||||||
|
#----------------------------------------------------------------------------
|
||||||
|
# Name: clroses.py
|
||||||
|
# Purpose: Class definitions for Roses interactive display programs.
|
||||||
|
#
|
||||||
|
# Author: Ric Werme
|
||||||
|
# WWW: http://WermeNH.com/roses
|
||||||
|
#
|
||||||
|
# Created: June 2007
|
||||||
|
# CVS-ID: $Id$
|
||||||
|
# Copyright: Public Domain, please give credit where credit is due.
|
||||||
|
# License: Sorry, no EULA.
|
||||||
|
#----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
# This is yet another incarnation of an old graphics hack based around
|
||||||
|
# misdrawing an analytic geometry curve called a rose. The basic form is
|
||||||
|
# simply the polar coordinate function r = cos(a * theta). "a" is the
|
||||||
|
# "order" of the rose, a zero value degenerates to r = 1, a circle. While
|
||||||
|
# this program is happy to draw that, much more interesting things happen when
|
||||||
|
# one or more of the following is in effect:
|
||||||
|
|
||||||
|
# 1) The "delta theta" between points is large enough to distort the curve,
|
||||||
|
# e.g. 90 degrees will draw a square, slightly less will be interesting.
|
||||||
|
|
||||||
|
# 2) The order of the rose is too large to draw it accurately.
|
||||||
|
|
||||||
|
# 3) Vectors are drawn at less than full speed.
|
||||||
|
|
||||||
|
# 4) The program is stepping through different patterns on its own.
|
||||||
|
|
||||||
|
# While you will be able to predict some aspects of the generated patterns,
|
||||||
|
# a lot of what there is to be found is found at random!
|
||||||
|
|
||||||
|
# The rose class has all the knowledge to implement generating vector data for
|
||||||
|
# roses and handles all the timing issues. It does not have the user interface
|
||||||
|
# for changing all the drawing parameters. It offers a "vision" of what an
|
||||||
|
# ideal Roses program should be, however, callers are welcome to assert their
|
||||||
|
# independence, override defaults, ignore features, etc.
|
||||||
|
|
||||||
|
from math import sin, cos, pi
|
||||||
|
|
||||||
|
# Rose class knows about:
|
||||||
|
# > Generating points and vectors (returning data as a list of points)
|
||||||
|
# > Starting a new rose (e.g. telling user to erase old vectors)
|
||||||
|
# > Stepping from one pattern to the next.
|
||||||
|
|
||||||
|
class rose:
|
||||||
|
"Defines everything needed for drawing a rose with timers."
|
||||||
|
|
||||||
|
# The following data is accessible by callers, but there are set
|
||||||
|
# methods for most everything and various method calls to client methods
|
||||||
|
# to display current values.
|
||||||
|
style = 100 # Angular distance along curve between points
|
||||||
|
sincr = -1 # Amount to increment style by in auto mode
|
||||||
|
petals = 2 # Lobes on the rose (even values have 2X lobes)
|
||||||
|
pincr = 1 # Amount to increment petals by in auto mode
|
||||||
|
nvec = 399 # Number of vectors to draw the rose
|
||||||
|
minvec = 0 # Minimum number acceptable in automatic mode
|
||||||
|
maxvec = 3600 # Maximum number acceptable in automatic mode
|
||||||
|
skipvec = 0 # Don't draw this many at the start (cheap animations)
|
||||||
|
drawvec = 3600 # Draw only this many (cheap animations)
|
||||||
|
step = 20 # Number of vectors to draw each clock tick
|
||||||
|
draw_delay = 50 # Time between roselet calls to watch pattern draw
|
||||||
|
wait_delay = 2000 # Time between roses in automatic mode
|
||||||
|
|
||||||
|
# Other variables that the application shouldn't access.
|
||||||
|
verbose = 0 # No good way to set this at the moment.
|
||||||
|
nextpt = 0 # Next position to draw on next clock tick
|
||||||
|
|
||||||
|
# Internal states:
|
||||||
|
INT_IDLE, INT_DRAW, INT_SEARCH, INT_WAIT, INT_RESIZE = range(5)
|
||||||
|
int_state = INT_IDLE
|
||||||
|
|
||||||
|
# Command states
|
||||||
|
CMD_STOP, CMD_GO = range(2)
|
||||||
|
cmd_state = CMD_STOP
|
||||||
|
|
||||||
|
# Return full rose line (a tuple of (x, y) tuples). Not used by interactive
|
||||||
|
# clients but still useful for command line and batch clients.
|
||||||
|
# This is the "purest" code and doesn't require the App* methods defined
|
||||||
|
# by the caller.
|
||||||
|
def rose(self, style, petals, vectors):
|
||||||
|
self.nvec = vectors
|
||||||
|
self.make_tables(vectors)
|
||||||
|
line = [(1.0, 0.0)]
|
||||||
|
for i in range (1, vectors):
|
||||||
|
theta = (style * i) % vectors
|
||||||
|
r = self.cos_table[(petals * theta) % vectors]
|
||||||
|
line.append((r * self.cos_table[theta], r * self.sin_table[theta]))
|
||||||
|
line.append((1.0, 0.0))
|
||||||
|
return line
|
||||||
|
|
||||||
|
# Generate vectors for the next chunk of rose.
|
||||||
|
|
||||||
|
# This is not meant to be called from an external module, as it is closely
|
||||||
|
# coupled to parameters set up within the class and limits set up by
|
||||||
|
# restart(). Restart() initializes all data this needs to start drawing a
|
||||||
|
# pattern, and clock() calls this to compute the next batch of points and
|
||||||
|
# hear if that is the last batch. We maintain all data we need to draw each
|
||||||
|
# batch after the first. theta should be 2.0*pi * style*i/self.nvec
|
||||||
|
# radians, but we deal in terms of the lookup table so it's just the index
|
||||||
|
# that refers to the same spot.
|
||||||
|
def roselet(self):
|
||||||
|
line = []
|
||||||
|
stop = self.nextpt + self.step
|
||||||
|
keep_running = True
|
||||||
|
if stop >= self.endpt:
|
||||||
|
stop = self.endpt
|
||||||
|
keep_running = False
|
||||||
|
for i in range (self.nextpt, stop + 1):
|
||||||
|
theta = (self.style * i) % self.nvec
|
||||||
|
r = self.cos_table[(self.petals * theta) % self.nvec]
|
||||||
|
line.append((r * self.cos_table[theta], r * self.sin_table[theta]))
|
||||||
|
self.nextpt = stop
|
||||||
|
return line, keep_running
|
||||||
|
|
||||||
|
# Generate sine and cosine lookup tables. We could create data for just
|
||||||
|
# 1/4 of a circle, at least if vectors was a multiple of 4, and share a
|
||||||
|
# table for both sine and cosine, but memory is cheaper than it was in
|
||||||
|
# PDP-11 days. OTOH, small, shared tables would be more cache friendly,
|
||||||
|
# but if we were that concerned, this would be in C.
|
||||||
|
def make_tables(self, vectors):
|
||||||
|
self.sin_table = [sin(2.0 * pi * i / vectors) for i in range(vectors)]
|
||||||
|
self.cos_table = [cos(2.0 * pi * i / vectors) for i in range(vectors)]
|
||||||
|
|
||||||
|
# Rescale (x,y) data to match our window. Note the negative scaling in the
|
||||||
|
# Y direction, this compensates for Y moving down the screen, but up on
|
||||||
|
# graph paper.
|
||||||
|
def rescale(self, line, offset, scale):
|
||||||
|
for i in range(len(line)):
|
||||||
|
line[i] = (line[i][0] * scale + offset[0],
|
||||||
|
line[i][1] * (-scale) + offset[1])
|
||||||
|
return line
|
||||||
|
|
||||||
|
# Euler's Method for computing the greatest common divisor. Knuth's
|
||||||
|
# "The Art of Computer Programming" vol.2 is the standard reference,
|
||||||
|
# but the web has several good ones too. Basically this sheds factors
|
||||||
|
# that aren't in the GCD and returns when there's nothing left to shed.
|
||||||
|
# N.B. Call with a >= b.
|
||||||
|
def gcd(self, a, b):
|
||||||
|
while b != 0:
|
||||||
|
a, b = b, a % b
|
||||||
|
return a
|
||||||
|
|
||||||
|
# Erase any old vectors and start drawing a new rose. When the program
|
||||||
|
# starts, the sine and cosine tables don't exist, build them here. (Of
|
||||||
|
# course, if an __init__() method is added, move the call there.
|
||||||
|
# If we're in automatic mode, check to see if the new pattern has neither
|
||||||
|
# too few or too many vectors and skip it if so. Skip by setting up for
|
||||||
|
# a one tick wait to let us get back to the main loop so the user can
|
||||||
|
# update parameters or stop.
|
||||||
|
def restart(self):
|
||||||
|
if self.verbose:
|
||||||
|
print 'restart: int_state', self.int_state, 'cmd_state', self.cmd_state
|
||||||
|
try:
|
||||||
|
tmp = self.sin_table[0]
|
||||||
|
except:
|
||||||
|
self.make_tables(self.nvec)
|
||||||
|
|
||||||
|
new_state = self.INT_DRAW
|
||||||
|
self.takesvec = self.nvec / self.gcd(self.nvec, self.style)
|
||||||
|
if not self.takesvec & 1 and self.petals & 1:
|
||||||
|
self.takesvec /= 2
|
||||||
|
if self.cmd_state == self.CMD_GO:
|
||||||
|
if self.minvec > self.takesvec or self.maxvec < self.takesvec:
|
||||||
|
new_state = self.INT_SEARCH
|
||||||
|
self.AppSetTakesVec(self.takesvec)
|
||||||
|
self.AppClear()
|
||||||
|
self.nextpt = self.skipvec
|
||||||
|
self.endpt = min(self.takesvec, self.skipvec + self.drawvec)
|
||||||
|
old_state, self.int_state = self.int_state, new_state
|
||||||
|
if old_state == self.INT_IDLE: # Clock not running
|
||||||
|
self.clock()
|
||||||
|
elif old_state == self.INT_WAIT: # May be long delay, restart
|
||||||
|
self.AppCancelTimer()
|
||||||
|
self.clock()
|
||||||
|
else:
|
||||||
|
return 1 # If called by clock(), return and start clock
|
||||||
|
return 0 # We're in INT_IDLE or INT_WAIT, clock running
|
||||||
|
|
||||||
|
# Called from App. Recompute the center and scale values for the subsequent pattern.
|
||||||
|
# Force us into INT_RESIZE state if not already there so that in 100 ms we'll start
|
||||||
|
# to draw something to give an idea of the new size.
|
||||||
|
def resize(self, size, delay):
|
||||||
|
xsize, ysize = size
|
||||||
|
self.center = (xsize / 2, ysize / 2)
|
||||||
|
self.scale = min(xsize, ysize) / 2.1
|
||||||
|
self.repaint(delay)
|
||||||
|
|
||||||
|
# Called from App or above. From App, called with small delay because
|
||||||
|
# some window managers will produce a flood of expose events or call us
|
||||||
|
# before initialization is done.
|
||||||
|
def repaint(self, delay):
|
||||||
|
if self.int_state != self.INT_RESIZE:
|
||||||
|
# print 'repaint after', delay
|
||||||
|
self.int_state = self.INT_RESIZE
|
||||||
|
self.AppCancelTimer()
|
||||||
|
self.AppAfter(delay, self.clock)
|
||||||
|
|
||||||
|
# Method that returns the next style and petal values for automatic
|
||||||
|
# mode and remembers them internally. Keep things scaled in the
|
||||||
|
# range [0:nvec) because there's little reason to exceed that.
|
||||||
|
def next(self):
|
||||||
|
self.style += self.sincr
|
||||||
|
self.petals += self.pincr
|
||||||
|
if self.style <= 0 or self.petals < 0:
|
||||||
|
self.style, self.petals = \
|
||||||
|
abs(self.petals) + 1, abs(self.style)
|
||||||
|
if self.style >= self.nvec:
|
||||||
|
self.style %= self.nvec # Don't bother defending against 0
|
||||||
|
if self.petals >= self.nvec:
|
||||||
|
self.petals %= self.nvec
|
||||||
|
self.AppSetParam(self.style, self.petals, self.nvec)
|
||||||
|
|
||||||
|
# Resume pattern drawing with the next one to display.
|
||||||
|
def resume(self):
|
||||||
|
self.next()
|
||||||
|
return self.restart()
|
||||||
|
|
||||||
|
# Go/Stop button.
|
||||||
|
def cmd_go_stop(self):
|
||||||
|
if self.cmd_state == self.CMD_STOP:
|
||||||
|
self.cmd_state = self.CMD_GO
|
||||||
|
self.resume() # Draw next pattern
|
||||||
|
elif self.cmd_state == self.CMD_GO:
|
||||||
|
self.cmd_state = self.CMD_STOP
|
||||||
|
self.update_labels()
|
||||||
|
|
||||||
|
# Centralize button naming to share with initialization.
|
||||||
|
# Leave colors to the application (assuming it cares), we can't guess
|
||||||
|
# what's available.
|
||||||
|
def update_labels(self):
|
||||||
|
if self.cmd_state == self.CMD_STOP:
|
||||||
|
self.AppCmdLabels(('Go', 'Redraw', 'Backward', 'Forward'))
|
||||||
|
else: # Must be in state CMD_GO
|
||||||
|
self.AppCmdLabels(('Stop', 'Redraw', 'Reverse', 'Skip'))
|
||||||
|
|
||||||
|
# Redraw/Redraw button
|
||||||
|
def cmd_redraw(self):
|
||||||
|
self.restart() # Redraw current pattern
|
||||||
|
|
||||||
|
# Backward/Reverse button
|
||||||
|
# Useful for when you see an interesting pattern and want
|
||||||
|
# to go back to it. If running, just change direction. If stopped, back
|
||||||
|
# up one step. The resume code handles the step, then we change the
|
||||||
|
# incrementers back to what they were. (Unless resume changed them too.)
|
||||||
|
def cmd_backward(self):
|
||||||
|
self.sincr = -self.sincr
|
||||||
|
self.pincr = -self.pincr
|
||||||
|
if self.cmd_state == self.CMD_STOP:
|
||||||
|
self.resume();
|
||||||
|
self.sincr = -self.sincr # Go forward again
|
||||||
|
self.pincr = -self.pincr
|
||||||
|
else:
|
||||||
|
self.AppSetIncrs(self.sincr, self.pincr)
|
||||||
|
|
||||||
|
# Forward/Skip button. CMD_STOP & CMD_GO both just call resume.
|
||||||
|
def cmd_step(self):
|
||||||
|
self.resume() # Draw next pattern
|
||||||
|
|
||||||
|
# Handler called on each timer event. This handles the metered drawing
|
||||||
|
# of a rose and the delays between them. It also registers for the next
|
||||||
|
# timer event unless we're idle (rose is done and the delay between
|
||||||
|
# roses is 0.)
|
||||||
|
def clock(self):
|
||||||
|
if self.int_state == self.INT_IDLE:
|
||||||
|
# print 'clock called in idle state'
|
||||||
|
delay = 0
|
||||||
|
elif self.int_state == self.INT_DRAW:
|
||||||
|
line, run = self.roselet()
|
||||||
|
self.AppCreateLine(self.rescale(line, self.center, self.scale))
|
||||||
|
if run:
|
||||||
|
delay = self.draw_delay
|
||||||
|
else:
|
||||||
|
if self.cmd_state == self.CMD_GO:
|
||||||
|
self.int_state = self.INT_WAIT
|
||||||
|
delay = self.wait_delay
|
||||||
|
else:
|
||||||
|
self.int_state = self.INT_IDLE
|
||||||
|
delay = 0
|
||||||
|
elif self.int_state == self.INT_SEARCH:
|
||||||
|
delay = self.resume() # May call us to start drawing
|
||||||
|
if self.int_state == self.INT_SEARCH:
|
||||||
|
delay = self.draw_delay # but not if searching.
|
||||||
|
elif self.int_state == self.INT_WAIT:
|
||||||
|
if self.cmd_state == self.CMD_GO:
|
||||||
|
delay = self.resume() # Calls us to start drawing
|
||||||
|
else:
|
||||||
|
self.int_state = self.INT_IDLE
|
||||||
|
delay = 0
|
||||||
|
elif self.int_state == self.INT_RESIZE: # Waiting for resize event stream to settle
|
||||||
|
self.AppSetParam(self.style, self.petals, self.nvec)
|
||||||
|
self.AppSetIncrs(self.sincr, self.pincr)
|
||||||
|
delay = self.restart() # Calls us to start drawing
|
||||||
|
|
||||||
|
if delay == 0:
|
||||||
|
if self.verbose:
|
||||||
|
print 'clock: going idle from state', self.int_state
|
||||||
|
else:
|
||||||
|
self.AppAfter(delay, self.clock)
|
||||||
|
|
||||||
|
# Methods to allow App to change the parameters on the screen.
|
||||||
|
# These expect to be called when the associated paramenter changes,
|
||||||
|
# but work reasonably well if several are called at once. (E.g.
|
||||||
|
# tkroses.py groups them into things that affect the visual display
|
||||||
|
# and warrant a new start, and things that just change and don't affect
|
||||||
|
# the ultimate pattern. All parameters within a group are updated
|
||||||
|
# at once even if the value hasn't changed.
|
||||||
|
|
||||||
|
# We restrict the style and petals parameters to the range [0: nvec)
|
||||||
|
# since numbers outside of that range aren't interesting. We don't
|
||||||
|
# immediately update the value in the application, we probably should.
|
||||||
|
|
||||||
|
# NW control window - key parameters
|
||||||
|
def SetStyle(self, value):
|
||||||
|
self.style = value % self.nvec
|
||||||
|
self.restart()
|
||||||
|
|
||||||
|
def SetSincr(self, value):
|
||||||
|
self.sincr = value
|
||||||
|
|
||||||
|
def SetPetals(self, value):
|
||||||
|
self.petals = value % self.nvec
|
||||||
|
self.restart()
|
||||||
|
|
||||||
|
def SetPincr(self, value):
|
||||||
|
self.pincr = value
|
||||||
|
|
||||||
|
|
||||||
|
# SW control window - vectors
|
||||||
|
def SetVectors(self, value):
|
||||||
|
self.nvec = value
|
||||||
|
self.style %= value
|
||||||
|
self.petals %= value
|
||||||
|
self.AppSetParam(self.style, self.petals, self.nvec)
|
||||||
|
self.make_tables(value)
|
||||||
|
self.restart()
|
||||||
|
|
||||||
|
def SetMinVec(self, value):
|
||||||
|
if self.maxvec >= value and self.nvec >= value:
|
||||||
|
self.minvec = value
|
||||||
|
|
||||||
|
def SetMaxVec(self, value):
|
||||||
|
if self.minvec < value:
|
||||||
|
self.maxvec = value
|
||||||
|
|
||||||
|
def SetSkipFirst(self, value):
|
||||||
|
self.skipvec = value
|
||||||
|
self.restart()
|
||||||
|
|
||||||
|
def SetDrawOnly(self, value):
|
||||||
|
self.drawvec = value
|
||||||
|
self.restart()
|
||||||
|
|
||||||
|
|
||||||
|
# SE control window - timings
|
||||||
|
def SetStep(self, value):
|
||||||
|
self.step = value
|
||||||
|
|
||||||
|
def SetDrawDelay(self, value):
|
||||||
|
self.draw_delay = value
|
||||||
|
|
||||||
|
def SetWaitDelay(self, value):
|
||||||
|
self.wait_delay = value
|
||||||
|
|
||||||
|
# Method for client to use to have us supply our defaults.
|
||||||
|
def SupplyControlValues(self):
|
||||||
|
self.update_labels()
|
||||||
|
self.AppSetParam(self.style, self.petals, self.nvec)
|
||||||
|
self.AppSetIncrs(self.sincr, self.pincr)
|
||||||
|
self.AppSetVectors(self.nvec, self.minvec, self.maxvec,
|
||||||
|
self.skipvec, self.drawvec)
|
||||||
|
self.AppSetTiming(self.step, self.draw_delay, self.wait_delay)
|
544
wxPython/samples/roses/wxroses.py
Normal file
544
wxPython/samples/roses/wxroses.py
Normal file
@@ -0,0 +1,544 @@
|
|||||||
|
#----------------------------------------------------------------------------
|
||||||
|
# Name: wxroses.py
|
||||||
|
# Purpose: wxPython GUI using clroses.py to display a classic graphics
|
||||||
|
# hack.
|
||||||
|
#
|
||||||
|
# Author: Ric Werme, Robin Dunn.
|
||||||
|
# WWW: http://WermeNH.com/roses
|
||||||
|
#
|
||||||
|
# Created: June 2007
|
||||||
|
# CVS-ID: $Id$
|
||||||
|
# Copyright: Public Domain, please give credit where credit is due.
|
||||||
|
# License: Sorry, no EULA.
|
||||||
|
#----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
# This module is responsible for everything involving GUI usage
|
||||||
|
# as clroses knows nothing about wxpython, tkintr, etc.
|
||||||
|
|
||||||
|
# There are some notes about how the Roses algorithm works in clroses.py,
|
||||||
|
# but the best reference should be at http://WermeNH.com/roses/index.html .
|
||||||
|
|
||||||
|
# There are a number of enhancements that could be done to wxRoses, and
|
||||||
|
# contributions are welcome as long as you don't destory the general
|
||||||
|
# structure, flavor, and all that. The following list is in the order
|
||||||
|
# I'd like to see done. Some are easy, some aren't, some are easy if
|
||||||
|
# you have experience in the right parts of external code.
|
||||||
|
|
||||||
|
# Brighter crossing points.
|
||||||
|
# Where many vectors cross, the display becomes washed out as a solid shape
|
||||||
|
# of light. On (antique) refresh vector graphics systems, crossing points
|
||||||
|
# are brighter because the electron beam paints the pixels multiple times.
|
||||||
|
# This gives complex patterns a lacy feel to some, and a 3-D sense to
|
||||||
|
# fluted shapes where vectors lie tangent to some curve. It would be
|
||||||
|
# nice to do the same in a bitmap buffer, the code to draw a vector is
|
||||||
|
# pretty simple, adding something that adds brightness to it via math or
|
||||||
|
# a lookup table ought to be a simple addition.
|
||||||
|
|
||||||
|
# Monochrome is so 20th century.
|
||||||
|
# There are a number of things that could be done with color. The simplest
|
||||||
|
# is to step through colors in a color list, better things to do would be
|
||||||
|
# for clroses.py to determine the length of an interesting "generator pattern,"
|
||||||
|
# e.g. the square in the opening display. Then it could change colors either
|
||||||
|
# every four vectors or cycle through the first four colors in the list.
|
||||||
|
|
||||||
|
# Bookmark that Rose!
|
||||||
|
# As you play with wxRoses, you'll come across some patterns that are
|
||||||
|
# "keepers." A bookmark mechanism would be handy.
|
||||||
|
|
||||||
|
# Save that Rose!
|
||||||
|
# It would be nice to have a Menu-bar/File/Save-as dialog to save a pattern
|
||||||
|
# as a jpg/png/gif file.
|
||||||
|
|
||||||
|
# Themes
|
||||||
|
# A pulldown option to select various themes is worthwhile. E.g.:
|
||||||
|
# Start an interesting animation,
|
||||||
|
# Select complex, lacy Roses,
|
||||||
|
# Select the author's favorites,
|
||||||
|
# Return to the initial Rose.
|
||||||
|
# Actually, all that's necessary are some pre-loaded bookmarks.
|
||||||
|
|
||||||
|
# Help text
|
||||||
|
# Standard fare, or:
|
||||||
|
|
||||||
|
# Slide show
|
||||||
|
# At CMU I created an interactive slide show that walked people through
|
||||||
|
# all the options and made suggestions about how to choose Style and Petal.
|
||||||
|
# I forget exactly what I said and may not have listings for it. At any rate,
|
||||||
|
# making the help mechanism start one of several "lessons" where it could
|
||||||
|
# control the display (without blocking the user's control) would be pretty
|
||||||
|
# straightforward.
|
||||||
|
|
||||||
|
import wx
|
||||||
|
import clroses
|
||||||
|
import wx.lib.colourselect as cs
|
||||||
|
|
||||||
|
|
||||||
|
# Class SpinPanel creates a control that includes both a StaticText widget
|
||||||
|
# which holds the the name of a parameter and a SpinCtrl widget which
|
||||||
|
# displays the current value. Values are set at initialization and can
|
||||||
|
# change via the SpinCtrl widget or by the program. So that the program
|
||||||
|
# can easily access the SpinCtrl, the SpinPanel handles are saved in the
|
||||||
|
# spin_panels dictionary.
|
||||||
|
class SpinPanel(wx.Panel):
|
||||||
|
def __init__(self, parent, name, min_value, value, max_value, callback):
|
||||||
|
wx.Panel.__init__(self, parent, -1)
|
||||||
|
if "wxMac" in wx.PlatformInfo:
|
||||||
|
self.SetWindowVariant(wx.WINDOW_VARIANT_SMALL)
|
||||||
|
self.st = wx.StaticText(self, -1, name)
|
||||||
|
self.sc = wx.SpinCtrl(self, -1, "", size = (70, -1))
|
||||||
|
self.sc.SetRange(min_value, max_value)
|
||||||
|
self.sc.SetValue(value)
|
||||||
|
self.sc.Bind(wx.EVT_SPINCTRL, self.OnSpin)
|
||||||
|
self.callback = callback
|
||||||
|
|
||||||
|
sizer = wx.BoxSizer(wx.HORIZONTAL)
|
||||||
|
sizer.Add(self.st, 0, wx.ALIGN_CENTER_VERTICAL)
|
||||||
|
sizer.Add((1,1), 1)
|
||||||
|
sizer.Add(self.sc)
|
||||||
|
self.SetSizer(sizer)
|
||||||
|
|
||||||
|
global spin_panels
|
||||||
|
spin_panels[name] = self
|
||||||
|
|
||||||
|
# Called (generally through spin_panels{}) to set the SpinCtrl value.
|
||||||
|
def SetValue(self, value):
|
||||||
|
self.sc.SetValue(value)
|
||||||
|
|
||||||
|
# Called when user changes the SpinCtrl value.
|
||||||
|
def OnSpin(self, event):
|
||||||
|
name = self.st.GetLabel()
|
||||||
|
value = self.sc.GetValue()
|
||||||
|
if verbose:
|
||||||
|
print 'OnSpin', name, '=', value
|
||||||
|
self.callback(name, value) # Call MyFrame.OnSpinback to call clroses
|
||||||
|
|
||||||
|
|
||||||
|
# This class is used to display the current rose diagram. It keeps a
|
||||||
|
# buffer bitmap of the current display, which it uses to refresh the
|
||||||
|
# screen with when needed. When it is told to draw some lines it does
|
||||||
|
# so to the buffer in order for it to always be up to date.
|
||||||
|
class RosePanel(wx.Panel):
|
||||||
|
def __init__(self, *args, **kw):
|
||||||
|
wx.Panel.__init__(self, *args, **kw)
|
||||||
|
self.InitBuffer()
|
||||||
|
self.resizeNeeded = False
|
||||||
|
self.useGCDC = False
|
||||||
|
self.useBuffer = True
|
||||||
|
|
||||||
|
# set default colors
|
||||||
|
self.SetBackgroundColour((51, 51, 51)) # gray20
|
||||||
|
self.SetForegroundColour((164, 211, 238)) # lightskyblue2
|
||||||
|
|
||||||
|
# connect the size and paint events to handlers
|
||||||
|
self.Bind(wx.EVT_SIZE, self.OnSize)
|
||||||
|
self.Bind(wx.EVT_PAINT, self.OnPaint)
|
||||||
|
self.Bind(wx.EVT_IDLE, self.OnIdle)
|
||||||
|
|
||||||
|
|
||||||
|
def InitBuffer(self):
|
||||||
|
size = self.GetClientSize()
|
||||||
|
self.buffer = wx.EmptyBitmap(max(1, size.width),
|
||||||
|
max(1, size.height))
|
||||||
|
|
||||||
|
def Clear(self):
|
||||||
|
dc = self.useBuffer and wx.MemoryDC(self.buffer) or wx.ClientDC(self)
|
||||||
|
dc.SetBackground(wx.Brush(self.GetBackgroundColour()))
|
||||||
|
dc.Clear()
|
||||||
|
if self.useBuffer:
|
||||||
|
self.Refresh(False)
|
||||||
|
|
||||||
|
def DrawLines(self, lines):
|
||||||
|
if len(lines) <= 1:
|
||||||
|
return
|
||||||
|
dc = self.useBuffer and wx.MemoryDC(self.buffer) or wx.ClientDC(self)
|
||||||
|
if self.useGCDC:
|
||||||
|
dc = wx.GCDC(dc)
|
||||||
|
dc.SetPen(wx.Pen(self.GetForegroundColour(), 1))
|
||||||
|
dc.DrawLines(lines)
|
||||||
|
if self.useBuffer:
|
||||||
|
self.Refresh(False)
|
||||||
|
|
||||||
|
def TriggerResize(self):
|
||||||
|
self.GetParent().TriggerResize(self.buffer.GetSize())
|
||||||
|
|
||||||
|
def TriggerRedraw(self):
|
||||||
|
self.GetParent().TriggerRedraw()
|
||||||
|
|
||||||
|
def OnSize(self, evt):
|
||||||
|
self.resizeNeeded = True
|
||||||
|
|
||||||
|
def OnIdle(self, evt):
|
||||||
|
if self.resizeNeeded:
|
||||||
|
self.InitBuffer()
|
||||||
|
self.TriggerResize()
|
||||||
|
if self.useBuffer:
|
||||||
|
self.Refresh()
|
||||||
|
self.resizeNeeded = False
|
||||||
|
|
||||||
|
def OnPaint(self, evt):
|
||||||
|
dc = wx.PaintDC(self)
|
||||||
|
if self.useBuffer:
|
||||||
|
dc.DrawBitmap(self.buffer, 0,0)
|
||||||
|
else:
|
||||||
|
self.TriggerRedraw()
|
||||||
|
|
||||||
|
|
||||||
|
# A panel used to collect options on how the rose is drawn
|
||||||
|
class OptionsPanel(wx.Panel):
|
||||||
|
def __init__(self, parent, rose):
|
||||||
|
wx.Panel.__init__(self, parent)
|
||||||
|
self.rose = rose
|
||||||
|
sizer = wx.StaticBoxSizer(wx.StaticBox(self, label='Options'),
|
||||||
|
wx.VERTICAL)
|
||||||
|
self.useGCDC = wx.CheckBox(self, label="Use GCDC")
|
||||||
|
sizer.Add(self.useGCDC, 0, wx.BOTTOM|wx.LEFT, 2)
|
||||||
|
self.useBuffer = wx.CheckBox(self, label="Use buffering")
|
||||||
|
sizer.Add(self.useBuffer, 0, wx.BOTTOM|wx.LEFT, 2)
|
||||||
|
|
||||||
|
def makeCButton(label):
|
||||||
|
btn = cs.ColourSelect(self, size=(20,22))
|
||||||
|
lbl = wx.StaticText(self, -1, label)
|
||||||
|
sizer = wx.BoxSizer(wx.HORIZONTAL)
|
||||||
|
sizer.Add(btn)
|
||||||
|
sizer.Add((4,4))
|
||||||
|
sizer.Add(lbl, 0, wx.ALIGN_CENTER_VERTICAL)
|
||||||
|
return sizer, btn
|
||||||
|
|
||||||
|
s, self.fg = makeCButton('Foreground')
|
||||||
|
sizer.Add(s)
|
||||||
|
s, self.bg = makeCButton('Background')
|
||||||
|
sizer.Add(s)
|
||||||
|
self.SetSizer(sizer)
|
||||||
|
|
||||||
|
self.Bind(wx.EVT_CHECKBOX, self.OnUseGCDC, self.useGCDC)
|
||||||
|
self.Bind(wx.EVT_CHECKBOX, self.OnUseBuffer, self.useBuffer)
|
||||||
|
self.Bind(wx.EVT_IDLE, self.OnIdle)
|
||||||
|
self.Bind(cs.EVT_COLOURSELECT, self.OnSetFG, self.fg)
|
||||||
|
self.Bind(cs.EVT_COLOURSELECT, self.OnSetBG, self.bg)
|
||||||
|
|
||||||
|
def OnIdle(self, evt):
|
||||||
|
if self.useGCDC.GetValue() != self.rose.useGCDC:
|
||||||
|
self.useGCDC.SetValue(self.rose.useGCDC)
|
||||||
|
if self.useBuffer.GetValue() != self.rose.useBuffer:
|
||||||
|
self.useBuffer.SetValue(self.rose.useBuffer)
|
||||||
|
if self.fg.GetValue() != self.rose.GetForegroundColour():
|
||||||
|
self.fg.SetValue(self.rose.GetForegroundColour())
|
||||||
|
if self.bg.GetValue() != self.rose.GetBackgroundColour():
|
||||||
|
self.bg.SetValue(self.rose.GetBackgroundColour())
|
||||||
|
|
||||||
|
def OnUseGCDC(self, evt):
|
||||||
|
self.rose.useGCDC = evt.IsChecked()
|
||||||
|
self.rose.TriggerRedraw()
|
||||||
|
|
||||||
|
def OnUseBuffer(self, evt):
|
||||||
|
self.rose.useBuffer = evt.IsChecked()
|
||||||
|
self.rose.TriggerRedraw()
|
||||||
|
|
||||||
|
def OnSetFG(self, evt):
|
||||||
|
self.rose.SetForegroundColour(evt.GetValue())
|
||||||
|
self.rose.TriggerRedraw()
|
||||||
|
|
||||||
|
def OnSetBG(self, evt):
|
||||||
|
self.rose.SetBackgroundColour(evt.GetValue())
|
||||||
|
self.rose.TriggerRedraw()
|
||||||
|
|
||||||
|
|
||||||
|
# MyFrame is the traditional class name to create and populate the
|
||||||
|
# application's frame. The general GUI has control/status panels on
|
||||||
|
# the right side and a panel on the left side that draws the rose
|
||||||
|
#
|
||||||
|
# This class also derives from clroses.rose so it can implement the
|
||||||
|
# required interfaces to connect the GUI to the rose engine.
|
||||||
|
class MyFrame(wx.Frame, clroses.rose):
|
||||||
|
# Color matching dictionary, convert label name to color:
|
||||||
|
# Stop and Go ala traffic lights,
|
||||||
|
# Skip and Forward look ahead to the purple mountain majesties (really bluish),
|
||||||
|
# Reverse and Backward look morosely behind to maroon memories,
|
||||||
|
# Redraw looks at the brown earth right below your feet.
|
||||||
|
# Yeah, so it's lame. All I really wanted was to color Stop and Go.
|
||||||
|
labelColours = {
|
||||||
|
'Go': 'dark green', 'Stop': 'red',
|
||||||
|
'Redraw': 'brown', 'Skip': 'dark slate blue',
|
||||||
|
'Backward': 'maroon', 'Forward': 'dark slate blue', 'Reverse': 'maroon'
|
||||||
|
}
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
def makeSP(name, labels, statictexts = None):
|
||||||
|
panel = wx.Panel(self.side_panel, -1)
|
||||||
|
box = wx.StaticBox(panel, -1, name)
|
||||||
|
sizer = wx.StaticBoxSizer(box, wx.VERTICAL)
|
||||||
|
for name, min_value, value, max_value in labels:
|
||||||
|
sp = SpinPanel(panel, name, min_value, value, max_value, self.OnSpinback)
|
||||||
|
sizer.Add(sp, 0, wx.EXPAND)
|
||||||
|
if statictexts:
|
||||||
|
for name, text in statictexts:
|
||||||
|
st = wx.StaticText(panel, -1, text)
|
||||||
|
spin_panels[name] = st # Supposed to be a SpinPanel....
|
||||||
|
sizer.Add(st, 0, wx.EXPAND)
|
||||||
|
panel.SetSizer(sizer)
|
||||||
|
return panel
|
||||||
|
|
||||||
|
wx.Frame.__init__(self, None, title="Roses in wxPython")
|
||||||
|
|
||||||
|
self.rose_panel = RosePanel(self)
|
||||||
|
self.side_panel = wx.Panel(self)
|
||||||
|
|
||||||
|
# The cmd panel is four buttons whose names and foreground colors
|
||||||
|
# change. Plop them in a StaticBox like the SpinPanels. Use
|
||||||
|
# a 2x2 grid, but StaticBoxSizer can't handle that. Therefore,
|
||||||
|
# create a sub panel, layout the buttons there, then give that to
|
||||||
|
# a higher panel that has the static box stuff.
|
||||||
|
self.cmd_panel = wx.Panel(self.side_panel, -1)
|
||||||
|
self.sub_panel = wx.Panel(self.cmd_panel, -1)
|
||||||
|
sizer = wx.GridSizer(rows = 2, cols = 2)
|
||||||
|
global ctrl_buttons
|
||||||
|
border = 'wxMac' in wx.PlatformInfo and 3 or 1
|
||||||
|
for name, handler in (
|
||||||
|
('Go', self.OnGoStop),
|
||||||
|
('Redraw', self.OnRedraw),
|
||||||
|
('Backward', self.OnBackward),
|
||||||
|
('Forward', self.OnForward)):
|
||||||
|
button = wx.Button(self.sub_panel, -1, name)
|
||||||
|
button.SetForegroundColour(self.labelColours[name])
|
||||||
|
ctrl_buttons[name] = button
|
||||||
|
button.Bind(wx.EVT_BUTTON, handler)
|
||||||
|
sizer.Add(button, 0, wx.EXPAND|wx.ALL, border)
|
||||||
|
self.sub_panel.SetSizer(sizer)
|
||||||
|
|
||||||
|
# Set up cmd_panel with StaticBox stuff
|
||||||
|
box = wx.StaticBox(self.cmd_panel, -1, 'Command')
|
||||||
|
sizer = wx.StaticBoxSizer(box, wx.VERTICAL)
|
||||||
|
sizer.Add(self.sub_panel)
|
||||||
|
self.cmd_panel.SetSizer(sizer)
|
||||||
|
|
||||||
|
# Now make the rest of the control panels...
|
||||||
|
# The order of creation of SpinCtrls and Buttons is the order that
|
||||||
|
# the tab key will step through, so the order of panel creation is
|
||||||
|
# important.
|
||||||
|
# In the SpinPanel data (name, min, value, max), value will be
|
||||||
|
# overridden by clroses.py defaults.
|
||||||
|
self.coe_panel = makeSP('Coefficient',
|
||||||
|
(('Style', 0, 100, 3600),
|
||||||
|
('Sincr', -3600, -1, 3600),
|
||||||
|
('Petal', 0, 2, 3600),
|
||||||
|
('Pincr', -3600, 1, 3600)))
|
||||||
|
|
||||||
|
self.vec_panel = makeSP('Vector',
|
||||||
|
(('Vectors' , 1, 399, 3600),
|
||||||
|
('Minimum' , 1, 1, 3600),
|
||||||
|
('Maximum' , 1, 3600, 3600),
|
||||||
|
('Skip first', 0, 0, 3600),
|
||||||
|
('Draw only' , 1, 3600, 3600)),
|
||||||
|
(('Takes', 'Takes 0000 vectors'), ))
|
||||||
|
|
||||||
|
self.tim_panel = makeSP('Timing',
|
||||||
|
(('Vec/tick' , 1, 20, 3600),
|
||||||
|
('msec/tick', 1, 50, 1000),
|
||||||
|
('Delay' , 1, 2000, 9999)))
|
||||||
|
|
||||||
|
self.opt_panel = OptionsPanel(self.side_panel, self.rose_panel)
|
||||||
|
|
||||||
|
# put them all on in a sizer attached to the side_panel
|
||||||
|
panelSizer = wx.BoxSizer(wx.VERTICAL)
|
||||||
|
panelSizer.Add(self.cmd_panel, 0, wx.EXPAND|wx.TOP|wx.LEFT|wx.RIGHT, 5)
|
||||||
|
panelSizer.Add(self.coe_panel, 0, wx.EXPAND|wx.TOP|wx.LEFT|wx.RIGHT, 5)
|
||||||
|
panelSizer.Add(self.vec_panel, 0, wx.EXPAND|wx.TOP|wx.LEFT|wx.RIGHT, 5)
|
||||||
|
panelSizer.Add(self.tim_panel, 0, wx.EXPAND|wx.TOP|wx.LEFT|wx.RIGHT, 5)
|
||||||
|
panelSizer.Add(self.opt_panel, 0, wx.EXPAND|wx.TOP|wx.LEFT|wx.RIGHT, 5)
|
||||||
|
self.side_panel.SetSizer(panelSizer)
|
||||||
|
|
||||||
|
# and now arrange the two main panels in another sizer for the frame
|
||||||
|
mainSizer = wx.BoxSizer(wx.HORIZONTAL)
|
||||||
|
mainSizer.Add(self.rose_panel, 1, wx.EXPAND)
|
||||||
|
mainSizer.Add(self.side_panel, 0, wx.EXPAND)
|
||||||
|
self.SetSizer(mainSizer)
|
||||||
|
|
||||||
|
# bind event handlers
|
||||||
|
self.timer = wx.Timer(self)
|
||||||
|
self.Bind(wx.EVT_TIMER, self.OnTimer, self.timer)
|
||||||
|
|
||||||
|
# Determine appropriate image size.
|
||||||
|
# At this point, the rose_panel and side_panel will both report
|
||||||
|
# size (20, 20). After mainSizer.Fit(self) they will report the
|
||||||
|
# same, but the Frame size, self.GetSize(), will report the desired
|
||||||
|
# side panel dimensions plus an extra 20 on the width. That lets
|
||||||
|
# us determine the frame size that will display the side panel and
|
||||||
|
# a square space for the diagram. Only after Show() will the two
|
||||||
|
# panels report the accurate sizes.
|
||||||
|
mainSizer.Fit(self)
|
||||||
|
rw, rh = self.rose_panel.GetSize()
|
||||||
|
sw, sh = self.side_panel.GetSize()
|
||||||
|
fw, fh = self.GetSize()
|
||||||
|
h = max(600, fh) # Change 600 to desired minimum size
|
||||||
|
w = h + fw - rw
|
||||||
|
if verbose:
|
||||||
|
print 'rose panel size', (rw, rh)
|
||||||
|
print 'side panel size', (sw, sh)
|
||||||
|
print ' frame size', (fw, fh)
|
||||||
|
print 'Want size', (w,h)
|
||||||
|
self.SetSize((w, h))
|
||||||
|
self.SupplyControlValues() # Ask clroses to tell us all the defaults
|
||||||
|
self.Show()
|
||||||
|
|
||||||
|
# Command button event handlers. These are relabled when changing between auto
|
||||||
|
# and manual modes. They simply reflect the call to a method in the base class.
|
||||||
|
#
|
||||||
|
# Go/Stop button
|
||||||
|
def OnGoStop(self, event):
|
||||||
|
if verbose:
|
||||||
|
print 'OnGoStop'
|
||||||
|
self.cmd_go_stop()
|
||||||
|
|
||||||
|
# Redraw/Redraw
|
||||||
|
def OnRedraw(self, event):
|
||||||
|
if verbose:
|
||||||
|
print 'OnRedraw'
|
||||||
|
self.cmd_redraw()
|
||||||
|
|
||||||
|
# Backward/Reverse
|
||||||
|
def OnBackward(self, event):
|
||||||
|
if verbose:
|
||||||
|
print 'OnBackward'
|
||||||
|
self.cmd_backward()
|
||||||
|
|
||||||
|
# Forward/Skip
|
||||||
|
def OnForward(self, event):
|
||||||
|
if verbose:
|
||||||
|
print 'OnForward'
|
||||||
|
self.cmd_step()
|
||||||
|
|
||||||
|
|
||||||
|
# The clroses.roses class expects to have methods available that
|
||||||
|
# implement the missing parts of the functionality needed to do
|
||||||
|
# the actual work of getting the diagram to the screen and etc.
|
||||||
|
# Those are implemented here as the App* methods.
|
||||||
|
|
||||||
|
def AppClear(self):
|
||||||
|
if verbose:
|
||||||
|
print 'AppClear: clear screen'
|
||||||
|
self.rose_panel.Clear()
|
||||||
|
|
||||||
|
def AppCreateLine(self, line):
|
||||||
|
# print 'AppCreateLine, len', len(line), 'next', self.nextpt
|
||||||
|
self.rose_panel.DrawLines(line)
|
||||||
|
|
||||||
|
# Here when clroses has set a new style and/or petal value, update
|
||||||
|
# strings on display.
|
||||||
|
def AppSetParam(self, style, petals, vectors):
|
||||||
|
spin_panels['Style'].SetValue(style)
|
||||||
|
spin_panels['Petal'].SetValue(petals)
|
||||||
|
spin_panels['Vectors'].SetValue(vectors)
|
||||||
|
|
||||||
|
def AppSetIncrs(self, sincr, pincr):
|
||||||
|
spin_panels['Sincr'].SetValue(sincr)
|
||||||
|
spin_panels['Pincr'].SetValue(pincr)
|
||||||
|
|
||||||
|
def AppSetVectors(self, vectors, minvec, maxvec, skipvec, drawvec):
|
||||||
|
spin_panels['Vectors'].SetValue(vectors)
|
||||||
|
spin_panels['Minimum'].SetValue(minvec)
|
||||||
|
spin_panels['Maximum'].SetValue(maxvec)
|
||||||
|
spin_panels['Skip first'].SetValue(skipvec)
|
||||||
|
spin_panels['Draw only'].SetValue(drawvec)
|
||||||
|
|
||||||
|
def AppSetTakesVec(self, takes):
|
||||||
|
spin_panels['Takes'].SetLabel('Takes %d vectors' % takes)
|
||||||
|
|
||||||
|
# clroses doesn't change this data, so it's not telling us something
|
||||||
|
# we don't already know.
|
||||||
|
def AppSetTiming(self, vecPtick, msecPtick, delay):
|
||||||
|
spin_panels['Vec/tick'].SetValue(vecPtick)
|
||||||
|
spin_panels['msec/tick'].SetValue(msecPtick)
|
||||||
|
spin_panels['Delay'].SetValue(delay)
|
||||||
|
|
||||||
|
# Command buttons change their names based on the whether we're in auto
|
||||||
|
# or manual mode.
|
||||||
|
def AppCmdLabels(self, labels):
|
||||||
|
for name, label in map(None, ('Go', 'Redraw', 'Backward', 'Forward'), labels):
|
||||||
|
ctrl_buttons[name].SetLabel(label)
|
||||||
|
ctrl_buttons[name].SetForegroundColour(self.labelColours[label])
|
||||||
|
|
||||||
|
|
||||||
|
# Timer methods. The paranoia about checking up on the callers is
|
||||||
|
# primarily because it's easier to check here. We expect that calls to
|
||||||
|
# AppAfter and OnTimer alternate, but don't verify that AppCancelTimer()
|
||||||
|
# is canceling anything as callers of that may be uncertain about what's
|
||||||
|
# happening.
|
||||||
|
|
||||||
|
# Method to provide a single callback after some amount of time.
|
||||||
|
def AppAfter(self, msec, callback):
|
||||||
|
if self.timer_callback:
|
||||||
|
print 'AppAfter: timer_callback already set!',
|
||||||
|
# print 'AppAfter:', callback
|
||||||
|
self.timer_callback = callback
|
||||||
|
self.timer.Start(msec, True)
|
||||||
|
|
||||||
|
# Method to cancel something we might be waiting for but have lost
|
||||||
|
# interest in.
|
||||||
|
def AppCancelTimer(self):
|
||||||
|
self.timer.Stop()
|
||||||
|
# print 'AppCancelTimer'
|
||||||
|
self.timer_callback = None
|
||||||
|
|
||||||
|
# When the timer happens, we come here and jump off to clroses internal code.
|
||||||
|
def OnTimer(self, evt):
|
||||||
|
callback = self.timer_callback
|
||||||
|
self.timer_callback = None
|
||||||
|
# print 'OnTimer,', callback
|
||||||
|
if callback:
|
||||||
|
callback() # Often calls AppAfter() and sets the callback
|
||||||
|
else:
|
||||||
|
print 'OnTimer: no callback!'
|
||||||
|
|
||||||
|
|
||||||
|
resize_delay = 300
|
||||||
|
|
||||||
|
def TriggerResize(self, size):
|
||||||
|
self.resize(size, self.resize_delay)
|
||||||
|
self.resize_delay = 100
|
||||||
|
|
||||||
|
def TriggerRedraw(self):
|
||||||
|
self.repaint(10)
|
||||||
|
|
||||||
|
# Called when data in spin boxes changes.
|
||||||
|
def OnSpinback(self, name, value):
|
||||||
|
if verbose:
|
||||||
|
print 'OnSpinback', name, value
|
||||||
|
if name == 'Style':
|
||||||
|
self.SetStyle(value)
|
||||||
|
elif name == 'Sincr':
|
||||||
|
self.SetSincr(value)
|
||||||
|
elif name == 'Petal':
|
||||||
|
self.SetPetals(value)
|
||||||
|
elif name == 'Pincr':
|
||||||
|
self.SetPincr(value)
|
||||||
|
|
||||||
|
elif name == 'Vectors':
|
||||||
|
self.SetVectors(value)
|
||||||
|
elif name == 'Minimum':
|
||||||
|
self.SetMinVec(value)
|
||||||
|
elif name == 'Maximum':
|
||||||
|
self.SetMaxVec(value)
|
||||||
|
elif name == 'Skip first':
|
||||||
|
self.SetSkipFirst(value)
|
||||||
|
elif name == 'Draw only':
|
||||||
|
self.SetDrawOnly(value)
|
||||||
|
|
||||||
|
elif name == 'Vec/tick':
|
||||||
|
self.SetStep(value)
|
||||||
|
elif name == 'msec/tick':
|
||||||
|
self.SetDrawDelay(value)
|
||||||
|
elif name == 'Delay':
|
||||||
|
self.SetWaitDelay(value)
|
||||||
|
else:
|
||||||
|
print 'OnSpinback: Don\'t recognize', name
|
||||||
|
|
||||||
|
verbose = 0 # Need some command line options...
|
||||||
|
spin_panels = {} # Hooks to get from rose to panel labels
|
||||||
|
ctrl_buttons = {} # Button widgets for command (NE) panel
|
||||||
|
|
||||||
|
app = wx.App(False)
|
||||||
|
MyFrame()
|
||||||
|
if verbose:
|
||||||
|
print 'spin_panels', spin_panels.keys()
|
||||||
|
print 'ctrl_buttons', ctrl_buttons.keys()
|
||||||
|
app.MainLoop()
|
@@ -482,7 +482,12 @@ wxpExtensions.append(ext)
|
|||||||
|
|
||||||
|
|
||||||
swig_sources = run_swig(['richtext.i'], 'src', GENDIR, PKGDIR,
|
swig_sources = run_swig(['richtext.i'], 'src', GENDIR, PKGDIR,
|
||||||
USE_SWIG, swig_force, swig_args, swig_deps)
|
USE_SWIG, swig_force, swig_args,
|
||||||
|
swig_deps + [ 'src/_richtextbuffer.i',
|
||||||
|
'src/_richtextctrl.i',
|
||||||
|
'src/_richtexthtml.i',
|
||||||
|
'src/_richtextxml.i',
|
||||||
|
])
|
||||||
if not MONOLITHIC and findLib('richtext', libdirs):
|
if not MONOLITHIC and findLib('richtext', libdirs):
|
||||||
richLib = makeLibName('richtext')
|
richLib = makeLibName('richtext')
|
||||||
else:
|
else:
|
||||||
@@ -569,6 +574,11 @@ if BUILD_GLCANVAS:
|
|||||||
gl_libs = libs + ['opengl32', 'glu32'] + makeLibName('gl')
|
gl_libs = libs + ['opengl32', 'glu32'] + makeLibName('gl')
|
||||||
gl_lflags = lflags
|
gl_lflags = lflags
|
||||||
|
|
||||||
|
if sys.platform[:6] == "darwin" and WXPORT == 'mac':
|
||||||
|
if not ARCH == "":
|
||||||
|
gl_lflags.append("-arch")
|
||||||
|
gl_lflags.append(ARCH)
|
||||||
|
|
||||||
ext = Extension('_glcanvas',
|
ext = Extension('_glcanvas',
|
||||||
swig_sources,
|
swig_sources,
|
||||||
|
|
||||||
|
@@ -24,10 +24,10 @@
|
|||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
%{
|
%{
|
||||||
// See http://tinyurl.com/e5adr for what premultiplying alpha means. It
|
// See http://tinyurl.com/e5adr for what premultiplying alpha means. wxMSW and
|
||||||
// appears to me that the other platforms are already doing it, so I'll just
|
// wxMac want to have the values premultiplied by the alpha value, but the
|
||||||
// automatically do it for wxMSW here.
|
// other platforms don't. These macros help keep the code clean.
|
||||||
#ifdef __WXMSW__
|
#if defined(__WXMSW__) || (defined(__WXMAC__) && wxMAC_USE_CORE_GRAPHICS)
|
||||||
#define wxPy_premultiply(p, a) ((p) * (a) / 0xff)
|
#define wxPy_premultiply(p, a) ((p) * (a) / 0xff)
|
||||||
#define wxPy_unpremultiply(p, a) ((a) ? ((p) * 0xff / (a)) : (p))
|
#define wxPy_unpremultiply(p, a) ((a) ? ((p) * 0xff / (a)) : (p))
|
||||||
#else
|
#else
|
||||||
@@ -500,8 +500,8 @@ def BitmapFromBuffer(width, height, dataBuffer, alphaBuffer=None):
|
|||||||
expected to contain a series of RGB bytes and be width*height*3
|
expected to contain a series of RGB bytes and be width*height*3
|
||||||
bytes long. A buffer object can optionally be supplied for the
|
bytes long. A buffer object can optionally be supplied for the
|
||||||
image's alpha channel data, and it is expected to be width*height
|
image's alpha channel data, and it is expected to be width*height
|
||||||
bytes long. On Windows the RGB values are 'premultiplied' by the
|
bytes long. On Windows and Mac the RGB values are 'premultiplied'
|
||||||
alpha values. (The other platforms do the multiplication
|
by the alpha values. (The other platforms do the multiplication
|
||||||
themselves.)
|
themselves.)
|
||||||
|
|
||||||
Unlike `wx.ImageFromBuffer` the bitmap created with this function
|
Unlike `wx.ImageFromBuffer` the bitmap created with this function
|
||||||
@@ -567,8 +567,8 @@ def BitmapFromBufferRGBA(width, height, dataBuffer):
|
|||||||
parameter must be a Python object that implements the buffer
|
parameter must be a Python object that implements the buffer
|
||||||
interface, such as a string, array, etc. The dataBuffer object is
|
interface, such as a string, array, etc. The dataBuffer object is
|
||||||
expected to contain a series of RGBA bytes (red, green, blue and
|
expected to contain a series of RGBA bytes (red, green, blue and
|
||||||
alpha) and be width*height*4 bytes long. On Windows the RGB
|
alpha) and be width*height*4 bytes long. On Windows and Mac the
|
||||||
values are 'premultiplied' by the alpha values. (The other
|
RGB values are 'premultiplied' by the alpha values. (The other
|
||||||
platforms do the multiplication themselves.)
|
platforms do the multiplication themselves.)
|
||||||
|
|
||||||
Unlike `wx.ImageFromBuffer` the bitmap created with this function
|
Unlike `wx.ImageFromBuffer` the bitmap created with this function
|
||||||
|
@@ -35,7 +35,7 @@ Blue (RGB) intensity values, and is used to determine drawing colours,
|
|||||||
window colours, etc. Valid RGB values are in the range 0 to 255.
|
window colours, etc. Valid RGB values are in the range 0 to 255.
|
||||||
|
|
||||||
In wxPython there are typemaps that will automatically convert from a
|
In wxPython there are typemaps that will automatically convert from a
|
||||||
colour name, from a '#RRGGBB' colour hex value string, or from a 3
|
colour name, from a '#RRGGBB' colour hex value string, or from a 3 or 4
|
||||||
integer tuple to a wx.Colour object when calling C++ methods that
|
integer tuple to a wx.Colour object when calling C++ methods that
|
||||||
expect a wxColour. This means that the following are all
|
expect a wxColour. This means that the following are all
|
||||||
equivallent::
|
equivallent::
|
||||||
@@ -59,7 +59,7 @@ public:
|
|||||||
|
|
||||||
DocCtorStr(
|
DocCtorStr(
|
||||||
wxColour(byte red=0, byte green=0, byte blue=0, byte alpha=wxALPHA_OPAQUE),
|
wxColour(byte red=0, byte green=0, byte blue=0, byte alpha=wxALPHA_OPAQUE),
|
||||||
"Constructs a colour from red, green and blue values.
|
"Constructs a colour from red, green, blue and alpha values.
|
||||||
|
|
||||||
:see: Alternate constructors `wx.NamedColour` and `wx.ColourRGB`.
|
:see: Alternate constructors `wx.NamedColour` and `wx.ColourRGB`.
|
||||||
", "");
|
", "");
|
||||||
@@ -165,8 +165,8 @@ is returned if the pixel is invalid (on X, unallocated).", "");
|
|||||||
%extend {
|
%extend {
|
||||||
KeepGIL(Get);
|
KeepGIL(Get);
|
||||||
DocAStr(Get,
|
DocAStr(Get,
|
||||||
"Get() -> (r, g, b)",
|
"Get(self, bool includeAlpha=False) -> (r,g,b) or (r,g,b,a)",
|
||||||
"Returns the RGB intensity values as a tuple.", "");
|
"Returns the RGB intensity values as a tuple, optionally the alpha value as well.", "");
|
||||||
PyObject* Get(bool includeAlpha=false) {
|
PyObject* Get(bool includeAlpha=false) {
|
||||||
PyObject* rv = PyTuple_New(includeAlpha ? 4 : 3);
|
PyObject* rv = PyTuple_New(includeAlpha ? 4 : 3);
|
||||||
int red = -1;
|
int red = -1;
|
||||||
|
@@ -242,6 +242,8 @@ static wxPyCoreAPI API = {
|
|||||||
wxRect2D_helper,
|
wxRect2D_helper,
|
||||||
wxPosition_helper,
|
wxPosition_helper,
|
||||||
|
|
||||||
|
wxPyCBOutputStream_create,
|
||||||
|
wxPyCBOutputStream_copy,
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@@ -93,6 +93,7 @@ typedef unsigned int size_t;
|
|||||||
typedef unsigned int time_t;
|
typedef unsigned int time_t;
|
||||||
typedef unsigned char byte;
|
typedef unsigned char byte;
|
||||||
typedef unsigned long wxUIntPtr;
|
typedef unsigned long wxUIntPtr;
|
||||||
|
typedef double wxDouble;
|
||||||
|
|
||||||
#define wxWindowID int
|
#define wxWindowID int
|
||||||
#define wxCoord int
|
#define wxCoord int
|
||||||
@@ -408,6 +409,19 @@ typedef unsigned long wxUIntPtr;
|
|||||||
%enddef
|
%enddef
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef _DO_FULL_DOCS
|
||||||
|
%define %RenameDocStr(newname, docstr, details, type, decl)
|
||||||
|
%feature("docstring") decl docstr;
|
||||||
|
%rename(newname) decl;
|
||||||
|
type decl
|
||||||
|
%enddef
|
||||||
|
#else
|
||||||
|
%define %RenameDocStr(newname, docstr, details, type, decl)
|
||||||
|
%feature("docstring") decl docstr details;
|
||||||
|
%rename(newname) decl;
|
||||||
|
type decl
|
||||||
|
%enddef
|
||||||
|
#endif
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
// Generates a base_On* method that just wraps a call to the On*, and mark it
|
// Generates a base_On* method that just wraps a call to the On*, and mark it
|
||||||
@@ -459,6 +473,204 @@ FORWARD_DECLARE(wxIcon, Icon);
|
|||||||
FORWARD_DECLARE(wxStaticBox, StaticBox);
|
FORWARD_DECLARE(wxStaticBox, StaticBox);
|
||||||
|
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
// This macro makes a class to wrap a type specific class derived from wxList,
|
||||||
|
// and make it look like a Python sequence, including with iterator support
|
||||||
|
|
||||||
|
%define wxLIST_WRAPPER(ListClass, ItemClass)
|
||||||
|
// first a bit of C++ code...
|
||||||
|
%{
|
||||||
|
class ListClass##_iterator
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ListClass##_iterator(ListClass::compatibility_iterator start)
|
||||||
|
: m_node(start) {}
|
||||||
|
|
||||||
|
ItemClass* next() {
|
||||||
|
ItemClass* obj = NULL;
|
||||||
|
if (m_node) {
|
||||||
|
obj = m_node->GetData();
|
||||||
|
m_node = m_node->GetNext();
|
||||||
|
}
|
||||||
|
else PyErr_SetString(PyExc_StopIteration, "");
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
ListClass::compatibility_iterator m_node;
|
||||||
|
};
|
||||||
|
%}
|
||||||
|
|
||||||
|
// Now declare the classes for SWIG
|
||||||
|
|
||||||
|
DocStr(ListClass##_iterator,
|
||||||
|
"This class serves as an iterator for a ListClass object.", "");
|
||||||
|
|
||||||
|
class ListClass##_iterator
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
//ListClass##_iterator();
|
||||||
|
~ListClass_iterator();
|
||||||
|
KeepGIL(next);
|
||||||
|
ItemClass* next();
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
DocStr(ListClass,
|
||||||
|
"This class wraps a wxList-based class and gives it a Python
|
||||||
|
sequence-like interface. Sequence operations supported are length,
|
||||||
|
index access and iteration.", "");
|
||||||
|
|
||||||
|
class ListClass
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
//ListClass(); This will always be created by some C++ function
|
||||||
|
~ListClass();
|
||||||
|
|
||||||
|
%extend {
|
||||||
|
KeepGIL(__len__);
|
||||||
|
size_t __len__() {
|
||||||
|
return self->size();
|
||||||
|
}
|
||||||
|
|
||||||
|
KeepGIL(__getitem__);
|
||||||
|
ItemClass* __getitem__(size_t index) {
|
||||||
|
if (index < self->size()) {
|
||||||
|
ListClass::compatibility_iterator node = self->Item(index);
|
||||||
|
if (node) return node->GetData();
|
||||||
|
}
|
||||||
|
PyErr_SetString(PyExc_IndexError, "Invalid list index");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
KeepGIL(__contains__);
|
||||||
|
bool __contains__(const ItemClass* obj) {
|
||||||
|
return self->Find(obj) != NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
KeepGIL(__iter__);
|
||||||
|
%newobject __iter__;
|
||||||
|
ListClass##_iterator* __iter__() {
|
||||||
|
return new ListClass##_iterator(self->GetFirst());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
%pythoncode {
|
||||||
|
def __repr__(self):
|
||||||
|
return "ListClass: " + repr(list(self))
|
||||||
|
}
|
||||||
|
};
|
||||||
|
%enddef
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// This macro is similar to the above, but it is to be used when there isn't a
|
||||||
|
// type-specific C++ list class to use. In other words the C++ code is using
|
||||||
|
// a plain wxList and typecasting the node values, so we'll do the same.
|
||||||
|
%define wxUNTYPED_LIST_WRAPPER(ListClass, ItemClass)
|
||||||
|
// first a bit of C++ code...
|
||||||
|
%{
|
||||||
|
class ListClass
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ListClass(wxList* theList)
|
||||||
|
: m_list(theList) {}
|
||||||
|
~ListClass() {}
|
||||||
|
public:
|
||||||
|
wxList* m_list;
|
||||||
|
};
|
||||||
|
|
||||||
|
class ListClass##_iterator
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ListClass##_iterator(wxList::compatibility_iterator start)
|
||||||
|
: m_node(start) {}
|
||||||
|
|
||||||
|
ItemClass* next() {
|
||||||
|
ItemClass* obj = NULL;
|
||||||
|
if (m_node) {
|
||||||
|
obj = (ItemClass*)m_node->GetData();
|
||||||
|
m_node = m_node->GetNext();
|
||||||
|
}
|
||||||
|
else PyErr_SetString(PyExc_StopIteration, "");
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
wxList::compatibility_iterator m_node;
|
||||||
|
};
|
||||||
|
%}
|
||||||
|
|
||||||
|
// Now declare the classes for SWIG
|
||||||
|
|
||||||
|
DocStr(ListClass##_iterator,
|
||||||
|
"This class serves as an iterator for a ListClass object.", "");
|
||||||
|
|
||||||
|
class ListClass##_iterator
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
//ListClass##_iterator();
|
||||||
|
~ListClass_iterator();
|
||||||
|
KeepGIL(next);
|
||||||
|
ItemClass* next();
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
DocStr(ListClass,
|
||||||
|
"This class wraps a wxList-based class and gives it a Python
|
||||||
|
sequence-like interface. Sequence operations supported are length,
|
||||||
|
index access and iteration.", "");
|
||||||
|
class ListClass
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
//ListClass(); This will always be created by some C++ function
|
||||||
|
~ListClass();
|
||||||
|
|
||||||
|
%extend {
|
||||||
|
KeepGIL(__len__);
|
||||||
|
size_t __len__() {
|
||||||
|
return self->m_list->size();
|
||||||
|
}
|
||||||
|
|
||||||
|
KeepGIL(__getitem__);
|
||||||
|
ItemClass* __getitem__(size_t index) {
|
||||||
|
if (index < self->m_list->size()) {
|
||||||
|
wxList::compatibility_iterator node = self->m_list->Item(index);
|
||||||
|
if (node) return (ItemClass*)node->GetData();
|
||||||
|
}
|
||||||
|
PyErr_SetString(PyExc_IndexError, "Invalid list index");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
KeepGIL(__contains__);
|
||||||
|
bool __contains__(const ItemClass* obj) {
|
||||||
|
return self->m_list->Find(obj) != NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
KeepGIL(__iter__);
|
||||||
|
%newobject __iter__;
|
||||||
|
ListClass##_iterator* __iter__() {
|
||||||
|
return new ListClass##_iterator(self->m_list->GetFirst());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
%pythoncode {
|
||||||
|
def __repr__(self):
|
||||||
|
return "ListClass: " + repr(list(self))
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// A typemap to handle converting a wxList& return value to this new list
|
||||||
|
// type. To use this just change the return value type in the class
|
||||||
|
// definition to this typedef instead of wxList, then SWIG will use the
|
||||||
|
// typemap.
|
||||||
|
%{
|
||||||
|
typedef wxList ListClass##_t;
|
||||||
|
%}
|
||||||
|
%typemap(out) ListClass##_t& {
|
||||||
|
ListClass* mylist = new ListClass($1);
|
||||||
|
$result = SWIG_NewPointerObj(SWIG_as_voidptr(mylist), SWIGTYPE_p_##ListClass, SWIG_POINTER_OWN );
|
||||||
|
}
|
||||||
|
%enddef
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
%{
|
%{
|
||||||
|
@@ -280,6 +280,26 @@ public:
|
|||||||
// Add a file to the memory FS
|
// Add a file to the memory FS
|
||||||
%pythoncode { AddFile = staticmethod(MemoryFSHandler_AddFile) }
|
%pythoncode { AddFile = staticmethod(MemoryFSHandler_AddFile) }
|
||||||
|
|
||||||
|
%extend {
|
||||||
|
static void AddFileWithMimeType(const wxString& filename,
|
||||||
|
PyObject* data,
|
||||||
|
const wxString& mimetype)
|
||||||
|
{
|
||||||
|
if (! PyString_Check(data)) {
|
||||||
|
wxPyBLOCK_THREADS(PyErr_SetString(PyExc_TypeError,
|
||||||
|
"Expected string object"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
wxPyBlock_t blocked = wxPyBeginBlockThreads();
|
||||||
|
void* ptr = (void*)PyString_AsString(data);
|
||||||
|
size_t size = PyString_Size(data);
|
||||||
|
wxPyEndBlockThreads(blocked);
|
||||||
|
|
||||||
|
wxMemoryFSHandler::AddFileWithMimeType(filename, ptr, size, mimetype);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool CanOpen(const wxString& location);
|
bool CanOpen(const wxString& location);
|
||||||
%newobject OpenFile;
|
%newobject OpenFile;
|
||||||
wxFSFile* OpenFile(wxFileSystem& fs, const wxString& location);
|
wxFSFile* OpenFile(wxFileSystem& fs, const wxString& location);
|
||||||
|
@@ -451,7 +451,7 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
MustHaveApp(wxThread);
|
MustHaveApp(wxThread_IsMain);
|
||||||
%inline %{
|
%inline %{
|
||||||
bool wxThread_IsMain() {
|
bool wxThread_IsMain() {
|
||||||
#ifdef WXP_WITH_THREAD
|
#ifdef WXP_WITH_THREAD
|
||||||
|
@@ -488,6 +488,9 @@ DocStr(wxRect,
|
|||||||
width and height properties. In wxPython most palces that expect a
|
width and height properties. In wxPython most palces that expect a
|
||||||
wx.Rect can also accept a (x,y,width,height) tuple.", "");
|
wx.Rect can also accept a (x,y,width,height) tuple.", "");
|
||||||
|
|
||||||
|
|
||||||
|
%typemap(in) wxRect*;
|
||||||
|
|
||||||
class wxRect
|
class wxRect
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -777,6 +780,9 @@ usually, but not necessarily, the larger one.", "");
|
|||||||
%property(Empty, IsEmpty, doc="See `IsEmpty`");
|
%property(Empty, IsEmpty, doc="See `IsEmpty`");
|
||||||
};
|
};
|
||||||
|
|
||||||
|
%apply wxRect& { wxRect* };
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
MustHaveApp(wxIntersectRect);
|
MustHaveApp(wxIntersectRect);
|
||||||
|
|
||||||
|
@@ -350,9 +350,6 @@ MustHaveApp(wxGraphicsPath);
|
|||||||
MustHaveApp(wxGraphicsContext);
|
MustHaveApp(wxGraphicsContext);
|
||||||
MustHaveApp(wxGCDC);
|
MustHaveApp(wxGCDC);
|
||||||
|
|
||||||
typedef double wxDouble;
|
|
||||||
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
@@ -643,6 +643,17 @@ string.", "",
|
|||||||
"Saves an image in the named file.", "",
|
"Saves an image in the named file.", "",
|
||||||
SaveMimeFile);
|
SaveMimeFile);
|
||||||
|
|
||||||
|
DocDeclStrName(
|
||||||
|
bool , SaveFile( wxOutputStream& stream, int type ),
|
||||||
|
"Saves an image in the named file.", "",
|
||||||
|
SaveStream);
|
||||||
|
|
||||||
|
|
||||||
|
DocDeclStrName(
|
||||||
|
bool , SaveFile( wxOutputStream& stream, const wxString& mimetype ),
|
||||||
|
"Saves an image in the named file.", "",
|
||||||
|
SaveMimeStream);
|
||||||
|
|
||||||
|
|
||||||
DocDeclStrName(
|
DocDeclStrName(
|
||||||
static bool , CanRead( wxInputStream& stream ),
|
static bool , CanRead( wxInputStream& stream ),
|
||||||
|
@@ -214,6 +214,7 @@ public:
|
|||||||
void PassMessages(bool bDoPass);
|
void PassMessages(bool bDoPass);
|
||||||
bool IsPassingMessages();
|
bool IsPassingMessages();
|
||||||
wxLog *GetOldLog();
|
wxLog *GetOldLog();
|
||||||
|
void DetachOldLog();
|
||||||
|
|
||||||
%property(OldLog, GetOldLog, doc="See `GetOldLog`");
|
%property(OldLog, GetOldLog, doc="See `GetOldLog`");
|
||||||
};
|
};
|
||||||
|
@@ -16,6 +16,9 @@
|
|||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
%newgroup
|
%newgroup
|
||||||
|
|
||||||
|
wxLIST_WRAPPER(wxMenuItemList, wxMenuItem);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
MustHaveApp(wxMenu);
|
MustHaveApp(wxMenu);
|
||||||
|
|
||||||
@@ -169,12 +172,7 @@ public:
|
|||||||
|
|
||||||
// get the items
|
// get the items
|
||||||
size_t GetMenuItemCount() const;
|
size_t GetMenuItemCount() const;
|
||||||
%extend {
|
wxMenuItemList& GetMenuItems();
|
||||||
PyObject* GetMenuItems() {
|
|
||||||
wxMenuItemList& list = self->GetMenuItems();
|
|
||||||
return wxPy_ConvertList(&list);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// search
|
// search
|
||||||
int FindItem(const wxString& item) const;
|
int FindItem(const wxString& item) const;
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
/////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
// Name: _window.i
|
// Name: _panel.i
|
||||||
// Purpose: SWIG interface for wxPanel and wxScrolledWindow
|
// Purpose: SWIG interface for wxPanel and wxScrolledWindow
|
||||||
//
|
//
|
||||||
// Author: Robin Dunn
|
// Author: Robin Dunn
|
||||||
|
1968
wxPython/src/_richtextbuffer.i
Normal file
1968
wxPython/src/_richtextbuffer.i
Normal file
File diff suppressed because it is too large
Load Diff
1237
wxPython/src/_richtextctrl.i
Normal file
1237
wxPython/src/_richtextctrl.i
Normal file
File diff suppressed because it is too large
Load Diff
102
wxPython/src/_richtexthtml.i
Normal file
102
wxPython/src/_richtexthtml.i
Normal file
@@ -0,0 +1,102 @@
|
|||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Name: _richtexthtml
|
||||||
|
// Purpose: wxRichTextHTMLHandler
|
||||||
|
//
|
||||||
|
// Author: Robin Dunn
|
||||||
|
//
|
||||||
|
// Created: 18-May-2007
|
||||||
|
// RCS-ID: $Id$
|
||||||
|
// Copyright: (c) 2007 by Total Control Software
|
||||||
|
// Licence: wxWindows license
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// Not a %module
|
||||||
|
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
%{
|
||||||
|
#include <wx/richtext/richtexthtml.h>
|
||||||
|
%}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
%newgroup
|
||||||
|
|
||||||
|
MAKE_CONST_WXSTRING2(HtmlName, wxT("HTML"));
|
||||||
|
MAKE_CONST_WXSTRING2(HtmlExt, wxT("html"));
|
||||||
|
|
||||||
|
class wxRichTextHTMLHandler: public wxRichTextFileHandler
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
wxRichTextHTMLHandler(const wxString& name = wxPyHtmlName,
|
||||||
|
const wxString& ext = wxPyHtmlExt,
|
||||||
|
int type = wxRICHTEXT_TYPE_HTML);
|
||||||
|
|
||||||
|
DocDeclStr(
|
||||||
|
virtual bool , CanSave() const,
|
||||||
|
"Can we save using this handler?", "");
|
||||||
|
DocDeclStr(
|
||||||
|
virtual bool , CanLoad() const,
|
||||||
|
"Can we load using this handler?", "");
|
||||||
|
DocDeclStr(
|
||||||
|
virtual bool , CanHandle(const wxString& filename) const,
|
||||||
|
"Can we handle this filename (if using files)? By default, checks the
|
||||||
|
extension.", "");
|
||||||
|
|
||||||
|
|
||||||
|
DocDeclStr(
|
||||||
|
void , SetTemporaryImageLocations(const wxArrayString& locations),
|
||||||
|
"Set the list of image locations generated by the last operation", "");
|
||||||
|
DocDeclStr(
|
||||||
|
const wxArrayString& , GetTemporaryImageLocations() const,
|
||||||
|
"Get the list of image locations generated by the last operation", "");
|
||||||
|
%property(TemporaryImageLocations, GetTemporaryImageLocations, SetTemporaryImageLocations);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
DocDeclStr(
|
||||||
|
void , ClearTemporaryImageLocations(),
|
||||||
|
"Clear the image locations generated by the last operation", "");
|
||||||
|
DocDeclStr(
|
||||||
|
bool , DeleteTemporaryImages(),
|
||||||
|
"Delete the in-memory or temporary files generated by the last operation", "");
|
||||||
|
|
||||||
|
|
||||||
|
// DocDeclStr(
|
||||||
|
// static bool , DeleteTemporaryImages(int flags, const wxArrayString& imageLocations),
|
||||||
|
// "Delete the in-memory or temporary files generated by the last operation. This
|
||||||
|
// is a static function that can be used to delete the saved locations from an
|
||||||
|
// earlier operation, for example after the user has viewed the HTML file.", "");
|
||||||
|
|
||||||
|
|
||||||
|
DocDeclStr(
|
||||||
|
static void , SetFileCounter(int counter),
|
||||||
|
"Reset the file counter, in case, for example, the same names are required each
|
||||||
|
time", "");
|
||||||
|
|
||||||
|
|
||||||
|
DocDeclStr(
|
||||||
|
void , SetTempDir(const wxString& tempDir),
|
||||||
|
"Set the directory for storing temporary files. If empty, the system temporary
|
||||||
|
directory will be used.", "");
|
||||||
|
DocDeclStr(
|
||||||
|
const wxString& , GetTempDir() const,
|
||||||
|
"Get the directory for storing temporary files. If empty, the system temporary
|
||||||
|
directory will be used.", "");
|
||||||
|
%property(TempDir, GetTempDir, SetTempDir);
|
||||||
|
|
||||||
|
|
||||||
|
DocDeclStr(
|
||||||
|
void , SetFontSizeMapping(const wxArrayInt& fontSizeMapping),
|
||||||
|
"Set mapping from point size to HTML font size. There should be 7 elements, one
|
||||||
|
for each HTML font size, each element specifying the maximum point size for
|
||||||
|
that HTML font size. E.g. 8, 10, 13, 17, 22, 29, 100
|
||||||
|
", "");
|
||||||
|
DocDeclStr(
|
||||||
|
wxArrayInt , GetFontSizeMapping() const,
|
||||||
|
"Get mapping deom point size to HTML font size.", "");
|
||||||
|
%property(FontSizeMapping, GetFontSizeMapping, SetFontSizeMapping);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------
|
67
wxPython/src/_richtextxml.i
Normal file
67
wxPython/src/_richtextxml.i
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Name: _richtextxml
|
||||||
|
// Purpose: wxRichTextXMLHandler
|
||||||
|
//
|
||||||
|
// Author: Robin Dunn
|
||||||
|
//
|
||||||
|
// Created: 18-May-2007
|
||||||
|
// RCS-ID: $Id$
|
||||||
|
// Copyright: (c) 2007 by Total Control Software
|
||||||
|
// Licence: wxWindows license
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// Not a %module
|
||||||
|
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
%{
|
||||||
|
#include <wx/richtext/richtextxml.h>
|
||||||
|
%}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
%newgroup
|
||||||
|
|
||||||
|
MAKE_CONST_WXSTRING2(XmlName, wxT("XML"));
|
||||||
|
MAKE_CONST_WXSTRING2(XmlExt, wxT("xml"));
|
||||||
|
|
||||||
|
|
||||||
|
class wxRichTextXMLHandler: public wxRichTextFileHandler
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
wxRichTextXMLHandler(const wxString& name = wxPyXmlName,
|
||||||
|
const wxString& ext = wxPyXmlExt,
|
||||||
|
int type = wxRICHTEXT_TYPE_XML);
|
||||||
|
|
||||||
|
// #if wxUSE_STREAMS
|
||||||
|
// /// Recursively export an object
|
||||||
|
// bool ExportXML(wxOutputStream& stream, wxMBConv* convMem, wxMBConv* convFile, wxRichTextObject& obj, int level);
|
||||||
|
// bool ExportStyleDefinition(wxOutputStream& stream, wxMBConv* convMem, wxMBConv* convFile, wxRichTextStyleDefinition* def, int level);
|
||||||
|
|
||||||
|
// /// Recursively import an object
|
||||||
|
// bool ImportXML(wxRichTextBuffer* buffer, wxXmlNode* node);
|
||||||
|
// bool ImportStyleDefinition(wxRichTextStyleSheet* sheet, wxXmlNode* node);
|
||||||
|
|
||||||
|
// /// Create style parameters
|
||||||
|
// wxString CreateStyle(const wxTextAttrEx& attr, bool isPara = false);
|
||||||
|
|
||||||
|
// /// Get style parameters
|
||||||
|
// bool GetStyle(wxTextAttrEx& attr, wxXmlNode* node, bool isPara = false);
|
||||||
|
// #endif
|
||||||
|
|
||||||
|
/// Can we save using this handler?
|
||||||
|
virtual bool CanSave() const;
|
||||||
|
|
||||||
|
/// Can we load using this handler?
|
||||||
|
virtual bool CanLoad() const;
|
||||||
|
|
||||||
|
|
||||||
|
// bool HasParam(wxXmlNode* node, const wxString& param);
|
||||||
|
// wxXmlNode *GetParamNode(wxXmlNode* node, const wxString& param);
|
||||||
|
// wxString GetNodeContent(wxXmlNode *node);
|
||||||
|
// wxString GetParamValue(wxXmlNode *node, const wxString& param);
|
||||||
|
// wxString GetText(wxXmlNode *node, const wxString& param = wxEmptyString, bool translate = false);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------
|
@@ -169,6 +169,11 @@ border size.", "");
|
|||||||
};
|
};
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
%newgroup
|
||||||
|
|
||||||
|
wxLIST_WRAPPER( wxSizerItemList, wxSizerItem );
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
DocStr(wxSizerItem,
|
DocStr(wxSizerItem,
|
||||||
"The wx.SizerItem class is used to track the position, size and other
|
"The wx.SizerItem class is used to track the position, size and other
|
||||||
@@ -1247,21 +1252,12 @@ as well.", "");
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
// wxList& GetChildren();
|
DocStr(GetChildren,
|
||||||
%extend {
|
"Returns all of the `wx.SizerItem` objects managed by the sizer in a
|
||||||
DocAStr(GetChildren,
|
list-like object.", "");
|
||||||
"GetChildren(self) -> list",
|
wxSizerItemList& GetChildren();
|
||||||
"Returns a list of all the `wx.SizerItem` objects managed by the sizer.", "");
|
|
||||||
PyObject* GetChildren() {
|
|
||||||
wxSizerItemList& list = self->GetChildren();
|
|
||||||
return wxPy_ConvertList(&list);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Manage whether individual windows or subsizers are considered
|
|
||||||
// in the layout calculations or not.
|
|
||||||
|
|
||||||
%extend {
|
%extend {
|
||||||
DocAStr(Show,
|
DocAStr(Show,
|
||||||
"Show(self, item, bool show=True, bool recursive=false) -> bool",
|
"Show(self, item, bool show=True, bool recursive=false) -> bool",
|
||||||
|
@@ -32,7 +32,7 @@ given for the Unix, Windows and Mac OS X systems, however please note
|
|||||||
that these are just examples and the actual values may differ. For
|
that these are just examples and the actual values may differ. For
|
||||||
example, under Windows the system administrator may change the
|
example, under Windows the system administrator may change the
|
||||||
standard directories locations, i.e. the Windows directory may be
|
standard directories locations, i.e. the Windows directory may be
|
||||||
named W:\Win2003 instead of the default C:\Windows.
|
named W:/Win2003 instead of the default C:/Windows.
|
||||||
|
|
||||||
The strings appname and username should be replaced with the value
|
The strings appname and username should be replaced with the value
|
||||||
returned by `wx.App.GetAppName` and the name of the currently logged
|
returned by `wx.App.GetAppName` and the name of the currently logged
|
||||||
@@ -85,14 +85,14 @@ absolute path whenever possible.", "");
|
|||||||
DocDeclStr(
|
DocDeclStr(
|
||||||
virtual wxString , GetConfigDir() const,
|
virtual wxString , GetConfigDir() const,
|
||||||
"Return the directory with system config files: /etc under Unix,
|
"Return the directory with system config files: /etc under Unix,
|
||||||
'c:\\Documents and Settings\\All Users\\Application Data' under Windows,
|
'c:/Documents and Settings/All Users/Application Data' under Windows,
|
||||||
/Library/Preferences for Mac", "");
|
/Library/Preferences for Mac", "");
|
||||||
|
|
||||||
|
|
||||||
DocDeclStr(
|
DocDeclStr(
|
||||||
virtual wxString , GetUserConfigDir() const,
|
virtual wxString , GetUserConfigDir() const,
|
||||||
"Return the directory for the user config files: $HOME under Unix,
|
"Return the directory for the user config files: $HOME under Unix,
|
||||||
'c:\\Documents and Settings\\username' under Windows, and
|
'c:/Documents and Settings/username' under Windows, and
|
||||||
~/Library/Preferences under Mac
|
~/Library/Preferences under Mac
|
||||||
|
|
||||||
Only use this if you have a single file to put there, otherwise
|
Only use this if you have a single file to put there, otherwise
|
||||||
@@ -103,7 +103,7 @@ Only use this if you have a single file to put there, otherwise
|
|||||||
virtual wxString , GetDataDir() const,
|
virtual wxString , GetDataDir() const,
|
||||||
"Return the location of the application's global, (i.e. not
|
"Return the location of the application's global, (i.e. not
|
||||||
user-specific,) data files: prefix/share/appname under Unix,
|
user-specific,) data files: prefix/share/appname under Unix,
|
||||||
'c:\\Program Files\\appname' under Windows,
|
'c:/Program Files/appname' under Windows,
|
||||||
appname.app/Contents/SharedSupport app bundle directory under Mac.", "");
|
appname.app/Contents/SharedSupport app bundle directory under Mac.", "");
|
||||||
|
|
||||||
|
|
||||||
@@ -117,8 +117,8 @@ host-specific. Same as `GetDataDir` except under Unix where it is
|
|||||||
DocDeclStr(
|
DocDeclStr(
|
||||||
virtual wxString , GetUserDataDir() const,
|
virtual wxString , GetUserDataDir() const,
|
||||||
"Return the directory for the user-dependent application data files:
|
"Return the directory for the user-dependent application data files:
|
||||||
$HOME/.appname under Unix, c:\\Documents and
|
$HOME/.appname under Unix, c:/Documents and
|
||||||
Settings\\username\\Application Data\\appname under Windows and
|
Settings/username/Application Data/appname under Windows and
|
||||||
~/Library/Application Support/appname under Mac", "");
|
~/Library/Application Support/appname under Mac", "");
|
||||||
|
|
||||||
|
|
||||||
@@ -128,7 +128,7 @@ Settings\\username\\Application Data\\appname under Windows and
|
|||||||
with the other machines
|
with the other machines
|
||||||
|
|
||||||
Same as `GetUserDataDir` for all platforms except Windows where it is
|
Same as `GetUserDataDir` for all platforms except Windows where it is
|
||||||
the 'Local Settings\\Application Data\\appname' directory.", "");
|
the 'Local Settings/Application Data/appname' directory.", "");
|
||||||
|
|
||||||
|
|
||||||
DocDeclStr(
|
DocDeclStr(
|
||||||
@@ -168,7 +168,7 @@ standard prefix/share/locale/lang/LC_MESSAGES.)", "");
|
|||||||
virtual wxString , GetDocumentsDir() const,
|
virtual wxString , GetDocumentsDir() const,
|
||||||
"Return the Documents directory for the current user.
|
"Return the Documents directory for the current user.
|
||||||
|
|
||||||
C:\Documents and Settings\username\Documents under Windows,
|
C:/Documents and Settings/username/Documents under Windows,
|
||||||
$HOME under Unix and ~/Documents under Mac", "");
|
$HOME under Unix and ~/Documents under Mac", "");
|
||||||
|
|
||||||
DocDeclStr(
|
DocDeclStr(
|
||||||
|
@@ -61,18 +61,43 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
%typemap(out) wxInputStream* {
|
%typemap(out) wxInputStream* {
|
||||||
wxPyInputStream * _ptr = NULL;
|
wxPyInputStream * _ptr = NULL;
|
||||||
|
if ($1)
|
||||||
if ($1) {
|
|
||||||
_ptr = new wxPyInputStream($1);
|
_ptr = new wxPyInputStream($1);
|
||||||
}
|
|
||||||
$result = wxPyConstructObject(_ptr, wxT("wxPyInputStream"), $owner);
|
$result = wxPyConstructObject(_ptr, wxT("wxPyInputStream"), $owner);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
// Typemaps for wxOutputStream. We only need in by reference and out by
|
||||||
|
// pointer in this one.
|
||||||
|
|
||||||
|
|
||||||
|
%typemap(in) wxOutputStream& (wxPyOutputStream* temp, bool created) {
|
||||||
|
if (wxPyConvertSwigPtr($input, (void **)&temp, wxT("wxPyOutputStream"))) {
|
||||||
|
$1 = temp->m_wxos;
|
||||||
|
created = false;
|
||||||
|
} else {
|
||||||
|
PyErr_Clear(); // clear the failure of the wxPyConvert above
|
||||||
|
$1 = wxPyCBOutputStream_create($input, false);
|
||||||
|
if ($1 == NULL) {
|
||||||
|
PyErr_SetString(PyExc_TypeError, "Expected wx.OutputStream or Python file-like object.");
|
||||||
|
SWIG_fail;
|
||||||
|
}
|
||||||
|
created = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
%typemap(freearg) wxOutputStream& { if (created$argnum) delete $1; }
|
||||||
|
|
||||||
|
|
||||||
|
%typemap(out) wxOutputStream* {
|
||||||
|
wxPyOutputStream * _ptr = NULL;
|
||||||
|
if ($1)
|
||||||
|
_ptr = new wxPyOutputStream($1);
|
||||||
|
$result = wxPyConstructObject(_ptr, wxT("wxPyOutputStream"), $owner);
|
||||||
|
}
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
enum wxSeekMode
|
enum wxSeekMode
|
||||||
@@ -107,14 +132,6 @@ public:
|
|||||||
void seek(int offset, int whence=0);
|
void seek(int offset, int whence=0);
|
||||||
int tell();
|
int tell();
|
||||||
|
|
||||||
/*
|
|
||||||
bool isatty();
|
|
||||||
int fileno();
|
|
||||||
void truncate(int size=-1);
|
|
||||||
void write(wxString data);
|
|
||||||
void writelines(wxStringPtrList);
|
|
||||||
*/
|
|
||||||
|
|
||||||
char Peek();
|
char Peek();
|
||||||
char GetC();
|
char GetC();
|
||||||
size_t LastRead();
|
size_t LastRead();
|
||||||
@@ -128,43 +145,41 @@ public:
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
// TODO: make a more fully implemented file interface...
|
|
||||||
class wxOutputStream {
|
|
||||||
public:
|
|
||||||
/*
|
|
||||||
void close();
|
|
||||||
void flush();
|
|
||||||
wxString* read(int size=-1);
|
|
||||||
wxString* readline(int size=-1);
|
|
||||||
wxStringPtrList* readlines(int sizehint=-1);
|
|
||||||
void seek(int offset, int whence=0);
|
|
||||||
int tell();
|
|
||||||
bool isatty();
|
|
||||||
int fileno();
|
|
||||||
void truncate(int size=-1);
|
|
||||||
void write(wxString data);
|
|
||||||
void writelines(wxStringPtrList);
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
%rename(OutputStream) wxPyOutputStream;
|
||||||
|
class wxPyOutputStream
|
||||||
|
{
|
||||||
|
public:
|
||||||
%extend {
|
%extend {
|
||||||
void write(PyObject* obj) {
|
wxPyOutputStream(PyObject* p) {
|
||||||
// We use only strings for the streams, not unicode
|
wxOutputStream* wxis = wxPyCBOutputStream::create(p);
|
||||||
PyObject* str = PyObject_Str(obj);
|
if (wxis)
|
||||||
if (! str) {
|
return new wxPyOutputStream(wxis);
|
||||||
PyErr_SetString(PyExc_TypeError, "Unable to convert to string");
|
else
|
||||||
return;
|
return NULL;
|
||||||
}
|
|
||||||
self->Write(PyString_AS_STRING(str),
|
|
||||||
PyString_GET_SIZE(str));
|
|
||||||
Py_DECREF(str);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
size_t LastWrite() const;
|
~wxPyOutputStream();
|
||||||
|
|
||||||
|
void close();
|
||||||
|
void flush();
|
||||||
|
bool eof();
|
||||||
|
void seek(int offset, int whence=0);
|
||||||
|
int tell();
|
||||||
|
|
||||||
|
void write(PyObject* data);
|
||||||
|
//void writelines(wxStringArray& arr);
|
||||||
|
|
||||||
|
void PutC(char c);
|
||||||
|
size_t LastWrite();
|
||||||
|
unsigned long SeekO(unsigned long pos, wxSeekMode mode = wxFromStart);
|
||||||
|
unsigned long TellO();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
%init %{
|
%init %{
|
||||||
wxPyPtrTypeMap_Add("wxInputStream", "wxPyInputStream");
|
wxPyPtrTypeMap_Add("wxInputStream", "wxPyInputStream");
|
||||||
|
wxPyPtrTypeMap_Add("wxOutputStream", "wxPyOutputStream");
|
||||||
%}
|
%}
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
@@ -24,6 +24,9 @@ MAKE_CONST_WXSTRING(PanelNameStr);
|
|||||||
%newgroup
|
%newgroup
|
||||||
|
|
||||||
|
|
||||||
|
wxLIST_WRAPPER(wxWindowList, wxWindow);
|
||||||
|
|
||||||
|
|
||||||
DocStr(wxVisualAttributes,
|
DocStr(wxVisualAttributes,
|
||||||
"struct containing all the visual attributes of a control", "");
|
"struct containing all the visual attributes of a control", "");
|
||||||
|
|
||||||
@@ -124,8 +127,13 @@ Styles
|
|||||||
deactivate it.
|
deactivate it.
|
||||||
|
|
||||||
wx.VSCROLL Use this style to enable a vertical scrollbar.
|
wx.VSCROLL Use this style to enable a vertical scrollbar.
|
||||||
|
Notice that this style cannot be used with
|
||||||
|
native controls which don't support scrollbars
|
||||||
|
nor with top-level windows in most ports.
|
||||||
|
|
||||||
wx.HSCROLL Use this style to enable a horizontal scrollbar.
|
wx.HSCROLL Use this style to enable a horizontal scrollbar.
|
||||||
|
The same limitations as for wx.VSCROLL apply to
|
||||||
|
this style.
|
||||||
|
|
||||||
wx.ALWAYS_SHOW_SB If a window has scrollbars, disable them
|
wx.ALWAYS_SHOW_SB If a window has scrollbars, disable them
|
||||||
instead of hiding them when they are
|
instead of hiding them when they are
|
||||||
@@ -990,26 +998,16 @@ before win instead of putting it right after it.", "");
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// parent/children relations
|
// parent/children relations
|
||||||
// -------------------------
|
// -------------------------
|
||||||
|
|
||||||
|
|
||||||
//wxWindowList& GetChildren(); // TODO: Do a typemap or a wrapper for wxWindowList
|
|
||||||
%extend {
|
|
||||||
DocStr(GetChildren,
|
DocStr(GetChildren,
|
||||||
"Returns a list of the window's children. NOTE: Currently this is a
|
"Returns an object containing a list of the window's children. The
|
||||||
copy of the child window list maintained by the window, so the return
|
object provides a Python sequence-like interface over the internal
|
||||||
value of this function is only valid as long as the window's children
|
list maintained by the window..", "");
|
||||||
do not change.", "");
|
wxWindowList& GetChildren();
|
||||||
PyObject* GetChildren() {
|
|
||||||
wxWindowList& list = self->GetChildren();
|
|
||||||
return wxPy_ConvertList(&list);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
DocDeclStr(
|
DocDeclStr(
|
||||||
wxWindow *, GetParent() const,
|
wxWindow *, GetParent() const,
|
||||||
@@ -2318,14 +2316,11 @@ MustHaveApp(wxWindow_FromHWND);
|
|||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
DocStr(GetTopLevelWindows,
|
DocStr(GetTopLevelWindows,
|
||||||
"Returns a list of the the application's top-level windows, (frames,
|
"Returns a list-like object of the the application's top-level windows, (frames,
|
||||||
dialogs, etc.) NOTE: Currently this is a copy of the list maintained
|
dialogs, etc.)", "");
|
||||||
by wxWidgets, and so it is only valid as long as no top-level windows
|
|
||||||
are closed or new top-level windows are created.
|
|
||||||
", "");
|
|
||||||
%inline %{
|
%inline %{
|
||||||
PyObject* GetTopLevelWindows() {
|
wxWindowList& GetTopLevelWindows() {
|
||||||
return wxPy_ConvertList(&wxTopLevelWindows);
|
return wxTopLevelWindows;
|
||||||
}
|
}
|
||||||
%}
|
%}
|
||||||
|
|
||||||
|
@@ -11,7 +11,7 @@
|
|||||||
/////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
%define DOCSTRING
|
%define DOCSTRING
|
||||||
"The wx.aui moduleis an Advanced User Interface library that aims to
|
"The wx.aui module is an Advanced User Interface library that aims to
|
||||||
implement \"cutting-edge\" interface usability and design features so
|
implement \"cutting-edge\" interface usability and design features so
|
||||||
developers can quickly and easily create beautiful and usable
|
developers can quickly and easily create beautiful and usable
|
||||||
application interfaces.
|
application interfaces.
|
||||||
|
@@ -712,6 +712,7 @@ Nearly all of the methods of this class are overridable in Python.", "");
|
|||||||
|
|
||||||
MustHaveApp(wxPyComboPopup);
|
MustHaveApp(wxPyComboPopup);
|
||||||
%rename(ComboPopup) wxPyComboPopup;
|
%rename(ComboPopup) wxPyComboPopup;
|
||||||
|
%typemap(out) wxPyComboCtrl* { $result = wxPyMake_wxObject($1, (bool)$owner); }
|
||||||
|
|
||||||
class wxPyComboPopup
|
class wxPyComboPopup
|
||||||
{
|
{
|
||||||
@@ -851,7 +852,6 @@ is associated with.", "");
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
%newgroup
|
%newgroup
|
||||||
|
|
||||||
|
@@ -1090,6 +1090,21 @@ void wxPyEndBlockThreads(wxPyBlock_t blocked) {
|
|||||||
// wxPyInputStream and wxPyCBInputStream methods
|
// wxPyInputStream and wxPyCBInputStream methods
|
||||||
|
|
||||||
|
|
||||||
|
static PyObject* wxPyGetMethod(PyObject* py, char* name)
|
||||||
|
{
|
||||||
|
if (!PyObject_HasAttrString(py, name))
|
||||||
|
return NULL;
|
||||||
|
PyObject* o = PyObject_GetAttrString(py, name);
|
||||||
|
if (!PyMethod_Check(o) && !PyCFunction_Check(o)) {
|
||||||
|
Py_DECREF(o);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
return o;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void wxPyInputStream::close() {
|
void wxPyInputStream::close() {
|
||||||
/* do nothing for now */
|
/* do nothing for now */
|
||||||
}
|
}
|
||||||
@@ -1246,7 +1261,7 @@ void wxPyInputStream::seek(int offset, int whence) {
|
|||||||
m_wxis->SeekI(offset, wxSeekMode(whence));
|
m_wxis->SeekI(offset, wxSeekMode(whence));
|
||||||
}
|
}
|
||||||
|
|
||||||
int wxPyInputStream::tell(){
|
int wxPyInputStream::tell() {
|
||||||
if (m_wxis)
|
if (m_wxis)
|
||||||
return m_wxis->TellI();
|
return m_wxis->TellI();
|
||||||
else return 0;
|
else return 0;
|
||||||
@@ -1285,9 +1300,9 @@ wxPyCBInputStream* wxPyCBInputStream::create(PyObject *py, bool block) {
|
|||||||
wxPyBlock_t blocked = wxPyBlock_t_default;
|
wxPyBlock_t blocked = wxPyBlock_t_default;
|
||||||
if (block) blocked = wxPyBeginBlockThreads();
|
if (block) blocked = wxPyBeginBlockThreads();
|
||||||
|
|
||||||
PyObject* read = getMethod(py, "read");
|
PyObject* read = wxPyGetMethod(py, "read");
|
||||||
PyObject* seek = getMethod(py, "seek");
|
PyObject* seek = wxPyGetMethod(py, "seek");
|
||||||
PyObject* tell = getMethod(py, "tell");
|
PyObject* tell = wxPyGetMethod(py, "tell");
|
||||||
|
|
||||||
if (!read) {
|
if (!read) {
|
||||||
PyErr_SetString(PyExc_TypeError, "Not a file-like object");
|
PyErr_SetString(PyExc_TypeError, "Not a file-like object");
|
||||||
@@ -1311,17 +1326,6 @@ wxPyCBInputStream* wxPyCBInputStream_copy(wxPyCBInputStream* other) {
|
|||||||
return new wxPyCBInputStream(*other);
|
return new wxPyCBInputStream(*other);
|
||||||
}
|
}
|
||||||
|
|
||||||
PyObject* wxPyCBInputStream::getMethod(PyObject* py, char* name) {
|
|
||||||
if (!PyObject_HasAttrString(py, name))
|
|
||||||
return NULL;
|
|
||||||
PyObject* o = PyObject_GetAttrString(py, name);
|
|
||||||
if (!PyMethod_Check(o) && !PyCFunction_Check(o)) {
|
|
||||||
Py_DECREF(o);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
return o;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
wxFileOffset wxPyCBInputStream::GetLength() const {
|
wxFileOffset wxPyCBInputStream::GetLength() const {
|
||||||
wxPyCBInputStream* self = (wxPyCBInputStream*)this; // cast off const
|
wxPyCBInputStream* self = (wxPyCBInputStream*)this; // cast off const
|
||||||
@@ -1406,6 +1410,196 @@ wxFileOffset wxPyCBInputStream::OnSysTell() const {
|
|||||||
return o;
|
return o;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------
|
||||||
|
// Output stream
|
||||||
|
|
||||||
|
wxPyOutputStream::~wxPyOutputStream()
|
||||||
|
{
|
||||||
|
if (m_wxos)
|
||||||
|
delete m_wxos;
|
||||||
|
}
|
||||||
|
|
||||||
|
void wxPyOutputStream::close()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void wxPyOutputStream::flush()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
bool wxPyOutputStream::eof()
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void wxPyOutputStream::seek(int offset, int whence)
|
||||||
|
{
|
||||||
|
if (m_wxos)
|
||||||
|
m_wxos->SeekO(offset, wxSeekMode(whence));
|
||||||
|
}
|
||||||
|
|
||||||
|
int wxPyOutputStream::tell()
|
||||||
|
{
|
||||||
|
if (m_wxos)
|
||||||
|
return m_wxos->TellO();
|
||||||
|
else return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void wxPyOutputStream::write(PyObject* data)
|
||||||
|
{
|
||||||
|
if (!m_wxos)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// We use only strings for the streams, not unicode
|
||||||
|
PyObject* str = PyObject_Str(data);
|
||||||
|
if (! str) {
|
||||||
|
PyErr_SetString(PyExc_TypeError, "Unable to convert to string");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
m_wxos->Write(PyString_AS_STRING(str), PyString_GET_SIZE(str));
|
||||||
|
Py_DECREF(str);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
wxPyCBOutputStream::wxPyCBOutputStream(PyObject *w, PyObject *s, PyObject *t, bool block)
|
||||||
|
: wxOutputStream(), m_write(w), m_seek(s), m_tell(t), m_block(block)
|
||||||
|
{}
|
||||||
|
|
||||||
|
wxPyCBOutputStream::wxPyCBOutputStream(const wxPyCBOutputStream& other)
|
||||||
|
{
|
||||||
|
m_write = other.m_write;
|
||||||
|
m_seek = other.m_seek;
|
||||||
|
m_tell = other.m_tell;
|
||||||
|
m_block = other.m_block;
|
||||||
|
Py_INCREF(m_write);
|
||||||
|
Py_INCREF(m_seek);
|
||||||
|
Py_INCREF(m_tell);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
wxPyCBOutputStream::~wxPyCBOutputStream() {
|
||||||
|
wxPyBlock_t blocked = wxPyBlock_t_default;
|
||||||
|
if (m_block) blocked = wxPyBeginBlockThreads();
|
||||||
|
Py_XDECREF(m_write);
|
||||||
|
Py_XDECREF(m_seek);
|
||||||
|
Py_XDECREF(m_tell);
|
||||||
|
if (m_block) wxPyEndBlockThreads(blocked);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
wxPyCBOutputStream* wxPyCBOutputStream::create(PyObject *py, bool block) {
|
||||||
|
wxPyBlock_t blocked = wxPyBlock_t_default;
|
||||||
|
if (block) blocked = wxPyBeginBlockThreads();
|
||||||
|
|
||||||
|
PyObject* write = wxPyGetMethod(py, "write");
|
||||||
|
PyObject* seek = wxPyGetMethod(py, "seek");
|
||||||
|
PyObject* tell = wxPyGetMethod(py, "tell");
|
||||||
|
|
||||||
|
if (!write) {
|
||||||
|
PyErr_SetString(PyExc_TypeError, "Not a file-like object");
|
||||||
|
Py_XDECREF(write);
|
||||||
|
Py_XDECREF(seek);
|
||||||
|
Py_XDECREF(tell);
|
||||||
|
if (block) wxPyEndBlockThreads(blocked);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (block) wxPyEndBlockThreads(blocked);
|
||||||
|
return new wxPyCBOutputStream(write, seek, tell, block);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
wxPyCBOutputStream* wxPyCBOutputStream_create(PyObject *py, bool block) {
|
||||||
|
return wxPyCBOutputStream::create(py, block);
|
||||||
|
}
|
||||||
|
|
||||||
|
wxPyCBOutputStream* wxPyCBOutputStream_copy(wxPyCBOutputStream* other) {
|
||||||
|
return new wxPyCBOutputStream(*other);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
wxFileOffset wxPyCBOutputStream::GetLength() const {
|
||||||
|
wxPyCBOutputStream* self = (wxPyCBOutputStream*)this; // cast off const
|
||||||
|
if (m_seek && m_tell) {
|
||||||
|
wxFileOffset temp = self->OnSysTell();
|
||||||
|
wxFileOffset ret = self->OnSysSeek(0, wxFromEnd);
|
||||||
|
self->OnSysSeek(temp, wxFromStart);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return wxInvalidOffset;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
size_t wxPyCBOutputStream::OnSysRead(void *buffer, size_t bufsize) {
|
||||||
|
m_lasterror = wxSTREAM_READ_ERROR;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t wxPyCBOutputStream::OnSysWrite(const void *buffer, size_t bufsize) {
|
||||||
|
if (bufsize == 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
wxPyBlock_t blocked = wxPyBeginBlockThreads();
|
||||||
|
PyObject* arglist = PyTuple_New(1);
|
||||||
|
PyTuple_SET_ITEM(arglist, 0, PyString_FromStringAndSize((char*)buffer, bufsize));
|
||||||
|
|
||||||
|
PyObject* result = PyEval_CallObject(m_write, arglist);
|
||||||
|
Py_DECREF(arglist);
|
||||||
|
|
||||||
|
if (result != NULL)
|
||||||
|
Py_DECREF(result);
|
||||||
|
else
|
||||||
|
m_lasterror = wxSTREAM_WRITE_ERROR;
|
||||||
|
wxPyEndBlockThreads(blocked);
|
||||||
|
return bufsize;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
wxFileOffset wxPyCBOutputStream::OnSysSeek(wxFileOffset off, wxSeekMode mode) {
|
||||||
|
wxPyBlock_t blocked = wxPyBeginBlockThreads();
|
||||||
|
PyObject* arglist = PyTuple_New(2);
|
||||||
|
|
||||||
|
if (sizeof(wxFileOffset) > sizeof(long))
|
||||||
|
// wxFileOffset is a 64-bit value...
|
||||||
|
PyTuple_SET_ITEM(arglist, 0, PyLong_FromLongLong(off));
|
||||||
|
else
|
||||||
|
PyTuple_SET_ITEM(arglist, 0, PyInt_FromLong(off));
|
||||||
|
|
||||||
|
PyTuple_SET_ITEM(arglist, 1, PyInt_FromLong(mode));
|
||||||
|
|
||||||
|
|
||||||
|
PyObject* result = PyEval_CallObject(m_seek, arglist);
|
||||||
|
Py_DECREF(arglist);
|
||||||
|
Py_XDECREF(result);
|
||||||
|
wxPyEndBlockThreads(blocked);
|
||||||
|
return OnSysTell();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
wxFileOffset wxPyCBOutputStream::OnSysTell() const {
|
||||||
|
wxPyBlock_t blocked = wxPyBeginBlockThreads();
|
||||||
|
PyObject* arglist = Py_BuildValue("()");
|
||||||
|
PyObject* result = PyEval_CallObject(m_tell, arglist);
|
||||||
|
Py_DECREF(arglist);
|
||||||
|
wxFileOffset o = 0;
|
||||||
|
if (result != NULL) {
|
||||||
|
if (PyLong_Check(result))
|
||||||
|
o = PyLong_AsLongLong(result);
|
||||||
|
else
|
||||||
|
o = PyInt_AsLong(result);
|
||||||
|
Py_DECREF(result);
|
||||||
|
};
|
||||||
|
wxPyEndBlockThreads(blocked);
|
||||||
|
return o;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------
|
//----------------------------------------------------------------------
|
||||||
|
|
||||||
IMPLEMENT_ABSTRACT_CLASS(wxPyCallback, wxObject);
|
IMPLEMENT_ABSTRACT_CLASS(wxPyCallback, wxObject);
|
||||||
|
@@ -173,6 +173,10 @@ MAKE_INT_ARRAY_TYPEMAPS(styles, styles_field)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
%apply wxRect& { wxRect* };
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
%typemap(in) wxPoint2D& (wxPoint2D temp) {
|
%typemap(in) wxPoint2D& (wxPoint2D temp) {
|
||||||
$1 = &temp;
|
$1 = &temp;
|
||||||
if ( ! wxPoint2D_helper($input, &$1)) SWIG_fail;
|
if ( ! wxPoint2D_helper($input, &$1)) SWIG_fail;
|
||||||
|
File diff suppressed because it is too large
Load Diff
@@ -974,7 +974,10 @@ class ButtonInfo(Control):
|
|||||||
self._shortHelp = shortHelp
|
self._shortHelp = shortHelp
|
||||||
self._longHelp = longHelp
|
self._longHelp = longHelp
|
||||||
|
|
||||||
disabledbmp = GrayOut(bmp)
|
if bmp:
|
||||||
|
disabledbmp = GrayOut(bmp)
|
||||||
|
else:
|
||||||
|
disabledbmp = wx.NullBitmap
|
||||||
|
|
||||||
self._bitmaps = {"Normal": bmp, "Toggled": None, "Disabled": disabledbmp,
|
self._bitmaps = {"Normal": bmp, "Toggled": None, "Disabled": disabledbmp,
|
||||||
"Hover": None, "Pressed": None}
|
"Hover": None, "Pressed": None}
|
||||||
|
@@ -140,10 +140,10 @@ class ColourSelect(wx.BitmapButton):
|
|||||||
|
|
||||||
def SetBitmap(self, bmp):
|
def SetBitmap(self, bmp):
|
||||||
self.SetBitmapLabel(bmp)
|
self.SetBitmapLabel(bmp)
|
||||||
self.SetBitmapSelected(bmp)
|
#self.SetBitmapSelected(bmp)
|
||||||
self.SetBitmapDisabled(bmp)
|
#self.SetBitmapDisabled(bmp)
|
||||||
self.SetBitmapFocus(bmp)
|
#self.SetBitmapFocus(bmp)
|
||||||
self.SetBitmapSelected(bmp)
|
#self.SetBitmapSelected(bmp)
|
||||||
self.Refresh()
|
self.Refresh()
|
||||||
|
|
||||||
|
|
||||||
|
@@ -1459,7 +1459,7 @@ class FNBRenderer:
|
|||||||
|
|
||||||
# erase old bitmap
|
# erase old bitmap
|
||||||
posx = self.GetDropArrowButtonPos(pc)
|
posx = self.GetDropArrowButtonPos(pc)
|
||||||
dc.DrawBitmap(self._xBgBmp, posx, 6)
|
dc.DrawBitmap(self._rightBgBmp, posx, 6)
|
||||||
|
|
||||||
# Draw the new bitmap
|
# Draw the new bitmap
|
||||||
dc.DrawBitmap(downBmp, posx, 6, True)
|
dc.DrawBitmap(downBmp, posx, 6, True)
|
||||||
@@ -3353,6 +3353,7 @@ class FlatNotebook(wx.Panel):
|
|||||||
|
|
||||||
self._pages.DoDeletePage(page)
|
self._pages.DoDeletePage(page)
|
||||||
self.Refresh()
|
self.Refresh()
|
||||||
|
self.Update()
|
||||||
|
|
||||||
# Fire a closed event
|
# Fire a closed event
|
||||||
closedEvent = FlatNotebookEvent(wxEVT_FLATNOTEBOOK_PAGE_CLOSED, self.GetId())
|
closedEvent = FlatNotebookEvent(wxEVT_FLATNOTEBOOK_PAGE_CLOSED, self.GetId())
|
||||||
@@ -4733,12 +4734,13 @@ class PageContainer(wx.Panel):
|
|||||||
|
|
||||||
for i in xrange(len(self._pagesInfoVec)):
|
for i in xrange(len(self._pagesInfoVec)):
|
||||||
pi = self._pagesInfoVec[i]
|
pi = self._pagesInfoVec[i]
|
||||||
item = wx.MenuItem(popupMenu, i, pi.GetCaption(), pi.GetCaption(), wx.ITEM_NORMAL)
|
item = wx.MenuItem(popupMenu, i+1, pi.GetCaption(), pi.GetCaption(), wx.ITEM_NORMAL)
|
||||||
self.Bind(wx.EVT_MENU, self.OnTabMenuSelection, item)
|
self.Bind(wx.EVT_MENU, self.OnTabMenuSelection, item)
|
||||||
|
|
||||||
# This code is commented, since there is an alignment problem with wx2.6.3 & Menus
|
# There is an alignment problem with wx2.6.3 & Menus so only use
|
||||||
# if self.TabHasImage(ii):
|
# images for versions above 2.6.3
|
||||||
# item.SetBitmaps( (*m_ImageList)[pi.GetImageIndex()] );
|
if wx.VERSION > (2, 6, 3, 0) and self.TabHasImage(i):
|
||||||
|
item.SetBitmap(self.GetImageList().GetBitmap(pi.GetImageIndex()))
|
||||||
|
|
||||||
popupMenu.AppendItem(item)
|
popupMenu.AppendItem(item)
|
||||||
item.Enable(pi.GetEnabled())
|
item.Enable(pi.GetEnabled())
|
||||||
@@ -4749,7 +4751,7 @@ class PageContainer(wx.Panel):
|
|||||||
def OnTabMenuSelection(self, event):
|
def OnTabMenuSelection(self, event):
|
||||||
""" Handles the wx.EVT_MENU event for L{PageContainer}. """
|
""" Handles the wx.EVT_MENU event for L{PageContainer}. """
|
||||||
|
|
||||||
selection = event.GetId()
|
selection = event.GetId() - 1
|
||||||
self.FireEvent(selection)
|
self.FireEvent(selection)
|
||||||
|
|
||||||
|
|
||||||
|
@@ -2,17 +2,27 @@
|
|||||||
# Name: BrowseImage.py
|
# Name: BrowseImage.py
|
||||||
# Purpose: Display and Select Image Files
|
# Purpose: Display and Select Image Files
|
||||||
#
|
#
|
||||||
# Author: Lorne White
|
# Original Author: Lorne White
|
||||||
#
|
#
|
||||||
# Version: 1.0
|
# Version: 2.0
|
||||||
# Date: January 29, 2002
|
# Date: June 16, 2007
|
||||||
# Licence: wxWindows license
|
# Licence: wxWindows license
|
||||||
#----------------------------------------------------------------------------
|
#----------------------------------------------------------------------------
|
||||||
# 1.0 Release
|
# 2.0 Release - Bill Baxter (wbaxter@gmail.com)
|
||||||
# Create list of all available image file types
|
# Date: June 16, 2007
|
||||||
# View "All Image" File Types as default filter
|
# o Changed to use sizers instead of fixed placement.
|
||||||
# Sort the file list
|
# o Made dialog resizeable
|
||||||
# Use newer "re" function for patterns
|
# o Added a splitter between file list and view pane
|
||||||
|
# o Made directory path editable
|
||||||
|
# o Added an "up" button" to go to the parent dir
|
||||||
|
# o Changed to show directories in file list
|
||||||
|
# o Don't select images on double click any more
|
||||||
|
# o Added a 'broken image' display for files that wx fails to identify
|
||||||
|
# o Redesigned appearance -- using bitmap buttons now, and rearranged things
|
||||||
|
# o Fixed display of masked gifs
|
||||||
|
# o Fixed zooming logic to show shrunken images at correct aspect ratio
|
||||||
|
# o Added different background modes for preview (white/grey/dark/checkered)
|
||||||
|
# o Added framing modes for preview (no frame/box frame/tinted border)
|
||||||
#
|
#
|
||||||
#----------------------------------------------------------------------------
|
#----------------------------------------------------------------------------
|
||||||
#
|
#
|
||||||
@@ -22,18 +32,32 @@
|
|||||||
# o Corrected a nasty bug or two - see comments below.
|
# o Corrected a nasty bug or two - see comments below.
|
||||||
# o There was a duplicate ImageView.DrawImage() method. Que?
|
# o There was a duplicate ImageView.DrawImage() method. Que?
|
||||||
#
|
#
|
||||||
|
#----------------------------------------------------------------------------
|
||||||
|
# 1.0 Release - Lorne White
|
||||||
|
# Date: January 29, 2002
|
||||||
|
# Create list of all available image file types
|
||||||
|
# View "All Image" File Types as default filter
|
||||||
|
# Sort the file list
|
||||||
|
# Use newer "re" function for patterns
|
||||||
|
#
|
||||||
|
|
||||||
#---------------------------------------------------------------------------
|
#---------------------------------------------------------------------------
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
import wx
|
import wx
|
||||||
|
|
||||||
dir_path = os.getcwd()
|
|
||||||
|
|
||||||
#---------------------------------------------------------------------------
|
#---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
BAD_IMAGE = -1
|
||||||
|
ID_WHITE_BG = wx.NewId()
|
||||||
|
ID_BLACK_BG = wx.NewId()
|
||||||
|
ID_GREY_BG = wx.NewId()
|
||||||
|
ID_CHECK_BG = wx.NewId()
|
||||||
|
ID_NO_FRAME = wx.NewId()
|
||||||
|
ID_BOX_FRAME = wx.NewId()
|
||||||
|
ID_CROP_FRAME = wx.NewId()
|
||||||
|
|
||||||
def ConvertBMP(file_nm):
|
def ConvertBMP(file_nm):
|
||||||
if file_nm is None:
|
if file_nm is None:
|
||||||
return None
|
return None
|
||||||
@@ -42,35 +66,68 @@ def ConvertBMP(file_nm):
|
|||||||
ext = fl_fld[1]
|
ext = fl_fld[1]
|
||||||
ext = ext[1:].lower()
|
ext = ext[1:].lower()
|
||||||
|
|
||||||
image = wx.Image(file_nm, wx.BITMAP_TYPE_ANY)
|
# Don't try to create it directly because wx throws up
|
||||||
return image
|
# an annoying messasge dialog if the type isn't supported.
|
||||||
|
if wx.Image.CanRead(file_nm):
|
||||||
|
image = wx.Image(file_nm, wx.BITMAP_TYPE_ANY)
|
||||||
|
return image
|
||||||
|
|
||||||
|
# BAD_IMAGE means a bad image, None just means no image (i.e. directory)
|
||||||
|
return BAD_IMAGE
|
||||||
|
|
||||||
|
|
||||||
def GetSize(file_nm): # for scaling image values
|
def GetCheckeredBitmap(blocksize=8,ntiles=4,rgb0='\xFF', rgb1='\xCC'):
|
||||||
image = ConvertBMP(file_nm)
|
"""Creates a square RGB checkered bitmap using the two specified colors.
|
||||||
bmp = image.ConvertToBitmap()
|
|
||||||
size = bmp.GetWidth(), bmp.GetHeight()
|
Inputs:
|
||||||
return size
|
- blocksize: the number of pixels in each solid color square
|
||||||
|
- ntiles: the number of tiles along width and height. Each tile is 2x2 blocks.
|
||||||
|
- rbg0,rgb1: the first and second colors, as 3-byte strings.
|
||||||
|
If only 1 byte is provided, it is treated as a grey value.
|
||||||
|
|
||||||
|
The bitmap returned will have width = height = blocksize*ntiles*2
|
||||||
|
"""
|
||||||
|
size = blocksize*ntiles*2
|
||||||
|
|
||||||
|
if len(rgb0)==1:
|
||||||
|
rgb0 = rgb0 * 3
|
||||||
|
if len(rgb1)==1:
|
||||||
|
rgb1 = rgb1 * 3
|
||||||
|
|
||||||
|
strip0 = (rgb0*blocksize + rgb1*blocksize)*(ntiles*blocksize)
|
||||||
|
strip1 = (rgb1*blocksize + rgb0*blocksize)*(ntiles*blocksize)
|
||||||
|
band = strip0 + strip1
|
||||||
|
data = band * ntiles
|
||||||
|
return wx.BitmapFromBuffer(size, size, data)
|
||||||
|
|
||||||
|
def GetNamedBitmap(name):
|
||||||
|
return IMG_CATALOG[name].getBitmap()
|
||||||
|
|
||||||
|
|
||||||
class ImageView(wx.Window):
|
class ImageView(wx.Window):
|
||||||
def __init__(self, parent, id=-1, pos=wx.DefaultPosition, size=wx.DefaultSize):
|
def __init__(self, parent, id=-1, pos=wx.DefaultPosition, size=wx.DefaultSize,
|
||||||
wx.Window.__init__(self, parent, id, pos, size)
|
style=wx.BORDER_SUNKEN
|
||||||
self.win = parent
|
):
|
||||||
|
wx.Window.__init__(self, parent, id, pos, size, style=style)
|
||||||
|
|
||||||
self.image = None
|
self.image = None
|
||||||
self.back_color = 'WHITE'
|
|
||||||
self.border_color = 'BLACK'
|
self.check_bmp = None
|
||||||
|
self.check_dim_bmp = None
|
||||||
|
|
||||||
|
# dark_bg is the brush/bitmap to use for painting in the whole background
|
||||||
|
# lite_bg is the brush/bitmap/pen to use for painting the image rectangle
|
||||||
|
self.dark_bg = None
|
||||||
|
self.lite_bg = None
|
||||||
|
|
||||||
|
self.border_mode = ID_CROP_FRAME
|
||||||
|
self.SetBackgroundMode( ID_WHITE_BG )
|
||||||
|
self.SetBorderMode( ID_NO_FRAME )
|
||||||
|
|
||||||
# Changed API of wx uses tuples for size and pos now.
|
# Changed API of wx uses tuples for size and pos now.
|
||||||
self.image_sizex = size[0]
|
|
||||||
self.image_sizey = size[1]
|
|
||||||
self.image_posx = pos[0]
|
|
||||||
self.image_posy = pos[1]
|
|
||||||
self.Bind(wx.EVT_PAINT, self.OnPaint)
|
self.Bind(wx.EVT_PAINT, self.OnPaint)
|
||||||
|
self.Bind(wx.EVT_ERASE_BACKGROUND, self.OnEraseBackground)
|
||||||
def OnPaint(self, event):
|
self.Bind(wx.EVT_SIZE, self.OnSize)
|
||||||
dc = wx.PaintDC(self)
|
|
||||||
self.DrawImage(dc)
|
|
||||||
|
|
||||||
|
|
||||||
def SetValue(self, file_nm): # display the selected file in the panel
|
def SetValue(self, file_nm): # display the selected file in the panel
|
||||||
@@ -78,56 +135,257 @@ class ImageView(wx.Window):
|
|||||||
self.image = image
|
self.image = image
|
||||||
self.Refresh()
|
self.Refresh()
|
||||||
|
|
||||||
def DrawBorder(self, dc):
|
def SetBackgroundMode(self, mode):
|
||||||
brush = wx.Brush(wx.NamedColour(self.back_color), wx.SOLID)
|
self.bg_mode = mode
|
||||||
dc.SetBrush(brush)
|
self._updateBGInfo()
|
||||||
dc.SetPen(wx.Pen(wx.NamedColour(self.border_color), 1))
|
|
||||||
dc.DrawRectangle(0, 0, self.image_sizex, self.image_sizey)
|
def _updateBGInfo(self):
|
||||||
|
bg = self.bg_mode
|
||||||
|
border = self.border_mode
|
||||||
|
|
||||||
|
self.dark_bg = None
|
||||||
|
self.lite_bg = None
|
||||||
|
|
||||||
|
if border == ID_BOX_FRAME:
|
||||||
|
self.lite_bg = wx.BLACK_PEN
|
||||||
|
|
||||||
|
if bg == ID_WHITE_BG:
|
||||||
|
if border == ID_CROP_FRAME:
|
||||||
|
self.SetBackgroundColour('LIGHT GREY')
|
||||||
|
self.lite_bg = wx.WHITE_BRUSH
|
||||||
|
else:
|
||||||
|
self.SetBackgroundColour('WHITE')
|
||||||
|
|
||||||
|
elif bg == ID_GREY_BG:
|
||||||
|
if border == ID_CROP_FRAME:
|
||||||
|
self.SetBackgroundColour('GREY')
|
||||||
|
self.lite_bg = wx.LIGHT_GREY_BRUSH
|
||||||
|
else:
|
||||||
|
self.SetBackgroundColour('LIGHT GREY')
|
||||||
|
|
||||||
|
elif bg == ID_BLACK_BG:
|
||||||
|
if border == ID_BOX_FRAME:
|
||||||
|
self.lite_bg = wx.WHITE_PEN
|
||||||
|
if border == ID_CROP_FRAME:
|
||||||
|
self.SetBackgroundColour('GREY')
|
||||||
|
self.lite_bg = wx.BLACK_BRUSH
|
||||||
|
else:
|
||||||
|
self.SetBackgroundColour('BLACK')
|
||||||
|
|
||||||
|
else:
|
||||||
|
if self.check_bmp is None:
|
||||||
|
self.check_bmp = GetCheckeredBitmap()
|
||||||
|
self.check_dim_bmp = GetCheckeredBitmap(rgb0='\x7F', rgb1='\x66')
|
||||||
|
if border == ID_CROP_FRAME:
|
||||||
|
self.dark_bg = self.check_dim_bmp
|
||||||
|
self.lite_bg = self.check_bmp
|
||||||
|
else:
|
||||||
|
self.dark_bg = self.check_bmp
|
||||||
|
|
||||||
|
self.Refresh()
|
||||||
|
|
||||||
|
def SetBorderMode(self, mode):
|
||||||
|
self.border_mode = mode
|
||||||
|
self._updateBGInfo()
|
||||||
|
|
||||||
|
def OnSize(self, event):
|
||||||
|
event.Skip()
|
||||||
|
self.Refresh()
|
||||||
|
|
||||||
|
def OnPaint(self, event):
|
||||||
|
dc = wx.PaintDC(self)
|
||||||
|
self.DrawImage(dc)
|
||||||
|
|
||||||
|
def OnEraseBackground(self, evt):
|
||||||
|
if self.bg_mode != ID_CHECK_BG:
|
||||||
|
evt.Skip()
|
||||||
|
return
|
||||||
|
dc = evt.GetDC()
|
||||||
|
if not dc:
|
||||||
|
dc = wx.ClientDC(self)
|
||||||
|
rect = self.GetUpdateRegion().GetBox()
|
||||||
|
dc.SetClippingRect(rect)
|
||||||
|
self.PaintBackground(dc, self.dark_bg)
|
||||||
|
|
||||||
|
def PaintBackground(self, dc, painter, rect=None):
|
||||||
|
if painter is None:
|
||||||
|
return
|
||||||
|
if rect is None:
|
||||||
|
pos = self.GetPosition()
|
||||||
|
sz = self.GetSize()
|
||||||
|
else:
|
||||||
|
pos = rect.Position
|
||||||
|
sz = rect.Size
|
||||||
|
|
||||||
|
if type(painter)==wx.Brush:
|
||||||
|
dc.SetPen(wx.TRANSPARENT_PEN)
|
||||||
|
dc.SetBrush(painter)
|
||||||
|
dc.DrawRectangle(pos.x,pos.y,sz.width,sz.height)
|
||||||
|
elif type(painter)==wx.Pen:
|
||||||
|
dc.SetPen(painter)
|
||||||
|
dc.SetBrush(wx.TRANSPARENT_BRUSH)
|
||||||
|
dc.DrawRectangle(pos.x-1,pos.y-1,sz.width+2,sz.height+2)
|
||||||
|
else:
|
||||||
|
self.TileBackground(dc, painter, pos.x,pos.y,sz.width,sz.height)
|
||||||
|
|
||||||
|
|
||||||
|
def TileBackground(self, dc, bmp, x,y,w,h):
|
||||||
|
"""Tile bmp into the specified rectangle"""
|
||||||
|
bw = bmp.GetWidth()
|
||||||
|
bh = bmp.GetHeight()
|
||||||
|
|
||||||
|
dc.SetClippingRegion(x,y,w,h)
|
||||||
|
|
||||||
|
# adjust so 0,0 so we always match with a tiling starting at 0,0
|
||||||
|
dx = x % bw
|
||||||
|
x = x - dx
|
||||||
|
w = w + dx
|
||||||
|
|
||||||
|
dy = y % bh
|
||||||
|
y = y - dy
|
||||||
|
h = h + dy
|
||||||
|
|
||||||
|
tx = x
|
||||||
|
x2 = x+w
|
||||||
|
y2 = y+h
|
||||||
|
|
||||||
|
while tx < x2:
|
||||||
|
ty = y
|
||||||
|
while ty < y2:
|
||||||
|
dc.DrawBitmap(bmp, tx, ty)
|
||||||
|
ty += bh
|
||||||
|
tx += bw
|
||||||
|
|
||||||
def DrawImage(self, dc):
|
def DrawImage(self, dc):
|
||||||
try:
|
|
||||||
image = self.image
|
if not hasattr(self,'image') or self.image is None:
|
||||||
except:
|
|
||||||
return
|
return
|
||||||
|
|
||||||
self.DrawBorder(dc)
|
wwidth,wheight = self.GetSize()
|
||||||
|
image = self.image
|
||||||
|
bmp = None
|
||||||
|
if image != BAD_IMAGE and image.IsOk():
|
||||||
|
iwidth = image.GetWidth() # dimensions of image file
|
||||||
|
iheight = image.GetHeight()
|
||||||
|
else:
|
||||||
|
bmp = wx.ArtProvider.GetBitmap(wx.ART_MISSING_IMAGE, wx.ART_MESSAGE_BOX, (64,64))
|
||||||
|
iwidth = bmp.GetWidth()
|
||||||
|
iheight = bmp.GetHeight()
|
||||||
|
|
||||||
if image is None:
|
# squeeze iwidth x iheight image into window, preserving aspect ratio
|
||||||
return
|
|
||||||
|
|
||||||
try:
|
xfactor = float(wwidth) / iwidth
|
||||||
bmp = image.ConvertToBitmap()
|
yfactor = float(wheight) / iheight
|
||||||
except:
|
|
||||||
return
|
|
||||||
|
|
||||||
iwidth = bmp.GetWidth() # dimensions of image file
|
if xfactor < 1.0 and xfactor < yfactor:
|
||||||
iheight = bmp.GetHeight()
|
scale = xfactor
|
||||||
|
elif yfactor < 1.0 and yfactor < xfactor:
|
||||||
|
scale = yfactor
|
||||||
|
else:
|
||||||
|
scale = 1.0
|
||||||
|
|
||||||
diffx = (self.image_sizex - iwidth)/2 # center calc
|
owidth = int(scale*iwidth)
|
||||||
if iwidth >= self.image_sizex -10: # if image width fits in window adjust
|
oheight = int(scale*iheight)
|
||||||
diffx = 5
|
|
||||||
iwidth = self.image_sizex - 10
|
|
||||||
|
|
||||||
diffy = (self.image_sizey - iheight)/2 # center calc
|
diffx = (wwidth - owidth)/2 # center calc
|
||||||
if iheight >= self.image_sizey - 10: # if image height fits in window adjust
|
diffy = (wheight - oheight)/2 # center calc
|
||||||
diffy = 5
|
|
||||||
iheight = self.image_sizey - 10
|
if not bmp:
|
||||||
|
if owidth!=iwidth or oheight!=iheight:
|
||||||
|
sc_image = sc_image = image.Scale(owidth,oheight)
|
||||||
|
else:
|
||||||
|
sc_image = image
|
||||||
|
bmp = sc_image.ConvertToBitmap()
|
||||||
|
|
||||||
|
if image != BAD_IMAGE and image.IsOk():
|
||||||
|
self.PaintBackground(dc, self.lite_bg, wx.Rect(diffx,diffy,owidth,oheight))
|
||||||
|
|
||||||
|
dc.DrawBitmap(bmp, diffx, diffy, useMask=True) # draw the image to window
|
||||||
|
|
||||||
|
|
||||||
|
class ImagePanel(wx.Panel):
|
||||||
|
def __init__(self, parent, id=-1, pos=wx.DefaultPosition, size=wx.DefaultSize,
|
||||||
|
style=wx.NO_BORDER
|
||||||
|
):
|
||||||
|
wx.Panel.__init__(self, parent, id, pos, size, style=style)
|
||||||
|
|
||||||
|
vbox = wx.BoxSizer(wx.VERTICAL)
|
||||||
|
self.SetSizer(vbox)
|
||||||
|
|
||||||
|
self.view = ImageView(self)
|
||||||
|
vbox.Add(self.view, 1, wx.GROW|wx.ALL, 0)
|
||||||
|
|
||||||
|
hbox_ctrls = wx.BoxSizer(wx.HORIZONTAL)
|
||||||
|
vbox.Add(hbox_ctrls, 0, wx.ALIGN_RIGHT|wx.TOP, 4)
|
||||||
|
|
||||||
|
bmp = GetNamedBitmap('White')
|
||||||
|
btn = wx.BitmapButton(self, ID_WHITE_BG, bmp, style=wx.BU_EXACTFIT)
|
||||||
|
self.Bind(wx.EVT_BUTTON, self.OnSetImgBackground, btn)
|
||||||
|
btn.SetToolTipString("Set background to white")
|
||||||
|
hbox_ctrls.Add(btn, 0, wx.ALIGN_LEFT|wx.LEFT, 4)
|
||||||
|
|
||||||
|
bmp = GetNamedBitmap('Grey')
|
||||||
|
btn = wx.BitmapButton(self, ID_GREY_BG, bmp, style=wx.BU_EXACTFIT)
|
||||||
|
self.Bind(wx.EVT_BUTTON, self.OnSetImgBackground, btn)
|
||||||
|
btn.SetToolTipString("Set background to grey")
|
||||||
|
hbox_ctrls.Add(btn, 0, wx.ALIGN_LEFT|wx.LEFT, 4)
|
||||||
|
|
||||||
|
bmp = GetNamedBitmap('Black')
|
||||||
|
btn = wx.BitmapButton(self, ID_BLACK_BG, bmp, style=wx.BU_EXACTFIT)
|
||||||
|
self.Bind(wx.EVT_BUTTON, self.OnSetImgBackground, btn)
|
||||||
|
btn.SetToolTipString("Set background to black")
|
||||||
|
hbox_ctrls.Add(btn, 0, wx.ALIGN_LEFT|wx.LEFT, 4)
|
||||||
|
|
||||||
|
bmp = GetNamedBitmap('Checked')
|
||||||
|
btn = wx.BitmapButton(self, ID_CHECK_BG, bmp, style=wx.BU_EXACTFIT)
|
||||||
|
self.Bind(wx.EVT_BUTTON, self.OnSetImgBackground, btn)
|
||||||
|
btn.SetToolTipString("Set background to chekered pattern")
|
||||||
|
hbox_ctrls.Add(btn, 0, wx.ALIGN_LEFT|wx.LEFT, 4)
|
||||||
|
|
||||||
|
|
||||||
|
hbox_ctrls.AddSpacer(7)
|
||||||
|
|
||||||
|
bmp = GetNamedBitmap('NoFrame')
|
||||||
|
btn = wx.BitmapButton(self, ID_NO_FRAME, bmp, style=wx.BU_EXACTFIT)
|
||||||
|
self.Bind(wx.EVT_BUTTON, self.OnSetBorderMode, btn)
|
||||||
|
btn.SetToolTipString("No framing around image")
|
||||||
|
hbox_ctrls.Add(btn, 0, wx.ALIGN_LEFT|wx.LEFT, 4)
|
||||||
|
|
||||||
|
bmp = GetNamedBitmap('BoxFrame')
|
||||||
|
btn = wx.BitmapButton(self, ID_BOX_FRAME, bmp, style=wx.BU_EXACTFIT)
|
||||||
|
self.Bind(wx.EVT_BUTTON, self.OnSetBorderMode, btn)
|
||||||
|
btn.SetToolTipString("Frame image with a box")
|
||||||
|
hbox_ctrls.Add(btn, 0, wx.ALIGN_LEFT|wx.LEFT, 4)
|
||||||
|
|
||||||
|
bmp = GetNamedBitmap('CropFrame')
|
||||||
|
btn = wx.BitmapButton(self, ID_CROP_FRAME, bmp, style=wx.BU_EXACTFIT|wx.BORDER_SIMPLE)
|
||||||
|
self.Bind(wx.EVT_BUTTON, self.OnSetBorderMode, btn)
|
||||||
|
btn.SetToolTipString("Frame image with a dimmed background")
|
||||||
|
hbox_ctrls.Add(btn, 0, wx.ALIGN_LEFT|wx.LEFT, 4)
|
||||||
|
|
||||||
|
|
||||||
|
def SetValue(self, file_nm): # display the selected file in the panel
|
||||||
|
self.view.SetValue(file_nm)
|
||||||
|
|
||||||
|
def SetBackgroundMode(self, mode):
|
||||||
|
self.view.SetBackgroundMode(mode)
|
||||||
|
|
||||||
|
def SetBorderMode(self, mode):
|
||||||
|
self.view.SetBorderMode(mode)
|
||||||
|
|
||||||
|
def OnSetImgBackground(self, event):
|
||||||
|
mode = event.GetId()
|
||||||
|
self.SetBackgroundMode(mode)
|
||||||
|
|
||||||
|
def OnSetBorderMode(self, event):
|
||||||
|
mode = event.GetId()
|
||||||
|
self.SetBorderMode(mode)
|
||||||
|
|
||||||
image.Rescale(iwidth, iheight) # rescale to fit the window
|
|
||||||
image.ConvertToBitmap()
|
|
||||||
bmp = image.ConvertToBitmap()
|
|
||||||
dc.DrawBitmap(bmp, diffx, diffy) # draw the image to window
|
|
||||||
|
|
||||||
|
|
||||||
class ImageDialog(wx.Dialog):
|
class ImageDialog(wx.Dialog):
|
||||||
def __init__(self, parent, set_dir = None):
|
def __init__(self, parent, set_dir = None):
|
||||||
wx.Dialog.__init__(self, parent, -1, "Image Browser", wx.DefaultPosition, (400, 400))
|
wx.Dialog.__init__(self, parent, -1, "Image Browser", wx.DefaultPosition, (400, 400),style=wx.DEFAULT_DIALOG_STYLE|wx.RESIZE_BORDER)
|
||||||
|
|
||||||
self.x_pos = 30 # initial display positions
|
|
||||||
self.y_pos = 20
|
|
||||||
self.delta = 20
|
|
||||||
|
|
||||||
size = wx.Size(80, -1)
|
|
||||||
|
|
||||||
self.set_dir = os.getcwd()
|
self.set_dir = os.getcwd()
|
||||||
self.set_file = None
|
self.set_file = None
|
||||||
@@ -136,77 +394,110 @@ class ImageDialog(wx.Dialog):
|
|||||||
if os.path.exists(set_dir): # set to working directory if nothing set
|
if os.path.exists(set_dir): # set to working directory if nothing set
|
||||||
self.set_dir = set_dir
|
self.set_dir = set_dir
|
||||||
|
|
||||||
self.dir_x = self.x_pos
|
vbox_top = wx.BoxSizer(wx.VERTICAL)
|
||||||
self.dir_y = self.y_pos
|
self.SetSizer(vbox_top)
|
||||||
self.dir = wx.StaticText(self, -1, self.set_dir, (self.dir_x, self.dir_y), (250, -1))
|
|
||||||
|
|
||||||
self.y_pos = self.y_pos + self.delta
|
hbox_loc = wx.BoxSizer(wx.HORIZONTAL)
|
||||||
|
vbox_top.Add(hbox_loc, 0, wx.GROW|wx.ALIGN_LEFT|wx.ALL, 0)
|
||||||
|
|
||||||
btn = wx.Button(self, 12331, ' Set Directory ', (self.x_pos, self.y_pos))
|
loc_label = wx.StaticText( self, -1, "Folder:")
|
||||||
self.Bind(wx.EVT_BUTTON, self.SetDirect, btn)
|
hbox_loc.Add(loc_label, 0, wx.ALIGN_LEFT|wx.ALIGN_CENTER_VERTICAL|wx.ALL|wx.ADJUST_MINSIZE, 5)
|
||||||
|
|
||||||
self.type_posy = self.y_pos # save the y position for the image type combo
|
self.dir = wx.TextCtrl( self, -1, self.set_dir, style=wx.TE_RICH|wx.TE_PROCESS_ENTER)
|
||||||
|
self.Bind(wx.EVT_TEXT_ENTER, self.OnDirectoryTextSet, self.dir)
|
||||||
|
hbox_loc.Add(self.dir, 1, wx.GROW|wx.ALIGN_LEFT|wx.ALL, 5)
|
||||||
|
|
||||||
|
up_bmp = wx.ArtProvider.GetBitmap(wx.ART_GO_DIR_UP, wx.ART_BUTTON, (16,16))
|
||||||
|
btn = wx.BitmapButton(self, -1, up_bmp)
|
||||||
|
btn.SetHelpText("Up one level")
|
||||||
|
btn.SetToolTipString("Up one level")
|
||||||
|
self.Bind(wx.EVT_BUTTON, self.OnUpDirectory, btn)
|
||||||
|
hbox_loc.Add(btn, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 2)
|
||||||
|
|
||||||
|
folder_bmp = wx.ArtProvider.GetBitmap(wx.ART_FOLDER_OPEN, wx.ART_BUTTON, (16,16))
|
||||||
|
btn = wx.BitmapButton(self, -1, folder_bmp)
|
||||||
|
btn.SetHelpText("Browse for a &folder...")
|
||||||
|
btn.SetToolTipString("Browse for a folder...")
|
||||||
|
self.Bind(wx.EVT_BUTTON, self.OnChooseDirectory, btn)
|
||||||
|
hbox_loc.Add(btn, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5)
|
||||||
|
|
||||||
|
hbox_nav = wx.BoxSizer(wx.HORIZONTAL)
|
||||||
|
vbox_top.Add(hbox_nav, 0, wx.ALIGN_LEFT|wx.ALL, 0)
|
||||||
|
|
||||||
|
|
||||||
|
label = wx.StaticText( self, -1, "Files of type:")
|
||||||
|
hbox_nav.Add(label, 0, wx.ALIGN_CENTER_VERTICAL|wx.LEFT, 5)
|
||||||
|
|
||||||
self.fl_ext = '*.bmp' # initial setting for file filtering
|
self.fl_ext = '*.bmp' # initial setting for file filtering
|
||||||
self.GetFiles() # get the file list
|
self.GetFiles() # get the file list
|
||||||
|
|
||||||
self.y_pos = self.y_pos + self.delta + 10
|
self.fl_ext_types = (
|
||||||
self.list_height = 150
|
# display, filter
|
||||||
|
("All supported formats", "All"),
|
||||||
|
("BMP (*.bmp)", "*.bmp"),
|
||||||
|
("GIF (*.gif)", "*.gif"),
|
||||||
|
("PNG (*.png)", "*.png"),
|
||||||
|
("JPEG (*.jpg)", "*.jpg"),
|
||||||
|
("ICO (*.ico)", "*.ico"),
|
||||||
|
("PNM (*.pnm)", "*.pnm"),
|
||||||
|
("PCX (*.pcx)", "*.pcx"),
|
||||||
|
("TIFF (*.tif)", "*.tif"),
|
||||||
|
("All Files", "*.*"),
|
||||||
|
)
|
||||||
|
self.set_type,self.fl_ext = self.fl_ext_types[0] # initial file filter setting
|
||||||
|
self.fl_types = [ x[0] for x in self.fl_ext_types ]
|
||||||
|
self.sel_type = wx.ComboBox( self, -1, self.set_type,
|
||||||
|
wx.DefaultPosition, wx.DefaultSize, self.fl_types,
|
||||||
|
wx.CB_DROPDOWN )
|
||||||
|
# after this we don't care about the order any more
|
||||||
|
self.fl_ext_types = dict(self.fl_ext_types)
|
||||||
|
|
||||||
# List of Labels
|
self.Bind(wx.EVT_COMBOBOX, self.OnSetType, self.sel_type)
|
||||||
self.tb = tb = wx.ListBox(self, -1, (self.x_pos, self.y_pos),
|
hbox_nav.Add(self.sel_type, 0, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5)
|
||||||
(160, self.list_height), self.fl_list,
|
|
||||||
wx.LB_SINGLE )
|
splitter = wx.SplitterWindow( self, -1, wx.DefaultPosition, wx.Size(100, 100), 0 )
|
||||||
|
splitter.SetMinimumPaneSize(100)
|
||||||
|
|
||||||
|
split_left = wx.Panel( splitter, -1, wx.DefaultPosition, wx.DefaultSize,
|
||||||
|
wx.NO_BORDER|wx.TAB_TRAVERSAL )
|
||||||
|
vbox_left = wx.BoxSizer(wx.VERTICAL)
|
||||||
|
split_left.SetSizer(vbox_left)
|
||||||
|
|
||||||
|
|
||||||
|
self.tb = tb = wx.ListBox( split_left, -1, wx.DefaultPosition, wx.DefaultSize,
|
||||||
|
self.fl_list, wx.LB_SINGLE )
|
||||||
self.Bind(wx.EVT_LISTBOX, self.OnListClick, tb)
|
self.Bind(wx.EVT_LISTBOX, self.OnListClick, tb)
|
||||||
self.Bind(wx.EVT_LISTBOX_DCLICK, self.OnListDClick, tb)
|
self.Bind(wx.EVT_LISTBOX_DCLICK, self.OnListDClick, tb)
|
||||||
|
vbox_left.Add(self.tb, 1, wx.GROW|wx.ALL, 0)
|
||||||
|
|
||||||
width, height = self.tb.GetSize()
|
width, height = self.tb.GetSize()
|
||||||
image_posx = self.x_pos + width + 20 # positions for setting the image window
|
|
||||||
image_posy = self.y_pos
|
|
||||||
image_sizex = 150
|
|
||||||
image_sizey = self.list_height
|
|
||||||
|
|
||||||
self.fl_types = [
|
split_right = wx.Panel( splitter, -1, wx.DefaultPosition, wx.DefaultSize,
|
||||||
"All Images", "Bmp", "Gif", "Png", "Jpg", "Ico", "Pnm",
|
wx.NO_BORDER|wx.TAB_TRAVERSAL )
|
||||||
"Pcx", "Tif", "All Files"
|
vbox_right = wx.BoxSizer(wx.VERTICAL)
|
||||||
]
|
split_right.SetSizer(vbox_right)
|
||||||
|
|
||||||
self.fl_ext_types = {
|
self.image_view = ImagePanel( split_right )
|
||||||
"All Images": "All",
|
vbox_right.Add(self.image_view, 1, wx.GROW|wx.ALL, 0)
|
||||||
"Bmp": "*.bmp",
|
|
||||||
"Gif": "*.gif",
|
|
||||||
"Png": "*.png",
|
|
||||||
"Jpg": "*.jpg",
|
|
||||||
"Ico": "*.ico",
|
|
||||||
"Pnm": "*.pnm",
|
|
||||||
"Pcx": "*.pcx",
|
|
||||||
"Tif": "*.tif",
|
|
||||||
"All Files": "*.*"
|
|
||||||
}
|
|
||||||
|
|
||||||
self.set_type = self.fl_types[0] # initial file filter setting
|
splitter.SplitVertically(split_left, split_right, 150)
|
||||||
self.fl_ext = self.fl_ext_types[self.set_type]
|
vbox_top.Add(splitter, 1, wx.GROW|wx.ALL, 5)
|
||||||
|
|
||||||
self.sel_type = wx.ComboBox(self, -1, self.set_type, (image_posx , self.type_posy),
|
hbox_btns = wx.BoxSizer(wx.HORIZONTAL)
|
||||||
(150, -1), self.fl_types, wx.CB_DROPDOWN)
|
vbox_top.Add(hbox_btns, 0, wx.ALIGN_RIGHT|wx.ALL, 5)
|
||||||
self.Bind(wx.EVT_COMBOBOX, self.OnSetType, self.sel_type)
|
|
||||||
|
|
||||||
self.image_view = ImageView( self, pos=(image_posx, image_posy),
|
ok_btn = wx.Button( self, wx.ID_OPEN, "", wx.DefaultPosition, wx.DefaultSize, 0 )
|
||||||
size=(image_sizex, image_sizey))
|
self.Bind(wx.EVT_BUTTON, self.OnOk, ok_btn)
|
||||||
|
#ok_btn.SetDefault()
|
||||||
|
hbox_btns.Add(ok_btn, 0, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5)
|
||||||
|
|
||||||
self.y_pos = self.y_pos + height + 20
|
cancel_btn = wx.Button( self, wx.ID_CANCEL, "",
|
||||||
|
wx.DefaultPosition, wx.DefaultSize, 0 )
|
||||||
btn = wx.Button(self, -1, ' Select ', (100, self.y_pos), size)
|
hbox_btns.Add(cancel_btn, 0, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5)
|
||||||
self.Bind(wx.EVT_BUTTON, self.OnOk, btn)
|
|
||||||
|
|
||||||
wx.Button(self, wx.ID_CANCEL, 'Cancel', (250, self.y_pos), size)
|
|
||||||
|
|
||||||
self.y_pos = self.y_pos + self.delta
|
|
||||||
fsize = (400, self.y_pos + 50) # resize dialog for final vertical position
|
|
||||||
self.SetSize(fsize)
|
|
||||||
|
|
||||||
self.ResetFiles()
|
self.ResetFiles()
|
||||||
|
|
||||||
|
|
||||||
def GetFiles(self): # get the file list using directory and extension values
|
def GetFiles(self): # get the file list using directory and extension values
|
||||||
if self.fl_ext == "All":
|
if self.fl_ext == "All":
|
||||||
all_files = []
|
all_files = []
|
||||||
@@ -222,11 +513,17 @@ class ImageDialog(wx.Dialog):
|
|||||||
self.fl_val = FindFiles(self, self.set_dir, self.fl_ext)
|
self.fl_val = FindFiles(self, self.set_dir, self.fl_ext)
|
||||||
self.fl_list = self.fl_val.files
|
self.fl_list = self.fl_val.files
|
||||||
|
|
||||||
|
|
||||||
self.fl_list.sort() # sort the file list
|
self.fl_list.sort() # sort the file list
|
||||||
|
# prepend the directories
|
||||||
|
self.fl_ndirs = len(self.fl_val.dirs)
|
||||||
|
self.fl_list = sorted(self.fl_val.dirs) + self.fl_list
|
||||||
|
|
||||||
def DisplayDir(self): # display the working directory
|
def DisplayDir(self): # display the working directory
|
||||||
if self.dir:
|
if self.dir:
|
||||||
self.dir.SetLabel(self.set_dir)
|
ipt = self.dir.GetInsertionPoint()
|
||||||
|
self.dir.SetValue(self.set_dir)
|
||||||
|
self.dir.SetInsertionPoint(ipt)
|
||||||
|
|
||||||
def OnSetType(self, event):
|
def OnSetType(self, event):
|
||||||
val = event.GetString() # get file type value
|
val = event.GetString() # get file type value
|
||||||
@@ -234,7 +531,7 @@ class ImageDialog(wx.Dialog):
|
|||||||
self.ResetFiles()
|
self.ResetFiles()
|
||||||
|
|
||||||
def OnListDClick(self, event):
|
def OnListDClick(self, event):
|
||||||
self.OnOk(0)
|
self.OnOk('dclick')
|
||||||
|
|
||||||
def OnListClick(self, event):
|
def OnListClick(self, event):
|
||||||
val = event.GetSelection()
|
val = event.GetSelection()
|
||||||
@@ -243,9 +540,40 @@ class ImageDialog(wx.Dialog):
|
|||||||
def SetListValue(self, val):
|
def SetListValue(self, val):
|
||||||
file_nm = self.fl_list[val]
|
file_nm = self.fl_list[val]
|
||||||
self.set_file = file_val = os.path.join(self.set_dir, file_nm)
|
self.set_file = file_val = os.path.join(self.set_dir, file_nm)
|
||||||
self.image_view.SetValue(file_val)
|
if val>=self.fl_ndirs:
|
||||||
|
self.image_view.SetValue(file_val)
|
||||||
|
else:
|
||||||
|
self.image_view.SetValue(None)
|
||||||
|
|
||||||
def SetDirect(self, event): # set the new directory
|
def OnDirectoryTextSet(self,event):
|
||||||
|
event.Skip()
|
||||||
|
path = event.GetString()
|
||||||
|
if os.path.isdir(path):
|
||||||
|
self.set_dir = path
|
||||||
|
self.ResetFiles()
|
||||||
|
return
|
||||||
|
|
||||||
|
if os.path.isfile(path):
|
||||||
|
dname,fname = os.path.split(path)
|
||||||
|
if os.path.isdir(dname):
|
||||||
|
self.ResetFiles()
|
||||||
|
# try to select fname in list
|
||||||
|
try:
|
||||||
|
idx = self.fl_list.index(fname)
|
||||||
|
self.tb.SetSelection(idx)
|
||||||
|
self.SetListValue(idx)
|
||||||
|
return
|
||||||
|
except ValueError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
wx.Bell()
|
||||||
|
|
||||||
|
def OnUpDirectory(self, event):
|
||||||
|
sdir = os.path.split(self.set_dir)[0]
|
||||||
|
self.set_dir = sdir
|
||||||
|
self.ResetFiles()
|
||||||
|
|
||||||
|
def OnChooseDirectory(self, event): # set the new directory
|
||||||
dlg = wx.DirDialog(self)
|
dlg = wx.DirDialog(self)
|
||||||
dlg.SetPath(self.set_dir)
|
dlg.SetPath(self.set_dir)
|
||||||
|
|
||||||
@@ -278,6 +606,12 @@ class ImageDialog(wx.Dialog):
|
|||||||
if len(self.fl_list):
|
if len(self.fl_list):
|
||||||
self.tb.Set(self.fl_list)
|
self.tb.Set(self.fl_list)
|
||||||
|
|
||||||
|
for idir in xrange(self.fl_ndirs):
|
||||||
|
d = self.fl_list[idir]
|
||||||
|
# mark directories as 'True' with client data
|
||||||
|
self.tb.SetClientData(idir, True)
|
||||||
|
self.tb.SetString(idir,'['+d+']')
|
||||||
|
|
||||||
try:
|
try:
|
||||||
self.tb.SetSelection(0)
|
self.tb.SetSelection(0)
|
||||||
self.SetListValue(0)
|
self.SetListValue(0)
|
||||||
@@ -297,24 +631,24 @@ class ImageDialog(wx.Dialog):
|
|||||||
self.EndModal(wx.ID_CANCEL)
|
self.EndModal(wx.ID_CANCEL)
|
||||||
|
|
||||||
def OnOk(self, event):
|
def OnOk(self, event):
|
||||||
self.result = self.set_file
|
if os.path.isdir(self.set_file):
|
||||||
self.EndModal(wx.ID_OK)
|
sdir = os.path.split(self.set_file)
|
||||||
|
|
||||||
|
#os.path.normapth?
|
||||||
|
if sdir and sdir[-1]=='..':
|
||||||
|
sdir = os.path.split(sdir[0])[0]
|
||||||
|
sdir = os.path.split(sdir)
|
||||||
|
self.set_dir = os.path.join(*sdir)
|
||||||
|
self.set_file = None
|
||||||
|
self.ResetFiles()
|
||||||
|
elif event != 'dclick':
|
||||||
|
self.result = self.set_file
|
||||||
|
self.EndModal(wx.ID_OK)
|
||||||
|
|
||||||
|
|
||||||
def OnFileDlg(self):
|
|
||||||
dlg = wx.FileDialog(self, "Choose an Image File", ".", "",
|
|
||||||
"Bmp (*.bmp)|*.bmp|JPEG (*.jpg)|*.jpg", wx.OPEN)
|
|
||||||
|
|
||||||
if dlg.ShowModal() == wx.ID_OK:
|
|
||||||
path = dlg.GetPath()
|
|
||||||
else:
|
|
||||||
path = None
|
|
||||||
|
|
||||||
dlg.Destroy()
|
|
||||||
return path
|
|
||||||
|
|
||||||
class FindFiles:
|
class FindFiles:
|
||||||
def __init__(self, parent, dir, mask):
|
def __init__(self, parent, dir, mask, with_dirs=True):
|
||||||
filelist = []
|
filelist = []
|
||||||
dirlist = [".."]
|
dirlist = [".."]
|
||||||
self.dir = dir
|
self.dir = dir
|
||||||
@@ -327,13 +661,21 @@ class FindFiles:
|
|||||||
continue
|
continue
|
||||||
|
|
||||||
path = os.path.join(dir, i)
|
path = os.path.join(dir, i)
|
||||||
|
|
||||||
|
if os.path.isdir(path):
|
||||||
|
dirlist.append(i)
|
||||||
|
continue
|
||||||
|
|
||||||
path = path.upper()
|
path = path.upper()
|
||||||
value = i.upper()
|
value = i.upper()
|
||||||
|
|
||||||
if pattern.match(value) != None:
|
if pattern.match(value) != None:
|
||||||
filelist.append(i)
|
filelist.append(i)
|
||||||
|
|
||||||
|
|
||||||
self.files = filelist
|
self.files = filelist
|
||||||
|
if with_dirs:
|
||||||
|
self.dirs = dirlist
|
||||||
|
|
||||||
def MakeRegex(self, pattern):
|
def MakeRegex(self, pattern):
|
||||||
import re
|
import re
|
||||||
@@ -356,3 +698,166 @@ class FindFiles:
|
|||||||
fl_name = fl_fld[0]
|
fl_name = fl_fld[0]
|
||||||
ext = fl_fld[1]
|
ext = fl_fld[1]
|
||||||
return ext[1:]
|
return ext[1:]
|
||||||
|
|
||||||
|
|
||||||
|
#----------------------------------------------------------------------
|
||||||
|
# This part of the file was generated by C:\Python25\Scripts\img2py
|
||||||
|
# then edited slightly.
|
||||||
|
|
||||||
|
import cStringIO, zlib
|
||||||
|
|
||||||
|
|
||||||
|
IMG_CATALOG = {}
|
||||||
|
|
||||||
|
class ImageClass: pass
|
||||||
|
|
||||||
|
def getWhiteData():
|
||||||
|
return zlib.decompress(
|
||||||
|
'x\xda\xeb\x0c\xf0s\xe7\xe5\x92\xe2b``\xe0\xf5\xf4p\t\x02\xd2< \xcc\xc1\x04$\
|
||||||
|
o\x8a\x9f\xde\x00\xa4\x98\x8b\x9d<C888n?\xf4\x7f\x00\xe4*z\xba8\x86HLMNP`202\
|
||||||
|
0\xf8\xf3\xff\xbf\xfc|.77\xb5$\x1f\xa9P\x979J\x8b\x18\x18N\\d\x16\t\xfd\xfc\
|
||||||
|
\xce\x07\xa8\x98\xc1\xd3\xd5\xcfe\x9dSB\x13\x00\xcc1\x1b\xb3' )
|
||||||
|
|
||||||
|
def getWhiteBitmap():
|
||||||
|
return wx.BitmapFromImage(getWhiteImage())
|
||||||
|
|
||||||
|
def getWhiteImage():
|
||||||
|
stream = cStringIO.StringIO(getWhiteData())
|
||||||
|
return wx.ImageFromStream(stream)
|
||||||
|
|
||||||
|
IMG_CATALOG['White'] = ImageClass()
|
||||||
|
IMG_CATALOG['White'].getData = getWhiteData
|
||||||
|
IMG_CATALOG['White'].getImage = getWhiteImage
|
||||||
|
IMG_CATALOG['White'].getBitmap = getWhiteBitmap
|
||||||
|
|
||||||
|
|
||||||
|
#----------------------------------------------------------------------
|
||||||
|
def getGreyData():
|
||||||
|
return zlib.decompress(
|
||||||
|
'x\xda\xeb\x0c\xf0s\xe7\xe5\x92\xe2b``\xe0\xf5\xf4p\t\x02\xd2< \xcc\xc1\x04$\
|
||||||
|
o\x8a\x9f\xde\x00\xa4\x98\x8b\x9d<C888n?\xf4\x7f\x00\xe4*y\xba8\x86HLMNP`202\
|
||||||
|
0\x98cY\xcc\xd6\xcf%,,\xac\x96\xe4#\x15\xea2Gi\x11\x03\xc3\xb6\xc7\xcc":A7%\
|
||||||
|
\x80\xaa\x19<]\xfd\\\xd69%4\x01\x00{m\x18s' )
|
||||||
|
|
||||||
|
def getGreyBitmap():
|
||||||
|
return wx.BitmapFromImage(getGreyImage())
|
||||||
|
|
||||||
|
def getGreyImage():
|
||||||
|
stream = cStringIO.StringIO(getGreyData())
|
||||||
|
return wx.ImageFromStream(stream)
|
||||||
|
|
||||||
|
IMG_CATALOG['Grey'] = ImageClass()
|
||||||
|
IMG_CATALOG['Grey'].getData = getGreyData
|
||||||
|
IMG_CATALOG['Grey'].getImage = getGreyImage
|
||||||
|
IMG_CATALOG['Grey'].getBitmap = getGreyBitmap
|
||||||
|
|
||||||
|
|
||||||
|
#----------------------------------------------------------------------
|
||||||
|
def getBlackData():
|
||||||
|
return zlib.decompress(
|
||||||
|
'x\xda\xeb\x0c\xf0s\xe7\xe5\x92\xe2b``\xe0\xf5\xf4p\t\x02\xd2< \xcc\xc1\x04$\
|
||||||
|
o\x8a\x9f\xde\x00\xa4\x98\x8b\x9d<C888n?\xf4\x7f\x00\xe4\xf2y\xba8\x86HLMN\
|
||||||
|
\x90`u\x16e``\xdc\xc3\xc0h\\3\xdb\x0c(\xc3\xe0\xe9\xea\xe7\xb2\xce)\xa1\t\
|
||||||
|
\x00\xb6`\x12\x08' )
|
||||||
|
|
||||||
|
def getBlackBitmap():
|
||||||
|
return wx.BitmapFromImage(getBlackImage())
|
||||||
|
|
||||||
|
def getBlackImage():
|
||||||
|
stream = cStringIO.StringIO(getBlackData())
|
||||||
|
return wx.ImageFromStream(stream)
|
||||||
|
|
||||||
|
IMG_CATALOG['Black'] = ImageClass()
|
||||||
|
IMG_CATALOG['Black'].getData = getBlackData
|
||||||
|
IMG_CATALOG['Black'].getImage = getBlackImage
|
||||||
|
IMG_CATALOG['Black'].getBitmap = getBlackBitmap
|
||||||
|
|
||||||
|
|
||||||
|
#----------------------------------------------------------------------
|
||||||
|
def getCheckedData():
|
||||||
|
return zlib.decompress(
|
||||||
|
'x\xda\xeb\x0c\xf0s\xe7\xe5\x92\xe2b``\xe0\xf5\xf4p\t\x02\xd2< \xcc\xc1\x04$\
|
||||||
|
o\x8a\x9f\xde\x00\xa4\x98\x8b\x9d<C888n?\xf4\x7f\x00\xe4\x1az\xba8\x86HLMNP`\
|
||||||
|
2020\x98cY\xcc\x16y\xe2\xc6\r\tWVeeaC\xb5\x8b\x91\x82\xdc\xccm\xde\xe7\xe7\
|
||||||
|
\xd9Zo\xc8S\xf2\x12\x0cd`\xd0\xd8\xc5&\xf6\xeb\xd5\xe5t\xa0f\x06OW?\x97uN\tM\
|
||||||
|
\x00qL\x1f\x94' )
|
||||||
|
|
||||||
|
def getCheckedBitmap():
|
||||||
|
return wx.BitmapFromImage(getCheckedImage())
|
||||||
|
|
||||||
|
def getCheckedImage():
|
||||||
|
stream = cStringIO.StringIO(getCheckedData())
|
||||||
|
return wx.ImageFromStream(stream)
|
||||||
|
|
||||||
|
IMG_CATALOG['Checked'] = ImageClass()
|
||||||
|
IMG_CATALOG['Checked'].getData = getCheckedData
|
||||||
|
IMG_CATALOG['Checked'].getImage = getCheckedImage
|
||||||
|
IMG_CATALOG['Checked'].getBitmap = getCheckedBitmap
|
||||||
|
|
||||||
|
|
||||||
|
#----------------------------------------------------------------------
|
||||||
|
def getNoFrameData():
|
||||||
|
return zlib.decompress(
|
||||||
|
"x\xda\xeb\x0c\xf0s\xe7\xe5\x92\xe2b``\xe0\xf5\xf4p\t\x02\xd2< \xcc\xc1\x04$\
|
||||||
|
o\x8a\x9f\xde\x00\xa4\x98\x8b\x9d<C888n?\xf4\x7f\x00\xe4\x9ay\xba8\x86HL]\
|
||||||
|
\xdb\xef\xc8\xc5\xa0 \xc04\xf7\xc5\xff\xf8m\xd1\x01.\xba\x93\x9e'\x86\xac\
|
||||||
|
\x14P\xb9\xb9O\xf0\x82\xd62\x0e\xa6\x06\xf9e\x8f;Yg\xc5F'\xd7g]\xf2\xadd;=\
|
||||||
|
\x87S\xfe\xf3\xc7\x15\x8f\x80&0x\xba\xfa\xb9\xacsJh\x02\x00\x07\xac't" )
|
||||||
|
|
||||||
|
def getNoFrameBitmap():
|
||||||
|
return wx.BitmapFromImage(getNoFrameImage())
|
||||||
|
|
||||||
|
def getNoFrameImage():
|
||||||
|
stream = cStringIO.StringIO(getNoFrameData())
|
||||||
|
return wx.ImageFromStream(stream)
|
||||||
|
|
||||||
|
IMG_CATALOG['NoFrame'] = ImageClass()
|
||||||
|
IMG_CATALOG['NoFrame'].getData = getNoFrameData
|
||||||
|
IMG_CATALOG['NoFrame'].getImage = getNoFrameImage
|
||||||
|
IMG_CATALOG['NoFrame'].getBitmap = getNoFrameBitmap
|
||||||
|
|
||||||
|
|
||||||
|
#----------------------------------------------------------------------
|
||||||
|
def getBoxFrameData():
|
||||||
|
return zlib.decompress(
|
||||||
|
"x\xda\xeb\x0c\xf0s\xe7\xe5\x92\xe2b``\xe0\xf5\xf4p\t\x02\xd2< \xcc\xc1\x04$\
|
||||||
|
o\x8a\x9f\xde\x00\xa4\x98\x8b\x9d<C888n?\xf4\x7f\x00\xe4:{\xba8\x86HL\x9d\
|
||||||
|
\xdbw\x91\x8bA\x81\x83\xb9\xfc\xd2\xff\xff\x9bl9\x02\x15\xd5\xdefnJ\xf6\xcb\
|
||||||
|
\xe2\xf0|\x17'\x980W\xed\xaa\xaf\xe0\xcd:\xfd\xaa\xef\xec!/\xda.]ggaH\xfcT\
|
||||||
|
\xbaRI\xca_\xef\xe6\x97\xf5\x9c;\xa2\x15\xfe\xbe^S\xbe\th\x1c\x83\xa7\xab\
|
||||||
|
\x9f\xcb:\xa7\x84&\x00k\xdd.\x08" )
|
||||||
|
|
||||||
|
def getBoxFrameBitmap():
|
||||||
|
return wx.BitmapFromImage(getBoxFrameImage())
|
||||||
|
|
||||||
|
def getBoxFrameImage():
|
||||||
|
stream = cStringIO.StringIO(getBoxFrameData())
|
||||||
|
return wx.ImageFromStream(stream)
|
||||||
|
|
||||||
|
IMG_CATALOG['BoxFrame'] = ImageClass()
|
||||||
|
IMG_CATALOG['BoxFrame'].getData = getBoxFrameData
|
||||||
|
IMG_CATALOG['BoxFrame'].getImage = getBoxFrameImage
|
||||||
|
IMG_CATALOG['BoxFrame'].getBitmap = getBoxFrameBitmap
|
||||||
|
|
||||||
|
|
||||||
|
#----------------------------------------------------------------------
|
||||||
|
def getCropFrameData():
|
||||||
|
return zlib.decompress(
|
||||||
|
"x\xda\xeb\x0c\xf0s\xe7\xe5\x92\xe2b``\xe0\xf5\xf4p\t\x02\xd2< \xcc\xc1\x04$\
|
||||||
|
o\x8a\x9f\xde\x00\xa4\x98\x8b\x9d<C888n?\xf4\x7f\x00\xe4zz\xba8\x86HL\xdd;\
|
||||||
|
\xc1\x90\xeb\x80\x03\x07K\xba\xf3\xbf\xd5\xfe\x17\xc5g;\xedh\x16i\xcf\xdc\
|
||||||
|
\xd4z\xc2\xa8G\x81GIA\x89\xafew\xbc\xf0e\x8e]\xd7\xd3\xd2\x1aT\x16\xacj8\xf3\
|
||||||
|
'\xa1\xca\xf9\xad\x85\xe3\xa4_1\xe7\xef~~\xcd\xedV\xc9\xf0\x7f#\xbftm\xb5\
|
||||||
|
\x8d\t\x03\xc8TW?\x97uN\tM\x00\x9c@0\x82" )
|
||||||
|
|
||||||
|
def getCropFrameBitmap():
|
||||||
|
return wx.BitmapFromImage(getCropFrameImage())
|
||||||
|
|
||||||
|
def getCropFrameImage():
|
||||||
|
stream = cStringIO.StringIO(getCropFrameData())
|
||||||
|
return wx.ImageFromStream(stream)
|
||||||
|
|
||||||
|
IMG_CATALOG['CropFrame'] = ImageClass()
|
||||||
|
IMG_CATALOG['CropFrame'].getData = getCropFrameData
|
||||||
|
IMG_CATALOG['CropFrame'].getImage = getCropFrameImage
|
||||||
|
IMG_CATALOG['CropFrame'].getBitmap = getCropFrameBitmap
|
||||||
|
@@ -511,6 +511,8 @@ class InspectionInfoPanel(wx.stc.StyledTextCtrl):
|
|||||||
st.append(self.Fmt('name', obj.GetName()))
|
st.append(self.Fmt('name', obj.GetName()))
|
||||||
st.append(self.Fmt('class', obj.__class__))
|
st.append(self.Fmt('class', obj.__class__))
|
||||||
st.append(self.Fmt('bases', obj.__class__.__bases__))
|
st.append(self.Fmt('bases', obj.__class__.__bases__))
|
||||||
|
if hasattr(obj, 'this'):
|
||||||
|
st.append(self.Fmt('this', repr(obj.this)))
|
||||||
st.append(self.Fmt('id', obj.GetId()))
|
st.append(self.Fmt('id', obj.GetId()))
|
||||||
st.append(self.Fmt('style', obj.GetWindowStyle()))
|
st.append(self.Fmt('style', obj.GetWindowStyle()))
|
||||||
st.append(self.Fmt('pos', obj.GetPosition()))
|
st.append(self.Fmt('pos', obj.GetPosition()))
|
||||||
@@ -561,6 +563,8 @@ class InspectionInfoPanel(wx.stc.StyledTextCtrl):
|
|||||||
def FmtSizer(self, obj):
|
def FmtSizer(self, obj):
|
||||||
st = ['Sizer:']
|
st = ['Sizer:']
|
||||||
st.append(self.Fmt('class', obj.__class__))
|
st.append(self.Fmt('class', obj.__class__))
|
||||||
|
if hasattr(obj, 'this'):
|
||||||
|
st.append(self.Fmt('this', repr(obj.this)))
|
||||||
st.append(self.Fmt('pos', obj.GetPosition()))
|
st.append(self.Fmt('pos', obj.GetPosition()))
|
||||||
st.append(self.Fmt('size', obj.GetSize()))
|
st.append(self.Fmt('size', obj.GetSize()))
|
||||||
st.append(self.Fmt('minsize', obj.GetMinSize()))
|
st.append(self.Fmt('minsize', obj.GetMinSize()))
|
||||||
|
@@ -22,20 +22,25 @@ def get_acroversion():
|
|||||||
global _acroversion
|
global _acroversion
|
||||||
if _acroversion == None:
|
if _acroversion == None:
|
||||||
import _winreg
|
import _winreg
|
||||||
acrosoft = [r'SOFTWARE\Adobe\Acrobat Reader\%version%\InstallPath',
|
adobesoft = _winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE, r'Software\Adobe')
|
||||||
r'SOFTWARE\Adobe\Adobe Acrobat\%version%\InstallPath',]
|
acrokeys, acroversions = [], []
|
||||||
|
for index in range(_winreg.QueryInfoKey(adobesoft)[0]):
|
||||||
for regkey in acrosoft:
|
key = _winreg.EnumKey(adobesoft, index)
|
||||||
for version in ('7.0', '6.0', '5.0', '4.0'):
|
if "acrobat" in key.lower():
|
||||||
|
acrokeys.append(_winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE, 'Software\\Adobe\\%s' % key))
|
||||||
|
for acrokey in acrokeys:
|
||||||
|
for index in range(_winreg.QueryInfoKey(acrokey)[0]):
|
||||||
|
key = _winreg.EnumKey(acrokey, index)
|
||||||
try:
|
try:
|
||||||
path = _winreg.QueryValue(_winreg.HKEY_LOCAL_MACHINE,
|
acroversions.append(float(key))
|
||||||
regkey.replace('%version%', version))
|
|
||||||
_acroversion = version
|
|
||||||
break
|
|
||||||
except:
|
except:
|
||||||
continue
|
pass
|
||||||
|
acroversions.sort(reverse=True)
|
||||||
|
if acroversions:
|
||||||
|
_acroversion = acroversions[0]
|
||||||
return _acroversion
|
return _acroversion
|
||||||
|
|
||||||
|
|
||||||
#----------------------------------------------------------------------
|
#----------------------------------------------------------------------
|
||||||
|
|
||||||
# The ActiveX module from Acrobat 7.0 has changed and it seems to now
|
# The ActiveX module from Acrobat 7.0 has changed and it seems to now
|
||||||
@@ -54,7 +59,7 @@ def get_acroversion():
|
|||||||
# Co-ordinates passed as parameters are in points (1/72 inch).
|
# Co-ordinates passed as parameters are in points (1/72 inch).
|
||||||
|
|
||||||
|
|
||||||
if get_acroversion() >= '7.0':
|
if get_acroversion() >= 7.0:
|
||||||
|
|
||||||
from wx.lib.activexwrapper import MakeActiveXClass
|
from wx.lib.activexwrapper import MakeActiveXClass
|
||||||
import win32com.client.gencache
|
import win32com.client.gencache
|
||||||
|
@@ -292,6 +292,22 @@ class Shell(editwindow.EditWindow):
|
|||||||
self.Bind(wx.EVT_CHAR, self.OnChar)
|
self.Bind(wx.EVT_CHAR, self.OnChar)
|
||||||
self.Bind(wx.EVT_KEY_DOWN, self.OnKeyDown)
|
self.Bind(wx.EVT_KEY_DOWN, self.OnKeyDown)
|
||||||
|
|
||||||
|
# Assign handler for the context menu
|
||||||
|
self.Bind(wx.EVT_CONTEXT_MENU, self.OnContextMenu)
|
||||||
|
self.Bind(wx.EVT_UPDATE_UI, self.OnUpdateUI)
|
||||||
|
|
||||||
|
# Assign handlers for edit events
|
||||||
|
self.Bind(wx.EVT_MENU, lambda evt: self.Cut(), id=wx.ID_CUT)
|
||||||
|
self.Bind(wx.EVT_MENU, lambda evt: self.Copy(), id=wx.ID_COPY)
|
||||||
|
self.Bind(wx.EVT_MENU, lambda evt: self.CopyWithPrompts(), id=frame.ID_COPY_PLUS)
|
||||||
|
self.Bind(wx.EVT_MENU, lambda evt: self.Paste(), id=wx.ID_PASTE)
|
||||||
|
self.Bind(wx.EVT_MENU, lambda evt: self.PasteAndRun(), id=frame.ID_PASTE_PLUS)
|
||||||
|
self.Bind(wx.EVT_MENU, lambda evt: self.SelectAll(), id=wx.ID_SELECTALL)
|
||||||
|
self.Bind(wx.EVT_MENU, lambda evt: self.Clear(), id=wx.ID_CLEAR)
|
||||||
|
self.Bind(wx.EVT_MENU, lambda evt: self.Undo(), id=wx.ID_UNDO)
|
||||||
|
self.Bind(wx.EVT_MENU, lambda evt: self.Redo(), id=wx.ID_REDO)
|
||||||
|
|
||||||
|
|
||||||
# Assign handler for idle time.
|
# Assign handler for idle time.
|
||||||
self.waiting = False
|
self.waiting = False
|
||||||
self.Bind(wx.EVT_IDLE, self.OnIdle)
|
self.Bind(wx.EVT_IDLE, self.OnIdle)
|
||||||
@@ -1367,6 +1383,48 @@ Platform: %s""" % \
|
|||||||
config.WriteBool('View/ShowLineNumbers', self.lineNumbers)
|
config.WriteBool('View/ShowLineNumbers', self.lineNumbers)
|
||||||
config.WriteInt('View/Zoom/Shell', self.GetZoom())
|
config.WriteInt('View/Zoom/Shell', self.GetZoom())
|
||||||
|
|
||||||
|
def GetContextMenu(self):
|
||||||
|
"""
|
||||||
|
Create and return a context menu for the shell.
|
||||||
|
This is used instead of the scintilla default menu
|
||||||
|
in order to correctly respect our immutable buffer.
|
||||||
|
"""
|
||||||
|
menu = wx.Menu()
|
||||||
|
menu.Append(wx.ID_UNDO, "Undo")
|
||||||
|
menu.Append(wx.ID_REDO, "Redo")
|
||||||
|
|
||||||
|
menu.AppendSeparator()
|
||||||
|
|
||||||
|
menu.Append(wx.ID_CUT, "Cut")
|
||||||
|
menu.Append(wx.ID_COPY, "Copy")
|
||||||
|
menu.Append(frame.ID_COPY_PLUS, "Copy Plus")
|
||||||
|
menu.Append(wx.ID_PASTE, "Paste")
|
||||||
|
menu.Append(frame.ID_PASTE_PLUS, "Paste Plus")
|
||||||
|
menu.Append(wx.ID_CLEAR, "Clear")
|
||||||
|
|
||||||
|
menu.AppendSeparator()
|
||||||
|
|
||||||
|
menu.Append(wx.ID_SELECTALL, "Select All")
|
||||||
|
return menu
|
||||||
|
|
||||||
|
def OnContextMenu(self, evt):
|
||||||
|
menu = self.GetContextMenu()
|
||||||
|
self.PopupMenu(menu)
|
||||||
|
|
||||||
|
def OnUpdateUI(self, evt):
|
||||||
|
id = evt.Id
|
||||||
|
if id in (wx.ID_CUT, wx.ID_CLEAR):
|
||||||
|
evt.Enable(self.CanCut())
|
||||||
|
elif id in (wx.ID_COPY, frame.ID_COPY_PLUS):
|
||||||
|
evt.Enable(self.CanCopy())
|
||||||
|
elif id in (wx.ID_PASTE, frame.ID_PASTE_PLUS):
|
||||||
|
evt.Enable(self.CanPaste())
|
||||||
|
elif id == wx.ID_UNDO:
|
||||||
|
evt.Enable(self.CanUndo())
|
||||||
|
elif id == wx.ID_REDO:
|
||||||
|
evt.Enable(self.CanRedo())
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## NOTE: The DnD of file names is disabled until I can figure out how
|
## NOTE: The DnD of file names is disabled until I can figure out how
|
||||||
|
@@ -304,7 +304,7 @@ class ParamFont(PPanel):
|
|||||||
except KeyError: error = True; wx.LogError('Invalid style specification')
|
except KeyError: error = True; wx.LogError('Invalid style specification')
|
||||||
try: weight = fontWeightsXml2wx[self.value[3]]
|
try: weight = fontWeightsXml2wx[self.value[3]]
|
||||||
except KeyError: error = True; wx.LogError('Invalid weight specification')
|
except KeyError: error = True; wx.LogError('Invalid weight specification')
|
||||||
try: underlined = bool(self.value[4])
|
try: underlined = bool(int(self.value[4]))
|
||||||
except ValueError: error = True; wx.LogError('Invalid underlined flag specification')
|
except ValueError: error = True; wx.LogError('Invalid underlined flag specification')
|
||||||
face = self.value[5]
|
face = self.value[5]
|
||||||
except IndexError:
|
except IndexError:
|
||||||
|
@@ -197,7 +197,7 @@ class xxxObject:
|
|||||||
# Special parameters
|
# Special parameters
|
||||||
specials = []
|
specials = []
|
||||||
# Bitmap tags
|
# Bitmap tags
|
||||||
bitmapTags = ['bitmap', 'bitmap2', 'icon']
|
bitmapTags = ['bitmap', 'bitmap2', 'icon', 'selected', 'focus', 'disabled']
|
||||||
# Required paremeters: none by default
|
# Required paremeters: none by default
|
||||||
required = []
|
required = []
|
||||||
# Default parameters with default values
|
# Default parameters with default values
|
||||||
|
@@ -148,7 +148,8 @@ wxID_HTML_SEARCHCHOICE = wx.html.ID_HTML_SEARCHCHOICE
|
|||||||
wxID_HTML_COUNTINFO = wx.html.ID_HTML_COUNTINFO
|
wxID_HTML_COUNTINFO = wx.html.ID_HTML_COUNTINFO
|
||||||
wxHtmlHelpWindow = wx.html.HtmlHelpWindow
|
wxHtmlHelpWindow = wx.html.HtmlHelpWindow
|
||||||
wxPreHtmlHelpWindow = wx.html.PreHtmlHelpWindow
|
wxPreHtmlHelpWindow = wx.html.PreHtmlHelpWindow
|
||||||
wxHtmlWindowEvent = wx.html.HtmlWindowEvent
|
wxHtmlCellEvent = wx.html.HtmlCellEvent
|
||||||
|
wxHtmlLinkEvent = wx.html.HtmlLinkEvent
|
||||||
wxHtmlHelpFrame = wx.html.HtmlHelpFrame
|
wxHtmlHelpFrame = wx.html.HtmlHelpFrame
|
||||||
wxPreHtmlHelpFrame = wx.html.PreHtmlHelpFrame
|
wxPreHtmlHelpFrame = wx.html.PreHtmlHelpFrame
|
||||||
wxHtmlHelpDialog = wx.html.HtmlHelpDialog
|
wxHtmlHelpDialog = wx.html.HtmlHelpDialog
|
||||||
|
Reference in New Issue
Block a user