summaryrefslogtreecommitdiff
path: root/ext/tk/sample/24hr_clock.rb
diff options
context:
space:
mode:
authornagai <nagai@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2005-11-15 07:51:30 +0000
committernagai <nagai@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2005-11-15 07:51:30 +0000
commitfb10e93036279b422ff566c92d91133623e8596b (patch)
tree251ff3c09c6f4de03d88d9aa3c643b836a2e573d /ext/tk/sample/24hr_clock.rb
parentea4a254de5b2b369c96e1e7591230bee54a2b4ab (diff)
* ext/tk/sample/24hr_clock.rb: a new example about handling of canvas items.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@9544 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'ext/tk/sample/24hr_clock.rb')
-rw-r--r--ext/tk/sample/24hr_clock.rb286
1 files changed, 286 insertions, 0 deletions
diff --git a/ext/tk/sample/24hr_clock.rb b/ext/tk/sample/24hr_clock.rb
new file mode 100644
index 0000000000..60d8072c57
--- /dev/null
+++ b/ext/tk/sample/24hr_clock.rb
@@ -0,0 +1,286 @@
+#!/usr/bin/env ruby
+
+require 'tk'
+
+class Clock
+ def initialize(clock24 = true)
+ @clock = (clock24)? 24: 12
+
+ @size = 200
+ @cdot_size = 5
+
+ @cdot_color = 'black'
+ @hour_hand_color = 'black'
+ @minute_hand_color = 'gray25'
+ @second_hand_color = 'gray50'
+
+ @mark_font = 'Helvetica -14'
+ @mark_width = 3
+ @mark_color = 'black'
+ @submark_color = 'gray50'
+
+ @c = TkCanvas.new(:width=>2*@size, :height=>2*@size,
+ :scrollregion=>[-@size, -@size, @size, @size]
+ ).pack(:fill=>:both, :expand=>true)
+
+ @tag = TkcTag.new(@c)
+ @hand_tag = TkcTag.new(@c)
+
+ @circle_coords = [[-0.9*@size, -0.9*@size], [0.9*@size, 0.9*@size]]
+ @oval = TkcOval.new(@c, @circle_coords, :fill=>'white', :tags=>[@tag])
+
+ f = TkFrame.new.pack
+ TkLabel.new(f, :text=>'CURRENT:').pack(:side=>:left)
+ @now = TkLabel.new(f, :text=>'00:00:00').pack(:side=>:left, :padx=>2)
+ TkLabel.new(f, :text=>' ').pack(:side=>:left)
+ TkLabel.new(f, :text=>' ').pack(:side=>:right)
+ @l = TkLabel.new(f, :text=>'00:00').pack(:side=>:right, :padx=>2)
+ TkLabel.new(f, :text=>'MOUSE-POINTER:').pack(:side=>:right)
+
+ cmd = proc{|x, y|
+ @l.text = '%02d:%02d' % coords_to_time(@c.canvasx(x), @c.canvasy(y))
+ }
+ @c.bind('Motion', cmd, '%x %y')
+ @tag.bind('Motion', cmd, '%x %y')
+
+ _create_hands
+ _create_marks
+
+ timer_proc = proc{
+ t = Time.now
+ @now.text = '%02d:%02d:%02d' % [t.hour, t.min, t.sec]
+ set_hands(t.hour, t.min, t.sec)
+ }
+
+ timer_proc.call
+ @timer = TkRTTimer.start(100, -1, timer_proc)
+ end
+
+ def _create_marks
+ @mark_tag = TkcTag.new(@c)
+
+ TkcLine.new(@c, 0, -0.90*@size, 0, -0.85*@size,
+ :tags=>[@tag, @mark_tag],
+ :width=>@mark_width, :fill=>@mark_color)
+ TkcLine.new(@c, 0.90*@size, 0, 0.85*@size, 0,
+ :tags=>[@tag, @mark_tag],
+ :width=>@mark_width, :fill=>@mark_color)
+ TkcLine.new(@c, 0, 0.90*@size, 0, 0.85*@size,
+ :tags=>[@tag, @mark_tag],
+ :width=>@mark_width, :fill=>@mark_color)
+ TkcLine.new(@c, -0.90*@size, 0, -0.85*@size, 0,
+ :tags=>[@tag, @mark_tag],
+ :width=>@mark_width, :fill=>@mark_color)
+
+ TkcText.new(@c, [0, -0.92*@size], :text=>0,
+ :anchor=>'s', :fill=>@mark_color)
+ TkcText.new(@c, [0.92*@size, 0], :text=>@clock.div(4),
+ :anchor=>'w', :fill=>@mark_color)
+ TkcText.new(@c, [0, 0.92*@size], :text=>@clock.div(2),
+ :anchor=>'n', :fill=>@mark_color)
+ TkcText.new(@c, [-0.92*@size, 0], :text=>@clock.div(4)*3,
+ :anchor=>'e', :fill=>@mark_color)
+
+ [30.0, 60.0].each{|angle|
+ rad = Math::PI * angle / 180.0
+ x_base = @size*Math::sin(rad)
+ y_base = @size*Math::cos(rad)
+
+ x1 = 0.90*x_base
+ y1 = 0.90*y_base
+
+ x2 = 0.85*x_base
+ y2 = 0.85*y_base
+
+ TkcLine.new(@c, x1, y1, x2, y2,
+ :tags=>[@tag, @mark_tag],
+ :width=>@mark_width, :fill=>@mark_color)
+ TkcLine.new(@c, x1, -y1, x2, -y2,
+ :tags=>[@tag, @mark_tag],
+ :width=>@mark_width, :fill=>@mark_color)
+ TkcLine.new(@c, -x1, y1, -x2, y2,
+ :tags=>[@tag, @mark_tag],
+ :width=>@mark_width, :fill=>@mark_color)
+ TkcLine.new(@c, -x1, -y1, -x2, -y2,
+ :tags=>[@tag, @mark_tag],
+ :width=>@mark_width, :fill=>@mark_color)
+
+ x3 = 0.92*x_base
+ y3 = 0.92*y_base
+
+ if @clock == 24
+ dh = angle.to_i/15
+ else # @clock == 12
+ dh = angle.to_i/30
+ end
+
+ TkcText.new(@c, x3, -y3, :text=>dh,
+ :anchor=>'sw', :fill=>@mark_color)
+ TkcText.new(@c, x3, y3, :text=>@clock.div(2)-dh,
+ :anchor=>'nw', :fill=>@mark_color)
+ TkcText.new(@c, -x3, y3, :text=>@clock.div(2)+dh,
+ :anchor=>'ne', :fill=>@mark_color)
+ TkcText.new(@c, -x3, -y3, :text=>@clock-dh,
+ :anchor=>'se', :fill=>@mark_color)
+ }
+
+ if @clock == 24
+ [15.0, 45.0, 75.0].each{|angle|
+ rad = Math::PI * angle / 180.0
+ x_base = @size*Math::sin(rad)
+ y_base = @size*Math::cos(rad)
+
+ x1 = 0.90*x_base
+ y1 = 0.90*y_base
+
+ x2 = 0.875*x_base
+ y2 = 0.875*y_base
+
+ TkcLine.new(@c, x1, y1, x2, y2,
+ :tags=>[@tag, @mark_tag],
+ :width=>@mark_width, :fill=>@submark_color)
+ TkcLine.new(@c, x1, -y1, x2, -y2,
+ :tags=>[@tag, @mark_tag],
+ :width=>@mark_width, :fill=>@submark_color)
+ TkcLine.new(@c, -x1, y1, -x2, y2,
+ :tags=>[@tag, @mark_tag],
+ :width=>@mark_width, :fill=>@submark_color)
+ TkcLine.new(@c, -x1, -y1, -x2, -y2,
+ :tags=>[@tag, @mark_tag],
+ :width=>@mark_width, :fill=>@submark_color)
+ }
+ end
+ end
+
+ def _create_hands
+ hour_hand_len = 0.55*@size
+ minute_hand_len = 0.85*@size
+ second_hand_len = 0.88*@size
+
+ hour_hand_width = 1.8*@cdot_size
+ minute_hand_width = 1.0*@cdot_size
+ second_hand_width = 1 # 0.4*@cdot_size
+
+ @hour_hand_coords = [
+ [0, -0.5*@cdot_size],
+ [hour_hand_width, -0.5*@cdot_size-hour_hand_width],
+ [hour_hand_width, -hour_hand_len+hour_hand_width],
+ [0, -hour_hand_len],
+ [-hour_hand_width, -hour_hand_len+hour_hand_width],
+ [-hour_hand_width, -0.5*@cdot_size-hour_hand_width],
+ ]
+ @minute_hand_coords = [
+ [0, -0.5*@cdot_size],
+ [minute_hand_width, -0.5*@cdot_size - minute_hand_width],
+ [minute_hand_width, -minute_hand_len+minute_hand_width],
+ [0, -minute_hand_len],
+ [-minute_hand_width, -minute_hand_len+minute_hand_width],
+ [-minute_hand_width, -0.5*@cdot_size-minute_hand_width],
+ ]
+ @second_hand_coords = [
+ [0, -0.5*@cdot_size],
+ [second_hand_width, -0.5*@cdot_size - second_hand_width],
+ [second_hand_width, -second_hand_len+second_hand_width],
+ [0, -second_hand_len],
+ [-second_hand_width, -second_hand_len+second_hand_width],
+ [-second_hand_width, -0.5*@cdot_size-second_hand_width],
+ ]
+
+ @hour_hand = TkcPolygon.new(@c, @hour_hand_coords,
+ :tags=>[@tag, @hand_tag],
+ :outline=>@hour_hand_color,
+ :fill=>@hour_hand_color)
+
+ @minute_hand = TkcPolygon.new(@c, @minute_hand_coords,
+ :tags=>[@tag, @hand_tag],
+ :outline=>@minute_hand_color,
+ :fill=>@minute_hand_color)
+
+ @second_hand = TkcPolygon.new(@c, @second_hand_coords,
+ :tags=>[@tag, @hand_tag],
+ :outline=>@second_hand_color,
+ :fill=>@second_hand_color)
+
+ @center_dot = TkcOval.new(@c,
+ [-@cdot_size, -@cdot_size],
+ [@cdot_size, @cdot_size],
+ :outline=>@cdot_color, :fill=>@cdot_color)
+ end
+ private :_create_hands
+
+ def _raise_hands
+ @hour_hand.raise
+ @minute_hand.raise
+ @second_hand.raise
+ @center_dot.raise
+ end
+ private :_raise_hands
+
+ def _raise_marks
+ @mark_tag.raise
+ end
+ private :_raise_marks
+
+ def set_hands(hh, mm, ss)
+ ss_angle = Math::PI * ss / 30.0
+ mm_angle = Math::PI * (mm + ss/60.0) / 30.0
+ hh_angle = Math::PI * (hh + (mm + ss/60.0)/60.0) / (@clock.div(2))
+
+ @second_hand.coords = @second_hand_coords.collect{|x, y|
+ r = Math::hypot(y, x)
+ a = Math::atan2(y, x) + ss_angle
+ [Math::cos(a) * r, Math::sin(a) * r]
+ }
+
+ @minute_hand.coords = @minute_hand_coords.collect{|x, y|
+ r = Math::hypot(y, x)
+ a = Math::atan2(y, x) + mm_angle
+ [Math::cos(a) * r, Math::sin(a) * r]
+ }
+
+ @hour_hand.coords = @hour_hand_coords.collect{|x, y|
+ r = Math::hypot(y, x)
+ a = Math::atan2(y, x) + hh_angle
+ [Math::cos(a) * r, Math::sin(a) * r]
+ }
+
+ _raise_hands
+ _raise_marks
+ end
+
+ def coords_to_time(x, y)
+ return ((y < 0)? [0, 0]: [@clock.div(2), 0]) if x == 0
+ if @clock == 24
+ offset = (x<0&&y<0)? 1800.0: 360.0
+ m_half = 720.0
+ else # @clock == 12
+ offset = (x<0&&y<0)? 900.0: 180.0
+ m_half = 360.0
+ end
+ (offset + m_half*Math.atan2(y,x)/Math::PI).round.divmod(60)
+ end
+
+ def create_pie(hh, mm, span, color='red')
+ if @clock == 24
+ start = 90.0 - (hh*60 + mm)/4.0 # 360.0*(hh*60+mm)/(24*60)
+ extent = -span/4.0
+ else # @clock == 12
+ start = 90.0 - (hh*60 + mm)/2.0 # 360.0*(hh*60+mm)/(12*60)
+ extent = -span/2.0
+ end
+
+ pie = TkcArc.new(@c, @circle_coords, :tags=>[@tag],
+ :outline=>'black', 'fill'=>color,
+ :start=>start, :extent=>extent)
+ _raise_hands
+ _raise_marks
+ pie
+ end
+end
+
+sched = Clock.new
+sched.create_pie(0,0, 60) # 60 minutes from 00:00
+sched.create_pie(6,30, 280, 'green') # 280 minutes from 06:30
+sched.create_pie(15,20, 90, 'blue') # 90 minutes from 15:20
+
+Tk.mainloop