MiniDisplay/minidisplay.cpp
author sl
Wed, 04 Jun 2014 08:12:37 +0200
changeset 32 1c2a7f563019
parent 31 e68f1542d9d3
child 33 cf5eba52cb1d
permissions -rw-r--r--
Messing around to try to get our animation to start and stop properly.
That's still not working though.
     1 #include "minidisplay.h"
     2 #include <QPainter>
     3 #include <QTimer>
     4 
     5 const int KMaxReadAttempt=100;
     6 
     7 MiniDisplay::MiniDisplay(QQuickItem *parent):
     8     QQuickItem(parent),iReadAttempt(0),iBrightness(iDisplay.MaxBrightness())
     9 {
    10     // By default, QQuickItem does not draw anything. If you subclass
    11     // QQuickItem to create a visual item, you will need to uncomment the
    12     // following line and re-implement updatePaintNode()
    13 
    14     // setFlag(ItemHasContents, true);
    15     //
    16     //qDebug() << "New MiniDisplay";
    17 }
    18 
    19 MiniDisplay::~MiniDisplay()
    20 {
    21     //qDebug() << "Delete MiniDisplay";
    22     close();
    23 }
    24 
    25 
    26 void MiniDisplay::open()
    27 {
    28     if (iDisplay.Open())
    29     {
    30         iDisplay.SetBrightness(iBrightness);
    31         emit opened();
    32         emit statusChanged();
    33     }
    34     else
    35     {
    36         emit openError();
    37     }
    38 }
    39 
    40 
    41 void MiniDisplay::close()
    42 {
    43     //qDebug() << "MiniDisplay::close";
    44     //Try to put back ourframe position to RAM 0,0 which is a multiple of 128
    45     if (iDisplay.IsOpen())
    46     {
    47         emit closing();
    48 
    49         if (iDisplay.DisplayPositionY()%128!=0)
    50         {
    51             //qDebug() << "SwapBuffer to put back our frame position to zero " << iDisplay.DisplayPositionY();
    52             iDisplay.SwapBuffers();
    53         }
    54     }
    55     iDisplay.Close();
    56     emit closed();
    57     emit statusChanged();
    58 }
    59 
    60 bool MiniDisplay::isOpen()
    61 {
    62     return iDisplay.IsOpen();
    63 }
    64 
    65 void MiniDisplay::clear()
    66 {
    67     if (!iDisplay.IsOpen()) return;
    68     //
    69     iDisplay.Clear();
    70 }
    71 
    72 void MiniDisplay::fill()
    73 {
    74     if (!iDisplay.IsOpen()) return;
    75     //
    76     iDisplay.SetAllPixels(0xFF);
    77 }
    78 
    79 void MiniDisplay::swapBuffers()
    80 {
    81     if (!iDisplay.IsOpen()) return;
    82     //
    83     iDisplay.SwapBuffers();
    84 }
    85 
    86 void MiniDisplay::requestPowerStatus()
    87 {
    88     if (!iDisplay.IsOpen()) return;
    89 
    90     iDisplay.RequestPowerSupplyStatus();
    91     QTimer::singleShot(4, this, SLOT(readTimer()));
    92     iReadAttempt=0;
    93 }
    94 
    95 void MiniDisplay::requestDeviceId()
    96 {
    97     if (!iDisplay.IsOpen()) return;
    98 
    99     iDisplay.RequestDeviceId();
   100     QTimer::singleShot(4, this, SLOT(readTimer()));
   101     iReadAttempt=0;
   102 }
   103 
   104 void MiniDisplay::requestFirmwareVersion()
   105 {
   106     if (!iDisplay.IsOpen()) return;
   107 
   108     iDisplay.RequestFirmwareRevision();
   109     QTimer::singleShot(4, this, SLOT(readTimer()));
   110     iReadAttempt=0;
   111 }
   112 
   113 
   114 
   115 /**
   116  * @brief setFont
   117  * @param aFont
   118  */
   119 void MiniDisplay::setFont(const QFont& aFont)
   120 {
   121     iFont=aFont;
   122     iFont.setStyleStrategy(QFont::NoAntialias);
   123     QString strDemo="0123456789ABCDEF";
   124     QFontMetrics metrics(iFont);
   125     int w=metrics.boundingRect(strDemo).width();
   126     int h=metrics.height();
   127     //int h=metrics.boundingRect(strDemo).height();
   128     QSize size(w,h);
   129     //Rendering in mono is quite broken we need RGB32
   130     QImage image(size,QImage::Format_RGB32);
   131     image.fill(0xFFFFFFFF);
   132     //Draw some text into our image
   133     {
   134         QPainter painter(&image);
   135         painter.setPen(0xFF000000);
   136         painter.setFont(iFont);
   137         painter.drawText(0,metrics.ascent(),strDemo);
   138     }
   139     //Save image as PNG for validation
   140     //image.save("font.png");
   141     //
   142     renderImage(&image);
   143 }
   144 
   145 /**
   146  * @brief MiniDisplay::renderWindow
   147  */
   148 void MiniDisplay::renderOwnWindow()
   149 {
   150     QImage image=window()->grabWindow();
   151     //image.save("window.png");
   152     renderImage(&image);
   153 }
   154 
   155 /**
   156  * @brief MiniDisplay::render
   157  * @param aWindow
   158  */
   159 void MiniDisplay::renderWindow(QQuickWindow* aWindow)
   160 {
   161     //if (!iDisplay.IsOpen()) return;
   162 
   163     QImage image=aWindow->grabWindow();
   164     //image.save("window.png");
   165     renderImage(&image);
   166 }
   167 
   168 /**
   169  * @brief MiniDisplay::render
   170  * @param aImage
   171  */
   172 void MiniDisplay::renderImage(QImage* aImage)
   173 {
   174     if (!iDisplay.IsOpen())
   175     {
   176         return;
   177     }
   178 
   179     //Convert our image into a bit array
   180     int w=aImage->width();
   181     int h=aImage->height();
   182 
   183     int pixelCount=w*h;
   184     BitArray bits(pixelCount);
   185 
   186     for (int i=0;i<w;i++)
   187         {
   188         for (int j=0;j<h;j++)
   189             {
   190             QRgb color=aImage->pixel(i,j);
   191             if (color!=0xffffffff)
   192                 {
   193                 bits.SetBit(i*h+j);
   194                 }
   195             }
   196         }
   197 
   198     //Just blit it then
   199     iDisplay.BitBlit(bits,w,h,0,0);
   200 }
   201 
   202 
   203 /**
   204  * @brief MiniDisplay::connectWindow
   205  * @param aWindow
   206  */
   207 void MiniDisplay::connectWindow(QQuickWindow* aWindow, QJSValue aFunction)
   208 {
   209     QObject::connect(aWindow, SIGNAL(afterAnimating()),
   210                      this,  SLOT(onAfterAnimating()));
   211 
   212     iAfterAnimatingCallback = aFunction;
   213     iWindow = aWindow;
   214 }
   215 
   216 /**
   217  * @brief MiniDisplay::onAfterAnimating
   218  */
   219 void MiniDisplay::onAfterAnimating()
   220 {
   221     static int frame=0;
   222     //qDebug() << frame << "MiniDisplay::onAfterAnimating";
   223     /*
   224     if (iAfterAnimatingCallback.isCallable())
   225     {
   226         iAfterAnimatingCallback.call();
   227     }*/
   228 
   229     //renderWindow(iWindow);
   230     //swapBuffers();
   231 
   232 
   233     //Interrestingly rendering will suspend when we stop changing our text field content
   234     //if (frame%8==0)
   235     {
   236         if (iAfterAnimatingCallback.isCallable())
   237         {
   238             iAfterAnimatingCallback.call(QJSValueList() << frame);
   239         }
   240     }
   241 
   242     frame++;
   243 }
   244 
   245 
   246 /**
   247  * @brief MiniDisplay::setPixel
   248  * @param x
   249  * @param y
   250  * @param on
   251  */
   252 void MiniDisplay::setPixel(int x, int y, bool on)
   253 {
   254     if (!iDisplay.IsOpen())
   255     {
   256         return;
   257     }
   258 
   259     iDisplay.SetPixel(x,y,on);
   260 }
   261 
   262 /**
   263  * @brief MiniDisplay::offScreenMode
   264  * @return
   265  */
   266 bool MiniDisplay::offScreenMode()
   267 {
   268    return iDisplay.OffScreenMode();
   269 }
   270 
   271 /**
   272  * @brief MiniDisplay::setOffScreenMode
   273  * @param aOn
   274  */
   275 void MiniDisplay::setOffScreenMode(bool aOn)
   276 {
   277     if (!iDisplay.IsOpen())
   278     {
   279         return;
   280     }
   281 
   282     iDisplay.SetOffScreenMode(aOn);
   283 }
   284 
   285 
   286 
   287 
   288 /**
   289  * @brief MiniDisplay::vendor
   290  * @return
   291  */
   292 QString MiniDisplay::vendor()
   293 {
   294     return QString::fromWCharArray(iDisplay.Vendor());
   295 }
   296 
   297 /**
   298  * @brief MiniDisplay::product
   299  * @return
   300  */
   301 QString MiniDisplay::product()
   302 {
   303     return QString::fromWCharArray(iDisplay.Product());
   304 }
   305 
   306 /**
   307  * @brief MiniDisplay::serialNumber
   308  * @return
   309  */
   310 QString MiniDisplay::serialNumber()
   311 {
   312     return QString::fromWCharArray(iDisplay.SerialNumber());
   313 }
   314 
   315 /**
   316  * @brief MiniDisplay::readTimer
   317  * Called when our read timer completes.
   318  * We then attempt to complete our pending display request.
   319  * We typically attempt to read an input report from our HID device.
   320  */
   321 void MiniDisplay::readTimer()
   322 {
   323     if (!iDisplay.IsOpen()) return;
   324     if (!iDisplay.RequestPending()) return;
   325 
   326     iReadAttempt++;
   327     GP1212A01A::Request request = iDisplay.AttemptRequestCompletion();
   328 
   329     if (!request)
   330     {
   331         if (iReadAttempt<KMaxReadAttempt)
   332         {
   333             //Will try again later
   334             QTimer::singleShot(4, this, SLOT(readTimer()));
   335         }
   336 
   337         return;
   338     }
   339 
   340     //TODO: Find a way to remove device specific stuff from here
   341     if (request==GP1212A01A::ERequestFirmwareRevision)
   342     {
   343         QString version=QString::fromLocal8Bit((const char*)iDisplay.InputReport().Buffer()+1);
   344         emit firmwareVersion(version);
   345     }
   346     else if (request==GP1212A01A::ERequestDeviceId)
   347     {
   348         QString id=QString::fromLocal8Bit((const char*)iDisplay.InputReport().Buffer()+1);
   349         emit deviceId(id);
   350     }
   351     else if (request==GP1212A01A::ERequestPowerSupplyStatus)
   352     {
   353         emit powerStatus(iDisplay.PowerOn());
   354     }
   355 }
   356 
   357 
   358 int MiniDisplay::maxBrightness() const
   359 {
   360     return iDisplay.MaxBrightness();
   361 }
   362 
   363 int MiniDisplay::minBrightness() const
   364 {
   365     return iDisplay.MinBrightness();
   366 }
   367 
   368 int MiniDisplay::brightness() const
   369 {
   370     return iBrightness;
   371 }
   372 
   373 void MiniDisplay::setBrightness(int aBrightness)
   374 {
   375     //Still track the brightness when disconnected
   376     iBrightness=aBrightness;
   377 
   378     if (!iDisplay.IsOpen()) return;
   379 
   380     iDisplay.SetBrightness(aBrightness);
   381 }
   382 
   383 /**
   384 @brief MiniDisplay::frameDifferencing
   385 @return
   386 */
   387 bool MiniDisplay::frameDifferencing() const
   388 {
   389     return iDisplay.FrameDifferencing();
   390 }
   391 
   392 /**
   393 @brief MiniDisplay::setFrameDifferencing
   394 @param aOn
   395 */
   396 void MiniDisplay::setFrameDifferencing(bool aOn)
   397 {
   398     iDisplay.SetFrameDifferencing(aOn);
   399 }
   400 
   401 
   402 QPoint MiniDisplay::framePosition() const
   403 {
   404     return QPoint(iDisplay.DisplayPositionX(),iDisplay.DisplayPositionX());
   405 }
   406 
   407 void MiniDisplay::setFramePosition(const QPoint& aPoint)
   408 {
   409     iFramePosition = aPoint;
   410 
   411     if (!iDisplay.IsOpen()) return;
   412 
   413     iDisplay.SetDisplayPosition(aPoint.x(),aPoint.y());
   414 }
   415 
   416 
   417