xref: /haiku/src/add-ons/screen_savers/simpleclock/SimpleClock.cpp (revision adb0d19d561947362090081e81d90dde59142026)
1 /*
2 **
3 ** A simple analog clock screensaver.
4 **
5 ** Version: 0.1
6 **
7 ** Copyright (c) 2008-2009 Gerasim Troeglazov (3dEyes**). All Rights Reserved.
8 ** This file may be used under the terms of the MIT License.
9 */
10 
11 
12 #include <ScreenSaver.h>
13 #include <StringView.h>
14 #include <View.h>
15 #include <Polygon.h>
16 #include <Bitmap.h>
17 #include <Screen.h>
18 #include <stdlib.h>
19 #include <stdio.h>
20 #include <time.h>
21 
22 class Clock : public BScreenSaver
23 {
24 public:
25 					Clock(BMessage *message, image_id id);
26 	void			StartConfig(BView *view);
27 	status_t		StartSaver(BView *v, bool preview);
28 	void			Draw(BView *v, int32 frame);
29 	BStringView		*tview;
30 private:
31 	void 			DrawBlock(BView *view, float x, float y, float a, float size);
32 	void 			DrawArrow(BView *view, float xc, float yc, float a, float len, float k,float width);
33 	time_t			tmptodaytime;
34 	float			todaysecond , todayminute , todayhour;
35 	struct tm		*TodayTime;
36 	BRect r;
37 };
38 
39 extern "C" _EXPORT BScreenSaver *instantiate_screen_saver(BMessage *message, image_id image)
40 {
41 	return new Clock(message, image);
42 }
43 
44 Clock::Clock(BMessage *message, image_id image)
45  : BScreenSaver(message, image)
46 {
47 }
48 
49 void Clock::StartConfig(BView *view)
50 {
51 	tview = new BStringView(BRect(10, 10, 200, 35), B_EMPTY_STRING, "Simple Clock");
52 	tview->SetFont(be_bold_font);
53 	tview->SetFontSize(15);
54 	view->AddChild(tview);
55 	view->AddChild(new BStringView(BRect(10, 40, 200, 65), B_EMPTY_STRING, " Ver 0.1, ©3dEyes**"));
56 }
57 
58 status_t Clock::StartSaver(BView *view, bool preview)
59 {
60 	SetTickSize(1000000);
61 	return B_OK;
62 }
63 
64 void Clock::DrawBlock(BView *view, float x, float y, float a, float size)
65 {
66 	float angles[4]={a-(M_PI/12),a+(M_PI/12),a+(M_PI)-(M_PI/12),a+(M_PI)+(M_PI/12)};
67 	BPoint points[4];
68 	for(int i=0;i<4;i++) {
69 		points[i].x= x+size*cos(angles[i]);
70 		points[i].y= y+size*sin(angles[i]);
71 	}
72 	view->FillPolygon(&points[0],4);
73 
74 }
75 
76 void Clock::DrawArrow(BView *view, float xc, float yc, float a, float len, float k, float width)
77 {
78 	float g = width/len;
79 
80 	float x = xc+(len)*cos(a);
81 	float y = yc+(len)*sin(a);
82 
83 	float size = len*k;
84 
85 	float angles[4]={a-g,a+g,a+(M_PI)-g,a+(M_PI)+g};
86 
87 	BPoint points[4];
88 	for(int i=0;i<4;i++) {
89 		points[i].x= x+size*cos(angles[i]);
90 		points[i].y= y+size*sin(angles[i]);
91 	}
92 	view->FillPolygon(&points[0],4);
93 }
94 
95 void Clock::Draw(BView *view, int32)
96 {
97 	BScreen screen;
98 	BBitmap buffer(view->Bounds(), screen.ColorSpace(), true);
99 	BView offscreen(view->Bounds(), NULL, 0, 0);
100 	buffer.AddChild(&offscreen);
101 	buffer.Lock();
102 
103 	int n;
104 	float a,R;
105 	float width = view->Bounds().Width();
106 	float height = view->Bounds().Height();
107 	float zoom = (height/1024) * 0.85;
108 
109 	time(&tmptodaytime);
110 	TodayTime = localtime(&tmptodaytime);
111 
112 	todaysecond = TodayTime->tm_sec;
113 	todayminute = TodayTime->tm_min + (todaysecond/60.0);
114 	todayhour   = TodayTime->tm_hour + (todayminute/60.0);
115 
116 	rgb_color bg_color = {0,0,0};
117 	offscreen.SetHighColor(bg_color);
118 	offscreen.SetLowColor(bg_color);
119 	offscreen.FillRect(offscreen.Bounds());
120 
121 	offscreen.SetHighColor(200,200,200);
122 
123 	for(n=0,a=0,R=510*zoom;n<60;n++,a+=(2*M_PI)/60) {
124 		float x = width/2 + R * cos(a);
125 		float y = height/2 + R * sin(a);
126 		DrawBlock(&offscreen,x,y,a,14*zoom);
127 	}
128 
129 	offscreen.SetHighColor(255,255,255);
130 
131 	for(n=0,a=0,R=500*zoom;n<12;n++,a+=(2*M_PI)/12) {
132 		float x = width/2 + R * cos(a);
133 		float y = height/2 + R * sin(a);
134 		DrawBlock(&offscreen,x,y,a,32*zoom);
135 	}
136 
137 	offscreen.SetHighColor(255,255,255);
138 	DrawArrow(&offscreen, width/2,height/2, ( ((2*M_PI)/60) * todayminute) - (M_PI/2), 220*zoom, 1, 8*zoom);
139 	DrawArrow(&offscreen, width/2,height/2, ( ((2*M_PI)/12) * todayhour) - (M_PI/2), 140*zoom, 1, 14*zoom);
140 	offscreen.FillEllipse(BPoint(width/2,height/2),24*zoom,24*zoom);
141 	offscreen.SetHighColor(250,20,20);
142 	DrawArrow(&offscreen, width/2,height/2, ( ((2*M_PI)/60) * todaysecond) - (M_PI/2), 240*zoom, 1, 4*zoom);
143 	offscreen.FillEllipse(BPoint(width/2,height/2),20*zoom,20*zoom);
144 
145 	offscreen.Sync();
146 	buffer.Unlock();
147 	view->DrawBitmap(&buffer);
148 	buffer.RemoveChild(&offscreen);
149 }
150