You can subscribe to this list here.
2005 |
Jan
|
Feb
|
Mar
(1) |
Apr
(21) |
May
(24) |
Jun
|
Jul
(16) |
Aug
(28) |
Sep
(5) |
Oct
(4) |
Nov
(2) |
Dec
(25) |
---|---|---|---|---|---|---|---|---|---|---|---|---|
2006 |
Jan
(9) |
Feb
(1) |
Mar
(3) |
Apr
(5) |
May
(24) |
Jun
(5) |
Jul
(2) |
Aug
(3) |
Sep
(4) |
Oct
(8) |
Nov
(37) |
Dec
(25) |
2007 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
(4) |
Jul
(1) |
Aug
|
Sep
(1) |
Oct
|
Nov
|
Dec
|
2008 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
(10) |
Nov
(1) |
Dec
(2) |
2009 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
(2) |
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
From: Kevin A. <al...@se...> - 2005-04-19 14:58:00
|
On Apr 19, 2005, at 5:13 AM, Sells, Fred wrote: > I use it and I edit (infrequently) outside the resource editor. When > that > happens, I use the resource editor to load and save to get it in sync. > I > have a very slight preference toward a separate module/script run from > the > command line. It would facilitate making the tool more robust and > making it > easier for users to customize to meet their needs. As a general rule, my own preference is to not add a lot of extra infrequently used menu items to any of the standard PythonCard tools. As an alternative, I added "scriptlets" to the codeEditor a long time ago, which are simply scripts of anything that can be run in the shell and that could include a standard Python module along with a call to run a particular function. There are some examples in the codeEditor scriptlets directory such as insertDateAndTime.py import time now = time.localtime(time.time()) dateStr = time.strftime("%A, %B %d, %Y, %I:%M %p", now) comp.document.ReplaceSelection(dateStr) You can think of scriptlets as "macros" if you want and there is even support in the codeEditor for making menu items that run these scriptlets, it just isn't documented, nor is there a UI for managing the menu, I just never seem to get around to writing it, even though it is a minor amount of code and UI for the dialog. As an example, I have the following line in my pythoncard_config\codeeditor\user.config.txt file which menu item with Ctrl+1 as a shortcut in the Shell menu: 'macros': [{'filename': 'C: \\python\\PythonCard\\tools\\codeEditor\\scriptlets\\insertDateAndTime.p y', 'key: 'Ctrl+1', 'label': 'insertDateAndTime'}], The line is just another key/value pair in the dictionary. The reason I bring this up is that the resourceEditor should probably have the same scriptlets support and with a dialog to easily allow people to add and remove items from the menu you can have whatever macros you want. ka |
From: Phil E. <ph...@li...> - 2005-04-19 08:26:52
|
Hi everybody: I'm now declaring this finished - the CVS check-in that I've just done includes a fix for an exception that was being raised when building a project without defining a Windows icon file. I've also written some basic documentation and checked this in under the 'doc' folder. Any and all feedback appreciated, either on this list or privately via e-mail. -- Regards Phil Edwards Brighton, UK |
From: Michael S. <mik...@ya...> - 2005-04-18 23:08:39
|
Here is simplified implementation of the example sent previously, using LayoutAnchor in wx.lib.anchor. All updating is taken care of in this case, so there is no need for the on_bgTemplate_size method (hence there would be no need for the changes to model.py). However, the wx documentation indicates that LayoutConstraints are now deprecated (http://wxpython.org/docs/api/wx.LayoutConstraints-class.html). Michael --- Michael Sorich <mik...@ya...> wrote: > Hi, > > I have written some simple code to allow for > anchoring > of components to edges of containers. This > corresponds > fairly closely to a past discussion on the list > http://aspn.activestate.com/ASPN/Mail/Message/pythoncard/1183899. > Attached are a few files that can be run to > demonstrate the concept. The code is very short and > simple. I have written it based on PythonCard v0.8.1 > > testAnchors.py has all the layout code included in > the > file. You should be able to run this application > without any changes to the PythonCard installation. > > If you update model.py, widget.py, and > propertyEditor.py in your PythonCard distribution, > you > will be able to get testAnchors2.py to run. This > should display the same example application. The > anchors variable is now stored in the rsrc file (and > can be set/viewed in the resource editor). The > testAnchors2.py file is now nothing more than the > standard file automatically created with a new > application. You should be able to test your own > examples simply make a new application and set the > anchors property in the property editor (there > should > be a list of options with default of LT ie left > and > top- and thus if you dont change the property it > will > continue to act as it did before this update). > Alternatively, load an existing rsrc file and alter > the anchors property and save. > > testAnchors.py is an example that demonstrates the > limitations of this approach. Components set to > expand > with an expanding container are greedy their > increase in size is equivalent to the increase in > size > of the container. Hence when there are multiple > components that are to change size this may cause > problems. A mechanism of sharing the container size > change between multiple components is necessary to > deal with this. I am unsure what the simplest way of > doing this is. I think it is rather confusing to set > the sharing on a component by component basis. A > simpler approach may be to partition the container > into segments (by rows or columns), with a simple > mechanism for sharing the container size changes. > The > components would then reference the sub containers > (using anchors). > > I hope this is useful. If so, feel free to use the > code under the same license as pythoncard. > > Michael > > Find local movie times and trailers on Yahoo! > Movies. > http://au.movies.yahoo.com> #!/usr/bin/python > > """ > __version__ = "$Revision: 1.3 $" > __date__ = "$Date: 2004/04/14 02:38:47 $" > """ > > # Notes/Musings: > # should be able to set the minimum and/or > maximum size of the container > # should be able to resize text as component > changes size (if wanted) > # > # 6 pieces of information for each component. > For each direction (X and Y): > # 1) Distance from Left/Top edge of container > to Left/Top edge of component (the variable position > holds this) > # 2) Distance from Left/Top edge of component > to Right/Bottom edge of component (the variable size > holds this) > # 3) Distance from Right/Bottom edge of > component to Right/Bottom edge of continer (the > variable RBPosition will hold this) > # * 2 of 3 pieces of information in each > direction must be set > # - the third piece changes with resizing > of the container > # * This means that a minimum of one distance > in the X axis and one distance in the Y-axis must be > set > # anchors variable holds information on which > sides of the component are anchored > # * possible values = 'LT', 'TR', 'LTR', > 'LTRB', 'RB' or 'TRB' > # * allows determination of which 4 distances > are constant > # > # the above assumes that 2 of the 3 distances > will remain constant and the remaining distance will > change as > # the size of the container changes > # change in container size = change in this > distance of the component (i.e. 100% of container > size change) > # a more advanced form of this would allow > setting of relative changes of each 3 distances as > the container resizes > # the sum of the 3 percents would equal 100 > # the simple methodology allows only for 2 > distances to be set at 0% and the third at 100% > # > # an example of where simple anchors will not > work is when there are 2 components that need to > expand in the same > # direction. As simple method only allows the > component to expand 100% of the container size > change or no change. > # Eg 2 TextAreas with anchors='LTRB' will cause > problems as container expands. Also a problem for 2 > components > # expanding in a single direction, under certain > conditions > # > # The more advanced anchors would allow this to > be overcome. However, a simpler solution may be to > include > # a method of partitioning the container space > into n rows or columns that can be set to change > size as percentages of > # the container size change. It may be possible > to implement this as a set of panels. Call the > container-component > # a PartitionPanel. Then the components would be > set using simple anchors relative to one of the > panels in the > # PartitionPanel. > > > from PythonCard import model > > > # include in widget.py (end of Widget.__init__) > def calcRBPosition(component): > """a tuple of the distance between the > right-bottom (aka south-east?) corner of the > component > and the right-bottom corner of the container > * this is complementary to the position > variable which is the distance between the left-top > corner of the component and > the left-top corner of the container > * also the size of the container is equal to > the sum of the LTPosition (aka position), size and > RBPosition of the component""" > container = component.getParent() > return > container.size[0]-component.position[0]-component.size[0], > container.size[1]-component.position[1]-component.size[1] > > # include in widget.py(Widget.anchorLayout()) > def anchorLayout(component): > """method called to re-layout the component > using anchors""" > > container = component.getParent() #the panel > > if component.anchors == 'LT': > #this is the current standard handling -> > don't need to do anything > pass > > elif component.anchors == 'LB': > #change position on the y axis > component.position = (component.position[0], > > container.size[1] - > component.size[1] - component.RBPosition[1]) > > elif component.anchors == 'TR': > #change position on the x axis > component.position = (container.size[0] - > component.size[0] - component.RBPosition[0], > > component.position[1]) > > elif component.anchors == 'RB': > #change position on x and y axes > component.position = (container.size[0] - > component.size[0] - component.RBPosition[0], > > container.size[1] - > component.size[1] - component.RBPosition[1]) > > elif component.anchors == 'LTR': > #change size in the x-axis > component.size = (container.size[0] - > component.position[0] - component.RBPosition[0], > > component.size[1]) > > elif component.anchors == 'LTB': > #change size in the y-axis > component.size = (component.size[0], > > container.size[1] - > component.position[1] - component.RBPosition[1]) > > elif component.anchors == 'LBR': > #change position on the y axis > component.position = (component.position[0], > > container.size[1] - > component.size[1] - component.RBPosition[1]) > #change size in the x-axis > component.size = (container.size[0] - > component.position[0] - component.RBPosition[0], > > component.size[1]) > > elif component.anchors == 'TRB': > #change position on the x axis > component.position = (container.size[0] - > component.size[0] - component.RBPosition[0], > > component.position[1]) > #change size in the y-axis > component.size = (component.size[0], > > container.size[1] - > component.position[1] - component.RBPosition[1]) > > elif component.anchors == 'LTRB': > # X and Y size change > component.size = (container.size[0] - > component.position[0] - component.RBPosition[0], > > container.size[1] - > component.position[1] - component.RBPosition[1]) > > class MyBackground(model.Background): > > def on_initialize(self, event): > #required so panel resizes with wxFrame > #move to model.py (Background.__init__) > self.panel.RBPosition = > self.size[0]-self.panel.position[0]-self.panel.size[0], > self.size[1]-self.panel.position[1]-self.panel.size[1] > > #for each component > # set the anchors variable > # this should eventually be set in the > ResourceEditor and saved in rsrc file > # add 'anchors' to WidgetSpec in > widget.py > # changed > tools/ResourceEditor/modules/propertyEditor.py to > include anchor in self.popItems > # calculate and store the RBPosition > # distance between the right-bottom > (aka south-east?) corner of the component > === message truncated ===> {'application':{'type':'Application', > 'name':'Template', > 'backgrounds': [ > {'type':'Background', > 'name':'bgTemplate', > 'title':'Standard Template with no menus', > 'size':(523, 300), > 'style':['resizeable'], > > 'components': [ > > {'type':'Choice', > 'name':'Choice1', > 'position':(22, 41), > 'anchors':'LT', > 'items':[], > }, > > {'type':'Tree', > 'name':'Tree1', > 'position':(390, 10), > 'size':(110, 225), > 'anchors':'TRB', > 'backgroundColor':(255, 255, 255), > 'font':{'faceName': 'Tahoma', 'family': > 'sansSerif', 'size': 8}, > }, > > {'type':'StaticText', > 'name':'StaticText1', > 'position':(312, 13), > 'anchors':'TR', > 'text':'StaticText1', > }, > > {'type':'TextField', > 'name':'TextField1', > 'position':(20, 75), > 'size':(350, -1), > 'anchors':'LTR', > 'text':'TextField1', > }, > > {'type':'TextArea', > 'name':'TextArea1', > 'position':(20, 115), > 'size':(352, 85), > 'anchors':'LTRB', > 'text':'TextArea1', > }, > > {'type':'Button', > 'name':'Button2', > 'position':(20, 210), > 'anchors':'LB', > 'label':'Button2', > }, > > {'type':'Button', > 'name':'Button1', > 'position':(295, 210), > 'anchors':'RB', > 'label':'Button1', > }, > > ] # end components > } # end background > ] # end backgrounds > } } > > #!/usr/bin/python > > """ > __version__ = "$Revision: 1.3 $" > __date__ = "$Date: 2004/04/14 02:38:47 $" > """ > > from PythonCard import model > > class MyBackground(model.Background): > > def on_initialize(self, event): > # if you have any initialization > # including sizer setup, do it here > pass > > > > if __name__ == '__main__': > app = model.Application(MyBackground) > app.MainLoop() > > {'application':{'type':'Application', > 'name':'Template', > 'backgrounds': [ > {'type':'Background', > 'name':'bgTemplate', > 'title':'Standard Template with no menus', > 'size':(523, 300), > 'style':['resizeable'], > > 'components': [ > > {'type':'Choice', > 'name':'Choice1', > 'position':(22, 41), > 'anchors':'LT', > 'items':[], > }, > > {'type':'Tree', > 'name':'Tree1', > 'position':(390, 10), > 'size':(110, 225), > 'anchors':'TRB', > 'backgroundColor':(255, 255, 255), > 'font':{'faceName': 'Tahoma', 'family': > 'sansSerif', 'size': 8}, > }, > > {'type':'StaticText', > 'name':'StaticText1', > 'position':(312, 13), > 'anchors':'TR', > 'text':'StaticText1', > }, > > {'type':'TextField', > 'name':'TextField1', > 'position':(20, 75), > 'size':(350, -1), > 'anchors':'LTR', > 'text':'TextField1', > }, > > {'type':'TextArea', > 'name':'TextArea1', > 'position':(20, 115), > 'size':(352, 85), > 'anchors':'LTRB', > 'text':'TextArea1', > }, > > {'type':'Button', > 'name':'Button2', > 'position':(20, 210), > 'anchors':'LB', > 'label':'Button2', > }, > > {'type':'Button', > 'name':'Button1', > 'position':(295, 210), > 'anchors':'RB', > 'label':'Button1', > }, > > ] # end components > } # end background > ] # end backgrounds > } } > > > """ > __version__ = "$Revision: 1.190 $" > __date__ = "$Date: 2004/09/28 21:24:24 $" > """ > > import os, sys > > # KEA 2004-08-09 > # assert some minimum requirements and attempt to > exit cleanly > # if they aren't met > > try: > # some things might work with lesser > # versions, but this is a reasonable base > assert sys.version_info >= (2, 3) > # sys.modules relative path fix > sys.path[0] = os.path.abspath(sys.path[0]) > #sys.path = [os.path.abspath(p) for p in > sys.path] > > import wx > assert wx.VERSION >= (2, 5, 2, 8) > except: > from wxPython.wx import wxPySimpleApp, wxFrame, > wxMessageDialog, wxICON_EXCLAMATION, wxOK, > wxVERSION_STRING > app = wxPySimpleApp() > frame = wxFrame(None, -1, "Minimum Requirements > Not Met") > #frame.Show(1) > message = "PythonCard minimum > requirements:\nPython 2.3 and wxPython 2.5.2.8\n\n" > + \ > "You are using Python %s\nand wxPython > %s.\n\nClick OK to exit." % (sys.version, > wxVERSION_STRING) > dialog = wxMessageDialog(frame, message, > "Minimum Requirements > Not Met", > wxICON_EXCLAMATION | > wxOK) > dialog.ShowModal() > dialog.Destroy() > #app.MainLoop() > sys.exit(0) > > > > import configuration > import log > import event > import resource > import widget > import menu > import statusbar > import debug > import component > import util > import dialog > > import types > import UserDict > import new > import locale > import inspect > > # KEA 2001-07-27 > from wx.lib import colourdb > > class WidgetDict(UserDict.UserDict, > event.Changeable): > def __init__(self, parent, d=None): > self.__dict__['parent'] = parent > self.__dict__['data'] = {} > self.__dict__['order'] = [] > if d is not None: self.update(d) > event.Changeable.__init__(self) > > # __getattr__ and __setattr__ need to be cleaned > up > # to support more attributes > def __getattr__(self, key): > if key == '_listeners': > return self.__dict__[key] > elif key == 'order': > pass > else: > return self.data[key] > > def __setattr__(self, key, item): > if key == '_listeners': > self.__dict__[key] = item > elif key == 'order': > pass > else: > self.__setitem__(key, item) > > """ > def __delattr__(self, key): > if key == '_listeners': > pass > else: > self.__delitem__(key) > """ > > def __setitem__(self, key, item): > if isinstance(item, dict): > item = resource.Resource(item) > control = > component.ComponentFactory().createComponent(self.parent, > self.parent.panel, item) > if key in self.data: > self.order.remove(key) > self.order.append(key) > self.data[key] = control > # notify listeners > self.fireChanged(key + "," + > control.__class__.__name__) > > def __delitem__(self, key): > control = self.data[key] > # KEA 2002-05-20 > # hack for 2.3.3 focus problem? > visible = control.visible > control.Show(0) > wClass = control.__class__.__name__ > focusWin = wx.Window_FindFocus() > if focusWin is not None and focusWin == > control: > #print "disconnecting > wx.wxEVT_KILL_FOCUS", control.name > focusWin.Disconnect(-1, -1, > wx.wxEVT_KILL_FOCUS) > if self.data[key].Destroy(): > self.order.remove(key) > del self.data[key] > self.fireChanged(key + "," + wClass) > else: > # why would Destroy fail? > # if it does fail we have > # a problem since we disconnected > wx.wxEVT_KILL_FOCUS > print "destroy failed", control > control.Show(visible) > > def clear(self): > for key in self.data.keys(): > self.__delitem__(key) > > def _getAttributeNames(self): > return self.data.keys() > > > def internationalResourceName(base): > aFileName = base + ".rsrc.py" > try: > default = locale.getdefaultlocale() > except: > default = None > log.debug('default: ' + str(default)) > if default and default[0] is not None: > language, country = default[0].split('_') > languageCountryName = base + '.' + language > + '_' + country + ".rsrc.py" > languageOnlyName = base + '.' + language + > ".rsrc.py" > if os.path.exists(languageCountryName): > aFileName = languageCountryName > elif os.path.exists(languageOnlyName): > aFileName = languageOnlyName > log.debug(language + ' ' + country + ' ' + > languageCountryName + ' ' + \ > languageOnlyName + ' ' + > aFileName) > return aFileName > > > # KEA 2002-09-09 > # this is derived from the frame loading in > # Application below > def childWindow(parent, frameClass, filename=None, > rsrc=None): > if filename is None: > if rsrc is None: > if util.main_is_frozen(): > # KEA 2004-05-20 > # running standalone > # need to support py2exe differently > than bundlebuilder and mcmillan probably > # but this is the py2exe 0.5 way > # figure out the .rsrc.py filename > based on the module name stored in library.zip > filename = > os.path.split(sys.modules[frameClass.__module__].__file__)[1] > # KEA 2004-09-14 > # it seems sort of dumb to duplicate > this function > # just to handle the parent > differently > === message truncated ===> #!/usr/bin/python > > """ > __version__ = "$Revision: 1.56 $" > __date__ = "$Date: 2004/10/03 19:21:34 $" > """ > > from PythonCard import dialog, font, model, > registry, util > from PythonCard.event import ChangeListener > import resourceOutput > import time > import os > import string > > import wx > > # KEA this is a load of dingos' kidneys and needs to > be rewritten > # 2002-02-22 > # now I'm compounding the problem by porting from > the original > # Property Editor to a PythonCard background > class PropertyEditor(model.Background, > ChangeListener): > > def on_initialize(self, event): > self._parent = self.GetParent() > self._comp = self._parent.components > self._updatingComponent = 0 > self.autoAttributeUpdate = True > > ##self.components.addChangeEventListener(self) > self._comp.addChangeEventListener(self) > > self.checkItems = ['enabled', 'visible', > 'editable', 'checked', 'default', \ > 'rules', 'labels', 'ticks', > 'horizontalScrollbar'] > self.popItems = ['anchors', 'layout', > 'border', 'style', 'alignment', 'stringSelection'] > self.cantModify = ['id', 'name', > 'alignment', 'layout', 'style', 'border', \ > 'horizontalScrollbar', 'min', 'max', > 'columns', 'rules', 'labels', 'ticks'] > > self.editItems = [self.components.wField, > self.components.wColor, > self.components.wFont, > self.components.wTextArea, > self.components.wChecked, > self.components.wPop, > self.components.wFile,] > > > # KEA 2001-08-14 > # this was causing an assertion error with > the hybrid wxPython > > #self.components.wComponentList.SetSelection(0) > if > self.components.wComponentList.stringSelection == > "": > wClass = "" > else: > wName, wClass = > self.components.wComponentList.stringSelection.split(" > : ") > self.setValidProps(wClass) > > #self.displayComponents(self.components) > self.displayComponents(self._comp) > self.visible = True > > # KEA 2004-08-23 > # support updating of attributes without the > need > # for clicking the Update button > def on_wField_closeField(self, event): > if self.autoAttributeUpdate: > self.updateComponent() > > def on_wTextArea_closeField(self, event): > if self.autoAttributeUpdate: > self.updateComponent() > > def on_wChecked_mouseClick(self, event): > if self.autoAttributeUpdate: > self.updateComponent() > > def on_wPop_select(self, event): > if self.autoAttributeUpdate: > self.updateComponent() > > def on_wColor_mouseClick(self, event): > result = dialog.colorDialog(self, > color=util.colorFromString(self.components.wField.text)) > if result.accepted: > self.components.wField.text = > str(result.color) > if self.autoAttributeUpdate: > self.updateComponent() > > def on_wFont_mouseClick(self, event): > wName, wClass = > self.components.wComponentList.stringSelection.split(" > : ") > ##widget = self.components[wName] > widget = self._comp[wName] > f = widget.font > if f is None: > desc = > font.fontDescription(widget.GetFont()) > f = font.Font(desc) > result = dialog.fontDialog(self, f) > if result.accepted: > #color = dlg.getColor() > f = result.font > #self.components.wField.SetValue("%s;%s" > % (f, color)) > self.components.wField.text = "%s" % f > if self.autoAttributeUpdate: > self.updateComponent() > > def on_wFile_mouseClick(self, event): > path, filename = > os.path.split(self.components.wField.text) > result = dialog.openFileDialog(self, > directory=path, filename=filename) > if result.accepted: > self.components.wField.text = > util.relativePath(self._parent.filename, > result.paths[0]) > if self.autoAttributeUpdate: > self.updateComponent() > > > def addWidgetToComponentList(self, widget): > wName = widget.name > # KEA 2004-01-25 > # just use __name__, the other code must > have been something from wxPython 2.3 > #wClass = str(widget.__class__).split('.') > #self.components.wComponentList.Append(wName > + " : " + wClass[len(wClass) - 1]) > wClass = widget.__class__.__name__ > self.components.wComponentList.Append(wName > + " : " + wClass) > > # KEA 2002-02-23 > # need to redo the logic below to avoid asserts > in hybrid > # versions of wxPython, but also be cleaner > def deleteWidgetFromComponentList(self, wName, > wClass): > i = > self.components.wComponentList.GetSelection() > j = > self.components.wComponentList.FindString(wName + " > : " + wClass) > if i == -1 or i != j: > if j != -1: > > self.components.wComponentList.Delete(j) > else: > if j > 0: > > self.components.wComponentList.SetSelection(j - 1) > if j != -1: > > self.components.wComponentList.Delete(j) > if > self.components.wComponentList.GetSelection() == -1: > self.setValidProps("") > > self.hideAllBut(self.components.wField) > else: > wName, wClass = > self.components.wComponentList.stringSelection.split(" > : ") > # deselect the name from properties > list > self.setValidProps(wClass) > propName = > self.components.wPropertyList.stringSelection > if propName == "": > propName = "name" > > self.components.wPropertyList.stringSelection = > "name" > self.displayProperty(wName, wClass, > propName) > > def selectComponentList(self, wName, wClass): > > self.components.wComponentList.stringSelection = > wName + " : " + wClass > self.setValidProps(wClass) > propName = > self.components.wPropertyList.stringSelection > #print propName > === message truncated ===> > """ > __version__ = "$Revision: 1.133 $" > __date__ = "$Date: 2004/09/14 17:28:45 $" > """ > > import wx > import event > import error > import font > import graphic > import component > > > def makeNewId(id): > if id == -1: > return wx.NewId() > else: > return id > > > class WidgetSpec( component.ComponentSpec ) : > def __init__( self, name, parent, events, > subclassAttributes ) : > events.extend( event.WIDGET_EVENTS ) > attributes = { > 'id':{'presence':'optional', > 'default':-1}, > 'enabled' : { 'presence' : 'optional', > 'default' : 1 }, > 'visible' : { 'presence' : 'optional', > 'default' : 1 }, > 'foregroundColor' : { 'presence' : > 'optional', 'default' : None }, > 'backgroundColor' : { 'presence' : > 'optional', 'default' : None }, > #'helpText' : { 'presence' : 'optional', > 'default' : '' }, > 'toolTip' : { 'presence' : 'optional', > 'default' : '' }, > 'font' : { 'presence' : 'optional', > 'default' : None }, > 'position' : { 'presence' : 'optional', > 'default' : [ -1, -1 ] }, > 'anchors' : { 'presence' : 'optional', > 'default' : 'LT', 'values' : [ 'LT', 'LB', 'TR', > 'RB', 'LTR', 'LTB', 'TRB', 'LTRB' ] }, > 'size' : { 'presence' : 'optional', > 'default' : [ -1, -1 ] }, > 'userdata' : {'presence':'optional', > 'default':''} > } > attributes.update(subclassAttributes) > component.ComponentSpec.__init__( self, > name, parent, events, attributes ) > > def getMinimalResourceDict(self, name): > """ > Class method that returns the minimal > resource dictionary needed to create a component. > The spec will provide the optional > attributes when the Resource is created. > """ > return {'type':self.getName(), 'name':name} > > > class Widget(component.Component): > """ > The base class for all of our GUI controls. > Each Widget must bind itself to the wxPython > event model. When it receives an event > from wxPython, it will convert the event > to a PythonCArd event.Event ( SelectEvent, > ClickEvent, > etc ) and post the event to the EventQueue. > """ > # _spec = WidgetSpec() > > def __init__(self, aParent, aResource): > component.Component.__init__(self) > self._parent = aParent > self._resource = aResource > self._name = aResource.name > self._setUserdata(self._resource.userdata) > self._setCommand(self._resource.command) > > # KEA 2004-04-23 > # Controls are enabled and visible by > default > # so no need to enable and call Show unless > False. > if not self._resource.enabled: > self._setEnabled(self._resource.enabled) > if not self._resource.visible: > self._setVisible(self._resource.visible) > if self._resource.foregroundColor is not > None: > > self._setForegroundColor(self._resource.foregroundColor) > if self._resource.backgroundColor is not > None: > > self._setBackgroundColor(self._resource.backgroundColor) > if self._resource.toolTip != "": > self._setToolTip(self._resource.toolTip) > if self._resource.font is None: > self._font = None > else: > > self._setFont(font.Font(self._resource.font, self)) > > #------------------------------------------------------------------------------------------- > > #allow to use rsrc files which don't have > anchors defined > if hasattr(aResource, 'anchors'): > self.anchors = aResource.anchors > #added stuff here > else: > self.anchors = 'LT' > > #it seems that self._parent (i.e. panel) is > not sized properly at this point > # -> use the wxFrame as the reference > container instead > ## print self._parent.GetParent().size, > self._parent.size > self.RBPosition = > self._parent.GetParent().size[0]-self.position[0]-self.size[0], > self._parent.GetParent().size[1]-self.position[1]-self.size[1] > > > def anchorLayout(self): > """method called to re-layout the component > using anchors""" > > container = self._parent.GetParent() #the > background (wxFrame) > > if self.anchors == 'LT': > #this is the current standard handling > -> don't need to do anything > pass > > elif self.anchors == 'LB': > #change position on the y axis > self.position = (self.position[0], > > container.size[1] - > self.size[1] - self.RBPosition[1]) > > elif self.anchors == 'TR': > #change position on the x axis > self.position = (container.size[0] - > self.size[0] - self.RBPosition[0], > self.position[1]) > > elif self.anchors == 'RB': > #change position on x and y axes > self.position = (container.size[0] - > self.size[0] - self.RBPosition[0], > container.size[1] - > self.size[1] - self.RBPosition[1]) > > elif self.anchors == 'LTR': > #change size in the x-axis > self.size = (container.size[0] - > self.position[0] - self.RBPosition[0], > self.size[1]) > > elif self.anchors == 'LTB': > #change size in the y-axis > self.size = (self.size[0], > container.size[1] - > self.position[1] - self.RBPosition[1]) > > elif self.anchors == 'LBR': > #change position on the y axis > self.position = (self.position[0], > > container.size[1] - > self.size[1] - self.RBPosition[1]) > #change size in the x-axis > self.size = (container.size[0] - > self.position[0] - self.RBPosition[0], > self.size[1]) > > elif self.anchors == 'TRB': > #change position on the x axis > self.position = (container.size[0] - > self.size[0] - self.RBPosition[0], > self.position[1]) > #change size in the y-axis > self.size = (self.size[0], > container.size[1] - > self.position[1] - self.RBPosition[1]) > > elif self.anchors == 'LTRB': > # X and Y size change > self.size = (container.size[0] - > self.position[0] - self.RBPosition[0], > === message truncated ===> #!/usr/bin/python > > """ > __version__ = "$Revision: 1.3 $" > __date__ = "$Date: 2004/04/14 02:38:47 $" > """ > > from PythonCard import model > > class MyBackground(model.Background): > > def on_initialize(self, event): > # if you have any initialization > # including sizer setup, do it here > pass > > > > if __name__ == '__main__': > app = model.Application(MyBackground) > app.MainLoop() > > {'application':{'type':'Application', > 'name':'Template', > 'backgrounds': [ > {'type':'Background', > 'name':'bgTemplate', > 'title':'Standard Template with no menus', > 'size':(523, 435), > 'style':['resizeable'], > > 'components': [ > > {'type':'TextArea', > 'name':'TextArea2', > 'position':(20, 215), > 'size':(351, 107), > 'anchors':'LTRB', > 'text':'TextArea2', > }, > > {'type':'Choice', > 'name':'Choice1', > 'position':(22, 41), > 'anchors':'LT', > 'items':[], > }, > > {'type':'Tree', > 'name':'Tree1', > 'position':(394, 14), > 'size':(110, 309), > 'anchors':'LTRB', > 'backgroundColor':(255, 255, 255), > 'font':{'faceName': 'Tahoma', 'family': > 'sansSerif', 'size': 8}, > }, > > {'type':'StaticText', > 'name':'StaticText1', > 'position':(312, 13), > 'anchors':'TR', > 'text':'StaticText1', > }, > > {'type':'TextField', > 'name':'TextField1', > 'position':(20, 75), > 'size':(350, -1), > 'anchors':'LTR', > 'text':'TextField1', > }, > > {'type':'TextArea', > 'name':'TextArea1', > 'position':(20, 115), > 'size':(352, 85), > 'anchors':'LTRB', > 'text':'TextArea1', > }, > > {'type':'Button', > 'name':'Button2', > 'position':(22, 342), > 'anchors':'LB', > 'label':'Button2', > }, > > {'type':'Button', > 'name':'Button1', > 'position':(421, 340), > 'anchors':'RB', > 'label':'Button1', > }, > > ] # end components > } # end background > ] # end backgrounds > } } > Find local movie times and trailers on Yahoo! Movies. http://au.movies.yahoo.com |
From: Michael S. <mik...@ya...> - 2005-04-18 19:42:30
|
Hi, I have written some simple code to allow for anchoring of components to edges of containers. This corresponds fairly closely to a past discussion on the list http://aspn.activestate.com/ASPN/Mail/Message/pythoncard/1183899. Attached are a few files that can be run to demonstrate the concept. The code is very short and simple. I have written it based on PythonCard v0.8.1 testAnchors.py has all the layout code included in the file. You should be able to run this application without any changes to the PythonCard installation. If you update model.py, widget.py, and propertyEditor.py in your PythonCard distribution, you will be able to get testAnchors2.py to run. This should display the same example application. The anchors variable is now stored in the rsrc file (and can be set/viewed in the resource editor). The testAnchors2.py file is now nothing more than the standard file automatically created with a new application. You should be able to test your own examples simply make a new application and set the anchors property in the property editor (there should be a list of options with default of LT ie left and top- and thus if you dont change the property it will continue to act as it did before this update). Alternatively, load an existing rsrc file and alter the anchors property and save. testAnchors.py is an example that demonstrates the limitations of this approach. Components set to expand with an expanding container are greedy their increase in size is equivalent to the increase in size of the container. Hence when there are multiple components that are to change size this may cause problems. A mechanism of sharing the container size change between multiple components is necessary to deal with this. I am unsure what the simplest way of doing this is. I think it is rather confusing to set the sharing on a component by component basis. A simpler approach may be to partition the container into segments (by rows or columns), with a simple mechanism for sharing the container size changes. The components would then reference the sub containers (using anchors). I hope this is useful. If so, feel free to use the code under the same license as pythoncard. Michael Find local movie times and trailers on Yahoo! Movies. http://au.movies.yahoo.com |
From: Philippe C. M. <phi...@sb...> - 2005-04-15 23:13:40
|
Hi, I have a few pythoncard scripts that I wish to launch from another one - ex: click on button 1 == call script 1, click on button 2 = call script 2. My code looks like below and although I do not get any error, the new wndow that appears on the click event is the same as the one from the launcher. Is there a way to achieve my goal ? Regards, Philippe class MyBackground(model.Background): def on_initialize(self, event): # if you have any initialization # including sizer setup, do it here pass #******************************************************************** def on_ID_mouseClick(self, event): import corpid app = model.Application(corpid.Corp_ID_Demo) app.MainLoop() if __name__ == '__main__': app = model.Application(MyBackground) app.MainLoop() -- ************************************* Philippe C. Martin SnakeCard, LLC www.snakecard.com +1 405 694 8098 ************************************* |
From: Phil E. <ped...@mi...> - 2005-04-15 15:30:37
|
Hi All: I've just checked the latest code changes for my standaloneBuilder tool into CVS. It's been tested under Windows XP and Linux and seems to do what is required of it. Note that in order to use it in its current form, you will need to have McMillan Installer and Inno Setup installed and configured on your computer. It would be especially nice if someone could tweak it to work with py2exe as well, maybe by way of a setting in the preferences. I'll get some documentation written for it shortly, in the mean time if somebody is feeling adventurous, perhaps they could try it out and let me have any comments and/or bug reports. Kevin, for the benefit of the archives so to speak, I just want to confirm for the record that I'm donating this code in it's entirety to the PythonCard project to be re-distributed under the same license as the rest of the project. Enjoy! -- Regards Phil Edwards (ped...@mi...) Provisioning Manager Mistral Internet Phone: 0870 751 6300 Fax: 0870 751 6399 Web: http://www.mistral.net This electronic message contains information from Mistral Internet which may be privileged or confidential. The information is intended to be for the use of the individual(s) or entity named above. If you are not the intended recipient be aware that any disclosure, copying, distribution or use of the contents of this information is prohibited. If you have received this electronic message in error, please notify us by telephone or email (to the numbers or address above) immediately. |
From: Kevin A. <al...@se...> - 2005-04-12 16:05:50
|
http://c2.com/cgi/wiki?XpCodeSprint This past weekend we had a coding sprint and many people used the codeEditor and tabbed codeEditor for editing files. All the files were in cvs, and were updated many times during each hour, typically after each small change. This made it very clear that there needs to be a more effective way of identifying that a file that has changed on disk that is out of sync with the view in the editor. So I need to get feedback on what the common menu item name is for "reload file from disk", "revert to saved" or whatever. I also want suggestions for what other editors do to watch for disk changes such as you would get from cvs and then auto-reloading or presenting the user with the option for reloading from disk, perhaps changing what is displayed in the title bar as well to indicate the file has changed. Then Alex or I will update the codeEditor and tabbed codeEditor to support these features. The sprint was quite fun and should be described by Ward Cunningham and others in their blogs soon (fingers crossed). A fairly large group of people picked up the idea of creating a line of sight chess game, one person was established as the customer and then we used agile (extreme) programming practices to create the application using PythonCard with fairly quick iterations over two days, roughly one iteration every 60 to 90 minutes. As with the previous coding sprint where I introduced people to PythonCard, only one other person had used PythonCard before. This time around, while all people were seasoned coders, only a few actually knew Python, which gave us another challenge, not the least of which was getting everyone setup with Python, wxPython, and PythonCard on three different OS platforms with a somewhat shaky wireless network. Still as you can see by what is in cvs, we made a lot of progress on the model as well as the display of the game and another day would probably have been enough to fill out the missing bits. http://c2.com/cgi/wiki?LineOfSightChess http://cvs.sourceforge.net/viewcvs.py/remorse/losc/ The current plan is to finish the loschess project as a joint XPDX and PORPIG coding project and then roll it into the PythonCard samples when it is done. ka |
From: Kevin A. <al...@se...> - 2005-04-07 07:43:55
|
Begin forwarded message: > From: "Arlo" <ar...@ar...> > Date: April 4, 2005 2:50:51 PM PDT > To: pyt...@py..., po...@po..., > sea...@li... > Subject: [Porpig] Portland area Code Sprint on April 9-10 > > XP / PYTHON CODE SPRINT > > XPDX will be hosting a code sprint on April 9-10, 2005 in downtown > Portland, > Oregon. > > We're all meeting in one big room, where we'll code and talk smack > until > beer-thirty. Come pair with long-time XPers to learn their techniques > while > working on nifty Python projects. > > If you're intending to attend at least part of the sprint, please > email Arlo > Belshee (a_x...@ar...). You can also add your name to the > Sprint wiki, at http://c2.com/cgi/wiki?XpCodeSprint . > > We've currently got about 20 confirmed attendees from Oregon, > Washington, > and California. There's no headcount limit; come on down and join us > for a > weekend of coding, learning, and fun. If you can't make it for the > whole > weekend, just tell Arlo which day you can make it for. > > Many of the attendees are new to Python. Some are experts. So feel > welcome > regardless of your skill level. Also, Python integrates well with other > common languages, allowing us to easily blend in work in a number of > different areas. There will probably be projects in a number of > different > languages, such as: > > * Pure Python > * Python and C++, via boost.org's boost::python interoperability > template > library > * Python and Java, via Jython > * And probably some Smalltalk, just because > > This is not a pure XP Sprint. Please feel free to come if you've never > even > heard of the practice. Many of us will be learning it this weekend. > Also, if > you have no interest in XP, come anyway. There will be a lot of Python > coding and a variety of interesting topics. > > ----------------------------------------------------------------------- > - > > There are several potential projects for you to work on. If any of > these > catch your eye, come to the sprint ready to plow into it. If they > don't, > come on down with your own pet project - or even with no project at > all. > Someone'll grab you as a pair partner. > > http://pythoncard.sourceforge.net/ > > http://moinmoin.wikiwikiweb.de/, or MoinMoin plugins. > > http://scons.sourceforge.net/ > > http://ipodder.sourceforge.net/index.php > > Agile programming infrastructure. Some (as yet poorly defined) set of > integrated tools to allow unit testing, automated build, automated > smoke > testing, release control, SCM, and other necessary activities. > > How about a rocket telemetry data analysis or visualization tool for > http://psas.pdx.edu/? We could even provide live hardware. > > Scope, a simpler automated test framework for C++ that takes advantage > of > the features of that language. > > ----------------------------------------------------------------------- > ---- > > LOCATION AND LOGISTICS > > Critical Path Software his kindly invited us to use a floor of its > downtown > facilities for this sprint. The office is at 711 SW Alder St. in > downtown > Portland. It is about a block from Pioneer Courthouse Square, so is an > easy > MAX ride from many places in the city. > > The code sprint will run on April 9th and 10th. We will start each day > at > 10:00, and run until evening. Saturday night, several of us will > probably > troop on down to one of the local beer establishments. > > Arlo Belshee is organizing this event. If you have questions, you may > contact him via email at a_x...@ar.... > > Arlo > > > > _______________________________________________ > Porpig mailing list > Po...@po... > http://lists.porpig.org/mailman/listinfo/porpig > |
From: Kevin A. <al...@se...> - 2005-04-05 18:50:12
|
I've checked in the changes suggested by Bob Ippolito. The new setup.py file looks like... from distutils.core import setup import sys if sys.platform == 'darwin': import py2app buildstyle = 'app' else: import py2exe buildstyle = 'console' setup( name = "minimal", data_files = [ (".", ["readme.txt", "minimal.rsrc.py"]) ], **{buildstyle: ["minimal.py"]} ) ka Begin forwarded message: > From: "Bob Ippolito" <bo...@re...> > Date: March 23, 2005 4:04:42 PM PST > To: al...@se... > Subject: PythonCard and py2app > > Using svn head of py2app (r436 or later), the following diff will > allow minimalStandalone's setup.py to build for both py2exe and > py2app. > > -bob > > > =================================================================== > RCS file: > /cvsroot/pythoncard/PythonCard/samples/minimalStandalone/setup.py,v > retrieving revision 1.2 > diff -u -r1.2 setup.py > --- setup.py 26 Mar 2004 16:37:37 -0000 1.2 > +++ setup.py 24 Mar 2005 00:01:09 -0000 > @@ -12,10 +12,16 @@ > """ > > from distutils.core import setup > -import py2exe > +import sys > +if sys.platform == 'darwin': > + import py2app > + buildstyle = 'app' > +else: > + import py2exe > + buildstyle = 'console' > > setup( name = "minimal", > - console = ["minimal.py"], > - data_files = [ (".", ["readme.txt", "minimal.rsrc.py"]) ] > + data_files = [ (".", ["readme.txt", "minimal.rsrc.py"]) ], > + **{buildstyle: ["minimal.py"]} > ) > > |
From: Kevin A. <al...@se...> - 2005-04-04 18:15:27
|
On Apr 4, 2005, at 9:52 AM, Kevin Altis wrote: > > I don't know why this never came up before, but I bet there is a > problem if you want to have a component named parent, data, or order, > so I probably need to test that, then change them to have leading > underscores or something like that in the future, which also means > updating the resourceEditor and perhaps some other tools. I'm not sure > if I'll get to that this week before I leave for the UK or not. > I retract this last part. Given that there are a number of methods and attributes that should be "protected" it makes more sense to change the places where you can set the component name to present an error dialog that disallows the "protected" names for methods and internal attributes. I think that would just be the strings in the list returned by dir() since the component names are really in the internal item 'data' and don't get exposed by dir. >>> dir(self.components) ['__cmp__', '__contains__', '__delitem__', '__doc__', '__getattr__', '__getitem__', '__init__', '__len__', '__module__', '__repr__', '__setattr__', '__setitem__', '_getAttributeNames', '_listeners', 'addChangeEventListener', 'clear', 'copy', 'data', 'fireChanged', 'fromkeys', 'get', 'has_key', 'items', 'iteritems', 'iterkeys', 'itervalues', 'keys', 'order', 'parent', 'pop', 'popitem', 'setdefault', 'update', 'values'] So the code to protect invalid names just has to do if name in dir(self.components): # alert dialog, etc. here asking for a different name Anyone see a problem with this? The __setitem__ method could also protect itself and throw an exception if we get a component name that would cause a problem. BTW, these developer type issues will very soon start appearing only on the pythoncard-devel mailing list for those of you that want to be involved in this kind of stuff and want to sign-up. http://lists.sourceforge.net/lists/listinfo/pythoncard-devel I just submitted a request to gmane to add gmane.comp.python.pythoncard.devel as well. ka |
From: Kevin A. <al...@se...> - 2005-03-09 08:53:25
|
We are good to go! ka |