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