class Rtml::Widgets::HighlevelVariableProcessing < Rtml::Widget affects :screen entry_point :terminal_variables, :tvars, :_if, :_elsif, :_else, :_end shared :setvars => Rtml::HighLevel::VariableManager.new disable_subprocessing! # Provides a higher-level conditional construct as an alternative to using next and variant tags to generate # a TML branch. # # Examples: # screen :main do # _if(tvars[:amount] == 0) { goto :amount_too_low } # _elsif(tvars[:amount] > 10000) { goto :amount_too_high } # _else { goto :swipe_card } # end # def _if(condition, &block) scrid = "#{parent.property('id')}_if" conditional_goto(scrid, condition, &block) end # Provides a higher-level conditional construct as an alternative to using next and variant tags to generate # a TML branch. # # Examples: # screen :main do # _if(tvars[:amount] == 0) { goto :amount_too_low } # _elsif(tvars[:amount] > 10000) { goto :amount_too_high } # _else { goto :swipe_card } # end # def _elsif(condition, &block) scrid = "#{parent.property('id')}_elsif" conditional_goto(scrid, condition, &block) end alias _elseif _elsif # Provides a higher-level conditional construct as an alternative to using next and variant tags to generate # a TML branch. # # Examples: # screen :main do # _if(tvars[:amount] == 0) { goto :amount_too_low } # _elsif(tvars[:amount] > 10000) { goto :amount_too_high } # _else { goto :swipe_card } # end # def _else(&block) scrid = "#{parent.property('id')}_else" conditional_goto(scrid, nil, &block) end # Returns a handle to the list of TML variables. Follow this with an array operator to access and manipulate # the variable assignments for this screen. # # You can use the alias #tvars for shorthand access to this method. # # Examples: # screen :init do => # terminal_variables[:amount] = 0 => # terminal_variables[:first_name] = 'John' => # terminal_variables[:last_name] = 'Smith' => # terminal_variables[:full_name] = tvars[:first_name] + => op="plus" ro="tmlvar:last_name" /> # end => # # You can also use periods instead of array operators to do the same thing: # # Examples: # screen :init do => # terminal_variables.amount = 0 => # terminal_variables.first_name = 'John' => # terminal_variables.last_name = 'Smith' => # terminal_variables.full_name = tvars.first_name + => op="plus" ro="tmlvar:last_name" /> # end => def terminal_variables setvars.screen ||= parent setvars end alias tvars terminal_variables alias tml terminal_variables private def conditional_goto(scrid, condition, &blk) unless (document.root / "screen[id='#{scrid}']").empty? scrid = "#{scrid}_#{widget_id}" end destination = parent.property('next') || ((c = parent / 'next').empty? ? 'assert' : c.first.property('uri')) if condition.nil? parent.goto scrid parent.property('next', nil) else parent.goto scrid, :if => condition end r = document.screen(scrid, :next => destination) method_name = "method_wrapper_for_#{scrid}" block = blk (class << r; self; end).instance_eval do define_method method_name, &block new_method = instance_method(method_name) define_method method_name do new_method.bind(self).call end end ret = r.send(method_name) if r.elements.length == 1 && (nxt = r.elements.first).name == 'next' && nxt.elements.empty? # all user did was "goto" -- that should result in a variant in parent, not a whole new screen. # This is mostly for TML legibility. if condition.blank? parent.goto nxt.property('uri') else parent.goto nxt.property('uri'), :if => condition end document.remove_screen(r) end ret # r end def document @document ||= parent.document end end