📄 lisp_codegen.py
字号:
def _string_to_colour(s): return '%d %d %d' % (int(s[1:3], 16), int(s[3:5], 16), int(s[5:], 16))def generate_code_foreground(obj): """\ returns the code fragment that sets the foreground colour of the given object. """ global import_packages self = _get_code_name(obj) try: color = cn('(wxColour_CreateRGB ') + '%s)' % \ _string_to_colour(obj.properties['foreground']) except (IndexError, ValueError): # the color is from system settings color = cn('(wxSystemSettings_GetColour ') + '%s)' % \ cn(obj.properties['foreground']) import_packages = import_packages | set(['wxColour']) return self + '(wxWindow_SetForegroundColour %s %s)\n' % (self,color)def generate_code_background(obj): """\ returns the code fragment that sets the background colour of the given object. """ global import_packages self = _get_code_name(obj) try: color = ('(wxColour_CreateRGB ') + '%s)' % \ _string_to_colour(obj.properties['background']) except (IndexError, ValueError): # the color is from system settings color = cn('(wxSystemSettings_GetColour ') + '%s)' % \ cn(obj.properties['background']) import_packages = import_packages | set(['wxColour']) print import_packages return '(wxWindow_SetBackgroundColour %s %s)\n' % (self,color)def generate_code_font(obj): """\ returns the code fragment that sets the font of the given object. """ global import_packages font = obj.properties['font'] size = font['size'] family = cn(font['family']) underlined = font['underlined'] style = cn(font['style']) weight = cn(font['weight']) face = '"%s"' % font['face'].replace('"', r'\"') self = _get_code_name(obj) import_packages = import_packages | set(['wxFont']) return ('(wxWindow_SetFont %s (wxFont_Create %s %s %s %s %s %s wxFONTENCODING_DEFAULT))\n' % (self, size, family, style, weight, underlined, face))def generate_code_id(obj, id=None): """\ returns a 2-tuple of strings representing the LOC that sets the id of the given object: the first line is the declaration of the variable, and is empty if the object's id is a constant, and the second line is the value of the id """ if obj and obj.preview: return '', '-1' # never generate ids for preview code if id is None: id = obj.properties.get('id') if id is None: return '', '-1' tokens = id.split('=') if len(tokens) > 1: name, val = tokens[:2] else: return '', tokens[0] # we assume name is declared elsewhere if not name: return '', val if val.strip() == '?': val = cn('wxNewId()') # check to see if we have to make the var global or not... name = name.strip() val = val.strip() if '.' in name: return ('%s = %s\n' % (name, val), name) return ('global %s; %s = %s\n' % (name, name, val), name)def generate_code_tooltip(obj): """\ returns the code fragment that sets the tooltip of the given object. """ self = _get_code_name(obj) return '(wxWindow_SetToolTip ' + self + '%s)\n' % \ quote_str(obj.properties['tooltip'])def generate_code_disabled(obj): self = _get_code_name(obj) try: disabled = int(obj.properties['disabled']) except: disabled = False if disabled: return '(wxWindow_IsEnabled ' + self + '0)\n'def generate_code_focused(obj): self = _get_code_name(obj) try: focused = int(obj.properties['focused']) except: focused = False if focused: return '(wxWindow_SetFocus ' + self + ')\n'def generate_code_hidden(obj): self = _get_code_name(obj) try: hidden = int(obj.properties['hidden']) except: hidden = False if hidden: return '(wxWindow_Hide ' + self + ')\n' def generate_common_properties(widget): """\ generates the code for various properties common to all widgets (background and foreground colors, font, ...) Returns a list of strings containing the generated code """ prop = widget.properties out = [] if prop.get('size', '').strip(): out.append(generate_code_size(widget)) if prop.get('background'): out.append(generate_code_background(widget)) if prop.get('foreground'): out.append(generate_code_foreground(widget)) if prop.get('font'): out.append(generate_code_font(widget)) # tooltip if prop.get('tooltip'): out.append(generate_code_tooltip(widget)) # trivial boolean properties if prop.get('disabled'): out.append(generate_code_disabled(widget)) if prop.get('focused'): out.append(generate_code_focused(widget)) if prop.get('hidden'): out.append(generate_code_hidden(widget)) return out# custom property handlersclass FontPropertyHandler: """Handler for font properties""" font_families = { 'default': 'wxDEFAULT', 'decorative': 'wxDECORATIVE', 'roman': 'wxROMAN', 'swiss': 'wxSWISS', 'script': 'wxSCRIPT', 'modern': 'wxMODERN', 'teletype': 'wxTELETYPE' } font_styles = { 'normal': 'wxNORMAL', 'slant': 'wxSLANT', 'italic': 'wxITALIC' } font_weights = { 'normal': 'wxNORMAL', 'light': 'wxLIGHT', 'bold': 'wxBOLD' } def __init__(self): self.dicts = { 'family': self.font_families, 'style': self.font_styles, 'weight': self.font_weights } self.attrs = { 'size': '0', 'style': '0', 'weight': '0', 'family': '0', 'underlined': '0', 'face': '' } self.current = None self.curr_data = [] def start_elem(self, name, attrs): self.curr_data = [] if name != 'font' and name in self.attrs: self.current = name else: self.current = None def end_elem(self, name, code_obj): if name == 'font': code_obj.properties['font'] = self.attrs return True elif self.current is not None: decode = self.dicts.get(self.current) if decode: val = decode.get("".join(self.curr_data), '0') else: val = "".join(self.curr_data) self.attrs[self.current] = val def char_data(self, data): self.curr_data.append(data)# end of class FontPropertyHandlerclass DummyPropertyHandler: """Empty handler for properties that do not need code""" def start_elem(self, name, attrs): pass def end_elem(self, name, code_obj): return True def char_data(self, data): pass# end of class DummyPropertyHandlerclass EventsPropertyHandler(object): def __init__(self): self.handlers = {} self.event_name = None self.curr_handler = [] def start_elem(self, name, attrs): if name == 'handler': self.event_name = attrs['event'] def end_elem(self, name, code_obj): if name == 'handler': if self.event_name and self.curr_handler: self.handlers[self.event_name] = ''.join(self.curr_handler) self.event_name = None self.curr_handler = [] elif name == 'events': code_obj.properties['events'] = self.handlers return True def char_data(self, data): data = data.strip() if data: self.curr_handler.append(data)# end of class EventsPropertyHandler # dictionary whose items are custom handlers for widget properties_global_property_writers = { 'font': FontPropertyHandler, 'events': EventsPropertyHandler, }# dictionary of dictionaries of property handlers specific for a widget# the keys are the class names of the widgets# Ex: _property_writers['wxRadioBox'] = {'choices', choices_handler}_property_writers = {}# map of widget class names to a list of extra modules needed for the# widget. Example: 'wxGrid': 'from wxLisp.grid import *\n'_widget_extra_modules = {}# set of lines of extra modules to add to the current file_current_extra_modules = {} def get_property_handler(property_name, widget_name): try: cls = _property_writers[widget_name][property_name] except KeyError: cls = _global_property_writers.get(property_name, None) if cls: return cls() return Nonedef add_property_handler(property_name, handler, widget_name=None): """\ sets a function to parse a portion of XML to get the value of the property property_name. If widget_name is not None, the function is called only if the property in inside a widget whose class is widget_name """ if widget_name is None: _global_property_writers[property_name] = handler else: try: _property_writers[widget_name][property_name] = handler except KeyError: _property_writers[widget_name] = { property_name: handler }class WidgetHandler: """\ Interface the various code generators for the widgets must implement """ """list of modules to import (eg. ['from wxLisp.grid import *\n'])""" import_modules = [] def get_code(self, obj): """\ Handler for normal widgets (non-toplevel): returns 3 lists of strings, init, properties and layout, that contain the code for the corresponding methods of the class to generate """ return [], [], [] def get_properties_code(self, obj): """\ Handler for the code of the set_properties method of toplevel objects. Returns a list of strings containing the code to generate """ return [] def get_init_code(self, obj): """\ Handler for the code of the constructor of toplevel objects. Returns a list of strings containing the code to generate. Usually the default implementation is ok (i.e. there are no extra lines to add). The generated lines are appended at the end of the constructor """ return [] def get_layout_code(self, obj): """\ Handler for the code of the do_layout method of toplevel objects. Returns a list of strings containing the code to generate. Usually the default implementation is ok (i.e. there are no extra lines to add) """ return []# end of class WidgetHandlerdef add_widget_handler(widget_name, handler): obj_builders[widget_name] = handlerdef setup(): """\ Code generator setup function. This is called once, when the code generator is loaded in wxglade. """ # scan widgets.txt for widgets, load lisp_codegen's _widgets_dir = os.path.join(common.wxglade_path, 'widgets') widgets_file = os.path.join(_widgets_dir, 'widgets.txt') if not os.path.isfile(widgets_file): print >> sys.stderr, "widgets file (%s) doesn't exist" % widgets_file return import sys sys.path.append(_widgets_dir) modules = open(widgets_file) for line in modules: module_name = line.strip() if not module_name or module_name.startswith('#'): continue module_name = module_name.split('#')[0].strip() try: m = __import__(module_name + '.lisp_codegen', {}, {}, ['initialize']) m.initialize() except (ImportError, AttributeError): pass## print 'ERROR loading "%s"' % module_name## import traceback;## traceback.print_exc()## else:## print 'initialized lisp generator for ', module_name modules.close() # ...then, the sizers import edit_sizers.lisp_sizers_codegen edit_sizers.lisp_sizers_codegen.initialize()
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -