Module: ShenmeGUI

Defined in:
lib/shenmegui/utils.rb,
lib/shenmegui/core.rb,
lib/shenmegui/controls.rb,
lib/shenmegui/file_dialog.rb

Overview

用在控件的属性上,给Array String Hash加上钩子,监视其对自身的操作,一旦内容有改变立刻请求同步控件属性

Defined Under Namespace

Modules: Control, FileDialog Classes: FakeSocket

Class Attribute Summary collapse

Class Method Summary collapse

Class Attribute Details

.elementsObject (readonly)

Returns the value of attribute elements.



20
21
22
# File 'lib/shenmegui/core.rb', line 20

def elements
  @elements
end

.socketObject (readonly)

Returns the value of attribute socket.



20
21
22
# File 'lib/shenmegui/core.rb', line 20

def socket
  @socket
end

.thisObject (readonly)

Returns the value of attribute this.



20
21
22
# File 'lib/shenmegui/core.rb', line 20

def this
  @this
end

Class Method Details

.alert(msg) ⇒ Object



58
59
60
61
# File 'lib/shenmegui/core.rb', line 58

def alert(msg)
  data = {message: msg}
  @socket.send("alert:0->#{data.to_json}")
end

.app(params = {}, &block) ⇒ Object



42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
# File 'lib/shenmegui/core.rb', line 42

def app(params={}, &block)
  raise "ShenmeGUI app has been initialized" if @initialized
  @initialized = true
  @fake_socket = FakeSocket.new
  @socket = @fake_socket
  body(params, &block)
  #找一个空闲的端口,不太好看
  temp_server = TCPServer.open('localhost', 0)
  @port = temp_server.addr[1]
  temp_server.close
  @title = params[:title] || 'Application'
  app_dir = File.expand_path($PROGRAM_NAME).match(/(.+)\/.+/)[1]
  File.open("#{app_dir}/index.html", 'w'){ |f| f.write @elements[0].render(port: @port, title: @title) }
  nil
end

.enable_debuggingObject



71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
# File 'lib/shenmegui/core.rb', line 71

def enable_debugging
  Thread.new do
    ShenmeGUI.instance_eval do
      bind = binding
      while true
        begin
          command = $stdin.gets.chomp
          result = bind.eval command
          puts "=> #{result}"
        rescue
          puts "#{$!}"
        end
      end
    end

  end
end

.get_open_file_name(params = {}) ⇒ Object



63
64
65
# File 'lib/shenmegui/core.rb', line 63

def get_open_file_name(params={})
  FileDialog.get_open_file_name(params)
end

.get_save_file_name(params = {}) ⇒ Object



67
68
69
# File 'lib/shenmegui/core.rb', line 67

def get_save_file_name(params={})
  FileDialog.get_save_file_name(params)
end

.handle_message(msg) ⇒ Object



22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
# File 'lib/shenmegui/core.rb', line 22

def handle_message(msg)
  match_data = msg.match(/(.+?):(\d+)(?:->)?({.+?})?/)
  command = match_data[1].to_sym
  id = match_data[2].to_i
  target = @elements[id]
  data = JSON.parse(match_data[3]) if match_data[3]
  case command
    when :sync
      target.update_properties(data)
    else
      event_lambda = target.events[command]
      @this = @elements[id]
      ShenmeGUI.instance_exec(&event_lambda) if event_lambda
      @this = nil

  end
  target
end

.open_browserObject



89
90
91
92
93
94
95
96
97
98
99
100
# File 'lib/shenmegui/core.rb', line 89

def open_browser
  app_dir = File.expand_path($PROGRAM_NAME).match(/(.+)\/.+/)[1]
  index_path = "#{app_dir}/index.html"
  if Gem.win_platform?
    `start #{index_path}`
  elsif Gem.platforms[1].os == 'linux'
    `xdg-open #{index_path}`
  elsif Gem.platforms[1].os == 'darwin'
    `open #{index_path}`
  end
rescue
end

.start!Object



102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
# File 'lib/shenmegui/core.rb', line 102

def start!
  EM.run do
    EM::WebSocket.run(:host => "0.0.0.0", :port => @port) do |ws|
      ws.onopen do
        puts "WebSocket connection open"
        # 同时只能有一个连接,而正常连接关闭的时候会把@socket指向FakeSocket,如果建立连接的时候发现@socket是WebSocket,便把连接关掉
        @socket.close if @socket.respond_to? :close
        @socket = ws

        class << ws
          alias :original_send :send
          def send(msg)
            puts "Sent: #{msg}"
            original_send(msg)
          end
        end

        @elements.each do |e|
          e.sync_events
          e.sync
        end
        @socket.send(@fake_socket.messages.shift) until @fake_socket.messages.empty?
      end

      ws.onclose do
        puts "Connection closed"
        @socket = @fake_socket
      end

      ws.onmessage do |msg|
        puts "Recieved: #{msg}"
        handle_message msg
      end

    end
  end
rescue Interrupt
  puts 'bye~'
end