1 /***************************************************************************
2 infoboxes.cpp - description
5 copyright : (C) 2002 by Jason Harris
6 email : jharris@30doradus.org
7 ***************************************************************************/
9 /***************************************************************************
11 * This program is free software; you can redistribute it and/or modify *
12 * it under the terms of the GNU General Public License as published by *
13 * the Free Software Foundation; either version 2 of the License, or *
14 * (at your option) any later version. *
16 ***************************************************************************/
23 #include "infoboxes.h"
24 #include "kstarsdatetime.h"
26 #include "geolocation.h"
29 InfoBoxes::InfoBoxes( int w
, int h
, QPoint tp
, bool tshade
,
30 QPoint gp
, bool gshade
, QPoint fp
, bool fshade
,
31 QColor colorText
, QColor colorGrab
, QColor colorBG
) :
32 boxColor(colorText
), grabColor(colorGrab
), bgColor(colorBG
),
33 GeoBox(0), FocusBox(0), TimeBox(0)
44 GrabPos
= QPoint( 0, 0 );
51 GeoBox
= new InfoBox( gx
, gy
, gshade
, "", "" );
52 TimeBox
= new InfoBox( tx
, ty
, tshade
, "", "", "" );
53 FocusBox
= new InfoBox( fx
, fy
, fshade
, "", "", "" );
55 fixCollisions( TimeBox
);
56 fixCollisions( FocusBox
);
61 InfoBoxes::InfoBoxes( int w
, int h
, int tx
, int ty
, bool tshade
,
62 int gx
, int gy
, bool gshade
, int fx
, int fy
, bool fshade
,
63 QColor colorText
, QColor colorGrab
, QColor colorBG
) :
64 boxColor(colorText
), grabColor(colorGrab
), bgColor(colorBG
) {
67 GrabPos
= QPoint( 0, 0 );
74 GeoBox
= new InfoBox( gx
, gy
, gshade
, "", "" );
75 TimeBox
= new InfoBox( tx
, ty
, tshade
, "", "", "" );
76 FocusBox
= new InfoBox( fx
, fy
, fshade
, "", "", "" );
78 fixCollisions( TimeBox
);
79 fixCollisions( FocusBox
);
84 InfoBoxes::~InfoBoxes(){
90 void InfoBoxes::resize( int w
, int h
) {
96 void InfoBoxes::drawBoxes( QPainter
&p
, QColor FGColor
, QColor grabColor
,
97 QColor BGColor
, unsigned int BGMode
) {
99 if ( GeoBox
->isVisible() ) {
100 p
.setPen( QPen( FGColor
) );
101 if ( GrabbedBox
== 1 ) {
102 p
.setPen( QPen( grabColor
) );
103 p
.drawRect( GeoBox
->x(), GeoBox
->y(), GeoBox
->width(), GeoBox
->height() );
105 GeoBox
->draw( p
, BGColor
, BGMode
);
108 if ( TimeBox
->isVisible() ) {
109 p
.setPen( QPen( FGColor
) );
110 if ( GrabbedBox
== 2 ) {
111 p
.setPen( QPen( grabColor
) );
112 p
.drawRect( TimeBox
->x(), TimeBox
->y(), TimeBox
->width(), TimeBox
->height() );
114 TimeBox
->draw( p
, BGColor
, BGMode
);
117 if ( FocusBox
->isVisible() ) {
118 p
.setPen( QPen( FGColor
) );
119 if ( GrabbedBox
== 3 ) {
120 p
.setPen( QPen( grabColor
) );
121 p
.drawRect( FocusBox
->x(), FocusBox
->y(), FocusBox
->width(), FocusBox
->height() );
123 FocusBox
->draw( p
, BGColor
, BGMode
);
128 bool InfoBoxes::grabBox( QMouseEvent
*e
) {
129 if ( GeoBox
->rect().contains( e
->pos() ) ) {
131 GrabPos
.setX( e
->x() - GeoBox
->x() );
132 GrabPos
.setY( e
->y() - GeoBox
->y() );
134 } else if ( TimeBox
->rect().contains( e
->pos() ) ) {
136 GrabPos
.setX( e
->x() - TimeBox
->x() );
137 GrabPos
.setY( e
->y() - TimeBox
->y() );
139 } else if ( FocusBox
->rect().contains( e
->pos() ) ) {
141 GrabPos
.setX( e
->x() - FocusBox
->x() );
142 GrabPos
.setY( e
->y() - FocusBox
->y() );
145 GrabbedBox
= 0; //this is probably redundant, because mouseRelease should call unGrabBox()...
150 bool InfoBoxes::unGrabBox( void ) {
160 bool InfoBoxes::dragBox( QMouseEvent
*e
) {
161 switch( GrabbedBox
) {
163 GeoBox
->move( e
->x() - GrabPos
.x(), e
->y() - GrabPos
.y() );
164 fixCollisions( GeoBox
);
168 TimeBox
->move( e
->x() - GrabPos
.x(), e
->y() - GrabPos
.y() );
169 fixCollisions( TimeBox
);
173 FocusBox
->move( e
->x() - GrabPos
.x(), e
->y() - GrabPos
.y() );
174 fixCollisions( FocusBox
);
177 default: //no box is grabbed; return false
182 bool InfoBoxes::shadeBox( QMouseEvent
*e
) {
183 if ( GeoBox
->rect().contains( e
->pos() ) ) {
184 GeoBox
->toggleShade();
185 if ( GeoBox
->rect().bottom() > height() ) GeoBox
->move( GeoBox
->x(), height() - GeoBox
->height() );
186 if ( GeoBox
->rect().right() > width() ) GeoBox
->move( width() - GeoBox
->width(), GeoBox
->y() );
187 if ( GeoBox
->anchorBottom() ) GeoBox
->move( GeoBox
->x(), height() - GeoBox
->height() );
188 if ( GeoBox
->anchorRight() ) GeoBox
->move( width() - GeoBox
->width(), GeoBox
->y() );
189 fixCollisions( TimeBox
);
190 fixCollisions( FocusBox
);
192 } else if ( TimeBox
->rect().contains( e
->pos() ) ) {
193 TimeBox
->toggleShade();
194 if ( TimeBox
->rect().bottom() > height() ) TimeBox
->move( TimeBox
->x(), height() - TimeBox
->height() );
195 if ( TimeBox
->rect().right() > width() ) TimeBox
->move( width() - TimeBox
->width(), TimeBox
->y() );
196 if ( TimeBox
->anchorBottom() ) TimeBox
->move( TimeBox
->x(), height() - TimeBox
->height() );
197 if ( TimeBox
->anchorRight() ) TimeBox
->move( width() - TimeBox
->width(), TimeBox
->y() );
198 fixCollisions( GeoBox
);
199 fixCollisions( FocusBox
);
201 } else if ( FocusBox
->rect().contains( e
->pos() ) ) {
202 FocusBox
->toggleShade();
203 if ( FocusBox
->rect().bottom() > height() ) FocusBox
->move( FocusBox
->x(), height() - FocusBox
->height() );
204 if ( FocusBox
->rect().right() > width() ) FocusBox
->move( width() - FocusBox
->width(), FocusBox
->y() );
205 if ( FocusBox
->anchorBottom() ) FocusBox
->move( FocusBox
->x(), height() - FocusBox
->height() );
206 if ( FocusBox
->anchorRight() ) FocusBox
->move( width() - FocusBox
->width(), FocusBox
->y() );
207 fixCollisions( TimeBox
);
208 fixCollisions( GeoBox
);
214 bool InfoBoxes::fixCollisions( InfoBox
*target
) {
215 int dLeft(0), dRight(0), dUp(0), dDown(0);
216 QRect area
= QRect( 0, 0, Width
, Height
);
217 QRect t
= target
->rect();
220 //Set Box1 and Box2 to the rects of the other two InfoBoxes, unless
221 //they are not visible (if so, set a null QRect)
222 if ( target
== GeoBox
) {
223 if ( FocusBox
->isVisible() ) Box1
= FocusBox
->rect();
224 else Box1
= QRect(0,0,0,0);
226 if ( TimeBox
->isVisible() ) Box2
= TimeBox
->rect();
227 else Box2
= QRect(0,0,0,0);
229 } else if ( target
== FocusBox
) {
230 if ( GeoBox
->isVisible() ) Box1
= GeoBox
->rect();
231 else Box1
= QRect(0,0,0,0);
233 if ( TimeBox
->isVisible() ) Box2
= TimeBox
->rect();
234 else Box2
= QRect(0,0,0,0);
236 } else if ( target
== TimeBox
) {
237 if ( FocusBox
->isVisible() ) Box1
= FocusBox
->rect();
238 else Box1
= QRect(0,0,0,0);
240 if ( GeoBox
->isVisible() ) Box2
= GeoBox
->rect();
241 else Box2
= QRect(0,0,0,0);
243 } else { return false; } //none of the Boxes match target!
245 //Shrink Box1 and Box2 by one pixel in each direction. This will make the
246 //Edges of adjacent boxes line up more nicely.
247 if ( Box1
.width() ) Box1
.setCoords( Box1
.left()+1, Box1
.top()+1, Box1
.right()-1, Box1
.bottom()-1 );
248 if ( Box2
.width() ) Box2
.setCoords( Box2
.left()+1, Box2
.top()+1, Box2
.right()-1, Box2
.bottom()-1 );
250 //First, make sure target box is within area rect.
251 if ( ! area
.contains( t
) ) {
252 /* if ( t.x() < area.x() ) target->move( area.x(), t.y() );
253 if ( t.y() < area.y() ) target->move( t.x(), area.y() );
254 if ( t.right() > area.right() ){ target->move( area.right() - t.width(), t.y() ); }
255 if ( t.bottom() > area.bottom() ) target->move( t.x(), area.bottom() - t.height() );*/
257 int x
= t
.x(), y
= t
.y();
259 if ( t
.x() < area
.x() ) x
= area
.x();
260 if ( t
.y() < area
.y() ) y
= area
.y();
261 if ( t
.right() > area
.right() ) x
= area
.right() - t
.width();
262 if ( t
.bottom() > area
.bottom() ) y
= area
.bottom() - t
.height();
275 if ( t
.intersects( Box1
) || t
.intersects( Box2
) ) {
276 //move t to the left one pixel at a time until there is no
277 //intersection with Box1 or Box2.
278 while ( leftRect
.intersects( Box1
) || leftRect
.intersects( Box2
) ) {
280 leftRect
.moveTopLeft( QPoint( t
.x() - dLeft
, t
.y() ) );
282 //If leftRect is outside area, set dLeft to a nonsense large value
283 if ( !area
.contains( leftRect
) ) { dLeft
= 100000; }
284 //repeat for right, up and down directions.
285 while ( rightRect
.intersects( Box1
) || rightRect
.intersects( Box2
) ) {
287 rightRect
.moveTopLeft( QPoint( t
.x() + dRight
, t
.y() ) );
289 if ( !area
.contains( rightRect
) ) { dRight
= 100000; }
291 while ( upRect
.intersects( Box1
) || upRect
.intersects( Box2
) ) {
293 upRect
.moveTopLeft( QPoint( t
.x(), t
.y() - dUp
) );
295 if ( !area
.contains( upRect
) ) { dUp
= 100000; }
297 while ( downRect
.intersects( Box1
) || downRect
.intersects( Box2
) ) {
299 downRect
.moveTopLeft( QPoint( t
.x(), t
.y() + dDown
) );
301 if ( !area
.contains( downRect
) ) { dDown
= 100000; }
304 //find the smallest displacement, and move the target box there.
305 //if the smallest displacement is 100000, then the function has failed
306 //to find any legal position; return false.
308 if ( dRight
< dmin
) dmin
= dRight
;
309 if ( dDown
< dmin
) dmin
= dDown
;
310 if ( dUp
< dmin
) dmin
= dUp
;
312 if ( dmin
== 100000 ) { return false; }
313 else if ( dmin
== dLeft
) {
314 target
->move( leftRect
.x(), leftRect
.y() );
315 } else if ( dmin
== dRight
) {
316 target
->move( rightRect
.x(), rightRect
.y() );
317 } else if ( dmin
== dUp
) {
318 target
->move( upRect
.x(), upRect
.y() );
319 } else if ( dmin
== dDown
) {
320 target
->move( downRect
.x(), downRect
.y() );
323 else // no intersection with other boxes
326 //Set Anchor flags based on new position
327 if ( target
->rect().right() >= width()-2 ) target
->setAnchorRight( true );
328 else target
->setAnchorRight( false );
329 if ( target
->rect().bottom() >= height()-2 ) target
->setAnchorBottom(true);
330 else target
->setAnchorBottom(false);
332 //Final check to see if we're still inside area (we may not be if target
333 //is bigger than area)
334 if ( area
.contains( target
->rect() ) ) return true;
338 bool InfoBoxes::timeChanged( const KStarsDateTime
&ut
, const KStarsDateTime
<
, dms
*lst
) {
339 QString ot1
= TimeBox
->text1();
340 QString ot2
= TimeBox
->text2();
341 QString ot3
= TimeBox
->text3();
343 TimeBox
->setText1( i18n( "Local Time", "LT: " ) + lt
.time().toString()
344 + " " + lt
.date().toString( "%d %b %Y" ) );
345 TimeBox
->setText2( i18n( "Universal Time", "UT: " ) + ut
.time().toString()
346 + " " + ut
.date().toString( "%d %b %Y" ) );
349 STString
= STString
.sprintf( "%02d:%02d:%02d ", lst
->hour(), lst
->minute(), lst
->second() );
351 //Don't use KLocale::formatNumber() for Julian Day because we don't want
352 //thousands-place separators
353 QString JDString
= QString::number( ut
.djd(), 'f', 2 );
354 JDString
.replace( ".", KGlobal::locale()->decimalSymbol() );
356 TimeBox
->setText3( i18n( "Sidereal Time", "ST: " ) + STString
+
357 i18n( "Julian Day", "JD: " ) + JDString
);
359 if ( ot1
== TimeBox
->text1() && ot2
== TimeBox
->text2() &&
360 ot3
== TimeBox
->text3() )
368 bool InfoBoxes::geoChanged(const GeoLocation
*geo
) {
369 QString ot1
= GeoBox
->text1();
370 QString ot2
= GeoBox
->text2();
372 QString name
= geo
->translatedName() + ", ";
373 if ( ! geo
->province().isEmpty() ) name
+= geo
->translatedProvince() + ", ";
374 name
+= geo
->translatedCountry();
375 GeoBox
->setText1( name
);
377 GeoBox
->setText2( i18n( "Longitude", "Long:" ) + " " +
378 KGlobal::locale()->formatNumber( geo
->lng()->Degrees(),3) + " " +
379 i18n( "Latitude", "Lat:" ) + " " +
380 KGlobal::locale()->formatNumber( geo
->lat()->Degrees(),3) );
382 if ( ot1
== GeoBox
->text1() && ot2
== GeoBox
->text2() )
390 bool InfoBoxes::focusObjChanged( const QString
&n
) {
391 QString ot1
= FocusBox
->text1();
393 FocusBox
->setText1( i18n( "Focused on: " ) + n
);
394 if ( ot1
== FocusBox
->text1() ) return false;
401 bool InfoBoxes::focusCoordChanged(const SkyPoint
*p
) {
402 QString ot2
= FocusBox
->text2();
403 QString ot3
= FocusBox
->text3();
405 FocusBox
->setText2( i18n( "Right Ascension", "RA" ) + ": " + p
->ra()->toHMSString() +
406 " " + i18n( "Declination", "Dec" ) + ": " + p
->dec()->toDMSString(true) );
407 FocusBox
->setText3( i18n( "Azimuth", "Az" ) + ": " + p
->az()->toDMSString(true) +
408 " " + i18n( "Altitude", "Alt" ) + ": " + p
->alt()->toDMSString(true) );
410 if ( ot2
== FocusBox
->text2() && ot3
== FocusBox
->text3() )
418 void InfoBoxes::checkBorders(bool resetToDefault
) {
419 if (resetToDefault
) {
420 TimeBox
->setAnchorFlag( InfoBox::AnchorNone
);
421 GeoBox
->setAnchorFlag( InfoBox::AnchorNone
);
422 FocusBox
->setAnchorFlag( InfoBox::AnchorNone
);
425 if ( GeoBox
->rect().right() >= Width
-2 ) GeoBox
->setAnchorRight( true );
426 if ( TimeBox
->rect().right() >= Width
-2 ) TimeBox
->setAnchorRight( true );
427 if ( FocusBox
->rect().right() >= Width
-2 ) FocusBox
->setAnchorRight( true );
428 if ( GeoBox
->rect().bottom() >= Height
-2 ) GeoBox
->setAnchorBottom( true );
429 if ( TimeBox
->rect().bottom() >= Height
-2 ) TimeBox
->setAnchorBottom( true );
430 if ( FocusBox
->rect().bottom() >= Height
-2 ) FocusBox
->setAnchorBottom( true );
432 if ( GeoBox
->anchorRight() ) GeoBox
->move( Width
, GeoBox
->y() );
433 if ( TimeBox
->anchorRight() ) TimeBox
->move( Width
, TimeBox
->y() );
434 if ( FocusBox
->anchorRight() ) FocusBox
->move( Width
, FocusBox
->y() );
435 if ( GeoBox
->anchorBottom() ) GeoBox
->move( GeoBox
->x(), Height
);
436 if ( TimeBox
->anchorBottom() ) TimeBox
->move( TimeBox
->x(), Height
);
437 if ( FocusBox
->anchorBottom() ) FocusBox
->move( FocusBox
->x(), Height
);
440 #include "infoboxes.moc"