cryptopunks-gui 0.0.10 → 0.0.14
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +24 -0
- data/LICENSE.txt +1 -1
- data/README.md +16 -52
- data/VERSION +1 -1
- data/app/cryptopunks_gui.rb +17 -319
- data/app/model/image.rb +187 -0
- data/app/view/help_dialog.rb +31 -0
- data/app/view/image_frame.rb +145 -0
- data/app/view/menu_bar.rb +88 -0
- data/app/view/preferences_dialog.rb +174 -0
- data/app/view/style_options_frame.rb +60 -0
- data/bin/cryptopunks-gui +0 -0
- data/cryptopunks-gui.gemspec +68 -67
- metadata +15 -13
- data/bin/cryptopunks-mac-gui +0 -8
- data/bin/cryptopunks-mac-gui.rb +0 -8
- data/bin/package-mac +0 -8
- data/bin/package-mac-app +0 -5
- data/bin/package-mac-dmg +0 -6
data/app/model/image.rb
ADDED
@@ -0,0 +1,187 @@
|
|
1
|
+
class CryptopunksGui
|
2
|
+
module Model
|
3
|
+
class Image
|
4
|
+
PALETTES = ['Standard'] + (Palette8bit.constants).map(&:to_s).map {|palette| palette.split('_').map(&:capitalize).join(' ')}.reject { |palette| palette.include?(' ') }.sort
|
5
|
+
STYLES = ['Normal', 'Led', 'Sketch']
|
6
|
+
OUTPUT_LOCATION_DEFAULT = File.join(Dir.home, 'cryptopunks')
|
7
|
+
CONFIG_FILE = File.join(OUTPUT_LOCATION_DEFAULT, 'cryptopunks.yml')
|
8
|
+
COLLECTIONS_YAML_PATH = File.join(OUTPUT_LOCATION_DEFAULT, 'cryptopunks-collections.yml')
|
9
|
+
COLLECTIONS_YAML_URL = 'https://raw.githubusercontent.com/cryptopunksnotdead/cryptopunks-gui/master/cryptopunks-collections.yml'
|
10
|
+
COLLECTIONS_YAML_REPO_PATH = File.expand_path('../../cryptopunks-collections.yml', __dir__)
|
11
|
+
|
12
|
+
attr_accessor :collection, :image_index, :zoom, :palette, :style, :led_spacing, :led_round_corner, :sketch_line, :flip, :mirror,
|
13
|
+
:collection_size, :collections_map, :images, :image_location, :output_location, :config
|
14
|
+
|
15
|
+
def initialize
|
16
|
+
initialize_output_location
|
17
|
+
initialize_collections_map
|
18
|
+
initialize_collection
|
19
|
+
load_config
|
20
|
+
initialize_defaults
|
21
|
+
observe_image_attribute_changes
|
22
|
+
end
|
23
|
+
|
24
|
+
def collection_options
|
25
|
+
@collections_map.keys.select {|collection_name| @collections_map[collection_name][:enabled]}
|
26
|
+
end
|
27
|
+
|
28
|
+
def palette_options
|
29
|
+
PALETTES
|
30
|
+
end
|
31
|
+
|
32
|
+
def style_options
|
33
|
+
STYLES
|
34
|
+
end
|
35
|
+
|
36
|
+
def initialize_output_location
|
37
|
+
@output_location = OUTPUT_LOCATION_DEFAULT
|
38
|
+
FileUtils.mkdir_p(@output_location)
|
39
|
+
end
|
40
|
+
|
41
|
+
def initialize_collections_map(reset: false)
|
42
|
+
FileUtils.touch(COLLECTIONS_YAML_PATH)
|
43
|
+
@collections_map = reset ? {} : (YAML.load(File.read(COLLECTIONS_YAML_PATH)) || {})
|
44
|
+
new_collections_map = {}
|
45
|
+
begin
|
46
|
+
http_response = Net::HTTP.get_response(URI(COLLECTIONS_YAML_URL))
|
47
|
+
if http_response.is_a?(Net::HTTPSuccess)
|
48
|
+
new_collections_map = YAML.load(http_response.body)
|
49
|
+
else
|
50
|
+
raise "code: #{http_response.code} message: #{http_response.message}"
|
51
|
+
end
|
52
|
+
rescue StandardError, SocketError => e
|
53
|
+
puts "Failed to utilize collection YAML from: #{COLLECTIONS_YAML_URL}"
|
54
|
+
puts e.full_message
|
55
|
+
puts "Utilizing local collection YAML instead: #{COLLECTIONS_YAML_REPO_PATH}"
|
56
|
+
new_collections_map = YAML.load(File.read(COLLECTIONS_YAML_REPO_PATH)) rescue {}
|
57
|
+
end
|
58
|
+
@collections_map_observers ||= {}
|
59
|
+
new_collections_map.each do |collection_name, collection_options|
|
60
|
+
@collections_map[collection_name] ||= {}
|
61
|
+
original_collections_map_for_collection = @collections_map[collection_name]
|
62
|
+
@collections_map[collection_name] = @collections_map[collection_name]
|
63
|
+
@collections_map[collection_name].reverse_merge!(collection_options)
|
64
|
+
@collections_map[collection_name][:enabled] = true unless @collections_map[collection_name].has_key?(:enabled)
|
65
|
+
@collections_map_observers[collection_name] ||= Glimmer::DataBinding::Observer.proc { |value, key|
|
66
|
+
if key == :enabled
|
67
|
+
self.collection = @collections_map.find { |name, options| options[:enabled] }.first if key == :enabled && value == false && @collection == collection_name
|
68
|
+
notify_observers(:collection_options)
|
69
|
+
end
|
70
|
+
save_collections_map
|
71
|
+
}.tap {|o| o.observe(original_collections_map_for_collection)}
|
72
|
+
end
|
73
|
+
@collections_map_observer ||= Glimmer::DataBinding::Observer.proc { |collection_options, collection_name|
|
74
|
+
if collection_options.nil?
|
75
|
+
self.collection = @collections_map.find { |name, options| options[:enabled] }.first if @collection == collection_name
|
76
|
+
self.collection = collection_name if @collections_map.select { |name, options| options[:enabled] }.count == 0
|
77
|
+
end
|
78
|
+
notify_observers(:collection_options)
|
79
|
+
save_collections_map
|
80
|
+
}.tap {|o| o.observe(@collections_map)}
|
81
|
+
save_collections_map
|
82
|
+
end
|
83
|
+
|
84
|
+
def save_collections_map
|
85
|
+
normalized_collections_map = Hash[@collections_map.map {|k,v| [k, v.to_h]}]
|
86
|
+
File.write(COLLECTIONS_YAML_PATH, YAML.dump(normalized_collections_map))
|
87
|
+
end
|
88
|
+
|
89
|
+
def initialize_collection
|
90
|
+
return if @collection && @collection == @last_collection
|
91
|
+
@collection ||= @collections_map.keys.first
|
92
|
+
url = @collections_map[@collection][:url]
|
93
|
+
width = @collections_map[@collection][:width]
|
94
|
+
height = @collections_map[@collection][:height]
|
95
|
+
@image_file = File.join(OUTPUT_LOCATION_DEFAULT, File.basename(url))
|
96
|
+
File.binwrite(@image_file, Net::HTTP.get(URI(url))) unless File.exist?(@image_file)
|
97
|
+
@images ||= {}
|
98
|
+
@images[@collection] ||= Punks::Image::Composite.read(@image_file, width: width, height: height)
|
99
|
+
@last_collection = @collection
|
100
|
+
self.image_index = 0
|
101
|
+
end
|
102
|
+
|
103
|
+
def load_config
|
104
|
+
FileUtils.touch(CONFIG_FILE)
|
105
|
+
@config = YAML.load(File.read(CONFIG_FILE)) || {}
|
106
|
+
@output_location = @config[:output_location]
|
107
|
+
@config[:output_location] = @output_location = OUTPUT_LOCATION_DEFAULT if @output_location.nil?
|
108
|
+
end
|
109
|
+
|
110
|
+
def save_config
|
111
|
+
File.write(CONFIG_FILE, YAML.dump(@config))
|
112
|
+
end
|
113
|
+
|
114
|
+
def initialize_defaults
|
115
|
+
@collection = @collections_map.keys.first
|
116
|
+
@zoom = 12
|
117
|
+
@palette = PALETTES.first
|
118
|
+
@style = STYLES.first
|
119
|
+
@led_spacing = 2
|
120
|
+
@led_round_corner = false
|
121
|
+
@sketch_line = 1
|
122
|
+
@mirror = false
|
123
|
+
@flip = false
|
124
|
+
end
|
125
|
+
|
126
|
+
def observe_image_attribute_changes
|
127
|
+
observer = Glimmer::DataBinding::Observer.proc { generate_image }
|
128
|
+
observer.observe(self, :collection)
|
129
|
+
observer.observe(self, :image_index)
|
130
|
+
observer.observe(self, :zoom)
|
131
|
+
observer.observe(self, :palette)
|
132
|
+
observer.observe(self, :style)
|
133
|
+
observer.observe(self, :led_spacing)
|
134
|
+
observer.observe(self, :led_round_corner)
|
135
|
+
observer.observe(self, :sketch_line)
|
136
|
+
observer.observe(self, :mirror)
|
137
|
+
observer.observe(self, :flip)
|
138
|
+
end
|
139
|
+
|
140
|
+
def generate_image
|
141
|
+
initialize_collection
|
142
|
+
return if @image_index.to_i >= @images[@collection].size
|
143
|
+
new_image_location = File.join(@output_location, "#{@collection.gsub(' ', '').downcase}-#{@image_index}#{"x#{@zoom}" if @zoom.to_i > 1}#{"-#{@palette.underscore}" if @palette != PALETTES.first}#{"-#{@style.underscore}" if @style != STYLES.first}#{"-spacing#{@led_spacing.to_i}" if @style == 'Led'}#{'-round-corner' if @style == 'Led' && @led_round_corner}#{"-line#{@sketch_line.to_i}" if @style == 'Sketch'}#{'-mirror' if @mirror}#{'-flip' if @flip}.png")
|
144
|
+
puts "Writing punk image to #{new_image_location}"
|
145
|
+
selected_punk = @images[@collection][@image_index.to_i]
|
146
|
+
selected_punk = selected_punk.change_palette8bit(Palette8bit.const_get(@palette.gsub(' ', '_').upcase.to_sym)) if @palette != PALETTES.first
|
147
|
+
@original_zoom = @zoom
|
148
|
+
if @previous_collection && @collection != @previous_collection && @collections_map[@collection][:width] != @collections_map[@previous_collection][:width]
|
149
|
+
@zoom = @collections_map[@collection][:default_zoom]
|
150
|
+
end
|
151
|
+
if @style != STYLES.first
|
152
|
+
style_options = {}
|
153
|
+
if @style == 'Led'
|
154
|
+
style_options[:spacing] = @led_spacing.to_i
|
155
|
+
style_options[:round_corner] = @led_round_corner
|
156
|
+
end
|
157
|
+
if @style == 'Sketch'
|
158
|
+
style_options[:line] = @sketch_line.to_i
|
159
|
+
end
|
160
|
+
selected_punk = selected_punk.send(@style.underscore, @zoom.to_i, **style_options)
|
161
|
+
end
|
162
|
+
selected_punk = selected_punk.mirror if @mirror
|
163
|
+
selected_punk = selected_punk.flip if @flip
|
164
|
+
selected_punk = selected_punk.zoom(@zoom.to_i) if @style == STYLES.first
|
165
|
+
selected_punk.save(new_image_location)
|
166
|
+
self.image_location = new_image_location
|
167
|
+
notify_observers(:zoom) if @zoom != @original_zoom
|
168
|
+
@previous_style = @style
|
169
|
+
@previous_collection = @collection
|
170
|
+
end
|
171
|
+
|
172
|
+
def change_output_location(new_output_location)
|
173
|
+
@output_location = new_output_location
|
174
|
+
@config[:output_location] = @output_location
|
175
|
+
save_config
|
176
|
+
generate_image
|
177
|
+
end
|
178
|
+
|
179
|
+
def reset_output_location
|
180
|
+
@output_location = OUTPUT_LOCATION_DEFAULT
|
181
|
+
@config[:output_location] = @output_location
|
182
|
+
save_config
|
183
|
+
generate_image
|
184
|
+
end
|
185
|
+
end
|
186
|
+
end
|
187
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
class CryptopunksGui
|
2
|
+
module View
|
3
|
+
module HelpDialog
|
4
|
+
def help_dialog(root: )
|
5
|
+
toplevel(root) {
|
6
|
+
title 'CryptoPunks GUI - README.md'
|
7
|
+
width 800
|
8
|
+
height 600
|
9
|
+
escapable true
|
10
|
+
|
11
|
+
help_dialog = text {
|
12
|
+
grid row: 0, column: 0, row_weight: 1, column_weight: 1
|
13
|
+
value help
|
14
|
+
}
|
15
|
+
|
16
|
+
help_dialog_yscrollbar = scrollbar {
|
17
|
+
grid row: 0, column: 1
|
18
|
+
orient 'vertical'
|
19
|
+
}
|
20
|
+
help_dialog.yscrollbar help_dialog_yscrollbar.tk
|
21
|
+
|
22
|
+
help_dialog_xscrollbar = scrollbar {
|
23
|
+
grid row: 1, column: 0, column_span: 2
|
24
|
+
orient 'horizontal'
|
25
|
+
}
|
26
|
+
help_dialog.xscrollbar help_dialog_xscrollbar.tk
|
27
|
+
}
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,145 @@
|
|
1
|
+
class CryptopunksGui
|
2
|
+
module View
|
3
|
+
module ImageFrame
|
4
|
+
def image_frame(root: , image: )
|
5
|
+
image_label = output_location_entry = image_index_spinbox = style_options_container_frame = nil
|
6
|
+
|
7
|
+
frame {
|
8
|
+
label {
|
9
|
+
text 'Collection:'
|
10
|
+
}
|
11
|
+
combobox {
|
12
|
+
readonly true
|
13
|
+
values <= [image, :collection_options]
|
14
|
+
text <=> [image, :collection]
|
15
|
+
}
|
16
|
+
|
17
|
+
label {
|
18
|
+
text 'Image Index:'
|
19
|
+
}
|
20
|
+
image_index_spinbox = spinbox {
|
21
|
+
from 0
|
22
|
+
to image.images[image.collection].size - 1
|
23
|
+
text <=> [image, :image_index]
|
24
|
+
}
|
25
|
+
|
26
|
+
label {
|
27
|
+
text 'Zoom:'
|
28
|
+
}
|
29
|
+
spinbox {
|
30
|
+
from 1
|
31
|
+
to 72
|
32
|
+
text <=> [image, :zoom]
|
33
|
+
}
|
34
|
+
|
35
|
+
label {
|
36
|
+
text 'Palette:'
|
37
|
+
}
|
38
|
+
combobox {
|
39
|
+
readonly true
|
40
|
+
text <=> [image, :palette]
|
41
|
+
}
|
42
|
+
|
43
|
+
label {
|
44
|
+
text 'Style:'
|
45
|
+
}
|
46
|
+
combobox {
|
47
|
+
readonly true
|
48
|
+
text <=> [image, :style, after_write: ->(val) {add_style_options(style_options_container_frame: style_options_container_frame, image: image)}]
|
49
|
+
}
|
50
|
+
|
51
|
+
style_options_container_frame = frame {
|
52
|
+
padding 0
|
53
|
+
}
|
54
|
+
|
55
|
+
frame {
|
56
|
+
padding 0
|
57
|
+
|
58
|
+
checkbutton {
|
59
|
+
grid row: 0, column: 0, column_weight: 0
|
60
|
+
variable <=> [image, :mirror]
|
61
|
+
}
|
62
|
+
label {
|
63
|
+
grid row: 0, column: 1
|
64
|
+
text 'Mirror'
|
65
|
+
|
66
|
+
on('Button-1') do
|
67
|
+
image.mirror = !image.mirror
|
68
|
+
end
|
69
|
+
}
|
70
|
+
|
71
|
+
checkbutton {
|
72
|
+
grid row: 0, column: 2
|
73
|
+
variable <=> [image, :flip]
|
74
|
+
}
|
75
|
+
label {
|
76
|
+
grid row: 0, column: 3
|
77
|
+
text 'Flip'
|
78
|
+
|
79
|
+
on('Button-1') do
|
80
|
+
image.flip = !image.flip
|
81
|
+
end
|
82
|
+
}
|
83
|
+
}
|
84
|
+
|
85
|
+
label {
|
86
|
+
text 'Output Location:'
|
87
|
+
}
|
88
|
+
frame {
|
89
|
+
padding 0
|
90
|
+
|
91
|
+
output_location_entry = entry {
|
92
|
+
grid row: 0, column: 0
|
93
|
+
readonly true
|
94
|
+
width 47
|
95
|
+
}
|
96
|
+
button {
|
97
|
+
grid row: 0, column: 1
|
98
|
+
text '...'
|
99
|
+
width 1.1
|
100
|
+
|
101
|
+
on('command') do
|
102
|
+
change_output_location(root: root, image: image)
|
103
|
+
end
|
104
|
+
}
|
105
|
+
}
|
106
|
+
|
107
|
+
image_label = label {
|
108
|
+
grid row_weight: 1
|
109
|
+
}
|
110
|
+
}
|
111
|
+
|
112
|
+
register_image_frame_observers(image_label: image_label, output_location_entry: output_location_entry, image_index_spinbox: image_index_spinbox, image: image)
|
113
|
+
end
|
114
|
+
|
115
|
+
def register_image_frame_observers(image_label: , output_location_entry: , image_index_spinbox: , image: )
|
116
|
+
Glimmer::DataBinding::Observer.proc do
|
117
|
+
image_label.image = output_location_entry.text = image.image_location
|
118
|
+
end.observe(image, :image_location)
|
119
|
+
|
120
|
+
Glimmer::DataBinding::Observer.proc do
|
121
|
+
image_index_spinbox.to = image.images[image.collection].size - 1
|
122
|
+
end.observe(image, :collection)
|
123
|
+
end
|
124
|
+
|
125
|
+
def add_style_options(style_options_container_frame: , image: )
|
126
|
+
style_options_container_frame.children.each(&:destroy)
|
127
|
+
style_options_container_frame.content {
|
128
|
+
case image.style
|
129
|
+
when 'Led'
|
130
|
+
led_style_options_frame(image: image)
|
131
|
+
when 'Sketch'
|
132
|
+
sketch_style_options_frame(image: image)
|
133
|
+
else
|
134
|
+
no_style_options_frame
|
135
|
+
end
|
136
|
+
}
|
137
|
+
end
|
138
|
+
|
139
|
+
def change_output_location(root: , image: )
|
140
|
+
new_output_location = choose_directory(parent: root)
|
141
|
+
image.change_output_location(new_output_location) unless new_output_location.to_s.empty?
|
142
|
+
end
|
143
|
+
end
|
144
|
+
end
|
145
|
+
end
|
@@ -0,0 +1,88 @@
|
|
1
|
+
# require_relative 'preferences_dialog'
|
2
|
+
require_relative 'help_dialog'
|
3
|
+
|
4
|
+
class CryptopunksGui
|
5
|
+
module View
|
6
|
+
module MenuBar
|
7
|
+
# include View::PreferencesDialog
|
8
|
+
include View::HelpDialog
|
9
|
+
|
10
|
+
LICENSE = File.expand_path('../../LICENSE.txt', __dir__)
|
11
|
+
HELP = File.expand_path('../../README.md', __dir__)
|
12
|
+
|
13
|
+
def cryptopunks_gui_menu_bar(root: , image: )
|
14
|
+
menu {
|
15
|
+
if OS.mac?
|
16
|
+
menu(:application) {
|
17
|
+
menu_item(:about, label: 'About') {
|
18
|
+
accelerator OS.mac? ? 'Command+Shift+A' : 'Control+Alt+A'
|
19
|
+
|
20
|
+
on('command') do
|
21
|
+
show_about_dialog(root: root)
|
22
|
+
end
|
23
|
+
}
|
24
|
+
|
25
|
+
# menu_item(:preferences) {
|
26
|
+
# on('command') do
|
27
|
+
# preferences_dialog(root: root, image: image)
|
28
|
+
# end
|
29
|
+
# }
|
30
|
+
}
|
31
|
+
end
|
32
|
+
|
33
|
+
menu(label: 'File', underline: 0) {
|
34
|
+
menu_item(label: 'Change Output Location...', underline: 7) {
|
35
|
+
accelerator OS.mac? ? 'Command+O' : 'Control+O'
|
36
|
+
|
37
|
+
on('command') do
|
38
|
+
change_output_location(root: root, image: image) # assumes View::ImageFrame is mixed in
|
39
|
+
end
|
40
|
+
}
|
41
|
+
|
42
|
+
menu_item(label: 'Reset Output Location', underline: 0) {
|
43
|
+
on('command') do
|
44
|
+
image.reset_output_location
|
45
|
+
end
|
46
|
+
}
|
47
|
+
|
48
|
+
menu_item(:separator)
|
49
|
+
|
50
|
+
# menu_item(label: 'Preferences...', underline: 0) {
|
51
|
+
# on('command') do
|
52
|
+
# preferences_dialog(root: root, image: image)
|
53
|
+
# end
|
54
|
+
# }
|
55
|
+
|
56
|
+
menu_item(:separator)
|
57
|
+
|
58
|
+
menu_item(label: 'Exit', underline: 1) {
|
59
|
+
on('command') do
|
60
|
+
exit(0)
|
61
|
+
end
|
62
|
+
}
|
63
|
+
}
|
64
|
+
|
65
|
+
menu(label: 'Help') {
|
66
|
+
menu_item(:help) {
|
67
|
+
on('command') do
|
68
|
+
help_dialog(root: root)
|
69
|
+
end
|
70
|
+
}
|
71
|
+
}
|
72
|
+
}
|
73
|
+
end
|
74
|
+
|
75
|
+
def show_about_dialog(root: )
|
76
|
+
message_box(parent: root, title: 'CryptoPunks GUI', message: "CryptoPunks GUI\n\n#{license}")
|
77
|
+
end
|
78
|
+
|
79
|
+
def license
|
80
|
+
@license ||= File.read(LICENSE)
|
81
|
+
end
|
82
|
+
|
83
|
+
def help
|
84
|
+
@help ||= File.read(HELP)
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
@@ -0,0 +1,174 @@
|
|
1
|
+
class CryptopunksGui
|
2
|
+
module View
|
3
|
+
module PreferencesDialog
|
4
|
+
def preferences_dialog(root: , image: )
|
5
|
+
toplevel(root) {
|
6
|
+
title 'Preferences'
|
7
|
+
width 1280
|
8
|
+
height 700
|
9
|
+
escapable true
|
10
|
+
|
11
|
+
scrollbar_frame {
|
12
|
+
label {
|
13
|
+
grid row: 0, column: 0
|
14
|
+
text ''
|
15
|
+
}
|
16
|
+
|
17
|
+
label {
|
18
|
+
grid row: 0, column: 1
|
19
|
+
text 'Collection Name'
|
20
|
+
}
|
21
|
+
|
22
|
+
label {
|
23
|
+
grid row: 0, column: 2
|
24
|
+
text 'URL'
|
25
|
+
width 82
|
26
|
+
}
|
27
|
+
|
28
|
+
label {
|
29
|
+
grid row: 0, column: 3
|
30
|
+
text 'Width'
|
31
|
+
width 3
|
32
|
+
}
|
33
|
+
|
34
|
+
label {
|
35
|
+
grid row: 0, column: 4
|
36
|
+
text 'Height'
|
37
|
+
width 3
|
38
|
+
}
|
39
|
+
|
40
|
+
label {
|
41
|
+
grid row: 0, column: 5
|
42
|
+
text "Default\nZoom"
|
43
|
+
width 3
|
44
|
+
}
|
45
|
+
|
46
|
+
label {
|
47
|
+
grid row: 0, column: 6, column_span: 3
|
48
|
+
text 'Actions'
|
49
|
+
}
|
50
|
+
|
51
|
+
image.collections_map.each_with_index do |pair, index|
|
52
|
+
collection_name, collection_options = pair
|
53
|
+
row = index + 1
|
54
|
+
|
55
|
+
checkbutton { |cb|
|
56
|
+
grid row: row, column: 0
|
57
|
+
# TODO consider using hash_proxy object to bind more effectively
|
58
|
+
variable <= [image.collections_map[collection_name], :enabled]
|
59
|
+
|
60
|
+
on('command') do
|
61
|
+
collection_options[:enabled] = cb.variable
|
62
|
+
end
|
63
|
+
}
|
64
|
+
|
65
|
+
entry {
|
66
|
+
grid row: row, column: 1
|
67
|
+
text collection_name
|
68
|
+
}
|
69
|
+
|
70
|
+
entry {
|
71
|
+
grid row: row, column: 2
|
72
|
+
text collection_options[:url]
|
73
|
+
width 82
|
74
|
+
}
|
75
|
+
|
76
|
+
spinbox {
|
77
|
+
grid row: row, column: 3
|
78
|
+
from 1
|
79
|
+
to 512
|
80
|
+
text collection_options[:width]
|
81
|
+
width 3
|
82
|
+
}
|
83
|
+
|
84
|
+
spinbox {
|
85
|
+
grid row: row, column: 4
|
86
|
+
from 1
|
87
|
+
to 512
|
88
|
+
text collection_options[:height]
|
89
|
+
width 3
|
90
|
+
}
|
91
|
+
|
92
|
+
spinbox {
|
93
|
+
grid row: row, column: 5
|
94
|
+
from 1
|
95
|
+
to 72
|
96
|
+
text collection_options[:default_zoom]
|
97
|
+
width 3
|
98
|
+
}
|
99
|
+
|
100
|
+
button {
|
101
|
+
grid row: row, column: 6
|
102
|
+
text 'X'
|
103
|
+
width 1
|
104
|
+
}
|
105
|
+
button {
|
106
|
+
grid row: row, column: 7
|
107
|
+
text '^'
|
108
|
+
width 1
|
109
|
+
}
|
110
|
+
button {
|
111
|
+
grid row: row, column: 8
|
112
|
+
text 'v'
|
113
|
+
width 1
|
114
|
+
}
|
115
|
+
end
|
116
|
+
|
117
|
+
row = image.collections_map.keys.size + 1
|
118
|
+
|
119
|
+
checkbutton {
|
120
|
+
grid row: row, column: 0
|
121
|
+
|
122
|
+
}
|
123
|
+
|
124
|
+
entry {
|
125
|
+
grid row: row, column: 1
|
126
|
+
text ''
|
127
|
+
}
|
128
|
+
|
129
|
+
entry {
|
130
|
+
grid row: row, column: 2
|
131
|
+
text ''
|
132
|
+
width 82
|
133
|
+
}
|
134
|
+
|
135
|
+
spinbox {
|
136
|
+
grid row: row, column: 3
|
137
|
+
from 1
|
138
|
+
to 512
|
139
|
+
text '24'
|
140
|
+
width 3
|
141
|
+
}
|
142
|
+
|
143
|
+
spinbox {
|
144
|
+
grid row: row, column: 4
|
145
|
+
from 1
|
146
|
+
to 512
|
147
|
+
text '24'
|
148
|
+
width 3
|
149
|
+
}
|
150
|
+
|
151
|
+
spinbox {
|
152
|
+
grid row: row, column: 5
|
153
|
+
from 1
|
154
|
+
to 72
|
155
|
+
text '12'
|
156
|
+
width 3
|
157
|
+
}
|
158
|
+
}
|
159
|
+
|
160
|
+
frame {
|
161
|
+
button {
|
162
|
+
text 'Reset'
|
163
|
+
|
164
|
+
on('command') do
|
165
|
+
image.initialize_collections_map(reset: true)
|
166
|
+
# TODO cause an update to all collections
|
167
|
+
end
|
168
|
+
}
|
169
|
+
}
|
170
|
+
}
|
171
|
+
end
|
172
|
+
end
|
173
|
+
end
|
174
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
class CryptopunksGui
|
2
|
+
module View
|
3
|
+
module StyleOptionsFrame
|
4
|
+
def led_style_options_frame(image: )
|
5
|
+
frame {
|
6
|
+
padding 0
|
7
|
+
|
8
|
+
label {
|
9
|
+
grid row: 0, column: 0, column_weight: 0
|
10
|
+
text 'Spacing:'
|
11
|
+
}
|
12
|
+
spinbox {
|
13
|
+
grid row: 0, column: 1
|
14
|
+
from 1
|
15
|
+
to 72
|
16
|
+
text <=> [image, :led_spacing]
|
17
|
+
}
|
18
|
+
|
19
|
+
checkbutton {
|
20
|
+
grid row: 0, column: 2
|
21
|
+
variable <=> [image, :led_round_corner]
|
22
|
+
}
|
23
|
+
label {
|
24
|
+
grid row: 0, column: 3
|
25
|
+
text 'Round Corner'
|
26
|
+
|
27
|
+
on('Button-1') do
|
28
|
+
image.led_round_corner = !image.led_round_corner
|
29
|
+
end
|
30
|
+
}
|
31
|
+
}
|
32
|
+
end
|
33
|
+
|
34
|
+
def sketch_style_options_frame(image: )
|
35
|
+
frame {
|
36
|
+
padding 0
|
37
|
+
|
38
|
+
label {
|
39
|
+
grid row: 0, column: 0, column_weight: 0
|
40
|
+
text 'Line:'
|
41
|
+
}
|
42
|
+
spinbox {
|
43
|
+
grid row: 0, column: 1
|
44
|
+
from 1
|
45
|
+
to 72
|
46
|
+
text <=> [image, :sketch_line]
|
47
|
+
}
|
48
|
+
}
|
49
|
+
end
|
50
|
+
|
51
|
+
def no_style_options_frame
|
52
|
+
frame { # filler
|
53
|
+
padding 0
|
54
|
+
height 0
|
55
|
+
width 0
|
56
|
+
}
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
data/bin/cryptopunks-gui
CHANGED
File without changes
|