1/* 2 * Copyright (c) 1999-2003 Matthijs Hollemans 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a 5 * copy of this software and associated documentation files (the "Software"), 6 * to deal in the Software without restriction, including without limitation 7 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 * and/or sell copies of the Software, and to permit persons to whom the 9 * Software is furnished to do so, subject to the following conditions: 10 * 11 * The above copyright notice and this permission notice shall be included in 12 * all copies or substantial portions of the Software. 13 * 14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 19 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 20 * DEALINGS IN THE SOFTWARE. 21 */ 22 23#include <Alert.h> 24#include <Deskbar.h> 25#include <MenuItem.h> 26#include <PopUpMenu.h> 27#include <String.h> 28#include <stdio.h> 29 30#include "WatchApp.h" 31#include "WatchView.h" 32 33#undef B_TRANSLATION_CONTEXT 34#define B_TRANSLATION_CONTEXT "WatchView" 35 36 37const rgb_color COLOR_FOREGROUND = { 0, 0, 0 }; 38 39/////////////////////////////////////////////////////////////////////////////// 40 41WatchView::WatchView() 42 : 43 BView(BRect(0, 0, 1, 1), 0, 0, 0) 44{ 45} 46 47/////////////////////////////////////////////////////////////////////////////// 48 49WatchView::WatchView(BMessage* message) 50 : BView( 51 BRect(0, 0, 15, 15), DESKBAR_ITEM_NAME, B_FOLLOW_NONE, 52 B_WILL_DRAW | B_PULSE_NEEDED) 53{ 54 oldTime = 0; 55 56 //SetFont(be_bold_font); 57 SetFont(be_plain_font); 58 59 // Calculate the maximum width for our replicant. Note that the Deskbar 60 // accepts replicants that are wider than 16 pixels, but not replicants 61 // that are higher than 16 pixels. 62 63 float width = StringWidth("@999") + 4; 64 ResizeTo(width, 15); 65 66 SetViewColor(B_TRANSPARENT_COLOR); 67} 68 69/////////////////////////////////////////////////////////////////////////////// 70 71WatchView* WatchView::Instantiate(BMessage* archive) 72{ 73 if (validate_instantiation(archive, REPLICANT_CLASS)) 74 { 75 return new WatchView(archive); 76 } 77 78 return NULL; 79} 80 81/////////////////////////////////////////////////////////////////////////////// 82 83status_t WatchView::Archive(BMessage* archive, bool deep) const 84{ 85 super::Archive(archive, deep); 86 87 archive->AddString("add_on", APP_SIGNATURE); 88 archive->AddString("class", REPLICANT_CLASS); 89 90 return B_OK; 91} 92 93/////////////////////////////////////////////////////////////////////////////// 94 95void WatchView::Draw(BRect updateRect) 96{ 97 super::Draw(updateRect); 98 99 char string[5]; 100 sprintf(string, "@%03ld", GetInternetTime()); 101 102 font_height height; // center the text horizontally 103 GetFontHeight(&height); // and vertically in the Deskbar 104 BRect rect = Bounds(); 105 float width = StringWidth(string); 106 float x = 1 + (rect.Width() - width)/2; 107 float y = height.ascent 108 + (rect.Height() - (height.ascent + height.descent))/2; 109 110 SetHighColor(Parent()->ViewColor()); 111 FillRect(updateRect); 112 113 SetLowColor(Parent()->ViewColor()); 114 SetHighColor(COLOR_FOREGROUND); 115 SetDrawingMode(B_OP_OVER); 116 DrawString(string, BPoint(x, y)); 117} 118 119/////////////////////////////////////////////////////////////////////////////// 120 121void WatchView::MouseDown(BPoint point) 122{ 123 BPopUpMenu* menu = new BPopUpMenu("WatchView", false, false); 124 125 menu->AddItem(new BMenuItem( 126 B_TRANSLATE("About"), 127 new BMessage(B_ABOUT_REQUESTED))); 128 129 menu->AddItem(new BMenuItem( 130 B_TRANSLATE("Quit"), new BMessage(B_QUIT_REQUESTED))); 131 132 menu->SetTargetForItems(this); 133 134 ConvertToScreen(&point); 135 menu->Go(point, true, false, true); 136 137 delete menu; 138} 139 140/////////////////////////////////////////////////////////////////////////////// 141 142void WatchView::MessageReceived(BMessage* msg) 143{ 144 switch (msg->what) 145 { 146 case B_ABOUT_REQUESTED: OnAboutRequested(); break; 147 case B_QUIT_REQUESTED: OnQuitRequested(); break; 148 default: super::MessageReceived(msg); break; 149 } 150} 151 152/////////////////////////////////////////////////////////////////////////////// 153 154void WatchView::OnAboutRequested() 155{ 156 BString text = B_TRANSLATE("WebWatch %1" 157 "\nAn internet time clock for your Deskbar\n\n" 158 "Created by Matthijs Hollemans\n" 159 "mahlzeit@users.sourceforge.net\n\n" 160 "Thanks to Jason Parks for his help.\n"); 161 text.ReplaceFirst("%1", VERSION); 162 BAlert* alert = new BAlert(NULL, text.String(), B_TRANSLATE("OK")); 163 alert->SetFlags(alert->Flags() | B_CLOSE_ON_ESCAPE); 164 alert->Go(NULL); 165} 166 167/////////////////////////////////////////////////////////////////////////////// 168 169void WatchView::OnQuitRequested() 170{ 171 // According to the Be Book, we are not allowed to do this 172 // since we're a view that's sitting on the Deskbar's shelf. 173 // But it works just fine for me, and I see no other way to 174 // make a Deskbar replicant quit itself. 175 176 BDeskbar deskbar; 177 deskbar.RemoveItem(DESKBAR_ITEM_NAME); 178} 179 180/////////////////////////////////////////////////////////////////////////////// 181 182void WatchView::Pulse() 183{ 184 int32 currentTime = GetInternetTime(); 185 if (oldTime != currentTime) 186 { 187 oldTime = currentTime; 188 Invalidate(); 189 } 190} 191 192/////////////////////////////////////////////////////////////////////////////// 193 194int32 WatchView::GetInternetTime() 195{ 196 // First we get the current time as the number of seconds since 197 // 1 January 1970 GMT and add an hour's worth of seconds to adjust 198 // for the Biel Mean Time (BMT). Then we get the number of seconds 199 // that have passed today, and divide it with the length of a beat 200 // to get the number of elapsed beats. 201 202 return (int32) (((real_time_clock() + 3600) % 86400) / 86.4); 203} 204 205/////////////////////////////////////////////////////////////////////////////// 206