|
From: John H. <ec...@ya...> - 2009-11-02 19:48:50
|
I can now be more specific about the layoutEditor error in handling the PDFWindow & FlashWindow wrappers. layoutEditor actually creates the components fine (in the same manner as htmlWindow) but when it saves the file, it always ended up with a size of (-1,-1). Of course that won't work properly.
What do I need to do to fix this?
Regards,
--
John Henry
----- Original Message ----
> From: John Henry <ec...@ya...>
> To: John Henry <kim...@ya...>; pyt...@li...
> Sent: Mon, November 2, 2009 8:42:47 AM
> Subject: FlashWindow (was e: [Pythoncard-users] PDFWindow)
>
> Using the same approach as PDFWindow, I managed to create a wrapper for
> FlashWindow. Unlike PDFWindow, this one actually works. However, layoutEditor
> doesn't recognize it and screws up. How do I added it to layoutEditor.
>
> Here's the wrapper code, follow by test sample program:
>
>
> """
> __version__ = "$Revision: 1.19 $"
> __date__ = "$Date: 2004/05/13 02:40:24 $"
> """
>
> import wx
>
> if wx.Platform == '__WXMSW__':
> from wx.lib import flashwin
> else:
> # need a graceful exit
> pass
>
> from PythonCard import event, log, widget
>
> FlashWindowEvents = (
> )
>
> class FlashWindowSpec(widget.WidgetSpec):
> def __init__(self):
> self.name = 'FlashWindow'
> self.parent = 'Widget'
> events = list(FlashWindowEvents)
> attributes = {
> 'size' : { 'presence' : 'optional', 'default' : [ 50, 50 ] },
> 'text' : { 'presence' : 'optional', 'default' : '' },
> }
> widget.WidgetSpec.__init__(self, 'FlashWindow', 'Widget', events,
> attributes )
>
>
> class FlashWindow(widget.Widget, flashwin.FlashWindow):
> """
> An HTML window using the MS HTML control.
> """
>
> _spec = FlashWindowSpec()
>
> def __init__(self, aParent, aResource):
> flashwin.FlashWindow.__init__(
> self,
> aParent,
> -1, # widget.makeNewId(aResource.id),
> aResource.position,
> aResource.size,
> style=wx.SUNKEN_BORDER,
> #style = wx.CLIP_SIBLINGS | wx.NO_FULL_REPAINT_ON_RESIZE,
> name = aResource.name
> )
>
> widget.Widget.__init__(self, aParent, aResource)
>
> self._setText(aResource.text)
>
> self._bindEvents(event.WIDGET_EVENTS + FlashWindowEvents)
>
> def _getText(self) :
> #return self.GetOpenedPage()
> return self.GetText()
>
> def _setText(self, aString):
> if aString == '' or aString[0] == '<':
> self.LoadMovie(0, aString)
> else:
> # filename or URL
> self.LoadMovie(0, aString)
>
> text = property(_getText, _setText)
>
> # KEA 2004-05-02
> # this will probably end up in Scriptable or Component
> # it should be completely generic
> # the only problem part would be the reference to the parent (background)
> # where the events are actually defined which would make this problematic
> # for a compound component or events bound to a Panel
> # what we really want is a reference to the application instance
> # there is probably some method to give us that in wxWidgets
> # UPDATE - I think GetTopLevelParent is what I was looking for
> def _bindEvents(self, eventList):
> # shouldn't components be subclasses of Scriptable?
> # components would have their own handlers but when
> # looking for a handler match it will search the parents
> # for now just grab handlers from the background
>
> # the references below would be self.findHandler instead of
> # background.findHandler
>
> #background = self.GetParent().GetParent()
> background = wx.GetTopLevelParent(self)
>
> if wx.GetApp()._showDebugMenu:
> bindUnusedEvents = True
> else:
> bindUnusedEvents = False
>
> # helper variable to simplify test for whether to bind
> InsteadOfTypeEvents
> # there is a good chance we will need to know
> # which events are bound, if we want to dynamically add or remove
> # events later, so go ahead and keep a reference to the list
> self.boundEvents = {}
>
> self.eventIdToHandler = {}
> self.wxEventIdMap = {}
>
> if 0:
> print "\nBINDING...", self.name
>
> for eventClass in eventList:
> #for eventClass in ButtonEvents:
> # need to figure out a way to avoid the need
> # for this id to class mapping which is used in _dispatch below
> self.wxEventIdMap[eventClass.id] = eventClass
> # command handler overrides normal mouseClick or select handler
> # so dispatch will automatically dispatch to the command handler
> # by looking up the handler this way
> # it also means that if there is a command association with this
> component
> # then the regular mouseClick or select handler will never be bound,
> just ignored
> if issubclass(eventClass, event.CommandTypeEvent) and self.command:
> handler = background.findHandler('on_' + self.command +
> '_command')
> if not handler:
> handler = background.findHandler('on_' + self.name + '_' +
> eventClass.name)
> else:
> handler = background.findHandler('on_' + self.name + '_' +
> eventClass.name)
> if not handler:
> handler = background.findHandler('on_' + eventClass.name)
> if handler or bindUnusedEvents:
> # only bind events that have an event handler
> # in this scenario unused events are never bound
> # which is more efficient, but the Message Watcher needs
> # to be changed
> # alternatively we can bind everything and then in _dispatch
> # if there isn't a match in eventIdToHandler then we know
> # the event isn't used and we can set used to False
> # the complication would be that we probably have to have to
> # always call Skip() which may or may not be a hassle with
> components
>
> # this doesn't bind command events
> # they would be of the form on_somename_command
> # or perhaps on_command but I don't think we would want
> # to support that
> # the event binding would be specific to a component
> # since on dispatch command overrides something like
> mouseClickEvent
> # but the name of the command is not related to the component
> # need to look at whether self.command has a value and then bind
> # with ButtonMouseClickEvent.binding if that isn't already bound
> # then in dispatch have to check again I think
>
> # need to avoid double binding
> # also binding shouldn't be order-specific
> # so how to avoid binding mouseDrag to _dispatch
> # if mouseMove is already bound or if binding mouseMove
> # not rebinding if mouseDrag is already bound
> # perhaps MouseDragEvent keeps a reference to MouseMoveEvent
> # and that is inserted into boundEvents, then we check
> boundEvents
> # prior to rebinding?
> if not self.boundEvents.get(eventClass.binding, None):
> background.Bind(eventClass.binding, self._dispatch, self)
> self.boundEvents[eventClass.binding] = eventClass.name
> if handler:
> if 0:
> print " binding", self.name, eventClass.name,
> handler.__name__, eventClass.id
> # KEA 2004-05-02
> # change to just using the method directly, Handler class
> not needed
> # actually the Handler class isn't needed at all
> # so if the initial list built to simplify findHandler
> # just stores a reference to the method that would be fine
> # as long as the whole system uses that
> # the only reason we don't just build the list ourselves
> # in _bindEvents is that every component needs to do
> findHandler
> # so it is more efficient to do once when the Scriptable
> object
> # is created than to reparse for each component
> #self.eventIdToHandler[eventClass.id] = handler
> #self.eventIdToHandler[eventClass.id] =
> handler.getFunction()
> self.eventIdToHandler[eventClass.id] = handler
>
> if 0:
> print "\n boundEvents:"
> for name in self.boundEvents.values():
> print " ", name
> print "\n\n"
> print "\n self.eventIdToHandler:"
> for id in self.eventIdToHandler:
> # KEA 2004-05-02
> # change to just using the method directly, Handler class not
> needed
> #print " ", id, self.eventIdToHandler[id]._function
> print " ", id, self.eventIdToHandler[id]
> print "\n\n"
>
>
> import sys
> from PythonCard import registry
> registry.Registry.getInstance().register(sys.modules[__name__].FlashWindow)
>
> #Sample program and rsrc file
>
> #!/usr/bin/python
>
> """
> __version__ = "$Revision: 1.19 $"
> __date__ = "$Date: 2004/08/12 19:18:59 $"
> """
>
> from PythonCard import dialog, model
> import wx
>
> class SimpleFlashViewer(model.Background):
>
> def on_initialize(self, event):
> self.flash = self.components.FlashDisplay
>
> btnFlags = wx.RIGHT | wx.ALIGN_CENTER_VERTICAL
>
> sizer3 = wx.BoxSizer(wx.HORIZONTAL)
> sizer3.Add((5, 5), 0) # spacer
> sizer3.Add(self.flash, 1, wx.EXPAND)
> sizer3.Add((10, 5), 0) # spacer
>
> sizer2 = wx.BoxSizer(wx.HORIZONTAL)
> sizer2.Add((5, 5), 1) # spacer
> sizer2.Add(self.components.btnOpenFile, 0, btnFlags, 5)
> sizer2.Add(self.components.btnOpenURL, 0, btnFlags, 5)
>
> sizer1 = wx.BoxSizer(wx.VERTICAL)
> sizer1.Add(sizer3, 1, wx.EXPAND)
> sizer1.Add((5, 5), 0) # spacer
> sizer1.Add(sizer2, 0, wx.EXPAND)
>
> sizer1.Fit(self)
> sizer1.SetSizeHints(self)
> self.panel.SetSizer(sizer1)
> self.panel.SetAutoLayout(1)
> self.panel.Layout()
>
> def on_btnOpenFile_mouseClick(self, event):
> wildcard = "SWF files (*.swf)|*.swf;*.SWF|All files (*.*)|*.*"
> result = dialog.openFileDialog(None, "Open file", '', '', wildcard)
> if result.accepted:
> self.flash.LoadMovie(0, result.paths[0])
> return
>
> def on_btnOpenURL_mouseClick(self, event):
> # you can retrieve flash files from internet too
> result = dialog.textEntryDialog(self, "Enter a URL of a .swf file",
> "Enter URL", '')
> if result.accepted and result.returnedString=="Ok":
> # setting the movie property works too
> self.flash.movie = result.text
> return
>
> if __name__ == '__main__':
> app = model.Application(SimpleFlashViewer)
> app.MainLoop()
>
> # rsrc file
>
> {'application':{'type':'Application',
> 'name':'SimpleFlashViewer',
> 'backgrounds': [
> {'type':'Background',
> 'name':'bgMin',
> 'title':'SimpleFlashViewer PythonCard Application',
> 'size':(698, 703),
> 'statusBar':1,
> 'style':['resizeable'],
>
> 'menubar': {'type':'MenuBar',
> 'menus': [
> {'type':'Menu',
> 'name':'menuFile',
> 'label':'&File',
> 'items': [
> {'type':'MenuItem',
> 'name':'menuFileExit',
> 'label':'E&xit\tAlt+X',
> 'command':'exit',
> },
> ]
> },
> ]
> },
> 'components': [
>
> {'type':'FlashWindow',
> 'name':'FlashDisplay',
> 'position':(0, 30),
> 'size':(685, 553),
> 'backgroundColor':(255, 255, 255, 255),
> },
>
> {'type':'Button',
> 'name':'btnOpenFile',
> 'position':(524, 593),
> 'label':'Open File',
> },
>
> {'type':'Button',
> 'name':'btnOpenURL',
> 'position':(599, 593),
> 'label':'Open URL',
> },
>
> ] # end components
> } # end background
> ] # end backgrounds
> } }
>
>
> --
> John Henry
|