shenmegui 0.2 → 0.2.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/shenmegui.rb +1 -0
- data/lib/shenmegui/controls.rb +4 -5
- data/lib/shenmegui/core.rb +46 -83
- data/lib/shenmegui/utils.rb +40 -0
- data/static/script.js +14 -6
- data/static/style.css +15 -8
- metadata +2 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: bc6619aba89ab7ea20df38ca2ac5de628a9c543b
|
4
|
+
data.tar.gz: c3ae4650931f9496dac8559595c865bf0f908657
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b16399a6fd8f540f6f7ab4bc2fd93a215e2cdad35a4a456fb17eeedc2889f124c4892b65ab621807b58ad999a175a6d7a0cad7557a8d5ee37543b5cd3fccf55b
|
7
|
+
data.tar.gz: c17d69a7269ccc136ae14371200b0849198230db52f511bbe2d2fb32b9d169657e2546176196e289a7c321919018517b55588661ddf8f79f688a26f66916f0a3
|
data/lib/shenmegui.rb
CHANGED
data/lib/shenmegui/controls.rb
CHANGED
@@ -39,7 +39,7 @@ module ShenmeGUI
|
|
39
39
|
|
40
40
|
end
|
41
41
|
|
42
|
-
available_events = %w{click input dblclick mouseover mouseout blur focus
|
42
|
+
available_events = %w{click input dblclick mouseover mouseout blur focus mousedown mouseup change onselect}.collect(&:to_sym)
|
43
43
|
available_events.each do |x|
|
44
44
|
define_method("on#{x}") do |&block|
|
45
45
|
return events[x] if block.nil?
|
@@ -111,24 +111,23 @@ module ShenmeGUI
|
|
111
111
|
end
|
112
112
|
|
113
113
|
class Button < Base
|
114
|
-
property :text
|
114
|
+
property :text
|
115
115
|
shortcut :text
|
116
116
|
|
117
117
|
end
|
118
118
|
|
119
119
|
class Textline < Base
|
120
|
-
property :text
|
120
|
+
property :text, :selection_start, :selection_end
|
121
121
|
shortcut :text
|
122
122
|
|
123
123
|
end
|
124
124
|
|
125
125
|
class Textarea < Base
|
126
|
-
property :text
|
126
|
+
property :text, :selection_start, :selection_end
|
127
127
|
shortcut :text
|
128
128
|
|
129
129
|
def <<(t)
|
130
130
|
text << "\n#{t}"
|
131
|
-
sync
|
132
131
|
end
|
133
132
|
end
|
134
133
|
|
data/lib/shenmegui/core.rb
CHANGED
@@ -1,43 +1,7 @@
|
|
1
1
|
module ShenmeGUI
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
@unhook_methods = %i{<< []= clear collect! compact! concat delete delete_at delete_if fill flatten! replace insert keep_if map map! pop push reject! replace rotate! select! shift shuffle! slice! sort! sort_by! uniq! unshift}
|
6
|
-
@unhook_methods = Hash[@unhook_methods.collect{|x| [x, Array.instance_method(x)]}]
|
7
|
-
|
8
|
-
def initialize(arr, owner)
|
9
|
-
@owner = owner
|
10
|
-
super(arr)
|
11
|
-
end
|
12
|
-
|
13
|
-
@unhook_methods.each do |k, v|
|
14
|
-
define_method(k) do |*arr, &block|
|
15
|
-
result = v.bind(self).call(*arr, &block)
|
16
|
-
@owner.sync
|
17
|
-
result
|
18
|
-
end
|
19
|
-
end
|
20
|
-
|
21
|
-
end
|
22
|
-
|
23
|
-
class HookedString < String
|
24
|
-
@unhook_methods = %i{<< []= capitalize! chomp! chop! clear concat delete! downcase! encode! force_encoding gsub! insert lstrip! succ! next! prepend replace reverse! rstrip! slice! squeeze! strip! sub! swapcase! tr! tr_s! upcase!}
|
25
|
-
@unhook_methods = Hash[@unhook_methods.collect{|x| [x, String.instance_method(x)]}]
|
26
|
-
|
27
|
-
def initialize(str, owner)
|
28
|
-
@owner = owner
|
29
|
-
super(str)
|
30
|
-
end
|
31
|
-
|
32
|
-
@unhook_methods.each do |k, v|
|
33
|
-
define_method(k) do |*arr, &block|
|
34
|
-
result = v.bind(self).call(*arr, &block)
|
35
|
-
@owner.sync
|
36
|
-
result
|
37
|
-
end
|
38
|
-
end
|
39
|
-
|
40
|
-
end
|
3
|
+
@elements = []
|
4
|
+
@temp_stack = []
|
41
5
|
|
42
6
|
class << self
|
43
7
|
attr_accessor :socket
|
@@ -73,61 +37,60 @@ module ShenmeGUI
|
|
73
37
|
@socket.send("alert:0->#{data.to_json}")
|
74
38
|
end
|
75
39
|
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
# "data:image/#{extension.downcase};base64,#{Base64.encode64(file)}"
|
80
|
-
# end
|
81
|
-
end
|
82
|
-
|
83
|
-
@elements = []
|
84
|
-
@temp_stack = []
|
40
|
+
def get_open_file_name(params={})
|
41
|
+
FileDialog.get_open_file_name(params)
|
42
|
+
end
|
85
43
|
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
44
|
+
def get_save_file_name(params={})
|
45
|
+
FileDialog.get_save_file_name(params)
|
46
|
+
end
|
47
|
+
|
48
|
+
def enable_debug
|
49
|
+
Thread.new do
|
50
|
+
ShenmeGUI.instance_eval do
|
51
|
+
bind = binding
|
52
|
+
while true
|
53
|
+
begin
|
54
|
+
command = $stdin.gets.chomp
|
55
|
+
result = eval command, bind
|
56
|
+
puts "=> #{result}"
|
57
|
+
rescue
|
58
|
+
puts "#{$!}"
|
59
|
+
end
|
97
60
|
end
|
98
61
|
end
|
99
|
-
end
|
100
62
|
|
63
|
+
end
|
101
64
|
end
|
102
|
-
end
|
103
|
-
|
104
|
-
def self.start!
|
105
|
-
ws_thread = Thread.new do
|
106
|
-
EM.run do
|
107
|
-
EM::WebSocket.run(:host => "0.0.0.0", :port => 80) do |ws|
|
108
|
-
ws.onopen do
|
109
|
-
puts "WebSocket connection open"
|
110
|
-
@elements.each { |e| e.add_events; e.sync }
|
111
|
-
end
|
112
|
-
|
113
|
-
ws.onclose { puts "Connection closed" }
|
114
65
|
|
115
|
-
|
116
|
-
|
117
|
-
|
66
|
+
def start!
|
67
|
+
ws_thread = Thread.new do
|
68
|
+
EM.run do
|
69
|
+
EM::WebSocket.run(:host => "0.0.0.0", :port => 80) do |ws|
|
70
|
+
ws.onopen do
|
71
|
+
puts "WebSocket connection open"
|
72
|
+
@elements.each { |e| e.add_events; e.sync }
|
73
|
+
end
|
74
|
+
|
75
|
+
ws.onclose { puts "Connection closed" }
|
76
|
+
|
77
|
+
ws.onmessage do |msg|
|
78
|
+
puts "Recieved message: #{msg}"
|
79
|
+
handle msg
|
80
|
+
end
|
81
|
+
|
82
|
+
@socket = ws
|
118
83
|
end
|
119
|
-
|
120
|
-
@socket = ws
|
121
84
|
end
|
122
85
|
end
|
123
|
-
end
|
124
86
|
|
125
|
-
|
126
|
-
|
87
|
+
index_path = "#{Dir.pwd}/index.html"
|
88
|
+
`start file:///#{index_path}`
|
127
89
|
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
90
|
+
ws_thread.join
|
91
|
+
rescue Interrupt
|
92
|
+
puts 'bye~'
|
93
|
+
end
|
132
94
|
|
95
|
+
end
|
133
96
|
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module ShenmeGUI
|
2
|
+
class HookedArray < Array
|
3
|
+
|
4
|
+
@unhook_methods = %i{<< []= clear collect! compact! concat delete delete_at delete_if fill flatten! replace insert keep_if map map! pop push reject! replace rotate! select! shift shuffle! slice! sort! sort_by! uniq! unshift}
|
5
|
+
@unhook_methods = Hash[@unhook_methods.collect{|x| [x, Array.instance_method(x)]}]
|
6
|
+
|
7
|
+
def initialize(arr, owner)
|
8
|
+
@owner = owner
|
9
|
+
super(arr)
|
10
|
+
end
|
11
|
+
|
12
|
+
@unhook_methods.each do |k, v|
|
13
|
+
define_method(k) do |*arr, &block|
|
14
|
+
result = v.bind(self).call(*arr, &block)
|
15
|
+
@owner.sync
|
16
|
+
result
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
|
22
|
+
class HookedString < String
|
23
|
+
@unhook_methods = %i{<< []= capitalize! chomp! chop! clear concat delete! downcase! encode! force_encoding gsub! insert lstrip! succ! next! prepend replace reverse! rstrip! slice! squeeze! strip! sub! swapcase! tr! tr_s! upcase!}
|
24
|
+
@unhook_methods = Hash[@unhook_methods.collect{|x| [x, String.instance_method(x)]}]
|
25
|
+
|
26
|
+
def initialize(str, owner)
|
27
|
+
@owner = owner
|
28
|
+
super(str)
|
29
|
+
end
|
30
|
+
|
31
|
+
@unhook_methods.each do |k, v|
|
32
|
+
define_method(k) do |*arr, &block|
|
33
|
+
result = v.bind(self).call(*arr, &block)
|
34
|
+
@owner.sync
|
35
|
+
result
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
40
|
+
end
|
data/static/script.js
CHANGED
@@ -22,23 +22,27 @@ function sync(obj){
|
|
22
22
|
|
23
23
|
var changeListeners = {
|
24
24
|
textline: {
|
25
|
-
event: 'input',
|
25
|
+
event: ['input','select'],
|
26
26
|
function: (function(){
|
27
27
|
this.properties.text = this.value;
|
28
|
+
this.properties.selection_start = this.selectionStart;
|
29
|
+
this.properties.selection_end = this.selectionEnd;
|
28
30
|
sync(this);
|
29
31
|
})
|
30
32
|
},
|
31
33
|
|
32
34
|
textarea: {
|
33
|
-
event: 'input',
|
35
|
+
event: ['input','select'],
|
34
36
|
function: (function(){
|
35
37
|
this.properties.text = this.value;
|
38
|
+
this.properties.selection_start = this.selectionStart;
|
39
|
+
this.properties.selection_end = this.selectionEnd;
|
36
40
|
sync(this);
|
37
41
|
})
|
38
42
|
},
|
39
43
|
|
40
44
|
checkbox: {
|
41
|
-
event: 'change',
|
45
|
+
event: ['change'],
|
42
46
|
function: (function(){
|
43
47
|
var options = this.getElementsByTagName('input');
|
44
48
|
var checked = [];
|
@@ -51,7 +55,7 @@ var changeListeners = {
|
|
51
55
|
},
|
52
56
|
|
53
57
|
select: {
|
54
|
-
event: 'change',
|
58
|
+
event: ['change'],
|
55
59
|
function: (function(){
|
56
60
|
this.properties.checked = this.value;
|
57
61
|
sync(this);
|
@@ -59,7 +63,7 @@ var changeListeners = {
|
|
59
63
|
},
|
60
64
|
|
61
65
|
radio: {
|
62
|
-
event: 'change',
|
66
|
+
event: ['change'],
|
63
67
|
function: (function(){
|
64
68
|
this.properties.checked = this.elements['radio'].value;
|
65
69
|
sync(this);
|
@@ -70,7 +74,11 @@ var changeListeners = {
|
|
70
74
|
function addChangeListener(obj){
|
71
75
|
var type = obj.getAttribute('data-type');
|
72
76
|
changeListener = changeListeners[type];
|
73
|
-
if(changeListener)
|
77
|
+
if(changeListener){
|
78
|
+
for(var i in changeListener.event){
|
79
|
+
obj.addEventListener(changeListener.event[i], changeListener.function);
|
80
|
+
}
|
81
|
+
}
|
74
82
|
}
|
75
83
|
|
76
84
|
function addEvents(obj, events){
|
data/static/style.css
CHANGED
@@ -16,7 +16,10 @@ body {
|
|
16
16
|
border-bottom-color: #808080;
|
17
17
|
box-shadow: 1px 1px 0 0 #000;
|
18
18
|
width: 400px;
|
19
|
-
cursor: default;
|
19
|
+
cursor: default;
|
20
|
+
float: left;
|
21
|
+
margin-right: 30px;
|
22
|
+
margin-bottom: 20px; }
|
20
23
|
.window .content {
|
21
24
|
padding: 7px 10px; }
|
22
25
|
.window .title {
|
@@ -34,13 +37,21 @@ body {
|
|
34
37
|
float: left;
|
35
38
|
margin-right: 2px; }
|
36
39
|
|
40
|
+
.button, .checkbox, .image, .progress, .radio, .select, .textarea, .textline, .label {
|
41
|
+
display: inline-block;
|
42
|
+
margin-bottom: 0.5em;
|
43
|
+
margin-right: 0.2em;
|
44
|
+
max-width: 100%; }
|
45
|
+
|
37
46
|
.stack > * {
|
38
|
-
display: block !important;
|
47
|
+
display: block !important;
|
48
|
+
max-width: 100%; }
|
39
49
|
|
40
50
|
.flow > * {
|
41
|
-
display: inline !important;
|
51
|
+
display: inline-block !important;
|
52
|
+
max-width: 100%; }
|
42
53
|
|
43
|
-
.
|
54
|
+
.progress {
|
44
55
|
width: 100%; }
|
45
56
|
|
46
57
|
button {
|
@@ -124,10 +135,6 @@ input[type="radio"]:checked + label:before {
|
|
124
135
|
.option {
|
125
136
|
margin-right: 1em; }
|
126
137
|
|
127
|
-
.button, .checkbox, .image, .progress, .radio, .select, .textarea, .textline, .label {
|
128
|
-
margin-bottom: 0.5em;
|
129
|
-
margin-right: 0.2em; }
|
130
|
-
|
131
138
|
.label {
|
132
139
|
font-weight: bolder; }
|
133
140
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: shenmegui
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 0.2.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- CicholGricenchos
|
@@ -34,6 +34,7 @@ files:
|
|
34
34
|
- lib/shenmegui/controls.rb
|
35
35
|
- lib/shenmegui/core.rb
|
36
36
|
- lib/shenmegui/file_dialog.rb
|
37
|
+
- lib/shenmegui/utils.rb
|
37
38
|
- static/script.js
|
38
39
|
- static/style.css
|
39
40
|
- templates/body.erb
|