# page format: {:uuid=>"9f7b8942-82ee-4695-8a61-d95f15f5dba3", :type=>:structure, :ufs=>:"org.gxg.gui.page", :title=>"Page", :version=>0.0, :mime_types=>"", :content=>{:component_type=>"page", :publish_path=>"", :background_uuid=>"", :menubar_uuid=>"", :attributes=>{}, :classes=>"", :style=>{}, :browsing=>{:draggable=>{}, :droppable=>{}, :resizable=>{}, :selectable=>{}, :sortable=>{}, :tool_tip=>{}, :alt_text=>""}, :authoring=>{:draggable=>{}, :droppable=>{}, :resizable=>{}, :selectable=>{}, :sortable=>{}, :tool_tip=>{}, :alt_text=>""}, :options=>{}, :value=>nil, :script=>"", :sub_components=>[]}} # # component format: {:uuid=>:"c44d8b14-1a97-4c6f-b07a-6999ca310241", :type=>:structure, :ufs=>:"org.gxg.gui.component", :title=>"Gui Component", :version=>0.0, :mime_types=>[], :content=>{:component_type=>"unspecified", :attributes=>{}, :classes=>"", :style=>{}, :browsing=>{:draggable=>{}, :droppable=>{}, :resizable=>{}, :selectable=>{}, :sortable=>{}, :tool_tip=>{}, :alt_text=>""}, :authoring=>{:draggable=>{}, :droppable=>{}, :resizable=>{}, :selectable=>{}, :sortable=>{}, :tool_tip=>{}, :alt_text=>""}, :options=>{}, :value=>nil, :script=>"", :sub_components=>[]}} #{ # :component_type => "page", # :publish_path => "", # :background_uuid => "", # :menubar_uuid => "", # :attributes => {}, # :classes => "", # :style => {}, # :browsing => {:draggable => {}, :droppable => {}, :resizable => {}, :selectable => {}, :sortable => {}, :tool_tip => {}, :alt_text => ""}, # :authoring => {:draggable => {}, :droppable => {}, :resizable => {}, :selectable => {}, :sortable => {}, :tool_tip => {}, :alt_text => ""}, # :options => {}, # :value => nil, # :script => "", # :sub_components => [] #} module GxG DISPLAY_DETAILS = {:host_path => "", :use_ssl => false, :connection => nil, :object => nil, :mode => :browsing} module Css @@CssCache = [] @@CssRuleProperties = {} # class CSSRule # Provide EASY interface to native CSS Rule. def initialize(the_native_rule) @native_rule = the_native_rule @name = (`#{@native_rule}.selectorText` || "").to_s.to_sym end # def native_object() @native_rule end # def inspect() "" end # def name() @name end # def keys() GxG::Css::valid_properties() end # def [](the_key) result = nil csskey = @@CssRuleProperties[(the_key)] if csskey result = `#{@native_rule}.style[#{csskey}]` end result end # def []=(the_key, the_value) # csskey = @@CssRuleProperties[(the_key)] if csskey `#{@native_rule}.style[#{csskey}] = #{(the_value || "")}` else # ignore invalid keys end the_value end # def merge(properties={}) properties.keys.each do |the_key| self[(the_key)] = properties[(the_key)] end self end # end # def self.refresh_css_cache() sheets = `document.styleSheets.length`.to_i if sheets > 0 new_cache = [] (0..(sheets - 1)).each do |sheet_index| begin ruleset = `document.styleSheets[#{sheet_index}].cssRules` rescue Exception => the_error ruleset = `document.styleSheets[#{sheet_index}].rules` end if ruleset rules = (`#{ruleset}.length`.to_i) if rules > 0 (0..(rules - 1)).each do |rule_index| begin native_rule = `document.styleSheets[#{sheet_index}].cssRules[#{rule_index}]` rescue Exception => the_error native_rule = `document.styleSheets[#{sheet_index}].rules[#{rule_index}]` end if native_rule new_cache << GxG::Css::CSSRule.new(native_rule) if @@CssRuleProperties.size == 0 `Object.keys(#{native_rule}.style)`.each do |the_property_label| if the_property_label if ["0", "1", "3", "4", "5", "6", "7", "8", "9"].include?(the_property_label[0]) the_key = the_property_label.to_sym else key_text = (the_property_label[0].capitalize + the_property_label[1..-1]).split_camelcase if key_text.is_a?(String) key_text = [(key_text)] end the_key = key_text.join("-").downcase.to_sym end unless @@CssRuleProperties.keys.include?(the_key) @@CssRuleProperties[(the_key)] = the_property_label.to_s end end end end # end end end end end @@CssCache = new_cache end true end # def self.valid_properties() @@CssRuleProperties.keys end # def self.get_property_name(the_key=nil) result = nil if the_key.is_a?(::Symbol) result = @@CssRuleProperties[(the_key)] end result end # def self.rules() result = [] @@CssCache.each do |entry| result << entry.name end result end # def self.find_rule(the_rule_selector=nil) result = [] @@CssCache.each do |entry| if entry.name == (the_rule_selector.to_s.to_sym) result << entry end end result end # def self.set_rule(the_rule_selector=nil, the_properties={}, options={:merge => true}) # find existing # overwrite or merge (options) # create if non-existent found = GxG::Css::find_rule(the_rule_selector) if found.size > 0 found.each do |the_rule_entry| the_rule = the_rule_entry.values[0] if options[:overwrite] == true @@CssRuleProperties.keys.each do |clear_key| unless the_properties.keys.include?(clear_key) `#{the_rule.native_object()}.style[#{@@CssRuleProperties[(clear_key)]}] = ""` end end end the_properties.keys.each do |the_key| csskey = @@CssRuleProperties[(the_key)] if csskey `#{the_rule.native_object()}.style[#{csskey}] = #{the_properties[(the_key)]}` else # ignore invalid keys end end end else # create it rule_body = {} the_properties.keys.each do |property_key| csskey = @@CssRuleProperties[(property_key)] if csskey rule_body[(csskey)] = the_properties[(property_key)] end end sheet_index = (`document.styleSheets.length`.to_i - 1) rules = `document.styleSheets[#{sheet_index}].cssRules` until rules do sheet_index -= 1 if sheet_index < 0 rules = nil break end rules = `document.styleSheets[#{sheet_index}].cssRules` end if rules # rule_index = (`#{rules}.length`.to_i - 1) response_code = `document.styleSheets[#{sheet_index}].addRule(#{the_rule_selector},"",#{rule_index})`.to_i if response_code == -1 begin native_rule = `document.styleSheets[#{sheet_index}].cssRules[#{rule_index}]` rescue Exception => the_error native_rule = `document.styleSheets[#{sheet_index}].rules[#{rule_index}]` end the_properties.keys.each do |property_key| csskey = @@CssRuleProperties[(property_key)] if csskey `#{native_rule}.style[#{csskey}] = #{the_properties[(property_key)]}` end end @@CssCache << GxG::Css::CSSRule.new(native_rule) end end end true end # def self.remove_rule(the_rule_selector=nil) found_indexes = [] @@CssCache.each_with_index do |entry, index| if entry.name == the_rule_selector.to_s.to_sym found_indexes << index end end found = [] found_indexes.reverse.each do |the_index| found << @@CssCache.delete_at(the_index) end if found.size > 0 found.each do |the_rule| native_rule = the_rule.native_object() the_sheet = `#{native_rule}.parentStyleSheet` if the_sheet rule_count = `#{the_sheet}.cssRules.length`.to_i if rule_count > 0 (0..(rule_count - 1)).to_a.reverse.each do |rule_index| other_native_rule = `#{the_sheet}.cssRules[#{rule_index}]` if other_native_rule if `#{native_rule}.selectorText == #{other_native_rule}.selectorText` `#{the_sheet}.deleteRule(#{rule_index})` end end end end end end true else false end end # end # module Graphics class WebGL # end # class Svg # end # class Canvas # end end # module Gui # class Display # There is typically only one of these instantiated. # url('data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7'); def self.valid_properties() GxG::Css::valid_properties() end # def initialize(settings={}) if GxG::DISPLAY_DETAILS[:object].is_a?(GxG::Gui::Display) raise Exception, "Display has already been constructed." else @uuid = (settings[:uuid] || GxG::uuid_generate) @remote_uuid = nil @channel = nil @update_queue = [] @document = ::Document @dom_object = ::Element.find('body') # @attributes = {} @classes = "" @style = {} @browsing = {:draggable => {}, :droppable => {}, :resizable => {}, :selectable => {}, :sortable => {}, :tool_tip => {}, :alt_text => ""} @authoring = {:draggable => {}, :droppable => {}, :resizable => {}, :selectable => {}, :sortable => {}, :tool_tip => {}, :alt_text => ""} @options = {} @value = nil # @update_timer = post_event_periodic(0.333) do self.transmit_update() end GxG::DISPLAY_DETAILS[:object] = self GxG::register(self) GxG::Css::refresh_css_cache() end self end # def uuid() @uuid end # def set_remote_uuid(the_uuid=nil) if the_uuid @remote_uuid = the_uuid end end # def dom_object() @dom_object end # def establish_dom_link() # No-op : already establish end # def channel() @channel end # def set_channel(the_channel=nil) @channel = the_channel end # def export_display(local_export=false) # Export entire key-frame of display state data. # build up export db pairs: export_db = [] link_db = [(self)] while link_db.size > 0 do entry = link_db.shift parent = GxG::parent_of(entry) if parent new_record = {:uuid => entry.uuid.to_s, :parent_uuid => parent.uuid.to_s, :type => nil, :attributes => {}, :classes => "", :style => {}, :browsing => {}, :authoring => {}, :options => {}, :value => nil, :content => []} new_record[:type] = GxG::Gui::GuiComponent::class_to_key(entry.class).to_s else if local_export == true new_record = {:uuid => @uuid.to_s, :parent_uuid => nil, :type => "display", :attributes => {}, :classes => "", :style => {}, :browsing => {}, :authoring => {}, :options => {}, :value => nil, :content => []} else new_record = {:uuid => @remote_uuid.to_s, :parent_uuid => nil, :type => "display", :attributes => {}, :classes => "", :style => {}, :browsing => {}, :authoring => {}, :options => {}, :value => nil, :content => []} end end new_record[:attributes] = entry.get_attributes() new_record[:classes] = entry.get_classes() new_record[:style] = entry.get_style() new_record[:browsing] = entry.get_features() new_record[:authoring] = entry.get_authoring_features() new_record[:options] = entry.get_options() new_record[:value] = entry.get_value() export_db << {:object => entry, :record => new_record} GxG::children_of(entry).each do |the_child| link_db << the_child end end object_record = Proc.new do |the_object| found = nil export_db.each do |export_record| if the_object.object_id == export_record[:object].object_id found = export_record break end end found end # Assemble export contents of records link_db = [(self)] while link_db.size > 0 do # {:uuid => "", :parent_uuid => "", :type => "", :classes => "", :style => {}, :features => {}, :value => nil, :content => []} entry = link_db.shift the_record = object_record.call(entry) if the_record GxG::children_of(entry).each do |the_child| child_record = object_record.call(the_child) the_record[:record][:content] << child_record[:record] link_db << the_child end end # end (export_db[0] || {})[:record] end # def import_display(import_records={}) result = false if import_records.size > 0 old_list = GxG::register_uuid_list() retain_list = [(@uuid.to_sym)] import_db = [] link_db = [(import_records)] while link_db.size > 0 do entry = link_db.shift # do a format check on the record? if (entry[:uuid] && entry[:type] && entry[:attributes] && entry[:classes] && entry[:style] && entry[:browsing] && entry[:authoring] && entry[:options] && entry[:content]) entry[:object] = GxG::object_by_uuid(entry[:uuid].to_sym) unless entry[:object] # create object parent = nil if entry[:parent_uuid] parent = GxG::object_by_uuid(entry[:parent_uuid].to_sym) end the_class = GxG::Gui::GuiComponent::key_to_class(entry[:type].to_sym) unless the_class == GxG::Gui::Display entry[:object] = the_class.new({:uuid => entry[:uuid].to_sym, :parent => (parent || self)}) end end if entry[:object] retain_list << entry[:object].uuid.to_sym end import_db << entry entry[:content].each do |the_record| link_db << the_record end else raise ArgumentError, "Malformed import record." end end # Set object internal data. while import_db.size > 0 do entry = import_db.shift if entry entry[:object].set_attributes(entry[:attributes]) entry[:object].set_classes(entry[:classes]) entry[:object].set_style(entry[:style]) entry[:object].set_features(entry[:browsing]) entry[:object].set_authoring_features(entry[:authoring]) entry[:object].set_options(entry[:options]) entry[:object].set_value(entry[:value]) end end # Render new state information to the DOM. post_event(:display) do self.render_dom end # Eliminate objects NOT included in this key-frame importation. old_list.each do |the_key| unless retain_list.include?(the_key) # unregister the_key object_by_uuid old_object = GxG::object_by_uuid(the_key) unless old_object.is_a?(::GxG::Gui::Display) if GxG::unregister(the_key) && old_object # de-activate object old_object.deactivate() end end end end result = true end result end # Server synchronization methods: def transmit_keyframe() keyframe = self.export_display() if keyframe.is_a?(::Hash) gxg_message = new_message gxg_message[:sender] = @uuid gxg_message[:to] = @remote_uuid gxg_message[:body] = {:method => "import_display", :parameters => keyframe} @channel.remote_call(gxg_message) end end # def transmit_update() if @update_queue.size > 0 gxg_message = new_message gxg_message[:sender] = @uuid gxg_message[:to] = @remote_uuid gxg_message[:body] = {:method => "receive_update", :parameters => {:operation => "update", :records => @update_queue}} @channel.remote_call(gxg_message) @update_queue = [] end end # def transmit_event(the_event_frame=nil) if the_event_frame.is_any?(::Hash, ::Array) gxg_message = new_message gxg_message[:sender] = @uuid gxg_message[:to] = @remote_uuid gxg_message[:body] = {:method => "receive_update", :parameters => {:operation => "pass_event", :events => the_event_frame}} @channel.remote_call(gxg_message) end end # def receive_update(operation_frame={}) if operation_frame.is_a?(::Hash) case operation_frame[:operation] when "update" if operation_frame[:records].is_a?(::Array) operation_frame[:records].each do |the_delta| dom_sync = true the_object = GxG::object_by_uuid(the_delta[:uuid].to_sym) if the_object if the_delta[:attributes].is_a?(::Hash) the_object.set_attributes(the_delta[:attributes]) end if the_delta[:classes] the_object.set_classes(the_delta[:classes]) end if the_delta[:style].is_a?(::Hash) the_object.set_style(the_delta[:style]) end if the_delta[:browsing].is_a?(::Hash) the_object.set_features(the_delta[:browsing]) end if the_delta[:authoring].is_a?(::Hash) the_object.set_authoring_features(the_delta[:authoring]) end if the_delta[:options].is_a?(::Hash) # Options only come FROM the server (One-Way) if the_delta[:options][:visibility] dom_sync = false case the_delta[:options][:visibility] when "show" the_object.show() when "hide" the_object.hide() when "toggle" the_object.toggle_visibility() end else the_object.set_options(the_delta[:options]) end end if the_delta[:value] the_object.set_value(the_delta[:value]) end if dom_sync == true the_object.sync_to_dom() end else puts "No Object for #{the_delta[:uuid]}" end end end when "remove" if operation_frame[:operation][:manifest].is_a?(::Array) operation_frame[:operation][:manifest].each do |the_uuid| the_object = GxG::object_by_uuid(the_uuid.to_sym) if the_object the_object.deactivate() GxG::unregister(the_uuid.to_sym) end end end end end end # def post_update(the_delta=nil) if the_delta.is_a?(::Hash) @update_queue << the_delta end end # def process_event(the_frame=nil) if the_frame.is_a?(::Hash) record = {:type => the_frame[:event].type.to_s, :details => {}} # ??? # puts "#{the_frame[:event].public_methods.sort.inspect}" # common details record[:details][:page_x] = the_frame[:event].page_x record[:details][:page_y] = the_frame[:event].page_y record[:details][:which] = the_frame[:event].which record[:details][:meta_key] = the_frame[:event].meta_key record[:details][:alt_key] = the_frame[:event].alt_key record[:details][:shift_key] = the_frame[:event].shift_key record[:details][:control_key] = the_frame[:event].ctrl_key if the_frame[:data] record[:details][:data] = the_frame[:data] else record[:details][:data] = nil end # type-specific details the_frame[:event] = record # self.transmit_event(the_frame) end end # State setting methods: def get_attributes() @attributes end # def set_attributes(data={}) @attributes = data end # def get_style() @style end # def set_style(style_data={}) @style = style_data end # def get_value() @value end # def set_value(data=nil) @value = data end # def get_classes() @classes end # def set_classes(data="") @classes = data end # def get_features() @browsing end # def set_features(data={}) @browsing = data end # def get_authoring_features() @authoring end # def set_authoring_features(data={}) @authoring = data end # def get_options() @options end # def set_options(data={}) @options = data end # def generate_html() accumulator = [] contents = GxG::children_of(self) contents.each do |the_object| accumulator << the_object.generate_html() end accumulator.join("\n") end # def render_dom(settings={}) # FIX: Make non-recursive, iterative. # Generate a complete replacement for the current DOM content. # Assume NO dom_objects are internally available to the child objects. # Call generate_html on each child new_dom_html = self.generate_html() ::Element.find('body').append(::Element::parse(new_dom_html)) # call establish_dom_link on each object after DOM commit. link_db = [(self)] while link_db.size > 0 do entry = link_db.shift GxG::children_of(entry).each do |the_object| the_object.activate() link_db << the_object end end # end # def refresh_dom() link_db = [(self)] while link_db.size > 0 do entry = link_db.shift GxG::children_of(entry).each do |the_object| the_object.sync_to_dom() link_db << the_object end end # end # def switch_to_mode(the_mode=:browsing) if the_mode.is_a?(String) the_mode = the_mode.to_sym end if GxG::DISPLAY_DETAILS[:mode] == :authoring if the_mode == :browsing # switch back to browsing mode GxG::DISPLAY_DETAILS[:mode] = :browsing link_db = [(self)] while link_db.size > 0 do entry = link_db.shift GxG::children_of(entry).each do |the_object| the_object.sync_from_dom() the_object.activate() link_db << the_object end end # TODO: update server gui-mode as well end else if the_mode == :authoring # switch to authoring mode GxG::DISPLAY_DETAILS[:mode] = :authoring link_db = [(self)] while link_db.size > 0 do entry = link_db.shift GxG::children_of(entry).each do |the_object| the_object.sync_from_dom() the_object.activate() link_db << the_object end end # TODO: update server gui-mode as well end end end # def activate() # No-op for display object end # def deactivate(settings={}) # No-op for display object end end # class GuiComponent # Abstract Class - only instantiate sub-classes. def self.class_mapping() { :display => GxG::Gui::Display, :background => GxG::Gui::Background, :page => GxG::Gui::Page, :window => GxG::Gui::Window, :menubar => GxG::Gui::MenuBar, :accordion => GxG::Gui::Accordion, :accordion_section => GxG::Gui::AccordionSection, :accordion_section_label => GxG::Gui::AccordionSectionLabel, :accordion_section_content => GxG::Gui::AccordionSectionContent, :anchor => GxG::Gui::Anchor, :button => GxG::Gui::Button, :division => GxG::Gui::Division, :input_label => GxG::Gui::InputLabel, :paragraph => GxG::Gui::Paragraph, :text_lable => GxG::Gui::TextLabel, :legend => GxG::Gui::Legend, :list_item => GxG::Gui::ListItem, :ordered_list => GxG::Gui::OrderedList, :unordered_list => GxG::Gui::UnorderedList, :control_group => GxG::Gui::ControlGroup, :field_set => GxG::Gui::FieldSet, :text_input => GxG::Gui::TextInput, :date_picker => GxG::Gui::DatePicker, :menu => GxG::Gui::Menu, :select_menu => GxG::Gui::SelectMenu, :select_menu_option => GxG::Gui::SelectMenuOption, :slider => GxG::Gui::Slider, :spinner => GxG::Gui::Spinner, :progress_bar => GxG::Gui::ProgressBar, :tabs => GxG::Gui::Tabs, :tab_section => GxG::Gui::TabSection, :table => GxG::Gui::Table, :table_row => GxG::Gui::TableRow, :table_header => GxG::Gui::TableHeader, :table_data => GxG::Gui::TableData, :image => GxG::Gui::Image } end # def self.key_to_class(the_key) GxG::Gui::GuiComponent::class_mapping()[(the_key)] end # def self.class_to_key(the_class) result = nil mapping = GxG::Gui::GuiComponent::class_mapping() mapping.keys.each do |the_key| if mapping[(the_key)] == the_class result = the_key break end end result end # def initialize(settings={}) @uuid = (settings[:uuid] || GxG::uuid_generate) @parent = settings[:parent] # Class, Style, and Features are for cached for browse-mode only. @base_tag = "div" @attributes = {} @classes = "" @style = {} @browsing = {:draggable => {}, :droppable => {}, :resizable => {}, :selectable => {}, :sortable => {}, :tool_tip => {}, :alt_text => ""} @authoring = {:draggable => {}, :droppable => {}, :resizable => {}, :selectable => {}, :sortable => {}, :tool_tip => {}, :alt_text => ""} @options = {} @value = nil @dom_object = nil @visible = true GxG::register(self,@parent) end # def uuid() @uuid end # def dom_object() @dom_object end # def visible?() @visible end # def hide() if @dom_object @dom_object.hide() @visible = false end end # def show() if @dom_object @dom_object.show() @visible = true end end # def toggle_visibility() if @dom_object if @visible == true self.hide() else self.show() end end end # def establish_dom_link() # @dom_object = Element.find("##{@uuid.to_s}") if @dom_object # Set event traps on @dom_object # ??? @dom_object.on :dblclick do |event| GxG::DISPLAY_DETAILS[:object].process_event({:uuid => @uuid, :event => event}) end @dom_object.on :mouseup do |event| GxG::DISPLAY_DETAILS[:object].process_event({:uuid => @uuid, :event => event}) end @dom_object.on :mousedown do |event| GxG::DISPLAY_DETAILS[:object].process_event({:uuid => @uuid, :event => event}) end # @dom_object.on :mouseenter do |event| # GxG::DISPLAY_DETAILS[:object].process_event({:uuid => @uuid, :event => event}) # end # @dom_object.on :mouseleave do |event| # GxG::DISPLAY_DETAILS[:object].process_event({:uuid => @uuid, :event => event}) # end end true end # def get_dom_features() valid_draggable_options = {:add_classes => "addClasses", :append_to => "appendTo", :axis => "axis", :cancel => "cancel", :classes => "classes", :connect_to_sortable => "connectToSortable", :containment => "containment", :cursor => "cursor", :cursor_at => "cursorAt", :delay => "delay", :disabled => "disabled", :distance => "distance", :grid => "grid", :handle => "handle", :helper => "helper", :iframe_fix => "iframeFix", :opacity => "opacity", :refresh_positions => "refreshPositions", :revert => "revert", :revert_duration => "revertDuration", :scope => "scope", :scroll => "scroll", :scroll_sensitivity => "scrollSensitivity", :scroll_speed => "scrollSpeed", :snap => "snap", :snap_mode => "snapMode", :snap_tolerance => "snapTolerance", :stack => "stack", :z_index => "z-index"} valid_droppable_options = {:accept => "accept", :active_class => "activeClass", :add_classes => "addClasses", :classes => "classes", :disabled => "disabled", :greedy => "greedy", :hover_class => "hoverClass", :scope => "scope", :tolerance => "tolerance"} valid_resizable_options = {:also_resize => "alsoResize", :animate => "animate", :animate_duration => "animateDuration", :animate_easing => "animateEasing", :aspect_ration => "aspectRatio", :auto_hide => "autoHide", :cancel => "cancel", :classes => "classes", :containment => "containment", :delay => "delay", :disabled => "disabled", :distance => "distance", :ghost => "ghost", :grid => "grid", :handles => "handles", :helper => "helper", :max_height => "maxHeight", :max_width => "maxWidth"} valid_selectable_options = {:append_to => "appendTo", :auto_refresh => "autoRefresh", :cancel => "cancel", :classes => "classes", :delay => "delay", :disabled => "disabled", :distance => "distance", :filter => "filter", :tolerance => "tolerance"} valid_sortable_options = {:append_to => "appendTo", :axis => "axis", :cancel => "cancel", :classes => "classes", :connect_with => "connectWith", :cursor => "cursor", :cursor_at => "cursorAt", :delay => "delay", :disabled => "disabled", :distance => "distance", :drop_on_empty => "dropOnEmpty", :grid => "grid", :handle => "handle", :helper => "helper", :items => "items", :opacity => "opacity", :placeholder => "placeholder", :revert => "revert", :scroll => "scroll", :scroll_sensitivity => "scrollSensitivity", :scroll_speed => "scrollSpeed", :tolerance => "tolerance", :z_index => "z-index"} # TODO: include tool_tip in process. the_features = {:draggable => {}, :droppable => {}, :resizable => {}, :selectable => {}, :sortable => {}, :tool_tip => {}, :alt_text => ""} if @dom_object begin valid_draggable_options.keys.each do |the_option_key| unless [].include?(the_option_key) the_features[:draggable][(the_option_key)] = @dom_object.draggable("option",(valid_draggable_options[(the_option_key)])) end end rescue Exception => the_error end # begin valid_droppable_options.keys.each do |the_option_key| unless [].include?(the_option_key) the_features[:droppable][(the_option_key)] = @dom_object.droppable("option",(valid_droppable_options[(the_option_key)])) end end rescue Exception => the_error end # begin valid_resizable_options.keys.each do |the_option_key| unless [].include?(the_option_key) the_features[:resizable][(the_option_key)] = @dom_object.resizable("option",(valid_resizable_options[(the_option_key)])) end end rescue Exception => the_error end # begin valid_selectable_options.keys.each do |the_option_key| unless [].include?(the_option_key) the_features[:selectable][(the_option_key)] = @dom_object.selectable("option",(valid_selectable_options[(the_option_key)])) end end rescue Exception => the_error end # begin valid_sortable_options.keys.each do |the_option_key| unless [].include?(the_option_key) the_features[:sortable][(the_option_key)] = @dom_object.sortable("option",(valid_sortable_options[(the_option_key)])) end end rescue Exception => the_error end # end # the_features end # def set_dom_features(the_features=nil) valid_draggable_options = {:add_classes => "addClasses", :append_to => "appendTo", :axis => "axis", :cancel => "cancel", :classes => "classes", :connect_to_sortable => "connectToSortable", :containment => "containment", :cursor => "cursor", :cursor_at => "cursorAt", :delay => "delay", :disabled => "disabled", :distance => "distance", :grid => "grid", :handle => "handle", :helper => "helper", :iframe_fix => "iframeFix", :opacity => "opacity", :refresh_positions => "refreshPositions", :revert => "revert", :revert_duration => "revertDuration", :scope => "scope", :scroll => "scroll", :scroll_sensitivity => "scrollSensitivity", :scroll_speed => "scrollSpeed", :snap => "snap", :snap_mode => "snapMode", :snap_tolerance => "snapTolerance", :stack => "stack", :z_index => "z-index"} valid_droppable_options = {:accept => "accept", :active_class => "activeClass", :add_classes => "addClasses", :classes => "classes", :disabled => "disabled", :greedy => "greedy", :hover_class => "hoverClass", :scope => "scope", :tolerance => "tolerance"} valid_resizable_options = {:also_resize => "alsoResize", :animate => "animate", :animate_duration => "animateDuration", :animate_easing => "animateEasing", :aspect_ration => "aspectRatio", :auto_hide => "autoHide", :cancel => "cancel", :classes => "classes", :containment => "containment", :delay => "delay", :disabled => "disabled", :distance => "distance", :ghost => "ghost", :grid => "grid", :handles => "handles", :helper => "helper", :max_height => "maxHeight", :max_width => "maxWidth"} valid_selectable_options = {:append_to => "appendTo", :auto_refresh => "autoRefresh", :cancel => "cancel", :classes => "classes", :delay => "delay", :disabled => "disabled", :distance => "distance", :filter => "filter", :tolerance => "tolerance"} valid_sortable_options = {:append_to => "appendTo", :axis => "axis", :cancel => "cancel", :classes => "classes", :connect_with => "connectWith", :cursor => "cursor", :cursor_at => "cursorAt", :delay => "delay", :disabled => "disabled", :distance => "distance", :drop_on_empty => "dropOnEmpty", :grid => "grid", :handle => "handle", :helper => "helper", :items => "items", :opacity => "opacity", :placeholder => "placeholder", :revert => "revert", :scroll => "scroll", :scroll_sensitivity => "scrollSensitivity", :scroll_speed => "scrollSpeed", :tolerance => "tolerance", :z_index => "z-index"} # unless the_features.is_a?(::Hash) the_features = @browsing end if @dom_object if the_features[:draggable][:enable] == true @dom_object.draggable() the_features[:draggable].keys.each do |the_option_key| if valid_draggable_options.keys.include?(the_option_key) && the_option_key != :enable @dom_object.draggable("option",(valid_draggable_options[(the_option_key)]),(the_features[:draggable][(the_option_key)])) end end else # @dom_object.draggable('disable') end if the_features[:droppable][:enable] == true @dom_object.droppable() the_features[:droppable].keys.each do |the_option_key| if valid_droppable_options.keys.include?(the_option_key) && the_option_key != :enable @dom_object.droppable("option",(valid_droppable_options[(the_option_key)]),(the_features[:droppable][(the_option_key)])) end end else # @dom_object.droppable('disable') end if the_features[:resizable][:enable] == true @dom_object.resizable() the_features[:resizable].keys.each do |the_option_key| if valid_resizable_options.keys.include?(the_option_key) && the_option_key != :enable @dom_object.resizable("option",(valid_resizable_options[(the_option_key)]),(the_features[:resizable][(the_option_key)])) end end else # @dom_object.resizable('disable') end if the_features[:selectable][:enable] == true @dom_object.selectable() the_features[:selectable].keys.each do |the_option_key| if valid_selectable_options.keys.include?(the_option_key) && the_option_key != :enable @dom_object.selectable("option",(valid_selectable_options[(the_option_key)]),(the_features[:selectable][(the_option_key)])) end end else # @dom_object.selectable('disable') end if the_features[:sortable][:enable] == true @dom_object.sortable() the_features[:sortable].keys.each do |the_option_key| if valid_sortable_options.keys.include?(the_option_key) && the_option_key != :enable @dom_object.sortable("option",(valid_sortable_options[(the_option_key)]),(the_features[:sortable][(the_option_key)])) end end else # @dom_object.sortable('disable') end end # true end # def activate() unless @dom_object self.establish_dom_link end if @dom_object # unless self.is_any?(GxG::Gui::Background, GxG::Gui::Page, GxG::Gui::Window) # unless in :authoring mode: if GxG::DISPLAY_DETAILS[:mode] == :authoring self.set_dom_features(@authoring) else self.set_dom_features(@browsing) end # TODO: figure out how to incorporate @browsing[:tool_tip] end # end # end # def deactivate(settings={}) if @dom_object begin @dom_object.remove rescue Exception end @dom_object = nil end end # def components() GxG::children_of(self) end # def add_component(the_type=nil, settings={}) result = nil if the_type.is_any?(::String, ::Symbol) # [:display, :background, :page, :window, :menubar, :accordion, :accordion_section, :accordion_section_label, :accordion_section_content, :anchor, :button, :division, :input_label, :paragraph, :text_lable, :legend, :list_item, :ordered_list, :unordered_list, :control_group, :field_set, :text_input, :date_picker, :menu, :select_menu, :select_menu_option, :slider, :spinner, :progress_bar, :tabs, :tab_section] viable = [] case GxG::Gui::GuiComponent::class_to_key(self.class) when :background viable = [:accordion, :anchor, :button, :division, :input_label, :paragraph, :text_lable, :legend, :ordered_list, :unordered_list, :control_group, :field_set, :text_input, :date_picker, :menu, :select_menu, :slider, :spinner, :progress_bar, :tabs, :table, :image] when :page viable = [:accordion, :anchor, :button, :division, :input_label, :paragraph, :text_lable, :legend, :ordered_list, :unordered_list, :control_group, :field_set, :text_input, :date_picker, :menu, :select_menu, :slider, :spinner, :progress_bar, :tabs, :table, :image] when :menubar viable = [:accordion, :anchor, :button, :division, :input_label, :paragraph, :text_lable, :legend, :ordered_list, :unordered_list, :control_group, :field_set, :text_input, :date_picker, :menu, :select_menu, :slider, :spinner, :progress_bar, :tabs, :table, :image] when :window viable = [:accordion, :anchor, :button, :division, :input_label, :paragraph, :text_lable, :legend, :ordered_list, :unordered_list, :control_group, :field_set, :text_input, :date_picker, :menu, :select_menu, :slider, :spinner, :progress_bar, :tabs, :table, :image] when :accordion viable = [:accordion_section] when :accordion_section viable = [:accordion_section_label, :accordion_section_content] when :accordion_section_label viable = [] when :accordion_section_content viable = [:accordion, :anchor, :button, :division, :input_label, :paragraph, :text_lable, :legend, :ordered_list, :unordered_list, :control_group, :field_set, :text_input, :date_picker, :menu, :select_menu, :slider, :spinner, :progress_bar, :tabs, :table, :image] when :anchor viable = [] when :button viable = [] when :division viable = [:accordion, :anchor, :button, :division, :input_label, :paragraph, :text_lable, :legend, :ordered_list, :unordered_list, :control_group, :field_set, :text_input, :date_picker, :menu, :select_menu, :slider, :spinner, :progress_bar, :tabs, :table, :image] when :input_label viable = [] when :paragraph viable = [] when :text_label viable = [] when :legend viable = [] when :list_item viable = [:accordion, :anchor, :button, :division, :input_label, :paragraph, :text_lable, :legend, :ordered_list, :unordered_list, :control_group, :field_set, :text_input, :date_picker, :menu, :select_menu, :slider, :spinner, :progress_bar, :tabs, :table, :image] when :ordered_list viable = [:list_item] when :unordered_list viable = [:list_item] when :control_group viable = [:anchor, :button, :input_label, :text_lable, :text_input, :date_picker, :menu, :select_menu, :slider, :spinner, :progress_bar] when :field_set viable = [:anchor, :button, :input_label, :text_lable, :text_input, :legend, :date_picker, :menu, :select_menu, :slider, :spinner, :progress_bar] when :text_input viable = [] when :date_picker viable = [] when :menu viable = [] when :select_menu viable = [:select_menu_option] when :select_menu_option viable = [] when :slider viable = [] when :spinner viable = [] when :progress_bar viable = [] when :tabs viable = [:tab_section] when :tab_section viable = [:accordion, :anchor, :button, :division, :input_label, :paragraph, :text_lable, :legend, :ordered_list, :unordered_list, :control_group, :field_set, :text_input, :date_picker, :menu, :select_menu, :slider, :spinner, :progress_bar, :tabs, :table, :image] when :table viable = [:table_row] when :table_row viable = [:table_header, :table_data] when :image viable = [] end # if viable.include?(the_type.to_sym) the_class = GxG::Gui::GuiComponent::key_to_class(the_type.to_sym) if the_class result = the_class.new(settings.merge({:parent => self})) else # err end else # err end # end result end # def receive_an_update(the_delta=nil) if the_delta.is_a?(::Hash) # TODO: fine-grained updates if the_delta[:attributes].is_a?(::Hash) self.set_attributes(the_delta[:attributes]) end if the_delta[:classes] self.set_classes(the_delta[:classes]) end if the_delta[:style].is_a?(::Hash) self.set_style(the_delta[:style]) end if the_delta[:browsing].is_a?(::Hash) self.set_features(the_delta[:browsing]) end if the_delta[:authoring].is_a?(::Hash) self.set_authoring_features(the_delta[:authoring]) end if the_delta[:options].is_a?(::Hash) self.set_options(the_delta[:options]) end if the_delta[:value] self.set_value(the_delta[:value]) end self.sync_to_dom() # ??? end end # def get_attributes() @attributes end # def set_attributes(data={}) @attributes = data end # def get_style() @style end # def set_style(style_data={}) @style = style_data end # def get_value() @value end # def set_value(data=nil) @value = data end # def get_classes() @classes end # def set_classes(data=nil) @classes = data.to_s end # def get_features() @browsing end # def set_features(data={}) @browsing = data end # def get_authoring_features() @authoring end # def set_authoring_features(data={}) @authoring = data end # def get_options() @options end # def set_options(data={}) # ??? if data.is_a?(::Hash) data.keys.each do |op_key| if op_key == :visibility case op_key when "hide" self.hide() when "show" self.show() when "toggle" self.toggle_visibility() end else @options[(op_key.to_sym)] = data[(op_key)] end end end # end # Rendering to DOM def generate_html() # TODO: figure out where to incorporate @browsing[:alt_text] (string) into html tag output. (508 compliance) if @classes.size > 0 result = "<#{@base_tag.to_s} id='#{@uuid.to_s}' class='#{@classes.to_s}'" else result = "<#{@base_tag.to_s} id='#{@uuid.to_s}'" end # if @attributes.size > 0 @attributes.keys.each do |the_key| result = result + " #{the_key.to_s}='#{@attributes[(the_key)].to_s}'" end end # if @style.keys.size > 0 style_string = " style='" else style_string = "" end @style.keys.each do |the_key| unless @style[(the_key)] == "" # ??? # the_property = GxG::Css::get_property_name(the_key) the_property = (the_key.to_s.gsub("_","-")) if the_property style_string = style_string + " #{the_property.to_s}: #{@style[(the_key)].to_s};" end end end if style_string.size > 0 result = (result + style_string + "'") end if ["button", "input", "li", "option", "progress", "param"].include?(@base_tag) # value is in the main tag def. if @attributes[:value] result = result + ">" else if @value result = (result + " value='" + @value.to_s + "'>") else result = result + ">" end end else # close the main tag def. result = result + ">" end accumulator = [] contents = GxG::children_of(self) contents.each do |the_object| accumulator << the_object.generate_html() end if (@attributes[:value] || self.respond_to?(:set_dom_value)) result = (result + accumulator.join("\n") + "") else if ["button", "input", "li", "option", "progress", "param"].include?(@base_tag) result = (result + accumulator.join("\n") + "") else # value is in-line text if @value result = (result + @value.to_s + accumulator.join("\n") + "") else result = (result + accumulator.join("\n") + "") end end end result end # def sync_to_dom() if @dom_object @dom_object.attr("class",@classes) @style.keys.each do |css_key| the_name = ::GxG::Css::get_property_name(css_key) if the_name @dom_object.css(the_name.to_s,@style[(css_key)]) end end @attributes.keys.each do |attr_key| @dom_object.attr(attr_key.to_s,@attributes[(attr_key)]) end unless @attributes[:value] unless @base_tag == "div" # @dom_object.innerHTML = @value.to_s @dom_object.html(@value.to_s).fadeIn(500) end end # if GxG::DISPLAY_DETAILS[:mode] == :authoring self.set_dom_features(self.get_authoring_features()) else self.set_dom_features(self.get_features()) end # end true end # def sync_from_dom() # Produces a state delta record to send to the server, as well as sets state to match dom. delta = nil if @dom_object delta = {} the_class = @dom_object.attr("class") if the_class != @classes @classes = the_class delta[:classes] = the_class end new_style = {} ::GxG::Css::valid_properties.each do |prop_key| the_name = ::GxG::Css::get_property_name(prop_key) if the_name && @style[(prop_key)] new_style[(prop_key)] = @dom_object.css(the_name.to_s) end end if new_style.size > 0 if new_style != @style @style = new_style delta[:style] = new_style end end if @attributes.size > 0 delta[:attributes] = {} end @attributes.keys.each do |attr_key| unless attr_key.to_s == "class" || attr_key.to_s == "style" the_attribute = @dom_object.attr(attr_key.to_s) if @attributes[(attr_key)] != the_attribute @attributes[(attr_key)] = the_attribute delta[:attributes][(attr_key)] = the_attribute end end end unless @attributes[:value] unless @base_tag == "div" the_value = @dom_object.innerHTML if @value != the_value @value = the_value delta[:value] = the_value end end end # the_features = self.get_dom_features() if GxG::DISPLAY_DETAILS[:mode] == :authoring if @authoring != the_features @authoring = the_features delta[:authoring] = the_features end else if @browsing != the_features @browsing = the_features delta[:browsing] = the_features end end # if delta.size > 0 delta[:uuid] = @uuid else delta = nil end end delta end # end # class Background < GuiComponent # def initialize(settings) super(settings) @base_tag = "div" # z-index of 0 or 1 self end # end # class Page < GuiComponent # def initialize(settings) super(settings) @base_tag = "div" # z-index of 50 self end # end # class Window < GuiComponent # #Window Options: # Extended Options: #closable # #Type: Boolean # #Usage: enable/disable close button # #Default: true #maximizable # #Type: Boolean # #Usage: enable/disable maximize button # #Default: false #minimizable # #Type: Boolean # #Usage: enable/disable minimize button # #Default: false #collapsable # #Type: Boolean # #Usage: enable/disable collapse button # #Default: false #minimizeLocation # #Type: String # #Usage: sets alignment of minimized dialogues # #Default: 'left' # #Valid: 'left', 'right' #dblclick # #Type: Boolean, String # #Usage: set action on double click # #Default: false # #Valid: false, 'maximize', 'minimize', 'collapse' #titlebar # #Type: Boolean, String # #Default: false # #Valid: false, 'none', 'transparent' #icons # #Type: Object # #Default: # #{ # "close" : "ui-icon-circle-closethick", // new in v1.0.1 # "maximize" : "ui-icon-extlink", # "minimize" : "ui-icon-minus", # "restore" : "ui-icon-newwin" #} # #Valid: # Basic Example: # $("
This is content
") # .dialog({ "title" : "My Dialog" }) # .dialogExtend({ # "maximizable" : true, # "dblclick" : "maximize", # "icons" : { "maximize" : "ui-icon-arrow-4-diag" } # }); # # So: @dom_object.dialog(standard_options).dialogExtend(extended_options) # def initialize(settings) super(settings) @base_tag = "div" # minimum z-index of 100, managed by jQuery # `#{@dom_object}.dialog(#{JSON.generate(standard_options)}).dialogExtend(#{JSON.generate(extended_options)})` self end # def activate() super() if @dom_object valid_standard_options = {:append_to => "appendTo", :auto_open => "autoOpen", :buttons => "buttons", :classes => "classes", :close_on_escape => "closeOnEscape", :close_text => "closeText", :dialog_class => "dialogClass", :draggable => "draggable", :height => "height", :hide => "hide", :max_height => "maxHeight", :max_width => "maxWidth", :min_height => "minHeight", :min_width => "minWidth", :modal => "modal", :position => "position", :resizable => "resizable", :show => "show", :title => "title", :width => "width"} valid_extended_options = {:closable => "closable", :maximizable => "maximizable", :minimizable => "minimizable", :collapsable => "collapsable", :minimize_location => "minimizeLocation", :double_click => "dblclick", :titlebar => "titlebar", :icons => "icons"} standard_options = {} extended_options = {} @options.keys.each do |the_option| if valid_standard_options.keys.include?(the_option) standard_options[(valid_standard_options[(the_option)])] = @options[(the_option)] end if valid_extended_options.keys.include?(the_option) extended_options[(valid_extended_options[(the_option)])] = @options[(the_option)] end end #`#{@dom_object}.dialog(#{JSON.generate(standard_options)}).dialogExtend(#{JSON.generate(extended_options)})` if extended_options.size > 0 @dom_object.dialog(standard_options).dialogExtend(extended_options) else @dom_object.dialog(standard_options) end end end # def hide() if @dom_object @dom_object.dialog("hide") @visible = false end end # def show() if @dom_object @dom_object.dialog("show") @visible = true end end # end # class Accordion < GuiComponent # def initialize(settings) super(settings) # `#{@dom_object}.accordion();` # has: Title, and Content (sections) self end # def activate() unless @dom_object self.establish_dom_link end if @dom_object @dom_object.accordion(); end # super() true end # end # class AccordionSection < GuiComponent # def initialize(settings) super(settings) # has: AccordionSectionLabel, and AccordionSectionContent: (any) # some compound-obj slight of hand here. # @banner = nil @content = nil self end # def establish_dom_link() unless @banner && @content contents = GxG::children_of(self) contents.each do |the_object| if the_object.is_a?(GxG::Gui::AccordionSectionLabel) @banner = the_object end if the_object.is_a?(GxG::Gui::AccordionSectionContent) @content = the_object end if @banner && @content break end end end true end # def activate() unless @banner && @content self.establish_dom_link() end true end # def deactivate() true end # def generate_html() accumulator = [] contents = GxG::children_of(self) contents.each do |the_object| accumulator << the_object.generate_html() end accumulator.join("\n") end # def sync_to_dom() # this is called on the banner and content elsewhere true end # def sync_from_dom() # this is called on the banner and content elsewhere ? nil end # def hide() # No-op end # def show() # No-op end # end # class AccordionSectionLabel < GuiComponent def initialize(settings) super(settings) @base_tag = "H3" # text held in @value ? self end # def set_options(options={}) @options = options if options[:font_size].is_a?(Numeric) # Font size in EM units only case options[:font_size].to_f when 2.0 @base_tag = "H1" when 1.5 @base_tag = "H2" when 1.17 @base_tag = "H3" when 1.0 @base_tag = "H4" when 0.83 @base_tag = "H5" when 0.67 @base_tag = "H6" else @base_tag = "H3" @style[:'font-size'] = "#{options[:font_size].to_f}em" end end end # end # class AccordionSectionContent < GuiComponent def initialize(settings) super(settings) self end # end # class Anchor < GuiComponent # def initialize(settings) super(settings) @base_tag = "a" # a (anchor) tag # has: href, and text value. self end # def generate_html() super({:href => "#"}) end end # class Button < GuiComponent # def initialize(settings) super(settings) @base_tag = "button" # button tag self end # end # class RadioButton < GuiComponent # def initialize(settings) super(settings) @base_tag = "input" @attributes[:type] = "radio" self end # end # class CheckBoxButton < GuiComponent # def initialize(settings) super(settings) @base_tag = "input" @attributes[:type] = "checkbox" self end # end # class Division < GuiComponent # def initialize(settings) super(settings) @base_tag = "div" self end # end # class InputLabel < GuiComponent # def initialize(settings) super(settings) @base_tag = "label" # label tag # for=(a control uuid) self end # def set_options(options={}) @options = options if options[:font_size].is_a?(Numeric) # Font size in EM units only @style[:'font-size'] = "#{options[:font_size].to_f}em" end end # end # class Paragraph < GuiComponent # def initialize(settings) super(settings) @base_tag = "p" # p tag self end # end # class TextLabel < GuiComponent # def initialize(settings) super(settings) @base_tag = "h1" # h1 tag self end # def set_options(options={}) @options = options if options[:font_size].is_a?(Numeric) # Font size in EM units only @style[:'font-size'] = "#{options[:font_size].to_f}em" end end # end # class Legend < GuiComponent # def initialize(settings) super(settings) @base_tag = "legend" # legend tag self end # end # class ListItem < GuiComponent # def initialize(settings) super(settings) @base_tag = "li" # li tag self end # end # class OrderedList < GuiComponent # def initialize(settings) super(settings) @base_tag = "ol" # ol tag self end # end # class UnorderedList < GuiComponent # def initialize(settings) super(settings) @base_tag = "ul" # ul tag self end # end # class ControlGroup < GuiComponent # See: http://jqueryui.com/controlgroup/ def initialize(settings) super(settings) self end # end # class FieldSet < GuiComponent def initialize(settings) super(settings) @base_tag = "fieldset" # fieldset tag self end # end # class TextInput < GuiComponent # See: http://jqueryui.com/controlgroup/ def initialize(settings) super(settings) @base_tag = "input" @attributes[:type] = "text" # input tag, type="text" # For auto-complete: `#{@dom_object}.autocomplete({source: });` self end # def generate_html() super({:type => "text"}) end # end # class DatePicker < GuiComponent # def initialize(settings) super(settings) @base_tag = "input" # `#{@dom_object}.datepicker();` # input tag, type="text" self end # def generate_html() super({:type => "text"}) end # def establish_dom_link() super() if @dom_object @dom_object.datepicker() end true end end # class MenuBar < GuiComponent # def initialize(settings) super(settings) # sections have: title # @record[:style][:z_index] = 99 self end # def establish_dom_link() # No event linking for menubar - just a place holder object. @dom_object = Element.find("##{@uuid.to_s}") end end # class Menu < GuiComponent private # def menu_body_html(menu_hash=nil) result = "" # FIX: watch your stack depth ! unless menu_hash menu_hash = @options[:menu_definition] end if menu_hash.is_a?(::Hash) menu_hash.keys.each do |choice| if menu_hash[(choice)].is_a?(::Array) result = (result + "
  • " + "#{choice.to_s}" + choice.to_s + "
  • ") # end if menu_hash[(choice)].is_a?(::Hash) result = (result + "
  • " + choice.to_s + "
      " + menu_body_html(menu_hash[(choice)]) + "
  • ") # end if menu_hash[(choice)].is_any?(::String, ::Symbol) result = (result + "
  • " + menu_hash[(choice)] + "
  • ") end # end end # result end # public # def decode_choice(selection=nil,menu_hash=nil) result = nil # FIX: watch your stack depth ! unless menu_hash menu_hash = @options[:menu_definition] end if menu_hash.is_a?(::Hash) menu_hash.keys.each do |choice| if menu_hash[(choice)].is_a?(::Array) if choice.to_s == selection result = menu_hash[(choice)][1] break end # end if menu_hash[(choice)].is_a?(::Hash) result = decode_choice(selection,menu_hash[(choice)]) if result break end end if menu_hash[(choice)].is_any?(::String, ::Symbol) if choice.to_s == selection result = menu_hash[(choice)] break end end end end result end # def initialize(settings) super(settings) @base_tag = "ul" # Needs custom generateHTML # Contains Ordered and Unordered Lists: class='ui-state-disabled' to disable menu any menu item/sub-item. # Idea: # @options[:menu_definition] contains the menu definition. # Structure: key is text label of choice, value is a) code associated, b) Array with image path to icon then code associated (later: 3rd item key-code). # If Hash = sub-menu following same pattern # trap menuselect to match string with @options[:menu_definition] hash/sub-hash # ??? self end # def establish_dom_link() @dom_object = Element.find("##{@uuid.to_s}") true end # def activate() unless @dom_object self.establish_dom_link end if @dom_object # Set event traps on @dom_object @dom_object.menu() self.hide() @dom_object.on :menuselect do |event,ui| self.hide() data = self.decode_choice(`#{ui}.item.text()`) if data GxG::DISPLAY_DETAILS[:object].process_event({:uuid => @uuid, :event => event, :data => data}) end end end true end # def set_options(the_options={}) if the_options.is_a?(::Hash) the_options.keys.each do |op_key| if op_key == :visibility case op_key when "hide" self.hide() when "show" self.show() when "toggle" self.toggle_visibility() end else # if op_key == :menu_definition if @options[:menu_definition].hash != the_options[:menu_definition].hash @options[:menu_definition] = the_options[:menu_definition] if @dom_object @dom_object.html(menu_body_html()) end end else @options[(op_key.to_sym)] = the_options[(op_key)] end # end end end # end # def generate_html() if @classes.size > 0 result = "<#{@base_tag.to_s} id='#{@uuid.to_s}' class='#{@classes.to_s}'" else result = "<#{@base_tag.to_s} id='#{@uuid.to_s}'" end # if @attributes.size > 0 @attributes.keys.each do |the_key| result = result + " #{the_key.to_s}='#{@attributes[(the_key)].to_s}'" end end # if @style.keys.size > 0 style_string = " style='" else style_string = "" end @style.keys.each do |the_key| unless @style[(the_key)] == "" #the_property = GxG::Css::get_property_name(the_key) the_property = (the_key.to_s.gsub("_","-")) if the_property style_string = style_string + " #{the_property.to_s}: #{@style[(the_key)].to_s};" end end end if style_string.size > 0 result = (result + style_string + "'") end result = (result + ">" + menu_body_html() + "") result end # end # class SelectMenu < GuiComponent # def initialize(settings) super(settings) @base_tag = "select" # select tag # Contains: SelectMenuOption(s). self end # end # class SelectMenuOption < GuiComponent # def initialize(settings) super(settings) @base_tag = "option" # option tag # to select the SelectMenuOption. self end # end # class Slider < GuiComponent # def initialize(settings) super(settings) # div tag # `#{@dom_object}.slider();` # Read Value: `#{@dom_object}.slider('value');` # Write Value: `#{@dom_object}.slider('value', the_value);` self end # def activate() unless @dom_object self.establish_dom_link() end if @dom_object @dom_object.slider() end end # end # class Spinner < GuiComponent # def initialize(settings) super(settings) @base_tag = "input" # input tag # `#{@dom_object}.spinner();` # Read Value: `#{@dom_object}.spinner('value');` # Write Value: `#{@dom_object}.spinner('value', the_value);` self end # def activate() if @dom_object @dom_object.spinner() end end end # class ProgressBar < GuiComponent # def initialize(settings) super(settings) # uses div tag # `#{@dom_object}.progressbar({value: 37});` # Read Progress Percentage Value: `#{@dom_object}.progressbar('value');` # Write Progress Percentage Value: `#{@dom_object}.progressbar('value', the_percentage);` # Inner div tag for progress-label:
    Loading...
    self end # def activate() unless @dom_object self.establish_dom_link() end if @dom_object @dom_object.progressbar() end end # end # class Tabs < GuiComponent # def initialize(settings) super(settings) # div tag # `#{@dom_object}.tabs();` #
    # #
    #

    Proin elit arcu, rutrum commodo, vehicula tempus, commodo a, risus. Curabitur nec arcu. Donec sollicitudin mi sit amet mauris. Nam elementum quam ullamcorper ante. Etiam aliquet massa et lorem. Mauris dapibus lacus auctor risus. Aenean tempor ullamcorper leo. Vivamus sed magna quis ligula eleifend adipiscing. Duis orci. Aliquam sodales tortor vitae ipsum. Aliquam nulla. Duis aliquam molestie erat. Ut et mauris vel pede varius sollicitudin. Sed ut dolor nec orci tincidunt interdum. Phasellus ipsum. Nunc tristique tempus lectus.

    #
    #
    #

    Morbi tincidunt, dui sit amet facilisis feugiat, odio metus gravida ante, ut pharetra massa metus id nunc. Duis scelerisque molestie turpis. Sed fringilla, massa eget luctus malesuada, metus eros molestie lectus, ut tempus eros massa ut dolor. Aenean aliquet fringilla sem. Suspendisse sed ligula in ligula suscipit aliquam. Praesent in eros vestibulum mi adipiscing adipiscing. Morbi facilisis. Curabitur ornare consequat nunc. Aenean vel metus. Ut posuere viverra nulla. Aliquam erat volutpat. Pellentesque convallis. Maecenas feugiat, tellus pellentesque pretium posuere, felis lorem euismod felis, eu ornare leo nisi vel felis. Mauris consectetur tortor et purus.

    #
    #
    #

    Mauris eleifend est et turpis. Duis id erat. Suspendisse potenti. Aliquam vulputate, pede vel vehicula accumsan, mi neque rutrum erat, eu congue orci lorem eget lorem. Vestibulum non ante. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Fusce sodales. Quisque eu urna vel enim commodo pellentesque. Praesent eu risus hendrerit ligula tempus pretium. Curabitur lorem enim, pretium nec, feugiat nec, luctus a, lacus.

    #

    Duis cursus. Maecenas ligula eros, blandit nec, pharetra at, semper at, magna. Nullam ac lacus. Nulla facilisi. Praesent viverra justo vitae neque. Praesent blandit adipiscing velit. Suspendisse potenti. Donec mattis, pede vel pharetra blandit, magna ligula faucibus eros, id euismod lacus dolor eget odio. Nam scelerisque. Donec non libero sed nulla mattis commodo. Ut sagittis. Donec nisi lectus, feugiat porttitor, tempor ac, tempor vitae, pede. Aenean vehicula velit eu tellus interdum rutrum. Maecenas commodo. Pellentesque nec elit. Fusce in lacus. Vivamus a libero vitae lectus hendrerit hendrerit.

    #
    #
    self end # def activate() unless @dom_object self.establish_dom_link() end if @dom_object @dom_object.tabs() end end # def generate_html() if @classes.size > 0 result = "<#{@base_tag.to_s} id='#{@uuid.to_s}' class='#{@classes.to_s}'" else result = "<#{@base_tag.to_s} id='#{@uuid.to_s}'" end # if @attributes.size > 0 @attributes.keys.each do |the_key| result = result + " #{the_key.to_s}='#{@attributes[(the_key)].to_s}'" end end # if @style.keys.size > 0 style_string = " style='" else style_string = "" end @style.keys.each do |the_key| unless @style[(the_key)] == "" the_property = GxG::Css::get_property_name(the_key) if the_property style_string = style_string + " #{the_property.to_s}: #{@style[(the_key)].to_s};" end end end if style_string.size > 0 result = (result + style_string + "'") end result = result + ">" section_headers = [] accumulator = [] contents = GxG::children_of(self) contents.each do |the_object| section_headers << {:uuid => the_object.uuid.to_s, :title => the_object.get_options()[:title].to_s} accumulator << the_object.generate_html() end result = result + "" result = (result + accumulator.join("\n") + "") # result end # end # class TabSection < GuiComponent # has label (bound to content uuid) and content (any): options = {:title => "Tab Label Text"} def hide() # No-op end def show() # No-op end end # class Table < GuiComponent # ??? def initialize(settings) super(settings) @base_tag = "table" self end end # class TableRow < GuiComponent def initialize(settings) super(settings) @base_tag = "tr" self end end # class TableHeader < GuiComponent def initialize(settings) super(settings) @base_tag = "th" self end end # class TableData < GuiComponent def initialize(settings) super(settings) @base_tag = "td" self end end # class Image < GuiComponent def initialize(settings) super(settings) @base_tag = "img" # REQUIRES attributes src=ImageURL and alt=TEXT to be set # set width and height in attributes, NOT style self end # def generate_html() if @classes.size > 0 result = "<#{@base_tag.to_s} id='#{@uuid.to_s}' class='#{@classes.to_s}'" else result = "<#{@base_tag.to_s} id='#{@uuid.to_s}'" end # if @attributes.size > 0 @attributes.keys.each do |the_key| result = result + " #{the_key.to_s}='#{@attributes[(the_key)].to_s}'" end end # if @style.keys.size > 0 style_string = " style='" else style_string = "" end @style.keys.each do |the_key| unless @style[(the_key)] == "" the_property = GxG::Css::get_property_name(the_key) if the_property style_string = style_string + " #{the_property.to_s}: #{@style[(the_key)].to_s};" end end end if style_string.size > 0 result = (result + style_string + "'") end result = result + ">" # NO end tag on img tag result end # end # class ToolTip < GuiComponent # def initialize(settings) super(settings) # This should be a modifier method (feature)- not a component. # uses *any* tag # `#{any_dom_object}.tooltip();` # Set the title attribute on the tag to allow display of the tooltip. self end # end # end end