Class: XRC2Ruby::Parser

Inherits:
Object
  • Object
show all
Includes:
REXML::StreamListener, ObjectTypes
Defined in:
lib/wx_sugar/xrc/xrc2ruby.rb

Overview

The parser goes through the XRC file and identifies top-level frames/dialogs and their child windows. Each window is turned into an instance of an ObjectType class; sizers and sizer settings are also stored. Each ObjectType stores the parameters associated with that specific type of window, and then can later output the wxRuby code to create that window.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeParser

Returns a new instance of Parser.



40
41
42
# File 'lib/wx_sugar/xrc/xrc2ruby.rb', line 40

def initialize
  @stack = []
end

Instance Attribute Details

#stackObject (readonly)

The stack of all objects found - pushed onto when the tag opens, popped off when the tag closes



38
39
40
# File 'lib/wx_sugar/xrc/xrc2ruby.rb', line 38

def stack
  @stack
end

Instance Method Details

#last_parentObject

The most recent parent



45
46
47
# File 'lib/wx_sugar/xrc/xrc2ruby.rb', line 45

def last_parent
  @stack.reverse.find { | obj | obj.kind_of? Parent }
end

#last_sizerObject

The most recent sizer



50
51
52
# File 'lib/wx_sugar/xrc/xrc2ruby.rb', line 50

def last_sizer
  @stack.reverse.find { | obj | obj.kind_of? Sizer }
end

#tag_end(tag) ⇒ Object

Process a tag ending



108
109
110
111
112
113
114
115
116
117
118
119
# File 'lib/wx_sugar/xrc/xrc2ruby.rb', line 108

def tag_end(tag)
  case tag
  when 'object'
    if stack.last.kind_of?(SizerItem)
      last_parent.size_child(@stack.last)
    end
    if stack.length == 1
      puts stack.first.output
    end
    @stack.pop
  end
end

#tag_start(tag, attrs) ⇒ Object

Process a tag opening



55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
# File 'lib/wx_sugar/xrc/xrc2ruby.rb', line 55

def tag_start(tag, attrs)
  case tag
  when 'resource' 
    # Top-level tag, ignore
  when 'object' # Some kind of object
    case attrs['class']
    # A set of sizer settings
    when 'sizeritem'
      stack.push( SizerItem.new(last_sizer) )

    # Some "special" object not corresponding to a standard class
    when 'panewindow', 'tool', 'separator', 'button'
      special = ObjectTypes.const_get(attrs['class'].upcase)
      stack.push( special.new(last_parent, attrs['name']) )
    # An ordinary window
    when /^wx/
      # Look up the correct representation for this object type
      kls = ObjectTypes.const_get(attrs['class'][2..-1])
      # Create and link to parent
      win = kls.new( last_parent,
                     attrs["class"], 
                     attrs["subclass"],
                     attrs["name"])

      if last_parent
        last_parent.add_child(win)
      end

      # Associate this with the containing sizer item, if there is one
      if stack.last.kind_of?(SizerItem)
        stack.last.window = win
      end
      stack.push(win)
    else
      Kernel.raise "Unexpected object of type '#{attrs['class']}' found"
    end
  else # All other tags are type-specific settings for the current tag
    @next_setting = "#{tag}="
  end
end

#text(text) ⇒ Object

When text is encountered, if non-empty it should be the value for a setting (eg <label> within a wxButton tag)



98
99
100
101
102
103
104
105
# File 'lib/wx_sugar/xrc/xrc2ruby.rb', line 98

def text(text)
  # Ignore empty
  return if text =~ /\A\s*\z/
  if @next_setting
    @stack.last.send(@next_setting, text)
  end
  @next_setting = nil
end