diff --git a/casinocoin-qt.pro b/casinocoin-qt.pro index 012f6ee..e8e3db5 100644 --- a/casinocoin-qt.pro +++ b/casinocoin-qt.pro @@ -3,7 +3,7 @@ TARGET = casinocoin-qt macx:TARGET = "CasinoCoin-Qt" VERSION = 1.3.0.0 INCLUDEPATH += src src/json src/qt -QT += core gui network +QT += core gui network quick greaterThan(QT_MAJOR_VERSION, 4): QT += widgets DEFINES += QT_GUI BOOST_THREAD_USE_LIB BOOST_SPIRIT_THREADSAFE USE_IPV6 __NO_SYSTEM_INCLUDES CONFIG += no_include_pwd @@ -259,7 +259,20 @@ HEADERS += src/qt/bitcoingui.h \ src/threadsafety.h \ src/limitedmap.h \ src/qt/macnotificationhandler.h \ - src/qt/splashscreen.h + src/qt/splashscreen.h \ + src/qt/CSCPublicAPI/casinocoinwebapi.h \ + src/qt/CSCPublicAPI/casinocoinwebapiparser.h \ + src/qt/CSCPublicAPI/jsonactivepromotionsparser.h \ + src/qt/CSCPublicAPI/jsonsingleactivepromotion.h \ + src/qt/qtquick_controls/cpp/guibannercontrol.h \ + src/qt/qtquick_controls/cpp/guibannerlistview.h \ + src/qt/qtquick_controls/cpp/guibannerwidget.h \ + src/qt/qtquick_controls/cpp/listiteminterface.h \ + src/qt/qtquick_controls/cpp/qmlbannerlistitem.h \ + src/qt/qtquick_controls/cpp/qmlbannerlistmodel.h \ + src/qt/qtquick_controls/cpp/qmlimageprovider.h \ + src/qt/qtquick_controls/cpp/qmllistitem.h \ + src/qt/qtquick_controls/cpp/qmllistmodel.h SOURCES += src/qt/bitcoin.cpp \ src/qt/bitcoingui.cpp \ @@ -330,7 +343,19 @@ SOURCES += src/qt/bitcoin.cpp \ src/noui.cpp \ src/leveldb.cpp \ src/txdb.cpp \ - src/qt/splashscreen.cpp + src/qt/splashscreen.cpp \ + src/qt/CSCPublicAPI/casinocoinwebapi.cpp \ + src/qt/CSCPublicAPI/casinocoinwebapiparser.cpp \ + src/qt/CSCPublicAPI/jsonactivepromotionsparser.cpp \ + src/qt/CSCPublicAPI/jsonsingleactivepromotion.cpp \ + src/qt/qtquick_controls/cpp/guibannercontrol.cpp \ + src/qt/qtquick_controls/cpp/guibannerlistview.cpp \ + src/qt/qtquick_controls/cpp/guibannerwidget.cpp \ + src/qt/qtquick_controls/cpp/qmlbannerlistitem.cpp \ + src/qt/qtquick_controls/cpp/qmlbannerlistmodel.cpp \ + src/qt/qtquick_controls/cpp/qmlimageprovider.cpp \ + src/qt/qtquick_controls/cpp/qmllistitem.cpp \ + src/qt/qtquick_controls/cpp/qmllistmodel.cpp RESOURCES += src/qt/bitcoin.qrc @@ -403,7 +428,10 @@ OTHER_FILES += README.md \ src/test/*.cpp \ src/test/*.h \ src/qt/test/*.cpp \ - src/qt/test/*.h + src/qt/test/*.h \ + src/qt/qtquick_controls/qml/QmlGUIBannerControl.qml \ + src/qt/qtquick_controls/qml/QmlGUIBannerListView.qml \ + src/qt/qtquick_controls/qml/QmlGUIBannerWindow.qml # platform specific defaults, if not overridden on command line isEmpty(BOOST_LIB_SUFFIX) { diff --git a/src/qt/CSCPublicAPI/casinocoinwebapi.cpp b/src/qt/CSCPublicAPI/casinocoinwebapi.cpp new file mode 100644 index 0000000..18732ef --- /dev/null +++ b/src/qt/CSCPublicAPI/casinocoinwebapi.cpp @@ -0,0 +1,52 @@ +#include "casinocoinwebapi.h" + +#include + +const QString CasinoCoinWebAPI::s_strServerAddress = "http://119.81.188.59/"; +const QString CasinoCoinWebAPI::s_strServerEndpoint = "CSCPublicAPI"; + +CasinoCoinWebAPI::CasinoCoinWebAPI( QObject*a_pParent ) + : QObject(a_pParent ) +{ + connect( &m_oNetworkAccessManager, SIGNAL(finished(QNetworkReply*)), this, SLOT(slotParseNetworkResponse(QNetworkReply*))); +} + +void CasinoCoinWebAPI::GetActivePromotions() +{ + Get( s_strServerAddress + "/" + s_strServerEndpoint + "/ActivePromotions" ); +} + +void CasinoCoinWebAPI::GetActiveCasinos() +{ + Get( s_strServerAddress + "/" + s_strServerEndpoint + "/ActiveCasinos" ); +} + +void CasinoCoinWebAPI::GetActiveNewsItems() +{ + Get( s_strServerAddress + "/" + s_strServerEndpoint + "/ActiveNewsItems" ); +} + +void CasinoCoinWebAPI::GetActiveExchanges() +{ + Get( s_strServerAddress + "/" + s_strServerEndpoint + "/ActiveExchanges" ); +} + +void CasinoCoinWebAPI::Get( const QString& a_rUrl ) +{ + QUrl oUrl ( a_rUrl ); + QNetworkRequest oNetworkRequest ( oUrl ); + m_oNetworkAccessManager.get( oNetworkRequest ); +} + +void CasinoCoinWebAPI::slotParseNetworkResponse( QNetworkReply *finished ) +{ + if ( finished->error() != QNetworkReply::NoError ) + { + // A communication error has occurred + emit signalNetworkError( finished->error() ); + return; + } + + QByteArray data = finished->readAll(); + emit signalResponseReady( data ); +} diff --git a/src/qt/CSCPublicAPI/casinocoinwebapi.h b/src/qt/CSCPublicAPI/casinocoinwebapi.h new file mode 100644 index 0000000..38359eb --- /dev/null +++ b/src/qt/CSCPublicAPI/casinocoinwebapi.h @@ -0,0 +1,37 @@ +#ifndef CASINOCOINWEBAPI_H +#define CASINOCOINWEBAPI_H + +#include + +#include +#include + +class CasinoCoinWebAPI : public QObject +{ + Q_OBJECT +public: + explicit CasinoCoinWebAPI( QObject* a_pParent = 0 ); + virtual ~CasinoCoinWebAPI(){} + + void GetActivePromotions(); + void GetActiveCasinos(); + void GetActiveNewsItems(); + void GetActiveExchanges(); + + static const QString s_strServerAddress; + static const QString s_strServerEndpoint; + +signals: + void signalResponseReady( const QByteArray& a_rJsonFile ); + void signalNetworkError( QNetworkReply::NetworkError a_eError ); + +public slots: + void slotParseNetworkResponse( QNetworkReply *finished ); + +private: + void Get( const QString& a_rUrl ); + + QNetworkAccessManager m_oNetworkAccessManager; +}; + +#endif // CASINOCOINWEBAPI_H diff --git a/src/qt/CSCPublicAPI/casinocoinwebapiparser.cpp b/src/qt/CSCPublicAPI/casinocoinwebapiparser.cpp new file mode 100644 index 0000000..05202a7 --- /dev/null +++ b/src/qt/CSCPublicAPI/casinocoinwebapiparser.cpp @@ -0,0 +1,66 @@ +#include "casinocoinwebapiparser.h" + +#include +#include +#include + +#include + +CasinoCoinWebAPIParser::CasinoCoinWebAPIParser( QObject* a_pParent ) + : QObject(a_pParent) +{ +} + +void CasinoCoinWebAPIParser::slotParseAnswer( const QByteArray& a_rJsonFile ) +{ + QJsonParseError oError; + QJsonDocument jsonDoc = QJsonDocument::fromJson( a_rJsonFile, &oError ); + if ( oError.error == QJsonParseError::NoError ) + { + QJsonObject docAsObject = jsonDoc.object(); + if ( docAsObject.find( "Result" ).value().isObject() ) + { + QJsonObject jsonObjectResult = docAsObject.find( "Result" ).value().toObject(); + if ( jsonObjectResult.find( "ActivePromotions" ).value().isArray() ) + { + ParsePromotions( docAsObject ); + } + else if ( jsonObjectResult.find( "ActiveNewsItems" ).value().isArray() ) + { + ParseNewsItems( docAsObject ); + } + else if ( jsonObjectResult.find( "ActiveCasinos" ).value().isArray() ) + { + ParseCasinos( docAsObject ); + } + else if ( jsonObjectResult.find( "ActiveExchanges" ).value().isArray() ) + { + ParseExchanges( docAsObject ); + } + } + } +} + +void CasinoCoinWebAPIParser::ParsePromotions( const QJsonObject& a_rJsonPromotions ) +{ + qDebug() << "ParsePromotions"; + emit signalActivePromotionsParsed( new JsonActivePromotionsParser( a_rJsonPromotions ) ); +} + +void CasinoCoinWebAPIParser::ParseCasinos( const QJsonObject& a_rJsonCasinos ) +{ + qDebug() << "Coming soon - ParseCasinos"; + qDebug() << a_rJsonCasinos; +} + +void CasinoCoinWebAPIParser::ParseExchanges( const QJsonObject& a_rJsonExchanges ) +{ + qDebug() << "Coming soon - ParseExchanges"; + qDebug() << a_rJsonExchanges; +} + +void CasinoCoinWebAPIParser::ParseNewsItems( const QJsonObject& a_rJsonNewsItems ) +{ + qDebug() << "Coming soon - ParseNewsItems"; + qDebug() << a_rJsonNewsItems; +} diff --git a/src/qt/CSCPublicAPI/casinocoinwebapiparser.h b/src/qt/CSCPublicAPI/casinocoinwebapiparser.h new file mode 100644 index 0000000..3ca8bb4 --- /dev/null +++ b/src/qt/CSCPublicAPI/casinocoinwebapiparser.h @@ -0,0 +1,32 @@ +#ifndef CASINOCOINWEBAPIPARSER_H +#define CASINOCOINWEBAPIPARSER_H + +#include + +#include "jsonactivepromotionsparser.h" +#include "jsonsingleactivepromotion.h" + +class CasinoCoinWebAPIParser : public QObject +{ + Q_OBJECT +public: + explicit CasinoCoinWebAPIParser( QObject* a_pParent = 0 ); + + +signals: + void signalActivePromotionsParsed( JsonActivePromotionsParser* a_pActivePromotions ); +// void signalActiveCasinosParsed( JsonActiveCasinosParser* a_pActivePromotions ); +// void signalActiveExchangesParsed( JsonActiveExchangesParser* a_pActivePromotions ); +// void signalActiveNewsItemsParsed( JsonActiveNewsItemsParser* a_pActivePromotions ); + +public slots: + void slotParseAnswer( const QByteArray& a_rJsonFile ); + +private: + void ParsePromotions( const QJsonObject& a_rJsonPromotions ); + void ParseCasinos ( const QJsonObject& a_rJsonCasinos ); + void ParseExchanges ( const QJsonObject& a_rJsonExchanges ); + void ParseNewsItems ( const QJsonObject& a_rJsonNewsItems ); +}; + +#endif // CASINOCOINWEBAPIPARSER_H diff --git a/src/qt/CSCPublicAPI/jsonactivepromotionsparser.cpp b/src/qt/CSCPublicAPI/jsonactivepromotionsparser.cpp new file mode 100644 index 0000000..0cfb464 --- /dev/null +++ b/src/qt/CSCPublicAPI/jsonactivepromotionsparser.cpp @@ -0,0 +1,42 @@ +#include "jsonactivepromotionsparser.h" + +#include + +JsonActivePromotionsParser::JsonActivePromotionsParser() +{ + +} + +JsonActivePromotionsParser::JsonActivePromotionsParser( const QJsonObject& a_rOther ) + : QJsonObject( a_rOther ) +{ + ResolvePromotionsArray(); +} + +void JsonActivePromotionsParser::ResolvePromotionsArray() +{ + if ( find( "Result" ).value().isObject() ) + { + if ( find( "Result" ).value().toObject().find( "ActivePromotions" ).value().isArray() ) + { + QJsonArray arrayOfCasinoDescriptors( find( "Result" ).value().toObject().find( "ActivePromotions" ).value().toArray() ); + foreach( QJsonValue singleCasinoDescriptor, arrayOfCasinoDescriptors ) + { + if ( singleCasinoDescriptor.isObject() ) + { + m_aActiveCasinos.append( JsonSingleActivePromotion( singleCasinoDescriptor.toObject() ) ); + } + } + } + } +} + +const QList& JsonActivePromotionsParser::GetPromotions() const +{ + return m_aActiveCasinos; +} + +QList& JsonActivePromotionsParser::GetPromotions() +{ + return m_aActiveCasinos; +} diff --git a/src/qt/CSCPublicAPI/jsonactivepromotionsparser.h b/src/qt/CSCPublicAPI/jsonactivepromotionsparser.h new file mode 100644 index 0000000..bad1b23 --- /dev/null +++ b/src/qt/CSCPublicAPI/jsonactivepromotionsparser.h @@ -0,0 +1,27 @@ +#ifndef JSONACTIVEPROMOTIONSPARSER_H +#define JSONACTIVEPROMOTIONSPARSER_H + +#include +#include +#include +#include + +#include "jsonsingleactivepromotion.h" + +class JsonActivePromotionsParser : public QJsonObject +{ +public: + JsonActivePromotionsParser(); + JsonActivePromotionsParser( const QJsonObject& a_rOther ); + virtual ~JsonActivePromotionsParser(){} + + const QList& GetPromotions() const; + QList& GetPromotions(); +private: + + void ResolvePromotionsArray(); + + QList m_aActiveCasinos; +}; + +#endif // JSONACTIVEPROMOTIONSPARSER_H diff --git a/src/qt/CSCPublicAPI/jsonsingleactivepromotion.cpp b/src/qt/CSCPublicAPI/jsonsingleactivepromotion.cpp new file mode 100644 index 0000000..3f7ae8d --- /dev/null +++ b/src/qt/CSCPublicAPI/jsonsingleactivepromotion.cpp @@ -0,0 +1,53 @@ +#include "jsonsingleactivepromotion.h" + +#include +#include +#include + +#include + +JsonSingleActivePromotion::JsonSingleActivePromotion() +{ + +} + +JsonSingleActivePromotion::JsonSingleActivePromotion( const QJsonObject& a_rOther ) + : QJsonObject( a_rOther ) +{ + StoreImage(); +} + +QString JsonSingleActivePromotion::GetImagePath() const +{ + return QString( "file://" + QDir::currentPath() + "/" + GetImageRelativePath() ); +} + +QString JsonSingleActivePromotion::GetImageRelativePath() const +{ + return QString( "adverts/" + find( "promotion_title" ).value().toString().remove( " " ) + "." + find( "image_mime_type" ).value().toString().split( "/" ).last() ); +} + +QString JsonSingleActivePromotion::StoreImage() +{ + QString strReturn = QString(); + if ( find( "image_mime_type" ).value().toString().split( "/" ).first().contains( "image" ) ) + { + QString strFileName = GetImageRelativePath(); + QByteArray binaryData = QByteArray::fromBase64( find( "promotion_image" ).value().toString().toLocal8Bit() ); + + if ( !QDir( "adverts" ).exists() ) + { + QDir().mkdir( "adverts" ); + } + QFile imageOutputFile( strFileName ); + QImage outputImage = QImage::fromData( binaryData, "JPEG" ); + if ( imageOutputFile.open( QIODevice::WriteOnly | QIODevice::Truncate ) ) + { + outputImage.save( &imageOutputFile, 0 ); + imageOutputFile.close(); + strReturn = strFileName; + } + } + return strReturn; +} + diff --git a/src/qt/CSCPublicAPI/jsonsingleactivepromotion.h b/src/qt/CSCPublicAPI/jsonsingleactivepromotion.h new file mode 100644 index 0000000..b2429b1 --- /dev/null +++ b/src/qt/CSCPublicAPI/jsonsingleactivepromotion.h @@ -0,0 +1,22 @@ +#ifndef JSONSINGLEACTIVEPROMOTION_H +#define JSONSINGLEACTIVEPROMOTION_H + +#include +#include +#include + +class JsonSingleActivePromotion : public QJsonObject +{ +public: + JsonSingleActivePromotion(); + JsonSingleActivePromotion( const QJsonObject& a_rOther ); + virtual ~JsonSingleActivePromotion(){} + + QString GetImagePath() const; + +private: + QString GetImageRelativePath() const; + QString StoreImage(); +}; + +#endif // JSONSINGLEACTIVEPROMOTION_H diff --git a/src/qt/bitcoin.qrc b/src/qt/bitcoin.qrc index 57c1ace..2daf3c0 100644 --- a/src/qt/bitcoin.qrc +++ b/src/qt/bitcoin.qrc @@ -1,4 +1,4 @@ - + res/icons/bitcoin.png res/icons/address-book.png @@ -40,6 +40,10 @@ res/icons/filesave.png res/icons/qrcode.png res/icons/debugwindow.png + res/icons/adverts_arrow_left.png + res/icons/adverts_arrow_left_hover.png + res/icons/adverts_arrow_right.png + res/icons/adverts_arrow_right_hover.png res/images/about.png @@ -99,4 +103,9 @@ locale/bitcoin_zh_CN.qm locale/bitcoin_zh_TW.qm + + qtquick_controls/qml/QmlGUIBannerControl.qml + qtquick_controls/qml/QmlGUIBannerListView.qml + qtquick_controls/qml/QmlGUIBannerWindow.qml + diff --git a/src/qt/forms/overviewpage.ui b/src/qt/forms/overviewpage.ui index e1dc0b1..870b030 100644 --- a/src/qt/forms/overviewpage.ui +++ b/src/qt/forms/overviewpage.ui @@ -6,8 +6,8 @@ 0 0 - 573 - 342 + 782 + 406 @@ -36,6 +36,18 @@ + + + 470 + 0 + + + + + 470 + 16777215 + + QFrame::NoFrame @@ -101,7 +113,7 @@ 12 - + Balance: @@ -124,13 +136,16 @@ 0 CSC + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse - + Unconfirmed: @@ -153,6 +168,9 @@ 0 CSC + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse @@ -179,54 +197,76 @@ 0 CSC + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse + + + + + 150 + 30 + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + Hide all advertisements (temporary) + + + false + + + false + + + true + + + + + + - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - - - :/images/backg - - - false - - - Qt::AlignCenter - - - -2 - - - + + + 150 + 0 + + QFrame::NoFrame diff --git a/src/qt/overviewpage.cpp b/src/qt/overviewpage.cpp index ad2d682..269f88f 100644 --- a/src/qt/overviewpage.cpp +++ b/src/qt/overviewpage.cpp @@ -9,6 +9,7 @@ #include "transactionfilterproxy.h" #include "guiutil.h" #include "guiconstants.h" +#include "qtquick_controls/cpp/guibannerwidget.h" #include #include @@ -100,9 +101,11 @@ OverviewPage::OverviewPage(QWidget *parent) : currentUnconfirmedBalance(-1), currentImmatureBalance(-1), txdelegate(new TxViewDelegate()), - filter(0) + filter(0), + advertsWidget(0) { ui->setupUi(this); + createAdvertsWidget(); // Recent transactions ui->listTransactions->setItemDelegate(txdelegate); @@ -145,7 +148,16 @@ void OverviewPage::setBalance(qint64 balance, qint64 unconfirmedBalance, qint64 // for the non-mining users bool showImmature = immatureBalance != 0; ui->labelImmature->setVisible(showImmature); - ui->labelImmatureText->setVisible(showImmature); + ui->labelImmatureText->setVisible(showImmature); +} + +void OverviewPage::createAdvertsWidget() +{ + advertsWidget = new GUIBannerWidget( this ); + ui->verticalLayoutAdvertWidget->addWidget( advertsWidget->dockQmlToWidget(), Qt::AlignCenter ); + // first load from local files as its faster, than look for new ads in CasinoCoinAPI +// advertsWidget->PopulateBannerLocally(); + advertsWidget->PopulateBannerFromWeb(); } void OverviewPage::setClientModel(ClientModel *model) @@ -211,3 +223,24 @@ void OverviewPage::showOutOfSyncWarning(bool fShow) ui->labelWalletStatus->setVisible(fShow); ui->labelTransactionsStatus->setVisible(fShow); } + + +void OverviewPage::on_pushButtonToggleAdverts_clicked() +{ + if ( ui->verticalLayoutAdvertWidget->itemAt( 0 ) ) + { + QWidget* pAdvertWidget = ui->verticalLayoutAdvertWidget->itemAt( 0 )->widget(); + if ( pAdvertWidget ) + { + pAdvertWidget->setVisible( !pAdvertWidget->isVisible() ); + if ( pAdvertWidget->isVisible() ) + { + ui->pushButtonToggleAdverts->setText( tr( "Hide all advertisements" ) ); + } + else + { + ui->pushButtonToggleAdverts->setText( tr( "Show advertisements" ) ); + } + } + } +} diff --git a/src/qt/overviewpage.h b/src/qt/overviewpage.h index 59ba3c6..9ffdcc0 100644 --- a/src/qt/overviewpage.h +++ b/src/qt/overviewpage.h @@ -10,6 +10,7 @@ class ClientModel; class WalletModel; class TxViewDelegate; class TransactionFilterProxy; +class GUIBannerWidget; QT_BEGIN_NAMESPACE class QModelIndex; @@ -45,10 +46,15 @@ private: TxViewDelegate *txdelegate; TransactionFilterProxy *filter; + GUIBannerWidget* advertsWidget; + /** Create widget to populate adverts */ + void createAdvertsWidget(); + private slots: void updateDisplayUnit(); void handleTransactionClicked(const QModelIndex &index); void updateAlerts(const QString &warnings); + void on_pushButtonToggleAdverts_clicked(); }; #endif // OVERVIEWPAGE_H diff --git a/src/qt/qtquick_controls/cpp/guibannercontrol.cpp b/src/qt/qtquick_controls/cpp/guibannercontrol.cpp new file mode 100644 index 0000000..50cd75a --- /dev/null +++ b/src/qt/qtquick_controls/cpp/guibannercontrol.cpp @@ -0,0 +1,51 @@ +#include "guibannercontrol.h" +#include "guibannerlistview.h" +#include "qmlbannerlistmodel.h" +#include "qmlbannerlistitem.h" + +GUIBannerControl::GUIBannerControl( QQuickItem* a_pParent ) + : QQuickItem( a_pParent ) + , m_pAdvertsView( 0 ) +{ +} + +GUIBannerControl::~GUIBannerControl() +{ + if ( m_pAdvertsView ) + { + delete m_pAdvertsView; + m_pAdvertsView = 0; + } +} + +void GUIBannerControl::InitializeAdvertsView( GUIBannerListView* a_pView ) +{ + if ( a_pView ) + { + if ( m_pAdvertsView ) + { + delete m_pAdvertsView; + } + m_pAdvertsView = a_pView; + } +} + +void GUIBannerControl::slotPopulateFromWeb( JsonActivePromotionsParser* a_pActivePromotions ) +{ + if ( m_pAdvertsView ) + { + QmlBannerListModel* pAdvertsModel = new QmlBannerListModel( *a_pActivePromotions ); + m_pAdvertsView->SetModel( pAdvertsModel ); + } +} + +void GUIBannerControl::slotPopulateLocally() +{ + if ( m_pAdvertsView ) + { + QmlBannerListModel* pAdvertsModel = new QmlBannerListModel( 0 ); + m_pAdvertsView->SetModel( pAdvertsModel ); + qDebug() << "Coming soon"; + } +} + diff --git a/src/qt/qtquick_controls/cpp/guibannercontrol.h b/src/qt/qtquick_controls/cpp/guibannercontrol.h new file mode 100644 index 0000000..3812814 --- /dev/null +++ b/src/qt/qtquick_controls/cpp/guibannercontrol.h @@ -0,0 +1,32 @@ +#ifndef GUIBANNERCONTROL_H +#define GUIBANNERCONTROL_H + +#include + +#include "../../CSCPublicAPI/jsonactivepromotionsparser.h" + +class GUIBannerListView; + +class GUIBannerControl : public QQuickItem +{ + Q_OBJECT +public: + GUIBannerControl( QQuickItem* a_pParent = 0 ); + virtual ~GUIBannerControl(); + + Q_INVOKABLE void InitializeAdvertsView( GUIBannerListView* a_pView ); + GUIBannerListView* GetAdvertsView() const { return m_pAdvertsView; } + +public slots: + void slotPopulateFromWeb( JsonActivePromotionsParser* a_pActivePromotions ); + void slotPopulateLocally(); + +signals: + +public slots: + +private: + GUIBannerListView* m_pAdvertsView; +}; + +#endif // GUIBANNERCONTROL_H diff --git a/src/qt/qtquick_controls/cpp/guibannerlistview.cpp b/src/qt/qtquick_controls/cpp/guibannerlistview.cpp new file mode 100644 index 0000000..e8cc33f --- /dev/null +++ b/src/qt/qtquick_controls/cpp/guibannerlistview.cpp @@ -0,0 +1,50 @@ +#include "guibannerlistview.h" + +#include "qmlbannerlistitem.h" +#include "qmlbannerlistmodel.h" +#include "qmllistmodel.h" + +#include +#include + +GUIBannerListView::GUIBannerListView( QQuickItem* a_pParent ) + : QQuickItem( a_pParent ) + , m_pModel( 0 ) +{ +} + +void GUIBannerListView::Clear() +{ + if ( m_pModel ) + { + m_pModel->clear(); + } +} + +void GUIBannerListView::OnClicked( int a_iItemIndex ) +{ + if ( m_pModel ) + { + QString strUrl = m_pModel->GetData( a_iItemIndex, QmlBannerListItem::ROLE_DESTINATION_URL ).toString(); + QDesktopServices::openUrl( QUrl( strUrl ) ); + } +} + +GUIBannerListView::~GUIBannerListView() +{ + if ( m_pModel ) + { + delete m_pModel; + m_pModel = 0; + } +} + +void GUIBannerListView::SetModel( QmlBannerListModel* a_pModel ) +{ + if ( m_pModel ) + { + delete m_pModel; + } + m_pModel = a_pModel; + emit signalModelChanged(); +} diff --git a/src/qt/qtquick_controls/cpp/guibannerlistview.h b/src/qt/qtquick_controls/cpp/guibannerlistview.h new file mode 100644 index 0000000..592741e --- /dev/null +++ b/src/qt/qtquick_controls/cpp/guibannerlistview.h @@ -0,0 +1,35 @@ +#ifndef GUIBANNERLISTVIEW_H +#define GUIBANNERLISTVIEW_H + +#include + +class QmlListModel; +class QmlBannerListModel; +class QmlBannerListItem; + +class GUIBannerListView : public QQuickItem +{ + Q_OBJECT + Q_PROPERTY( QmlBannerListModel* p_pListModel MEMBER m_pModel NOTIFY signalModelChanged ) + +public: + explicit GUIBannerListView( QQuickItem *a_pParent = 0 ); + virtual ~GUIBannerListView(); /** Destructor **/ + + void SetModel( QmlBannerListModel* a_pModel ); + QmlBannerListModel* GetModel() const { return m_pModel; } + + void Clear(); + + Q_INVOKABLE void OnClicked( int a_iItemIndex ); +signals: + void signalModelChanged(); + +public slots: + +private: + + QmlBannerListModel* m_pModel; +}; + +#endif // GUIBANNERLISTVIEW_H diff --git a/src/qt/qtquick_controls/cpp/guibannerwidget.cpp b/src/qt/qtquick_controls/cpp/guibannerwidget.cpp new file mode 100644 index 0000000..9127f30 --- /dev/null +++ b/src/qt/qtquick_controls/cpp/guibannerwidget.cpp @@ -0,0 +1,88 @@ +#include "guibannerwidget.h" + +#include +#include +#include + +// qml +#include "guibannercontrol.h" +#include "guibannerlistview.h" +#include "qmlbannerlistmodel.h" +#include "qmlbannerlistitem.h" +#include "qmlimageprovider.h" + +// web +#include "../../CSCPublicAPI/casinocoinwebapi.h" +#include "../../CSCPublicAPI/casinocoinwebapiparser.h" + +GUIBannerWidget::GUIBannerWidget(QWidget *parent) + : QWidget(parent) + , m_pBannerControl( 0 ) + , m_pWebApiParserTemporary( new CasinoCoinWebAPIParser( this ) ) + , m_pWebApiTemporary( new CasinoCoinWebAPI( this ) ) +{ + registerCustomQmlTypes(); + connect( m_pWebApiTemporary, SIGNAL( signalResponseReady(const QByteArray&)), m_pWebApiParserTemporary, SLOT( slotParseAnswer(const QByteArray&)), Qt::UniqueConnection ); + connect( m_pWebApiTemporary, SIGNAL( signalNetworkError(QNetworkReply::NetworkError)), this, SLOT( slotNetworkError(QNetworkReply::NetworkError)), Qt::UniqueConnection ); +} + +GUIBannerWidget::~GUIBannerWidget() +{ + +} + +void GUIBannerWidget::registerCustomQmlTypes() +{ + qmlRegisterType("CasinoCoinControls", 1, 0, "GUIBannerControl" ); + qmlRegisterType("CasinoCoinControls", 1, 0, "GUIBannerListView" ); + qmlRegisterType("CasinoCoinControls", 1, 0, "QmlBannerListModel" ); + qmlRegisterType("CasinoCoinControls", 1, 0, "QmlImageProvider" ); +} + +QWidget* GUIBannerWidget::dockQmlToWidget() +{ + QQuickView* pBannerWindow = new QQuickView; + pBannerWindow->setSource( QUrl( QStringLiteral( "qrc:/qml/qtquick_controls/qml/QmlGUIBannerWindow.qml" ) ) ); + + QWidget* pPlaceHolder = QWidget::createWindowContainer( pBannerWindow, this ); + pPlaceHolder->setMinimumSize( 445, 120 ); + pPlaceHolder->setMaximumSize( 445, 120 ); + pPlaceHolder->setStyleSheet( "background-color: rgb(242, 241, 240);"); + QQuickItem* pRootObject = pBannerWindow->rootObject(); + if ( pRootObject ) + { + m_pBannerControl = pRootObject->findChild(); + if ( m_pBannerControl ) + { + if ( m_pWebApiParserTemporary ) + { + connect( m_pWebApiParserTemporary, SIGNAL( signalActivePromotionsParsed(JsonActivePromotionsParser*)), m_pBannerControl, SLOT( slotPopulateFromWeb(JsonActivePromotionsParser*)), Qt::UniqueConnection ); + } + m_pBannerControl->setWidth( ( 115 * 3 ) + ( 4 * 10 ) + 60 ); + m_pBannerControl->setHeight( 115 ); + } + } + + return pPlaceHolder; +} + +void GUIBannerWidget::PopulateBannerFromWeb() +{ + if ( m_pWebApiTemporary ) + { + m_pWebApiTemporary->GetActivePromotions(); + } +} + +void GUIBannerWidget::PopulateBannerLocally() +{ + if ( m_pBannerControl ) + { + m_pBannerControl->slotPopulateLocally(); + } +} + +void GUIBannerWidget::slotNetworkError( QNetworkReply::NetworkError a_eError ) +{ + PopulateBannerLocally(); +} diff --git a/src/qt/qtquick_controls/cpp/guibannerwidget.h b/src/qt/qtquick_controls/cpp/guibannerwidget.h new file mode 100644 index 0000000..e3a4e3e --- /dev/null +++ b/src/qt/qtquick_controls/cpp/guibannerwidget.h @@ -0,0 +1,36 @@ +#ifndef GUIBANNERWIDGET_H +#define GUIBANNERWIDGET_H + +#include +#include + +class CasinoCoinWebAPIParser; +class CasinoCoinWebAPI; +class GUIBannerControl; + +class GUIBannerWidget : public QWidget +{ + Q_OBJECT + +public: + GUIBannerWidget(QWidget *parent = 0); + ~GUIBannerWidget(); + + QWidget* dockQmlToWidget(); + + void PopulateBannerFromWeb(); + void PopulateBannerLocally(); + +private: + void registerCustomQmlTypes(); + + GUIBannerControl* m_pBannerControl; + + CasinoCoinWebAPIParser* m_pWebApiParserTemporary; + CasinoCoinWebAPI* m_pWebApiTemporary; + +private slots: + void slotNetworkError( QNetworkReply::NetworkError a_eError ); +}; + +#endif // GUIBANNERWIDGET_H diff --git a/src/qt/qtquick_controls/cpp/listiteminterface.h b/src/qt/qtquick_controls/cpp/listiteminterface.h new file mode 100644 index 0000000..4f2ecee --- /dev/null +++ b/src/qt/qtquick_controls/cpp/listiteminterface.h @@ -0,0 +1,19 @@ +#ifndef LISTITEMINTERFACE_H +#define LISTITEMINTERFACE_H + +#include + +class ListItemInterface : public QObject +{ + Q_OBJECT +public: + + ListItemInterface( QObject* a_pParent = 0 ) : QObject( a_pParent ){} /** Constructor **/ + virtual ~ListItemInterface() {} /** Destructor **/ + + virtual QVariant GetData( int a_iRole ) const = 0; /** Data Accesor **/ + virtual bool SetData( int a_iRole, QVariant a_variantData ) = 0; /** Sets given value at specified role **/ + virtual QHash RoleNames() const = 0; /** User roles in model **/ +}; + +#endif // LISTITEMINTERFACE_H diff --git a/src/qt/qtquick_controls/cpp/qmlbannerlistitem.cpp b/src/qt/qtquick_controls/cpp/qmlbannerlistitem.cpp new file mode 100644 index 0000000..e1245fe --- /dev/null +++ b/src/qt/qtquick_controls/cpp/qmlbannerlistitem.cpp @@ -0,0 +1,32 @@ +#include "qmlbannerlistitem.h" + +#include + +QmlBannerListItem::QmlBannerListItem(QString a_strImageSource, QString a_strDestinationUrl, QString a_strDescription, QObject* a_pParent ) + : QmlListItem( QVariant( a_strImageSource ), QVariant( a_strDestinationUrl ), QVariant( a_strDescription ), a_pParent ) +{ +} + +QmlBannerListItem::QmlBannerListItem( const JsonSingleActivePromotion& a_rCasinoDescription, QObject* a_pParent ) + : QmlListItem( QVariant( a_rCasinoDescription.GetImagePath() ), a_rCasinoDescription.find( "access_url" ).value().toVariant(), a_rCasinoDescription.find( "description" ).value().toVariant(), a_pParent ) +{ +} + +QmlBannerListItem::QmlBannerListItem( QObject* a_pParent ) + : QmlListItem( QVariant( "" ), QVariant( "" ), QVariant( "" ), a_pParent ) +{ +} + +QmlBannerListItem::~QmlBannerListItem() +{ + +} + +QHash QmlBannerListItem::RoleNames() const +{ + QHash aRoleNames; + aRoleNames[ROLE_IMAGE_SOURCE] = "m_imageSource"; + aRoleNames[ROLE_DESTINATION_URL] = "m_destinationUrl"; + aRoleNames[ROLE_DESCRIPTION] = "m_description"; + return aRoleNames; +} diff --git a/src/qt/qtquick_controls/cpp/qmlbannerlistitem.h b/src/qt/qtquick_controls/cpp/qmlbannerlistitem.h new file mode 100644 index 0000000..9647258 --- /dev/null +++ b/src/qt/qtquick_controls/cpp/qmlbannerlistitem.h @@ -0,0 +1,37 @@ +#ifndef QMLBANNERLISTITEM_H +#define QMLBANNERLISTITEM_H + +#include "qmllistitem.h" +#include "../../CSCPublicAPI/jsonsingleactivepromotion.h" + +class QmlBannerListItem : public QmlListItem +{ + Q_OBJECT +public: + enum EBannerRoles /** User-specific model roles **/ + { ROLE_IMAGE_SOURCE = ROLE_1 + , ROLE_DESTINATION_URL = ROLE_2 + , ROLE_DESCRIPTION = ROLE_3 + }; + + explicit QmlBannerListItem + ( QString a_strImageSource + , QString a_strDestinationUrl + , QString a_strDescription + , QObject *a_pParent = 0 + ); + explicit QmlBannerListItem ( const JsonSingleActivePromotion& a_rCasinoDescription + , QObject *a_pParent = 0 + ); + explicit QmlBannerListItem( QObject *a_pParent = 0 ); + virtual ~QmlBannerListItem(); + + virtual QHash RoleNames() const; /** Define class-specific roles **/ + +signals: + +public slots: + +}; + +#endif // QMLBANNERLISTITEM_H diff --git a/src/qt/qtquick_controls/cpp/qmlbannerlistmodel.cpp b/src/qt/qtquick_controls/cpp/qmlbannerlistmodel.cpp new file mode 100644 index 0000000..f726a6d --- /dev/null +++ b/src/qt/qtquick_controls/cpp/qmlbannerlistmodel.cpp @@ -0,0 +1,30 @@ +#include "qmlbannerlistmodel.h" + +#include "qmlbannerlistitem.h" + +#include "../../CSCPublicAPI/jsonactivepromotionsparser.h" +#include "../../CSCPublicAPI/jsonsingleactivepromotion.h" + +#include + +QmlBannerListModel::QmlBannerListModel( QObject* a_pParent ) + : QmlListModel( new QmlBannerListItem( 0 ), a_pParent ) +{ +} + +QmlBannerListModel::QmlBannerListModel + ( const JsonActivePromotionsParser& a_rActivePromotions + , QObject* a_pParent + ) + : QmlListModel( new QmlBannerListItem( 0 ), a_pParent ) +{ + foreach( const JsonSingleActivePromotion& rPromotion, a_rActivePromotions.GetPromotions() ) + { + append( new QmlBannerListItem( rPromotion, this ) ); + } +} + +QmlBannerListModel::~QmlBannerListModel() +{ + +} diff --git a/src/qt/qtquick_controls/cpp/qmlbannerlistmodel.h b/src/qt/qtquick_controls/cpp/qmlbannerlistmodel.h new file mode 100644 index 0000000..a42c95e --- /dev/null +++ b/src/qt/qtquick_controls/cpp/qmlbannerlistmodel.h @@ -0,0 +1,26 @@ +#ifndef QMLBANNERLISTMODEL_H +#define QMLBANNERLISTMODEL_H + +#include "qmllistmodel.h" + +class QmlBannerListItem; +class JsonActivePromotionsParser; + +class QmlBannerListModel : public QmlListModel +{ + Q_OBJECT +public: + explicit QmlBannerListModel( QObject* a_pParent = 0 ); + explicit QmlBannerListModel + ( const JsonActivePromotionsParser& a_rActivePromotions + , QObject* a_pParent = 0 + ); + virtual ~QmlBannerListModel(); /** Destructor **/ + +signals: + +public slots: + +}; + +#endif // QMLBANNERLISTMODEL_H diff --git a/src/qt/qtquick_controls/cpp/qmlimageprovider.cpp b/src/qt/qtquick_controls/cpp/qmlimageprovider.cpp new file mode 100644 index 0000000..fc052c8 --- /dev/null +++ b/src/qt/qtquick_controls/cpp/qmlimageprovider.cpp @@ -0,0 +1,39 @@ +#include "qmlimageprovider.h" + +QmlImageProvider::QmlImageProvider( QQuickItem* a_pParent ) + : QQuickPaintedItem( a_pParent ) +{ + +} + +QmlImageProvider::QmlImageProvider( const QImage& a_rImage, QQuickItem* a_pParent ) + : QQuickPaintedItem( a_pParent ) + , m_oImage( a_rImage ) +{ +} + +void QmlImageProvider::SetImage( const QImage& a_rImage ) +{ + if ( a_rImage != m_oImage ) + { + m_oImage = QImage( a_rImage ); + emit signalImageChanged(); + } +} + +void QmlImageProvider::paint( QPainter* a_pPainter ) +{ + if ( a_pPainter ) + { + a_pPainter->drawImage( QPoint( 0, 0 ), m_oImage ); + } +} + +void QmlImageProvider::paintImage( const QImage& a_rImage, QPainter* a_pPainter ) +{ + SetImage( a_rImage ); + if ( a_pPainter ) + { + a_pPainter->drawImage( QPoint( 0, 0 ), m_oImage ); + } +} diff --git a/src/qt/qtquick_controls/cpp/qmlimageprovider.h b/src/qt/qtquick_controls/cpp/qmlimageprovider.h new file mode 100644 index 0000000..e7b7c8d --- /dev/null +++ b/src/qt/qtquick_controls/cpp/qmlimageprovider.h @@ -0,0 +1,26 @@ +#ifndef QMLIMAGEPROVIDER_H +#define QMLIMAGEPROVIDER_H + +#include +#include +#include + +class QmlImageProvider : public QQuickPaintedItem +{ + Q_OBJECT + + Q_PROPERTY( QImage p_oImage MEMBER m_oImage NOTIFY signalImageChanged ) +public: + explicit QmlImageProvider( QQuickItem* a_pParent = 0 ); + explicit QmlImageProvider( const QImage& a_rImage, QQuickItem* a_pParent = 0 ); + + void SetImage( const QImage& a_rImage ); + virtual void paint( QPainter* a_pPainter ); + void paintImage( const QImage& a_rImage, QPainter* a_pPainter ); +signals: + void signalImageChanged(); +private: + QImage m_oImage; +}; + +#endif // QMLIMAGEPROVIDER_H diff --git a/src/qt/qtquick_controls/cpp/qmllistitem.cpp b/src/qt/qtquick_controls/cpp/qmllistitem.cpp new file mode 100644 index 0000000..a88bd52 --- /dev/null +++ b/src/qt/qtquick_controls/cpp/qmllistitem.cpp @@ -0,0 +1,196 @@ +#include "qmllistitem.h" + +#include + +QmlListItem::QmlListItem( QObject* a_pParent ) + : ListItemInterface( a_pParent ) +{ + // Nothing +} + +QmlListItem::QmlListItem( QVariant a_role1 + , QObject* a_pParent + ) + : ListItemInterface( a_pParent ) +{ + m_aDataHash[ROLE_1] = a_role1; +} + +QmlListItem::QmlListItem( QVariant a_role1 + , QVariant a_role2 + , QObject* a_pParent + ) + : ListItemInterface( a_pParent ) +{ + m_aDataHash[ROLE_1] = a_role1; + m_aDataHash[ROLE_2] = a_role2; +} + +QmlListItem::QmlListItem( QVariant a_role1 + , QVariant a_role2 + , QVariant a_role3 + , QObject* a_pParent + ) + : ListItemInterface( a_pParent ) +{ + m_aDataHash[ROLE_1] = a_role1; + m_aDataHash[ROLE_2] = a_role2; + m_aDataHash[ROLE_3] = a_role3; +} + +QmlListItem::QmlListItem( QVariant a_role1 + , QVariant a_role2 + , QVariant a_role3 + , QVariant a_role4 + , QObject* a_pParent + ) + : ListItemInterface( a_pParent ) +{ + m_aDataHash[ROLE_1] = a_role1; + m_aDataHash[ROLE_2] = a_role2; + m_aDataHash[ROLE_3] = a_role3; + m_aDataHash[ROLE_4] = a_role4; +} + +QmlListItem::QmlListItem( QVariant a_role1 + , QVariant a_role2 + , QVariant a_role3 + , QVariant a_role4 + , QVariant a_role5 + , QObject* a_pParent + ) + : ListItemInterface( a_pParent ) +{ + m_aDataHash[ROLE_1] = a_role1; + m_aDataHash[ROLE_2] = a_role2; + m_aDataHash[ROLE_3] = a_role3; + m_aDataHash[ROLE_4] = a_role4; + m_aDataHash[ROLE_5] = a_role5; +} + +QmlListItem::QmlListItem( QVariant a_role1 + , QVariant a_role2 + , QVariant a_role3 + , QVariant a_role4 + , QVariant a_role5 + , QVariant a_role6 + , QObject* a_pParent + ) + : ListItemInterface( a_pParent ) +{ + m_aDataHash[ROLE_1] = a_role1; + m_aDataHash[ROLE_2] = a_role2; + m_aDataHash[ROLE_3] = a_role3; + m_aDataHash[ROLE_4] = a_role4; + m_aDataHash[ROLE_5] = a_role5; + m_aDataHash[ROLE_6] = a_role6; +} + +QmlListItem::QmlListItem( QVariant a_role1 + , QVariant a_role2 + , QVariant a_role3 + , QVariant a_role4 + , QVariant a_role5 + , QVariant a_role6 + , QVariant a_role7 + , QObject* a_pParent + ) + : ListItemInterface( a_pParent ) +{ + m_aDataHash[ROLE_1] = a_role1; + m_aDataHash[ROLE_2] = a_role2; + m_aDataHash[ROLE_3] = a_role3; + m_aDataHash[ROLE_4] = a_role4; + m_aDataHash[ROLE_5] = a_role5; + m_aDataHash[ROLE_6] = a_role6; + m_aDataHash[ROLE_7] = a_role7; +} + +QmlListItem::QmlListItem( QVariant a_role1 + , QVariant a_role2 + , QVariant a_role3 + , QVariant a_role4 + , QVariant a_role5 + , QVariant a_role6 + , QVariant a_role7 + , QVariant a_role8 + , QObject* a_pParent + ) + : ListItemInterface( a_pParent ) +{ + m_aDataHash[ROLE_1] = a_role1; + m_aDataHash[ROLE_2] = a_role2; + m_aDataHash[ROLE_3] = a_role3; + m_aDataHash[ROLE_4] = a_role4; + m_aDataHash[ROLE_5] = a_role5; + m_aDataHash[ROLE_6] = a_role6; + m_aDataHash[ROLE_7] = a_role7; + m_aDataHash[ROLE_8] = a_role8; +} + +QmlListItem::QmlListItem( QVariant a_role1 + , QVariant a_role2 + , QVariant a_role3 + , QVariant a_role4 + , QVariant a_role5 + , QVariant a_role6 + , QVariant a_role7 + , QVariant a_role8 + , QVariant a_role9 + , QObject* a_pParent + ) + : ListItemInterface( a_pParent ) +{ + m_aDataHash[ROLE_1] = a_role1; + m_aDataHash[ROLE_2] = a_role2; + m_aDataHash[ROLE_3] = a_role3; + m_aDataHash[ROLE_4] = a_role4; + m_aDataHash[ROLE_5] = a_role5; + m_aDataHash[ROLE_6] = a_role6; + m_aDataHash[ROLE_7] = a_role7; + m_aDataHash[ROLE_8] = a_role8; + m_aDataHash[ROLE_9] = a_role9; +} + +QmlListItem::QmlListItem( const QmlListItem& a_rOther ) + : ListItemInterface( a_rOther.parent() ) + , m_aDataHash( a_rOther.m_aDataHash ) +{ + // Nothing +} + +QmlListItem::~QmlListItem() +{ + // Nothing +} + +QVariant QmlListItem::GetData( int a_iRole ) const +{ + return m_aDataHash[static_cast( a_iRole )]; +} + +bool QmlListItem::SetData( int a_iRole, QVariant a_variantData ) +{ + + if ( m_aDataHash[static_cast( a_iRole )] != a_variantData ) + { + m_aDataHash[static_cast( a_iRole )] = a_variantData; + return true; + } + return false; +} + +QHash QmlListItem::RoleNames() const +{ + QHash aRoleNames; + aRoleNames[ROLE_1] = "m_role1"; + aRoleNames[ROLE_2] = "m_role2"; + aRoleNames[ROLE_3] = "m_role3"; + aRoleNames[ROLE_4] = "m_role4"; + aRoleNames[ROLE_5] = "m_role5"; + aRoleNames[ROLE_6] = "m_role6"; + aRoleNames[ROLE_7] = "m_role7"; + aRoleNames[ROLE_8] = "m_role8"; + return aRoleNames; +} + diff --git a/src/qt/qtquick_controls/cpp/qmllistitem.h b/src/qt/qtquick_controls/cpp/qmllistitem.h new file mode 100644 index 0000000..1333473 --- /dev/null +++ b/src/qt/qtquick_controls/cpp/qmllistitem.h @@ -0,0 +1,109 @@ +#ifndef QMLLISTITEM_H +#define QMLLISTITEM_H + +// Qt +#include +#include +#include + +// ptcommon +#include "listiteminterface.h" + +class QmlListItem : public ListItemInterface +{ + Q_OBJECT + +public: + + enum ERoles /** User-specific model roles **/ + { ROLE_1 = Qt::UserRole + 1 + , ROLE_2 = Qt::UserRole + 2 + , ROLE_3 = Qt::UserRole + 3 + , ROLE_4 = Qt::UserRole + 4 + , ROLE_5 = Qt::UserRole + 5 + , ROLE_6 = Qt::UserRole + 6 + , ROLE_7 = Qt::UserRole + 7 + , ROLE_8 = Qt::UserRole + 8 + , ROLE_9 = Qt::UserRole + 9 + , ROLE_10 = Qt::UserRole + 10 + , ROLE_LAST = Qt::UserRole + 11 + }; + + explicit QmlListItem( QObject* a_pParent = 0 ); /** Default Constructor **/ + + explicit QmlListItem( QVariant a_role1 + , QObject* a_pParent = 0 + ); /** Constructor with first role filled **/ + explicit QmlListItem( QVariant a_role1 + , QVariant a_role2 + , QObject* a_pParent = 0 + ); /** Contstructor with first two roles filled **/ + explicit QmlListItem( QVariant a_role1 + , QVariant a_role2 + , QVariant a_role3 + , QObject* a_pParent = 0 + ); /** Contstructor with first three roles filled **/ + explicit QmlListItem( QVariant a_role1 + , QVariant a_role2 + , QVariant a_role3 + , QVariant a_role4 + , QObject* a_pParent = 0 + ); /** Contstructor with first four roles filled **/ + explicit QmlListItem( QVariant a_role1 + , QVariant a_role2 + , QVariant a_role3 + , QVariant a_role4 + , QVariant a_role5 + , QObject* a_pParent = 0 + ); /** Contstructor with first five roles filled **/ + explicit QmlListItem( QVariant a_role1 + , QVariant a_role2 + , QVariant a_role3 + , QVariant a_role4 + , QVariant a_role5 + , QVariant a_role6 + , QObject* a_pParent = 0 + ); /** Contstructor with first six roles filled **/ + explicit QmlListItem( QVariant a_role1 + , QVariant a_role2 + , QVariant a_role3 + , QVariant a_role4 + , QVariant a_role5 + , QVariant a_role6 + , QVariant a_role7 + , QObject* a_pParent = 0 + ); /** Contstructor with first seven roles filled **/ + explicit QmlListItem( QVariant a_role1 + , QVariant a_role2 + , QVariant a_role3 + , QVariant a_role4 + , QVariant a_role5 + , QVariant a_role6 + , QVariant a_role7 + , QVariant a_role8 + , QObject* a_pParent = 0 + ); /** Contstructor with first eight roles filled **/ + explicit QmlListItem( QVariant a_role1 + , QVariant a_role2 + , QVariant a_role3 + , QVariant a_role4 + , QVariant a_role5 + , QVariant a_role6 + , QVariant a_role7 + , QVariant a_role8 + , QVariant a_role9 + , QObject* a_pParent = 0 + ); /** Contstructor with first nine roles filled **/ + + QmlListItem( const QmlListItem& a_rOther ); /** Copy constructor **/ + virtual ~QmlListItem(); /** Destructor **/ + + virtual QVariant GetData( int a_iRole ) const; /** Retrieve role-specific data from class **/ + virtual bool SetData( int a_iRole, QVariant a_variantData ); /** Sets given value at specified role **/ + virtual QHash RoleNames() const; /** Define class-specific roles **/ + +private: + QHash m_aDataHash; /** Container keeping all item-specific roles **/ +}; + +#endif // QMLLISTITEM_H diff --git a/src/qt/qtquick_controls/cpp/qmllistmodel.cpp b/src/qt/qtquick_controls/cpp/qmllistmodel.cpp new file mode 100644 index 0000000..d701bc6 --- /dev/null +++ b/src/qt/qtquick_controls/cpp/qmllistmodel.cpp @@ -0,0 +1,315 @@ +#include "qmllistmodel.h" + +#include + +QmlListModel::QmlListModel( QObject* a_pParent ) + : QAbstractListModel( a_pParent ) + , m_pPrototype( 0 ) + , m_iCurrentElementIndex( -1 ) +{ + m_aItems = QList(); +} + +QmlListModel::QmlListModel( ListItemInterface* a_pPrototype, QObject* a_pParent ) + : QAbstractListModel( a_pParent ) + , m_pPrototype( a_pPrototype ) + , m_iCurrentElementIndex( -1 ) +{ + m_aItems = QList(); +} + +QmlListModel::~QmlListModel() +{ + clear(); + if ( m_pPrototype ) + { + delete m_pPrototype; + m_pPrototype = 0; + } +} + +int QmlListModel::rowCount( const QModelIndex& a_rParent ) const +{ + Q_UNUSED( a_rParent ); + return m_aItems.size(); +} + +QVariant QmlListModel::data( const QModelIndex& a_rIndex, int a_iRole ) const +{ + if ( a_rIndex.row() < 0 ) + { + return QVariant(); + } + if ( a_rIndex.row() > m_aItems.size() ) + { + return QVariant(); + } + ListItemInterface* pValidate = m_aItems.at( a_rIndex.row() ); + if ( pValidate ) + { + return pValidate->GetData( a_iRole ); + } + return QVariant(); +} + +bool QmlListModel::setData( const QModelIndex& a_rIndex, const QVariant& a_rValue, int a_iRole ) +{ + if ( a_rIndex.isValid() && a_iRole > Qt::UserRole ) + { + ListItemInterface* pItem = m_aItems.at( a_rIndex.row() ); + if ( pItem ) + { + if ( pItem->SetData( a_iRole, a_rValue ) ) + { + emit dataChanged( a_rIndex, a_rIndex ); + return true; + } + } + } + return false; +} + +QHash QmlListModel::roleNames() const //NS +{ + if ( m_pPrototype ) + { + return m_pPrototype->RoleNames(); + } + return ( QHash() ); +} + +bool QmlListModel::removeRows( int a_iRow, int a_iCount, const QModelIndex& a_rParent ) //NS +{ + if ( a_iRow < 0 ) + { + return false; + } + if ( a_iCount <= 0 ) + { + return false; + } + if ( ( a_iRow + a_iCount ) > m_aItems.size() ) + { + return false; + } + beginRemoveRows( a_rParent, a_iRow, a_iRow + a_iCount - 1 ); + for ( int i = 0; i < a_iCount; i++ ) + { + ListItemInterface* pItem = m_aItems.takeAt( a_iRow ); + delete pItem; + pItem = 0; + } + endRemoveRows(); + emit signalCountChanged( rowCount() ); + return true; +} + +void QmlListModel::append( ListItemInterface* a_pItem ) //NS +{ + if ( a_pItem != 0 ) + { + beginInsertRows( QModelIndex(), rowCount(), rowCount() ); + m_aItems.append( a_pItem ); + a_pItem->setObjectName( objectName() + "_item_" + QString::number( rowCount() ) ); + endInsertRows(); + emit signalCountChanged( rowCount() ); + } +} + +void QmlListModel::insert( int a_iIndex, ListItemInterface* a_pItem ) //NS +{ + if ( a_pItem != 0 && a_iIndex >= 0 && a_iIndex <= m_aItems.size() ) + { + beginInsertRows( QModelIndex(), a_iIndex, a_iIndex ); + m_aItems.insert( a_iIndex, a_pItem ); + a_pItem->setObjectName( objectName() + "_item_" + QString::number( a_iIndex ) ); + endInsertRows(); + emit signalCountChanged( rowCount() ); + } +} + +QVariant QmlListModel::get( int a_iIndex ) +{ + if ( a_iIndex < 0 ) + { + return QVariant(); + } + if ( a_iIndex >= m_aItems.size() ) + { + return QVariant(); + } + QMap aItemData; + ListItemInterface* pItem = m_aItems.at( a_iIndex ); + if ( pItem ) + { + QHashIterator aRolesItr( pItem->RoleNames() ); + while ( aRolesItr.hasNext() ) + { + aRolesItr.next(); + aItemData.insert( aRolesItr.value(), QVariant( pItem->GetData( aRolesItr.key() ) ) ); + } + return QVariant( aItemData ); + } + return QVariant(); +} + +void QmlListModel::clear() +{ + if ( m_aItems.size() > 0 ) + { + removeRows( 0, m_aItems.size() ); + // signalCountChanged emitted inside removeRows + } +} + +void QmlListModel::refresh() +{ + if ( m_aItems.size() > 0 ) + { + beginResetModel(); + endResetModel(); + } +} + +int QmlListModel::GetItemIndex( int a_iItemRole, QVariant a_variantValue ) const +{ + for ( int i = 0; i < m_aItems.size(); i++ ) + { + if ( m_aItems[i]->GetData( a_iItemRole ) == a_variantValue ) + { + return i; + } + } + return -1; +} + +ListItemInterface* QmlListModel::GetCurrentItem() const +{ + + if ( m_iCurrentElementIndex >= 0 && m_aItems.size() > m_iCurrentElementIndex ) + { + return m_aItems[m_iCurrentElementIndex]; + } + return 0; +} + +void QmlListModel::SetCurrentItemIndex( int a_iIndex ) +{ + + if ( a_iIndex == -1 + || ( a_iIndex >= 0 && a_iIndex < rowCount() ) + ) + { + if ( m_iCurrentElementIndex != a_iIndex ) + { + m_iCurrentElementIndex = a_iIndex; + emit signalCurrentItemIndexChanged(); + } + else + { + if ( m_iCurrentElementIndex != -1 ) + { + emit signalCurrentItemIndexClicked(); + } + } + } +} + +int QmlListModel::GetCurrentItemIndex() const +{ + return m_iCurrentElementIndex; +} + +bool QmlListModel::SetData( int a_iIndex, const QVariant& a_rValue, int a_iRole ) +{ + QModelIndex modelIndex = createIndex( a_iIndex, 0 ); + return setData( modelIndex, a_rValue, a_iRole ); +} + +QVariant QmlListModel::GetData( int a_iIndex, int a_iRole ) +{ + QModelIndex modelIndex = createIndex( a_iIndex, 0 ); + return data( modelIndex, a_iRole ); +} + +void QmlListModel::Sort( int a_iRole, Qt::SortOrder a_eOrder ) +{ + QList aSortedList; + + if ( a_eOrder == Qt::AscendingOrder ) + { + foreach ( ListItemInterface* pItem, m_aItems ) + { + int iSortedIndex = 0; + const int iSortedListCount = aSortedList.count(); + QVariant valueOriginal = pItem->GetData( a_iRole ); + + bool bIndexFound = false; + for ( iSortedIndex = iSortedListCount - 1 ; iSortedIndex >= 0 ; --iSortedIndex ) + { + const ListItemInterface* pSortedItem = aSortedList.at( iSortedIndex ); + if ( pSortedItem ) + { + QVariant valueSorted = pSortedItem->GetData( a_iRole ); + if ( Compare( a_iRole, valueOriginal, valueSorted ) > 0 ) + { + aSortedList.insert( iSortedIndex + 1, pItem ); + bIndexFound = true; + break; + } + } + } + if ( !bIndexFound ) + { + aSortedList.prepend( pItem ); + } + } + } + else if ( Qt::DescendingOrder ) + { + foreach ( ListItemInterface* pItem, m_aItems ) + { + int iSortedIndex = 0; + const int iSortedListCount = aSortedList.count(); + QVariant valueOriginal = pItem->GetData( a_iRole ); + + bool bIndexFound = false; + for ( iSortedIndex = 0 ; iSortedIndex < iSortedListCount ; ++iSortedIndex ) + { + const ListItemInterface* pSortedItem = aSortedList.at( iSortedIndex ); + if ( pSortedItem ) + { + QVariant valueSorted = pSortedItem->GetData( a_iRole ); + if ( Compare( a_iRole, valueOriginal, valueSorted ) > 0 ) + { + aSortedList.insert( iSortedIndex, pItem ); + bIndexFound = true; + break; + } + } + } + if ( !bIndexFound ) + { + aSortedList.append( pItem ); + } + } + } + m_aItems = aSortedList; + + emit dataChanged( createIndex( 0, 0 ), createIndex( rowCount() - 1, 0 ) ); +} + +int QmlListModel::Compare( int a_iRole, QVariant& a_rValue1, QVariant& a_rValue2 ) +{ + Q_UNUSED( a_iRole ); + int iReturn = 0; + if ( a_rValue1 > a_rValue2 ) + { + iReturn = 1; + } + else if ( a_rValue1 < a_rValue2 ) + { + iReturn = -1; + } + return iReturn; +} diff --git a/src/qt/qtquick_controls/cpp/qmllistmodel.h b/src/qt/qtquick_controls/cpp/qmllistmodel.h new file mode 100644 index 0000000..c755b32 --- /dev/null +++ b/src/qt/qtquick_controls/cpp/qmllistmodel.h @@ -0,0 +1,83 @@ +#ifndef QMLLISTMODEL_H +#define QMLLISTMODEL_H + +#include +#include + +#include "qmllistitem.h" + +class QmlListModel : public QAbstractListModel +{ + Q_OBJECT + + Q_PROPERTY( int count READ rowCount NOTIFY signalCountChanged ) + Q_PROPERTY( int p_iCurrentElementIndex MEMBER m_iCurrentElementIndex NOTIFY signalCurrentItemIndexChanged ) +public: + ////////////////// + // Methods + explicit QmlListModel( QObject* a_pParent = 0 ); /** Default Constructor **/ + explicit QmlListModel( ListItemInterface* a_pPrototype, QObject* a_pParent = 0 ); /** Constructor with item prototype **/ + virtual ~QmlListModel(); /** Destructor **/ + + int rowCount( const QModelIndex& a_rParent = QModelIndex() ) const; /** size of list getter **/ + QVariant data( const QModelIndex& a_rIndex, int a_iRole = Qt::DisplayRole ) const; /** function returning model data at specific index **/ + virtual bool setData /** Sets the role data for the item at index to value. **/ + ( const QModelIndex& a_rIndex + , const QVariant& a_rValue + , int a_iRole = Qt::EditRole + ); + QHash roleNames() const; /** returns user defined roles for model **/ + bool removeRows( int a_iRow, int a_iCount, const QModelIndex& a_rParent = QModelIndex() ); /** deletes /count/ rows from model starting at /row/ **/ + + // Methods created to match QML Model style of data manipulation + Q_INVOKABLE void append( ListItemInterface* a_pItem ); /** appends /a_pItem/ element to the list **/ + Q_INVOKABLE void insert( int a_iIndex, ListItemInterface* a_pItem ); /** insert /a_pItem/ to the list before the given /a_iIndex/ **/ + Q_INVOKABLE QVariant get( int a_iIndex ); /** returns QMap containing value<->role pa at /a_iIndex/ **/ + Q_INVOKABLE void clear(); /** clears the list **/ + Q_INVOKABLE void refresh(); /** refreshes the list **/ + + inline const ListItemInterface* GetItem( int a_iIndex ) const; /** Get item at index **/ + int GetItemIndex( int a_iItemRole, QVariant a_variantValue ) const; /** Get index of first item having given a_variantValue at given a_iItemRole **/ + + /** NOTE!! + This three methods have their implementation, however whole + currentItem system must be implemented manually for every derived class. **/ + ListItemInterface* GetCurrentItem() const; /** Get current item pointer **/ + virtual void SetCurrentItemIndex( int a_iIndex ); /** Set current item index **/ + int GetCurrentItemIndex() const; /** Get current item index **/ + + bool SetData( int a_iIndex, const QVariant& a_rValue, int a_iRole ); /** Sets the role data for the item at index to value. **/ + QVariant GetData( int a_iIndex, int a_iRole ); /** Get model data at specific index **/ + + void Sort( int a_iRole, Qt::SortOrder a_eOrder = Qt::AscendingOrder ); /** Sort items in list model by role in the given order **/ + +signals: + void signalCountChanged( int a_iNewCount ); /** notify that list contents changed **/ + void signalCurrentItemIndexChanged(); /** notify that currently highlighted/focused item changed **/ + void signalCurrentItemIndexClicked(); /** notify that currently highlighted/focused item was clicked again **/ + void signalTextColorCol1Changed(); /** notify that text color in col1 changed **/ + void signalTextSizeChanged(); /** notify that text size changed **/ + void signalRowHeightChanged(); /** notify that row height changed **/ +protected: + ///////////////// + // Methods + virtual int Compare( int a_iRole, QVariant& a_rValue1, QVariant& a_rValue2 ); /** Compare two values with given role **/ + + ////////////////// + // Properties + ListItemInterface* m_pPrototype; /** information on what type is held in a list **/ + QList m_aItems; /** list with model data **/ + int m_iCurrentElementIndex; /** current element index **/ +}; + +const ListItemInterface* QmlListModel::GetItem( int a_iIndex ) const +{ + if ( m_aItems.size() > a_iIndex && a_iIndex >= 0 ) + { + return m_aItems[a_iIndex]; + } + return 0; +} + + +#endif // QMLLISTMODEL_H diff --git a/src/qt/qtquick_controls/qml/QmlGUIBannerControl.qml b/src/qt/qtquick_controls/qml/QmlGUIBannerControl.qml new file mode 100644 index 0000000..a2171d7 --- /dev/null +++ b/src/qt/qtquick_controls/qml/QmlGUIBannerControl.qml @@ -0,0 +1,166 @@ +import QtQuick 2.2 +import CasinoCoinControls 1.0 + +GUIBannerControl +{ + id: id_bannerControl + + property color colorBackgroundInWidget: "#F2F0F1" + Rectangle + { + id: id_leftArrow + height: id_bannerControl.height + width: 30 + color: colorBackgroundInWidget + Image + { + id: id_leftArrowImage + + source: "qrc:/icons/res/icons/adverts_arrow_left.png" + + anchors.centerIn: id_leftArrow + } + anchors.left: id_bannerControl.left + + MouseArea + { + id: id_leftArrowMouseArea + anchors.fill: id_leftArrow + + hoverEnabled: true + + onEntered: + { + id_leftArrowImage.source = "qrc:/icons/res/icons/adverts_arrow_left_hover.png" + id_bannerListView.m_PathView.decrementCurrentIndex() + id_animationTimer.restart() + } + onExited: + { + id_leftArrowImage.source = "qrc:/icons/res/icons/adverts_arrow_left.png" + id_animationTimer.stop() + } + onClicked: + { + id_bannerListView.m_PathView.decrementCurrentIndex() + } + } + } + Rectangle + { + id: id_BannersArea + height: id_bannerControl.height + width: id_bannerControl.width - id_leftArrow.width - id_rightArrow.width + color: colorBackgroundInWidget + z: -1 + + anchors.horizontalCenter: id_bannerControl.horizontalCenter + anchors.left: id_leftArrow.left + Rectangle + { + id: id_fadeOutLeft + + height: id_BannersArea.width / 6 + width: id_BannersArea.height + rotation: 270 + z: 1 + + anchors.left: id_BannersArea.left + anchors.verticalCenter: id_BannersArea.verticalCenter + gradient: + Gradient + { + GradientStop { position: 0.0; color: colorBackgroundInWidget } + GradientStop { position: 0.7; color: "transparent" } + GradientStop { position: 1.0; color: "transparent" } + } + } + QmlGUIBannerListView + { + id: id_bannerListView + + anchors.fill: id_BannersArea + Component.onCompleted: + { + id_bannerControl.InitializeAdvertsView( id_bannerListView ) + } + } + Rectangle + { + id: id_fadeOutRight + + height: id_BannersArea.width / 6 + width: id_BannersArea.height + rotation: 90 + z: 1 + + anchors.right: id_BannersArea.right + anchors.verticalCenter: id_BannersArea.verticalCenter + gradient: + Gradient + { + GradientStop { position: 0.0; color: colorBackgroundInWidget } + GradientStop { position: 0.7; color: "transparent" } + GradientStop { position: 1.0; color: "transparent" } + } + } +} + Rectangle + { + id: id_rightArrow + height: id_bannerControl.height + width: 30 + color: colorBackgroundInWidget + Image + { + id: id_rightArrowImage + source: "qrc:/icons/res/icons/adverts_arrow_right.png" + + anchors.centerIn: id_rightArrow + } + + anchors.right: id_bannerControl.right + + MouseArea + { + id: id_rightArrowMouseArea + anchors.fill: id_rightArrow + + hoverEnabled: true + + onEntered: + { + id_rightArrowImage.source = "qrc:/icons/res/icons/adverts_arrow_right_hover.png" + id_bannerListView.m_PathView.incrementCurrentIndex() + id_animationTimer.restart() + } + onExited: + { + id_rightArrowImage.source = "qrc:/icons/res/icons/adverts_arrow_right.png" + id_animationTimer.stop() + } + onClicked: + { + id_bannerListView.m_PathView.incrementCurrentIndex() + } + } + Timer + { + id: id_animationTimer + interval: id_bannerListView.m_PathView.highlightMoveDuration + running: false + repeat: true + onTriggered: + { + if ( id_rightArrowMouseArea.containsMouse ) + { + id_bannerListView.m_PathView.incrementCurrentIndex() + } + if ( id_leftArrowMouseArea.containsMouse ) + { + id_bannerListView.m_PathView.decrementCurrentIndex() + } + } + } + } +} diff --git a/src/qt/qtquick_controls/qml/QmlGUIBannerListView.qml b/src/qt/qtquick_controls/qml/QmlGUIBannerListView.qml new file mode 100644 index 0000000..ce2ee41 --- /dev/null +++ b/src/qt/qtquick_controls/qml/QmlGUIBannerListView.qml @@ -0,0 +1,73 @@ +import QtQuick 2.0 +import CasinoCoinControls 1.0 + +GUIBannerListView +{ + id: id_bannerView + + property int m_iItemBorderWidth: 1 + property int m_iColumnWidth: 0 + property alias m_ListModel: id_pathView.model + property alias m_PathView: id_pathView + + PathView + { + id: id_pathView + anchors.fill: id_bannerView + + pathItemCount: 3 + highlightRangeMode: PathView.StrictlyEnforceRange + highlightMoveDuration: 1000 + preferredHighlightBegin: 0.5 + preferredHighlightEnd: 0.5 + visible: true + interactive: false + + model: id_bannerView.p_pListModel + delegate: id_elementDelegate + path: Path + { + startX: 30; startY: id_bannerView.height / 2 + PathLine { x: id_bannerView.width - 30; y: id_bannerView.height / 2 } + } + } + + Component + { + id: id_elementDelegate + Rectangle + { + id: id_listElement + objectName: id_bannerView.objectName + "_Element" + index + + width: 115 + height: width + + Image + { + id: id_advertisementImage + source: m_imageSource + scale: ( id_listElement.width / width ) + anchors.centerIn: id_listElement + } + + // coming soon +// QmlImageProvider +// { +// id: id_advertisementImage +// scale: ( id_listElement.width / width ) +// anchors.centerIn: id_listElement +// } + MouseArea + { + id: id_leftItemMouseArea + anchors.fill: id_listElement + onClicked: + { + id_bannerView.OnClicked( index ) + } + } + } + } + +} diff --git a/src/qt/qtquick_controls/qml/QmlGUIBannerWindow.qml b/src/qt/qtquick_controls/qml/QmlGUIBannerWindow.qml new file mode 100644 index 0000000..a1ff692 --- /dev/null +++ b/src/qt/qtquick_controls/qml/QmlGUIBannerWindow.qml @@ -0,0 +1,14 @@ +import QtQuick 2.2 + +Rectangle +{ + id: id_root + QmlGUIBannerControl + { + id: id_bannerControlMain + } + color: "#F2F0F1" + width: id_bannerControlMain.width + height: id_bannerControlMain.height +} + diff --git a/src/qt/res/icons/adverts_arrow_left.png b/src/qt/res/icons/adverts_arrow_left.png new file mode 100644 index 0000000..4872786 Binary files /dev/null and b/src/qt/res/icons/adverts_arrow_left.png differ diff --git a/src/qt/res/icons/adverts_arrow_left_hover.png b/src/qt/res/icons/adverts_arrow_left_hover.png new file mode 100644 index 0000000..d3fac2d Binary files /dev/null and b/src/qt/res/icons/adverts_arrow_left_hover.png differ diff --git a/src/qt/res/icons/adverts_arrow_right.png b/src/qt/res/icons/adverts_arrow_right.png new file mode 100644 index 0000000..71b9b6c Binary files /dev/null and b/src/qt/res/icons/adverts_arrow_right.png differ diff --git a/src/qt/res/icons/adverts_arrow_right_hover.png b/src/qt/res/icons/adverts_arrow_right_hover.png new file mode 100644 index 0000000..c149be2 Binary files /dev/null and b/src/qt/res/icons/adverts_arrow_right_hover.png differ