/* * Qt UI * * Copyright (C) 2014 Samsung Electronics Co., Ltd. All rights reserved. * * Contact: * GiWoong Kim * SeokYeon Hwang * Sangho Park * Stanislav Vorobiov * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, * MA 02110-1301, USA. * * Contributors: * - S-Core Co., Ltd * */ #include "displaybase.h" #include "mainwindow.h" #include "resource/ui_strings.h" #include "menu/sdbhelper.h" extern "C" { #include "util/ui_operations.h" void qt5_graphic_hw_invalidate(void); void req_set_sensor_accel_angle(int angle); } DisplayBase::DisplayBase(DisplayType *displayForm, QSize resolution, qreal scaleFactor, QWidget *w) : resolution(resolution), widget(w) { this->win = (MainWindow *)widget->parentWidget(); this->rect = displayForm->getRect(); this->maskImage = displayForm->getMask(); this->rotateAngle = displayForm->getAngle(); this->scaleFactor = scaleFactor; this->isDragging = false; this->tsHelper = NULL; this->mouseHelper = NULL; this->offGuide = NULL; this->movingMode = false; this->grabPos = SKINVIEW_NULLITY_POSITION; this->grabWinPos = win->pos(); this->dropping = false; this->sdbHelper = new SdbHelper((MainWindow *)widget->parentWidget(), this); this->isTsEnabled = is_touchscreen_enabled(); if (isTsEnabled == true) { qDebug("touch screen device was enabled"); /* touch screen */ tsHelper = new TouchScreenHelper(this); win->getMainView()->getKbdHelper()->setMtTracker(tsHelper->getMtTracker()); widget->setCursor(Qt::ArrowCursor); } else { qDebug("touch screen device was not enabled"); /* mouse */ mouseHelper = new MouseHelper(this, resolution); widget->setCursor(Qt::BlankCursor); widget->setMouseTracking(true); } loadOffGuideImg(); req_set_sensor_accel_angle(rotateAngle); /* update sensor */ updateGeometry(); } void DisplayBase::loadOffGuideImg() { QString offImage = QDir(QCoreApplication::applicationDirPath() + QDir::separator() + SDK_EMULATOR_IMAGES_PATH + DISPLAY_OFF_GUIDE_IMAGE_FILE).absolutePath(); if (offGuideImg.load(offImage) == false) { qWarning() << "failed to load image from" << offImage; } } bool DisplayBase::isOffGuideReady() { return !offGuideImg.isNull(); } void DisplayBase::showOffGuideImg() { if (!offGuide) { offGuide = new QLabel(win); offGuide->setStyleSheet( "background-color: black; border-style: none;"); offGuide->setAlignment(Qt::AlignCenter); } offGuide->setGeometry(getGeometry()); offGuide->setPixmap(offGuideImg.scaled( getGeometry().width(), getGeometry().height(), Qt::KeepAspectRatio, Qt::SmoothTransformation)); if (maskImage.size() != QSize(0, 0)) { offGuide->setMask(maskImage.scaled( maskImage.width() * scaleFactor, maskImage.height() * scaleFactor).mask()); } widget->update(); offGuide->show(); } void DisplayBase::hideOffGuideImg() { if (isOffGuideShown()) { offGuide->hide(); } } bool DisplayBase::isOffGuideShown() { return (offGuide && offGuide->isVisible()); } void DisplayBase::switchForm(DisplayType *displayForm) { qDebug() << "display switch angle:" << displayForm->getAngle(); rotateAngle = displayForm->getAngle(); rect = displayForm->getRect(); maskImage = displayForm->getMask(); req_set_sensor_accel_angle(rotateAngle); /* update sensor */ updateGeometry(); invalidateDisplay(); widget->update(); } void DisplayBase::scaleForm(qreal scaleFactor) { qDebug() << "display scale factor:" << scaleFactor; this->scaleFactor = scaleFactor; updateGeometry(); invalidateDisplay(); widget->update(); } void DisplayBase::invalidateDisplay() { qt5_graphic_hw_invalidate(); } void DisplayBase::updateGeometry() { hideOffGuideImg(); qreal sx = rect.x() * scaleFactor; qreal sy = rect.y() * scaleFactor; widget->setGeometry(qRound(sx), qRound(sy), rect.width() * scaleFactor, rect.height() * scaleFactor); } const QRect &DisplayBase::getGeometry() { return widget->geometry(); } QRegion DisplayBase::getMask() { return widget->mask(); } void DisplayBase::handlePaint() { /* do nothing */ } void DisplayBase::handleResize() { qDebug() << "resize display:" << widget->size(); qt5_graphic_hw_invalidate(); /* masking */ if (maskImage.size() != QSize(0, 0)) { qDebug("set a mask to display"); widget->setMask(maskImage.scaled( maskImage.width() * scaleFactor, maskImage.height() * scaleFactor).mask()); } /* update widget position */ sdbHelper->updateGeometry(rect); } QPoint DisplayBase::getGuestPos(QPoint hostPos) { QPoint guestPos = hostPos / scaleFactor; const int guestPosX = guestPos.x(); const int guestPosY = guestPos.y(); /* TODO: calculate for all angle (x*cos(rad)-y*sin(rad)) */ switch(rotateAngle) { case 90: /* Reverse Landscape */ guestPos.setX(guestPosY); guestPos.setY(rect.width() - guestPosX); break; case 180: /* Reverse Portrait */ guestPos.setX(rect.width() - guestPosX); guestPos.setY(rect.height() - guestPosY); break; case 270: /* Landscape */ guestPos.setX(rect.height() - guestPosY); guestPos.setY(guestPosX); break; case 0: break; default: qWarning() << "unsupported coordinate system:" << rotateAngle; break; } return guestPos; } TouchScreenHelper *DisplayBase::getTouchScreenHelper() { return tsHelper; } MouseHelper *DisplayBase::getMouseHelper() { return mouseHelper; } void DisplayBase::clearInput() { qDebug("clear input"); if (tsHelper != NULL) { tsHelper->touchReleased(); } if (mouseHelper != NULL) { mouseHelper->mouseReleased(); } isDragging = false; } /* called by overriding function */ void DisplayBase::handleMousePress(QMouseEvent *event) { if (isMovingMode() == true) { if (event->button() == Qt::LeftButton) { grabWindow(event->globalPos()); } else { qDebug("cancel the moving mode"); grabPos = SKINVIEW_NULLITY_POSITION; win->turnOffMovingMode(); } return; } if (event->button() == Qt::LeftButton) { isDragging = true; if (tsHelper != NULL) { tsHelper->touchPressed(event->pos(), getGuestPos(event->pos())); } if (mouseHelper != NULL) { mouseHelper->mousePressed(); } } else { if (isDragging == true) { clearInput(); } } } /* called by overriding function */ void DisplayBase::handleMouseRelease(QMouseEvent *event) { if (isMovingMode() == true) { releaseWindow(); win->turnOffMovingMode(); if (mouseHelper != NULL) { mouseHelper->mouseSync(getGuestPos(event->pos())); } return; } if (event->button() == Qt::LeftButton) { if (isDragging == true) { isDragging = false; } if (tsHelper != NULL) { tsHelper->touchReleased(event->pos(), getGuestPos(event->pos())); } if (mouseHelper != NULL) { mouseHelper->mouseReleased(); } } } /* called by overriding function */ void DisplayBase::handleMouseMove(QMouseEvent *event) { if (isMovingMode() == true) { if (isGrabWindow() == true) { /* move a window */ win->move(grabWinPos + (event->globalPos() - grabPos)); } return; } /* touch screen device */ if (tsHelper != NULL) { if (isDragging == true) { int hostPosX = event->x(); int hostPosY = event->y(); /* bounds checking */ if (hostPosX < 0) { hostPosX = 0; isDragging = false; } else if (hostPosX >= widget->width()) { hostPosX = widget->width() - 1; isDragging = false; } if (hostPosY < 0) { hostPosY = 0; isDragging = false; } else if (hostPosY >= widget->height()) { hostPosY = widget->height() - 1; isDragging = false; } if (isDragging == false) { QPoint clientPos(hostPosX, hostPosY); qDebug() << "drag out of touch screen:" << clientPos; tsHelper->touchReleased(event->pos(), getGuestPos(clientPos)); } else { tsHelper->touchMoved(event->pos(), getGuestPos(event->pos())); } } } /* mouse device */ if (mouseHelper != NULL) { const int hostPosX = event->x(); const int hostPosY = event->y(); if (hostPosX < 0 || hostPosX > widget->width() || hostPosY < 0 || hostPosY > widget->height()) { if (isDragging == true) { qDebug("drag out: auto release"); isDragging = false; mouseHelper->mouseReleased(); return; } } mouseHelper->mouseMoved( event->pos(), getGuestPos(event->pos())); } } /* called by overriding function */ void DisplayBase::handleMouseEnter(QEvent *event) { if (mouseHelper != NULL) { mouseHelper->mouseEnter(); } } /* called by overriding function */ void DisplayBase::handleMouseLeave(QEvent *event) { if (mouseHelper != NULL) { mouseHelper->mouseLeave(); } } void DisplayBase::turnOnMovingMode() { if (isDragging == true) { clearInput(); } movingMode = true; widget->setCursor(Qt::SizeAllCursor); } void DisplayBase::turnOffMovingMode() { movingMode = false; if (isTsEnabled == true) { widget->setCursor(Qt::ArrowCursor); } else { widget->setCursor(Qt::BlankCursor); } } void DisplayBase::handleDragEnterEvent(QDragEnterEvent *event) { if (!event->mimeData()->hasUrls()) { qDebug() << "ignore action"; event->setDropAction(Qt::IgnoreAction); } /* check if sdb is ready */ if (!sdbHelper->isSdbReady()) { qDebug("sdb is not ready"); event->setDropAction(Qt::IgnoreAction); return; } foreach (const QUrl &url, event->mimeData()->urls()) { QString fileName = url.toLocalFile(); if (fileName.isEmpty()) { qDebug() << "empty file"; event->setDropAction(Qt::IgnoreAction); return; } } if (dropping == false && sdbHelper->isProgressing() == false) { event->acceptProposedAction(); event->setDropAction(Qt::CopyAction); } else { event->setDropAction(Qt::IgnoreAction); } } void DisplayBase::handleDropEvent(QDropEvent *event) { dropping = true; QList urls = event->mimeData()->urls(); QList fileNameList; foreach (const QUrl &url, urls) { QString fileName = url.toLocalFile(); if (!fileName.isEmpty()) { fileNameList << fileName; } } if (fileNameList.isEmpty()) { qDebug("There is nothing to drop."); return; } qDebug() << "fileNameList: " << fileNameList; /* Installation is supported if dropping item is only one packaging file.*/ if (fileNameList.size() == 1) { QString installFileName = fileNameList.at(0); QFileInfo fi(installFileName); QString extension = fi.suffix(); if (QString::compare(extension, FILE_EXTENSION_WGT, Qt::CaseInsensitive) == 0 || QString::compare(extension, FILE_EXTENSION_TPK, Qt::CaseInsensitive) == 0 || QString::compare(extension, FILE_EXTENSION_RPM, Qt::CaseInsensitive) == 0) { QMessageBox *msgBox = new QMessageBox(win); msgBox->setIcon(QMessageBox::Information); msgBox->setWindowTitle(EMULATOR_TITLE); msgBox->setText(QString(MSG_DROPPED_PACKAGE) + MSG_INSTALL_SELECT_DESC + installFileName); QPushButton *pButtonPush = msgBox->addButton(BUTTON_PUSH, QMessageBox::NoRole); QPushButton *pButtonInstall = msgBox->addButton(BUTTON_INSTALL, QMessageBox::YesRole); msgBox->addButton(BUTTON_CANCEL, QMessageBox::RejectRole); msgBox->setDefaultButton(pButtonInstall); msgBox->exec(); if (msgBox->clickedButton() == pButtonInstall) { sdbHelper->install(fi); } else if (msgBox->clickedButton() == pButtonPush) { goto push_file; } dropping = false; return; } } push_file: QString defaultPath = sdbHelper->getGuestDefaultPushPath(); if (!items.contains(defaultPath)) { items << defaultPath; } QInputDialog *dialog = new QInputDialog(win); bool isOk; do { QString dir = dialog->getItem(win, EMULATOR_TITLE, MSG_PUSH_POPUP, items, 0, true, &isOk); if (!isOk) { break; } if (dir.isEmpty()) { qDebug() << "dir is empty."; QMessageBox::warning(win, EMULATOR_TITLE, MSG_EMPTY_DIR, QMessageBox::Ok | QMessageBox::Default); /* retry */ continue; } else { if (!dir.endsWith("/")) { dir.append("/"); } sdbHelper->push(fileNameList, dir); /* TODO: check if dir is exist or has permission to push. */ if (!items.contains(dir)) { items << dir; } break; } } while (true); dropping = false; } bool DisplayBase::isMovingMode() { return movingMode; } void DisplayBase::grabWindow(QPoint pos) { qDebug("grab"); grabPos = pos; grabWinPos = win->pos(); } void DisplayBase::releaseWindow() { qDebug("release"); grabPos = SKINVIEW_NULLITY_POSITION; } bool DisplayBase::isGrabWindow() { return (grabPos != SKINVIEW_NULLITY_POSITION); } DisplayBase::~DisplayBase() { qDebug("destroy display"); if (offGuide != NULL) { delete offGuide; } if (tsHelper != NULL) { delete tsHelper; } if (mouseHelper != NULL) { delete mouseHelper; } if (sdbHelper != NULL) { delete sdbHelper; } }