cryptopunks-gui 0.0.8 → 0.0.12

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 6ee3d5ade75811ebc70295c6f76b54ba9303f54478f384cccad7893f677fc10e
4
- data.tar.gz: eaa8d181497699192da8ed4a507f7482f305aac74920e8a4259c25dd49316a11
3
+ metadata.gz: ce9f96af3964a08b2afadfa66fffae558338ced44cc09871fb3e967eeff84bc0
4
+ data.tar.gz: 669c2e11acfda26508c3494b4cf66bfd3213fac457b30257dfb6edf2dd590fc8
5
5
  SHA512:
6
- metadata.gz: 8ff9986b156bc144985f4e2a74b288218e15048ff3cf0b06962a7d0220210d1c8cdeae9b44795deada9baa0bf5d822bb547a41c10b86a3047846da6fbc9c80e7
7
- data.tar.gz: 8647990b82c10f17bac2894d0fa6e3a6e6e73fbb40fc55b47ffcc69e0a20de8cd2a974d129dcb051550a81fd3380a4fce9910bc7bd24af87c4fd39f8bbce344d
6
+ metadata.gz: 0e8be7e8519cb582a373acfa18d93ad4f62f954c7c8f0278694a66481e828ee248133caffbf2f0a73ce86ae7c8398ef24287d7b834da637b5db7923847ea4aad
7
+ data.tar.gz: '068c1cc0ea6687d2e5c915673973897febd2613b37569d349502031414b798b53aa7de85ab591c69968d21e99a6f81c223710dd476653ee8a0f69fc37f2b65bd'
data/CHANGELOG.md CHANGED
@@ -1,9 +1,32 @@
1
1
  # Change Log
2
2
 
3
+ ## 0.0.12
4
+
5
+ - Upgrade to glimmer-dsl-tk 0.0.46
6
+ - File & Help Menus
7
+ - Update COLLECTIONS_YAML_URL to point to cryptopunksnotdead repository (recently moved there)
8
+ - Add 'Mirror', 'Flip', 'Led' and 'Sketch' details (e.g. spacing or line) to output file name (e.g. '...-mirror.png')
9
+ - Fix issue with allowing out of bounds image index when entering index that is equal to count of images in a collection (off by 1 error)
10
+ - Fix written file name for downloaded sprites (was excluding .png before)
11
+ - Fix issue with @punk_directory mistakenly referenced after being removed through refactoring
12
+
13
+ ## 0.0.11
14
+
15
+ - Support configuring default collections through a web hosted yaml file at: https://raw.githubusercontent.com/AndyObtiva/cryptopunks-gui/master/cryptopunks-collections.yml
16
+ - New Green Punks, Clown Punks, and Bubble Gum Punks collections
17
+
18
+ ## 0.0.10
19
+
20
+ - Fix issue with cryptopunks GUI erroring when cancelling selection of a new output location (or getting blocked by OS for security reasons)
21
+
22
+ ## 0.0.9
23
+
24
+ - Added Halloween special collections: Scream, Jack 'O' Lantern, Joker, and Frankenstein
25
+
3
26
  ## 0.0.8
4
27
 
5
- - Remove Boring Apes collections since they are 28x28 instead of 24x24, thus incomptible with the cryptopunks Ruby gem
6
- - Fixed Boring Apes collection image dimensions (28x28 instead of default 24x24)
28
+ - Added missing Bored Apes (vanilla) collection
29
+ - Fixed Bored Apes collection image dimensions (28x28 instead of default 24x24)
7
30
 
8
31
  ## 0.0.7
9
32
 
data/LICENSE.txt CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2021 Andy Maleh
1
+ Copyright (c) 2021 Crypto Punk's Not Dead
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining
4
4
  a copy of this software and associated documentation files (the
data/README.md CHANGED
@@ -1,8 +1,8 @@
1
- # <img src="https://raw.githubusercontent.com/AndyObtiva/cryptopunks-gui/master/icons/cryptopunks-gui.png" height=85 /> CryptoPunks GUI 0.0.8
1
+ # <img src="https://raw.githubusercontent.com/AndyObtiva/cryptopunks-gui/master/icons/cryptopunks-gui.png" height=85 /> CryptoPunks GUI 0.0.12
2
2
  ## Simplified Minting
3
3
  [![Gem Version](https://badge.fury.io/rb/cryptopunks-gui.svg)](http://badge.fury.io/rb/cryptopunks-gui)
4
4
 
5
- This is a Graphical User Interface for the famous [cryptopunks Ruby gem](https://github.com/cryptopunksnotdead/cryptopunks/tree/master/cryptopunks).
5
+ This is a Graphical User Interface for the [cryptopunks Ruby gem](https://github.com/cryptopunksnotdead/cryptopunks/tree/master/cryptopunks).
6
6
 
7
7
  It automatically downloads image collection sprites on first use (e.g. `punks.png` from https://github.com/larvalabs/cryptopunks).
8
8
 
@@ -14,18 +14,18 @@ Minted cryptopunks are stored at `~/cryptopunks/` by default ([output location c
14
14
 
15
15
  - [Tcl/Tk (ActiveTcl)](https://tkdocs.com/tutorial/install.html)
16
16
  - [RVM](https://rvm.io/) (unless you are on Windows)
17
- - [Ruby 3.0.2 compiled with RVM for Tk](https://rvm.io/integration/tk#tk) (unless you are on Windows for which Tcl/Tk instructions include installation of Ruby)
17
+ - [Ruby 3.0.2 compiled with RVM for Tk](https://rvm.io/integration/tk#tk) (unless you are on Windows for which Tcl/Tk instructions include installation of Ruby [get v3.0.2])
18
18
 
19
19
  ## Setup
20
20
 
21
- You can use CryptoPunks GUI via gem or via cloning repository.
21
+ You can use CryptoPunks GUI via gem or via cloning repository (if you encounter any issues, please try older versions of the gem and report the issues encountered).
22
22
 
23
23
  ### Gem
24
24
 
25
25
  Run:
26
26
 
27
27
  ```
28
- gem install cryptopunks-gui -v0.0.8
28
+ gem install cryptopunks-gui -v0.0.12
29
29
  ```
30
30
 
31
31
  Afterwards, run app via:
@@ -73,7 +73,13 @@ ruby app/cryptopunks_gui.rb
73
73
 
74
74
  Change collection to pick a different collection of images.
75
75
 
76
- There are currently 34 available collections (from https://github.com/cryptopunksnotdead/awesome-24px):
76
+ ![Screenshot](/screenshots/cryptopunks-gui-screenshot-collection-zombies.png)
77
+
78
+ Image collections are configured in [cryptopunks-collections.yml](/cryptopunks-collections.yml).
79
+
80
+ If you cloned the project locally, you may edit [cryptopunks-collections.yml](/cryptopunks-collections.yml) to add/remove collections.
81
+
82
+ There are 41 available collections (mostly from https://github.com/cryptopunksnotdead/awesome-24px):
77
83
  - [Punks](https://raw.githubusercontent.com/larvalabs/cryptopunks/master/punks.png) ![image examples](https://github.com/cryptopunksnotdead/awesome-24px/raw/master/i/punks-strip.png)
78
84
  - [Mohawks](https://raw.githubusercontent.com/cryptopunksnotdead/programming-cryptopunks/master/i/mohawks.png) ![image examples](https://github.com/cryptopunksnotdead/awesome-24px/raw/master/i/mohawks-strip.png)
79
85
  - [Blondies](https://raw.githubusercontent.com/cryptopunksnotdead/programming-cryptopunks/master/i/blondies.png) ![image examples](https://github.com/cryptopunksnotdead/awesome-24px/raw/master/i/blondies-strip.png)
@@ -81,7 +87,14 @@ There are currently 34 available collections (from https://github.com/cryptopunk
81
87
  - [Apes](https://raw.githubusercontent.com/cryptopunksnotdead/programming-cryptopunks/master/i/apes.png) ![image examples](https://github.com/cryptopunksnotdead/awesome-24px/raw/master/i/apes-strip.png)
82
88
  - [Aliens](https://raw.githubusercontent.com/cryptopunksnotdead/programming-cryptopunks/master/i/aliens.png) ![image examples](https://github.com/cryptopunksnotdead/awesome-24px/raw/master/i/aliens-strip.png)
83
89
  - [Golden Punks](https://raw.githubusercontent.com/cryptopunksnotdead/awesome-24px/master/collection/goldenpunks.png) ![image examples](https://github.com/cryptopunksnotdead/awesome-24px/raw/master/i/goldenpunks-strip.png)
90
+ - [Green Punks](https://i.redd.it/uwrsn2lrr3o71.png)
91
+ - [Clown Punks](https://i.redd.it/ut0kk25heex71.png)
92
+ - [Bubble Gum Punks](https://i.redd.it/hjddd1s8ydx71.png)
84
93
  - [Halloween Punks](https://raw.githubusercontent.com/cryptopunksnotdead/awesome-24px/master/collection/halloweenpunks.png) ![image examples](https://github.com/cryptopunksnotdead/awesome-24px/raw/master/i/halloweenpunks-strip.png)
94
+ - [Scream Punks](https://raw.githubusercontent.com/cryptopunksnotdead/cryptopunks/master/halloween/i/screampunks%402x.png)
95
+ - [Jack 'O' Lantern Punks](https://raw.githubusercontent.com/cryptopunksnotdead/cryptopunks/master/halloween/i/jackpunks%402x.png)
96
+ - [Joker Punks](https://raw.githubusercontent.com/cryptopunksnotdead/cryptopunks/master/halloween/i/jokerpunks%402x.png)
97
+ - [Frankenstein Punks](https://raw.githubusercontent.com/cryptopunksnotdead/cryptopunks/master/halloween/i/frankensteinpunks%402x.png)
85
98
  - [Front Punks](https://raw.githubusercontent.com/cryptopunksnotdead/programming-cryptopunks/master/i/frontpunks.png) ![image examples](https://github.com/cryptopunksnotdead/awesome-24px/raw/master/i/frontpunks-strip.png)
86
99
  - [More Punks](https://raw.githubusercontent.com/cryptopunksnotdead/programming-cryptopunks/master/i/morepunks.png') ![image examples](https://github.com/cryptopunksnotdead/awesome-24px/raw/master/i/morepunks-strip.png)
87
100
  - [Expansion Punks](https://expansionpunks.com/provenance/expansionpunks.png) ![image examples](https://github.com/cryptopunksnotdead/awesome-24px/raw/master/i/expansionpunks-strip.png)
@@ -109,10 +122,16 @@ There are currently 34 available collections (from https://github.com/cryptopunk
109
122
  - [Punk Rocks](https://raw.githubusercontent.com/cryptopunksnotdead/programming-cryptopunks/master/i/punkrocks.png) ![image examples](https://github.com/cryptopunksnotdead/awesome-24px/raw/master/i/punkrocks-strip.png)
110
123
  - [Tulips](https://raw.githubusercontent.com/cryptopunksnotdead/awesome-24px/master/collection/tulips.png) ![image examples](https://github.com/cryptopunksnotdead/awesome-24px/raw/master/i/tulips-strip.png)
111
124
 
112
- ![Screenshot](/screenshots/cryptopunks-gui-screenshot-collection-zombies.png)
113
-
114
125
  ![Screenshot](/screenshots/cryptopunks-gui-screenshot-collection-apes.png)
115
126
 
127
+ ![Screenshot](/screenshots/cryptopunks-gui-screenshot-collection-scream-punks.png)
128
+
129
+ ![Screenshot](/screenshots/cryptopunks-gui-screenshot-collection-jack-o-lantern-punks.png)
130
+
131
+ ![Screenshot](/screenshots/cryptopunks-gui-screenshot-collection-joker-punks.png)
132
+
133
+ ![Screenshot](/screenshots/cryptopunks-gui-screenshot-collection-frankenstein-punks.png)
134
+
116
135
  ![Screenshot](/screenshots/cryptopunks-gui-screenshot-collection-alien-clan.png)
117
136
 
118
137
  ![Screenshot](/screenshots/cryptopunks-gui-screenshot-collection-bored-apes-stars-and-stripes.png)
@@ -217,7 +236,7 @@ You may select a new output location by clicking on the `...` button.
217
236
 
218
237
  [MIT](LICENSE.txt)
219
238
 
220
- Copyright (c) 2021 - Cryptopunks GUI by [Andy Maleh](https://github.com/AndyObtiva)
239
+ Copyright (c) 2021 - Cryptopunks GUI by [Crypto Punk's Not Dead](https://github.com/cryptopunksnotdead)
221
240
 
222
241
  --
223
242
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.0.8
1
+ 0.0.12
@@ -1,332 +1,42 @@
1
1
  require 'glimmer-dsl-tk'
2
+ require 'glimmer/data_binding/observer'
2
3
  require 'cryptopunks'
3
4
  require 'facets'
4
5
  require 'fileutils'
5
6
  require 'net/http'
6
7
  require 'uri'
7
- require 'glimmer/data_binding/observer'
8
8
  require 'yaml'
9
9
  require 'puts_debuggerer'
10
10
 
11
+ require_relative 'model/image'
12
+ require_relative 'view/menu_bar'
13
+ require_relative 'view/image_frame'
14
+ require_relative 'view/style_options_frame'
15
+
11
16
  class CryptopunksGui
12
17
  include Glimmer
13
-
14
- PALETTES = ['Standard'] + (Palette8bit.constants).map(&:name).map {|palette| palette.split('_').map(&:capitalize).join(' ')}.reject { |palette| palette.include?(' ') }.sort
15
- STYLES = ['Normal', 'Led', 'Sketch']
16
- COLLECTION_URL_MAP = {
17
- 'Punks' => 'https://raw.githubusercontent.com/larvalabs/cryptopunks/master/punks.png',
18
- 'Mohawks' => 'https://raw.githubusercontent.com/cryptopunksnotdead/programming-cryptopunks/master/i/mohawks.png',
19
- 'Blondies' => 'https://raw.githubusercontent.com/cryptopunksnotdead/programming-cryptopunks/master/i/blondies.png',
20
- 'Zombies' => 'https://raw.githubusercontent.com/cryptopunksnotdead/programming-cryptopunks/master/i/zombies.png',
21
- 'Apes' => 'https://raw.githubusercontent.com/cryptopunksnotdead/programming-cryptopunks/master/i/apes.png',
22
- 'Aliens' => 'https://raw.githubusercontent.com/cryptopunksnotdead/programming-cryptopunks/master/i/aliens.png',
23
- 'Golden Punks' => 'https://raw.githubusercontent.com/cryptopunksnotdead/awesome-24px/master/collection/goldenpunks.png',
24
- 'Halloween Punks' => 'https://raw.githubusercontent.com/cryptopunksnotdead/awesome-24px/master/collection/halloweenpunks.png',
25
- 'Front Punks' => 'https://raw.githubusercontent.com/cryptopunksnotdead/programming-cryptopunks/master/i/frontpunks.png',
26
- 'More Punks' => 'https://raw.githubusercontent.com/cryptopunksnotdead/programming-cryptopunks/master/i/morepunks.png',
27
- 'Expansion Punks' => 'https://expansionpunks.com/provenance/expansionpunks.png',
28
- 'Avalanche Punks' => 'https://raw.githubusercontent.com/cryptopunksnotdead/awesome-24px/master/collection/avalanchepunks.png',
29
- 'International Punks' => 'https://raw.githubusercontent.com/cryptopunksnotdead/awesome-24px/master/collection/intlpunks.png',
30
- 'Ape Punks' => 'https://raw.githubusercontent.com/cryptopunksnotdead/awesome-24px/master/collection/apepunks.png',
31
- 'Alien Clan' => 'https://raw.githubusercontent.com/cryptopunksnotdead/programming-cryptopunks/master/i/alienclan.png',
32
- 'Bored Apes' => 'https://raw.githubusercontent.com/cryptopunksnotdead/awesome-24px/master/collection/boredapes.png',
33
- 'Bored Apes Blue' => 'https://raw.githubusercontent.com/cryptopunksnotdead/awesome-24px/master/collection/boredapes_blue.png',
34
- 'Bored Apes Red' => 'https://raw.githubusercontent.com/cryptopunksnotdead/awesome-24px/master/collection/boredapes_red.png',
35
- 'Bored Apes Neon Glow' => 'https://raw.githubusercontent.com/cryptopunksnotdead/awesome-24px/master/collection/boredapes_neon_glow.png',
36
- 'Bored Apes Stars and Stripes' => 'https://raw.githubusercontent.com/cryptopunksnotdead/awesome-24px/master/collection/boredapes_stars_and_stripes.png',
37
- 'Bored Apes Acid' => 'https://raw.githubusercontent.com/cryptopunksnotdead/awesome-24px/master/collection/boredapes_acid.png',
38
- 'Cool Cats' => 'https://raw.githubusercontent.com/cryptopunksnotdead/awesome-24px/master/collection/coolcats.png',
39
- 'Cool Cats Mohawks' => 'https://raw.githubusercontent.com/cryptopunksnotdead/awesome-24px/master/collection/coolcats_mohawks.png',
40
- 'Cool Cats Ninjas' => 'https://raw.githubusercontent.com/cryptopunksnotdead/awesome-24px/master/collection/coolcats_ninjas.png',
41
- 'Cool Cats TV Heads' => 'https://raw.githubusercontent.com/cryptopunksnotdead/awesome-24px/master/collection/coolcats_tvheads.png',
42
- 'Cool Cats Pirates' => 'https://raw.githubusercontent.com/cryptopunksnotdead/awesome-24px/master/collection/coolcats_pirates.png',
43
- 'Cool Cats Unicorns' => 'https://raw.githubusercontent.com/cryptopunksnotdead/awesome-24px/master/collection/coolcats_unicorns.png',
44
- 'Cool Cats Dragons' => 'https://raw.githubusercontent.com/cryptopunksnotdead/awesome-24px/master/collection/coolcats_dragons.png',
45
- 'Cool Cats Frogs' => 'https://raw.githubusercontent.com/cryptopunksnotdead/awesome-24px/master/collection/coolcats_frogs.png',
46
- 'Pudgy Penguins' => 'https://raw.githubusercontent.com/cryptopunksnotdead/awesome-24px/master/collection/pudgypenguins.png',
47
- 'Dodge' => 'https://raw.githubusercontent.com/cryptopunksnotdead/programming-cryptopunks/master/i/dodge.png',
48
- 'Rocks' => 'https://raw.githubusercontent.com/cryptopunksnotdead/awesome-24px/master/collection/rocks.png',
49
- 'Punk Rocks' => 'https://raw.githubusercontent.com/cryptopunksnotdead/programming-cryptopunks/master/i/punkrocks.png',
50
- 'Tulips' => 'https://raw.githubusercontent.com/cryptopunksnotdead/awesome-24px/master/collection/tulips.png',
51
- }
52
-
53
- attr_accessor :collection, :image_index, :zoom, :palette, :style, :led_spacing, :led_round_corner, :sketch_line, :flip, :mirror
18
+ include View::MenuBar
19
+ include View::ImageFrame
20
+ include View::StyleOptionsFrame
54
21
 
55
22
  def initialize
56
- initialize_punk_directory
57
- initialize_collection
58
- load_config
59
- initialize_defaults
60
- observe_image_attribute_changes
23
+ @image = Model::Image.new
61
24
  create_gui
62
- self.image_index = 0
63
- @root.open
64
- end
65
-
66
- def collection_options
67
- COLLECTION_URL_MAP.keys
25
+ @image.image_index = 0
68
26
  end
69
27
 
70
- def palette_options
71
- PALETTES
72
- end
73
-
74
- def style_options
75
- STYLES
76
- end
77
-
78
- def initialize_punk_directory
79
- @punk_directory = @punk_config_directory = File.join(Dir.home, 'cryptopunks')
80
- FileUtils.mkdir_p(@punk_directory)
81
- end
82
-
83
- def initialize_collection
84
- return if @collection && @collection == @last_collection
85
- @collection ||= COLLECTION_URL_MAP.keys.first
86
- url = COLLECTION_URL_MAP[@collection]
87
- @punk_file = File.join(@punk_config_directory, File.basename(url, '.png'))
88
- File.write(@punk_file, Net::HTTP.get(URI(url))) unless File.exist?(@punk_file)
89
- @images ||= {}
90
- dimension = @collection.start_with?('Bored Apes') ? 28 : 24
91
- @images[@collection] ||= Punks::Image::Composite.read(@punk_file, width: dimension, height: dimension)
92
- @last_collection = @collection
93
- self.image_index = 0
94
- @image_index_spinbox.to = @images[@collection].size - 1 if @image_index_spinbox
95
- end
96
-
97
- def load_config
98
- @punk_config_file = File.join(@punk_config_directory, 'cryptopunks.yml')
99
- FileUtils.touch(@punk_config_file)
100
- @punk_config = YAML.load(File.read(@punk_config_file)) || {punk_directory: @punk_directory}
101
- @punk_directory = @punk_config[:punk_directory]
102
- end
103
-
104
- def save_config
105
- File.write(@punk_config_file, YAML.dump(@punk_config))
106
- end
107
-
108
- def initialize_defaults
109
- @collection = COLLECTION_URL_MAP.keys.first
110
- @zoom = 12
111
- @palette = PALETTES.first
112
- @style = STYLES.first
113
- @led_spacing = 2
114
- @led_round_corner = false
115
- @sketch_line = 1
116
- @mirror = false
117
- @flip = false
118
- end
119
-
120
- def observe_image_attribute_changes
121
- observer = Glimmer::DataBinding::Observer.proc { generate_image }
122
- observer.observe(self, :collection)
123
- observer.observe(self, :image_index)
124
- observer.observe(self, :zoom)
125
- observer.observe(self, :palette)
126
- observer.observe(self, :style)
127
- observer.observe(self, :led_spacing)
128
- observer.observe(self, :led_round_corner)
129
- observer.observe(self, :sketch_line)
130
- observer.observe(self, :mirror)
131
- observer.observe(self, :flip)
132
- end
133
-
134
- def generate_image
135
- initialize_collection
136
- return if @image_index.to_i > @images[@collection].size
137
- image_location = File.join(@punk_directory, "#{@collection.gsub(' ', '').downcase}-#{@image_index}#{"x#{@zoom}" if @zoom.to_i > 1}#{"-#{@palette.underscore}" if @palette != PALETTES.first}#{"-#{@style.underscore}" if @style != STYLES.first}.png")
138
- puts "Writing punk image to #{image_location}"
139
- selected_punk = @images[@collection][@image_index.to_i]
140
- selected_punk = selected_punk.change_palette8bit(Palette8bit.const_get(@palette.gsub(' ', '_').upcase.to_sym)) if @palette != PALETTES.first
141
- @original_zoom = @zoom
142
- if @style != STYLES.first
143
- style_options = {}
144
- if @style == 'Led'
145
- style_options[:spacing] = @led_spacing.to_i
146
- style_options[:round_corner] = @led_round_corner
147
- end
148
- if @style == 'Sketch'
149
- style_options[:line] = @sketch_line.to_i
150
- end
151
- selected_punk = selected_punk.send(@style.underscore, @zoom.to_i, **style_options)
152
- end
153
- selected_punk = selected_punk.mirror if @mirror
154
- selected_punk = selected_punk.flip if @flip
155
- selected_punk = selected_punk.zoom(@zoom.to_i) if @style == STYLES.first
156
- selected_punk.save(image_location)
157
- @image_label.image = image_location
158
- @output_location_entry.text = image_location
159
- @previous_style = @style
160
- notify_observers(:zoom) if @zoom != @original_zoom
28
+ def launch
29
+ @root.open
161
30
  end
162
31
 
163
32
  def create_gui
164
- @root = root {
33
+ @root = root { |root_proxy|
165
34
  title 'CryptoPunks GUI'
166
35
  iconphoto File.expand_path('../icons/cryptopunks-gui.png', __dir__)
167
36
 
168
- frame {
169
- label {
170
- text 'Collection:'
171
- }
172
- combobox {
173
- readonly true
174
- text <=> [self, :collection]
175
- }
176
-
177
- label {
178
- text 'Image Index:'
179
- }
180
- @image_index_spinbox = spinbox {
181
- from 0
182
- to @images[@collection].size - 1
183
- text <=> [self, :image_index]
184
- }
185
-
186
- label {
187
- text 'Zoom:'
188
- }
189
- spinbox {
190
- from 1
191
- to 72
192
- text <=> [self, :zoom]
193
- }
194
-
195
- label {
196
- text 'Palette:'
197
- }
198
- combobox {
199
- readonly true
200
- text <=> [self, :palette]
201
- }
202
-
203
- label {
204
- text 'Style:'
205
- }
206
- combobox {
207
- readonly true
208
- text <=> [self, :style, after_write: ->(val) {add_style_options}]
209
- }
210
-
211
- @style_options_frame = frame {
212
- padding 0
213
- }
214
-
215
- frame {
216
- padding 0
217
-
218
- checkbutton {
219
- grid row: 0, column: 0, column_weight: 0
220
- variable <=> [self, :mirror]
221
- }
222
- label {
223
- grid row: 0, column: 1
224
- text 'Mirror'
225
-
226
- on('Button-1') do
227
- self.mirror = !mirror
228
- end
229
- }
230
-
231
- checkbutton {
232
- grid row: 0, column: 2
233
- variable <=> [self, :flip]
234
- }
235
- label {
236
- grid row: 0, column: 3
237
- text 'Flip'
238
-
239
- on('Button-1') do
240
- self.flip = !flip
241
- end
242
- }
243
- }
244
-
245
- label {
246
- text 'Output Location:'
247
- }
248
- frame {
249
- padding 0
250
-
251
- @output_location_entry = entry {
252
- grid row: 0, column: 0
253
- readonly true
254
- width 47
255
- }
256
- button {
257
- grid row: 0, column: 1
258
- text '...'
259
- width 1.1
260
-
261
- on('command') do
262
- @punk_directory = choose_directory(parent: @root)
263
- @punk_config[:punk_directory] = @punk_directory
264
- save_config
265
- generate_image
266
- end
267
- }
268
- }
269
-
270
- @image_label = label {
271
- grid row_weight: 1
272
- }
273
- }
274
- }
275
- end
276
-
277
- def add_style_options
278
- @style_options_frame.content {
279
- @style_options_frame.children.each(&:destroy)
280
- if @style == 'Led'
281
- frame {
282
- padding 0
283
-
284
- label {
285
- grid row: 0, column: 0, column_weight: 0
286
- text 'Spacing:'
287
- }
288
- spinbox {
289
- grid row: 0, column: 1
290
- from 1
291
- to 72
292
- text <=> [self, :led_spacing]
293
- }
294
-
295
- checkbutton {
296
- grid row: 0, column: 2
297
- variable <=> [self, :led_round_corner]
298
- }
299
- label {
300
- grid row: 0, column: 3
301
- text 'Round Corner'
302
-
303
- on('Button-1') do
304
- self.led_round_corner = !led_round_corner
305
- end
306
- }
307
- }
308
- elsif @style == 'Sketch'
309
- frame {
310
- padding 0
311
-
312
- label {
313
- grid row: 0, column: 0, column_weight: 0
314
- text 'Line:'
315
- }
316
- spinbox {
317
- grid row: 0, column: 1
318
- from 1
319
- to 72
320
- text <=> [self, :sketch_line]
321
- }
322
- }
323
- else
324
- frame { # filler
325
- padding 0
326
- height 0
327
- width 0
328
- }
329
- end
37
+ cryptopunks_gui_menu_bar(root: root_proxy, image: @image)
38
+
39
+ image_frame(root: root_proxy, image: @image)
330
40
  }
331
41
  end
332
42
  end
@@ -0,0 +1,187 @@
1
+ class CryptopunksGui
2
+ module Model
3
+ class Image
4
+ PALETTES = ['Standard'] + (Palette8bit.constants).map(&:name).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.write(@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, :images)
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
@@ -2,16 +2,16 @@
2
2
  # DO NOT EDIT THIS FILE DIRECTLY
3
3
  # Instead, edit Juwelier::Tasks in Rakefile, and run 'rake gemspec'
4
4
  # -*- encoding: utf-8 -*-
5
- # stub: cryptopunks-gui 0.0.8 ruby app
5
+ # stub: cryptopunks-gui 0.0.12 ruby app
6
6
 
7
7
  Gem::Specification.new do |s|
8
8
  s.name = "cryptopunks-gui".freeze
9
- s.version = "0.0.8"
9
+ s.version = "0.0.12"
10
10
 
11
11
  s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version=
12
12
  s.require_paths = ["app".freeze]
13
13
  s.authors = ["Andy Maleh".freeze]
14
- s.date = "2021-10-28"
14
+ s.date = "2021-11-22"
15
15
  s.description = "CryptoPunks GUI for Simplified Minting - Built with Glimmer DSL for Tk (requires ActiveTcl to run cryptopunks-gui command)".freeze
16
16
  s.email = "andy.am@gmail.com".freeze
17
17
  s.executables = ["cryptopunks-gui".freeze]
@@ -26,14 +26,21 @@ Gem::Specification.new do |s|
26
26
  "README.md",
27
27
  "VERSION",
28
28
  "app/cryptopunks_gui.rb",
29
+ "app/model/image.rb",
30
+ "app/view/help_dialog.rb",
31
+ "app/view/image_frame.rb",
32
+ "app/view/menu_bar.rb",
33
+ "app/view/preferences_dialog.rb",
34
+ "app/view/style_options_frame.rb",
29
35
  "bin/cryptopunks-gui",
30
36
  "cryptopunks-gui.gemspec",
37
+ "icons/cryptopunks-gui.icns",
31
38
  "icons/cryptopunks-gui.png"
32
39
  ]
33
40
  s.homepage = "http://github.com/AndyObtiva/cryptopunks-gui".freeze
34
41
  s.licenses = ["MIT".freeze]
35
42
  s.post_install_message = "To launch CryptoPunks GUI, run command: cryptopunks-gui".freeze
36
- s.rubygems_version = "3.2.22".freeze
43
+ s.rubygems_version = "3.2.31".freeze
37
44
  s.summary = "CryptoPunks GUI for Simplified Minting".freeze
38
45
 
39
46
  if s.respond_to? :specification_version then
@@ -41,7 +48,7 @@ Gem::Specification.new do |s|
41
48
  end
42
49
 
43
50
  if s.respond_to? :add_runtime_dependency then
44
- s.add_runtime_dependency(%q<glimmer-dsl-tk>.freeze, ["~> 0.0.30"])
51
+ s.add_runtime_dependency(%q<glimmer-dsl-tk>.freeze, ["= 0.0.47"])
45
52
  s.add_runtime_dependency(%q<cryptopunks>.freeze, ["~> 2.0.1"])
46
53
  s.add_development_dependency(%q<rspec>.freeze, ["~> 3.5.0"])
47
54
  s.add_development_dependency(%q<rdoc>.freeze, ["~> 3.12"])
@@ -49,7 +56,7 @@ Gem::Specification.new do |s|
49
56
  s.add_development_dependency(%q<simplecov>.freeze, [">= 0"])
50
57
  s.add_development_dependency(%q<rake-tui>.freeze, [">= 0"])
51
58
  else
52
- s.add_dependency(%q<glimmer-dsl-tk>.freeze, ["~> 0.0.30"])
59
+ s.add_dependency(%q<glimmer-dsl-tk>.freeze, ["= 0.0.47"])
53
60
  s.add_dependency(%q<cryptopunks>.freeze, ["~> 2.0.1"])
54
61
  s.add_dependency(%q<rspec>.freeze, ["~> 3.5.0"])
55
62
  s.add_dependency(%q<rdoc>.freeze, ["~> 3.12"])
Binary file
metadata CHANGED
@@ -1,29 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cryptopunks-gui
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.8
4
+ version: 0.0.12
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andy Maleh
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-10-28 00:00:00.000000000 Z
11
+ date: 2021-11-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: glimmer-dsl-tk
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - "~>"
17
+ - - '='
18
18
  - !ruby/object:Gem::Version
19
- version: 0.0.30
19
+ version: 0.0.47
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - "~>"
24
+ - - '='
25
25
  - !ruby/object:Gem::Version
26
- version: 0.0.30
26
+ version: 0.0.47
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: cryptopunks
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -124,8 +124,15 @@ files:
124
124
  - README.md
125
125
  - VERSION
126
126
  - app/cryptopunks_gui.rb
127
+ - app/model/image.rb
128
+ - app/view/help_dialog.rb
129
+ - app/view/image_frame.rb
130
+ - app/view/menu_bar.rb
131
+ - app/view/preferences_dialog.rb
132
+ - app/view/style_options_frame.rb
127
133
  - bin/cryptopunks-gui
128
134
  - cryptopunks-gui.gemspec
135
+ - icons/cryptopunks-gui.icns
129
136
  - icons/cryptopunks-gui.png
130
137
  homepage: http://github.com/AndyObtiva/cryptopunks-gui
131
138
  licenses:
@@ -146,7 +153,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
146
153
  - !ruby/object:Gem::Version
147
154
  version: '0'
148
155
  requirements: []
149
- rubygems_version: 3.2.22
156
+ rubygems_version: 3.2.31
150
157
  signing_key:
151
158
  specification_version: 4
152
159
  summary: CryptoPunks GUI for Simplified Minting