assets/src/ruboto/widget.rb in ruboto-1.1.2 vs assets/src/ruboto/widget.rb in ruboto-1.2.0

- old
+ new

@@ -15,12 +15,66 @@ # Prepare View # java_import 'android.view.View' +# Set an attribute value by name on the given target. This method is used by +# all the widget methods generated by "ruboto_import_widget" and +# "ruboto_import_widgets": +# +# button text: 'Click me!', layout: {weight: 1, gravity: :center} +# +# The attribute can be a public field, a JavaBean attribute, or a setter method. +# +# set_attribute button, :text, 'Click me!' +# set_attribute button.layout_attributes, :weight, 1 +# +# The given attribute name can match the attribute name exactly or be accessed +# by the snake_case version of the attribute. It can also be accessed by the +# setter name, either snake_case or camelCase. +# +# set_attribute button, :textAlignment, android.view.View::TEXT_ALIGNMENT_CENTER +# set_attribute button, :text_alignment, android.view.View::TEXT_ALIGNMENT_CENTER +# set_attribute button, :set_text_alignment, android.view.View::TEXT_ALIGNMENT_CENTER +# set_attribute button, :setTextAlignment, android.view.View::TEXT_ALIGNMENT_CENTER +# +# You can use symbols as values for common constants. Currently constants for +# the following classes are enabled using symbols: +# +# * android.view.Gravity +# * android.view.ViewGroup::LayoutParams +# * android.widget.LinearLayout +# * android.widget.RelativeLayout +# +# set_attribute button, :text_alignment, :text_alignment_center +# set_attribute button.layout_attributes, :gravity, :center +# set_attribute button.layout_attributes, :width, :fill_parent +# +# Integer values in the range 0x80000000..0xFFFFFFFF are converted to a negative +# Integer value enabling setting of 4-byte color values as Ruby integer literals. +# +# set_attribute button, :background_color, 0x0000FF00 +# +# You can use an array as a value for multi-value attributes like margins and +# padding. +# +# set_attribute button, :padding, [10, 20, 10, 30] +# +def set_attribute(target, k, v) + assign_method = "#{k}=" + field_assign_method = "#{k.to_s.gsub(/(_)([a-z])/) { $2.upcase }}=" + setter_method = "set#{k.to_s.gsub(/(^|_)([a-z])/) { $2.upcase }}" + method_name = + (target.respond_to?(assign_method) && assign_method) || + (target.respond_to?(field_assign_method) && field_assign_method) || + (target.respond_to?(setter_method) && setter_method) || + k + invoke_with_converted_arguments(target, method_name, v) +end + def invoke_with_converted_arguments(target, method_name, values) - converted_values = [*values].map { |i| @@convert_constants[i] || i } + converted_values = [*values].map { |i| View.convert_constant(i) } scaled_values = converted_values.map.with_index do |v, i| v.is_a?(Integer) && v >= 0x80000000 && v <= 0xFFFFFFFF ? v.to_i - 0x100000000 : v end target.send(method_name, *scaled_values) @@ -28,81 +82,70 @@ View.class_eval do @@convert_constants ||= {} def self.add_constant_conversion(from, to) - @@convert_constants[from] = to + symbol = from.to_s.downcase.to_sym + if @@convert_constants.include?(symbol) + puts "WARNING: Overwriting symbol to constant conversion for #{symbol.inspect}: #{@@convert_constants[symbol].inspect} => #{to.inspect}" + end + @@convert_constants[symbol] = to end def self.convert_constant(from) return from unless from.is_a?(Symbol) - @@convert_constants[from] or raise "Symbol #{from.inspect} doesn't have a corresponding View constant #{from.to_s.upcase}" + unless @@convert_constants.include?(from) + raise "Symbol #{from.inspect} doesn't have a corresponding View constant #{from.to_s.upcase}." + end + @@convert_constants[from] end def self.setup_constant_conversion (self.constants - self.superclass.constants).each do |i| - View.add_constant_conversion i.downcase.to_sym, self.const_get(i) + View.add_constant_conversion i, self.const_get(i) end end def configure(context, params = {}) - if width = params.delete(:width) + if (width = params.delete(:width)) getLayoutParams.width = View.convert_constant(width) puts "\nDEPRECATION: The ':width' option is deprecated. Use :layout => {:width => XX} instead." end - if height = params.delete(:height) + if (height = params.delete(:height)) getLayoutParams.height = View.convert_constant(height) - puts "\nDEPRECATION: The ':height' option is deprecated. Use :height => {:width => XX} instead." + puts "\nDEPRECATION: The ':height' option is deprecated. Use :layout => {:height => XX} instead." end - if margins = params.delete(:margins) + if (margins = params.delete(:margins)) getLayoutParams.set_margins(*margins) - puts "\nDEPRECATION: The ':margins' option is deprecated. Use :layout => {:margins => XX} instead." + puts "\nDEPRECATION: The ':margins' option is deprecated. Use :layout => {:margins => [L, T, R, B]} instead." end - if layout = params.delete(:layout) + if (layout = params.delete(:layout)) lp = getLayoutParams - layout.each do |k, v| - method_name = k.to_s - if lp.respond_to?("#{k}=") - method_name = "#{k}=" - elsif method_name.include?("_") - method_name = method_name.gsub(/_([a-z])/){$1.upcase} - method_name = "#{method_name}=" if lp.respond_to?("#{method_name}=") - end - - invoke_with_converted_arguments(lp, method_name, v) - end + layout.each { |k, v| set_attribute(lp, k, v) } end - params.each do |k, v| - setter_method = "set#{k.to_s.gsub(/(^|_)([a-z])/) { $2.upcase }}" - assign_method = "#{k}=" - method_name = self.respond_to?(assign_method) ? assign_method : - (self.respond_to?(setter_method) ? setter_method : k) - invoke_with_converted_arguments(self, method_name, v) - end + params.each { |k, v| set_attribute(self, k, v) } end end # # Load ViewGroup constants # - java_import 'android.view.ViewGroup' ViewGroup::LayoutParams.constants.each do |i| - View.add_constant_conversion i.downcase.to_sym, ViewGroup::LayoutParams.const_get(i) + View.add_constant_conversion i, ViewGroup::LayoutParams.const_get(i) end # # Load Gravity constants # - java_import 'android.view.Gravity' Gravity.constants.each do |i| - View.add_constant_conversion i.downcase.to_sym, Gravity.const_get(i) + View.add_constant_conversion i, Gravity.const_get(i) end # # RubotoActivity View Generation # @@ -188,19 +231,19 @@ def setup_list_view android.widget.ListView.__persistent__ = true android.widget.ListView.class_eval do def configure(context, params = {}) if (list = params.delete(:list)) - item_layout = params.delete(:item_layout) || R::layout::simple_list_item_1 + item_layout = params.delete(:item_layout) || android.R::layout::simple_list_item_1 params[:adapter] = android.widget.ArrayAdapter.new(context, item_layout, list) end super(context, params) end def reload_list(list) - @adapter_list.clear - @adapter_list.addAll(list) + adapter.clear + adapter.addAll(list) adapter.notifyDataSetChanged invalidate end end end @@ -209,20 +252,20 @@ android.widget.Spinner.__persistent__ = true android.widget.Spinner.class_eval do def configure(context, params = {}) if (list = params.delete(:list)) item_layout = params.delete(:item_layout) - params[:adapter] = android.widget.ArrayAdapter.new(context, item_layout || R::layout::simple_spinner_item, list) + params[:adapter] = android.widget.ArrayAdapter.new(context, item_layout || android.R::layout::simple_spinner_item, list) dropdown_layout = params.delete(:dropdown_layout) params[:adapter].setDropDownViewResource(dropdown_layout) if dropdown_layout end super(context, params) end def reload_list(list) - @adapter.clear - @adapter.addAll(list) - @adapter.notifyDataSetChanged + adapter.clear + adapter.addAll(list) + adapter.notifyDataSetChanged invalidate end end end