// @(#)root/test:$Id$ // Author: Valeriy Onuchin & Fons Rademakers 04/10/98 /////////////////////////////////////////////////////////////////// // ROOT implementation of the X11 xclock. // // To run this example do the following: // $ root // root [0] gSystem.Load("libGpad") // root [1] gSystem.Load("Aclock") // root [1] Aclock a // // root [2] .q // // Other ROOT fun examples: Tetris, Hello ... // // Begin_Html // // End_Html // /////////////////////////////////////////////////////////////////// #include #include #include "Aclock.h" ClassImp(Aclock) Float_t MinuteHand::fgMinuteHandX[] = { -0.05, 0, 0.05 }; Float_t MinuteHand::fgMinuteHandY[] = { -0.04, 0.625, -0.04 }; Float_t HourHand::fgHourHandX[] = { -0.05, 0, 0.05 }; Float_t HourHand::fgHourHandY[] = { -0.04, 0.4, -0.04 }; Float_t SecondHand::fgSecondHandX[] = { 0., 0.035, 0., -0.035 }; Float_t SecondHand::fgSecondHandY[] = { 0.78, 0.73, 0.68, 0.73 }; TDatime *ClockHand::fgTime = new TDatime; TPolygon::TPolygon(Int_t n, Float_t *x, Float_t *y) : TPolyLine(n+1,x,y) { // Create filled polygon. Polygon will be added to current pad. if (!TVirtualPad::Pad()) { Error("Constructor","Create TPad first!"); return; } fPad = (TPad*)TVirtualPad::Pad(); fX[n] = x[0]; // create an extra point to connect polyline ends fY[n] = y[0]; Draw(); // append to fPad } void TPolygon::Paint(Option_t *) { // Paint filled polygon. TAttLine::Modify(); TAttFill::Modify(); fPad->PaintFillArea(fN-1, fX, fY); fPad->PaintPolyLine(fN, fX, fY, ""); } ClockHand::ClockHand(Int_t n, Float_t *x, Float_t *y) : TPolygon(n,x,y) { // Create clockhand fPrevTimeValue = 0; fX0 = new Float_t[GetN()]; // initial shape and position fY0 = new Float_t[GetN()]; // initial shape and position for (int i = 0; i < GetN(); i++) { fX0[i] = fX[i]; fY0[i] = fY[i]; } SetFillColor(9); // default fill color } void ClockHand::Update() { // Update hand position if (!IsModified()) return; fPrevTimeValue = GetTimeValue(); Move(GetHandAngle()); } void ClockHand::Move(Float_t clock_angle) { // Move clockhand. Int_t n = GetN(); // ClockPoints used to rotate,scale and shift initial points static ClockPoints *points = new ClockPoints(); Float_t wh = (Float_t)fPad->XtoPixel(fPad->GetX2()); Float_t hh = (Float_t)fPad->YtoPixel(fPad->GetY1()); for (int i = 0; i < n; i++) { points->SetXY(fX0[i],fY0[i]); points->Rotate(clock_angle); if (wh < hh) points->Scale(0.5,0.5*wh/hh); // scale to have a circular clock else points->Scale(0.5*hh/wh,0.5); points->Shift(0.5,0.5); // move to the center of pad fX[i] = points->GetX(); fY[i] = points->GetY(); } } Aclock::Aclock(Int_t csize) : TTimer(500, kTRUE) { // Create a clock in a new canvas. fPad = new TCanvas("Aclock:canvas","xclock",-csize,csize); fPad->SetFillColor(14); // grey fMinuteHand = new MinuteHand(); fSecondHand = new SecondHand(); fHourHand = new HourHand(); SetBit(kCanDelete); Draw(); // append this Aclock to fPad Animate(); gSystem->AddTimer(this); // start timer = start animation } Aclock::~Aclock() { // Clean up the clock. delete fMinuteHand; delete fSecondHand; delete fHourHand; } void Aclock::Paint(Option_t *) { // Just draw clock scale (time and minutes ticks) static ClockPoints *point1 = new ClockPoints(); static ClockPoints *point2 = new ClockPoints(); Float_t wh = (Float_t)fPad->XtoPixel(fPad->GetX2()); Float_t hh = (Float_t)fPad->YtoPixel(fPad->GetY1()); for (int i = 0; i < 60; i++ ) { // draw minute/hour ticks point1->SetXY(0.,0.9); if (!(i%5)) point2->SetXY(0.,0.8); // hour ticks are longer else point2->SetXY(0.,0.87); Float_t angle = 6.*i; point1->Rotate(angle); point2->Rotate(angle); if (wh < hh) { // scale in oder to draw circle scale point1->Scale(0.5,0.5*wh/hh); point2->Scale(0.5,0.5*wh/hh); } else { point1->Scale(0.5*hh/wh,0.5); point2->Scale(0.5*hh/wh,0.5); } point1->Shift(0.5,0.5); // move to center of pad point2->Shift(0.5,0.5); fPad->PaintLine(point1->GetX(),point1->GetY(),point2->GetX(),point2->GetY()); } } void Aclock::Animate() { // Update clock hand positions and redraw the fPad if (!fSecondHand->IsModified()) return; fHourHand->Update(); // update position every minute fMinuteHand->Update(); // update position every minute fSecondHand->Update(); // update position every second fPad->Modified(); // drawing ... fPad->Update(); } Bool_t Aclock::Notify() { // Actions after timer's time-out Animate(); TTimer::Reset(); return kFALSE; }