Fl_Clock.cxx 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218
  1. //
  2. // "$Id: Fl_Clock.cxx 7903 2010-11-28 21:06:39Z matt $"
  3. //
  4. // Clock widget for the Fast Light Tool Kit (FLTK).
  5. //
  6. // Copyright 1998-2010 by Bill Spitzak and others.
  7. //
  8. // This library is free software; you can redistribute it and/or
  9. // modify it under the terms of the GNU Library General Public
  10. // License as published by the Free Software Foundation; either
  11. // version 2 of the License, or (at your option) any later version.
  12. //
  13. // This library is distributed in the hope that it will be useful,
  14. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  16. // Library General Public License for more details.
  17. //
  18. // You should have received a copy of the GNU Library General Public
  19. // License along with this library; if not, write to the Free Software
  20. // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
  21. // USA.
  22. //
  23. // Please report all bugs and problems on the following page:
  24. //
  25. // http://www.fltk.org/str.php
  26. //
  27. #include <FL/Fl.H>
  28. #include <FL/Fl_Clock.H>
  29. #include <FL/fl_draw.H>
  30. #include <math.h>
  31. #include <time.h>
  32. #ifndef WIN32
  33. # include <sys/time.h>
  34. #endif /* !WIN32 */
  35. // Original clock display written by Paul Haeberli at SGI.
  36. // Modifications by Mark Overmars for Forms
  37. // Further changes by Bill Spitzak for fltk
  38. const float hourhand[4][2] = {{-0.5f, 0}, {0, 1.5f}, {0.5f, 0}, {0, -7.0f}};
  39. const float minhand[4][2] = {{-0.5f, 0}, {0, 1.5f}, {0.5f, 0}, {0, -11.5f}};
  40. const float sechand[4][2] = {{-0.1f, 0}, {0, 2.0f}, {0.1f, 0}, {0, -11.5f}};
  41. static void drawhand(double ang,const float v[][2],Fl_Color fill,Fl_Color line)
  42. {
  43. fl_push_matrix();
  44. fl_rotate(ang);
  45. fl_color(fill); fl_begin_polygon();
  46. int i; for (i=0; i<4; i++) fl_vertex(v[i][0],v[i][1]); fl_end_polygon();
  47. fl_color(line); fl_begin_loop();
  48. for (i=0; i<4; i++) fl_vertex(v[i][0],v[i][1]); fl_end_loop();
  49. fl_pop_matrix();
  50. }
  51. void Fl_Clock_Output::drawhands(Fl_Color fill, Fl_Color line) {
  52. if (!active_r()) {
  53. fill = fl_inactive(fill);
  54. line = fl_inactive(line);
  55. }
  56. drawhand(-360*(hour()+minute()/60.0)/12, hourhand, fill, line);
  57. drawhand(-360*(minute()+second()/60.0)/60, minhand, fill, line);
  58. drawhand(-360*(second()/60.0), sechand, fill, line);
  59. }
  60. static void rect(double x, double y, double w, double h) {
  61. double r = x+w;
  62. double t = y+h;
  63. fl_begin_polygon();
  64. fl_vertex(x, y);
  65. fl_vertex(r, y);
  66. fl_vertex(r, t);
  67. fl_vertex(x, t);
  68. fl_end_polygon();
  69. }
  70. /**
  71. Draw clock with the given position and size.
  72. \param[in] X, Y, W, H position and size
  73. */
  74. void Fl_Clock_Output::draw(int X, int Y, int W, int H) {
  75. Fl_Color box_color = type()==FL_ROUND_CLOCK ? FL_GRAY : color();
  76. Fl_Color shadow_color = fl_color_average(box_color, FL_BLACK, 0.5);
  77. draw_box(box(), X, Y, W, H, box_color);
  78. fl_push_matrix();
  79. fl_translate(X+W/2.0-.5, Y+H/2.0-.5);
  80. fl_scale((W-1)/28.0, (H-1)/28.0);
  81. if (type() == FL_ROUND_CLOCK) {
  82. fl_color(active_r() ? color() : fl_inactive(color()));
  83. fl_begin_polygon(); fl_circle(0,0,14); fl_end_polygon();
  84. fl_color(active_r() ? FL_FOREGROUND_COLOR : fl_inactive(FL_FOREGROUND_COLOR));
  85. fl_begin_loop(); fl_circle(0,0,14); fl_end_loop();
  86. }
  87. // draw the shadows:
  88. fl_push_matrix();
  89. fl_translate(0.60, 0.60);
  90. drawhands(shadow_color, shadow_color);
  91. fl_pop_matrix();
  92. // draw the tick marks:
  93. fl_push_matrix();
  94. fl_color(active_r() ? FL_FOREGROUND_COLOR : fl_inactive(FL_FOREGROUND_COLOR));
  95. for (int i=0; i<12; i++) {
  96. if (i==6) rect(-0.5, 9, 1, 2);
  97. else if (i==3 || i==0 || i== 9) rect(-0.5, 9.5, 1, 1);
  98. else rect(-0.25, 9.5, .5, 1);
  99. fl_rotate(-30);
  100. }
  101. fl_pop_matrix();
  102. // draw the hands:
  103. drawhands(selection_color(), FL_FOREGROUND_COLOR); // color was 54
  104. fl_pop_matrix();
  105. }
  106. /**
  107. Draw clock with current position and size.
  108. */
  109. void Fl_Clock_Output::draw() {
  110. draw(x(), y(), w(), h());
  111. draw_label();
  112. }
  113. /**
  114. Set the displayed time.
  115. Set the time in hours, minutes, and seconds.
  116. \param[in] H, m, s displayed time
  117. \see hour(), minute(), second()
  118. */
  119. void Fl_Clock_Output::value(int H, int m, int s) {
  120. if (H!=hour_ || m!=minute_ || s!=second_) {
  121. hour_ = H; minute_ = m; second_ = s;
  122. value_ = (H * 60 + m) * 60 + s;
  123. damage(FL_DAMAGE_CHILD);
  124. }
  125. }
  126. /**
  127. Set the displayed time.
  128. Set the time in seconds since the UNIX epoch (January 1, 1970).
  129. \param[in] v seconds since epoch
  130. \see value()
  131. */
  132. void Fl_Clock_Output::value(ulong v) {
  133. value_ = v;
  134. struct tm *timeofday;
  135. // Some platforms, notably Windows, now use a 64-bit time_t value...
  136. time_t vv = (time_t)v;
  137. timeofday = localtime(&vv);
  138. value(timeofday->tm_hour, timeofday->tm_min, timeofday->tm_sec);
  139. }
  140. /**
  141. Create a new Fl_Clock_Output widget with the given position, size and label.
  142. The default boxtype is \c FL_NO_BOX.
  143. \param[in] X, Y, W, H position and size of the widget
  144. \param[in] L widget label, default is no label
  145. */
  146. Fl_Clock_Output::Fl_Clock_Output(int X, int Y, int W, int H, const char *L)
  147. : Fl_Widget(X, Y, W, H, L) {
  148. box(FL_UP_BOX);
  149. selection_color(fl_gray_ramp(5));
  150. align(FL_ALIGN_BOTTOM);
  151. hour_ = 0;
  152. minute_ = 0;
  153. second_ = 0;
  154. value_ = 0;
  155. }
  156. ////////////////////////////////////////////////////////////////
  157. /**
  158. Create an Fl_Clock widget using the given position, size, and label string.
  159. The default boxtype is \c FL_NO_BOX.
  160. \param[in] X, Y, W, H position and size of the widget
  161. \param[in] L widget label, default is no label
  162. */
  163. Fl_Clock::Fl_Clock(int X, int Y, int W, int H, const char *L)
  164. : Fl_Clock_Output(X, Y, W, H, L) {}
  165. /**
  166. Create an Fl_Clock widget using the given boxtype, position, size, and
  167. label string.
  168. \param[in] t boxtype
  169. \param[in] X, Y, W, H position and size of the widget
  170. \param[in] L widget label, default is no label
  171. */
  172. Fl_Clock::Fl_Clock(uchar t, int X, int Y, int W, int H, const char *L)
  173. : Fl_Clock_Output(X, Y, W, H, L) {
  174. type(t);
  175. box(t==FL_ROUND_CLOCK ? FL_NO_BOX : FL_UP_BOX);
  176. }
  177. static void tick(void *v) {
  178. ((Fl_Clock*)v)->value(time(0));
  179. Fl::add_timeout(1.0, tick, v);
  180. }
  181. int Fl_Clock::handle(int event) {
  182. switch (event) {
  183. case FL_SHOW:
  184. tick(this);
  185. break;
  186. case FL_HIDE:
  187. Fl::remove_timeout(tick, this);
  188. break;
  189. }
  190. return Fl_Clock_Output::handle(event);
  191. }
  192. /**
  193. The destructor removes the clock.
  194. */
  195. Fl_Clock::~Fl_Clock() {
  196. Fl::remove_timeout(tick, this);
  197. }
  198. //
  199. // End of "$Id: Fl_Clock.cxx 7903 2010-11-28 21:06:39Z matt $".
  200. //