1 /** 2 * clock.d 3 * 4 * A gtkD widget that implements a clock face 5 * 6 * Based on the Gtkmm example by: 7 * Jonathon Jongsma 8 * 9 * and the original GTK+ example by: 10 * (c) 2005-2006, Davyd Madeley 11 * 12 * Authors: 13 * Jonas Kivi (D version) 14 * Jonathon Jongsma (C++ version) 15 * Davyd Madeley (C version) 16 */ 17 18 module clock; 19 20 version(Tango) import tango.io.Stdout; 21 else import std.stdio; 22 23 version(Tango) import tango.math.Math; 24 else import std.math; 25 26 version(Tango) 27 { 28 import tango.time.Time; 29 import tangoClock = tango.time.WallClock; 30 } 31 else version(D_Version2) 32 { 33 import std.datetime; 34 } 35 else 36 { 37 import std.date; 38 } 39 40 import glib.Timeout; 41 42 import cairo.Context; 43 import cairo.Surface; 44 45 import gtk.Widget; 46 import gtk.DrawingArea; 47 48 class Clock : DrawingArea 49 { 50 public: 51 this() 52 { 53 //Attach our expose callback, which will draw the window. 54 addOnDraw(&drawCallback); 55 } 56 57 protected: 58 //Override default signal handler: 59 bool drawCallback(Context cr, Widget widget) 60 { 61 if ( m_timeout is null ) 62 { 63 //Create a new timeout that will ask the window to be drawn once every second. 64 m_timeout = new Timeout( 1000, &onSecondElapsed, false ); 65 } 66 67 // This is where we draw on the window 68 69 GtkAllocation size; 70 71 getAllocation(size); 72 73 // scale to unit square and translate (0, 0) to be (0.5, 0.5), i.e. the 74 // center of the window 75 cr.scale(size.width, size.height); 76 cr.translate(0.5, 0.5); 77 cr.setLineWidth(m_lineWidth); 78 79 cr.save(); 80 cr.setSourceRgba(0.3, 0.6, 0.2, 0.9); // brownish green 81 cr.paint(); 82 cr.restore(); 83 84 cr.arc(0, 0, m_radius, 0, 2 * PI); 85 86 cr.save(); 87 cr.setSourceRgba(0.0, 0.0, 0.0, 0.8); 88 cr.fillPreserve(); 89 cr.restore(); 90 91 cr.save(); 92 cr.setSourceRgba(1.0, 1.0, 1.0, 1.0); 93 cr.setLineWidth( m_lineWidth * 1.7); 94 cr.strokePreserve(); 95 cr.clip(); 96 cr.restore(); 97 98 99 //clock ticks 100 101 for (int i = 0; i < 12; i++) 102 { 103 double inset = 0.07; 104 105 cr.save(); 106 cr.setSourceRgba(1.0, 1.0, 1.0, 1.0); 107 cr.setLineWidth( m_lineWidth * 0.25); 108 cr.setLineCap(cairo_line_cap_t.ROUND); 109 110 if (i % 3 != 0) 111 { 112 inset *= 1.2; 113 cr.setLineWidth( m_lineWidth * 0.5 ); 114 } 115 116 cr.moveTo( 117 (m_radius - inset) * cos (i * PI / 6), 118 (m_radius - inset) * sin (i * PI / 6)); 119 cr.lineTo ( 120 m_radius * cos (i * PI / 6), 121 m_radius * sin (i * PI / 6)); 122 cr.stroke(); 123 cr.restore(); // stack-pen-size 124 } 125 126 version(Tango) 127 { 128 auto time = tangoClock.WallClock.now.time; 129 130 double minutes = time.minutes * PI / 30; 131 double hours = time.hours * PI / 6; 132 double seconds = time.seconds * PI / 30; 133 } 134 else version(D_Version2) 135 { 136 SysTime lNow = std.datetime.Clock.currTime(); 137 138 // compute the angles of the indicators of our clock 139 double minutes = lNow.minute * PI / 30; 140 double hours = lNow.hour * PI / 6; 141 double seconds= lNow.second * PI / 30; 142 } 143 else 144 { 145 d_time lNow; 146 string lNowString; 147 148 // Grab the date and time relative to UTC 149 lNow = std.date.getUTCtime(); 150 // Convert this into the local date and time for display. 151 lNowString = std.date.toString(lNow); 152 153 Date timeinfo; 154 timeinfo.parse(lNowString); 155 156 // compute the angles of the indicators of our clock 157 double minutes = timeinfo.minute * PI / 30; 158 double hours = timeinfo.hour * PI / 6; 159 double seconds= timeinfo.second * PI / 30; 160 } 161 162 cr.save(); 163 cr.setLineCap(cairo_line_cap_t.ROUND); 164 165 // draw the seconds hand 166 cr.save(); 167 cr.setLineWidth(m_lineWidth / 3); 168 cr.setSourceRgba(0.7, 0.7, 0.85, 0.8); // blueish gray 169 cr.moveTo(0, 0); 170 cr.lineTo(sin(seconds) * (m_radius * 0.8), 171 -cos(seconds) * (m_radius * 0.8)); 172 cr.stroke(); 173 cr.restore(); 174 175 // draw the minutes hand 176 //cr.setSourceRgba(0.117, 0.337, 0.612, 0.9); // blue 177 cr.setSourceRgba(0.712, 0.337, 0.117, 0.9); // red 178 cr.moveTo(0, 0); 179 cr.lineTo(sin(minutes + seconds / 60) * (m_radius * 0.7), 180 -cos(minutes + seconds / 60) * (m_radius * 0.7)); 181 cr.stroke(); 182 183 // draw the hours hand 184 cr.setSourceRgba(0.337, 0.612, 0.117, 0.9); // green 185 cr.moveTo(0, 0); 186 cr.lineTo(sin(hours + minutes / 12.0) * (m_radius * 0.4), 187 -cos(hours + minutes / 12.0) * (m_radius * 0.4)); 188 cr.stroke(); 189 cr.restore(); 190 191 // draw a little dot in the middle 192 cr.arc(0, 0, m_lineWidth / 3.0, 0, 2 * PI); 193 cr.fill(); 194 195 return true; 196 } 197 198 bool onSecondElapsed() 199 { 200 //force our program to redraw the entire clock once per every second. 201 GtkAllocation area; 202 getAllocation(area); 203 204 queueDrawArea(area.x, area.y, area.width, area.height); 205 206 return true; 207 } 208 209 double m_radius = 0.40; 210 double m_lineWidth = 0.065; 211 212 Timeout m_timeout; 213 } 214