shoes-core 4.0.0.pre11 → 4.0.0.pre12

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: b4b04df9c670f569189c22acf3d710762cb070648e055b8caa4df59bd9ee54fc
4
- data.tar.gz: c3acdfe4ebb5e220cfa34f1c23ca267805c54e0e1140ecd84f0259dfea5fc4aa
3
+ metadata.gz: 661b33d7f533fcfeca029b50a73d2825fd861b9cb3dd22b802407c2c9530982a
4
+ data.tar.gz: 1910df83d014768abe2dbd8fbc4475b857ca9c84c96e85506aa8db8572ce891d
5
5
  SHA512:
6
- metadata.gz: 4d7b39734d1c215b6d74c9b59c4f3ad6a91f472a7f72dad13881ac05811ced22f44747d021a84ec262e9dff7d0fc72a7ec16b118b4169f7c0358f121c786ab38
7
- data.tar.gz: ff7a77a85ea9f3c2c73c15ef602a9dda20d90bd95975d4ab2aa35536cdb6383abad68004ec2459b3ef8bb1ce50c85769e5e09c207ac0fa034281b92f65ecd719
6
+ metadata.gz: 6955fbb19afbb56560f631f52c139ae43420da5c16cfd4f2cc85bb42114af6fbec7db5f49697fb9ce977f8a64b1b7d6425a4406f7580ed8fd0de0fb13cd56527
7
+ data.tar.gz: 1d9df772049d179b46c3a70a92c5309a09495812607cdbdc9b4366040d778652dabca4c807e9ff2e2eaf2f8def21f0f335541ee6072f44dfef1ff48e7d0183ab
@@ -69,12 +69,16 @@ class Shoes
69
69
  end
70
70
 
71
71
  def quit
72
+ Shoes.apps.each(&:close)
73
+ end
74
+
75
+ alias exit quit
76
+
77
+ def close
72
78
  Shoes.unregister self
73
79
  @__app__.quit
74
80
  end
75
81
 
76
- alias close quit
77
-
78
82
  def parent
79
83
  @__app__.current_slot.parent
80
84
  end
@@ -123,16 +127,19 @@ class Shoes
123
127
  inspect_details
124
128
  end
125
129
 
126
- DELEGATE_BLACKLIST = [:parent, :app].freeze
127
-
128
130
  # class definitions are evaluated top to bottom, want to have all of them
129
131
  # so define at bottom
130
132
  DELEGATE_METHODS = ((Shoes::App.public_instance_methods(false) +
131
- Shoes::DSL.public_instance_methods) - DELEGATE_BLACKLIST).freeze
133
+ Shoes::DSL.public_instance_methods)).freeze
132
134
 
133
135
  def self.subscribe_to_dsl_methods(klazz)
136
+ # Delegate anything in the app/dsl public list that DOESN'T have a method
137
+ # already defined on the class in question
138
+ methods_to_delegate = DELEGATE_METHODS - klazz.public_instance_methods
139
+
134
140
  klazz.extend Forwardable unless klazz.is_a? Forwardable
135
- klazz.def_delegators :app, *DELEGATE_METHODS
141
+ klazz.def_delegators :app, *methods_to_delegate
142
+
136
143
  @method_subscribers ||= []
137
144
  @method_subscribers << klazz
138
145
  end
@@ -2,6 +2,7 @@
2
2
  class Shoes
3
3
  class Button < Common::UIElement
4
4
  include Common::Clickable
5
+ include Common::Focus
5
6
  include Common::State
6
7
 
7
8
  # We don't actually support release from buttons, but want to use the
@@ -14,10 +15,6 @@ class Shoes
14
15
  styles[:text] = text || 'Button'
15
16
  end
16
17
 
17
- def focus
18
- @gui.focus
19
- end
20
-
21
18
  def text=(value)
22
19
  style(text: value.to_s)
23
20
  @gui.text = value.to_s
@@ -2,6 +2,7 @@
2
2
  class Shoes
3
3
  class CheckButton < Common::UIElement
4
4
  include Common::Clickable
5
+ include Common::Focus
5
6
  include Common::State
6
7
 
7
8
  def checked?
@@ -12,10 +13,6 @@ class Shoes
12
13
  style(checked: value)
13
14
  @gui.checked = value
14
15
  end
15
-
16
- def focus
17
- @gui.focus
18
- end
19
16
  end
20
17
 
21
18
  class Check < CheckButton
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+ class Shoes
3
+ module Common
4
+ module Focus
5
+ def focus
6
+ @gui.focus
7
+ end
8
+ end
9
+ end
10
+ end
@@ -5,6 +5,10 @@ class Shoes
5
5
  attr_reader :hover_blk, :leave_blk
6
6
 
7
7
  def self.included(base)
8
+ create_hover_class(base)
9
+ end
10
+
11
+ def self.create_hover_class(base)
8
12
  clazz = Class.new {}
9
13
  name = base.name.split("::").last
10
14
  Shoes.const_set("#{name}Hover", clazz)
@@ -47,7 +47,7 @@ class Shoes
47
47
  # @example
48
48
  # Shoes.configuration.backend_class(shoes_button) # => Shoes::Swt::Button
49
49
  def backend_class(object)
50
- klazz = object.is_a?(Class) ? object : object.class
50
+ klazz = object.is_a?(Class) ? object : find_shoes_base_class(object)
51
51
  class_name = klazz.name.split("::").last
52
52
  # Lookup with false to not consult modules higher in the chain Object
53
53
  # because Shoes::Swt.const_defined? 'Range' => true
@@ -55,6 +55,11 @@ class Shoes
55
55
  backend.const_get(class_name, false)
56
56
  end
57
57
 
58
+ def find_shoes_base_class(object)
59
+ return object.shoes_base_class if object.respond_to?(:shoes_base_class)
60
+ object.class
61
+ end
62
+
58
63
  # Creates an appropriate backend object, passing along additional
59
64
  # arguments
60
65
  #
@@ -2,6 +2,6 @@
2
2
 
3
3
  class Shoes
4
4
  module Core
5
- VERSION = "4.0.0.pre11"
5
+ VERSION = "4.0.0.pre12"
6
6
  end
7
7
  end
@@ -31,12 +31,12 @@ class Shoes
31
31
  flow margin_top: 10 do
32
32
  button "OK", margin_left: 150 do
33
33
  @result = @e.text
34
- quit
34
+ close
35
35
  end
36
36
 
37
37
  button "Cancel" do
38
38
  @result = nil
39
- quit
39
+ close
40
40
  end
41
41
  end
42
42
  end
@@ -60,6 +60,7 @@ require 'shoes/common/attachable'
60
60
  require 'shoes/common/changeable'
61
61
  require 'shoes/common/clickable'
62
62
  require 'shoes/common/fill'
63
+ require 'shoes/common/focus'
63
64
  require 'shoes/common/hover'
64
65
  require 'shoes/common/link_finder'
65
66
  require 'shoes/common/positioning'
@@ -251,6 +251,14 @@ EOS
251
251
 
252
252
  create Shoes::Shape, left, top, opts, blk
253
253
  end
254
+
255
+ def mask(*_)
256
+ raise Shoes::NotImplementedError,
257
+ <<~EOS
258
+ Sorry mask is not supported currently in Shoes 4!
259
+ Check out github issue #527 for any changes/updates or if you want to help :)
260
+ EOS
261
+ end
254
262
  end
255
263
  end
256
264
  end
@@ -2,6 +2,7 @@
2
2
  class Shoes
3
3
  class InputBox < Common::UIElement
4
4
  include Common::Changeable
5
+ include Common::Focus
5
6
  include Common::State
6
7
 
7
8
  def before_initialize(styles, text)
@@ -13,10 +14,6 @@ class Shoes
13
14
  update_visibility
14
15
  end
15
16
 
16
- def focus
17
- @gui.focus
18
- end
19
-
20
17
  def text
21
18
  @gui.text
22
19
  end
@@ -27,6 +27,7 @@ class Shoes
27
27
 
28
28
  class ListBox < Common::UIElement
29
29
  include Common::Changeable
30
+ include Common::Focus
30
31
  include Common::State
31
32
 
32
33
  style_with :change, :choose, :common_styles, :dimensions, :items, :state, :text
@@ -18,5 +18,6 @@ class Shoes
18
18
 
19
19
  class Stack < Slot; end
20
20
  class Flow < Slot; end
21
+ class Widget < Slot; end
21
22
  end
22
23
  end
@@ -1,13 +1,13 @@
1
1
  # frozen_string_literal: true
2
2
  class Shoes
3
3
  class Oval < Common::ArtElement
4
- style_with :art_styles, :center, :common_styles, :dimensions, :radius
4
+ style_with :art_styles, :center, :common_styles, :dimensions
5
5
  STYLES = { fill: Shoes::COLORS[:black] }.freeze
6
6
 
7
7
  def create_dimensions(left, top, width, height)
8
8
  left ||= @style[:left] || 0
9
9
  top ||= @style[:top] || 0
10
- width ||= @style[:diameter] || @style[:width] || (@style[:radius] || 0) * 2
10
+ width ||= @style[:width] || @style[:diameter] || (@style[:radius] || 0) * 2
11
11
  height ||= @style[:height] || width
12
12
 
13
13
  @dimensions = AbsoluteDimensions.new left, top, width, height, @style
@@ -7,6 +7,7 @@ require 'shoes/ui/cli/default_command'
7
7
  require 'shoes/ui/cli/help_command'
8
8
  require 'shoes/ui/cli/manual_command'
9
9
  require 'shoes/ui/cli/package_command'
10
+ require 'shoes/ui/cli/samples_command'
10
11
  require 'shoes/ui/cli/select_backend_command'
11
12
  require 'shoes/ui/cli/version_command'
12
13
 
@@ -17,6 +18,7 @@ class Shoes
17
18
  help: HelpCommand,
18
19
  manual: ManualCommand,
19
20
  package: PackageCommand,
21
+ samples: SamplesCommand,
20
22
  select_backend: SelectBackendCommand,
21
23
  version: VersionCommand,
22
24
  }.freeze
@@ -29,7 +31,7 @@ class Shoes
29
31
 
30
32
  def run(args)
31
33
  if args.empty?
32
- Shoes::UI::CLI::HelpCommand.new([]).run
34
+ Shoes::UI::CLI::HelpCommand.new.run
33
35
  exit(1)
34
36
  end
35
37
 
@@ -39,7 +41,7 @@ class Shoes
39
41
 
40
42
  def create_command(*args)
41
43
  command_class = SUPPORTED_COMMANDS[args.first.to_sym] || DefaultCommand
42
- command_class.new(args.dup)
44
+ command_class.new(*args.dup)
43
45
  end
44
46
  end
45
47
  end
@@ -5,7 +5,7 @@ class Shoes
5
5
  class BaseCommand
6
6
  attr_reader :args
7
7
 
8
- def initialize(args)
8
+ def initialize(*args)
9
9
  @args = args
10
10
  end
11
11
 
@@ -16,11 +16,22 @@ class Shoes
16
16
  Shoes.logger.warn("Unexpected extra parameters '#{unexpected}'")
17
17
  end
18
18
 
19
- def self.help
19
+ def parse!(args)
20
+ options.parse!(args)
21
+ true
22
+ rescue OptionParser::InvalidOption => e
23
+ puts "Whoops! #{e.message}"
24
+ puts
25
+ puts help
26
+
27
+ false
28
+ end
29
+
30
+ def help
20
31
  nil
21
32
  end
22
33
 
23
- def self.help_from_options(command, options)
34
+ def help_from_options(command, options)
24
35
  lines = ["#{command}\n"] + options.summarize
25
36
  lines.join("")
26
37
  end
@@ -16,18 +16,7 @@ class Shoes
16
16
  end
17
17
  end
18
18
 
19
- def parse!(args)
20
- self.class.options.parse!(args)
21
- true
22
- rescue OptionParser::InvalidOption => e
23
- puts "Whoops! #{e.message}"
24
- puts
25
- puts self.class.help
26
-
27
- false
28
- end
29
-
30
- def self.options
19
+ def options
31
20
  OptionParser.new do |opts|
32
21
  # Keep around command dashed options
33
22
  opts.on('-v', '--version', 'Shoes version') do
@@ -47,7 +36,7 @@ class Shoes
47
36
  end
48
37
  end
49
38
 
50
- def self.help
39
+ def help
51
40
  help_from_options("shoes [options] file", options)
52
41
  end
53
42
  end
@@ -13,7 +13,7 @@ class Shoes
13
13
  command_classes.concat(SUPPORTED_COMMANDS.map(&:last))
14
14
 
15
15
  command_classes.each do |command_class|
16
- text = command_class.help.to_s
16
+ text = command_class.new([]).help.to_s
17
17
  unless text.empty?
18
18
  puts text
19
19
  puts
@@ -21,7 +21,7 @@ class Shoes
21
21
  end
22
22
  end
23
23
 
24
- def self.help
24
+ def help
25
25
  <<-EOS
26
26
  shoes help
27
27
  Displays this help text
@@ -8,7 +8,7 @@ class Shoes
8
8
  Shoes::Manual.run "English"
9
9
  end
10
10
 
11
- def self.help
11
+ def help
12
12
  <<-EOS
13
13
  shoes manual
14
14
  Run the interactive Shoes manual
@@ -14,12 +14,12 @@ class Shoes
14
14
  rescue OptionParser::InvalidOption => e
15
15
  puts "Whoops! #{e.message}"
16
16
  puts
17
- puts self.class.help
17
+ puts help
18
18
 
19
19
  false
20
20
  end
21
21
 
22
- def self.help
22
+ def help
23
23
  help_from_options("shoes package [options] file",
24
24
  Shoes::Packager.new.options) + <<-EOS
25
25
 
@@ -0,0 +1,42 @@
1
+ # frozen_string_literal: true
2
+ require 'fileutils'
3
+ require 'shoes/samples'
4
+
5
+ class Shoes
6
+ module UI
7
+ class CLI
8
+ class SamplesCommand < BaseCommand
9
+ attr_accessor :destination_dir
10
+
11
+ def run
12
+ if parse!(args)
13
+ source = Shoes::Samples.path
14
+ destination = File.join((destination_dir || Dir.pwd), "shoes_samples")
15
+
16
+ if File.exist?(destination)
17
+ puts "Oops, #{destination} already exists! Try somewhere else, maybe with -d."
18
+ else
19
+ FileUtils.cp_r source, destination
20
+ end
21
+ end
22
+ end
23
+
24
+ def options
25
+ OptionParser.new do |opts|
26
+ opts.on('-dDEST', '--destination=DEST', 'Destination directory') do |destination|
27
+ self.destination_dir = destination
28
+ end
29
+ end
30
+ end
31
+
32
+ def help
33
+ help_from_options("shoes samples [options]",
34
+ options) + <<-EOS
35
+
36
+ Installs samples to try out.
37
+ EOS
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
@@ -9,7 +9,7 @@ class Shoes
9
9
  Shoes::UI::Picker.new.run(ENV["SHOES_BIN_DIR"], backend)
10
10
  end
11
11
 
12
- def self.help
12
+ def help
13
13
  <<-EOS
14
14
  shoes select_backend [backend]
15
15
  Select a Shoes backend to use. A backend can be specified, or Shoes will
@@ -7,7 +7,7 @@ class Shoes
7
7
  puts "Shoes #{Shoes::Core::VERSION}"
8
8
  end
9
9
 
10
- def self.help
10
+ def help
11
11
  <<-EOS
12
12
  shoes version
13
13
  Prints the current Shoes version
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class Shoes
4
- VERSION = "4.0.0.pre11"
4
+ VERSION = "4.0.0.pre12"
5
5
  end
@@ -2,17 +2,22 @@
2
2
  class Shoes
3
3
  # This is the superclass for creating custom Shoes widgets.
4
4
  #
5
- # To use, inherit from {Shoes::Widget}. You get a few magical effects:
5
+ # To use, inherit from {Shoes::Widget} and implement a initialize_widget
6
+ # method. You get a few magical effects:
6
7
  #
7
8
  # * When you inherit from {Shoes::Widget}, you get a method in your Apps to
8
9
  # create your widgets. The method is lower- and snake-cased. It returns
9
10
  # an instance of your widget class.
11
+ #
10
12
  # * Your widgets delegate missing methods to their app object. This
11
13
  # allows you to use the Shoes DSL within your widgets.
12
14
  #
15
+ # * Your widget otherwise behaves like a flow. If the final parameter to
16
+ # the widget method is a Hash, that will initialize the flow as well.
17
+ #
13
18
  # @example
14
19
  # class SayHello < Shoes::Widget
15
- # def initialize word
20
+ # def initialize_widget word
16
21
  # para "Hello #{word}", stroke: green, size: 80
17
22
  # end
18
23
  # end
@@ -21,40 +26,47 @@ class Shoes
21
26
  # say_hello 'Shoes'
22
27
  # end
23
28
  #
24
- class Widget
25
- include Common::Inspect
26
-
29
+ class Widget < Shoes::Flow
27
30
  Shoes::App.subscribe_to_dsl_methods self
28
31
 
29
- attr_accessor :parent
30
- attr_writer :app
32
+ attr_accessor :original_args
31
33
 
32
- class << self
33
- attr_accessor :app
34
+ # Having Widget define initialize makes it easier for us to detect whether
35
+ # subclasses have inappropriately overridden it or not.
36
+ def initialize(*_)
37
+ super
34
38
  end
35
39
 
36
- # lookup a bit more complicated as during initialize we do
37
- # not have @app yet...
38
- def app
39
- @app || self.class.app
40
+ def initialize_widget
41
+ # Expected to be overridden by children but not guaranteed
42
+ end
43
+
44
+ def shoes_base_class
45
+ Shoes::Widget
40
46
  end
41
47
 
42
48
  def self.inherited(klass, &_blk)
49
+ # Ensure Hover styling class exists, but Widget gets hover behavior from parents
50
+ Shoes::Common::Hover.create_hover_class(klass)
51
+
43
52
  dsl_method = dsl_method_name(klass)
44
- Shoes::App.new_dsl_method(dsl_method) do |*args, &blk|
45
- # we set app 2 times because widgets execute most of their code
46
- # straight in initialize. I dunno if there is a good way of setting
47
- # an @app instance variable before initialize is executed. We could
48
- # hand it over in #initialize but that would break the interface
49
- # and people would have to set it themselves or make sure to call
50
- # super so for not it's like this.
51
- # Setting the ref on the instance is important as we might have
52
- # instances of the same widget in different Shoes::Apps so each one
53
- # needs to save the reference to the one it was started with
54
- klass.app = self
55
- widget_instance = klass.new(*args, &blk)
56
- widget_instance.app = self
57
- widget_instance.parent = @__app__.current_slot
53
+ Shoes::App.new_dsl_method(dsl_method) do |*args|
54
+ # Old-school widgets that try to use initialize instead of
55
+ # initialize_widget will get a warning before they likely fail on new.
56
+ klass.warn_about_initialize
57
+
58
+ # If last arg is a Hash, pass that to the underlying Flow
59
+ container_args = args.last.is_a?(Hash) ? args.last : {}
60
+
61
+ # Expected to call through to initialize our underlying slot behavior
62
+ widget_instance = klass.new(@__app__, @__app__.current_slot, container_args)
63
+
64
+ # Call the user's widget initialization, with proper slot context
65
+ old_current_slot = @__app__.current_slot
66
+ @__app__.current_slot = widget_instance
67
+ widget_instance.initialize_widget(*args)
68
+ @__app__.current_slot = old_current_slot
69
+
58
70
  widget_instance
59
71
  end
60
72
  end
@@ -64,5 +76,16 @@ class Shoes
64
76
  .gsub(/([A-Z]+)([A-Z][a-z])/, '\1_\2')
65
77
  .gsub(/([a-z\d])([A-Z])/, '\1_\2').downcase
66
78
  end
79
+
80
+ def self.warn_about_initialize
81
+ if instance_method(:initialize).owner != Shoes::Widget
82
+ Shoes.logger.warn <<~EOS
83
+ You've defined an `initialize` method on class '#{self}'. This is no longer supported.
84
+ Your widget likely won't display, and you'll potentially receive argument errors.
85
+
86
+ Instead, define `initialize_widget` and we'll call it from your generated widget method.
87
+ EOS
88
+ end
89
+ end
67
90
  end
68
91
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: shoes-core
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.0.0.pre11
4
+ version: 4.0.0.pre12
5
5
  platform: ruby
6
6
  authors:
7
7
  - Team Shoes
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-08-21 00:00:00.000000000 Z
11
+ date: 2017-10-02 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: Shoes is the best little GUI toolkit for Ruby. Shoes makes building for
14
14
  Mac, Windows, and Linux super simple. This is the DSL for writing your app. You'll
@@ -45,6 +45,7 @@ files:
45
45
  - lib/shoes/common/changeable.rb
46
46
  - lib/shoes/common/clickable.rb
47
47
  - lib/shoes/common/fill.rb
48
+ - lib/shoes/common/focus.rb
48
49
  - lib/shoes/common/hover.rb
49
50
  - lib/shoes/common/image_handling.rb
50
51
  - lib/shoes/common/inspect.rb
@@ -149,6 +150,7 @@ files:
149
150
  - lib/shoes/ui/cli/help_command.rb
150
151
  - lib/shoes/ui/cli/manual_command.rb
151
152
  - lib/shoes/ui/cli/package_command.rb
153
+ - lib/shoes/ui/cli/samples_command.rb
152
154
  - lib/shoes/ui/cli/select_backend_command.rb
153
155
  - lib/shoes/ui/cli/version_command.rb
154
156
  - lib/shoes/ui/picker.rb
@@ -180,7 +182,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
180
182
  version: 1.3.1
181
183
  requirements: []
182
184
  rubyforge_project:
183
- rubygems_version: 2.6.11
185
+ rubygems_version: 2.6.13
184
186
  signing_key:
185
187
  specification_version: 4
186
188
  summary: The best little DSL for the best little GUI toolkit for Ruby.