cryptopunks-gui 0.0.9 → 0.0.13

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: e8d25a5e618dcccd4040032c7a0957938d5b349688e701751f96e09cddb51917
4
- data.tar.gz: 3afc23cc9be06e3dba292ed17248133e4250195c256f06f6986fd8011976c3a1
3
+ metadata.gz: 46ac37666e9b977617717e77af92359aa2644dee38fb7173bb6908e821c543b3
4
+ data.tar.gz: b22e902d9f9f9850a7fb378ac06a410333e18d290160e584b1bfdc8dfaefddf2
5
5
  SHA512:
6
- metadata.gz: 858543e8a8385eccbe3af5476aed027e99fe991eeea40bf8fbcdbd3fef45866bf712725c3833d9c6b9225e4b95cabd462045a84c266da2179189ca3b3cab5038
7
- data.tar.gz: c1679d9d0cd0d6091d4a4abf270cb419e4dac4ce3b5a5953d0a9682f9dae2eef504d9b5df661004e8af3f0092cf948ac5375132f0e090a41a8f9dc1285b5bb30
6
+ metadata.gz: c375eb8fd78107079fd7e48f24ee8d344cd80ee9400a57085c1675d96e04b5b2477318179398960dcac2d9e6dd800c2ff05668fc07c71dc5cc0146e8bd623c74
7
+ data.tar.gz: 3a411372e9b4ee1e28e5f9f16d0358c16defb1e0e5f6fbbb10bff2ef10a49cc794fd49321c9c8f518f7b35270f4a07ae4b7205001cc88ac9d4c98e4ec9fa7c10
data/CHANGELOG.md CHANGED
@@ -1,8 +1,31 @@
1
1
  # Change Log
2
2
 
3
+ ## 0.0.13
4
+
5
+ - Support older Ruby versions down to 2.7.2 by fixing an issue with not having `#name` method on `Symbol`
6
+
7
+ ## 0.0.12
8
+
9
+ - Upgrade to glimmer-dsl-tk 0.0.46
10
+ - File & Help Menus
11
+ - Update COLLECTIONS_YAML_URL to point to cryptopunksnotdead repository (recently moved there)
12
+ - Add 'Mirror', 'Flip', 'Led' and 'Sketch' details (e.g. spacing or line) to output file name (e.g. '...-mirror.png')
13
+ - 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)
14
+ - Fix written file name for downloaded sprites (was excluding .png before)
15
+ - Fix issue with @punk_directory mistakenly referenced after being removed through refactoring
16
+
17
+ ## 0.0.11
18
+
19
+ - Support configuring default collections through a web hosted yaml file at: https://raw.githubusercontent.com/AndyObtiva/cryptopunks-gui/master/cryptopunks-collections.yml
20
+ - New Green Punks, Clown Punks, and Bubble Gum Punks collections
21
+
22
+ ## 0.0.10
23
+
24
+ - Fix issue with cryptopunks GUI erroring when cancelling selection of a new output location (or getting blocked by OS for security reasons)
25
+
3
26
  ## 0.0.9
4
27
 
5
- - Added Halloween special collections: Scream, Jack 'O' Lantern, Joker, and Frankestein
28
+ - Added Halloween special collections: Scream, Jack 'O' Lantern, Joker, and Frankenstein
6
29
 
7
30
  ## 0.0.8
8
31
 
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.9
1
+ # <img src="https://raw.githubusercontent.com/AndyObtiva/cryptopunks-gui/master/icons/cryptopunks-gui.png" height=85 /> CryptoPunks GUI 0.0.13
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.9
28
+ gem install cryptopunks-gui -v0.0.13
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 38 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,6 +87,9 @@ There are currently 38 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)
85
94
  - [Scream Punks](https://raw.githubusercontent.com/cryptopunksnotdead/cryptopunks/master/halloween/i/screampunks%402x.png)
86
95
  - [Jack 'O' Lantern Punks](https://raw.githubusercontent.com/cryptopunksnotdead/cryptopunks/master/halloween/i/jackpunks%402x.png)
@@ -113,10 +122,16 @@ There are currently 38 available collections (from https://github.com/cryptopunk
113
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)
114
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)
115
124
 
116
- ![Screenshot](/screenshots/cryptopunks-gui-screenshot-collection-zombies.png)
117
-
118
125
  ![Screenshot](/screenshots/cryptopunks-gui-screenshot-collection-apes.png)
119
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
+
120
135
  ![Screenshot](/screenshots/cryptopunks-gui-screenshot-collection-alien-clan.png)
121
136
 
122
137
  ![Screenshot](/screenshots/cryptopunks-gui-screenshot-collection-bored-apes-stars-and-stripes.png)
@@ -221,7 +236,7 @@ You may select a new output location by clicking on the `...` button.
221
236
 
222
237
  [MIT](LICENSE.txt)
223
238
 
224
- 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)
225
240
 
226
241
  --
227
242
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.0.9
1
+ 0.0.13
@@ -1,341 +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' => {url: 'https://raw.githubusercontent.com/larvalabs/cryptopunks/master/punks.png', width: 24, height: 24, default_zoom: 12},
18
- 'Mohawks' => {url: 'https://raw.githubusercontent.com/cryptopunksnotdead/programming-cryptopunks/master/i/mohawks.png', width: 24, height: 24, default_zoom: 12},
19
- 'Blondies' => {url: 'https://raw.githubusercontent.com/cryptopunksnotdead/programming-cryptopunks/master/i/blondies.png', width: 24, height: 24, default_zoom: 12},
20
- 'Zombies' => {url: 'https://raw.githubusercontent.com/cryptopunksnotdead/programming-cryptopunks/master/i/zombies.png', width: 24, height: 24, default_zoom: 12},
21
- 'Apes' => {url: 'https://raw.githubusercontent.com/cryptopunksnotdead/programming-cryptopunks/master/i/apes.png', width: 24, height: 24, default_zoom: 12},
22
- 'Aliens' => {url: 'https://raw.githubusercontent.com/cryptopunksnotdead/programming-cryptopunks/master/i/aliens.png', width: 24, height: 24, default_zoom: 12},
23
- 'Golden Punks' => {url: 'https://raw.githubusercontent.com/cryptopunksnotdead/awesome-24px/master/collection/goldenpunks.png', width: 24, height: 24, default_zoom: 12},
24
- 'Halloween Punks' => {url: 'https://raw.githubusercontent.com/cryptopunksnotdead/awesome-24px/master/collection/halloweenpunks.png', width: 24, height: 24, default_zoom: 12},
25
- 'Scream Punks' => {url: 'https://raw.githubusercontent.com/cryptopunksnotdead/cryptopunks/master/halloween/i/screampunks%402x.png', width: 48, height: 48, default_zoom: 6},
26
- "Jack 'O' Lantern Punks" => {url: 'https://raw.githubusercontent.com/cryptopunksnotdead/cryptopunks/master/halloween/i/jackpunks%402x.png', width: 48, height: 48, default_zoom: 6},
27
- 'Joker Punks' => {url: 'https://raw.githubusercontent.com/cryptopunksnotdead/cryptopunks/master/halloween/i/jokerpunks%402x.png', width: 48, height: 48, default_zoom: 6},
28
- 'Frankenstein Punks' => {url: 'https://raw.githubusercontent.com/cryptopunksnotdead/cryptopunks/master/halloween/i/frankensteinpunks%402x.png', width: 48, height: 48, default_zoom: 6},
29
- 'Front Punks' => {url: 'https://raw.githubusercontent.com/cryptopunksnotdead/programming-cryptopunks/master/i/frontpunks.png', width: 24, height: 24, default_zoom: 12},
30
- 'More Punks' => {url: 'https://raw.githubusercontent.com/cryptopunksnotdead/programming-cryptopunks/master/i/morepunks.png', width: 24, height: 24, default_zoom: 12},
31
- 'Expansion Punks' => {url: 'https://expansionpunks.com/provenance/expansionpunks.png', width: 24, height: 24, default_zoom: 12},
32
- 'Avalanche Punks' => {url: 'https://raw.githubusercontent.com/cryptopunksnotdead/awesome-24px/master/collection/avalanchepunks.png', width: 24, height: 24, default_zoom: 12},
33
- 'International Punks' => {url: 'https://raw.githubusercontent.com/cryptopunksnotdead/awesome-24px/master/collection/intlpunks.png', width: 24, height: 24, default_zoom: 12},
34
- 'Ape Punks' => {url: 'https://raw.githubusercontent.com/cryptopunksnotdead/awesome-24px/master/collection/apepunks.png', width: 24, height: 24, default_zoom: 12},
35
- 'Alien Clan' => {url: 'https://raw.githubusercontent.com/cryptopunksnotdead/programming-cryptopunks/master/i/alienclan.png', width: 24, height: 24, default_zoom: 12},
36
- 'Bored Apes' => {url: 'https://raw.githubusercontent.com/cryptopunksnotdead/awesome-24px/master/collection/boredapes.png', width: 28, height: 28, default_zoom: 10},
37
- 'Bored Apes Blue' => {url: 'https://raw.githubusercontent.com/cryptopunksnotdead/awesome-24px/master/collection/boredapes_blue.png', width: 28, height: 28, default_zoom: 10},
38
- 'Bored Apes Red' => {url: 'https://raw.githubusercontent.com/cryptopunksnotdead/awesome-24px/master/collection/boredapes_red.png', width: 28, height: 28, default_zoom: 10},
39
- 'Bored Apes Neon Glow' => {url: 'https://raw.githubusercontent.com/cryptopunksnotdead/awesome-24px/master/collection/boredapes_neon_glow.png', width: 28, height: 28, default_zoom: 10},
40
- 'Bored Apes Stars and Stripes' => {url: 'https://raw.githubusercontent.com/cryptopunksnotdead/awesome-24px/master/collection/boredapes_stars_and_stripes.png', width: 28, height: 28, default_zoom: 10},
41
- 'Bored Apes Acid' => {url: 'https://raw.githubusercontent.com/cryptopunksnotdead/awesome-24px/master/collection/boredapes_acid.png', width: 28, height: 28, default_zoom: 10},
42
- 'Cool Cats' => {url: 'https://raw.githubusercontent.com/cryptopunksnotdead/awesome-24px/master/collection/coolcats.png', width: 24, height: 24, default_zoom: 12},
43
- 'Cool Cats Mohawks' => {url: 'https://raw.githubusercontent.com/cryptopunksnotdead/awesome-24px/master/collection/coolcats_mohawks.png', width: 24, height: 24, default_zoom: 12},
44
- 'Cool Cats Ninjas' => {url: 'https://raw.githubusercontent.com/cryptopunksnotdead/awesome-24px/master/collection/coolcats_ninjas.png', width: 24, height: 24, default_zoom: 12},
45
- 'Cool Cats TV Heads' => {url: 'https://raw.githubusercontent.com/cryptopunksnotdead/awesome-24px/master/collection/coolcats_tvheads.png', width: 24, height: 24, default_zoom: 12},
46
- 'Cool Cats Pirates' => {url: 'https://raw.githubusercontent.com/cryptopunksnotdead/awesome-24px/master/collection/coolcats_pirates.png', width: 24, height: 24, default_zoom: 12},
47
- 'Cool Cats Unicorns' => {url: 'https://raw.githubusercontent.com/cryptopunksnotdead/awesome-24px/master/collection/coolcats_unicorns.png', width: 24, height: 24, default_zoom: 12},
48
- 'Cool Cats Dragons' => {url: 'https://raw.githubusercontent.com/cryptopunksnotdead/awesome-24px/master/collection/coolcats_dragons.png', width: 24, height: 24, default_zoom: 12},
49
- 'Cool Cats Frogs' => {url: 'https://raw.githubusercontent.com/cryptopunksnotdead/awesome-24px/master/collection/coolcats_frogs.png', width: 24, height: 24, default_zoom: 12},
50
- 'Pudgy Penguins' => {url: 'https://raw.githubusercontent.com/cryptopunksnotdead/awesome-24px/master/collection/pudgypenguins.png', width: 24, height: 24, default_zoom: 12},
51
- 'Dodge' => {url: 'https://raw.githubusercontent.com/cryptopunksnotdead/programming-cryptopunks/master/i/dodge.png', width: 24, height: 24, default_zoom: 12},
52
- 'Rocks' => {url: 'https://raw.githubusercontent.com/cryptopunksnotdead/awesome-24px/master/collection/rocks.png', width: 24, height: 24, default_zoom: 12},
53
- 'Punk Rocks' => {url: 'https://raw.githubusercontent.com/cryptopunksnotdead/programming-cryptopunks/master/i/punkrocks.png', width: 24, height: 24, default_zoom: 12},
54
- 'Tulips' => {url: 'https://raw.githubusercontent.com/cryptopunksnotdead/awesome-24px/master/collection/tulips.png', width: 24, height: 24, default_zoom: 12},
55
- }
56
-
57
- 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
58
21
 
59
22
  def initialize
60
- initialize_punk_directory
61
- initialize_collection
62
- load_config
63
- initialize_defaults
64
- observe_image_attribute_changes
23
+ @image = Model::Image.new
65
24
  create_gui
66
- self.image_index = 0
67
- @root.open
68
- end
69
-
70
- def collection_options
71
- COLLECTION_URL_MAP.keys
25
+ @image.image_index = 0
72
26
  end
73
27
 
74
- def palette_options
75
- PALETTES
76
- end
77
-
78
- def style_options
79
- STYLES
80
- end
81
-
82
- def initialize_punk_directory
83
- @punk_directory = @punk_config_directory = File.join(Dir.home, 'cryptopunks')
84
- FileUtils.mkdir_p(@punk_directory)
85
- end
86
-
87
- def initialize_collection
88
- return if @collection && @collection == @last_collection
89
- @collection ||= COLLECTION_URL_MAP.keys.first
90
- url = COLLECTION_URL_MAP[@collection][:url]
91
- width = COLLECTION_URL_MAP[@collection][:width]
92
- height = COLLECTION_URL_MAP[@collection][:height]
93
- @punk_file = File.join(@punk_config_directory, File.basename(url, '.png'))
94
- File.write(@punk_file, Net::HTTP.get(URI(url))) unless File.exist?(@punk_file)
95
- @images ||= {}
96
- @images[@collection] ||= Punks::Image::Composite.read(@punk_file, width: width, height: height)
97
- @last_collection = @collection
98
- self.image_index = 0
99
- @image_index_spinbox.to = @images[@collection].size - 1 if @image_index_spinbox
100
- end
101
-
102
- def load_config
103
- @punk_config_file = File.join(@punk_config_directory, 'cryptopunks.yml')
104
- FileUtils.touch(@punk_config_file)
105
- @punk_config = YAML.load(File.read(@punk_config_file)) || {punk_directory: @punk_directory}
106
- @punk_directory = @punk_config[:punk_directory]
107
- end
108
-
109
- def save_config
110
- File.write(@punk_config_file, YAML.dump(@punk_config))
111
- end
112
-
113
- def initialize_defaults
114
- @collection = COLLECTION_URL_MAP.keys.first
115
- @zoom = 12
116
- @palette = PALETTES.first
117
- @style = STYLES.first
118
- @led_spacing = 2
119
- @led_round_corner = false
120
- @sketch_line = 1
121
- @mirror = false
122
- @flip = false
123
- end
124
-
125
- def observe_image_attribute_changes
126
- observer = Glimmer::DataBinding::Observer.proc { generate_image }
127
- observer.observe(self, :collection)
128
- observer.observe(self, :image_index)
129
- observer.observe(self, :zoom)
130
- observer.observe(self, :palette)
131
- observer.observe(self, :style)
132
- observer.observe(self, :led_spacing)
133
- observer.observe(self, :led_round_corner)
134
- observer.observe(self, :sketch_line)
135
- observer.observe(self, :mirror)
136
- observer.observe(self, :flip)
137
- end
138
-
139
- def generate_image
140
- initialize_collection
141
- return if @image_index.to_i > @images[@collection].size
142
- 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")
143
- puts "Writing punk image to #{image_location}"
144
- selected_punk = @images[@collection][@image_index.to_i]
145
- selected_punk = selected_punk.change_palette8bit(Palette8bit.const_get(@palette.gsub(' ', '_').upcase.to_sym)) if @palette != PALETTES.first
146
- @original_zoom = @zoom
147
- if @previous_collection && @collection != @previous_collection && COLLECTION_URL_MAP[@collection][:width] != COLLECTION_URL_MAP[@previous_collection][:width]
148
- @zoom = COLLECTION_URL_MAP[@collection][:default_zoom]
149
- end
150
- if @style != STYLES.first
151
- style_options = {}
152
- if @style == 'Led'
153
- style_options[:spacing] = @led_spacing.to_i
154
- style_options[:round_corner] = @led_round_corner
155
- end
156
- if @style == 'Sketch'
157
- style_options[:line] = @sketch_line.to_i
158
- end
159
- selected_punk = selected_punk.send(@style.underscore, @zoom.to_i, **style_options)
160
- end
161
- selected_punk = selected_punk.mirror if @mirror
162
- selected_punk = selected_punk.flip if @flip
163
- selected_punk = selected_punk.zoom(@zoom.to_i) if @style == STYLES.first
164
- selected_punk.save(image_location)
165
- @image_label.image = image_location
166
- @output_location_entry.text = image_location
167
- @previous_style = @style
168
- @previous_collection = @collection
169
- notify_observers(:zoom) if @zoom != @original_zoom
28
+ def launch
29
+ @root.open
170
30
  end
171
31
 
172
32
  def create_gui
173
- @root = root {
33
+ @root = root { |root_proxy|
174
34
  title 'CryptoPunks GUI'
175
35
  iconphoto File.expand_path('../icons/cryptopunks-gui.png', __dir__)
176
36
 
177
- frame {
178
- label {
179
- text 'Collection:'
180
- }
181
- combobox {
182
- readonly true
183
- text <=> [self, :collection]
184
- }
185
-
186
- label {
187
- text 'Image Index:'
188
- }
189
- @image_index_spinbox = spinbox {
190
- from 0
191
- to @images[@collection].size - 1
192
- text <=> [self, :image_index]
193
- }
194
-
195
- label {
196
- text 'Zoom:'
197
- }
198
- spinbox {
199
- from 1
200
- to 72
201
- text <=> [self, :zoom]
202
- }
203
-
204
- label {
205
- text 'Palette:'
206
- }
207
- combobox {
208
- readonly true
209
- text <=> [self, :palette]
210
- }
211
-
212
- label {
213
- text 'Style:'
214
- }
215
- combobox {
216
- readonly true
217
- text <=> [self, :style, after_write: ->(val) {add_style_options}]
218
- }
219
-
220
- @style_options_frame = frame {
221
- padding 0
222
- }
223
-
224
- frame {
225
- padding 0
226
-
227
- checkbutton {
228
- grid row: 0, column: 0, column_weight: 0
229
- variable <=> [self, :mirror]
230
- }
231
- label {
232
- grid row: 0, column: 1
233
- text 'Mirror'
234
-
235
- on('Button-1') do
236
- self.mirror = !mirror
237
- end
238
- }
239
-
240
- checkbutton {
241
- grid row: 0, column: 2
242
- variable <=> [self, :flip]
243
- }
244
- label {
245
- grid row: 0, column: 3
246
- text 'Flip'
247
-
248
- on('Button-1') do
249
- self.flip = !flip
250
- end
251
- }
252
- }
253
-
254
- label {
255
- text 'Output Location:'
256
- }
257
- frame {
258
- padding 0
259
-
260
- @output_location_entry = entry {
261
- grid row: 0, column: 0
262
- readonly true
263
- width 47
264
- }
265
- button {
266
- grid row: 0, column: 1
267
- text '...'
268
- width 1.1
269
-
270
- on('command') do
271
- @punk_directory = choose_directory(parent: @root)
272
- @punk_config[:punk_directory] = @punk_directory
273
- save_config
274
- generate_image
275
- end
276
- }
277
- }
278
-
279
- @image_label = label {
280
- grid row_weight: 1
281
- }
282
- }
283
- }
284
- end
285
-
286
- def add_style_options
287
- @style_options_frame.content {
288
- @style_options_frame.children.each(&:destroy)
289
- if @style == 'Led'
290
- frame {
291
- padding 0
292
-
293
- label {
294
- grid row: 0, column: 0, column_weight: 0
295
- text 'Spacing:'
296
- }
297
- spinbox {
298
- grid row: 0, column: 1
299
- from 1
300
- to 72
301
- text <=> [self, :led_spacing]
302
- }
303
-
304
- checkbutton {
305
- grid row: 0, column: 2
306
- variable <=> [self, :led_round_corner]
307
- }
308
- label {
309
- grid row: 0, column: 3
310
- text 'Round Corner'
311
-
312
- on('Button-1') do
313
- self.led_round_corner = !led_round_corner
314
- end
315
- }
316
- }
317
- elsif @style == 'Sketch'
318
- frame {
319
- padding 0
320
-
321
- label {
322
- grid row: 0, column: 0, column_weight: 0
323
- text 'Line:'
324
- }
325
- spinbox {
326
- grid row: 0, column: 1
327
- from 1
328
- to 72
329
- text <=> [self, :sketch_line]
330
- }
331
- }
332
- else
333
- frame { # filler
334
- padding 0
335
- height 0
336
- width 0
337
- }
338
- end
37
+ cryptopunks_gui_menu_bar(root: root_proxy, image: @image)
38
+
39
+ image_frame(root: root_proxy, image: @image)
339
40
  }
340
41
  end
341
42
  end
@@ -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.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.9 ruby app
5
+ # stub: cryptopunks-gui 0.0.13 ruby app
6
6
 
7
7
  Gem::Specification.new do |s|
8
8
  s.name = "cryptopunks-gui".freeze
9
- s.version = "0.0.9"
9
+ s.version = "0.0.13"
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-30"
14
+ s.date = "2021-11-24"
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.1.4".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.33"])
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.33"])
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.9
4
+ version: 0.0.13
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-30 00:00:00.000000000 Z
11
+ date: 2021-11-24 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.33
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.33
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.1.4
150
157
  signing_key:
151
158
  specification_version: 4
152
159
  summary: CryptoPunks GUI for Simplified Minting