tk-doubleslider 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 7f2017932a98ff943f05066b9e8e77c6f0d998d5
4
+ data.tar.gz: 1b7aedd78ff5f2f85bc664ab70dc3db2873834f0
5
+ SHA512:
6
+ metadata.gz: 26cd45d3211fc4b549ea1d0cb8f3386c04528e2bd53db992f559eb4561599812238aafa082a2516ff68746c0103a28480b25cc2d1832ca6fbac952f39fb82ed2
7
+ data.tar.gz: 78446d42e156067ac7982faad07352dcabeac9244582d46287e6e7446e7c757b4f901d87fa872b6e8175b76943467d7ceda5ca055baca7b499176c8e489e5563
@@ -0,0 +1,18 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ .ruby-*
7
+ Gemfile.lock
8
+ InstalledFiles
9
+ _yardoc
10
+ coverage
11
+ doc/
12
+ lib/bundler/man
13
+ pkg
14
+ rdoc
15
+ spec/reports
16
+ test/tmp
17
+ test/version_tmp
18
+ tmp
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in tk-doubleslider.gemspec
4
+ gemspec
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 chrislee35
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,126 @@
1
+ # Tk::Doubleslider
2
+
3
+ A double-headed slider widget allows for a range to be specified. This implementation works for Ruby Tk and provides ways to provide customized formatting of values, non-linear values, and log-based sliders (i.e., lots of accuracy for low values, but not for high values).
4
+
5
+ This has been tested in:
6
+ * ruby-1.8.7-p371
7
+ * ruby-1.9.3-p392
8
+ * ruby-2.0.0-p0
9
+
10
+ RVM install command example (rvm doesn't install with tk or tcl by default):
11
+
12
+ rvm reinstall 1.9.3 --enable-shared --enable-pthread --with-tk --with-tcl
13
+
14
+ ## Installation
15
+
16
+ Add this line to your application's Gemfile:
17
+
18
+ gem 'tk-doubleslider'
19
+
20
+ And then execute:
21
+
22
+ $ bundle
23
+
24
+ Or install it yourself as:
25
+
26
+ $ gem install tk-doubleslider
27
+
28
+ ## Usage
29
+
30
+ Within a Tk project, you'll need to have a Window with a Frame to place the Doubleslider within. Here is a minimalistic example:
31
+
32
+ require 'tk'
33
+
34
+ def minimal_example()
35
+ # create the root window for this Tk app
36
+ root = TkRoot.new() {
37
+ title "Tk::DoubleSlider Test"
38
+ protocol('WM_DELETE_WINDOW', proc{ exit })
39
+ }
40
+ # bind ctrl-c to exit
41
+ root.bind('Control-c', proc{ exit })
42
+ # create a frame to place the Doubleslider within
43
+ left_frame = TkFrame.new(root)
44
+ left_frame.grid(:row=>0,:column=>0,:sticky=>'new')
45
+ # create a "time window" from 7 days ago until now
46
+ time_min = Time.now.to_i - (7*24*60*60)
47
+ time_max = Time.now.to_i
48
+ # create a "time slider" with a value formatter in HH:MM format and a delta formatter of 0.00 hours.
49
+ timeslide = Tk::Doubleslider.new( left_frame,
50
+ :min=>time_min, # what's the minimal possible value
51
+ :max=>time_max, # what's the maximum possible value
52
+ :low=>time_min, # what's the current minimum value
53
+ :high=>time_max, # what's the current max
54
+ :snap => 300, # when you slide the slider, by what increments (for this example, it's every 5 minutes)
55
+ :label=>'Time', # what do you call this slider
56
+ :valuefmt => proc { |x| Time.at(x).strftime("%H:%M") }, # how shall we format the values
57
+ :deltafmt => proc { |x| sprintf("%0.2f hours", (x/3600.0)) } # how shall we format the delta
58
+ )
59
+ # pack everything together
60
+ timeslide.pack()
61
+ # enter the main loop
62
+ Tk.mainloop()
63
+ end
64
+
65
+
66
+ Great, so what options can Tk::Doubleslider take and what are their defaults?
67
+
68
+ height = 36.0 # height in pixels
69
+ width = 360.0 # width in pixel
70
+ min = 0.0 # minimum possible value
71
+ max = 0.0 # maximum possible value
72
+ low = 0.0 # the current minimum value
73
+ high = 0.0 # the current high value
74
+ ballsize = 5 # the size in pixels of the header (the knob)
75
+ snap = false # snap increments in value
76
+ logbase = false # use logirithms to scale the slider (pretty cool stuff)
77
+ # colors for the slider
78
+ colors = {
79
+ :background => 'grey20',
80
+ :line => 'grey75',
81
+ :low_head => '#996666',
82
+ :high_head => '#996666',
83
+ :text => 'white',
84
+ :delta => 'white',
85
+ }
86
+ # margins
87
+ left_margin = 10.0
88
+ right_margin = 20.0
89
+ top_margin = 6.0
90
+ bottom_margin = 4.0
91
+ change_cb = nil # callback to call when a selection has changed, object must have a method called, "call", which must accept a low and high value (see example below)
92
+ # how to format the value
93
+ valuefmt = proc { |x| sprintf "%d", x }
94
+ # how to format the delta (defaults to valuefmt)
95
+ deltafmt = nil
96
+ # the label to display on the slider, a string
97
+ label = nil
98
+
99
+ Now, how about that callback that I promised you?
100
+
101
+ class TkDS_Callback
102
+ def call(low, high)
103
+ puts "#{low} #{high}"
104
+ if low < 90
105
+ puts "Maybe you should reconsider your answer"
106
+ end
107
+ end
108
+ end
109
+
110
+ timeslide = Tk::Doubleslider.new( left_frame, :min => 0, :max => 100, :low => 90, :high => 100,
111
+ :cb => TkDS_Callback.new, :label => 'your love for TkDS')
112
+
113
+
114
+
115
+ ## Contributing
116
+
117
+ 1. Fork it
118
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
119
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
120
+ 4. Push to the branch (`git push origin my-new-feature`)
121
+ 5. Create new Pull Request
122
+
123
+ ## Copyright
124
+
125
+ Copyright (c) 2011 Chris Lee, PhD. See LICENSE.txt for
126
+ further details.
@@ -0,0 +1,12 @@
1
+ #!/usr/bin/env rake
2
+ require "bundler/gem_tasks"
3
+
4
+ require 'rake/testtask'
5
+
6
+ Rake::TestTask.new do |t|
7
+ t.libs << 'lib'
8
+ t.test_files = FileList['test/test_*.rb']
9
+ t.verbose = true
10
+ end
11
+
12
+ task :default => :test
@@ -0,0 +1,174 @@
1
+ #require "tk/doubleslider/version"
2
+ # DESCRIPTION: provides a TK widget with two "heads", a high and a low.
3
+ # Copyright (C) 2007 Christopher Lee
4
+ #
5
+ # This program is free software: you can redistribute it and/or modify
6
+ # it under the terms of the GNU General Public License as published by
7
+ # the Free Software Foundation, either version 3 of the License, or
8
+ # (at your option) any later version.
9
+ #
10
+ # This program is distributed in the hope that it will be useful,
11
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ # GNU General Public License for more details.
14
+ #
15
+ # You should have received a copy of the GNU General Public License
16
+ # along with this program. If not, see <http://www.gnu.org/licenses/>.
17
+ module Tk
18
+ class Doubleslider
19
+ VERSION = "0.1.1"
20
+
21
+ def pack(*args)
22
+ @canvas.pack(*args)
23
+ end
24
+
25
+ def redraw
26
+ @canvas.delete('all');
27
+ x1 = value2x(@low)
28
+ x2 = value2x(@high)
29
+ y = @height/2
30
+ TkcText.new(@canvas, 2, @height - 2, :text=>@label, :anchor=>'sw', :fill => @colors[:text]) if @label
31
+ TkcLine.new(@canvas, @left_margin, y, @width - @right_margin, y, :fill => @colors[:line], :width => 1, :tags => ['track'])
32
+ TkcLine.new(@canvas, @left_margin, y, @width - @right_margin, y, :fill => @colors[:line], :width => 4, :tags => ['selection'])
33
+ TkcOval.new(@canvas, x1 - @ballsize, y - @ballsize, x1 + @ballsize, y + @ballsize, :fill => @colors[:low_head], :width => 1, :tags => ['low'])
34
+ TkcOval.new(@canvas, x2 - @ballsize, y - @ballsize, x2 + @ballsize, y + @ballsize, :fill => @colors[:high_head], :width => 1, :tags => ['high'])
35
+ if @valuefmt
36
+ TkcText.new(@canvas, x1, @top_margin, :text => @valuefmt.call(@low), :tags => ['lowvalue'], :fill => @colors[:text])
37
+ TkcText.new(@canvas, x2, @height - @bottom_margin, :text => @valuefmt.call(@high), :tags => ['highvalue'], :fill => @colors[:text])
38
+ fmt = @deltafmt || @valuefmt # use delta format instead of value format if it is defined
39
+ TkcText.new(@canvas, (x1+x2)/2, y, :text => fmt.call(@high - @low), :tags => ['delta'], :fill => @colors[:delta])
40
+ coords = @canvas.bbox('delta')
41
+ TkcRectangle.new(@canvas,coords[0], coords[1], coords[2], coords[3], :fill => @colors[:background], :tags => ['deltabg'], :outline => @colors[:background]) if coords.length > 0
42
+ @canvas.raise('delta','all')
43
+ end
44
+ @canvas.itembind('low', 'ButtonPress-1', proc { @sel = 'low' })
45
+ @canvas.itembind('high', 'ButtonPress-1', proc { @sel = 'high' })
46
+ @canvas.itembind('all', 'ButtonRelease-1', proc { @sel = nil })
47
+ @canvas.itembind('low||high', 'Button1-Motion', proc { |x,y| move(@sel,x,y) }, "%x %y")
48
+ end
49
+
50
+ def move(tag, x, y)
51
+ return unless @sel
52
+ @canvas.raise @sel, 'all'
53
+ x = @left_margin if x < @left_margin
54
+ x = @width - @right_margin if x > @width - @right_margin
55
+ x = value2x(snap(x2value(x)))
56
+ y = @height/2
57
+ # don't update the text and deltas unless they need to be updated
58
+ return if instance_variable_get("@#{@sel}") == x2value(x)
59
+ instance_variable_set("@#{@sel}",x2value(x))
60
+ @canvas.coords(@sel, x - @ballsize, y - @ballsize, x + @ballsize, y + @ballsize)
61
+ if @sel == 'low' and @low > @high
62
+ @high = @low
63
+ @canvas.coords('high', x - @ballsize, y - @ballsize, x + @ballsize, y + @ballsize)
64
+ elsif @sel == 'high' and @high < @low
65
+ @low = @high
66
+ @canvas.coords('low', x - @ballsize, y - @ballsize, x + @ballsize, y + @ballsize)
67
+ end
68
+ lx = value2x(@low)
69
+ hx = value2x(@high)
70
+ @canvas.coords('selection', lx, y, hx, y)
71
+ if @valuefmt
72
+ @canvas.coords('lowvalue', lx, @top_margin)
73
+ @canvas.coords('highvalue', hx, @height - @bottom_margin)
74
+ @canvas.coords('delta', (lx+hx)/2, y)
75
+ @canvas.itemconfigure('lowvalue', :text => @valuefmt.call(@low))
76
+ @canvas.itemconfigure('highvalue', :text => @valuefmt.call(@high))
77
+ fmt = @deltafmt || @valuefmt # use delta format instead of value format if it is defined
78
+ @canvas.itemconfigure('delta', :text => fmt.call(@high - @low))
79
+ coords = @canvas.bbox('delta')
80
+ w1 = coords[2] - coords[0]
81
+ if coords[0] < lx +5
82
+ if lx < @width/2
83
+ coords2 = @canvas.bbox('lowvalue')
84
+ ox = coords2[2] + 10 + (w1/2)
85
+ oy = @top_margin
86
+ @canvas.coords('delta',ox,oy)
87
+ else
88
+ coords2 = @canvas.bbox('highvalue')
89
+ ox = coords2[0] - 10 - (w1/2)
90
+ oy = @height - @bottom_margin
91
+ @canvas.coords('delta',ox,oy)
92
+ end
93
+ end
94
+ coords = @canvas.bbox('delta')
95
+ @canvas.coords('deltabg', coords[0], coords[1], coords[2], coords[3])
96
+ end
97
+ @change_cb.call(@low,@high) if @change_cb
98
+ end
99
+
100
+ def snap(x)
101
+ return x unless @snap
102
+ return @max if x > @max - @snap
103
+ x = (x - (x % @snap)).to_i
104
+ return x
105
+ end
106
+
107
+ def x2value(x)
108
+ x = @left_margin if x < @left_margin
109
+ r = @width - @right_margin
110
+ x = r if x > r
111
+ l = @left_margin
112
+ o = (x - l).to_f
113
+ dx = (r - l).to_f
114
+ frac = o/dx
115
+ if @logbase
116
+ return @max**(o/dx)
117
+ else
118
+ return @min+((o/dx)*(@max - @min))
119
+ end
120
+ end
121
+
122
+ def value2x(v)
123
+ v = @max if v > @max
124
+ v = @min if v < @min
125
+ w = @width - @left_margin - @right_margin
126
+ if @logbase
127
+ return @left_margin + (Math.log(v)*w/Math.log(@max))
128
+ else
129
+ return @left_margin + (((v - @min).to_f/(@max - @min).to_f)*w)
130
+ end
131
+ end
132
+
133
+ attr_accessor :change_cb, :valuefmt, :colors
134
+ def initialize(parent,*args)
135
+ @height = 36.0
136
+ @width = 360.0
137
+ @min = @max = @low = @high = 0.0
138
+ @ballsize = 5
139
+ @snap = false
140
+ @logbase = false
141
+ @colors = {
142
+ :background => 'grey20',
143
+ :line => 'grey75',
144
+ :low_head => '#996666',
145
+ :high_head => '#996666',
146
+ :text => 'white',
147
+ :delta => 'white',
148
+ }
149
+ @left_margin = 10.0
150
+ @right_margin = 20.0
151
+ @top_margin = 6.0
152
+ @bottom_margin = 4.0
153
+ @selection = nil
154
+ @change_cb = nil
155
+ @valuefmt = proc { |x| sprintf "%d", x }
156
+ @deltafmt = nil
157
+ @label = nil
158
+ if args.length > 0
159
+ args[0].each do |k,v|
160
+ if instance_variable_defined?("@#{k}")
161
+ if v =~ /^[\d\.]+$/
162
+ instance_variable_set("@#{k}", v.to_f)
163
+ else
164
+ instance_variable_set("@#{k}", v)
165
+ end
166
+ end
167
+ end
168
+ end
169
+ @canvas = TkCanvas.new(parent, :width => @width, :height => @height, :scrollregion => [0, 0, @width, @height])
170
+ @canvas.configure('background', @colors[:background]) if @colors[:background]
171
+ redraw
172
+ end
173
+ end
174
+ end
@@ -0,0 +1,5 @@
1
+ module Tk
2
+ module Doubleslider
3
+ VERSION = "0.1.1"
4
+ end
5
+ end
@@ -0,0 +1,3 @@
1
+ require 'test/unit'
2
+ require 'tk'
3
+ require File.expand_path('../../lib/tk/doubleslider.rb', __FILE__)
@@ -0,0 +1,42 @@
1
+ unless Kernel.respond_to?(:require_relative)
2
+ module Kernel
3
+ def require_relative(path)
4
+ require File.join(File.dirname(caller[0]), path.to_str)
5
+ end
6
+ end
7
+ end
8
+
9
+ require_relative 'helper'
10
+
11
+ class TestDoubleslider < Test::Unit::TestCase
12
+ def test_display_double_headed_slider_with_linear_scale_and_custom_value_and_delta_formatters
13
+ # create the root window for this Tk app
14
+ root = TkRoot.new() {
15
+ title "Tk::DoubleSlider Test"
16
+ protocol('WM_DELETE_WINDOW', proc{ exit })
17
+ }
18
+ # bind ctrl-c to exit
19
+ root.bind('Control-c', proc{ exit })
20
+ # create a frame to place the Doubleslider within
21
+ left_frame = TkFrame.new(root)
22
+ left_frame.grid(:row=>0,:column=>0,:sticky=>'new')
23
+ # create a "time window" from 7 days ago until now
24
+ time_min = Time.now.to_i - (7*24*60*60)
25
+ time_max = Time.now.to_i
26
+ # create a "time slider" with a value formatter in HH:MM format and a delta formatter of 0.00 hours.
27
+ timeslide = Tk::Doubleslider.new( left_frame,
28
+ :min=>time_min, # what's the minimal possible value
29
+ :max=>time_max, # what's the maximum possible value
30
+ :low=>time_min, # what's the current minimum value
31
+ :high=>time_max, # what's the current max
32
+ :snap => 300, # when you slide the slider, by what increments (for this example, it's every 5 minutes)
33
+ :label=>'Time', # what do you call this slider
34
+ :valuefmt => proc { |x| Time.at(x).strftime("%H:%M") }, # how shall we format the values
35
+ :deltafmt => proc { |x| sprintf("%0.2f hours", (x/3600.0)) } # how shall we format the delta
36
+ )
37
+ # pack everything together
38
+ timeslide.pack()
39
+ # enter the main loop
40
+ Tk.mainloop()
41
+ end
42
+ end
@@ -0,0 +1,27 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'tk/doubleslider/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "tk-doubleslider"
8
+ spec.version = Tk::Doubleslider::VERSION
9
+ spec.authors = ["chrislee35"]
10
+ spec.email = ["rubygems@chrislee.dhs.org"]
11
+ spec.description = %q{This provides an advanced, double-headed slider widget that allows selection of a range of values on a linear, log, square root, or cube root axis.}
12
+ spec.summary = %q{A double headed slider widget for Tk}
13
+ spec.homepage = "https://rubygems.org/gems/tk-doubleslider"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files`.split($/)
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_development_dependency "bundler", "~> 1.3"
22
+ spec.add_development_dependency "rake"
23
+
24
+ #spec.add_runtime_dependency "tk"
25
+
26
+ spec.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
27
+ end
metadata ADDED
@@ -0,0 +1,85 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: tk-doubleslider
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.1
5
+ platform: ruby
6
+ authors:
7
+ - chrislee35
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2013-05-10 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ~>
18
+ - !ruby/object:Gem::Version
19
+ version: '1.3'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: '1.3'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ description: This provides an advanced, double-headed slider widget that allows selection
42
+ of a range of values on a linear, log, square root, or cube root axis.
43
+ email:
44
+ - rubygems@chrislee.dhs.org
45
+ executables: []
46
+ extensions: []
47
+ extra_rdoc_files: []
48
+ files:
49
+ - .gitignore
50
+ - Gemfile
51
+ - LICENSE.txt
52
+ - README.md
53
+ - Rakefile
54
+ - lib/tk/doubleslider.rb
55
+ - lib/tk/doubleslider/version.rb
56
+ - test/helper.rb
57
+ - test/test_tk-doubleslider.rb
58
+ - tk-doubleslider.gemspec
59
+ homepage: https://rubygems.org/gems/tk-doubleslider
60
+ licenses:
61
+ - MIT
62
+ metadata: {}
63
+ post_install_message:
64
+ rdoc_options: []
65
+ require_paths:
66
+ - lib
67
+ required_ruby_version: !ruby/object:Gem::Requirement
68
+ requirements:
69
+ - - '>='
70
+ - !ruby/object:Gem::Version
71
+ version: '0'
72
+ required_rubygems_version: !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - - '>='
75
+ - !ruby/object:Gem::Version
76
+ version: '0'
77
+ requirements: []
78
+ rubyforge_project:
79
+ rubygems_version: 2.0.3
80
+ signing_key:
81
+ specification_version: 4
82
+ summary: A double headed slider widget for Tk
83
+ test_files:
84
+ - test/helper.rb
85
+ - test/test_tk-doubleslider.rb