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