1 /* 2 * Copyright (c) 2008-2009 Gerasim Troeglazov (3dEyes**). All Rights Reserved. 3 * This file may be used under the terms of the MIT License. 4 */ 5 6 7 #include <stdio.h> 8 #include <stdlib.h> 9 #include <time.h> 10 11 #include <Bitmap.h> 12 #include <Catalog.h> 13 #include <Polygon.h> 14 #include <Screen.h> 15 #include <ScreenSaver.h> 16 #include <StringView.h> 17 #include <View.h> 18 19 20 class Clock : public BScreenSaver 21 { 22 public: 23 Clock(BMessage *message, image_id id); 24 void StartConfig(BView *view); 25 status_t StartSaver(BView *view, bool preview); 26 void Draw(BView *view, int32 frame); 27 private: 28 void _drawBlock(BView *view, float x, float y, float alpha, 29 float size); 30 void _drawArrow(BView *view, float x0, float y0, float angle, 31 float length, float coeff, float width); 32 float centerX, centerY; 33 }; 34 35 36 extern "C" _EXPORT BScreenSaver *instantiate_screen_saver(BMessage *message, 37 image_id image) 38 { 39 return new Clock(message, image); 40 } 41 42 43 Clock::Clock(BMessage *message, image_id image) 44 : 45 BScreenSaver(message, image) 46 { 47 B_TRANSLATE_MARK_SYSTEM_NAME_VOID("SimpleClock"); 48 } 49 50 51 void 52 Clock::StartConfig(BView *view) 53 { 54 BStringView *aboutView = new BStringView(BRect(10, 10, 200, 35), 55 B_EMPTY_STRING, "Simple Clock"); 56 aboutView->SetFont(be_bold_font); 57 aboutView->SetFontSize(15); 58 view->AddChild(aboutView); 59 aboutView = new BStringView(BRect(10, 40, 200, 65), 60 B_EMPTY_STRING, " Ver 1.0, ©3dEyes**"); 61 view->AddChild(aboutView); 62 } 63 64 65 status_t 66 Clock::StartSaver(BView *view, bool) 67 { 68 SetTickSize(1000000); 69 return B_OK; 70 } 71 72 73 void 74 Clock::Draw(BView *view, int32) 75 { 76 BScreen screenView; 77 BBitmap bufferBitmap(view->Bounds(), screenView.ColorSpace(), true); 78 BView offscreenView(view->Bounds(), NULL, 0, 0); 79 bufferBitmap.AddChild(&offscreenView); 80 bufferBitmap.Lock(); 81 82 float width = view->Bounds().Width(); 83 float height = view->Bounds().Height(); 84 float zoom = (height / 1024.0) * 0.65; 85 86 time_t timeInfo; 87 time(&timeInfo); 88 struct tm *nowTime = localtime(&timeInfo); 89 90 float secondVal = nowTime->tm_sec; 91 float minuteVal = nowTime->tm_min + (secondVal / 60.0); 92 float hourVal = nowTime->tm_hour + (minuteVal / 60.0); 93 94 offscreenView.SetHighColor(0, 0, 0); 95 offscreenView.SetLowColor(0, 0, 0); 96 offscreenView.FillRect(offscreenView.Bounds()); 97 98 offscreenView.SetHighColor(200, 200, 200); 99 100 centerX = width / 2.0; 101 centerY = height / 2.0; 102 103 float markAngle = 0; 104 float markRadius = 510.0 * zoom; 105 106 for(int mark = 0; mark < 60; mark++, markAngle += (2 * M_PI) / 60) { 107 float x = centerX + markRadius * cos(markAngle); 108 float y = centerY + markRadius * sin(markAngle); 109 _drawBlock(&offscreenView, x, y, markAngle, 14.0 * zoom); 110 } 111 112 offscreenView.SetHighColor(255, 255, 255); 113 114 markAngle = 0; 115 markRadius = 500.0 * zoom; 116 117 for (int mark = 0; mark < 12; mark++, markAngle += (2 * M_PI) / 12) { 118 float x = centerX + markRadius * cos(markAngle); 119 float y = centerY + markRadius * sin(markAngle); 120 _drawBlock(&offscreenView, x, y, markAngle, 32 * zoom); 121 } 122 123 offscreenView.SetHighColor(255, 255, 255); 124 _drawArrow(&offscreenView, centerX, centerY, 125 ((2 * M_PI / 60) * minuteVal) - (M_PI / 2), 220 * zoom, 1, 8 * zoom); 126 127 _drawArrow(&offscreenView, centerX, centerY, 128 ((2 * M_PI / 12) * hourVal) - (M_PI / 2), 140 * zoom, 1, 14 * zoom); 129 offscreenView.FillEllipse(BPoint(centerX, centerY), 130 24 * zoom, 24 * zoom); 131 132 offscreenView.SetHighColor(250, 20, 20); 133 _drawArrow(&offscreenView, centerX, centerY, 134 ((2 * M_PI / 60) * secondVal) - (M_PI / 2), 240 * zoom, 1, 4 * zoom); 135 offscreenView.FillEllipse(BPoint(centerX, centerY), 136 20 * zoom, 20 * zoom); 137 138 offscreenView.Sync(); 139 bufferBitmap.Unlock(); 140 view->DrawBitmap(&bufferBitmap); 141 bufferBitmap.RemoveChild(&offscreenView); 142 } 143 144 145 void 146 Clock::_drawBlock(BView *view, float x, float y, float alpha, float size) 147 { 148 float blockAngles[4] = {alpha - (M_PI / 12), alpha + (M_PI / 12), 149 alpha + M_PI - (M_PI / 12), alpha + M_PI + (M_PI / 12)}; 150 151 BPoint blockPoints[4]; 152 for (int index = 0; index < 4; index++) { 153 blockPoints[index].x = x + size * cos(blockAngles[index]); 154 blockPoints[index].y = y + size * sin(blockAngles[index]); 155 } 156 view->FillPolygon(&blockPoints[0], 4); 157 } 158 159 160 void 161 Clock::_drawArrow(BView *view, float x0, float y0, float angle, float length, 162 float coeff, float width) 163 { 164 float alpha = width / length; 165 166 float x = x0 + length * cos(angle); 167 float y = y0 + length * sin(angle); 168 169 float size = length * coeff; 170 171 float blockAngles[4] = {angle - alpha, angle + alpha, 172 angle + M_PI - alpha, angle + M_PI + alpha}; 173 174 BPoint blockPoints[4]; 175 for(int index = 0; index < 4; index++) { 176 blockPoints[index].x = x + size * cos(blockAngles[index]); 177 blockPoints[index].y = y + size * sin(blockAngles[index]); 178 } 179 view->FillPolygon(&blockPoints[0], 4); 180 } 181