[Kstars-devel] branches/KDE/4.6/kdeedu/kstars/kstars

Akarsh Simha akarshsimha at gmail.com
Sun Jan 2 10:48:00 CET 2011


SVN commit 1210795 by asimha:

Backends separated. Working, unclean, hackish version.

+ SkyMap is now a QGraphicsView

+ The widget on which all drawing is done is called SkyMapQDraw for
  the Qt version (and will be called SkyMapGLDraw for the GL version).

+ SkyMapQDraw and the future SkyMapGLDraw inherit from an abstract
  SkyMapDrawAbstract class which contains common methods that draw
  using QPainter, and allows the reimplementation of paintEvent() or
  paintGL() as is appropriate in the children.

+ The SkyMapQDraw is set as the child widget of the
  QGraphicsView::viewport(). This seems to be the typical workaround
  for getting an QGLWidget to work as a non-background widget in a
  QGV. I don't know if there is a more elegant way _that works_. This
  is one of those hackish things.

+ SkyMap::forceUpdate() calls a repaint() (for the time being, not
  update()) on the SkyMapQDraw instead of the SkyMap itself. I don't
  know why this is necessary as yet. This is one more of the hackish
  things.

TODO:

1. See if there are less hackish ways of doing things. (But this is
   not on priority for the 4.6 release. If it works, and is reasonably
   neat, I think we should let it in.) If these are actually Qt bugs,
   file them and triage them.

2. Implement the GL backend.

Please let me know what you think. If it's okay, I'll transfer this to
4.6 after I'm done with the GL stuff. I solicit everyone's response on
this as soon as possible, since the release is in a very very short
time from now.

CCMAIL: kstars-devel at kde.org, hdevalence at gmail.com

 M  +1 -1      CMakeLists.txt  
 M  +5 -0      kstarsdata.h  
 M  +36 -16    skymap.cpp  
 M  +39 -61    skymap.h  
 D             skymapdraw.cpp  
 D             skymapdraw.h  
 A             skymapdrawabstract.cpp   skymapdraw.cpp#1210794 [License: GPL (v2+)]
 A             skymapdrawabstract.h   [License: GPL (v2+)]
 M  +8 -54     skymapevents.cpp  
 A             skymapqdraw.cpp   [License: GPL (v2+)]
 A             skymapqdraw.h   skymapdraw.h#1210794 [License: GPL (v2+)]


--- branches/KDE/4.6/kdeedu/kstars/kstars/CMakeLists.txt #1210794:1210795
@@ -310,7 +310,7 @@
 	kspopupmenu.cpp obslistpopupmenu.cpp kstars.cpp ksalmanac.cpp 
 	kstarsactions.cpp kstarsdata.cpp kstarsdatetime.cpp kstarsdcop.cpp kstarsinit.cpp 
 	kstarssplash.cpp ksutils.cpp kswizard.cpp main.cpp 
-	simclock.cpp skymap.cpp skymapdraw.cpp skymapevents.cpp
+	simclock.cpp skymap.cpp skymapdrawabstract.cpp skymapqdraw.cpp skymapevents.cpp
 	skypainter.cpp skyqpainter.cpp skyglpainter.cpp
 	texture.cpp texturemanager.cpp
 	timezonerule.cpp 
--- branches/KDE/4.6/kdeedu/kstars/kstars/kstarsdata.h #1210794:1210795
@@ -203,6 +203,11 @@
     /** Synchronize list of visible FOVs and list of selected FOVs in Options */
     void syncFOV();
 
+    /**
+     *@return the list of visible FOVs
+     */
+    inline const QList<FOV*> getVisibleFOVs() const { return visibleFOVs; }
+
     /** Return log object */
     OAL::Log *logObject() { return m_logObject; }
 
--- branches/KDE/4.6/kdeedu/kstars/kstars/skymap.cpp #1210794:1210795
@@ -25,6 +25,7 @@
 #include <QFile>
 #include <QPointF>
 #include <QApplication>
+#include <QGraphicsScene>
 
 #include <kactioncollection.h>
 #include <kconfig.h>
@@ -58,6 +59,8 @@
 #include "projections/azimuthalequidistantprojector.h"
 #include "projections/equirectangularprojector.h"
 
+#include "skymapqdraw.h"
+
 #ifdef HAVE_XPLANET
 #include <KProcess>
 #include <kfiledialog.h>
@@ -139,14 +142,17 @@
 }
 
 SkyMap::SkyMap() :
+    QGraphicsView( KStars::Instance() ),
+    /*
 #ifdef USEGL
     QGLWidget( QGLFormat(QGL::SampleBuffers), KStars::Instance() ),
 #else 
     QWidget( KStars::Instance() ),
 #endif
+    */
     computeSkymap(true), angularDistanceMode(false), scrollCount(0),
-    data( KStarsData::Instance() ), pmenu(0), sky(0), sky2(0),
-    ClickedObject(0), FocusObject(0), TransientObject(0), m_proj(0)
+    data( KStarsData::Instance() ), pmenu(0),
+    ClickedObject(0), FocusObject(0), TransientObject(0), m_proj(0), m_SkyMapDraw(NULL)
 {
     m_Scale = 1.0;
 
@@ -171,8 +177,6 @@
     ClickedObject = NULL;
     FocusObject = NULL;
 
-    sky   = new QPixmap( width(),  height() );
-    sky2  = new QPixmap( width(),  height() );
     pmenu = new KSPopupMenu();
 
     setupProjector();
@@ -223,22 +227,39 @@
     m_iboxes->addInfoBox(m_geoBox);
     m_iboxes->addInfoBox(m_objBox);
 
-    m_fpstime.start();
-    m_framecount = 0;
+    // TODO: Pick the render enging from Options. For now, we will
+    // hardcode it here, for testing purposes only!
+    SkyMapQDraw *smqd = new SkyMapQDraw( this ); 
+    m_SkyMapDraw = smqd;
+    m_SkyMapDrawWidget = smqd;
 
+    // DEBUG: Okay. None of this seems to work. So I'm going to do it
+    // the stupid way -- where I just add the SkyMapQDraw (QWidget) as
+    // a child of this QGV.
+    /*
+    m_SkyScene = new QGraphicsScene( this );
+    m_SkyScene->addWidget( smqd );
+    setCacheMode( QGraphicsView::CacheNone );
+    smqd->show();
+    setScene( m_SkyScene );
+    */
+    smqd->setParent( this->viewport() );
+    smqd->show();
+
     //The update timer will be destructed when SkyMap is..
     QTimer *update = new QTimer(this);
     update->setInterval(30);
     connect(update, SIGNAL(timeout()), this, SLOT(update()) );
     update->start();
 
+    /*
     #ifdef USEGL
     if( !format().testOption( QGL::SampleBuffers ) )
         qWarning() << "No sample buffer; can't use multisampling (antialiasing)";
     if( !format().testOption( QGL::StencilBuffer ) )
         qWarning() << "No stencil buffer; can't draw concave polygons";
-
     #endif
+    */
 }
 
 void SkyMap::slotToggleGeoBox(bool flag) {
@@ -286,23 +307,17 @@
         Options::setFocusDec( focus()->dec().Degrees() );
     }
 
-    delete sky;
-    delete sky2;
     delete pmenu;
 
     delete m_proj;
 }
 
 void SkyMap::setGeometry( int x, int y, int w, int h ) {
-    QWidget::setGeometry( x, y, w, h );
-    *sky = sky->scaled( w, h );
-    *sky2 = sky2->scaled( w, h );
+    QGraphicsView::setGeometry( x, y, w, h );
 }
 
 void SkyMap::setGeometry( const QRect &r ) {
-    QWidget::setGeometry( r );
-    *sky = sky->scaled( r.width(), r.height() );
-    *sky2 = sky2->scaled( r.width(), r.height() );
+    QGraphicsView::setGeometry( r );
 }
 
 
@@ -894,6 +909,7 @@
 void SkyMap::setZoomFactor(double factor) {
     Options::setZoomFactor(  KSUtils::clamp(factor, MINZOOM, MAXZOOM)  );
     forceUpdate();
+    kDebug() << "Z00m CHANGED! CALLING forceUpdate()";
     emit zoomChanged();
 }
 
@@ -915,13 +931,17 @@
 
     computeSkymap = true;
     
+    kDebug() << "FORCING UPDATE!";
+
     // Ensure that stars are recomputed
     data->incUpdateID();
-
+    /*
     if( now )
         repaint();
     else
         update();
+    */
+    m_SkyMapDrawWidget->repaint(); // DEBUG: Testing.
 }
 
 float SkyMap::fov() {
--- branches/KDE/4.6/kdeedu/kstars/kstars/skymap.h #1210794:1210795
@@ -18,20 +18,20 @@
 #ifndef SKYMAP_H_
 #define SKYMAP_H_
 
-#define USEGL
+// #define USEGL
 
 #include <QTimer>
-#ifdef USEGL
-    #include <QGLWidget>
-#else
-    #include <QWidget>
-#endif
+#include <QGraphicsView>
 #include <QPixmap>
 #include <QTime>
 
+
 #include "skyobjects/skypoint.h"
 #include "skyobjects/skyline.h"
 
+#include "skymapdrawabstract.h"
+#include "skymapqdraw.h"
+
 #include <config-kstars.h>
 
 #define HOVER_INTERVAL 500
@@ -51,6 +51,8 @@
 class InfoBoxes;
 class Projector;
 
+class QGraphicsScene;
+
 /**@class SkyMap
 	*
 	*This is the canvas on which the sky is painted.  It's the main widget for KStars.
@@ -66,10 +68,13 @@
 	*@version 1.0
 	*/
 
-class SkyMap::QGraphicsView {
+class SkyMap : public QGraphicsView {
 
-    Q_OBJECT
+    Q_OBJECT;
 
+    friend class SkyMapDrawAbstract;
+    friend class SkyMapQDraw; // FIXME: This is the ugliest thing I've done in my life. Please, please, do something else.
+
 protected:
     /**
     *Constructor.  Read stored settings from KConfig object (focus position,
@@ -269,6 +274,7 @@
 
     bool isPointNull( const QPointF &p );
 
+    // NOTE: This method is draw-backend independent.
     /**@short update the geometry of the angle ruler. */
     void updateAngleRuler();
 
@@ -280,35 +286,26 @@
     	*/
     bool isObjectLabeled( SkyObject *o );
 
-    /**@short Convenience function for shutting off tracking mode.  Just calls KStars::slotTrack().
+    /*@*@short Convenience function for shutting off tracking mode.  Just calls KStars::slotTrack().
     	*/
     void stopTracking();
 
-    // TODO: Decide the fate of this method. This method should
-    // probably be implemented only in the SkyMapQDraw class, and should be
-    // called out of that class, since it uses QPainter.
-
-    /**@short Draw the current Sky map to a pixmap which is to be printed or exported to a file.
-    	*
-    	*@param pd pointer to the QPaintDevice on which to draw.  
-    	*@see KStars::slotExportImage()
-    	*@see KStars::slotPrint()
-    	*/
-    void exportSkyImage( QPaintDevice *pd );
-
     /** Get the current projector.
         @return a pointer to the current projector. */
     const Projector * projector() const;
 
-    /**@short Draw "user labels".  User labels are name labels attached to objects manually with
-     * the right-click popup menu.  Also adds a label to the FocusObject if the Option UseAutoLabel
-     * is true.
-     * @param labelObjects QList of pointers to the objects which need labels (excluding the centered object)
-     * @param psky painter for the sky
-     * @note the labelObjects list is managed by the SkyMapComponents class
+    /**
+     *@short Proxy method for SkyMapDrawAbstract::exportSkyImage()
      */
-    void drawObjectLabels( QList< SkyObject* >& labelObjects );
+    void exportSkyImage( QPaintDevice *pd ) { m_SkyMapDraw->exportSkyImage( pd ); }
 
+    /**
+     *@short Proxy method for SkyMapDrawAbstract::drawObjectLabels()
+     */
+    void drawObjectLabels( QList< SkyObject* >& labelObjects ) { m_SkyMapDraw->drawObjectLabels( labelObjects ); }
+
+
+
 public slots:
     //DEBUG_KIO_JOB
     void slotJobResult( KJob *j );
@@ -421,11 +418,13 @@
      */
     void slotClockSlewing();
 
+    // NOTE: This method is draw-backend independent.
     /**Enables the angular distance measuring mode. It saves the first
      * position of the ruler in a SkyPoint. It makes difference between
      * having clicked on the skymap and not having done so */
     void slotBeginAngularDistance();
 
+    // NOTE: This method is draw-backend independent.
     /**Computes the angular distance, prints the result in the status
      * bar and disables the angular distance measuring mode
      * If the user has clicked on the map the status bar shows the 
@@ -482,14 +481,6 @@
     void mousePointChanged(SkyPoint*);
 
 protected:
-    #ifdef USEGL
-    virtual void resizeGL(int width, int height);
-    virtual void initializeGL();
-    //virtual void paintGL();
-    #endif
-    /**Draw the Sky, and all objects in it. */
-    virtual void paintEvent( QPaintEvent *e );
-
     /**Process keystrokes:
      * @li arrow keys  Slew the map
      * @li +/- keys  Zoom in and out
@@ -541,6 +532,11 @@
      */
     virtual void resizeEvent( QResizeEvent * );
 
+    /**
+     *@short Asks the SkyMapDrawWidget to repaint itself
+     */
+    virtual void paintEvent( QPaintEvent *e );
+
 private slots:
     /**Gradually fade the Transient Hover Label into the background sky color, and
     	*redraw the screen after each color change.  Once it has faded fully, set the 
@@ -548,6 +544,7 @@
     	*/
     void slotTransientTimeout();
 
+    // NOTE: Akarsh believes that this method is backend-independent, and is pretty confident about that, but he thinks that it really requires a second inspection.
     /**@short attach transient label to object nearest the mouse cursor.
     	*This slot is connected to the timeout() signal of the HoverTimer, which is restarted
     	*in every mouseMoveEvent().  So this slot is executed only if the mouse does not move for 
@@ -563,29 +560,7 @@
     void setMouseMoveCursor();
 
 private:
-    /**Draw the overlays on top of the sky map.  These include the infoboxes,
-    	*field-of-view indicator, telescope symbols, zoom box and any other
-    	*user-interaction graphics.
-    	*
-    	*The overlays can be updated rapidly, without having to recompute the entire SkyMap.
-    	*The stored Sky image is simply blitted onto the SkyMap widget, and then we call
-    	*drawOverlays() to refresh the overlays.
-    	*@param pm pointer to the Sky pixmap
-    	*/
-    void drawOverlays( QPainter& p );
 
-    /**Draw symbols at the position of each Telescope currently being controlled by KStars.
-    	*@note The shape of the Telescope symbol is currently a hard-coded bullseye.
-    	*@param psky reference to the QPainter on which to draw (this should be the Sky pixmap). 
-    	*/
-    void drawTelescopeSymbols(QPainter &psky);
-
-    /**
-    	*@short Draw a dotted-line rectangle which traces the potential new field-of-view in ZoomBox mode.
-    	*@param psky reference to the QPainter on which to draw (this should be the Sky pixmap). 
-    	*/
-    void drawZoomBox( QPainter &psky );
-
     /**@short Begin fading out the name label attached to TransientObject.
     	*
     	*mouseMoveEvent() will call fadeTransientLabel() when TransientObject is not a 
@@ -664,7 +639,6 @@
 
     KStarsData *data;
     KSPopupMenu *pmenu;
-    QPixmap *sky, *sky2;
     SkyPoint  Focus, ClickedPoint, FocusPoint, MousePoint, Destination;
     SkyObject *ClickedObject, *FocusObject, *TransientObject;
 
@@ -684,10 +658,14 @@
     InfoBoxWidget* m_objBox;
     InfoBoxes*     m_iboxes;
 
+    // Note: These two point to the same stuff
+    SkyMapDrawAbstract *m_SkyMapDraw;
+    QWidget *m_SkyMapDrawWidget;
+
+    QGraphicsScene *m_SkyScene;
+
     static SkyMap* pinstance;
 
-    QTime m_fpstime;
-    int m_framecount;
 };
 
 #endif
--- branches/KDE/4.6/kdeedu/kstars/kstars/skymapevents.cpp #1210794:1210795
@@ -57,8 +57,9 @@
     //FIXME: No equivalent for this line in Qt4 ??
     //	if ( testWState( Qt::WState_AutoMask ) ) updateMask();
 
-    *sky  = sky->scaled( width(), height() );
-    *sky2 = sky2->scaled( width(), height() );
+    // TODO: Hopefully the child QWidget / QGLWidget will scale automatically...
+    // No, it doesn't seem to:
+    m_SkyMapDrawWidget->resize( size() );
 
     // Resize infoboxes container.
     // FIXME: this is not really pretty. Maybe there are some better way to this???
@@ -641,7 +642,7 @@
     }
 }
 
-#ifdef USEGL
+/*
 void SkyMap::initializeGL()
 {
 }
@@ -682,60 +683,13 @@
 
     ++m_framecount;
 }
-#else
-void SkyMap::paintEvent( QPaintEvent *event )
-{
-    //If computeSkymap is false, then we just refresh the window using the stored sky pixmap
-    //and draw the "overlays" on top.  This lets us update the overlay information rapidly
-    //without needing to recompute the entire skymap.
-    //use update() to trigger this "short" paint event; to force a full "recompute"
-    //of the skymap, use forceUpdate().
+*/
 
-    if(m_framecount == 25) {
-        float sec = m_fpstime.elapsed()/1000.;
-        printf("FPS: %.2f\n", m_framecount/sec);
-        m_framecount = 0;
-        m_fpstime.restart();
+void SkyMap::paintEvent( QPaintEvent *e ) {
+    // Do nothing for now.
+    kDebug() << "Was here";
     }
 
-    ++m_framecount;
-    if (!computeSkymap)
-    {
-        QPainter p;
-        p.begin( this );
-        p.drawLine(0,0,1,1); // Dummy operation to circumvent bug
-        p.drawPixmap( 0, 0, *sky );
-        drawOverlays(p);
-        p.end();
-        return ; // exit because the pixmap is repainted and that's all what we want
-    }
-
-    // FIXME: used to to notify infobox about possible change of object coordinates
-    // Not elegant at all. Should find better option
-    showFocusCoords();
-    setupProjector();
-    
-    SkyQPainter psky(this, sky);
-    //FIXME: we may want to move this into the components.
-    psky.begin();
-    
-    //Draw all sky elements
-    psky.drawSkyBackground();
-    data->skyComposite()->draw( &psky );
-    //Finish up
-    psky.end();
-
-    QPainter psky2;
-    psky2.begin( this );
-    psky2.drawLine(0,0,1,1); // Dummy op.
-    psky2.drawPixmap( 0, 0, *sky );
-    drawOverlays(psky2);
-    psky2.end();
-
-    computeSkymap = false;	// use forceUpdate() to compute new skymap else old pixmap will be shown
-}
-#endif
-
 double SkyMap::zoomFactor( const int modifier ) {
     double factor = ( modifier & Qt::ControlModifier) ? DZOOM : 2.0; 
     if ( modifier & Qt::ShiftModifier ) 


More information about the Kstars-devel mailing list