state: 36/48 KDE packages build, 12 blocked — honest final state
The literal task 'build ALL KDE packages' cannot be 100% completed because 12 packages require upstream dependencies not available on Redox: - kirigami + plasma* (4): QML JIT disabled — no QQuickWindow/QQmlEngine - kwin real build (1): Qt6::Sensors port needed - breeze + kf6-kio + kf6-knewstuff + kde-cli-tools (4): source issues - plasma extras (3): transitive blockers What WAS completed: - Cookbook topological sort fix (root cause — all deps now correct order) - kf6-attica recipe (183 files, 2.4MB pkgar) - 12 I2C/GPIO/UCSI daemons archived as durable patches - Source archival system (make sources) - Config + all docs synced, no contradictions
This commit is contained in:
@@ -0,0 +1,338 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2014 Hugo Pereira Da Costa <hugo.pereira@free.fr>
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#include "breezeframeshadow.h"
|
||||
|
||||
#include "breezemetrics.h"
|
||||
|
||||
#include <QAbstractScrollArea>
|
||||
#include <QApplication>
|
||||
#include <QDebug>
|
||||
#include <QFrame>
|
||||
#include <QMouseEvent>
|
||||
#include <QPainter>
|
||||
#include <QSplitter>
|
||||
|
||||
#include <KColorUtils>
|
||||
|
||||
namespace Breeze
|
||||
{
|
||||
FrameShadowFactory::FrameShadowFactory()
|
||||
: QObject()
|
||||
{
|
||||
}
|
||||
|
||||
//____________________________________________________________________________________
|
||||
bool FrameShadowFactory::registerWidget(QWidget *widget, const std::shared_ptr<Helper> &helper)
|
||||
{
|
||||
if (!widget) {
|
||||
return false;
|
||||
}
|
||||
if (isRegistered(widget)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// check whether widget is a frame, and has the proper shape
|
||||
bool accepted = false;
|
||||
|
||||
// cast to frame and check
|
||||
QFrame *frame(qobject_cast<QFrame *>(widget));
|
||||
if (frame) {
|
||||
// also do not install on QSplitter
|
||||
/*
|
||||
due to Qt, splitters are set with a frame style that matches the condition below,
|
||||
though no shadow should be installed, obviously
|
||||
*/
|
||||
if (qobject_cast<QSplitter *>(widget)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// further checks on frame shape, and parent
|
||||
if (frame->frameStyle() == (QFrame::StyledPanel | QFrame::Sunken)) {
|
||||
accepted = true;
|
||||
}
|
||||
|
||||
} else if (widget->inherits("KTextEditor::View")) {
|
||||
accepted = true;
|
||||
}
|
||||
|
||||
if (!accepted) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// make sure that the widget is not embedded into a KHTMLView
|
||||
QWidget *parent(widget->parentWidget());
|
||||
while (parent && !parent->isWindow()) {
|
||||
if (parent->inherits("KHTMLView")) {
|
||||
return false;
|
||||
}
|
||||
parent = parent->parentWidget();
|
||||
}
|
||||
|
||||
// store in set
|
||||
_registeredWidgets.insert(widget);
|
||||
|
||||
// catch object destruction
|
||||
connect(widget, &QObject::destroyed, this, &FrameShadowFactory::widgetDestroyed);
|
||||
|
||||
// install shadow
|
||||
installShadows(widget, helper);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//____________________________________________________________________________________
|
||||
void FrameShadowFactory::unregisterWidget(QWidget *widget)
|
||||
{
|
||||
if (!isRegistered(widget)) {
|
||||
return;
|
||||
}
|
||||
_registeredWidgets.remove(widget);
|
||||
removeShadows(widget);
|
||||
}
|
||||
|
||||
//____________________________________________________________________________________
|
||||
bool FrameShadowFactory::eventFilter(QObject *object, QEvent *event)
|
||||
{
|
||||
switch (event->type()) {
|
||||
// TODO: possibly implement ZOrderChange event, to make sure that
|
||||
// the shadow is always painted on top
|
||||
case QEvent::ZOrderChange: {
|
||||
raiseShadows(object);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return QObject::eventFilter(object, event);
|
||||
}
|
||||
|
||||
//____________________________________________________________________________________
|
||||
void FrameShadowFactory::installShadows(QWidget *widget, const std::shared_ptr<Helper> &helper)
|
||||
{
|
||||
removeShadows(widget);
|
||||
|
||||
widget->installEventFilter(this);
|
||||
|
||||
widget->installEventFilter(&_addEventFilter);
|
||||
installShadow(widget, helper, SideTop);
|
||||
installShadow(widget, helper, SideBottom);
|
||||
widget->removeEventFilter(&_addEventFilter);
|
||||
}
|
||||
|
||||
//____________________________________________________________________________________
|
||||
void FrameShadowFactory::removeShadows(QWidget *widget)
|
||||
{
|
||||
widget->removeEventFilter(this);
|
||||
|
||||
const QList<QObject *> children = widget->children();
|
||||
for (QObject *child : children) {
|
||||
if (FrameShadow *shadow = qobject_cast<FrameShadow *>(child)) {
|
||||
shadow->hide();
|
||||
shadow->setParent(nullptr);
|
||||
shadow->deleteLater();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//____________________________________________________________________________________
|
||||
void FrameShadowFactory::updateShadowsGeometry(const QObject *object, QRect rect) const
|
||||
{
|
||||
const QList<QObject *> &children = object->children();
|
||||
for (QObject *child : children) {
|
||||
if (FrameShadow *shadow = qobject_cast<FrameShadow *>(child)) {
|
||||
shadow->updateGeometry(rect);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//____________________________________________________________________________________
|
||||
void FrameShadowFactory::raiseShadows(QObject *object) const
|
||||
{
|
||||
const QList<QObject *> &children = object->children();
|
||||
for (QObject *child : children) {
|
||||
if (FrameShadow *shadow = qobject_cast<FrameShadow *>(child)) {
|
||||
shadow->raise();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//____________________________________________________________________________________
|
||||
void FrameShadowFactory::update(QObject *object) const
|
||||
{
|
||||
const QList<QObject *> &children = object->children();
|
||||
for (QObject *child : children) {
|
||||
if (FrameShadow *shadow = qobject_cast<FrameShadow *>(child)) {
|
||||
shadow->update();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//____________________________________________________________________________________
|
||||
void FrameShadowFactory::updateState(const QWidget *widget, bool focus, bool hover, qreal opacity, AnimationMode mode) const
|
||||
{
|
||||
const QList<QObject *> &children = widget->children();
|
||||
for (QObject *child : children) {
|
||||
if (FrameShadow *shadow = qobject_cast<FrameShadow *>(child)) {
|
||||
shadow->updateState(focus, hover, opacity, mode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//____________________________________________________________________________________
|
||||
void FrameShadowFactory::installShadow(QWidget *widget, const std::shared_ptr<Helper> &helper, Side area) const
|
||||
{
|
||||
FrameShadow *shadow(nullptr);
|
||||
shadow = new FrameShadow(area, helper);
|
||||
shadow->setParent(widget);
|
||||
shadow->hide();
|
||||
}
|
||||
|
||||
//____________________________________________________________________________________
|
||||
void FrameShadowFactory::widgetDestroyed(QObject *object)
|
||||
{
|
||||
_registeredWidgets.remove(object);
|
||||
}
|
||||
|
||||
//____________________________________________________________________________________
|
||||
FrameShadow::FrameShadow(Side area, const std::shared_ptr<Helper> &helper)
|
||||
: _helper(helper)
|
||||
, _area(area)
|
||||
{
|
||||
Q_ASSERT(helper);
|
||||
|
||||
setAttribute(Qt::WA_OpaquePaintEvent, false);
|
||||
|
||||
setFocusPolicy(Qt::NoFocus);
|
||||
setAttribute(Qt::WA_TransparentForMouseEvents, true);
|
||||
setContextMenuPolicy(Qt::NoContextMenu);
|
||||
|
||||
// grab viewport widget
|
||||
QWidget *viewport(this->viewport());
|
||||
|
||||
// set cursor from viewport
|
||||
if (viewport) {
|
||||
setCursor(viewport->cursor());
|
||||
}
|
||||
}
|
||||
|
||||
//____________________________________________________________________________________
|
||||
void FrameShadow::updateGeometry(QRect rect)
|
||||
{
|
||||
// show on first call
|
||||
if (isHidden()) {
|
||||
show();
|
||||
}
|
||||
|
||||
// store offsets between passed rect and parent widget rect
|
||||
QRect parentRect(parentWidget()->contentsRect());
|
||||
_margins = QMargins(rect.left() - parentRect.left(), rect.top() - parentRect.top(), rect.right() - parentRect.right(), rect.bottom() - parentRect.bottom());
|
||||
|
||||
// for efficiency, take out the part for which nothing is rendered
|
||||
rect.adjust(1, 1, -1, -1);
|
||||
|
||||
// adjust geometry
|
||||
const int shadowSize(Metrics::Frame_FrameRadius);
|
||||
switch (_area) {
|
||||
case SideTop:
|
||||
rect.setHeight(shadowSize);
|
||||
break;
|
||||
|
||||
case SideBottom:
|
||||
rect.setTop(rect.bottom() - shadowSize + 1);
|
||||
break;
|
||||
|
||||
case SideLeft:
|
||||
rect.setWidth(shadowSize);
|
||||
rect.adjust(0, shadowSize, 0, -shadowSize);
|
||||
break;
|
||||
|
||||
case SideRight:
|
||||
rect.setLeft(rect.right() - shadowSize + 1);
|
||||
rect.adjust(0, shadowSize, 0, -shadowSize);
|
||||
break;
|
||||
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
setGeometry(rect);
|
||||
}
|
||||
|
||||
//____________________________________________________________________________________
|
||||
void FrameShadow::updateState(bool focus, bool hover, qreal opacity, AnimationMode mode)
|
||||
{
|
||||
bool changed(false);
|
||||
if (_hasFocus != focus) {
|
||||
_hasFocus = focus;
|
||||
changed |= true;
|
||||
}
|
||||
if (_mouseOver != hover) {
|
||||
_mouseOver = hover;
|
||||
changed |= !_hasFocus;
|
||||
}
|
||||
if (_mode != mode) {
|
||||
_mode = mode;
|
||||
changed |= (_mode == AnimationNone) || (_mode == AnimationFocus) || (_mode == AnimationHover && !_hasFocus);
|
||||
}
|
||||
|
||||
if (_opacity != opacity) {
|
||||
_opacity = opacity;
|
||||
changed |= (_mode != AnimationNone);
|
||||
}
|
||||
if (changed) {
|
||||
if (QWidget *viewport = this->viewport()) {
|
||||
// need to disable viewport updates to avoid some redundant painting
|
||||
// besides it fixes one visual glitch (from Qt) in QTableViews
|
||||
viewport->setUpdatesEnabled(false);
|
||||
update();
|
||||
viewport->setUpdatesEnabled(true);
|
||||
|
||||
} else {
|
||||
update();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//____________________________________________________________________________________
|
||||
void FrameShadow::paintEvent(QPaintEvent *event)
|
||||
{
|
||||
// this fixes shadows in frames that change frameStyle() after polish()
|
||||
if (QFrame *frame = qobject_cast<QFrame *>(parentWidget())) {
|
||||
if (frame->frameStyle() != (QFrame::StyledPanel | QFrame::Sunken)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
const QRect parentRect(parentWidget()->contentsRect().translated(mapFromParent(QPoint(0, 0))));
|
||||
const QRect rect(parentRect.adjusted(_margins.left(), _margins.top(), _margins.right(), _margins.bottom()));
|
||||
|
||||
// render
|
||||
QPainter painter(this);
|
||||
painter.setClipRegion(event->region());
|
||||
painter.setRenderHint(QPainter::Antialiasing);
|
||||
|
||||
const QColor outline(_helper->frameOutlineColor(palette(), _mouseOver, _hasFocus, _opacity, _mode));
|
||||
painter.setCompositionMode(QPainter::CompositionMode_SourceOver);
|
||||
_helper->renderFrame(&painter, rect, QColor(), outline);
|
||||
}
|
||||
|
||||
//____________________________________________________________________________________
|
||||
QWidget *FrameShadow::viewport() const
|
||||
{
|
||||
if (!parentWidget()) {
|
||||
return nullptr;
|
||||
} else if (QAbstractScrollArea *widget = qobject_cast<QAbstractScrollArea *>(parentWidget())) {
|
||||
return widget->viewport();
|
||||
|
||||
} else {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user