Report abuse

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
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
95
96
require "silverlight"
include System::Windows::Controls
include System::Windows::Browser

# This fixes a problem with the value... needs to be a clr string as well.  Stupid clr
class HtmlElement
  alias_method :orig_set_property, :set_property
  def set_property(index, value)
      orig_set_property(index.to_s.to_clr_string, value.to_s.to_clr_string)
  end
end

# Monkey patch existing SilverlightApplicaiton definition to use our debugging thing
class SilverlightApplication
  def puts(message)
    Mint::Debug.puts(message)
  end
end

# Change this to be a global function in addition to the app function. It can then be accessed anywhere in the application!
def puts(message)
  Mint::Debug.puts(message)
end

module Mint
  class Debug
    
    # Better-looking debug panel, and fixes cross-browser issues (umm... it didn't work in firefox or safari before)
    def self.puts (message)
      document = HtmlPage.document  
  
      # Inject the main container
      if document.debug_container.nil?
        div = document.create_element('div')
        div[:id] = "debug_container"
        div[:style] = "position:absolute; top: 10px; right: 10px; border:solid 1px #666; padding:10px; font-size:8pt; font-family:Verdana; background-color:#EEF"
        document.get_elements_by_tag_name("body").get_Item(0).append_child(div)
      end
  
      # Inject a new set of info
      if document.debug_print.nil?
        document.debug_container.set_property "innerHTML", "<div id='debug_links' style='float:right;'><a href='#' onclick='var cont = document.getElementById(\"debug_container\"); cont.innerHTML = \"\"; cont.style.visibility = \"hidden\"'>[ clear ]</a></div><div style=' margin-bottom:10px;'><b>Debug Console</b></div><div id='debug_print'></div>"
      end

      # Show the container
      document.debug_container.style[:visibility] = 'visible'

      # Add our message
      oldhtml = document.debug_print.get_property "innerHTML"
      document.debug_print.set_property "innerHTML", "#{oldhtml} #{message} <br />"
    end
  end

  # Solution for user controls. 
  # Loads the specified xaml, and stores it in @view.  
  # Proxies @view 
  # Support for Custom Events
  class UserControl < Grid
    def initialize (name)
      raise "Must specify component name in initialize" if name.nil?
      @view = load_xaml(:name => name) #name.downcase?
      @name = name
      children.add @view
      @custom_events = {}
      
    end

    def load_xaml(options = {}) 
        options = {:type => System::Windows::Controls::UserControl, :name => "app"}.merge(options)
        view = options[:type].new
        Application.current.load_component view, "#{options[:name]}.xaml"
        view
    end
  
    def method_missing(m, *args, &block)
      listen(m, &block) unless block.nil?  # Assume they want to listen if they pass a block.  If we're wrong, it's not that big of a deal
      @view.send(m, *args, &block)
    end
    
    # Custom Event System ... Normally, use my_control.my_custom_event {} instead of my_control.listen
    def listen(name, &block)
      name = name.to_s                                        # so you can use strings or symbols. This might be a bad idea, but I don't know ruby well enough to know any better
      @custom_events[name] = [] if @custom_events[name].nil?  # I should change this to a dictionary instead and allow you to unlisten :)
      @custom_events[name] << block
    end
    
    # You can send an event object if you want.. .NET probably forces it to be some event type or something
    def dispatch(name, event = {})
      name = name.to_s
      return if @custom_events[name].nil?
      @custom_events[name].each do |block|
        block.call(self, event)
      end
    end
  end
end