WPF clock
Ruby
code posted
by
Edd Morgan
created at 12 Jun 00:17
Edit
|
Back
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 |
require 'WindowsBase' require 'PresentationFramework' require 'PresentationCore' require 'System.Core, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' class Clock CLOCK_WIDTH = 150 CLOCK_HEIGHT = 150 LABEL_HEIGHT = CLOCK_HEIGHT / 7 LABEL_WIDTH = CLOCK_WIDTH / 7 RADIUS = CLOCK_WIDTH / 2 RADS = Math::PI / 180 MIN_LOCATIONS = {} HOUR_LOCATIONS = {} def run! plot_locations # build our window @window = System::Windows::Window.new @window.background = System::Windows::Media::Brushes.LightGray @window.width = CLOCK_WIDTH * 2 @window.height = CLOCK_HEIGHT * 2 @window.resize_mode = System::Windows::ResizeMode.NoResize @canvas = System::Windows::Controls::Canvas.new @canvas.width = CLOCK_WIDTH @canvas.height = CLOCK_HEIGHT # create shapes to represent clock hands @minute_hand = System::Windows::Shapes::Line.new @minute_hand.stroke = System::Windows::Media::Brushes.Black @minute_hand.stroke_thickness = 1 @minute_hand.x1 = CLOCK_WIDTH / 2 @minute_hand.y1 = CLOCK_HEIGHT / 2 @hour_hand = System::Windows::Shapes::Line.new @hour_hand.stroke = System::Windows::Media::Brushes.Black @hour_hand.stroke_thickness = 3 @hour_hand.x1 = CLOCK_WIDTH / 2 @hour_hand.y1 = CLOCK_HEIGHT / 2 # .. and stick them to our canvas @canvas.children.add(@minute_hand) @canvas.children.add(@hour_hand) plot_face # draw a clock face plot_labels # draw clock numbers plot_hands # draw minute / hour hands @window.content = @canvas app = System::Windows::Application.new app.run(@window) # the Application object handles the lifecycle of our app # including the execution loop end # determine 2 sets of equidistant points around the circumference of a circle # of CLOCK_WIDTH and CLOCK_HEIGHT dimensions. def plot_locations for i in (0..60) # 60 minutes, and 12 hours a = i * 6 x = (RADIUS * Math.sin(a * RADS)).to_i + (CLOCK_WIDTH / 2) y = (CLOCK_HEIGHT / 2) - (RADIUS * Math.cos(a * RADS)).to_i coords = [x, y] HOUR_LOCATIONS[i / 5] = coords if i % 5 == 0 # is this also an 'hour' location (ie. every 5 minutes)? MIN_LOCATIONS[i] = coords end end # draws a circle to represent the clock's face def plot_face extra_x = (CLOCK_WIDTH * 0.15) # pad our circle a little extra_y = (CLOCK_HEIGHT * 0.15) face = System::Windows::Shapes::Ellipse.new face.fill = System::Windows::Media::Brushes.White face.width = CLOCK_WIDTH + extra_x face.height = CLOCK_HEIGHT + extra_y face.margin = System::Windows::Thickness.new(0 - (extra_x/2), 0 - (extra_y/2), 0, 0) face.stroke = System::Windows::Media::Brushes.Gray # give it a slight border face.stroke_thickness = 1 System::Windows::Controls::Canvas.set_z_index(face, -1) # send our circle to the back @canvas.children.add(face) # add the clock face to our canvas end # at each point along the hour locations, put a number def plot_labels HOUR_LOCATIONS.each_pair do |p, coords| unless p == 0 lbl = System::Windows::Controls::Label.new lbl.horizontal_content_alignment = System::Windows::HorizontalAlignment.Center lbl.width = LABEL_WIDTH lbl.height = LABEL_HEIGHT lbl.content = p.to_s lbl.margin = System::Windows::Thickness.new(coords[0] - (LABEL_WIDTH / 2), coords[1] - (LABEL_HEIGHT / 2), 0, 0) lbl.padding = System::Windows::Thickness.new(0, 0, 0, 0) @canvas.children.add(lbl) end end end def plot_hands time = Time.now hours = time.hour minutes = time.min if !@minutes || minutes != @minutes @hours = hours >= 12 ? hours - 12 : hours @minutes = minutes == 0 ? 60 : minutes # Dispatcher.BeginInvoke() is asynchronous, though it probably doesn't matter too much here @minute_hand.dispatcher.begin_invoke(System::Windows::Threading::DispatcherPriority.Render, System::Action.new { @minute_hand.x2 = MIN_LOCATIONS[@minutes][0] @minute_hand.y2 = MIN_LOCATIONS[@minutes][1] @hour_hand.x2 = HOUR_LOCATIONS[@hours][0] @hour_hand.y2 = HOUR_LOCATIONS[@hours][1] }) end end end clock = Clock.new timer = System::Timers::Timer.new timer.interval = 1000 timer.elapsed { clock.plot_hands } timer.enabled = true clock.run! |
4.92 KB in 6 ms with coderay