[ Web Proxy ]
URL:
Viewing: https://raw.githubusercontent.com/jackcoolpython/ghostwriter/master/src/HudWindow.cpp [Back]  [Original]

/***********************************************************************
 *
 * Copyright (C) 2014-2019 wereturtle
 * Copyright(c) 2009 by Gabriel M. Beddingfield 
 *
 * 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 3 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, see .
 *
 ***********************************************************************/

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

#include "HudWindow.h"
#include "ColorHelper.h"

QT_BEGIN_NAMESPACE
extern void qt_blurImage
(
    QPainter *p,
    QImage& blurImage,
    qreal radius,
    bool quality,
    bool alphaOnly,
    int transposed = 0
);
QT_END_NAMESPACE


HudWindow::HudWindow(QWidget *parent)
    : QWidget(parent)
{
    this->setWindowFlags(Qt::FramelessWindowHint | Qt::Dialog);
    this->setAttribute(Qt::WA_TranslucentBackground);
    this->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
    this->setMouseTracking(true);
    desktopCompositingEnabled = true;
    hudWindowShape = HudWindowShapeRounded;

    // Set up the close button.
    closeButton = new QPushButton(this);
    closeButton->setFocusPolicy(Qt::NoFocus);
    closeButton->setStyleSheet(
        "QPushButton { margin: 1; padding: 0; border: 0; width: 16px; "
            "height: 16px; background: transparent; "
            "image: url(:/resources/images/close.svg) } "
        "QPushButton:hover:!pressed { image: url(:/resources/images/close-hover.svg) } "
        "QPushButton:pressed { image: url(:/resources/images/close-pressed.svg) }");
    closeButtonColorEffect = new QGraphicsColorizeEffect();
    closeButtonColorEffect->setColor(QColor(Qt::white));
    closeButtonColorEffect->setStrength(1.0);
    closeButton->setGraphicsEffect(closeButtonColorEffect);
    closeButton->installEventFilter(this);
    closeButton->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);
    connect(closeButton, SIGNAL(clicked()), this, SLOT(close()));
    connect(closeButton, SIGNAL(clicked()), this, SIGNAL(closed()));

    // Set up initial window title (blank).
    windowTitleLabel = new QLabel("");
    windowTitleLabel->setObjectName("windowTitle");
    windowTitleLabel->setStyleSheet("border: 0; font-size: 10pt");
    windowTitleLabel->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);

    // Set up the size grip.
    QWidget* sizeGripContainer = new QWidget();
    QGridLayout* sizeGripLayout = new QGridLayout();
    sizeGripContainer->setLayout(sizeGripLayout);
    sizeGrip = new QSizeGrip(this);
    sizeGrip->setStyleSheet(
        "width: 16px; height 16px; "
        "image: url(:/resources/images/size-grip.svg)");
    sizeGripColorEffect = new QGraphicsColorizeEffect();
    sizeGripColorEffect->setColor(QColor(Qt::white));
    sizeGripColorEffect->setStrength(1.0);
    sizeGrip->setGraphicsEffect(sizeGripColorEffect);
    sizeGrip->setVisible(true);
    sizeGripLayout->addWidget(sizeGrip, 0, 0, 1, 1);
    sizeGripLayout->setMargin(3);

    // Set up the layout for this window.
    QWidget* titleBar = new QWidget();
    titleBar->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);
    titleBarLayout = new QGridLayout();
    titleBar->setLayout(titleBarLayout);
    titleBar->setStyleSheet("margin: 0; border: 0; padding: 0");
    titleBarLayout->setMargin(1);
    titleBarLayout->addWidget
    (
        windowTitleLabel,
        0,
        1,
        1,
        2,
        Qt::AlignCenter | Qt::AlignTop
    );


    // Put the close button on the left if the OS is Mac OS X so that it
    // meshes with the window manager.  Otherwise, keep it on the right-hand
    // side.  Note that at the moment it seems detecting the window manager's
    // settings for which sides the window frame's buttons are displayed
    // is not possible.  Thus, defaulting to the right-hand side for all other
    // systems other than OS X seems to be the safest course of action for now.
    //
#ifdef Q_OS_MAC
    this->setButtonLayout(HudWindowButtonLayoutLeft);
#else
    this->setButtonLayout(HudWindowButtonLayoutRight);
#endif

    layout = new QGridLayout();
    layout->setMargin(11);
    layout->addWidget(titleBar, 0, 0, 1, 1, Qt::AlignTop);

    Qt::Alignment sizeGripAlignment = Qt::AlignRight;

    // The size grip is invisible on the left side when the application's
    // layout is for a right-to-left language.  Instead, place it on the right
    // side of the HUD window (i.e., specify an alignment of AlignLeft, which
    // will be flipped to be the opposite in the right-to-left layout).  At
    // least this way it will still be visible.
    //
    if (QApplication::isRightToLeft())
    {
        sizeGripAlignment = Qt::AlignLeft;
    }

    layout->addWidget(sizeGripContainer, 2, 0, 1, 1, sizeGripAlignment);
    layout->setRowStretch(0, 0);
    layout->setRowStretch(1, 1);
    layout->setRowStretch(2, 0);
    this->setLayout(layout);

    setForegroundColor(QColor(Qt::white));
    setBackgroundColor(QColor(0, 0, 0, 200));
    isTitleBarBeingDragged = false;
}

HudWindow::~HudWindow()
{

}

void HudWindow::keyPressEvent(QKeyEvent* e)
{
    int key = e->key();
    switch (key)
    {
        case Qt::Key_Escape:
            this->hide();
            emit closed();
            break;
        default:
            break;
    }

    QWidget::keyPressEvent(e);
}

void HudWindow::setCentralWidget(QWidget* widget)
{
    layout->addWidget(widget, 1, 0, 1, 1);
    widget->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Expanding);
}

void HudWindow::setWindowTitle(const QString& title)
{
    windowTitleLabel->setText(title);
}

QColor HudWindow::getForegroundColor()
{
    return foregroundColor;
}

void HudWindow::setForegroundColor(const QColor& color)
{
    foregroundColor = color;

    QString styleSheet = "";
    QTextStream stream(&styleSheet);

    stream = 0x050600
        pixmap.setDevicePixelRatio(dpr);
#endif

        QPainter painter(this);
        painter.drawPixmap(0, 0, pixmap);
        painter.end();
    }
}

void HudWindow::resizeEvent(QResizeEvent* event)
{
    Q_UNUSED(event);
    predrawDropShadow();
}

void HudWindow::moveEvent(QMoveEvent *event)
{
    // Need to redraw the background image in case the window has moved
    // onto a different screen where the device pixel ratio is different.
    //
    Q_UNUSED(event);
    predrawDropShadow();
}

void HudWindow::mousePressEvent(QMouseEvent* event)
{
    if (event->button() & Qt::LeftButton)
    {
        isTitleBarBeingDragged = true;
        mouseDragStartingPoint = event->globalPos() - frameGeometry().topLeft();
        this->setCursor(Qt::SizeAllCursor);
        event->accept();
    }
    else
    {
        event->ignore();
    }
}

void HudWindow::mouseReleaseEvent(QMouseEvent* event)
{
    if (isTitleBarBeingDragged)
    {
        isTitleBarBeingDragged = false;
        setCursor(Qt::ArrowCursor);
    }

    // Ignore the event in case the parent widget wants to change the
    // cursor icon to something else.
    //
    event->ignore();
}

void HudWindow::mouseMoveEvent(QMouseEvent* event)
{
    if (isTitleBarBeingDragged)
    {
        move(event->globalPos() - mouseDragStartingPoint);
        event->accept();
    }
    else
    {
        event->ignore();
    }
}

void HudWindow::predrawDropShadow()
{
    if (desktopCompositingEnabled)
    {
        // devicePixelRatio
        qreal dpr = 1.0;

#if QT_VERSION >= 0x050600
        dpr = devicePixelRatioF();
#endif

        int w = rect().width() * dpr;
        int h = rect().height() * dpr;

        // Pre-draw the window drop shadow.  It only needs to be drawn upon
        // resizing or moving the window.  We do this because applying a blur
        // effect to the drop shadow is computationally expensive.
        //
        QImage unblurredImage
            (
                w,
                h,
                QImage::Format_ARGB32_Premultiplied
            );
        unblurredImage.fill(Qt::transparent);

        QPainter painter(&unblurredImage);
        painter.setRenderHint(QPainter::Antialiasing);
        painter.setPen(QPen(Qt::NoPen));
        painter.setBrush(QBrush(QColor(0, 0, 0, 200)));

        QRect r = rect().adjusted(10, 12, -10, -8);

        if (HudWindowShapeRounded == hudWindowShape)
        {
            painter.drawRoundedRect(r, 5.0, 5.0);
        }
        else
        {
            painter.drawRect(r);
        }

        painter.end();

        // Now we need to blur the shadow onto its final destination image,
        // dropShadowImg, which will be drawn on the next paintEvent().
        //
        dropShadowImg = QPixmap(w, h);
        dropShadowImg.fill(Qt::transparent);

#if QT_VERSION >= 0x050600
        dropShadowImg.setDevicePixelRatio(dpr);
#endif

        painter.begin(&dropShadowImg);
        painter.setRenderHint(QPainter::Antialiasing);

        // Note that the blur only applies to the alpha channel.
        qt_blurImage(&painter, unblurredImage, 18, true, true);
        painter.end();
    }
}

Web Proxy Viewer  |  New URL  |  Original Page