📄 zonemap.cpp
字号:
int zx, zy; winToZone( m_cursor_x, m_cursor_y, zx, zy); long lDistance; long lClosest = LONG_MAX; TimeZone closestZone; QPoint lPoint; for ( unsigned i = 0; i < cities.count(); i++ ) { CityPos *cp = cities[i]; // use the manhattenLength, a good enough of an appoximation here lDistance = QABS(zy - cp->lat) + QABS(zx - cp->lon); // first to zero wins! if ( lDistance < lClosest ) { lClosest = lDistance; lPoint = QPoint(cp->lat, cp->lon); closestZone = TimeZone(cp->id); } } if (m_cursor != closestZone) { m_cursor = closestZone; zoneToWin( m_cursor.lon(), m_cursor.lat(), nlwx, nlwy); bounds = expandTo(bounds, QPoint(nlwx, nlwy)); } else { nlwx = olwx; nlwy = olwy; } // m_curosr m_last = m_cursor; QDateTime cityTime = m_cursor.fromUtc(TimeZone::utcDateTime()); QString name = m_cursor.city().replace( QRegExp("_"), " " ); lblCity->setText( qApp->translate("DefaultCityNames", name) + "\n" + TimeString::localHM( cityTime.time())); lblCity->setMinimumSize( lblCity->sizeHint() ); lblCity->resize( QMAX(lblCity->sizeHint().width(),80), QMAX(lblCity->sizeHint().height(),40) ); // Now decide where to move the label, x & y can be reused int x, y; contentsToViewport(nlwx, nlwy, x, y); // // Put default position for the city label in the "above left" // area. This avoids obscuring the popup for quite a bit of // the map. Use the "below right" position for the border cases. // x -= iLABELOFFSET + lblCity->width(); if (x < 0) { // right x += 2*iLABELOFFSET + lblCity->width(); // still keep on screen, over red dot if need be. if ((x+lblCity->width() > width())) x -= x+lblCity->width() - width(); } y -= iLABELOFFSET + lblCity->height(); if (y < 0) { // below y += 2*iLABELOFFSET + lblCity->height(); // still keep on screen, over red dot if need be. if ((y+lblCity->height() > height())) y -= y+lblCity->height() - height(); } // draw in the city and the label if ( m_repaint.isValid()) { int repx, repy; zoneToWin( m_repaint.lon(), m_repaint.lat(), repx, repy ); bounds = expandTo(bounds, QPoint(repx, repy)); } m_repaint = m_last; lblCity->move( x, y ); lblCity->show(); // m_curosr repaintContents( bounds.x()-(1+iCITYOFFSET), bounds.y()-(1+iCITYOFFSET), bounds.width()+2+iCITYSIZE, bounds.height()+2+iCITYSIZE); }}void ZoneMap::slotFindCity( const QPoint &pos ){ initCities(); int tmpx, tmpy; viewportToContents(pos.x(), pos.y(), tmpx, tmpy); setCursorPoint(tmpx, tmpy);}void ZoneMap::showCity( const TimeZone &city ){ // use set cursor point to erase old point if need be. int mx, my; zoneToWin(city.lon(), city.lat(), mx, my); setCursorPoint(mx, my);}void ZoneMap::resizeEvent( QResizeEvent *e ){ // // Disable zooming when resizing. // if (bZoom) { bZoom = FALSE; cmdZoom->setOn(FALSE); } // keep the zoom button down in the corner QSize _size = e->size(); cmdZoom->move( _size.width() - cmdZoom->width(), _size.height() - cmdZoom->height() ); if ( !bZoom ) { drawableW = width() - 2 * frameWidth(); drawableH = height() - 2 * frameWidth(); makeMap( drawableW, drawableH ); resizeContents( drawableW, drawableH ); } else { resizeContents( wImg, hImg ); }}void ZoneMap::drawCities( QPainter *p ){ int x,y; // draw in the cities // for testing only as when you put it // on the small screen it looks awful and not to mention useless p->setPen( red ); TimeZone curZone; const char *zoneID; QStrListIterator it( TimeZone::ids() ); for (; it.current(); ++it) { zoneID = it.current(); curZone = TimeZone( zoneID ); zoneToWin( curZone.lat(), curZone.lon(), x, y ); if ( x > wImg ) x = x - wImg; p->drawRect( x - iCITYOFFSET, y - iCITYOFFSET, iCITYSIZE, iCITYSIZE); }}static void dayNight(QImage *pImage){ // create a mask that functions from sun.h double dJulian, dSunRad, dSunDecl, dSunRadius, dSunLong; int wImage = pImage->width(), hImage = pImage->height(), iStart, iStop, iMid, relw, i; short * wtab = new short [ wImage ]; time_t tCurrent; struct tm *pTm; // get the position of the sun based on our current time... tCurrent = time( NULL ); pTm = gmtime( &tCurrent ); dJulian = jtime( pTm ); sunpos( dJulian, 0, &dSunRad, &dSunDecl, &dSunRadius, &dSunLong ); // now get the projected illumination projillum( wtab, wImage, hImage, dSunDecl ); relw = wImage - int( wImage * 0.0275 ); // draw the map, keeping in mind that we may go too far off the map... iMid = ( relw * ( 24*60 - pTm->tm_hour * 60 - pTm->tm_min ) ) / ( 24*60 ); for ( i = 0; i < hImage; i++ ) { if ( wtab[i] > 0 ) { iStart = iMid - wtab[i]; iStop = iMid + wtab[i]; if ( iStart < 0 ) { darken( pImage, iStop, wImage + iStart, i ); } else if ( iStop > wImage ) { darken( pImage, iStop - wImage, iStart, i ); } else { darken( pImage, 0, iStart, i ); darken( pImage, iStop, wImage, i ); } } else { darken( pImage, 0, wImage, i ); } } delete [] wtab;}static inline void darken( QImage *pImage, int start, int stop, int row ){ // Always clip stop parameter to ensure our preconditions if ( stop >= pImage->width() ) stop = pImage->width() - 1; // Assume that the image is 32bpp as we should have converted to that previously... QRgb *p = (QRgb *)pImage->scanLine( row ); for ( int j = start; j <= stop; j++ ) { QRgb rgb = p[j]; p[j] = qRgb( 2 * qRed( rgb ) / 3, 2 * qGreen( rgb ) / 3, 2 * qBlue( rgb ) / 3 ); }}void ZoneMap::makeMap( int w, int h ){ QImage imgOrig = Resource::loadImage( strMAP ); if ( imgOrig.isNull() ) { QMessageBox::warning( this, tr( "Couldn't Find Map" ), tr( "<p>Couldn't load map: %1, exiting") .arg( strMAP ) ); exit(-1); } // set up the color table for darkening... imgOrig = imgOrig.convertDepth( 32 ); // else go one with making the map... if ( bIllum ) { // do a daylight mask dayNight(&imgOrig); } // redo the width and height wImg = w; hImg = h; ox = ( wImg / 2 ) - int( wImg * 0.0275 ); oy = hImg / 2; pixCurr->convertFromImage( imgOrig.smoothScale(w, h), QPixmap::ThresholdDither ); // should also work out max accell, or accell rates for this zoom. maxMovement=wImg*90;}void ZoneMap::drawCity( QPainter *p, const TimeZone &city ){ int x, y; p->setPen( red ); zoneToWin( city.lon(), city.lat(), x, y ); if (m_cursor_x != -1 && m_cursor_y != -1) { p->drawLine( m_cursor_x, m_cursor_y, x, y); } p->drawRect( m_cursor_x - iCITYOFFSET, m_cursor_y - iCITYOFFSET, iCITYSIZE, iCITYSIZE );}void ZoneMap::drawContents( QPainter *p, int cx, int cy, int cw, int ch ){ // if there is a need to resize, then do it... // get our drawable area drawableW = width() - 2 * frameWidth(); drawableH = height() - 2 * frameWidth(); int pixmapW = pixCurr->width(), pixmapH = pixCurr->height(); if ( !bZoom && ( ( pixmapW != drawableW ) || ( pixmapH != drawableH) ) ) { makeMap( drawableW, drawableH ); } // taken from the scrollview example... int rowheight = pixCurr->height(); int toprow = cy / rowheight; int bottomrow = ( cy + ch + rowheight - 1 ) / rowheight; int colwidth = pixCurr->width(); int leftcol= cx / colwidth; int rightcol= ( cx + cw + colwidth - 1 ) / colwidth; for ( int r = toprow; r <= bottomrow; r++ ) { int py = r * rowheight; for ( int c = leftcol; c <= rightcol; c++ ) { int px = c * colwidth; p->drawPixmap( px, py, *pixCurr ); } } // Draw that city! if ( m_last.isValid() ) drawCity( p, m_last );}void ZoneMap::slotZoom( bool setZoom ){ if (setZoom == bZoom) return; bZoom = setZoom; int cx, cy; winToZone(m_cursor_x, m_cursor_y, cx, cy); if ( bZoom ) { makeMap( 2 * wImg , 2 * hImg ); resizeContents( wImg, hImg ); } else { makeMap( drawableW, drawableH ); resizeContents( drawableW, drawableH ); } zoneToWin(cx, cy, cx, cy); setCursorPoint(cx, cy); ensureVisible(cx, cy); int lx, ly; zoneToWin( m_cursor.lon(), m_cursor.lat(), lx, ly ); updateContents( QRect(QMIN(lx, cx)-(1+iCITYOFFSET), QMIN(ly, cy)-(1+iCITYOFFSET), QABS(lx - cx)+2+iCITYSIZE, QABS(ly - cy)+2+iCITYSIZE));}void ZoneMap::slotIllum( bool setIllum ){ bIllum = !setIllum; // make the map... makeMap( pixCurr->width(), pixCurr->height() ); updateContents( 0, 0, wImg, hImg );}void ZoneMap::slotUpdate( void ){ // recalculate the light, most people will never see this, // but it is good to be thorough makeMap ( pixCurr->width(), pixCurr->height() ); updateContents( contentsX(), contentsY(), drawableW, drawableH );}void ZoneMap::slotRedraw( void ){ // paint over that pesky city... int x, y; if ( m_repaint.isValid() ) { m_last = TimeZone(); zoneToWin(m_repaint.lon(), m_repaint.lat(), x, y); updateContents( x - iCITYOFFSET, y - iCITYOFFSET, iCITYSIZE, iCITYSIZE); m_repaint = TimeZone(); }}void ZoneMap::initCities(){ // Contructing TimeZone::TimeZone( city ) is hideously expensive - // preload the position of each city. if ( citiesInit ) return; QStrList list = TimeZone::ids() ; QStrListIterator it( list ); int count = 0; cities.resize( list.count() ); for (; it.current(); ++it) { QCString zoneID = it.current(); TimeZone curZone( zoneID ); if ( !curZone.isValid() ){ qDebug("ZoneMap::slotFindCity Invalid zoneID %s", zoneID.data() ); continue; } CityPos *cp = new CityPos; cp->lat = curZone.lat(); cp->lon = curZone.lon(); cp->id = zoneID.copy(); cities.insert( count++, cp ); } cities.resize(count); citiesInit = TRUE; /* should also set min lat max lat min long max long and go through zone file for min distance between two cities, (halv it for default min movement) */ ulong lDistance; ulong lClosest = ULONG_MAX; for ( uint i = 0; i < cities.count(); i++ ) { long latfrom = cities[i]->lat; long lonfrom = cities[i]->lon; for ( uint j = 0; j < cities.count(); j++ ) { if (i != j) { long latto = cities[j]->lat; long lonto = cities[j]->lon; // use the manhattenLength, a good enough of an appoximation here lDistance = QABS(latfrom - latto) + QABS(lonfrom - lonto); // first to zero wins! if ( lDistance < lClosest ) { lClosest = lDistance; } } } }}#ifdef TEST_ACCESS_TO_CITIESvoid ZoneMap::testAccess(){ qDebug("test access"); initCities(); for ( unsigned i = 0; i < cities.count(); i++ ) { CityPos *cp = cities[i]; // check if pixel for this city and or pixels around this city can // be accessed. int lat, lon, x, y, cx, cy; lat = cp->lat; lon = cp->lon; zoneToWin(lon, lat, x, y); bool found = false; QCString id = cp->id; for (cx = x-1; cx <= x+1; ++cx) { for (cy = y-1; cy <= y+1; ++cy) { setCursorPoint(cx,cy); if (m_cursor.id() == id) { found = true; break; } } } if (!found) { qDebug("couldn't find city %s", (const char *)id); for (cx = x-1; cx <= x+1; ++cx) { for (cy = y-1; cy <= y+1; ++cy) { setCursorPoint(cx,cy); qDebug("\t%d:%d got %s instead", cx, cy, (const char *)m_cursor.id()); } } } }}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -