Import Oxygen windec into kdebase
svn path=/trunk/KDE/kdebase/workspace/; revision=676051
This commit is contained in:
parent
afd0dae2a8
commit
83cd5b0ba2
29 changed files with 11321 additions and 0 deletions
49
clients/oxygen/CMakeLists.txt
Normal file
49
clients/oxygen/CMakeLists.txt
Normal file
|
@ -0,0 +1,49 @@
|
|||
project(kstyle-oxygen)
|
||||
|
||||
########### next target ###############
|
||||
|
||||
set( oxygen_SRCS
|
||||
oxygen.cpp
|
||||
tileset.cpp
|
||||
stylehint.cpp
|
||||
sizefromcontents.cpp
|
||||
qsubcmetrics.cpp
|
||||
pixelmetric.cpp
|
||||
stdpix.cpp
|
||||
drawcomplexcontrol.cpp
|
||||
drawcontrol.cpp
|
||||
drawprimitive.cpp
|
||||
dynamicbrush.cpp
|
||||
oxrender.cpp
|
||||
)
|
||||
|
||||
qt4_add_resources(oxygen.qrc oxygen.qrc)
|
||||
|
||||
kde4_automoc( ${oxygen_SRCS} )
|
||||
kde4_add_plugin(kstyle-oxygen ${oxygen_SRCS} )
|
||||
|
||||
# TODO: check if too much definitions.
|
||||
target_link_libraries( kstyle-oxygen
|
||||
${KDE4_KDECORE_LIBS}
|
||||
${QT_QT3SUPPORT_LIBRARY}
|
||||
${QT_QTOPENGL_LIBRARY}
|
||||
${KDE4_KDEFX_LIBS}
|
||||
${X11_X11_LIB}
|
||||
${X11_Xfixes_LIB}
|
||||
${X11_Xcursor_LIB}
|
||||
${X11_Xinerama_LIB}
|
||||
${X11_Xrender_LIB}
|
||||
${X11_Xrandr_LIB}
|
||||
${X11_XTest_LIB}
|
||||
${X11_LIBRARIES}
|
||||
# freetype
|
||||
# fontconfig
|
||||
GLU GL
|
||||
)
|
||||
|
||||
install( TARGETS kstyle-oxygen DESTINATION ${PLUGIN_INSTALL_DIR}/plugins/styles/ )
|
||||
|
||||
########### install files ###############
|
||||
|
||||
install( FILES oxygen.themerc DESTINATION ${DATA_INSTALL_DIR}/kstyle/themes )
|
||||
|
83
clients/oxygen/README - config
Normal file
83
clients/oxygen/README - config
Normal file
|
@ -0,0 +1,83 @@
|
|||
# NOTE: The file is ready-to-use. You can just copy it to ~/.config/Oxygen/Style.conf.
|
||||
|
||||
# Config file path:
|
||||
# ~/.config/Oxygen/Style.conf
|
||||
|
||||
# style section: (with def. values)
|
||||
|
||||
[Style]
|
||||
# controls the way the huge bg pixmaps (BackgroundMode=3) are created
|
||||
# 0: No acceleration, the pixmap is fetched from a daemon "oxygenPP" that MUST be running if you wanna use this (maybe removed)
|
||||
# 1: the QGradient classes are used (afaics pure software) - slow
|
||||
# 2: XRender, *use this*, currently the fastest and in matters of color best adjusted function
|
||||
# 3: OpenGL, currently too dark - slow as long as we don't have HW for gl_ext_pixmap_from_texture...
|
||||
Acceleration=2
|
||||
|
||||
# the background appereance
|
||||
# 0: plain color
|
||||
# 1: the beloved scanlines - don't argue, they'll stay ;)
|
||||
# 2: [reserved]
|
||||
# 3: complex lights (i.e. huge pixmap with several gradients, see above)
|
||||
# 4: Simple gradient that brightens on the upper and darkens on the lower end (fallback suggestion 1, alphablending can be cached)
|
||||
# 5: Simple gradient that darkens on left and right side
|
||||
# 6: The window vertically brightens to the center
|
||||
# 7: The window horizontally brightens to the center (like Apples Brushed Metal, fallback suggestion 2, requires realtime alphablending)
|
||||
BackgroundMode=3
|
||||
|
||||
# 0: X
|
||||
# 1: V
|
||||
# 2: O
|
||||
CheckType=0
|
||||
|
||||
# do you like glass/gloss?
|
||||
Aqua=true
|
||||
|
||||
# invert (sink) normal buttons etc by default
|
||||
InverseButtons=false
|
||||
|
||||
# not fully supportes yet, don't try values < 1 here (if you want a stable desktop ;)
|
||||
Scale=1.0
|
||||
|
||||
# whether there shall be unstylish icons in popupmenus
|
||||
ShowMenuIcons=false
|
||||
|
||||
# affects the scanlines
|
||||
# 0: scanlines
|
||||
# 1: checkboard
|
||||
# 2: should have been bricks, looks crap ;P
|
||||
Structure=0
|
||||
|
||||
# the color roles to use for various elements, the counter color is autocalculated
|
||||
# WindowText: 0
|
||||
# Window: 10
|
||||
# Base: 9
|
||||
# Text: 6
|
||||
# Button: 1
|
||||
# ButtonText: 8
|
||||
# Highlight: 12
|
||||
# HighlightedText: 13
|
||||
|
||||
# all buttons, colored parts of combos, sliders (in scrollbars as well)
|
||||
role_button=10
|
||||
role_buttonHover=1
|
||||
# popup menus (also for non editable combos), menubar highlight
|
||||
role_popup=10
|
||||
# the progressbar
|
||||
role_progress=10
|
||||
role_progressGroove=0
|
||||
# tabwidget header
|
||||
role_tab=1
|
||||
|
||||
# the way of tabblending
|
||||
# 0: Jump
|
||||
# 1: CrossFade
|
||||
# 2: ScanlineBlend
|
||||
# 3: SlideIn
|
||||
# 4: SlideOut
|
||||
# 5: RollIn
|
||||
# 6: RollOut
|
||||
# 7: OpenVertically
|
||||
# 8: CloseVertically
|
||||
# 9: OpenHorizontally
|
||||
# 10: CloseHorizontally
|
||||
TabTransition=1
|
668
clients/oxygen/animation.cpp
Normal file
668
clients/oxygen/animation.cpp
Normal file
|
@ -0,0 +1,668 @@
|
|||
/***************************************************************************
|
||||
* Copyright (C) 2006-2007 by Thomas L<EFBFBD>bking *
|
||||
* thomas.luebking@web.de *
|
||||
* *
|
||||
* 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., *
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||||
***************************************************************************/
|
||||
|
||||
#include "oxrender.h"
|
||||
|
||||
#define ANIMATIONS (activeTabs + progressbars.count() + \
|
||||
hoverWidgets.count() + complexHoverWidgets.count() + indexedHoverWidgets.count())
|
||||
|
||||
#define startTimer if (!timer->isActive()) timer->start(50)
|
||||
|
||||
bool TabAnimInfo::eventFilter( QObject* object, QEvent* event ) {
|
||||
if (event->type() != QEvent::Paint || !animStep)
|
||||
return false;
|
||||
QPainter p((QWidget*)object);
|
||||
p.drawPixmap(0,0, tabPix[2]);
|
||||
p.end();
|
||||
return true;
|
||||
}
|
||||
|
||||
// QPixmap::grabWidget(.) currently fails on the background offset,
|
||||
// so we use our own implementation
|
||||
//TODO: fix scrollareas (the scrollbars aren't painted, so check for availability and usage...)
|
||||
QPixmap grabWidget(QWidget * root) {
|
||||
if (!root)
|
||||
return QPixmap();
|
||||
|
||||
QPixmap pix(root->size());
|
||||
QPoint zero(0,0);
|
||||
QPainter p(&pix);
|
||||
const QBrush bg = root->palette().brush(root->backgroundRole());
|
||||
if (bg.style() == Qt::TexturePattern)
|
||||
p.drawTiledPixmap(root->rect(), bg.texture(), root->mapTo(root->topLevelWidget(), zero));
|
||||
else
|
||||
p.fillRect(root->rect(), bg);
|
||||
p.end();
|
||||
|
||||
QList <QWidget*> widgets = root->findChildren<QWidget*>();
|
||||
|
||||
// resizing (in case)
|
||||
if (root->testAttribute(Qt::WA_PendingResizeEvent) ||
|
||||
!root->testAttribute(Qt::WA_WState_Created)) {
|
||||
QResizeEvent e(root->size(), QSize());
|
||||
QApplication::sendEvent(root, &e);
|
||||
}
|
||||
foreach (QWidget *w, widgets) {
|
||||
if (root->testAttribute(Qt::WA_PendingResizeEvent) ||
|
||||
!root->testAttribute(Qt::WA_WState_Created)) {
|
||||
QResizeEvent e(w->size(), QSize());
|
||||
QApplication::sendEvent(w, &e);
|
||||
}
|
||||
}
|
||||
|
||||
// painting
|
||||
QPainter::setRedirected( root, &pix );
|
||||
QPaintEvent e = QPaintEvent(QRect(zero, root->size()));
|
||||
QCoreApplication::sendEvent(root, &e);
|
||||
QPainter::restoreRedirected(root);
|
||||
|
||||
foreach (QWidget *w, widgets) {
|
||||
if (w->isVisibleTo(root)) {
|
||||
if (w->autoFillBackground()) {
|
||||
const QBrush bg = w->palette().brush(w->backgroundRole());
|
||||
QPainter p(&pix);
|
||||
QRect wrect = QRect(zero, w->size()).translated(w->mapTo(root, zero));
|
||||
if (bg.style() == Qt::TexturePattern)
|
||||
p.drawTiledPixmap(wrect, bg.texture(), w->mapTo(root->topLevelWidget(), zero));
|
||||
else
|
||||
p.fillRect(wrect, bg);
|
||||
p.end();
|
||||
}
|
||||
QPainter::setRedirected( w, &pix, -w->mapTo(root, zero) );
|
||||
e = QPaintEvent(QRect(zero, w->size()));
|
||||
QCoreApplication::sendEvent(w, &e);
|
||||
QPainter::restoreRedirected(w);
|
||||
}
|
||||
}
|
||||
|
||||
return pix;
|
||||
}
|
||||
|
||||
static QHash<QWidget*, uint> progressbars;
|
||||
typedef QHash<QWidget*, HoverFadeInfo> HoverFades;
|
||||
static HoverFades hoverWidgets;
|
||||
typedef QHash<QWidget*, ComplexHoverFadeInfo> ComplexHoverFades;
|
||||
static ComplexHoverFades complexHoverWidgets;
|
||||
typedef QHash<QWidget*, IndexedFadeInfo> IndexedFades;
|
||||
static IndexedFades indexedHoverWidgets;
|
||||
static QHash<QTabWidget*, TabAnimInfo*> tabwidgets;
|
||||
static int activeTabs = 0;
|
||||
|
||||
// --- ProgressBars --------------------
|
||||
void OxygenStyle::updateProgressbars() {
|
||||
if (progressbars.isEmpty())
|
||||
return;
|
||||
//Update the registered progressbars.
|
||||
QHash<QWidget*, uint>::iterator iter;
|
||||
QProgressBar *pb;
|
||||
animationUpdate = true;
|
||||
for (iter = progressbars.begin(); iter != progressbars.end(); iter++) {
|
||||
if ( !qobject_cast<QProgressBar*>(iter.key()) )
|
||||
continue;
|
||||
pb = (QProgressBar*)(iter.key());
|
||||
if (pb->paintingActive() || !pb->isVisible() ||
|
||||
!(pb->value() > pb->minimum()) || !(pb->value() < pb->maximum()))
|
||||
continue;
|
||||
// int mod = (pb->orientation() == Qt::Horizontal) ?
|
||||
// (pb->height()-dpi.$8)*2 :
|
||||
// (pb->width()-dpi.$6)*2;
|
||||
// if (!mod)
|
||||
// continue;
|
||||
// ++iter.value();
|
||||
// if (mod)
|
||||
// iter.value() %= mod;
|
||||
if (iter.value() % 2) { // odd - fade out
|
||||
iter.value() -= 2;
|
||||
if (iter.value() < 4) // == 3
|
||||
++iter.value(); // 4
|
||||
if ((iter.value()+1) % 4) // save some cycles...
|
||||
continue;
|
||||
}
|
||||
else { //fade in
|
||||
iter.value() += 2;
|
||||
if (iter.value() > 39) // == 40
|
||||
++iter.value(); // 41
|
||||
if (iter.value() % 4) // save some cycles...
|
||||
continue;
|
||||
}
|
||||
pb->repaint(pb->rect().adjusted(dpi.$3,dpi.$4,-dpi.$3,-dpi.$5));
|
||||
}
|
||||
animationUpdate = false;
|
||||
}
|
||||
|
||||
int OxygenStyle::progressStep(const QWidget *w) const {
|
||||
return progressbars.value(const_cast<QWidget*>(w),0);
|
||||
}
|
||||
|
||||
void OxygenStyle::progressbarDestroyed(QObject* obj) {
|
||||
progressbars.remove(static_cast<QWidget*>(obj));
|
||||
if (!ANIMATIONS) timer->stop();
|
||||
}
|
||||
|
||||
// --- TabWidgets --------------------
|
||||
void OxygenStyle::tabChanged(int index) {
|
||||
if (config.tabTransition == Jump) return; // ugly nothing ;)
|
||||
QTabWidget* tw = (QTabWidget*)sender();
|
||||
QHash<QTabWidget*, TabAnimInfo*>::iterator i = tabwidgets.find(tw);
|
||||
if (i == tabwidgets.end()) // this tab isn't handled for some reason?
|
||||
return;
|
||||
|
||||
TabAnimInfo* tai = i.value();
|
||||
|
||||
QWidget *ctw = tw->widget(tai->lastTab);
|
||||
tai->lastTab = index;
|
||||
if (!ctw)
|
||||
return;
|
||||
tai->tabPix[0] = /*QPixmap::*/grabWidget(ctw);
|
||||
|
||||
ctw = tw->currentWidget();
|
||||
if (!ctw) {
|
||||
tai->tabPix[0] = QPixmap();
|
||||
return;
|
||||
}
|
||||
tai->tabPix[1] = /*QPixmap::*/grabWidget(ctw);
|
||||
tai->tabPix[2] = tai->tabPix[0];
|
||||
|
||||
tai->animStep = 6;
|
||||
// TAB Transitions, NOTE, I'm using a bit X11 code here as this prevents deep pixmap
|
||||
// copies that are sometimes not necessary
|
||||
// TODO make an - ifdef'd ? - qt version for other platforms
|
||||
switch (config.tabTransition) {
|
||||
case CrossFade:
|
||||
OXRender::blend(tai->tabPix[1], tai->tabPix[2], 0.1666);
|
||||
break;
|
||||
case SlideIn: {
|
||||
//TODO handle different bar positions
|
||||
Display *dpy = QX11Info::display();
|
||||
GC gc = XCreateGC( dpy, tai->tabPix[2].handle(), 0, 0 );
|
||||
XCopyArea( dpy, tai->tabPix[1].handle(), tai->tabPix[2].handle(), gc,
|
||||
0, 6*tai->tabPix[1].height()/7,
|
||||
tai->tabPix[1].width(), tai->tabPix[1].height()/7, 0, 0 );
|
||||
XFreeGC ( dpy , gc );
|
||||
break;
|
||||
}
|
||||
case SlideOut: {
|
||||
tai->tabPix[2] = tai->tabPix[1];
|
||||
//TODO handle different bar positions
|
||||
QPainter p(&tai->tabPix[2]);
|
||||
p.drawPixmap(0,0,tai->tabPix[0],0,tai->tabPix[0].height()/7,tai->tabPix[0].width(),6*tai->tabPix[0].height()/7);
|
||||
break;
|
||||
}
|
||||
case RollOut: {
|
||||
Display *dpy = QX11Info::display();
|
||||
GC gc = XCreateGC( dpy, tai->tabPix[2].handle(), 0, 0 );
|
||||
int h = tai->tabPix[1].height()/7;
|
||||
int y = (tai->tabPix[1].height()-h)/2;
|
||||
XCopyArea( dpy, tai->tabPix[1].handle(), tai->tabPix[2].handle(), gc,
|
||||
0, y, tai->tabPix[1].width(), h, 0, y );
|
||||
XFreeGC ( dpy , gc );
|
||||
break;
|
||||
}
|
||||
case RollIn: {
|
||||
Display *dpy = QX11Info::display();
|
||||
GC gc = XCreateGC( dpy, tai->tabPix[2].handle(), 0, 0 );
|
||||
int h = tai->tabPix[1].height()/14;
|
||||
XCopyArea( dpy, tai->tabPix[1].handle(), tai->tabPix[2].handle(), gc,
|
||||
0, 0, tai->tabPix[1].width(), h, 0, 0 );
|
||||
XCopyArea( dpy, tai->tabPix[1].handle(), tai->tabPix[2].handle(), gc,
|
||||
0, tai->tabPix[1].height()-h, tai->tabPix[1].width(), h,
|
||||
0, tai->tabPix[1].height()-h );
|
||||
XFreeGC ( dpy , gc );
|
||||
break;
|
||||
}
|
||||
case CloseVertically: {
|
||||
Display *dpy = QX11Info::display();
|
||||
GC gc = XCreateGC( dpy, tai->tabPix[2].handle(), 0, 0 );
|
||||
int h = tai->tabPix[1].height()/14;
|
||||
XCopyArea( dpy, tai->tabPix[1].handle(), tai->tabPix[2].handle(), gc,
|
||||
0, tai->tabPix[1].height()/2-h, tai->tabPix[1].width(), h, 0, 0 );
|
||||
XCopyArea( dpy, tai->tabPix[1].handle(), tai->tabPix[2].handle(), gc,
|
||||
0, tai->tabPix[1].height()/2, tai->tabPix[1].width(), h,
|
||||
0, tai->tabPix[1].height()-h );
|
||||
XFreeGC ( dpy , gc );
|
||||
break;
|
||||
}
|
||||
case OpenVertically: {
|
||||
tai->tabPix[2] = tai->tabPix[1];
|
||||
QPainter p(&tai->tabPix[2]);
|
||||
int h = 6*tai->tabPix[0].height()/14;
|
||||
p.drawPixmap(0,0,tai->tabPix[0],0,tai->tabPix[0].height()/2-h,
|
||||
tai->tabPix[0].width(),h);
|
||||
p.drawPixmap(0,tai->tabPix[0].height()-h,tai->tabPix[0],
|
||||
0,tai->tabPix[0].height()/2,tai->tabPix[0].width(),h);
|
||||
break;
|
||||
}
|
||||
case CloseHorizontally: {
|
||||
Display *dpy = QX11Info::display();
|
||||
GC gc = XCreateGC( dpy, tai->tabPix[2].handle(), 0, 0 );
|
||||
int w = tai->tabPix[1].width()/14;
|
||||
XCopyArea( dpy, tai->tabPix[1].handle(), tai->tabPix[2].handle(), gc,
|
||||
tai->tabPix[1].width()/2-w, 0, w, tai->tabPix[1].height(), 0, 0 );
|
||||
XCopyArea( dpy, tai->tabPix[1].handle(), tai->tabPix[2].handle(), gc,
|
||||
tai->tabPix[1].width()/2, 0, w, tai->tabPix[1].height(),
|
||||
tai->tabPix[1].width()-w, 0 );
|
||||
XFreeGC ( dpy , gc );
|
||||
break;
|
||||
}
|
||||
case OpenHorizontally: {
|
||||
tai->tabPix[2] = tai->tabPix[1];
|
||||
QPainter p(&tai->tabPix[2]);
|
||||
int w = 6*tai->tabPix[0].width()/14;
|
||||
p.drawPixmap(0,0,tai->tabPix[0],tai->tabPix[0].width()/2-w,0,
|
||||
w,tai->tabPix[0].height());
|
||||
p.drawPixmap(tai->tabPix[0].width()-w,0,tai->tabPix[0],
|
||||
tai->tabPix[0].width()/2,0,w,tai->tabPix[0].height());
|
||||
break;
|
||||
}
|
||||
case ScanlineBlend:
|
||||
default: {
|
||||
Display *dpy = QX11Info::display();
|
||||
GC gc = XCreateGC( dpy, tai->tabPix[2].handle(), 0, 0 );
|
||||
for (int i = 6; i < tai->tabPix[2].height(); i+=6)
|
||||
XCopyArea( dpy, tai->tabPix[1].handle(), tai->tabPix[2].handle(), gc,
|
||||
0, i, tai->tabPix[1].width(), 1, 0, i );
|
||||
XFreeGC ( dpy , gc );
|
||||
}
|
||||
}
|
||||
ctw->parentWidget()->installEventFilter(tai);
|
||||
_BLOCKEVENTS_(ctw);
|
||||
QList<QWidget*> widgets = ctw->findChildren<QWidget*>();
|
||||
foreach(QWidget *widget, widgets) {
|
||||
_BLOCKEVENTS_(widget);
|
||||
if (widget->autoFillBackground()) {
|
||||
tai->autofillingWidgets.append(widget);
|
||||
widget->setAutoFillBackground(false);
|
||||
}
|
||||
}
|
||||
ctw->repaint();
|
||||
startTimer;
|
||||
}
|
||||
|
||||
void OxygenStyle::updateTabAnimation() {
|
||||
if (tabwidgets.isEmpty())
|
||||
return;
|
||||
QHash<QTabWidget*, TabAnimInfo*>::iterator i;
|
||||
activeTabs = 0;
|
||||
TabAnimInfo* tai;
|
||||
QWidget *ctw = 0, *widget = 0; QList<QWidget*> widgets;
|
||||
int index;
|
||||
for (i = tabwidgets.begin(); i != tabwidgets.end(); i++) {
|
||||
tai = i.value();
|
||||
if (!tai->animStep)
|
||||
continue;
|
||||
ctw = i.key()->currentWidget();
|
||||
if (! --(tai->animStep)) { // zero, stop animation
|
||||
tai->tabPix[2] =
|
||||
tai->tabPix[1] =
|
||||
tai->tabPix[0] = QPixmap();
|
||||
ctw->parentWidget()->removeEventFilter(tai);
|
||||
_UNBLOCKEVENTS_(ctw);
|
||||
widgets = ctw->findChildren<QWidget*>();
|
||||
// ctw->repaint();
|
||||
foreach(widget, widgets) {
|
||||
index = tai->autofillingWidgets.indexOf(widget);
|
||||
if (index != -1) {
|
||||
tai->autofillingWidgets.removeAt(index);
|
||||
widget->setAutoFillBackground(true);
|
||||
}
|
||||
_UNBLOCKEVENTS_(widget);
|
||||
widget->update(); //if necessary
|
||||
}
|
||||
ctw->repaint(); //asap
|
||||
tai->autofillingWidgets.clear();
|
||||
continue;
|
||||
}
|
||||
++activeTabs;
|
||||
switch (config.tabTransition) {
|
||||
case CrossFade:
|
||||
OXRender::blend(tai->tabPix[1], tai->tabPix[2], 1.1666-0.1666*tai->animStep);
|
||||
break;
|
||||
case SlideIn: {
|
||||
//TODO handle different bar positions
|
||||
Display *dpy = QX11Info::display();
|
||||
GC gc = XCreateGC( dpy, tai->tabPix[2].handle(), 0, 0 );
|
||||
XCopyArea( dpy, tai->tabPix[1].handle(), tai->tabPix[2].handle(), gc,
|
||||
0, tai->animStep*tai->tabPix[1].height()/7,
|
||||
tai->tabPix[1].width(), (7-tai->animStep)*tai->tabPix[1].height()/7,
|
||||
0, 0 );
|
||||
XFreeGC ( dpy , gc );
|
||||
break;
|
||||
}
|
||||
case SlideOut: {
|
||||
tai->tabPix[2] = tai->tabPix[1];
|
||||
//TODO handle different bar positions
|
||||
QPainter p(&tai->tabPix[2]);
|
||||
p.drawPixmap(0,0,tai->tabPix[0],0,(7-tai->animStep)*tai->tabPix[0].height()/7,tai->tabPix[0].width(),tai->animStep*tai->tabPix[0].height()/7);
|
||||
break;
|
||||
}
|
||||
case RollOut: {
|
||||
Display *dpy = QX11Info::display();
|
||||
GC gc = XCreateGC( dpy, tai->tabPix[2].handle(), 0, 0 );
|
||||
int h = (7-tai->animStep)*tai->tabPix[1].height()/7;
|
||||
int y = (tai->tabPix[1].height()-h)/2;
|
||||
XCopyArea( dpy, tai->tabPix[1].handle(), tai->tabPix[2].handle(), gc,
|
||||
0, y, tai->tabPix[1].width(), h, 0, y );
|
||||
XFreeGC ( dpy , gc );
|
||||
break;
|
||||
}
|
||||
case RollIn: {
|
||||
Display *dpy = QX11Info::display();
|
||||
GC gc = XCreateGC( dpy, tai->tabPix[2].handle(), 0, 0 );
|
||||
int h = (7-tai->animStep)*tai->tabPix[1].height()/14;
|
||||
XCopyArea( dpy, tai->tabPix[1].handle(), tai->tabPix[2].handle(), gc,
|
||||
0, 0, tai->tabPix[1].width(), h, 0, 0 );
|
||||
XCopyArea( dpy, tai->tabPix[1].handle(), tai->tabPix[2].handle(), gc,
|
||||
0, tai->tabPix[1].height()-h, tai->tabPix[1].width(), h,
|
||||
0, tai->tabPix[1].height()-h );
|
||||
XFreeGC ( dpy , gc );
|
||||
break;
|
||||
}
|
||||
case CloseVertically: {
|
||||
Display *dpy = QX11Info::display();
|
||||
GC gc = XCreateGC( dpy, tai->tabPix[2].handle(), 0, 0 );
|
||||
int h = (7-tai->animStep)*tai->tabPix[1].height()/14;
|
||||
XCopyArea( dpy, tai->tabPix[1].handle(), tai->tabPix[2].handle(), gc,
|
||||
0, tai->tabPix[1].height()/2-h, tai->tabPix[1].width(), h, 0, 0 );
|
||||
XCopyArea( dpy, tai->tabPix[1].handle(), tai->tabPix[2].handle(), gc,
|
||||
0, tai->tabPix[1].height()/2, tai->tabPix[1].width(), h,
|
||||
0, tai->tabPix[1].height()-h );
|
||||
XFreeGC ( dpy , gc );
|
||||
break;
|
||||
}
|
||||
case OpenVertically: {
|
||||
tai->tabPix[2] = tai->tabPix[1];
|
||||
QPainter p(&tai->tabPix[2]);
|
||||
int h = tai->animStep*tai->tabPix[0].height()/14;
|
||||
p.drawPixmap(0,0,tai->tabPix[0],0,tai->tabPix[0].height()/2-h,
|
||||
tai->tabPix[0].width(),h);
|
||||
p.drawPixmap(0,tai->tabPix[0].height()-h,tai->tabPix[0],
|
||||
0,tai->tabPix[0].height()/2,tai->tabPix[0].width(),h);
|
||||
break;
|
||||
}
|
||||
case CloseHorizontally: {
|
||||
Display *dpy = QX11Info::display();
|
||||
GC gc = XCreateGC( dpy, tai->tabPix[2].handle(), 0, 0 );
|
||||
int w = (7-tai->animStep)*tai->tabPix[1].width()/14;
|
||||
XCopyArea( dpy, tai->tabPix[1].handle(), tai->tabPix[2].handle(), gc,
|
||||
tai->tabPix[1].width()/2-w, 0, w, tai->tabPix[1].height(), 0, 0 );
|
||||
XCopyArea( dpy, tai->tabPix[1].handle(), tai->tabPix[2].handle(), gc,
|
||||
tai->tabPix[1].width()/2, 0, w, tai->tabPix[1].height(),
|
||||
tai->tabPix[1].width()-w, 0 );
|
||||
XFreeGC ( dpy , gc );
|
||||
break;
|
||||
}
|
||||
case OpenHorizontally: {
|
||||
tai->tabPix[2] = tai->tabPix[1];
|
||||
QPainter p(&tai->tabPix[2]);
|
||||
int w = tai->animStep*tai->tabPix[0].width()/14;
|
||||
p.drawPixmap(0,0,tai->tabPix[0],tai->tabPix[0].width()/2-w,0,
|
||||
w,tai->tabPix[0].height());
|
||||
p.drawPixmap(tai->tabPix[0].width()-w,0,tai->tabPix[0],
|
||||
tai->tabPix[0].width()/2,0,w,tai->tabPix[0].height());
|
||||
break;
|
||||
}
|
||||
case ScanlineBlend:
|
||||
default: {
|
||||
Display *dpy = QX11Info::display();
|
||||
GC gc = XCreateGC( dpy, tai->tabPix[2].handle(), 0, 0 );
|
||||
for (int i = tai->animStep; i < tai->tabPix[2].height(); i+=6)
|
||||
XCopyArea( dpy, tai->tabPix[1].handle(), tai->tabPix[2].handle(), gc,
|
||||
0, i, tai->tabPix[1].width(), 1, 0, i );
|
||||
XFreeGC ( dpy , gc );
|
||||
}
|
||||
}
|
||||
ctw->parentWidget()->repaint();
|
||||
}
|
||||
if (!ANIMATIONS) timer->stop();
|
||||
}
|
||||
|
||||
void OxygenStyle::tabDestroyed(QObject* obj) {
|
||||
tabwidgets.remove(static_cast<QTabWidget*>(obj));
|
||||
// delete tai;
|
||||
if (!ANIMATIONS) timer->stop();
|
||||
}
|
||||
|
||||
|
||||
// -- Buttons etc. -------------------------------
|
||||
void OxygenStyle::updateFades() {
|
||||
if (hoverWidgets.isEmpty())
|
||||
return;
|
||||
HoverFades::iterator it = hoverWidgets.begin();
|
||||
while (it != hoverWidgets.end()) {
|
||||
if (it.value().fadeIn) {
|
||||
it.value().step += 1;
|
||||
it.key()->update();
|
||||
if (it.value().step > 7)
|
||||
it = hoverWidgets.erase(it);
|
||||
else
|
||||
++it;
|
||||
}
|
||||
else { // fade out
|
||||
it.value().step-=2;
|
||||
it.key()->update();
|
||||
if (it.value().step < 1)
|
||||
it = hoverWidgets.erase(it);
|
||||
else
|
||||
++it;
|
||||
}
|
||||
}
|
||||
if (!ANIMATIONS) timer->stop();
|
||||
}
|
||||
|
||||
void OxygenStyle::fadeIn(QWidget *widget) {
|
||||
HoverFades::iterator it = hoverWidgets.find(widget);
|
||||
if (it == hoverWidgets.end()) {
|
||||
it = hoverWidgets.insert(widget, HoverFadeInfo(1, true));
|
||||
}
|
||||
it.value().fadeIn = true;
|
||||
connect(widget, SIGNAL(destroyed(QObject*)), this, SLOT(fadeDestroyed(QObject*)));
|
||||
startTimer;
|
||||
}
|
||||
|
||||
void OxygenStyle::fadeOut(QWidget *widget) {
|
||||
HoverFades::iterator it = hoverWidgets.find(widget);
|
||||
if (it == hoverWidgets.end()) {
|
||||
it = hoverWidgets.insert(widget, HoverFadeInfo(6, false));
|
||||
}
|
||||
it.value().fadeIn = false;
|
||||
connect(widget, SIGNAL(destroyed(QObject*)), this, SLOT(fadeDestroyed(QObject*)));
|
||||
startTimer;
|
||||
}
|
||||
|
||||
void OxygenStyle::fadeDestroyed(QObject* obj) {
|
||||
hoverWidgets.remove(static_cast<QWidget*>(obj));
|
||||
if (!ANIMATIONS) timer->stop();
|
||||
}
|
||||
|
||||
int OxygenStyle::hoverStep(const QWidget *widget) const {
|
||||
if (!widget)
|
||||
return 0;
|
||||
HoverFades::iterator it = hoverWidgets.find(const_cast<QWidget*>(widget));
|
||||
if (it != hoverWidgets.end())
|
||||
return it.value().step;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// -- Complex controls ----------------------
|
||||
|
||||
void OxygenStyle::updateComplexFades() {
|
||||
if (complexHoverWidgets.isEmpty())
|
||||
return;
|
||||
bool update;
|
||||
ComplexHoverFades::iterator it = complexHoverWidgets.begin();
|
||||
while (it != complexHoverWidgets.end()) {
|
||||
ComplexHoverFadeInfo &info = it.value();
|
||||
update = false;
|
||||
for (SubControl control = (SubControl)0x01;
|
||||
control <= (SubControl)0x80;
|
||||
control = (SubControl)(control<<1)) {
|
||||
if (info.fadingInControls & control) {
|
||||
update = true;
|
||||
info.steps[control] += 2;
|
||||
if (info.steps.value(control) > 4)
|
||||
info.fadingInControls &= ~control;
|
||||
}
|
||||
else if (info.fadingOutControls & control) {
|
||||
update = true;
|
||||
--info.steps[control];
|
||||
if (info.steps.value(control) < 1)
|
||||
info.fadingOutControls &= ~control;
|
||||
}
|
||||
}
|
||||
if (update)
|
||||
it.key()->update();
|
||||
if (info.activeSubControls == SC_None && // needed to detect changes!
|
||||
info.fadingOutControls == SC_None &&
|
||||
info.fadingInControls == SC_None)
|
||||
it = complexHoverWidgets.erase(it);
|
||||
else
|
||||
++it;
|
||||
}
|
||||
if (!ANIMATIONS) timer->stop();
|
||||
}
|
||||
|
||||
const ComplexHoverFadeInfo *OxygenStyle::complexHoverFadeInfo(const QWidget *widget,
|
||||
SubControls activeSubControls) const {
|
||||
QWidget *w = const_cast<QWidget*>(widget);
|
||||
ComplexHoverFades::iterator it = complexHoverWidgets.find(w);
|
||||
if (it == complexHoverWidgets.end()) {
|
||||
// we have no entry yet
|
||||
if (activeSubControls == SC_None)
|
||||
return 0; // no need here
|
||||
// ...but we'll need one
|
||||
it = complexHoverWidgets.insert(w, ComplexHoverFadeInfo());
|
||||
connect(widget, SIGNAL(destroyed(QObject*)),
|
||||
this, SLOT(complexFadeDestroyed(QObject*)));
|
||||
startTimer;
|
||||
}
|
||||
// we now have an entry - check for validity and update in case
|
||||
ComplexHoverFadeInfo *info = &it.value();
|
||||
if (info->activeSubControls != activeSubControls) { // sth. changed
|
||||
SubControls diff = info->activeSubControls ^ activeSubControls;
|
||||
SubControls newActive = diff & activeSubControls;
|
||||
SubControls newDead = diff & info->activeSubControls;
|
||||
info->fadingInControls &= ~newDead;
|
||||
info->fadingInControls |= newActive;
|
||||
info->fadingOutControls &= ~newActive;
|
||||
info->fadingOutControls |= newDead;
|
||||
info->activeSubControls = activeSubControls;
|
||||
for (SubControl control = (SubControl)0x01;
|
||||
control <= (SubControl)0x80;
|
||||
control = (SubControl)(control<<1)) {
|
||||
if (newActive & control)
|
||||
info->steps[control] = 1;
|
||||
else if (newDead & control) {
|
||||
info->steps[control] = 6;
|
||||
}
|
||||
}
|
||||
}
|
||||
return info;
|
||||
}
|
||||
|
||||
void OxygenStyle::complexFadeDestroyed(QObject* obj) {
|
||||
complexHoverWidgets.remove(static_cast<QWidget*>(obj));
|
||||
if (!ANIMATIONS) timer->stop();
|
||||
}
|
||||
|
||||
// -- Indexed items like menus, tabs ---------------------
|
||||
void OxygenStyle::updateIndexedFades() {
|
||||
if (indexedHoverWidgets.isEmpty())
|
||||
return;
|
||||
IndexedFades::iterator it;
|
||||
QHash<long int, int>::iterator stepIt;
|
||||
it = indexedHoverWidgets.begin();
|
||||
while (it != indexedHoverWidgets.end()) {
|
||||
IndexedFadeInfo &info = it.value();
|
||||
if (info.fadingInIndices.isEmpty() && info.fadingOutIndices.isEmpty()) {
|
||||
++it;
|
||||
continue;
|
||||
}
|
||||
|
||||
stepIt = info.fadingInIndices.begin();
|
||||
while (stepIt != info.fadingInIndices.end()) {
|
||||
stepIt.value() += 2;
|
||||
if (stepIt.value() > 4)
|
||||
stepIt = info.fadingInIndices.erase(stepIt);
|
||||
else
|
||||
++stepIt;
|
||||
}
|
||||
|
||||
stepIt = info.fadingOutIndices.begin();
|
||||
while (stepIt != info.fadingOutIndices.end()) {
|
||||
--stepIt.value();
|
||||
if (stepIt.value() < 1)
|
||||
stepIt = info.fadingOutIndices.erase(stepIt);
|
||||
else
|
||||
++stepIt;
|
||||
}
|
||||
|
||||
it.key()->update();
|
||||
|
||||
if (info.index == 0L && // nothing actually hovered
|
||||
info.fadingInIndices.isEmpty() && // no fade ins
|
||||
info.fadingOutIndices.isEmpty()) // no fade outs
|
||||
it = indexedHoverWidgets.erase(it);
|
||||
else
|
||||
++it;
|
||||
}
|
||||
if (!ANIMATIONS) timer->stop();
|
||||
}
|
||||
|
||||
const IndexedFadeInfo *OxygenStyle::indexedFadeInfo(const QWidget *widget,
|
||||
long int index) const {
|
||||
QWidget *w = const_cast<QWidget*>(widget);
|
||||
IndexedFades::iterator it = indexedHoverWidgets.find(w);
|
||||
if (it == indexedHoverWidgets.end()) {
|
||||
// we have no entry yet
|
||||
if (index == 0L)
|
||||
return 0L;
|
||||
// ... but we'll need one
|
||||
it = indexedHoverWidgets.insert(w, IndexedFadeInfo(0L));
|
||||
connect(widget, SIGNAL(destroyed(QObject*)),
|
||||
this, SLOT(indexedFadeDestroyed(QObject*)));
|
||||
startTimer;
|
||||
}
|
||||
// we now have an entry - check for validity and update in case
|
||||
IndexedFadeInfo *info = &it.value();
|
||||
if (info->index != index) { // sth. changed
|
||||
info->fadingInIndices[index] = 1;
|
||||
if (info->index)
|
||||
info->fadingOutIndices[info->index] = 6;
|
||||
info->index = index;
|
||||
}
|
||||
return info;
|
||||
}
|
||||
|
||||
void OxygenStyle::indexedFadeDestroyed(QObject* obj) {
|
||||
indexedHoverWidgets.remove(static_cast<QWidget*>(obj));
|
||||
if (!ANIMATIONS) timer->stop();
|
||||
}
|
||||
|
||||
int IndexedFadeInfo::step(long int index) {
|
||||
typedef QHash<long int, int> Index2Step;
|
||||
Index2Step::iterator stepIt;
|
||||
for (stepIt = fadingInIndices.begin(); stepIt != fadingInIndices.end(); stepIt++)
|
||||
if (stepIt.key() == index)
|
||||
return stepIt.value();
|
||||
for (stepIt = fadingOutIndices.begin(); stepIt != fadingOutIndices.end(); stepIt++)
|
||||
if (stepIt.key() == index)
|
||||
return stepIt.value();
|
||||
return 0;
|
||||
}
|
127
clients/oxygen/debug.h
Normal file
127
clients/oxygen/debug.h
Normal file
|
@ -0,0 +1,127 @@
|
|||
#define PRINTDEVICE(p) qWarning("device is %s", (p->device()->devType() == QInternal::Widget) ?\
|
||||
"Widget": (p->device()->devType() == QInternal::Pixmap) ?\
|
||||
"Pixmap": (p->device()->devType() == QInternal::Printer) ?\
|
||||
"Printer": (p->device()->devType() == QInternal::Picture) ?\
|
||||
"Picture": (p->device()->devType() == QInternal::UndefinedDevice) ?\
|
||||
"UndefinedDevice": "fuckdevice!" );
|
||||
|
||||
#define PRINTFLAGS(f) qWarning("Style Flags:\n%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s",\
|
||||
f & QStyle::Style_Default ? "Default, " : "",\
|
||||
f & QStyle::Style_Enabled ? "Enabled, " : "",\
|
||||
f & QStyle::Style_Raised ? "Raised, " : "",\
|
||||
f & QStyle::Style_Sunken ? "Sunken, " : "",\
|
||||
f & QStyle::Style_Off ? "Off, " : "",\
|
||||
f & QStyle::Style_NoChange ? "NoChange, " : "",\
|
||||
f & QStyle::Style_On ? "On, " : "",\
|
||||
f & QStyle::Style_Down ? "Down, " : "",\
|
||||
f & QStyle::Style_Horizontal ? "Horizontal, " : "",\
|
||||
f & QStyle::Style_HasFocus ? "HasFocus, " : "",\
|
||||
f & QStyle::Style_Top ? "Top, " : "",\
|
||||
f & QStyle::Style_Bottom ? "Bottom, " : "",\
|
||||
f & QStyle::Style_FocusAtBorder ? "FocusAtBorder, " : "",\
|
||||
f & QStyle::Style_AutoRaise ? "AutoRaise, " : "",\
|
||||
f & QStyle::Style_MouseOver ? "MouseOver, " : "",\
|
||||
f & QStyle::Style_Up ? "Style_Up, " : "",\
|
||||
f & QStyle::Style_Selected ? "Selected, " : "",\
|
||||
f & QStyle::Style_HasFocus ? "HasFocus, " : "",\
|
||||
f & QStyle::Style_Active ? "Active, " : "",\
|
||||
f & QStyle::Style_ButtonDefault ? "ButtonDefault" : "" )
|
||||
|
||||
#define PRINTEVENT(e) qWarning("Event: %s",\
|
||||
e->type() == QEvent::Timer ? " Timer " : \
|
||||
e->type() == QEvent::MouseButtonPress ? " MouseButtonPress " : \
|
||||
e->type() == QEvent::MouseButtonRelease ? " MouseButtonRelease " : \
|
||||
e->type() == QEvent::MouseButtonDblClick ? " MouseButtonDblClick " : \
|
||||
e->type() == QEvent::MouseMove ? " MouseMove " : \
|
||||
e->type() == QEvent::KeyPress ? " KeyPress " : \
|
||||
e->type() == QEvent::KeyRelease ? " KeyRelease " : \
|
||||
e->type() == QEvent::FocusIn ? " FocusIn " : \
|
||||
e->type() == QEvent::FocusOut ? " FocusOut " : \
|
||||
e->type() == QEvent::Enter ? " Enter " : \
|
||||
e->type() == QEvent::Leave ? " Leave " : \
|
||||
e->type() == QEvent::Paint ? " Paint " : \
|
||||
e->type() == QEvent::Move ? " Move " : \
|
||||
e->type() == QEvent::Resize ? " Resize " : \
|
||||
e->type() == QEvent::Create ? " Create " : \
|
||||
e->type() == QEvent::Destroy ? " Destroy " : \
|
||||
e->type() == QEvent::Show ? " Show " : \
|
||||
e->type() == QEvent::Hide ? " Hide " : \
|
||||
e->type() == QEvent::Close ? " Close " : \
|
||||
e->type() == QEvent::Quit ? " Quit " : \
|
||||
e->type() == QEvent::Reparent ? " Reparent " : \
|
||||
e->type() == QEvent::ShowMinimized ? " ShowMinimized " : \
|
||||
e->type() == QEvent::ShowNormal ? " ShowNormal " : \
|
||||
e->type() == QEvent::WindowActivate ? " WindowActivate " : \
|
||||
e->type() == QEvent::WindowDeactivate ? " WindowDeactivate " : \
|
||||
e->type() == QEvent::ShowToParent ? " ShowToParent " : \
|
||||
e->type() == QEvent::HideToParent ? " HideToParent " : \
|
||||
e->type() == QEvent::ShowMaximized ? " ShowMaximized " : \
|
||||
e->type() == QEvent::ShowFullScreen ? " ShowFullScreen " : \
|
||||
e->type() == QEvent::Accel ? " Accel " : \
|
||||
e->type() == QEvent::Wheel ? " Wheel " : \
|
||||
e->type() == QEvent::AccelAvailable ? " AccelAvailable " : \
|
||||
e->type() == QEvent::CaptionChange ? " CaptionChange " : \
|
||||
e->type() == QEvent::IconChange ? " IconChange " : \
|
||||
e->type() == QEvent::ParentFontChange ? " ParentFontChange " : \
|
||||
e->type() == QEvent::ApplicationFontChange ? " ApplicationFontChange " : \
|
||||
e->type() == QEvent::ParentPaletteChange ? " ParentPaletteChange " : \
|
||||
e->type() == QEvent::ApplicationPaletteChange ? " ApplicationPaletteChange " : \
|
||||
e->type() == QEvent::PaletteChange ? " PaletteChange " : \
|
||||
e->type() == QEvent::Clipboard ? " Clipboard " : \
|
||||
e->type() == QEvent::Speech ? " Speech " : \
|
||||
e->type() == QEvent::SockAct ? " SockAct " : \
|
||||
e->type() == QEvent::AccelOverride ? " AccelOverride " : \
|
||||
e->type() == QEvent::DeferredDelete ? " DeferredDelete " : \
|
||||
e->type() == QEvent::DragEnter ? " DragEnter " : \
|
||||
e->type() == QEvent::DragMove ? " DragMove " : \
|
||||
e->type() == QEvent::DragLeave ? " DragLeave " : \
|
||||
e->type() == QEvent::Drop ? " Drop " : \
|
||||
e->type() == QEvent::DragResponse ? " DragResponse " : \
|
||||
e->type() == QEvent::ChildInserted ? " ChildInserted " : \
|
||||
e->type() == QEvent::ChildRemoved ? " ChildRemoved " : \
|
||||
e->type() == QEvent::LayoutHint ? " LayoutHint " : \
|
||||
e->type() == QEvent::ShowWindowRequest ? " ShowWindowRequest " : \
|
||||
e->type() == QEvent::WindowBlocked ? " WindowBlocked " : \
|
||||
e->type() == QEvent::WindowUnblocked ? " WindowUnblocked " : \
|
||||
e->type() == QEvent::ActivateControl ? " ActivateControl " : \
|
||||
e->type() == QEvent::DeactivateControl ? " DeactivateControl " : \
|
||||
e->type() == QEvent::ContextMenu ? " ContextMenu " : \
|
||||
e->type() == QEvent::IMStart ? " IMStart " : \
|
||||
e->type() == QEvent::IMCompose ? " IMCompose " : \
|
||||
e->type() == QEvent::IMEnd ? " IMEnd " : \
|
||||
e->type() == QEvent::Accessibility ? " Accessibility " : \
|
||||
e->type() == QEvent::TabletMove ? " TabletMove " : \
|
||||
e->type() == QEvent::LocaleChange ? " LocaleChange " : \
|
||||
e->type() == QEvent::LanguageChange ? " LanguageChange " : \
|
||||
e->type() == QEvent::LayoutDirectionChange ? " LayoutDirectionChange " : \
|
||||
e->type() == QEvent::Style ? " Style " : \
|
||||
e->type() == QEvent::TabletPress ? " TabletPress " : \
|
||||
e->type() == QEvent::TabletRelease ? " TabletRelease " : \
|
||||
e->type() == QEvent::OkRequest ? " OkRequest " : \
|
||||
e->type() == QEvent::HelpRequest ? " HelpRequest " : \
|
||||
e->type() == QEvent::WindowStateChange ? " WindowStateChange " : \
|
||||
e->type() == QEvent::IconDrag ? " IconDrag " : "Unknown Event");
|
||||
|
||||
#define PRINTCOMPLEXCONTROL(cc) qWarning("Complex Control: %s",\
|
||||
QStyle::CC_SpinWidget ? " QStyle::CC_SpinWidget " : \
|
||||
QStyle::CC_ComboBox ? " CC_ComboBox " : \
|
||||
QStyle::CC_ScrollBar ? " CC_ScrollBar " : \
|
||||
QStyle::CC_Slider ? " CC_Slider " : \
|
||||
QStyle::CC_ToolButton ? " CC_ToolButton " : \
|
||||
QStyle::CC_TitleBar ? "CC_TitleBar " : \
|
||||
QStyle::CC_ListView ? "CC_ListView " : "Unknow Control");
|
||||
|
||||
#define _IDENTIFYOBJECT_(o) qWarning("%s (%s)%s%s (%s)", o->name(), o->className(), o->parent() ? " is child of " : " has no daddy", o->parent() ? o->parent()->name() : "", o->parent() ? o->parent()->className() : "!")
|
||||
|
||||
#define _COMPARECOLORS_(c1,c2) qWarning("%d/%d/%d vs. %d/%d/%d", c1.red(), c1.green(), c1.blue(), c2.red(), c2.green(), c2.blue());
|
||||
|
||||
// #define MOUSEDEBUG
|
||||
#undef MOUSEDEBUG
|
||||
|
||||
//#define FUNCTIONALBG
|
||||
#undef FUNCTIONALBG
|
||||
|
||||
#include <qtimer.h>
|
||||
#define _PROFILESTART_ QTime timer; int time; timer.start();
|
||||
#define _PROFILERESTART_ timer.restart();
|
||||
#define _PROFILESTOP_(_STRING_) time = timer.elapsed(); qWarning("%s: %d",_STRING_,time);
|
625
clients/oxygen/drawcomplexcontrol.cpp
Normal file
625
clients/oxygen/drawcomplexcontrol.cpp
Normal file
|
@ -0,0 +1,625 @@
|
|||
/***************************************************************************
|
||||
* Copyright (C) 2006-2007 by Thomas L<EFBFBD>bking *
|
||||
* thomas.luebking@web.de *
|
||||
* *
|
||||
* 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., *
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||||
***************************************************************************/
|
||||
|
||||
#include <QComboBox>
|
||||
#include <QPainter>
|
||||
#include <QTime>
|
||||
// #include <QPixmapCache>
|
||||
#include <QStyleOptionComplex>
|
||||
#include <cmath>
|
||||
#include "oxygen.h"
|
||||
|
||||
using namespace Oxygen;
|
||||
|
||||
extern Config config;
|
||||
extern Dpi dpi;
|
||||
|
||||
#include "inlinehelp.cpp"
|
||||
#include "makros.h"
|
||||
|
||||
void OxygenStyle::drawComplexControl ( ComplexControl control, const QStyleOptionComplex * option, QPainter * painter, const QWidget * widget) const
|
||||
{
|
||||
Q_ASSERT(option);
|
||||
Q_ASSERT(painter);
|
||||
|
||||
bool sunken = option->state & State_Sunken;
|
||||
bool isEnabled = option->state & State_Enabled;
|
||||
bool hover = isEnabled && (option->state & State_MouseOver);
|
||||
bool hasFocus = option->state & State_HasFocus;
|
||||
|
||||
switch ( control )
|
||||
{
|
||||
case CC_SpinBox: // A spinbox, like QSpinBox
|
||||
if (const QStyleOptionSpinBox *sb =
|
||||
qstyleoption_cast<const QStyleOptionSpinBox *>(option)) {
|
||||
QStyleOptionSpinBox copy = *sb;
|
||||
int uh = 0;
|
||||
|
||||
if (sb->frame && (sb->subControls & SC_SpinBoxFrame))
|
||||
drawPrimitive ( PE_PanelLineEdit, sb, painter, widget );
|
||||
|
||||
if (!isEnabled)
|
||||
break; // why bother the user with elements he can't use... ;)
|
||||
|
||||
Tile::PosFlags pf;
|
||||
|
||||
if (sb->subControls & SC_SpinBoxUp) {
|
||||
copy.subControls = SC_SpinBoxUp;
|
||||
copy.rect = subControlRect(CC_SpinBox, sb, SC_SpinBoxUp, widget);
|
||||
uh = copy.rect.height();
|
||||
|
||||
pf = Tile::Top | Tile::Left | Tile::Right;
|
||||
isEnabled = sb->stepEnabled & QAbstractSpinBox::StepUpEnabled;
|
||||
hover = isEnabled && (sb->activeSubControls == SC_SpinBoxUp);
|
||||
sunken = sunken && (sb->activeSubControls == SC_SpinBoxUp);
|
||||
|
||||
int dx = copy.rect.width()/4, dy = copy.rect.height()/4;
|
||||
copy.rect.adjust(dx, 2*dy,-dx,-dpi.$1);
|
||||
|
||||
QColor c;
|
||||
if (hover)
|
||||
c = COLOR(Highlight);
|
||||
else if (isEnabled)
|
||||
c = COLOR(Text);
|
||||
else
|
||||
c = midColor(COLOR(Base), QPalette::Text);
|
||||
|
||||
painter->setPen(c);
|
||||
drawPrimitive(PE_IndicatorSpinUp, ©, painter, widget);
|
||||
}
|
||||
|
||||
if (sb->subControls & SC_SpinBoxDown) {
|
||||
copy.subControls = SC_SpinBoxDown;
|
||||
copy.rect = subControlRect(CC_SpinBox, sb, SC_SpinBoxDown, widget);
|
||||
|
||||
pf = Tile::Bottom | Tile::Left | Tile::Right;
|
||||
isEnabled = sb->stepEnabled & QAbstractSpinBox::StepDownEnabled;
|
||||
hover = isEnabled && (sb->activeSubControls == SC_SpinBoxDown);
|
||||
sunken = sunken && (sb->activeSubControls == SC_SpinBoxDown);
|
||||
|
||||
int dx = copy.rect.width()/4, dy = copy.rect.height()/4;
|
||||
copy.rect.adjust(dx, dpi.$1,-dx,-2*dy);
|
||||
|
||||
QColor c;
|
||||
if (hover)
|
||||
c = COLOR(Highlight);
|
||||
else if (isEnabled)
|
||||
c = COLOR(Text);
|
||||
else
|
||||
c = midColor(COLOR(Base), QPalette::Text);
|
||||
|
||||
painter->setPen(c);
|
||||
drawPrimitive(PE_IndicatorSpinDown, ©, painter, widget);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case CC_GroupBox:
|
||||
if (const QStyleOptionGroupBox *groupBox =
|
||||
qstyleoption_cast<const QStyleOptionGroupBox *>(option)) {
|
||||
if (groupBox->subControls & QStyle::SC_GroupBoxFrame) {
|
||||
QStyleOptionFrameV2 frame;
|
||||
frame.QStyleOption::operator=(*groupBox);
|
||||
frame.features = groupBox->features;
|
||||
frame.lineWidth = groupBox->lineWidth;
|
||||
frame.midLineWidth = groupBox->midLineWidth;
|
||||
frame.rect = subControlRect(CC_GroupBox, option, SC_GroupBoxFrame, widget);
|
||||
drawPrimitive(PE_FrameGroupBox, &frame, painter, widget);
|
||||
}
|
||||
|
||||
// Draw title
|
||||
if ((groupBox->subControls & QStyle::SC_GroupBoxLabel) &&
|
||||
!groupBox->text.isEmpty()) {
|
||||
QColor textColor = groupBox->textColor;
|
||||
if (textColor.isValid()) painter->setPen(textColor);
|
||||
QFont tmpfnt = painter->font(); tmpfnt.setBold(true);
|
||||
painter->setFont ( tmpfnt );
|
||||
QStyleOptionGroupBox copy = *groupBox; copy.fontMetrics = QFontMetrics(tmpfnt);
|
||||
QRect textRect = subControlRect(CC_GroupBox, ©, SC_GroupBoxLabel, widget);
|
||||
int alignment = Qt::AlignCenter; //int(groupBox->textAlignment);
|
||||
if (!styleHint(QStyle::SH_UnderlineShortcut, option, widget))
|
||||
alignment |= Qt::TextHideMnemonic;
|
||||
else
|
||||
alignment |= Qt::TextShowMnemonic;
|
||||
|
||||
drawItemText(painter, textRect, alignment, groupBox->palette, isEnabled, groupBox->text,
|
||||
textColor.isValid() ? QPalette::NoRole : QPalette::Foreground);
|
||||
int x = textRect.bottom(); textRect = RECT; textRect.setTop(x);
|
||||
x = textRect.width()/4; textRect.adjust(x,0,-x,0);
|
||||
shadows.line[0][Sunken].render(textRect, painter);
|
||||
}
|
||||
|
||||
// Draw checkbox // TODO: sth better - maybe a round thing in the upper left corner...? also doesn't hover - yet.
|
||||
if (groupBox->subControls & SC_GroupBoxCheckBox) {
|
||||
QStyleOptionButton box;
|
||||
box.QStyleOption::operator=(*groupBox);
|
||||
box.rect = subControlRect(CC_GroupBox, option, SC_GroupBoxCheckBox, widget);
|
||||
drawPrimitive(PE_IndicatorCheckBox, &box, painter, widget);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case CC_ComboBox: // A combobox, like QComboBox
|
||||
if (const QStyleOptionComboBox *cmb =
|
||||
qstyleoption_cast<const QStyleOptionComboBox *>(option)) {
|
||||
QRect ar, r = RECT.adjusted(0,0,0,-dpi.$2);
|
||||
const QComboBox* combo = widget ?
|
||||
qobject_cast<const QComboBox*>(widget) : 0;
|
||||
const bool listShown = combo && combo->view() &&
|
||||
((QWidget*)(combo->view()))->isVisible();
|
||||
const bool reverse = (option->direction == Qt::RightToLeft);
|
||||
|
||||
// do we have an arrow?
|
||||
if ((cmb->subControls & SC_ComboBoxArrow))
|
||||
ar = subControlRect(CC_ComboBox, cmb, SC_ComboBoxArrow, widget);
|
||||
|
||||
// the label
|
||||
if ((cmb->subControls & SC_ComboBoxFrame) && cmb->frame) {
|
||||
if (cmb->editable)
|
||||
drawPrimitive(PE_PanelLineEdit, option, painter, widget);
|
||||
else {
|
||||
drawPrimitive(PE_PanelButtonBevel, option, painter, widget);
|
||||
}
|
||||
}
|
||||
|
||||
// the arrow
|
||||
if (!ar.isNull()) {
|
||||
ar.adjust(ar.width()/3,ar.height()/3,-ar.width()/3,-ar.height()/3);
|
||||
QStyleOptionComboBox tmpOpt = *cmb;
|
||||
PrimitiveElement arrow;
|
||||
if (!listShown)
|
||||
arrow = PE_IndicatorArrowDown;
|
||||
else if (reverse)
|
||||
arrow = PE_IndicatorArrowRight;
|
||||
else
|
||||
arrow = PE_IndicatorArrowLeft;
|
||||
if (cmb->editable)
|
||||
hover = hover && (cmb->activeSubControls == SC_ComboBoxArrow);
|
||||
painter->setRenderHint ( QPainter::Antialiasing, true );
|
||||
painter->save();
|
||||
|
||||
painter->setPen(COLOR(Text));
|
||||
if (hover || listShown) {
|
||||
if (cmb->editable)
|
||||
painter->setPen(COLOR(Highlight));
|
||||
}
|
||||
tmpOpt.rect = ar;
|
||||
drawPrimitive(arrow, &tmpOpt, painter, widget);
|
||||
painter->restore();
|
||||
}
|
||||
}
|
||||
break;
|
||||
case CC_ScrollBar: // A scroll bar, like QScrollBar
|
||||
if (const QStyleOptionSlider *scrollbar =
|
||||
qstyleoption_cast<const QStyleOptionSlider *>(option)) {
|
||||
// Make a copy here and reset it for each primitive.
|
||||
QStyleOptionSlider newScrollbar = *scrollbar;
|
||||
|
||||
// TODO: this is a stupid hack, move the whole special scrollbar painting here!
|
||||
if (widget && widget->parentWidget() &&
|
||||
widget->parentWidget()->parentWidget() &&
|
||||
widget->parentWidget()->parentWidget()->inherits("QComboBoxListView")) {
|
||||
painter->fillRect(RECT, PAL.brush(QPalette::Base));
|
||||
newScrollbar.state |= State_Item;
|
||||
}
|
||||
|
||||
State saveFlags = newScrollbar.state;
|
||||
if (scrollbar->minimum == scrollbar->maximum)
|
||||
saveFlags &= ~State_Enabled;
|
||||
|
||||
SubControls hoverControls = scrollbar->activeSubControls &
|
||||
(SC_ScrollBarSubLine | SC_ScrollBarAddLine | SC_ScrollBarSlider);
|
||||
const ComplexHoverFadeInfo *info =
|
||||
complexHoverFadeInfo(widget, hoverControls);
|
||||
|
||||
#define PAINT_ELEMENT(_SC_, _CE_)\
|
||||
if (scrollbar->subControls & _SC_) {\
|
||||
newScrollbar.rect = scrollbar->rect;\
|
||||
newScrollbar.state = saveFlags;\
|
||||
newScrollbar.rect = subControlRect(control, &newScrollbar, _SC_, widget);\
|
||||
if (newScrollbar.rect.isValid()) {\
|
||||
if (!(scrollbar->activeSubControls & _SC_))\
|
||||
newScrollbar.state &= ~(State_Sunken | State_MouseOver);\
|
||||
if (info && (info->fadingInControls & _SC_ || info->fadingOutControls & _SC_))\
|
||||
const_cast<OxygenStyle*>( this )->complexStep = info->steps.value(_SC_); \
|
||||
else \
|
||||
const_cast<OxygenStyle*>( this )->complexStep = 0; \
|
||||
drawControl(_CE_, &newScrollbar, painter, widget);\
|
||||
}\
|
||||
}//
|
||||
|
||||
PAINT_ELEMENT(SC_ScrollBarSubLine, CE_ScrollBarSubLine);
|
||||
PAINT_ELEMENT(SC_ScrollBarAddLine, CE_ScrollBarAddLine);
|
||||
PAINT_ELEMENT(SC_ScrollBarSubPage, CE_ScrollBarSubPage);
|
||||
PAINT_ELEMENT(SC_ScrollBarAddPage, CE_ScrollBarAddPage);
|
||||
// PAINT_ELEMENT(SC_ScrollBarFirst, CE_ScrollBarFirst);
|
||||
// PAINT_ELEMENT(SC_ScrollBarLast, CE_ScrollBarLast);
|
||||
|
||||
if (scrollbar->subControls & SC_ScrollBarSlider) {
|
||||
newScrollbar.rect = scrollbar->rect;
|
||||
newScrollbar.state = saveFlags;
|
||||
newScrollbar.rect = subControlRect(control, &newScrollbar,
|
||||
SC_ScrollBarSlider, widget);
|
||||
if (newScrollbar.rect.isValid()) {
|
||||
if (!(scrollbar->activeSubControls & SC_ScrollBarSlider))
|
||||
newScrollbar.state &= ~(State_Sunken | State_MouseOver);
|
||||
if (scrollbar->state & State_HasFocus)
|
||||
newScrollbar.state |= (State_Sunken | State_MouseOver);
|
||||
if (info && (info->fadingInControls & SC_ScrollBarSlider ||
|
||||
info->fadingOutControls & SC_ScrollBarSlider))
|
||||
const_cast<OxygenStyle*>( this )->complexStep =
|
||||
info->steps.value(SC_ScrollBarSlider);
|
||||
else
|
||||
const_cast<OxygenStyle*>( this )->complexStep = 0;
|
||||
drawControl(CE_ScrollBarSlider, &newScrollbar, painter, widget);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case CC_Slider: // A slider, like QSlider
|
||||
if (const QStyleOptionSlider *slider =
|
||||
qstyleoption_cast<const QStyleOptionSlider *>(option)) {
|
||||
QRect groove = QCommonStyle::subControlRect(CC_Slider, slider, SC_SliderGroove, widget);
|
||||
QRect handle = QCommonStyle::subControlRect(CC_Slider, slider, SC_SliderHandle, widget);
|
||||
|
||||
isEnabled = isEnabled && (slider->maximum > slider->minimum);
|
||||
hover = isEnabled && hover && (slider->activeSubControls & SC_SliderHandle);
|
||||
sunken = sunken && (slider->activeSubControls & SC_SliderHandle);
|
||||
|
||||
const int ground = 0;
|
||||
|
||||
if ((slider->subControls & SC_SliderGroove) &&
|
||||
groove.isValid()) {
|
||||
QRect r;
|
||||
QColor c = btnBgColor(PAL, isEnabled, hasFocus);
|
||||
if ( slider->orientation == Qt::Horizontal ) {
|
||||
// the groove
|
||||
groove.adjust(0,handle.height()/3,0,-handle.height()/3);
|
||||
fillWithMask(painter, groove, gradient(COLOR(Window),
|
||||
groove.height(), Qt::Vertical, GradSunken),
|
||||
&masks.button);
|
||||
#if 0
|
||||
// the "temperature"
|
||||
if (slider->sliderPosition != ground &&
|
||||
slider->maximum > slider->minimum) {
|
||||
groove.adjust(0,dpi.$1,0,-dpi.$1);
|
||||
int groundX = groove.width() * (ground - slider->minimum) /
|
||||
(slider->maximum - slider->minimum);
|
||||
bool rightSide = slider->sliderPosition > ground;
|
||||
if (slider->upsideDown) {
|
||||
rightSide = !rightSide;
|
||||
groundX = groove.right() - groundX;
|
||||
}
|
||||
else
|
||||
groundX += groove.left();
|
||||
|
||||
if (rightSide) {
|
||||
groove.setLeft(groundX);
|
||||
groove.setRight(handle.center().x());
|
||||
}
|
||||
else {
|
||||
groove.setLeft(handle.center().x());
|
||||
groove.setRight(groundX);
|
||||
}
|
||||
fillWithMask(painter, groove, gradient(COLOR(Window),
|
||||
groove.height(), Qt::Vertical, config.gradient),
|
||||
&masks.button);
|
||||
}
|
||||
#else
|
||||
groove.adjust(0,dpi.$1,0,-dpi.$1);
|
||||
fillWithMask(painter, groove, gradient(COLOR(Window),
|
||||
groove.height(), Qt::Vertical, config.gradient),
|
||||
&masks.button);
|
||||
#endif
|
||||
// for later (cosmetic)
|
||||
handle.translate(0,dpi.$3);
|
||||
}
|
||||
else { // Vertical
|
||||
// the groove
|
||||
groove.adjust(handle.width()/3,0,-handle.width()/3,0);
|
||||
fillWithMask(painter, groove, gradient(COLOR(Window),
|
||||
groove.width(), Qt::Horizontal, GradSunken),
|
||||
&masks.button);
|
||||
#if 0
|
||||
// the "temperature"
|
||||
if (slider->sliderPosition != ground &&
|
||||
slider->maximum > slider->minimum) {
|
||||
groove.adjust(dpi.$1,0,-dpi.$1,0);
|
||||
int groundY = groove.height() * (ground - slider->minimum) /
|
||||
(slider->maximum - slider->minimum);
|
||||
bool upside = slider->sliderPosition > ground;
|
||||
if (slider->upsideDown) {
|
||||
upside = !upside;
|
||||
groundY = groove.bottom() - groundY;
|
||||
}
|
||||
else
|
||||
groundY += groove.top();
|
||||
|
||||
if (upside) {
|
||||
groove.setBottom(handle.center().y());
|
||||
groove.setTop(groundY);
|
||||
}
|
||||
else {
|
||||
groove.setBottom(groundY);
|
||||
groove.setTop(handle.center().y());
|
||||
}
|
||||
fillWithMask(painter, groove, gradient(COLOR(Window),
|
||||
groove.width(), Qt::Horizontal, config.gradient),
|
||||
&masks.button);
|
||||
}
|
||||
#else
|
||||
groove.adjust(dpi.$1,0,-dpi.$1,0);
|
||||
fillWithMask(painter, groove, gradient(COLOR(Window),
|
||||
groove.width(), Qt::Horizontal, config.gradient),
|
||||
&masks.button);
|
||||
#endif
|
||||
// for later (cosmetic)
|
||||
handle.translate(dpi.$3,0);
|
||||
}
|
||||
}
|
||||
|
||||
int direction = 0;
|
||||
if (slider->orientation == Qt::Vertical)
|
||||
++direction;
|
||||
|
||||
// ticks - TODO: paint our own ones?
|
||||
if ((slider->subControls & SC_SliderTickmarks) &&
|
||||
(slider->tickPosition != QSlider::NoTicks) ) {
|
||||
if (slider->tickPosition == QSlider::TicksAbove) {
|
||||
direction += 2;
|
||||
if (slider->orientation == Qt::Horizontal)
|
||||
handle.translate(0,-dpi.$6);
|
||||
else
|
||||
handle.translate(-dpi.$6,0);
|
||||
}
|
||||
QStyleOptionSlider tmpSlider = *slider;
|
||||
tmpSlider.subControls = SC_SliderTickmarks;
|
||||
QCommonStyle::drawComplexControl(control, &tmpSlider, painter, widget);
|
||||
}
|
||||
|
||||
// handle
|
||||
if (slider->subControls & SC_SliderHandle) {
|
||||
int step = 0;
|
||||
if (!hasFocus) {
|
||||
const ComplexHoverFadeInfo *info =
|
||||
complexHoverFadeInfo(widget, slider->activeSubControls & SC_SliderHandle);
|
||||
if (info && (info->fadingInControls & SC_SliderHandle ||
|
||||
info->fadingOutControls & SC_SliderHandle))
|
||||
step = info->steps.value(SC_SliderHandle);
|
||||
}
|
||||
// shadow
|
||||
QPoint xy = handle.topLeft();
|
||||
painter->drawPixmap(sunken ? xy + QPoint(dpi.$1,dpi.$1) : xy,
|
||||
shadows.slider[direction][sunken][hover]);
|
||||
// gradient
|
||||
xy += QPoint(dpi.$2, direction?dpi.$1:0);
|
||||
fillWithMask(painter, xy, gradient(btnBgColor(PAL, isEnabled,
|
||||
hover || hasFocus, step), dpi.SliderControl-dpi.$4,
|
||||
Qt::Vertical, config.gradBtn), masks.slider[direction]);
|
||||
painter->drawPixmap(xy, lights.slider[direction]);
|
||||
// SAVE_PEN;
|
||||
// painter->setPen(btnFgColor(PAL, isEnabled, hover || hasFocus, step));
|
||||
// painter->drawPoint(handle.center());
|
||||
// RESTORE_PEN;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case CC_ToolButton: // A tool button, like QToolButton
|
||||
// special handling for the tabbar scrollers ----------------------------------
|
||||
if (widget && widget->parentWidget() &&
|
||||
qobject_cast<QTabBar*>(widget->parent())) {
|
||||
QColor c = widget->parentWidget()->palette().color(config.role_tab[0]);
|
||||
QColor c2 = widget->parentWidget()->palette().color(config.role_tab[1]);
|
||||
if (sunken) {
|
||||
int dy = (RECT.height()-RECT.width())/2;
|
||||
QRect r = RECT.adjusted(dpi.$2,dy,-dpi.$2,-dy);
|
||||
painter->drawTiledPixmap(r, gradient(c, r.height(), Qt::Vertical, GradSunken));
|
||||
}
|
||||
painter->save();
|
||||
painter->setPen( isEnabled ? c2 : midColor(c, c2) );
|
||||
drawControl(CE_ToolButtonLabel, option, painter, widget);
|
||||
painter->restore();
|
||||
break;
|
||||
}
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
if (const QStyleOptionToolButton *toolbutton
|
||||
= qstyleoption_cast<const QStyleOptionToolButton *>(option)) {
|
||||
QRect menuarea = subControlRect(control, toolbutton, SC_ToolButtonMenu, widget);
|
||||
QRect button = subControlRect(control, toolbutton, SC_ToolButton, widget);
|
||||
State bflags = toolbutton->state;
|
||||
|
||||
if ((bflags & State_AutoRaise) && !hover)
|
||||
bflags &= ~State_Raised;
|
||||
|
||||
State mflags = bflags;
|
||||
|
||||
if (toolbutton->activeSubControls & SC_ToolButton)
|
||||
bflags |= State_Sunken;
|
||||
|
||||
hover = isEnabled && (bflags & (State_Sunken | State_On | State_Raised | State_HasFocus));
|
||||
|
||||
QStyleOption tool(0); tool.palette = toolbutton->palette;
|
||||
|
||||
// frame around whole button
|
||||
if (hover) {
|
||||
tool.rect = RECT; tool.state = bflags;
|
||||
drawPrimitive(PE_PanelButtonTool, &tool, painter, widget);
|
||||
}
|
||||
|
||||
// don't paint a dropdown arrow iff the button's really pressed
|
||||
if (!(bflags & State_Sunken) &&
|
||||
(toolbutton->subControls & SC_ToolButtonMenu)) {
|
||||
if (toolbutton->activeSubControls & SC_ToolButtonMenu)
|
||||
painter->drawTiledPixmap(menuarea, gradient(COLOR(Window),
|
||||
menuarea.height(), Qt::Vertical,
|
||||
GradSunken));
|
||||
QPen oldPen = painter->pen();
|
||||
painter->setPen(midColor(COLOR(Window), COLOR(WindowText), 2, 1));
|
||||
tool.rect = menuarea; tool.state = mflags;
|
||||
drawPrimitive(PE_IndicatorButtonDropDown, &tool, painter, widget);
|
||||
painter->setPen(oldPen);
|
||||
if (hover) {
|
||||
menuarea.setLeft(button.right()-shadows.line[1][Sunken].thickness()/2);
|
||||
shadows.line[1][Sunken].render(menuarea, painter);
|
||||
}
|
||||
}
|
||||
|
||||
// label in the toolbutton area
|
||||
QStyleOptionToolButton label = *toolbutton;
|
||||
label.rect = button;
|
||||
drawControl(CE_ToolButtonLabel, &label, painter, widget);
|
||||
}
|
||||
break;
|
||||
case CC_TitleBar: // A Title bar, like what is used in Q3Workspace
|
||||
if (const QStyleOptionTitleBar *tb =
|
||||
qstyleoption_cast<const QStyleOptionTitleBar *>(option))
|
||||
{
|
||||
painter->fillRect(RECT, PAL.brush(QPalette::Window));
|
||||
QRect ir;
|
||||
if (option->subControls & SC_TitleBarLabel)
|
||||
{
|
||||
ir = subControlRect(CC_TitleBar, tb, SC_TitleBarLabel, widget);
|
||||
painter->setPen(PAL.color(QPalette::WindowText));
|
||||
painter->drawText(ir.x() + dpi.$2, ir.y(), ir.width() - dpi.$2, ir.height(), Qt::AlignCenter | Qt::TextSingleLine, tb->text);
|
||||
}
|
||||
|
||||
|
||||
#define PAINT_WINDOW_BUTTON(_scbtn_, _spbtn_)\
|
||||
{\
|
||||
tmpOpt.rect = subControlRect(CC_TitleBar, tb, _scbtn_, widget);\
|
||||
if (tb->activeSubControls & _scbtn_)\
|
||||
tmpOpt.state = tb->state;\
|
||||
else\
|
||||
tmpOpt.state &= ~(State_Sunken | State_MouseOver);\
|
||||
pm = standardPixmap ( _spbtn_, &tmpOpt, widget );\
|
||||
painter->drawPixmap(tmpOpt.rect.topLeft(), pm);\
|
||||
}
|
||||
|
||||
QPixmap pm;
|
||||
QStyleOptionTitleBar tmpOpt = *tb;
|
||||
if (tb->subControls & SC_TitleBarCloseButton)
|
||||
PAINT_WINDOW_BUTTON(SC_TitleBarCloseButton, SP_TitleBarCloseButton)
|
||||
|
||||
if (tb->subControls & SC_TitleBarMaxButton
|
||||
&& tb->titleBarFlags & Qt::WindowMaximizeButtonHint)
|
||||
{
|
||||
if (tb->titleBarState & Qt::WindowMaximized)
|
||||
PAINT_WINDOW_BUTTON(SC_TitleBarNormalButton, SP_TitleBarNormalButton)
|
||||
else
|
||||
PAINT_WINDOW_BUTTON(SC_TitleBarMaxButton, SP_TitleBarMaxButton)
|
||||
}
|
||||
|
||||
if (tb->subControls & SC_TitleBarMinButton
|
||||
&& tb->titleBarFlags & Qt::WindowMinimizeButtonHint)
|
||||
{
|
||||
if (tb->titleBarState & Qt::WindowMinimized)
|
||||
PAINT_WINDOW_BUTTON(SC_TitleBarNormalButton, SP_TitleBarNormalButton)
|
||||
else
|
||||
PAINT_WINDOW_BUTTON(SC_TitleBarMinButton, SP_TitleBarMinButton)
|
||||
}
|
||||
|
||||
if (tb->subControls & SC_TitleBarNormalButton &&
|
||||
tb->titleBarFlags & Qt::WindowMinMaxButtonsHint)
|
||||
PAINT_WINDOW_BUTTON(SC_TitleBarNormalButton, SP_TitleBarNormalButton)
|
||||
|
||||
if (tb->subControls & SC_TitleBarShadeButton)
|
||||
PAINT_WINDOW_BUTTON(SC_TitleBarShadeButton, SP_TitleBarShadeButton)
|
||||
|
||||
if (tb->subControls & SC_TitleBarUnshadeButton)
|
||||
PAINT_WINDOW_BUTTON(SC_TitleBarUnshadeButton, SP_TitleBarUnshadeButton)
|
||||
|
||||
if (tb->subControls & SC_TitleBarContextHelpButton
|
||||
&& tb->titleBarFlags & Qt::WindowContextHelpButtonHint)
|
||||
PAINT_WINDOW_BUTTON(SC_TitleBarContextHelpButton, SP_TitleBarContextHelpButton)
|
||||
|
||||
if (tb->subControls & SC_TitleBarSysMenu
|
||||
&& tb->titleBarFlags & Qt::WindowSystemMenuHint)
|
||||
{
|
||||
if (!tb->icon.isNull())
|
||||
{
|
||||
ir = subControlRect(CC_TitleBar, tb, SC_TitleBarSysMenu, widget);
|
||||
tb->icon.paint(painter, ir);
|
||||
}
|
||||
else
|
||||
PAINT_WINDOW_BUTTON(SC_TitleBarSysMenu, SP_TitleBarMenuButton)
|
||||
}
|
||||
}
|
||||
break;
|
||||
// case CC_Q3ListView: // Used for drawing the Q3ListView class
|
||||
case CC_Dial: // A dial, like QDial
|
||||
if (const QStyleOptionSlider *dial =
|
||||
qstyleoption_cast<const QStyleOptionSlider *>(option)) {
|
||||
painter->save();
|
||||
QRect rect = RECT;
|
||||
if (rect.width() > rect.height()) {
|
||||
rect.setLeft(rect.x()+(rect.width()-rect.height())/2); rect.setWidth(rect.height());
|
||||
}
|
||||
else {
|
||||
rect.setTop(rect.y()+(rect.height()-rect.width())/2); rect.setHeight(rect.width());
|
||||
}
|
||||
|
||||
int d = qMax(rect.width()/6, dpi.$10);
|
||||
int r = (rect.width()-d)/2;
|
||||
qreal a;
|
||||
if (dial->maximum == dial->minimum)
|
||||
a = M_PI / 2;
|
||||
else if (dial->dialWrapping)
|
||||
a = M_PI * 3 / 2 - (dial->sliderValue - dial->minimum) * 2 * M_PI
|
||||
/ (dial->maximum - dial->minimum);
|
||||
else
|
||||
a = (M_PI * 8 - (dial->sliderValue - dial->minimum) * 10 * M_PI
|
||||
/ (dial->maximum - dial->minimum)) / 6;
|
||||
|
||||
QPoint cp((int)(r * cos(a)), -(int)(r * sin(a)));
|
||||
cp += rect.center();
|
||||
|
||||
// the huge ring
|
||||
r = d/2; rect.adjust(r,r,-r,-r);
|
||||
painter->setPen(COLOR(Window).dark(115));
|
||||
painter->setRenderHint( QPainter::Antialiasing );
|
||||
painter->drawEllipse(rect);
|
||||
rect.translate(0, 1);
|
||||
painter->setPen(COLOR(Window).light(108));
|
||||
painter->drawEllipse(rect);
|
||||
// the value
|
||||
QFont fnt = painter->font();
|
||||
fnt.setPixelSize( rect.height()/3 );
|
||||
painter->setFont(fnt);
|
||||
painter->setBrush(Qt::NoBrush);
|
||||
painter->setPen(PAL.foreground().color());
|
||||
drawItemText(painter, rect, Qt::AlignCenter, PAL, isEnabled,
|
||||
QString::number(dial->sliderValue));
|
||||
// the drop
|
||||
painter->setPen(Qt::NoPen);
|
||||
rect = QRect(0,0,d,d);
|
||||
rect.moveCenter(cp);
|
||||
painter->setBrush(QColor(0,0,0,50));
|
||||
painter->drawEllipse(rect);
|
||||
rect.adjust(dpi.$2,dpi.$1,-dpi.$2,-dpi.$2);
|
||||
painter->setBrushOrigin(rect.topLeft());
|
||||
painter->setBrush(gradient(btnBgColor(PAL, isEnabled, hover||hasFocus),
|
||||
rect.height(), Qt::Vertical, GradRadialGloss));
|
||||
painter->drawEllipse(rect);
|
||||
painter->restore();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
QCommonStyle::drawComplexControl( control, option, painter, widget );
|
||||
} // switch
|
||||
}
|
1311
clients/oxygen/drawcontrol.cpp
Normal file
1311
clients/oxygen/drawcontrol.cpp
Normal file
File diff suppressed because it is too large
Load diff
858
clients/oxygen/drawprimitive.cpp
Normal file
858
clients/oxygen/drawprimitive.cpp
Normal file
|
@ -0,0 +1,858 @@
|
|||
/***************************************************************************
|
||||
* Copyright (C) 2006-2007 by Thomas L<EFBFBD>bking *
|
||||
* thomas.luebking@web.de *
|
||||
* *
|
||||
* 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., *
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||||
***************************************************************************/
|
||||
|
||||
#include <QAction>
|
||||
#include <QApplication>
|
||||
#include <QAbstractScrollArea>
|
||||
#include <QComboBox>
|
||||
#include <QDesktopWidget>
|
||||
#include <QLabel>
|
||||
#include <QLayout>
|
||||
#include <QLineEdit>
|
||||
#include <QMenu>
|
||||
#include <QMenuBar>
|
||||
#include <QStyleOptionButton>
|
||||
#include <QPainter>
|
||||
#include <QPainterPath>
|
||||
#include <QX11Info>
|
||||
#include "oxygen.h"
|
||||
#include "oxrender.h"
|
||||
#include "dynamicbrush.h"
|
||||
|
||||
#include <QtDebug>
|
||||
|
||||
#include <cmath>
|
||||
|
||||
using namespace Oxygen;
|
||||
|
||||
extern int bgYoffset_;
|
||||
extern Pixmap shadowPix;
|
||||
extern Config config;
|
||||
extern Dpi dpi;
|
||||
|
||||
#include "inlinehelp.cpp"
|
||||
#include "makros.h"
|
||||
|
||||
|
||||
void OxygenStyle::drawPrimitive ( PrimitiveElement pe, const QStyleOption * option, QPainter * painter, const QWidget * widget) const {
|
||||
Q_ASSERT(option);
|
||||
Q_ASSERT(painter);
|
||||
|
||||
bool sunken = option->state & State_Sunken;
|
||||
bool isEnabled = option->state & State_Enabled;
|
||||
bool hover = isEnabled && (option->state & State_MouseOver);
|
||||
bool hasFocus = option->state & State_HasFocus;
|
||||
bool up = false;
|
||||
|
||||
|
||||
switch ( pe ) {
|
||||
case PE_FrameDefaultButton: // This frame around a default button, e.g. in a dialog.
|
||||
// we swap colors instead, frame only on focus!
|
||||
break;
|
||||
case PE_PanelButtonCommand: // Button used to initiate an action, for example, a QPushButton.
|
||||
case PE_PanelButtonBevel: { // Generic panel with a button bevel.
|
||||
const int $4 = dpi.$4;
|
||||
//bool isOn = option->state & State_On;
|
||||
const QStyleOptionButton* opt = qstyleoption_cast<const QStyleOptionButton*>(option);
|
||||
//bool isDefault = opt && (opt->features & QStyleOptionButton::DefaultButton);
|
||||
|
||||
int step = hoverStep(widget);
|
||||
|
||||
QColor c = btnBgColor(PAL, isEnabled, 0, 0);
|
||||
QRect r = RECT;
|
||||
|
||||
// shadow
|
||||
shadows.button[sunken][step?step:hover*7].render(r, painter);
|
||||
|
||||
r.adjust($4, $4, -$4, -$4);
|
||||
|
||||
// background
|
||||
painter->setRenderHint(QPainter::Antialiasing,false);
|
||||
fillWithMask(painter, r, c, &masks.button);
|
||||
|
||||
// edge and a nice light gradient
|
||||
painter->setRenderHint(QPainter::Antialiasing);
|
||||
QLinearGradient lg(r.x(), r.y(), r.x(), r.bottom());
|
||||
QGradientStops stops;
|
||||
stops << QGradientStop( 0, QColor(255,255,255, (isEnabled&&!sunken ? 220 : 160)) )
|
||||
<< QGradientStop( 0.1, QColor(255,255,255, (isEnabled&&!sunken ? 100 : 60)) )
|
||||
<< QGradientStop( 1, QColor(255,255,255, (isEnabled&&!sunken ? 50 : 35)) );
|
||||
lg.setStops(stops);
|
||||
QLinearGradient lg2(r.x(), r.y(), r.x(), r.bottom());
|
||||
stops.clear();
|
||||
stops << QGradientStop( 0, QColor(255,255,255, 40) )
|
||||
<< QGradientStop( 1, QColor(255,255,255, 0) );
|
||||
lg2.setStops(stops);
|
||||
painter->setPen(QPen(QBrush(lg),1));
|
||||
painter->setBrush(lg2);
|
||||
QRectF rf = r;
|
||||
rf.adjust(0.5, 0.5,-0.5,-0.5);
|
||||
painter->drawRoundRect(rf, int(ceil(9*90.0/r.width())), int(ceil(9*90.0/r.height())));
|
||||
|
||||
// hover effect
|
||||
QRadialGradient rg = QRadialGradient(r.width()/2.0, 0.35*r.height(), qMax(r.width(),r.height())/2.0 - 5, r.width()/2.0, 0.35*r.height());
|
||||
c = btnBgColor(PAL, isEnabled, hover, step);
|
||||
c.setAlpha(190);
|
||||
QColor c2= c;
|
||||
c2.setAlpha(60);
|
||||
stops << QGradientStop( 0, c ) << QGradientStop( 1, c2 );
|
||||
rg.setStops(stops);
|
||||
painter->setPen(Qt::NoPen);
|
||||
painter->setBrush(rg);
|
||||
r.adjust(1,1,-1,-1);
|
||||
painter->drawRoundRect(r, int(ceil(9*90.0/r.width())), int(ceil(9*90.0/r.height())));
|
||||
break;
|
||||
}
|
||||
case PE_PanelButtonTool: { // Panel for a Tool button, used with QToolButton.
|
||||
if (sunken || (option->state & State_On)) {
|
||||
if (sunken) hover = false;
|
||||
/*
|
||||
fillWithMask(painter, RECT,
|
||||
gradient(COLOR(Window), RECT.height(), Qt::Vertical,
|
||||
hover ? GradButton : GradSunken), &masks.button);
|
||||
shadows.lineEdit[1].render(RECT, painter);
|
||||
*/
|
||||
QRect r = RECT;
|
||||
painter->setRenderHint(QPainter::Antialiasing);
|
||||
QRadialGradient rg(r.width()/2, r.height()/2, r.height()/2, r.width()/2, r.height()/4);
|
||||
QGradientStops stops;
|
||||
stops << QGradientStop( 0, QColor(0,0,0, 50) )
|
||||
<< QGradientStop( 1, QColor(0,0,0, 0) );
|
||||
rg.setStops(stops);
|
||||
painter->fillRect(r, rg);
|
||||
rg = QRadialGradient(r.width()/2, r.height()/2, r.height()/2, r.width()/2, 3*r.height()/4);
|
||||
stops.clear();
|
||||
stops << QGradientStop( 0, QColor(255,255,255, 190) )
|
||||
<< QGradientStop( 1, QColor(255,255,255, 0) );
|
||||
rg.setStops(stops);
|
||||
painter->fillRect(r, rg);
|
||||
}
|
||||
/* else if (hover) {
|
||||
fillWithMask(painter, RECT.adjusted(dpi.$2,dpi.$1,-dpi.$2,0),
|
||||
gradient(COLOR(Window), RECT.height(), Qt::Vertical,
|
||||
GradButton), &masks.button);
|
||||
shadows.group.render(RECT, painter, Tile::Ring);
|
||||
}
|
||||
*/ break;
|
||||
}
|
||||
case PE_PanelLineEdit: { // Panel for a QLineEdit.
|
||||
// spinboxes and combos allready have a lineedit as global frame
|
||||
if (widget && widget->parentWidget() &&
|
||||
(widget->parentWidget()->inherits("QAbstractSpinBox") ||
|
||||
widget->parentWidget()->inherits("QComboBox")))
|
||||
break;
|
||||
if (qstyleoption_cast<const QStyleOptionFrame *>(option) &&
|
||||
static_cast<const QStyleOptionFrame *>(option)->lineWidth < 1) {
|
||||
painter->fillRect(RECT, COLOR(Base)); break;
|
||||
}
|
||||
|
||||
if (isEnabled) {
|
||||
fillWithMask(painter, RECT, COLOR(Base), &masks.button);
|
||||
if (hasFocus) {
|
||||
painter->save();
|
||||
painter->setPen(QPen(COLOR(Highlight), dpi.$2));
|
||||
painter->drawLine(RECT.left()+dpi.$4, RECT.bottom(),
|
||||
RECT.right()-dpi.$3, RECT.bottom());
|
||||
painter->restore();
|
||||
}
|
||||
}
|
||||
shadows.lineEdit[isEnabled].render(RECT, painter);
|
||||
break;
|
||||
}
|
||||
case PE_FrameFocusRect: { // Generic focus indicator.
|
||||
painter->save();
|
||||
painter->setBrush(Qt::NoBrush);
|
||||
painter->setPen(COLOR(Highlight));
|
||||
painter->drawLine(RECT.bottomLeft(), RECT.bottomRight());
|
||||
painter->restore();
|
||||
break;
|
||||
}
|
||||
case PE_IndicatorArrowUp: // Generic Up arrow.
|
||||
case PE_IndicatorSpinUp: // Up symbol for a spin widget, for example a QSpinBox.
|
||||
case PE_IndicatorSpinPlus: // Increase symbol for a spin widget.
|
||||
up = true;
|
||||
case PE_IndicatorHeaderArrow: // Arrow used to indicate sorting on a list or table header
|
||||
case PE_IndicatorButtonDropDown: // indicator for a drop down button, for example, a tool button that displays a menu.
|
||||
case PE_IndicatorArrowDown: // Generic Down arrow.
|
||||
case PE_IndicatorSpinDown: // Down symbol for a spin widget.
|
||||
case PE_IndicatorSpinMinus: { // Decrease symbol for a spin widget.
|
||||
if (const QStyleOptionHeader* hopt =
|
||||
qstyleoption_cast<const QStyleOptionHeader*>(option)) {
|
||||
if (hopt->sortIndicator == QStyleOptionHeader::None)
|
||||
break;
|
||||
up = hopt->sortIndicator == QStyleOptionHeader::SortUp;
|
||||
}
|
||||
SAVE_ANTIALIAS;
|
||||
bool hadNoBrush = painter->brush() == Qt::NoBrush;
|
||||
painter->setRenderHint(QPainter::Antialiasing);
|
||||
if (hadNoBrush)
|
||||
painter->setBrush(painter->pen().brush());
|
||||
|
||||
int w = RECT.width();
|
||||
|
||||
// we want a golden mean cut arrow ;) 1:1.6180339887498948482
|
||||
int x[3], y[2];
|
||||
if (w < 8*RECT.height()/5) {
|
||||
if (w%2) --w;
|
||||
x[0] = RECT.x(); x[1] = RECT.right(); x[2] = x[0] + w/2;
|
||||
int h = 5*w/8; if (!(h%2)) --h;
|
||||
y[0] = RECT.y() + (RECT.height()-h)/2; y[1] = y[0] + h;
|
||||
}
|
||||
else {
|
||||
w = 8*RECT.height()/5;
|
||||
if (w%2) --w;
|
||||
x[0] = RECT.x() + (RECT.width()-w)/2; x[1] = x[0] + w; x[2] = x[0] + w/2;
|
||||
y[0] = RECT.y(); y[1] = RECT.bottom();
|
||||
}
|
||||
if (up) {
|
||||
// 0.5 is to have sharp horizontal edges
|
||||
const QPointF points[3] = { QPointF(x[0], y[1]+0.5), QPointF(x[1], y[1]+0.5), QPointF(x[2], y[0]) };
|
||||
painter->drawPolygon(points, 3);
|
||||
}
|
||||
else {
|
||||
// 0.5 is to have sharp horizontal edges
|
||||
const QPointF points[3] = { QPointF(x[0], y[0]-0.5), QPointF(x[1], y[0]-0.5), QPointF(x[2], y[1]) };
|
||||
painter->drawPolygon(points, 3);
|
||||
}
|
||||
if (hadNoBrush)
|
||||
painter->setBrush(Qt::NoBrush);
|
||||
RESTORE_ANTIALIAS;
|
||||
break;
|
||||
}
|
||||
case PE_IndicatorArrowRight: // Generic Right arrow.
|
||||
up = true;
|
||||
case PE_IndicatorArrowLeft: { // Generic Left arrow.
|
||||
SAVE_ANTIALIAS;
|
||||
bool hadNoBrush = painter->brush() == Qt::NoBrush;
|
||||
painter->setRenderHint(QPainter::Antialiasing);
|
||||
if (hadNoBrush)
|
||||
painter->setBrush(painter->pen().brush());
|
||||
int x[2], y[3], h = RECT.height();
|
||||
if (h < 8*RECT.width()/5) {
|
||||
if (h%2) --h;
|
||||
y[0] = RECT.y(); y[1] = RECT.bottom(); y[2] = y[0] + h/2;
|
||||
int w = 5*h/8; if (!(w%2)) --w;
|
||||
x[0] = RECT.x() + (RECT.width()-w)/2; x[1] = x[0] + w;
|
||||
}
|
||||
else {
|
||||
h = 8*RECT.width()/5;
|
||||
if (h%2) --h;
|
||||
y[0] = RECT.y() + (RECT.height()-h)/2; y[1] = y[0] + h; y[2] = y[0] + h/2;
|
||||
x[0] = RECT.x(); x[1] = RECT.right();
|
||||
}
|
||||
if (up) { //right
|
||||
// 0.5 is to have sharp vertical edge
|
||||
const QPointF points[3] = { QPointF(x[0]+0.5, y[0]), QPointF(x[0]+0.5, y[1]), QPointF(x[1], y[2]) };
|
||||
painter->drawPolygon(points, 3);
|
||||
}
|
||||
else {
|
||||
const QPointF points[3] = { QPointF(x[0], y[2]), QPointF(x[1]-0.5, y[0]), QPointF(x[1]-0.5, y[1]) };
|
||||
painter->drawPolygon(points, 3);
|
||||
}
|
||||
if (hadNoBrush)
|
||||
painter->setBrush(Qt::NoBrush);
|
||||
RESTORE_ANTIALIAS;
|
||||
break;
|
||||
}
|
||||
case PE_IndicatorCheckBox: { // On/off indicator, for example, a QCheckBox.
|
||||
|
||||
drawPrimitive(PE_PanelButtonBevel, option, painter, widget);
|
||||
|
||||
if (!(sunken || (option->state & State_Off))) {
|
||||
QColor c = btnFgColor(PAL, isEnabled, hover||hasFocus);
|
||||
painter->save();
|
||||
painter->setRenderHint(QPainter::Antialiasing);
|
||||
QRect r = RECT.adjusted(dpi.$6,dpi.$6,-dpi.$6,-dpi.$6);
|
||||
const QPixmap &fill = gradient(c, r.height(), Qt::Vertical, config.gradBtn);
|
||||
switch (config.checkType) {
|
||||
case 0: {
|
||||
QPen pen(fill, r.width()/5, Qt::SolidLine, Qt::RoundCap, Qt::BevelJoin);
|
||||
painter->setPen(pen);
|
||||
painter->drawLine(r.x(),r.bottom(),r.right(),r.y());
|
||||
if (option->state & State_On)
|
||||
painter->drawLine(r.x(),r.y(),r.right(),r.bottom());
|
||||
break;
|
||||
}
|
||||
default:
|
||||
case 1: {
|
||||
QPen pen(fill, r.width()/5, Qt::SolidLine, Qt::RoundCap, Qt::BevelJoin);
|
||||
painter->setPen(pen);
|
||||
const QPoint points[4] = {
|
||||
QPoint(r.right(), r.top()),
|
||||
QPoint(r.x()+r.width()/3, r.bottom()),
|
||||
QPoint(r.x(), r.bottom()-r.height()/3),
|
||||
QPoint(r.x()+r.width()/3, r.bottom()-r.height()/5)
|
||||
};
|
||||
painter->drawPolygon(points, (option->state & State_On)?4:2);
|
||||
break;
|
||||
}
|
||||
case 2:
|
||||
if (option->state & State_On)
|
||||
painter->fillRect(r, fill);
|
||||
else {
|
||||
QRect r2 = r; r2.setBottom(r.top()+r.height()/3);
|
||||
fillWithMask(painter, r2, fill, &masks.button);
|
||||
r2 = r; r2.setTop(r.bottom()-r.height()/3);
|
||||
fillWithMask(painter, r2, fill, &masks.button);
|
||||
}
|
||||
}
|
||||
painter->restore();
|
||||
}
|
||||
break;
|
||||
}
|
||||
case PE_IndicatorRadioButton: { // Exclusive on/off indicator, for example, a QRadioButton.
|
||||
bool isOn = option->state & State_On;
|
||||
if (isOn) sunken = false;
|
||||
hover = hover && !isOn;
|
||||
const int $2 = dpi.$2, $1 = dpi.$1;
|
||||
int step = isOn ? 0 : hoverStep(widget);
|
||||
QColor c = btnBgColor(PAL, isEnabled, hover||hasFocus, step);
|
||||
QPoint xy = RECT.topLeft();
|
||||
|
||||
// shadow
|
||||
painter->drawPixmap(sunken?xy+QPoint($1,$1):xy, shadows.radio[sunken][hover||hasFocus]);
|
||||
|
||||
// glass
|
||||
xy += QPoint($2,$1);
|
||||
int sz = dpi.ExclusiveIndicator - dpi.$4;
|
||||
if (isEnabled)
|
||||
fillWithMask(painter, xy, gradient(c, sz, Qt::Vertical, config.gradBtn), masks.radio);
|
||||
else
|
||||
fillWithMask(painter, xy, c, masks.radio);
|
||||
painter->save();
|
||||
painter->setBrush(Qt::NoBrush);
|
||||
painter->setPen(Qt::white);
|
||||
painter->setRenderHint(QPainter::Antialiasing);
|
||||
painter->drawEllipse(xy.x(), xy.y(), sz, sz);
|
||||
painter->restore();
|
||||
|
||||
if (isOn) { // drop?
|
||||
xy += QPoint($2,$2);
|
||||
sz -= dpi.$4;
|
||||
QColor c = btnFgColor(PAL, isEnabled, hover||hasFocus);
|
||||
xy += QPoint($2,$2);
|
||||
fillWithMask(painter, xy, gradient(c, sz, Qt::Vertical, config.gradBtn), masks.radioIndicator);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case PE_Q3DockWindowSeparator: // Item separator for Qt 3 compatible dock window and toolbar contents.
|
||||
break;
|
||||
case PE_Frame: { // Generic frame; see also QFrame.
|
||||
if (widget) {
|
||||
// handle the
|
||||
if (widget->inherits("QComboBoxPrivateContainer")) {
|
||||
SAVE_PEN;
|
||||
painter->setPen(COLOR(Base));
|
||||
painter->drawRect(RECT.adjusted(0,0,-1,-1));
|
||||
RESTORE_PEN;
|
||||
break;
|
||||
}
|
||||
|
||||
bool inverse = true, niceFrame = false;
|
||||
QRect rect = RECT; const QRect *outerRect = 0;
|
||||
|
||||
const Tile::Mask *mask = 0L; const Tile::Set *shadow = 0L;
|
||||
if (sunken) {
|
||||
shadow = &shadows.lineEdit[isEnabled];
|
||||
mask = &masks.button;
|
||||
}
|
||||
else if (option->state & State_Raised) {
|
||||
shadow = &shadows.tab;
|
||||
mask = &masks.tab;
|
||||
}
|
||||
QPoint zero;
|
||||
const QBrush *brush = &PAL.brush(widget->backgroundRole());
|
||||
if (qobject_cast<const QFrame*>(widget)) { // frame, can be killed unless...
|
||||
if (widget->inherits("QTextEdit")) { // ...it's a TextEdit!
|
||||
niceFrame = true;
|
||||
inverse = false; brush = &PAL.brush(QPalette::Base);
|
||||
}
|
||||
else { // maybe we need to corect a textlabels margin
|
||||
if (const QLabel* label = qobject_cast<const QLabel*>(widget))
|
||||
if (label->text() != QString() && label->margin() < dpi.$3)
|
||||
const_cast<QLabel*>(label)->setMargin(dpi.$3);
|
||||
break; // painted on visual frame
|
||||
}
|
||||
}
|
||||
else if (qobject_cast<const VisualFrame*>(widget)) {
|
||||
if (widget->parentWidget() && widget->parentWidget()->parentWidget())
|
||||
brush = &PAL.brush(widget->parentWidget()->parentWidget()->backgroundRole());
|
||||
niceFrame = true;
|
||||
zero = widget->mapTo(widget->topLevelWidget(), QPoint(0,0));
|
||||
if (!sunken) {
|
||||
outerRect = &RECT;
|
||||
if (option->state & State_Raised)
|
||||
rect = RECT.adjusted(dpi.$2,dpi.$1,-dpi.$2,-dpi.$4);
|
||||
else
|
||||
rect = RECT.adjusted(dpi.$2,dpi.$2,-dpi.$2,-dpi.$2);
|
||||
}
|
||||
}
|
||||
if (niceFrame) {
|
||||
if (mask)
|
||||
fillWithMask(painter, rect, *brush, mask, Tile::Full, false, zero, inverse, outerRect);
|
||||
if (hasFocus) {
|
||||
painter->save();
|
||||
painter->setPen(QPen(COLOR(Highlight), dpi.$2));
|
||||
painter->drawLine(rect.left()+dpi.$4, rect.bottom(), rect.right()-dpi.$3, rect.bottom());
|
||||
painter->restore();
|
||||
}
|
||||
if (shadow)
|
||||
shadow->render(RECT, painter);
|
||||
else { // plain frame
|
||||
//horizontal
|
||||
shadows.line[false][Sunken].render(RECT, painter, Tile::Full, false);
|
||||
shadows.line[false][Sunken].render(RECT, painter, Tile::Full, true);
|
||||
//vertical
|
||||
shadows.line[true][Sunken].render(RECT, painter, Tile::Full, false);
|
||||
shadows.line[true][Sunken].render(RECT, painter, Tile::Full, true);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
// fallback, we cannot paint shaped frame contents
|
||||
if (sunken)
|
||||
shadows.sunken.render(RECT,painter);
|
||||
else if (option->state & State_Raised)
|
||||
// shadows.raised.render(RECT,painter);
|
||||
break;
|
||||
else {
|
||||
//horizontal
|
||||
shadows.line[false][Sunken].render(RECT, painter, Tile::Full, false);
|
||||
shadows.line[false][Sunken].render(RECT, painter, Tile::Full, true);
|
||||
//vertical
|
||||
shadows.line[true][Sunken].render(RECT, painter, Tile::Full, false);
|
||||
shadows.line[true][Sunken].render(RECT, painter, Tile::Full, true);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case PE_FrameMenu: { // Frame for popup windows/menus; see also QMenu.
|
||||
SAVE_PEN;
|
||||
QRect frame = RECT;
|
||||
int x,y,w,h;
|
||||
frame.getRect(&x, &y, &w, &h);
|
||||
|
||||
painter->setRenderHint(QPainter::Antialiasing);
|
||||
painter->setBrush(Qt::NoBrush);
|
||||
QLinearGradient lg(0, 0, 0, 10);
|
||||
QGradientStops stops;
|
||||
stops << QGradientStop( 0, QColor(255,255,255, 110) )
|
||||
<< QGradientStop( 1, QColor(128,128,128, 60) );
|
||||
lg.setStops(stops);
|
||||
painter->setPen(QPen(QBrush(lg),1));
|
||||
painter->drawLine(QPointF(6.3, 0.5), QPointF(w-6.3, 0.5));
|
||||
painter->drawArc(QRectF(0.5, 0.5, 9.5, 9.5),90*16, 90*16);
|
||||
painter->drawArc(QRectF(w-9.5-0.5, 0.5, 9.5, 9.5), 0, 90*16);
|
||||
|
||||
painter->setPen(QColor(128,128,128, 60));
|
||||
painter->drawLine(QPointF(0.5, 6.3), QPointF(0.5, h-6.3));
|
||||
painter->drawLine(QPointF(w-0.5, 6.3), QPointF(w-0.5, h-6.3));
|
||||
|
||||
lg = QLinearGradient(0, h-10, 0, h);
|
||||
stops.clear();
|
||||
stops << QGradientStop( 0, QColor(128,128,128, 60) )
|
||||
<< QGradientStop( 1, QColor(0,0,0, 50) );
|
||||
lg.setStops(stops);
|
||||
painter->setPen(QPen(QBrush(lg),1));
|
||||
painter->drawArc(QRectF(0.5, h-9.5-0.5, 9.5, 9.5),180*16, 90*16);
|
||||
painter->drawArc(QRectF(w-9.5-0.5, h-9.5-0.5, 9.5, 9.5), 270*16, 90*16);
|
||||
painter->drawLine(QPointF(6.3, h-0.5), QPointF(w-6.3, h-0.5));
|
||||
|
||||
RESTORE_PEN;
|
||||
#if 0
|
||||
if (config.glassMenus) {
|
||||
painter->save();
|
||||
painter->setPen(Qt::white);
|
||||
painter->setBrush(Qt::NoBrush);
|
||||
painter->drawRect(RECT.adjusted(0,0,-1,-1));
|
||||
painter->restore();
|
||||
// painter->fillRect(RECT, Qt::white);
|
||||
}
|
||||
if (config.menuShadow) {
|
||||
QRect rect = RECT.adjusted(0,0, // don't ask...
|
||||
shadows.line[true][Sunken].thickness()+1,
|
||||
shadows.line[false][Sunken].thickness()+1);
|
||||
//horizontal
|
||||
shadows.line[false][Sunken].render(rect, painter, Tile::Full, false);
|
||||
shadows.line[false][Sunken].render(rect, painter, Tile::Full, true);
|
||||
//vertical
|
||||
shadows.line[true][Sunken].render(rect, painter, Tile::Full, false);
|
||||
shadows.line[true][Sunken].render(rect, painter, Tile::Full, true);
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
case PE_PanelMenuBar: // Panel for menu bars.
|
||||
case PE_FrameDockWidget: // Panel frame for dock windows and toolbars.
|
||||
break;
|
||||
case PE_FrameTabWidget: // Frame for tab widgets.
|
||||
if (const QStyleOptionTabWidgetFrame *twf =
|
||||
qstyleoption_cast<const QStyleOptionTabWidgetFrame *>(option)) {
|
||||
|
||||
bool mirror = false, vertical = false;
|
||||
switch (twf->shape) {
|
||||
case QTabBar::RoundedNorth: case QTabBar::TriangularNorth:
|
||||
break;
|
||||
case QTabBar::RoundedSouth: case QTabBar::TriangularSouth:
|
||||
mirror = true; break;
|
||||
case QTabBar::RoundedEast: case QTabBar::TriangularEast:
|
||||
mirror = true;
|
||||
case QTabBar::RoundedWest: case QTabBar::TriangularWest:
|
||||
vertical = true; break;
|
||||
}
|
||||
|
||||
int baseHeight =
|
||||
vertical ? twf->tabBarSize.width() : twf->tabBarSize.height();
|
||||
if (baseHeight < 0)
|
||||
baseHeight = pixelMetric( PM_TabBarBaseHeight, option, widget )-dpi.$2;
|
||||
if (!baseHeight) {
|
||||
shadows.tab.render(RECT, painter);
|
||||
break;
|
||||
}
|
||||
|
||||
QRect rect(RECT), tabRect(RECT), fillRect;
|
||||
int offset = 8;
|
||||
Qt::Orientation o = Qt::Vertical;
|
||||
Tile::PosFlags pf = Tile::Ring;
|
||||
if (vertical) { // east or west
|
||||
o = Qt::Horizontal;
|
||||
rect.adjust(0,offset,0,-offset);
|
||||
if (mirror) { // east
|
||||
rect.setLeft(rect.right()-baseHeight);
|
||||
fillRect = rect.adjusted(0, dpi.$2, -dpi.$3, -dpi.$3);
|
||||
pf &= ~Tile::Left;
|
||||
o = Qt::Horizontal;
|
||||
tabRect.setRight(tabRect.right()-(baseHeight-dpi.$2));
|
||||
}
|
||||
else {
|
||||
rect.setWidth(baseHeight);
|
||||
fillRect = rect.adjusted(dpi.$3, dpi.$2, 0, -dpi.$3);
|
||||
pf &= ~Tile::Right;
|
||||
o = Qt::Horizontal;
|
||||
tabRect.setLeft(tabRect.left()+(baseHeight-dpi.$2));
|
||||
}
|
||||
baseHeight = fillRect.width();
|
||||
}
|
||||
else { // north or south
|
||||
rect.adjust(offset,0,-offset,0);
|
||||
if (mirror) { //south
|
||||
rect.setTop(rect.bottom()-baseHeight);
|
||||
fillRect = rect.adjusted(dpi.$3, 0, -dpi.$3, -dpi.$3);
|
||||
pf &= ~Tile::Top;
|
||||
tabRect.setBottom(tabRect.bottom()-(baseHeight-dpi.$3));
|
||||
}
|
||||
else { // north
|
||||
rect.setHeight(baseHeight);
|
||||
fillRect = rect.adjusted(dpi.$3, dpi.$2, -dpi.$3, 0);
|
||||
pf &= ~Tile::Bottom;
|
||||
tabRect.setTop(tabRect.top()+baseHeight);
|
||||
}
|
||||
baseHeight = fillRect.height();
|
||||
}
|
||||
|
||||
shadows.tab.render(rect, painter, pf);
|
||||
fillWithMask(painter, fillRect, gradient(CONF_COLOR(role_tab[0]), baseHeight, o, config.gradientStrong), &masks.tab, pf | Tile::Center);
|
||||
masks.tab.outline(fillRect, painter, CONF_COLOR(role_tab[0]).dark(110), true, pf);
|
||||
shadows.tab.render(tabRect, painter, Tile::Ring);
|
||||
}
|
||||
break;
|
||||
case PE_FrameLineEdit: // Panel frame for line edits.
|
||||
shadows.lineEdit[isEnabled].render(RECT.adjusted(0,0,0,-dpi.$2),painter);
|
||||
break;
|
||||
case PE_FrameGroupBox: { // Panel frame around group boxes.
|
||||
QRect rect = RECT.adjusted(dpi.$4,dpi.$2,-dpi.$4,0);
|
||||
rect.setHeight(qMax(dpi.$32, RECT.height()));
|
||||
fillWithMask(painter, rect, groupLight(rect.height()), &masks.button,
|
||||
Tile::Full&~Tile::Bottom);
|
||||
rect.setBottom(RECT.bottom()-dpi.$32);
|
||||
shadows.group.render(RECT, painter, Tile::Ring);
|
||||
masks.button.outline(rect, painter, COLOR(Window).light(120), true,
|
||||
Tile::Full&~Tile::Bottom);
|
||||
break;
|
||||
}
|
||||
// case PE_FrameButtonBevel: // Panel frame for a button bevel
|
||||
// case PE_FrameButtonTool: // Panel frame for a tool button
|
||||
case PE_FrameStatusBar: // Frame for a section of a status bar; see also QStatusBar.
|
||||
break;
|
||||
case PE_FrameWindow: // Frame around a MDI window or a docking window.
|
||||
{
|
||||
painter->save();
|
||||
painter->setPen(PAL.color(QPalette::Window).dark(110));
|
||||
painter->drawRect(RECT);
|
||||
painter->restore();
|
||||
break;
|
||||
}
|
||||
case PE_Q3Separator: // Qt 3 compatible generic separator.
|
||||
break;
|
||||
case PE_IndicatorViewItemCheck: // On/off indicator for a view item
|
||||
case PE_Q3CheckListIndicator: // Qt 3 compatible Checkbox part of a list view item.
|
||||
case PE_IndicatorMenuCheckMark: { // Check mark used in a menu.
|
||||
QRect rect;
|
||||
if (RECT.width() > RECT.height())
|
||||
rect.setRect(RECT.x()+(RECT.width()-RECT.height())/2, RECT.y(),
|
||||
RECT.height()-1, RECT.height()-1);
|
||||
else
|
||||
rect.setRect(RECT.x(), RECT.y()+(RECT.height()-RECT.width())/2,
|
||||
RECT.width()-1, RECT.width()-1);
|
||||
int off = rect.width()/4;
|
||||
|
||||
painter->save();
|
||||
const bool selected = option->state & State_Selected && isEnabled;
|
||||
painter->setBrush(Qt::NoBrush);
|
||||
QPalette::ColorRole fgr;
|
||||
if (pe == PE_IndicatorMenuCheckMark) {
|
||||
if (widget)
|
||||
fgr = selected ? widget->backgroundRole() : widget->foregroundRole();
|
||||
else
|
||||
fgr = selected ? QPalette::Window : QPalette::WindowText;
|
||||
}
|
||||
else
|
||||
fgr = selected ? QPalette::HighlightedText : QPalette::Text;
|
||||
|
||||
painter->setPen(PAL.color(fgr));
|
||||
painter->drawRect(rect.adjusted(0, off, -off, 0));
|
||||
|
||||
if (!(option->state & State_Off)) {
|
||||
painter->setRenderHint(QPainter::Antialiasing);
|
||||
if (!(pe == PE_IndicatorMenuCheckMark || selected)) {
|
||||
fgr = QPalette::Highlight;
|
||||
painter->setPen(PAL.color(fgr));
|
||||
}
|
||||
painter->setBrush(PAL.color(fgr));
|
||||
const QPoint points[4] = {
|
||||
QPoint(rect.right(), rect.top()),
|
||||
QPoint(rect.x()+rect.width()/3, rect.bottom()),
|
||||
QPoint(rect.x(), rect.bottom()-rect.height()/3),
|
||||
QPoint(rect.x()+rect.width()/3, rect.bottom()-rect.height()/5)
|
||||
};
|
||||
painter->drawPolygon(points, 4);
|
||||
}
|
||||
painter->restore();
|
||||
break;
|
||||
}
|
||||
case PE_Q3CheckListExclusiveIndicator: // Qt 3 compatible Radio button part of a list view item.
|
||||
painter->save();
|
||||
painter->setRenderHint ( QPainter::Antialiasing );
|
||||
painter->drawEllipse ( RECT );
|
||||
_PRINTFLAGS_;
|
||||
if (option->state & State_On) {
|
||||
painter->setBrush ( painter->pen().color() );
|
||||
painter->drawEllipse ( RECT.adjusted(RECT.width()/4, RECT.height()/4, -RECT.width()/4, -RECT.height()/4) );
|
||||
}
|
||||
painter->restore();
|
||||
break;
|
||||
// case PE_IndicatorProgressChunk: // Section of a progress bar indicator; see also QProgressBar.
|
||||
// case PE_Q3CheckListController: // Qt 3 compatible Controller part of a list view item.
|
||||
case PE_IndicatorBranch: // Lines used to represent the branch of a tree in a tree view.
|
||||
{
|
||||
SAVE_PEN;
|
||||
int mid_h = RECT.x() + RECT.width() / 2;
|
||||
int mid_v = RECT.y() + RECT.height() / 2;
|
||||
int bef_h = mid_h;
|
||||
int bef_v = mid_v;
|
||||
int aft_h = mid_h;
|
||||
int aft_v = mid_v;
|
||||
|
||||
painter->setPen(widget ?
|
||||
midColor( PAL.color(widget->backgroundRole()), PAL.color(widget->foregroundRole())) :
|
||||
midColor( PAL.color(QPalette::Base), PAL.color(QPalette::Text)) );
|
||||
static const int decoration_size = 9;
|
||||
if (option->state & State_Children) {
|
||||
int delta = decoration_size / 2 + 2;
|
||||
bef_h -= delta;
|
||||
bef_v -= delta;
|
||||
aft_h += delta;
|
||||
aft_v += delta;
|
||||
QStyleOption tmpOpt = *option;
|
||||
tmpOpt.rect = QRect(bef_h+2, bef_v+2, decoration_size, decoration_size);
|
||||
drawPrimitive(option->state & State_Open ? PE_IndicatorArrowDown :
|
||||
option->direction == Qt::RightToLeft ? PE_IndicatorArrowLeft :
|
||||
PE_IndicatorArrowRight, &tmpOpt, painter, widget);
|
||||
}
|
||||
if (RECT.x() == -1) { // this is for the first col and i don't see why we'd need a line here
|
||||
RESTORE_PEN;
|
||||
break;
|
||||
}
|
||||
|
||||
if (option->state & (State_Item | State_Sibling))
|
||||
painter->drawLine(mid_h, RECT.y(), mid_h, bef_v);
|
||||
if (option->state & State_Sibling)
|
||||
painter->drawLine(mid_h, aft_v, mid_h, RECT.bottom());
|
||||
if (option->state & State_Item) {
|
||||
if (option->direction == Qt::RightToLeft)
|
||||
painter->drawLine(RECT.left(), mid_v, bef_h, mid_v);
|
||||
else
|
||||
painter->drawLine(aft_h, mid_v, RECT.right(), mid_v);
|
||||
}
|
||||
RESTORE_PEN;
|
||||
break;
|
||||
}
|
||||
case PE_IndicatorDockWidgetResizeHandle: // Resize handle for dock windows.
|
||||
{
|
||||
QPoint *points; int num;
|
||||
const int $12 = dpi.$12, $6 = dpi.$6;
|
||||
if (RECT.width() > RECT.height()) {
|
||||
int x = RECT.left()+RECT.width()/3;
|
||||
int y = RECT.top()+(RECT.height()-$6)/2;
|
||||
num = RECT.width()/(3*$12);
|
||||
if ((RECT.width()/3) % $12) ++num;
|
||||
points = new QPoint[num];
|
||||
for (int i = 0; i < num; ++i) {
|
||||
points[i] = QPoint(x,y); x += $12;
|
||||
}
|
||||
}
|
||||
else {
|
||||
int x = RECT.left()+(RECT.width()-$6)/2;
|
||||
int y = RECT.top()+RECT.height()/3;
|
||||
num = RECT.height()/(3*$12);
|
||||
if ((RECT.height()/3) % $12) ++num;
|
||||
points = new QPoint[num];
|
||||
for (int i = 0; i < num; ++i) {
|
||||
points[i] = QPoint(x,y); y += $12;
|
||||
}
|
||||
}
|
||||
painter->save();
|
||||
painter->setPen(Qt::NoPen);
|
||||
const QPixmap *fill; int cnt = num/2, imp = 1;
|
||||
QPalette::ColorRole role = QPalette::WindowText;
|
||||
if (hover) {
|
||||
role = QPalette::Highlight;
|
||||
imp = 8;
|
||||
}
|
||||
if (num%2)
|
||||
{
|
||||
fill = &gradient(midColor(COLOR(Window), PAL.color(role), 3, imp), $6, Qt::Vertical, GradSunken);
|
||||
fillWithMask(painter, points[cnt], *fill, masks.notch);
|
||||
}
|
||||
--num;
|
||||
for (int i = 0; i < cnt; ++i)
|
||||
{
|
||||
fill = &gradient(midColor(COLOR(Window), PAL.color(role), 3+cnt-i, imp), $6, Qt::Vertical, GradSunken);
|
||||
fillWithMask(painter, points[i], *fill, masks.notch);
|
||||
fillWithMask(painter, points[num-i], *fill, masks.notch);
|
||||
}
|
||||
painter->restore();
|
||||
delete[] points;
|
||||
break;
|
||||
}
|
||||
case PE_IndicatorToolBarHandle: // The handle of a toolbar.
|
||||
if (!(widget && widget->parentWidget()) ||
|
||||
widget->parentWidget()->underMouse()) {
|
||||
painter->save();
|
||||
QRect rect = RECT; bool line = false; int dx(0), dy(0);
|
||||
if (RECT.width() > RECT.height()) {
|
||||
line = (RECT.width() > 9*RECT.height()/2);
|
||||
if (line) {
|
||||
dx = 3*RECT.height()/2; dy = 0;
|
||||
}
|
||||
rect.setLeft(rect.left()+(rect.width()-rect.height())/2);
|
||||
rect.setWidth(rect.height());
|
||||
}
|
||||
else {
|
||||
line = (RECT.height() > 3*RECT.width());
|
||||
if (line) {
|
||||
dx = 0; dy = 3*RECT.width()/2;
|
||||
}
|
||||
rect.setTop(rect.top()+(rect.height()-rect.width())/2);
|
||||
rect.setHeight(rect.width());
|
||||
}
|
||||
QColor c = hover?COLOR(Highlight):COLOR(Window).dark(110);
|
||||
painter->setRenderHint(QPainter::Antialiasing);
|
||||
painter->setBrush(gradient(c, rect.height(), Qt::Vertical, GradSunken));
|
||||
painter->setPen(Qt::NoPen);
|
||||
painter->setBrushOrigin(rect.topLeft());
|
||||
painter->drawEllipse(rect);
|
||||
if (line) {
|
||||
const int $1 = dpi.$1;
|
||||
rect.adjust($1,$1,-$1,-$1);
|
||||
painter->setBrush(gradient(c, rect.height(), Qt::Vertical, GradSunken));
|
||||
rect.translate(-dx,-dy);
|
||||
painter->setBrushOrigin(rect.topLeft());
|
||||
painter->drawEllipse(rect);
|
||||
rect.translate( 2*dx, 2*dy);
|
||||
painter->setBrushOrigin(rect.topLeft());
|
||||
painter->drawEllipse(rect);
|
||||
}
|
||||
painter->restore();
|
||||
}
|
||||
break;
|
||||
case PE_IndicatorToolBarSeparator: // The separator in a toolbar.
|
||||
break;
|
||||
case PE_PanelToolBar: // The panel for a toolbar.
|
||||
break;
|
||||
// case PE_PanelTipLabel: // The panel for a tip label.
|
||||
case PE_FrameTabBarBase: // The frame that is drawn for a tabbar, ususally drawn for a tabbar that isn't part of a tab widget
|
||||
if (widget &&
|
||||
(qobject_cast<const QTabBar*>(widget) || // we alter the paintevent
|
||||
(widget->parentWidget() &&
|
||||
qobject_cast<QTabWidget*>(widget->parentWidget())))) // KDE abuse, allready has a nice base
|
||||
break;
|
||||
|
||||
if (const QStyleOptionTabBarBase *tbb
|
||||
= qstyleoption_cast<const QStyleOptionTabBarBase *>(option)) {
|
||||
int size(0); Qt::Orientation o = Qt::Vertical;
|
||||
Tile::PosFlags pf = Tile::Ring;
|
||||
QRect fillRect;
|
||||
bool north = false;
|
||||
switch (tbb->shape) {
|
||||
case QTabBar::RoundedSouth:
|
||||
case QTabBar::TriangularSouth:
|
||||
// fillRect = RECT.adjusted(dpi.$3, dpi.$2, -dpi.$3, 0);
|
||||
pf &= ~Tile::Top;
|
||||
size = /*fillRect*/RECT.height();
|
||||
break;
|
||||
case QTabBar::RoundedNorth:
|
||||
case QTabBar::TriangularNorth:
|
||||
north = true;
|
||||
// fillRect = RECT.adjusted(dpi.$3, 0, -dpi.$3, -dpi.$3);
|
||||
pf &= ~Tile::Bottom;
|
||||
size = /*fillRect*/RECT.height();
|
||||
break;
|
||||
case QTabBar::RoundedWest:
|
||||
case QTabBar::TriangularWest:
|
||||
// fillRect = RECT.adjusted(0, dpi.$2, -dpi.$3, -dpi.$3);
|
||||
pf &= ~Tile::Right;
|
||||
o = Qt::Horizontal;
|
||||
size = /*fillRect*/RECT.width();
|
||||
break;
|
||||
case QTabBar::RoundedEast:
|
||||
case QTabBar::TriangularEast:
|
||||
// fillRect = RECT.adjusted(dpi.$3, dpi.$2, 0, -dpi.$3);
|
||||
pf &= ~Tile::Left;
|
||||
o = Qt::Horizontal;
|
||||
size = /*fillRect*/RECT.width();
|
||||
break;
|
||||
}
|
||||
fillWithMask(painter, RECT,
|
||||
gradient(CONF_COLOR(role_tab[0]), size, o, config.gradientStrong),
|
||||
&masks.button, pf | Tile::Center);
|
||||
if (north)
|
||||
shadows.lineEdit[0].render(RECT, painter, Tile::Ring & ~Tile::Bottom);
|
||||
else
|
||||
shadows.tab.render(RECT, painter, pf);
|
||||
// masks.tab.outline(fillRect, painter, CONF_COLOR(role_tab[0]).dark(110), true, pf);
|
||||
}
|
||||
break;
|
||||
case PE_IndicatorTabTear: // An indicator that a tab is partially scrolled out of the visible tab bar when there are many tabs.
|
||||
break;
|
||||
default:
|
||||
QCommonStyle::drawPrimitive( pe, option, painter, widget );
|
||||
} // switch
|
||||
}
|
1190
clients/oxygen/dynamicbrush.cpp
Normal file
1190
clients/oxygen/dynamicbrush.cpp
Normal file
File diff suppressed because it is too large
Load diff
115
clients/oxygen/dynamicbrush.h
Normal file
115
clients/oxygen/dynamicbrush.h
Normal file
|
@ -0,0 +1,115 @@
|
|||
/***************************************************************************
|
||||
* Copyright (C) 2006-2007 by Thomas Lübking *
|
||||
* thomas.luebking@web.de *
|
||||
* *
|
||||
* 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., *
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef DYNAMICBRUSH_H
|
||||
#define DYNAMICBRUSH_H
|
||||
|
||||
class QTimer;
|
||||
class QImage;
|
||||
class QRect;
|
||||
class QGLWidget;
|
||||
|
||||
#include <QMap>
|
||||
#include <QObject>
|
||||
#include <QSize>
|
||||
#include <QRect>
|
||||
#include <QPixmap>
|
||||
#include <X11/Xlib.h>
|
||||
#include <fixx11h.h>
|
||||
|
||||
class BgSet {
|
||||
public:
|
||||
BgSet();
|
||||
BgSet(const QPixmap* pix, int dx, int dy, int w, int h,
|
||||
bool updateDeco = true);
|
||||
BgSet(const QPixmap* pix, int d, int s, Qt::Orientation o,
|
||||
bool updateDeco = true);
|
||||
void setPixmap(const QPixmap* pix, int dx, int dy, int w, int h,
|
||||
bool updateDeco = false);
|
||||
void setPixmap(const QPixmap* pix, int d, int s, Qt::Orientation o,
|
||||
bool updateDeco = false);
|
||||
void wipe();
|
||||
~BgSet();
|
||||
QPixmap *window,
|
||||
*decoTop, *decoBottom, *decoLeft, *decoRight;
|
||||
};
|
||||
|
||||
typedef QMap<QWidget*, BgSet*> BgPixCache;
|
||||
|
||||
class DynamicBrush : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
enum Mode {Tiled = 0, QtGradient, XRender, OpenGL,
|
||||
VGradient1, HGradient1, VGradient2, HGradient2, Glass};
|
||||
DynamicBrush(Mode mode, QObject *parent = 0);
|
||||
DynamicBrush(Pixmap pixmap = -1, int bgYoffset = 0, QObject *parent = 0);
|
||||
~DynamicBrush();
|
||||
// QPixmap shadow(const QRect &rect);
|
||||
void setMode(Mode);
|
||||
void setXPixmap(Pixmap pixmap = -1);
|
||||
protected:
|
||||
virtual bool eventFilter ( QObject * watched, QEvent * event );
|
||||
private:
|
||||
// bg pixmap creating
|
||||
const BgSet* bgSetTiled(const QSize &size, bool updateDeco);
|
||||
const BgSet* bgSetGL(const QSize &size, bool updateDeco);
|
||||
const BgSet* bgSetRender(const QSize &size, bool updateDeco);
|
||||
const BgSet* bgSetGradient1(const QSize &size, bool updateDeco);
|
||||
const BgSet* bgSetGradient2(const QSize &size, bool updateDeco);
|
||||
const BgSet* bgSetQt(const QSize &size, bool updateDeco);
|
||||
const BgSet* bgSetGlass(const QSize &size, bool updateDeco);
|
||||
|
||||
// get the deco dimensions from the deco
|
||||
void readDecoDim(QWidget *topLevelWidget);
|
||||
|
||||
// tiling
|
||||
Pixmap _pixmap;
|
||||
int _bgYoffset;
|
||||
void generateTiles(Mode mode);
|
||||
|
||||
// complex (gl/qt/render)
|
||||
BgPixCache::iterator checkCache(bool &found);
|
||||
|
||||
// openGL
|
||||
void initGL();
|
||||
QGLWidget *_glContext;
|
||||
QPixmap *glPixmap(const QRect &rect, const QSize &size, int darkness = 0);
|
||||
|
||||
// gradients
|
||||
QPixmap _tile[2][2];
|
||||
QColor _bgC[2];
|
||||
|
||||
// states
|
||||
QSize _size;
|
||||
Mode _mode;
|
||||
bool _isActiveWindow;
|
||||
int decoDim[4];
|
||||
|
||||
// bender
|
||||
QWidget *_topLevelWidget;
|
||||
|
||||
// wiping
|
||||
QTimer *_timerBgWipe;
|
||||
private slots:
|
||||
void wipeBackground();
|
||||
};
|
||||
|
||||
#endif //DYNAMICBRUSH_H
|
521
clients/oxygen/genpixmaps.cpp
Normal file
521
clients/oxygen/genpixmaps.cpp
Normal file
|
@ -0,0 +1,521 @@
|
|||
#define fillRect(_X_,_Y_,_W_,_H_,_B_) setPen(Qt::NoPen); p.setBrush(_B_); p.drawRect(_X_,_Y_,_W_,_H_)
|
||||
|
||||
void OxygenStyle::generatePixmaps()
|
||||
{
|
||||
QPixmap tmp; QPainter p;
|
||||
QLinearGradient lg; QGradientStops stops;
|
||||
QRadialGradient rg;
|
||||
|
||||
// PUSHBUTTON =====================================
|
||||
// shadow
|
||||
int $1 = dpi.$1, $2 = dpi.$2, $2_2 = lround($2/2.0);
|
||||
int $3 = dpi.$3, $4 = dpi.$4, $5 = dpi.$5;
|
||||
int $9 = dpi.$9, $9_2 = ($9-1)/2;
|
||||
int $7 = dpi.$7, $8 = dpi.$8;
|
||||
int $13 = dpi.$13, $15 = $7+$8, $6 = dpi.$6;
|
||||
tmp = QPixmap($15,$15);
|
||||
for (int i = 0; i < 8; ++i) { // opaque?
|
||||
for (int j = 0; j < 2; ++j) { // sunken?
|
||||
tmp.fill(Qt::transparent);
|
||||
p.begin(&tmp);
|
||||
p.setPen(Qt::NoPen);
|
||||
p.setRenderHint(QPainter::Antialiasing);
|
||||
QRadialGradient rg;
|
||||
if (j) {
|
||||
rg = QRadialGradient($15/2.0, $15/2.0, $5, $15/2.0, $15/2.0+$3);
|
||||
stops.clear();
|
||||
stops << QGradientStop( 0, QColor(0,0,0, 150) )
|
||||
<< QGradientStop( 0.59, QColor(0,0,0, 70) )
|
||||
<< QGradientStop( 1, QColor(0,0,0, 0) );
|
||||
rg.setStops(stops);
|
||||
}
|
||||
else {
|
||||
rg = QRadialGradient($15/2.0, $15/2.0, $15/2.0, $15/2.0, $15/2.0+$2);
|
||||
stops.clear();
|
||||
stops << QGradientStop( 0, QColor(0,0,0, 160) )
|
||||
<< QGradientStop( 0.4, QColor(0,0,0, 60) )
|
||||
<< QGradientStop( 0.85, QColor(0,0,0, 0) )
|
||||
<< QGradientStop( 1, QColor(0,0,0, 0) );
|
||||
rg.setStops(stops);
|
||||
|
||||
if (i) {
|
||||
rg = QRadialGradient($15/2.0, $15/2.0, $15/2.0, $15/2.0, $15/2.0);
|
||||
stops.clear();
|
||||
QColor c = QColor(222,193,0);//COLOR(Highlight);
|
||||
c.setAlpha(180*i/8);
|
||||
stops << QGradientStop( 0, c );
|
||||
c.setAlpha(0);
|
||||
stops << QGradientStop( 1, c );
|
||||
rg.setStops(stops);
|
||||
}
|
||||
}
|
||||
|
||||
p.setBrush(rg);
|
||||
p.drawRoundRect(0,0,$15,$15,90,90);
|
||||
|
||||
p.end();
|
||||
shadows.button[j][i] = Tile::Set(tmp,$7,$7,$15-2*$7,$15-2*$7);
|
||||
}
|
||||
}
|
||||
|
||||
// light
|
||||
tmp.fill(Qt::transparent);
|
||||
p.begin(&tmp);
|
||||
p.setPen(Qt::NoPen);
|
||||
p.setRenderHint(QPainter::Antialiasing);
|
||||
p.setBrush(QColor(0,0,0,80));
|
||||
p.drawRoundRect(0,0,$9,$9,90,90);
|
||||
p.setBrush(QColor(0,0,0,80));
|
||||
p.drawRoundRect($1,$1,$9-2*$1,$9-2*$1,80,80);
|
||||
p.setBrush(QColor(0,0,0,80));
|
||||
p.drawRoundRect($2,$2,$9-2*$2,$9-2*$2,70,70);
|
||||
p.setBrush(QColor(0,0,0,255));
|
||||
p.drawRoundRect($3,$3,$9-2*$3,$9-2*$3,60,60);
|
||||
p.end();
|
||||
lights.button =
|
||||
Tile::Mask(tmp,$9_2,$9_2,$9-2*$9_2,$9-2*$9_2, $3,$3,-$3,-$3, 75,75);
|
||||
|
||||
// mask
|
||||
tmp = QPixmap($9,$9);
|
||||
tmp.fill(Qt::transparent);
|
||||
p.begin(&tmp);
|
||||
p.setPen(Qt::NoPen);
|
||||
p.setRenderHint(QPainter::Antialiasing);
|
||||
p.setBrush(QColor(0,0,0,255));
|
||||
p.drawRoundRect(0,0,$9,$9,90,90);
|
||||
p.end();
|
||||
masks.button = Tile::Mask(tmp,$9_2,$9_2,$9-2*$9_2,$9-2*$9_2,0,0,0,0,90,90);
|
||||
|
||||
// -> LINEEDIT
|
||||
QImage tmpImg($9,$9+$9, QImage::Format_ARGB32);
|
||||
|
||||
for (int i = 0; i < 2; ++i) {
|
||||
int add = i*30;
|
||||
tmpImg.fill(Qt::transparent);
|
||||
|
||||
p.begin(&tmpImg);
|
||||
|
||||
// draw the shadows themselves, they appear on the inside naturally - as it's sunken
|
||||
p.setPen(Qt::NoPen);
|
||||
p.setRenderHint(QPainter::Antialiasing);
|
||||
rg = QRadialGradient($9/2.0,$9/2.0, dpi.$5, $9/2.0,$9/2.0+1.5*$1);
|
||||
stops.clear();
|
||||
stops << QGradientStop( 0, QColor(0,0,0, 0) )
|
||||
<< QGradientStop( 0.4, QColor(0,0,0, 0) )
|
||||
<< QGradientStop( 0.58, QColor(0,0,0, 40/2) )
|
||||
<< QGradientStop( 0.75, QColor(0,0,0, 103/3) )
|
||||
<< QGradientStop( 0.88, QColor(0,0,0, 161/3) )
|
||||
<< QGradientStop( 1, QColor(0,0,0, 255/3) );
|
||||
rg.setStops(stops);
|
||||
p.setBrush(rg);
|
||||
|
||||
p.drawRoundRect(0,0,$9,$9,80,80);
|
||||
|
||||
// move the bottom part
|
||||
p.drawImage(QPoint(0,$9+dpi.$4), tmpImg, QRect(0,dpi.$5,$9,$9_2));
|
||||
|
||||
// draw white edge at bottom
|
||||
p.setBrush(Qt::NoBrush);
|
||||
p.setPen(QColor(255,255,255,160));
|
||||
p.drawRoundRect(0,$9,$9,$9,80,80);
|
||||
p.setPen(Qt::red);
|
||||
p.setPen(QColor(255,255,255,210));
|
||||
p.setRenderHint(QPainter::Antialiasing,false);
|
||||
p.drawLine($1, $9+$9 -$2,$2, $9 + $9 - $3);
|
||||
p.drawLine($9-$2, $9+$9 -$2, $9-$3, $9 + $9 - $3);
|
||||
p.setRenderHint(QPainter::Antialiasing);
|
||||
p.setPen(Qt::NoPen);
|
||||
|
||||
// repeat the one good line we have for the next 9 lines (where we later draw the long shadow on top)
|
||||
p.setCompositionMode( QPainter::CompositionMode_Source );
|
||||
p.drawImage(QRect(0,dpi.$5,$9,dpi.$9), tmpImg, QRect(0,$9_2,$9,$1));
|
||||
p.setCompositionMode( QPainter::CompositionMode_SourceOver );
|
||||
|
||||
// draw the shadow from the top and down
|
||||
lg = QLinearGradient(0,$3,0,dpi.$12);
|
||||
stops.clear();
|
||||
stops << QGradientStop( 0, QColor(106,56,0, 15) )
|
||||
<< QGradientStop( 1.0, QColor(106,56,0, 0) );
|
||||
|
||||
lg.setStops(stops);
|
||||
p.fillRect($2,$3,dpi.$5,dpi.$10, lg);
|
||||
stops.clear();
|
||||
p.end();
|
||||
|
||||
shadows.lineEdit[i] = Tile::Set(QPixmap::fromImage(tmpImg),$9_2,$9_2+$9,$9-2*$9_2,$9-2*$9_2);
|
||||
}
|
||||
|
||||
// relief
|
||||
tmp = QPixmap($9,$9);
|
||||
tmp.fill(Qt::transparent);
|
||||
p.begin(&tmp);
|
||||
QPen pen = p.pen(); pen.setWidth($1); p.setPen(pen);
|
||||
p.setRenderHint(QPainter::Antialiasing);
|
||||
p.setBrush(Qt::NoBrush);
|
||||
p.setPen(QColor(255,255,255,40));
|
||||
p.drawRoundRect(0,0,$9-$2,$9-$2,60,60);
|
||||
p.setPen(QColor(255,255,255,60));
|
||||
p.drawRoundRect($2,$2,$9-$2,$9-$2,60,60);
|
||||
p.setPen(QColor(0,0,0,50));
|
||||
p.drawRoundRect($1,$1,$9-dpi.$3,$9-dpi.$3,60,60);
|
||||
p.end();
|
||||
shadows.relief = Tile::Set(tmp,$9_2,$9_2,$9-2*$9_2,$9-2*$9_2);
|
||||
|
||||
|
||||
// outlines
|
||||
tmp = QPixmap($9,$9);
|
||||
for (int i = 0; i < 2; ++i) {
|
||||
tmp.fill(Qt::transparent);
|
||||
p.begin(&tmp);
|
||||
p.setRenderHint(QPainter::Antialiasing);
|
||||
p.setPen(QColor(255,255,255,100+i*60));
|
||||
p.setBrush(Qt::NoBrush);
|
||||
p.drawRoundRect(0,0,$9,2*$9,75,38);
|
||||
p.end();
|
||||
frames.button[i] = Tile::Set(tmp,$9_2,$9_2,$9-2*$9_2,$9-2*$9_2);
|
||||
}
|
||||
// frames.button[0] = Tile::Nuno(100);
|
||||
// frames.button[1] = Tile::Nuno(160);
|
||||
|
||||
// toplight
|
||||
int $49 = SCALE(49);
|
||||
int $49_2 = ($49-1)/2;
|
||||
tmp = QPixmap($49,$49);
|
||||
tmp.fill(Qt::transparent);
|
||||
rg = QRadialGradient( tmp.rect().center(), $49_2 );
|
||||
rg.setColorAt ( 0, QColor(255,255,255,160) );
|
||||
rg.setColorAt ( 1, QColor(255,255,255,0) );
|
||||
p.begin(&tmp);
|
||||
p.fillRect(0,0,$49,$49,rg);
|
||||
p.end();
|
||||
tmp = tmp.scaled( $49, dpi.$5, Qt::IgnoreAspectRatio, Qt::SmoothTransformation );
|
||||
tmp = tmp.copy(0,$2,$49,dpi.$3);
|
||||
lights.top = Tile::Line(tmp,Qt::Horizontal,$49_2,-$49_2);
|
||||
|
||||
// ================================================================
|
||||
|
||||
// RADIOUTTON =====================================
|
||||
int rw = dpi.ExclusiveIndicator;
|
||||
int rh = dpi.ExclusiveIndicator;
|
||||
// shadow
|
||||
for (int i = 0; i < 2; ++i) { // opaque?
|
||||
for (int j = 0; j < 2; ++j) { // sunken?
|
||||
shadows.radio[j][i] = QPixmap(rw-$1*j, rh-$1*j);
|
||||
shadows.radio[j][i].fill(Qt::transparent);
|
||||
p.begin(&shadows.radio[j][i]);
|
||||
p.setPen(Qt::NoPen);
|
||||
p.setRenderHint(QPainter::Antialiasing);
|
||||
p.setBrush(QColor(0,0,0,(1+i+j)*9));
|
||||
p.drawEllipse(shadows.radio[j][i].rect());
|
||||
if (!j) {
|
||||
p.setBrush(QColor(0,0,0,(i+1)*20));
|
||||
p.drawEllipse($2_2,$2_2,rw-$2,rh-$2);
|
||||
}
|
||||
p.end();
|
||||
}
|
||||
}
|
||||
|
||||
// mask
|
||||
rw -= dpi.$4; rh -= dpi.$4;
|
||||
masks.radio = QPixmap(rw, rh);
|
||||
masks.radio.fill(Qt::transparent);
|
||||
p.begin(&masks.radio);
|
||||
p.setPen(Qt::NoPen);
|
||||
p.setRenderHint(QPainter::Antialiasing);
|
||||
p.setBrush(QColor(0,0,0,255));
|
||||
p.drawEllipse(0,0,rw,rh);
|
||||
p.end();
|
||||
|
||||
rw -= dpi.$4; rh -= dpi.$4;
|
||||
masks.radioGroove = QPixmap(rw, rh);
|
||||
masks.radioGroove.fill(Qt::transparent);
|
||||
p.begin(&masks.radioGroove);
|
||||
p.setPen(Qt::NoPen);
|
||||
p.setRenderHint(QPainter::Antialiasing);
|
||||
p.setBrush(QColor(0,0,0,255));
|
||||
p.drawEllipse(0,0,rw,rh);
|
||||
p.end();
|
||||
|
||||
// mask fill
|
||||
rw -= dpi.$4; rh -= dpi.$4;
|
||||
masks.radioIndicator = QPixmap(rw, rh);
|
||||
masks.radioIndicator.fill(Qt::transparent);
|
||||
p.begin(&masks.radioIndicator);
|
||||
p.setPen(Qt::NoPen);
|
||||
p.setRenderHint(QPainter::Antialiasing);
|
||||
p.setBrush(QColor(0,0,0,255));
|
||||
p.drawEllipse(0,0,rw,rh);
|
||||
p.end();
|
||||
|
||||
// ================================================================
|
||||
|
||||
// NOTCH =====================================
|
||||
masks.notch = QPixmap(dpi.$6, dpi.$6);
|
||||
masks.notch.fill(Qt::transparent);
|
||||
p.begin(&masks.notch);
|
||||
p.setPen(Qt::NoPen);
|
||||
p.setRenderHint(QPainter::Antialiasing);
|
||||
p.setBrush(Qt::black);
|
||||
p.drawEllipse(0,0,dpi.$6,dpi.$6);
|
||||
p.end();
|
||||
// ================================================================
|
||||
|
||||
// RECTANGULAR =====================================
|
||||
|
||||
// raised
|
||||
|
||||
// sunken
|
||||
tmp = QPixmap($9,$9);
|
||||
tmp.fill(Qt::transparent);
|
||||
p.begin(&tmp);
|
||||
p.fillRect($1,0,$9-$2,$1, QColor(0,0,0,10));
|
||||
p.fillRect($2,$1,$9-$4,$1, QColor(0,0,0,20));
|
||||
p.fillRect($2,$2,$9-$4,$1, QColor(0,0,0,40));
|
||||
p.fillRect($3,$3,$9-$6,$1, QColor(0,0,0,80));
|
||||
|
||||
p.fillRect($1,$9-$1,$9-$2,$1, QColor(255,255,255,10));
|
||||
p.fillRect($2,$9-$2,$9-$4,$1, QColor(255,255,255,20));
|
||||
p.fillRect($2,$9-$3,$9-$4,$1, QColor(255,255,255,40));
|
||||
p.fillRect($3,$9-$4,$9-$6,$1, QColor(255,255,255,80));
|
||||
|
||||
p.fillRect(0,$1,$1,$9-$2, QColor(128,128,128,10));
|
||||
p.fillRect($1,$2,$1,$9-$4, QColor(128,128,128,20));
|
||||
p.fillRect($2,$2,$1,$9-$4, QColor(128,128,128,40));
|
||||
p.fillRect($3,$3,$1,$9-$6, QColor(128,128,128,80));
|
||||
|
||||
p.fillRect($9-$1,$1,$1,$9-$2, QColor(128,128,128,10));
|
||||
p.fillRect($9-$2,$2,$1,$9-$4, QColor(128,128,128,20));
|
||||
p.fillRect($9-$3,$2,$1,$9-$4, QColor(128,128,128,40));
|
||||
p.fillRect($9-$4,$3,$1,$9-$6, QColor(128,128,128,80));
|
||||
|
||||
p.end();
|
||||
shadows.sunken = Tile::Set(tmp,$9_2,$9_2,$9-2*$9_2,$9-2*$9_2);
|
||||
|
||||
// ================================================================
|
||||
|
||||
// TABBAR =====================================
|
||||
|
||||
// mask
|
||||
tmp = QPixmap($13,$13);
|
||||
tmp.fill(Qt::transparent);
|
||||
p.begin(&tmp);
|
||||
p.setPen(Qt::NoPen);
|
||||
p.setRenderHint(QPainter::Antialiasing);
|
||||
p.setBrush(QColor(0,0,0,255));
|
||||
p.drawRoundRect(0,0,$13,$13,99,99);
|
||||
p.end();
|
||||
int $13_2 = ($13-1)/2;
|
||||
masks.tab = Tile::Mask(tmp,$13_2,$13_2,$13-2*$13_2,$13-2*$13_2,0,0,0,0,99,99);
|
||||
|
||||
// shadow
|
||||
int $17 = SCALE(17);
|
||||
tmpImg = QImage($17,$17, QImage::Format_ARGB32);
|
||||
tmpImg.fill(Qt::transparent);
|
||||
p.begin(&tmpImg);
|
||||
p.setPen(Qt::NoPen);
|
||||
p.setRenderHint(QPainter::Antialiasing);
|
||||
p.setBrush(QColor(0,0,0,15)); p.drawRoundRect(0,0,$17,$17,90,90);
|
||||
p.setBrush(QColor(0,0,0,18)); p.drawRoundRect($1,$1,$17-$2,$17-$2,93,93);
|
||||
p.setBrush(QColor(0,0,0,23)); p.drawRoundRect($2,$2,$17-dpi.$4,$17-dpi.$4,96,96);
|
||||
p.setBrush(QColor(0,0,0,28)); p.drawRoundRect(dpi.$3,dpi.$3,$17-dpi.$6,$17-dpi.$6,99,99);
|
||||
p.setCompositionMode( QPainter::CompositionMode_DestinationOut );
|
||||
p.setBrush(QColor(0,0,0,255)); p.drawRoundRect($2,$1,$17-dpi.$4,$17-dpi.$5,99,99);
|
||||
p.setCompositionMode( QPainter::CompositionMode_SourceOver );
|
||||
p.setPen(QColor(255,255,255,170)); p.setBrush(Qt::NoBrush);
|
||||
p.drawRoundRect($2,$1,$17-dpi.$4,$17-dpi.$5,99,99);
|
||||
p.end();
|
||||
int $17_2 = ($17-1)/2;
|
||||
shadows.tab = Tile::Set(QPixmap::fromImage(tmpImg),$17_2,$17_2,$17-2*$17_2,$17-2*$17_2);
|
||||
|
||||
// GROUPBOX =====================================
|
||||
|
||||
// shadow
|
||||
tmpImg = QImage($49,$49, QImage::Format_ARGB32);
|
||||
tmpImg.fill(Qt::transparent);
|
||||
p.begin(&tmpImg);
|
||||
p.setPen(Qt::NoPen);
|
||||
p.setRenderHint(QPainter::Antialiasing);
|
||||
p.setBrush(QColor(0,0,0,5)); p.drawRoundRect(0,0,$49,2*$49,14,7);
|
||||
p.setBrush(QColor(0,0,0,9)); p.drawRoundRect($1,$1,$49-$2,2*$49,13,7);
|
||||
p.setBrush(QColor(0,0,0,11)); p.drawRoundRect($2,$2,$49-dpi.$4,2*$49,12,6);
|
||||
p.setBrush(QColor(0,0,0,13)); p.drawRoundRect(dpi.$3,dpi.$3,$49-dpi.$6,2*$49,48,24);
|
||||
p.setCompositionMode( QPainter::CompositionMode_DestinationIn );
|
||||
p.setBrush(QColor(0,0,0,0)); p.drawRoundRect(dpi.$4,dpi.$2,$49-dpi.$8,2*$49,11,6);
|
||||
// p.setCompositionMode( QPainter::CompositionMode_SourceOver );
|
||||
// p.setPen(QColor(255,255,255,200)); p.setBrush(Qt::NoBrush);
|
||||
// p.drawRoundRect(dpi.$4,dpi.$2,$49-dpi.$8,2*$49,11,6);
|
||||
p.setRenderHint(QPainter::Antialiasing, false);
|
||||
// p.setCompositionMode( QPainter::CompositionMode_DestinationIn );
|
||||
int $33 = SCALE(33);
|
||||
for (int i = 1; i < $33; ++i) {
|
||||
p.setPen(QColor(0,0,0,CLAMP(i*lround(255.0/dpi.$32),0,255)));
|
||||
p.drawLine(0, $49-i, $49, $49-i);
|
||||
}
|
||||
p.end();
|
||||
int $12 = dpi.$12;
|
||||
shadows.group = Tile::Set(QPixmap::fromImage(tmpImg),$12,$12,$49-2*$12,$1);
|
||||
|
||||
// mask --> uses buttons
|
||||
// int $25 = SCALE(25);
|
||||
// tmp = QPixmap($25,$25);
|
||||
// tmp.fill(Qt::transparent);
|
||||
// p.begin(&tmp);
|
||||
// p.setPen(Qt::NoPen);
|
||||
// p.setRenderHint(QPainter::Antialiasing);
|
||||
// p.setBrush(QColor(0,0,0,255));
|
||||
// p.drawRoundRect(0,0,$25,$25,22,22);
|
||||
// p.end();
|
||||
// $12 = ($25-1)/2;
|
||||
// masks.group = Tile::Mask(tmp,$12,$12,$25-2*$12,$25-2*$12,0,0,0,0,22,22);
|
||||
|
||||
// shadow line
|
||||
int w,h,c1,c2;
|
||||
for (int i = 0; i < 2; ++i) { // orientarion
|
||||
if (i) {
|
||||
w = $2; h = $49;
|
||||
lg = QLinearGradient(0,0,0,$49);
|
||||
}
|
||||
else {
|
||||
w = $49; h = $2;
|
||||
lg = QLinearGradient(0,0,$49,0);
|
||||
}
|
||||
tmp = QPixmap(w,h);
|
||||
for (int j = 0; j < 3; ++j) { // direction
|
||||
c1 = (j > 0) ? 255 : 111; c2 = (j > 0) ? 111 : 255;
|
||||
tmp.fill(Qt::transparent);
|
||||
p.begin(&tmp);
|
||||
stops << QGradientStop( 0, QColor(c1,c1,c1,0) )
|
||||
<< QGradientStop( 0.5, QColor(c1,c1,c1,71) )
|
||||
<< QGradientStop( 1, QColor(c1,c1,c1,0) );
|
||||
lg.setStops(stops);
|
||||
if (i) {
|
||||
p.fillRect(0,0,$1,$49,lg);
|
||||
}
|
||||
else {
|
||||
p.fillRect(0,0,$49,$1,lg);
|
||||
}
|
||||
stops.clear();
|
||||
stops << QGradientStop( 0, QColor(c2,c2,c2,0) )
|
||||
<< QGradientStop( 0.5, QColor(c2,c2,c2,74) )
|
||||
<< QGradientStop( 1, QColor(c2,c2,c2,0) );
|
||||
lg.setStops(stops);
|
||||
if (i) {
|
||||
p.fillRect($1,0,$2-$1,$49,lg);
|
||||
}
|
||||
else {
|
||||
p.fillRect(0,$1,$49,$2-$1,lg);
|
||||
}
|
||||
stops.clear();
|
||||
p.end();
|
||||
shadows.line[i][j] =
|
||||
Tile::Line(tmp, i ? Qt::Vertical : Qt::Horizontal, $49_2, -$49_2);
|
||||
}
|
||||
}
|
||||
|
||||
// slider handles =================================================
|
||||
QPoint triangle[3] = { QPoint(0, 100), QPoint(-100, -100), QPoint(100, -100) };
|
||||
int size;
|
||||
for (int i = 0; i < 4; ++i) { // direction
|
||||
size = dpi.SliderControl;
|
||||
for (int j = 0; j < 2; ++j) { // sunken?
|
||||
if (j) size -= $2;
|
||||
for (int k = 0; k < 2; ++k) { // opaque?
|
||||
shadows.slider[i][j][k] = QPixmap(size, size);
|
||||
shadows.slider[i][j][k].fill(Qt::transparent);
|
||||
p.begin(&shadows.slider[i][j][k]);
|
||||
p.setRenderHint(QPainter::Antialiasing);
|
||||
p.setPen(Qt::NoPen);
|
||||
p.setBrush(QColor(0,0,0, (1+j+k)*18));
|
||||
p.translate(size/2, size/2);
|
||||
p.scale(size/200.0, size/200.0);
|
||||
p.rotate(-i*90.0);
|
||||
p.drawPolygon(triangle, 3);
|
||||
if (!j) {
|
||||
p.scale(0.78, 0.78);
|
||||
p.setBrush(QColor(0,0,0, (k+1)*12));
|
||||
p.drawPolygon(triangle, 3);
|
||||
}
|
||||
p.end();
|
||||
}
|
||||
}
|
||||
size = dpi.SliderControl - $4;
|
||||
masks.slider[i] = QPixmap(size, size);
|
||||
masks.slider[i].fill(Qt::transparent);
|
||||
p.begin(&masks.slider[i]);
|
||||
p.setRenderHint(QPainter::Antialiasing);
|
||||
p.setPen(Qt::NoPen);
|
||||
p.setBrush(Qt::black);
|
||||
p.translate(size/2, size/2); p.scale(size/200.0, size/200.0);
|
||||
p.rotate(-i*90.0);
|
||||
p.drawPolygon(triangle, 3);
|
||||
p.end();
|
||||
lights.slider[i] = QPixmap(size, size);
|
||||
lights.slider[i].fill(Qt::transparent);
|
||||
p.begin(&lights.slider[i]);
|
||||
p.setRenderHint(QPainter::Antialiasing);
|
||||
p.setPen(Qt::white);
|
||||
p.setBrush(Qt::NoBrush);
|
||||
p.translate(size/2, size/2); p.scale(size/200.0, size/200.0);
|
||||
p.rotate(-i*90.0);
|
||||
p.drawPolygon(triangle, 3);
|
||||
p.end();
|
||||
}
|
||||
// ================================================================
|
||||
// ================================================================
|
||||
// Popup corners - not really pxmaps, though ;) ===================
|
||||
// masks.popupCorner[0] = QRegion(0,0,$9,$9);
|
||||
// masks.popupCorner[1] = QRegion(0,0,$9,$9);
|
||||
// masks.popupCorner[2] = QRegion(0,0,$9,$9);
|
||||
// masks.popupCorner[3] = QRegion(0,0,$9,$9);
|
||||
// ================================================================
|
||||
#define _INITPIX_(_PIX_,_W_,_H_)\
|
||||
_PIX_ = QPixmap(_W_, _H_);\
|
||||
_PIX_.fill(Qt::transparent);\
|
||||
p.begin(&_PIX_);\
|
||||
p.setPen(Qt::NoPen);\
|
||||
p.setRenderHint(QPainter::Antialiasing)
|
||||
|
||||
#define _CLOSE_ARROW_(_PIX_, _OFF_)\
|
||||
triangle[0] = QPoint(_OFF_, _PIX_.rect().center().y()+_OFF_);\
|
||||
triangle[1] = _PIX_.rect().topRight()+QPoint(-_OFF_,_OFF_);\
|
||||
triangle[2] = _PIX_.rect().bottomRight()-QPoint(_OFF_,_OFF_);\
|
||||
p.drawPolygon(triangle, 3)
|
||||
|
||||
#define _MIN_ARROW_(_PIX_, _OFF_)\
|
||||
triangle[0] = _PIX_.rect().bottomLeft()+QPoint(_OFF_,-_OFF_);\
|
||||
triangle[1] = _PIX_.rect().topLeft()+QPoint(_OFF_,_OFF_);\
|
||||
triangle[2] = _PIX_.rect().bottomRight()-QPoint(_OFF_,_OFF_);\
|
||||
p.drawPolygon(triangle, 3)
|
||||
|
||||
#define _MAX_ARROW_(_PIX_, _OFF_)\
|
||||
triangle[0] = _PIX_.rect().topLeft()+QPoint(_OFF_,_OFF_);\
|
||||
triangle[1] = _PIX_.rect().topRight()+QPoint(-_OFF_,_OFF_);\
|
||||
triangle[2] = _PIX_.rect().bottomRight()-QPoint(_OFF_,_OFF_);\
|
||||
p.drawPolygon(triangle, 3)
|
||||
|
||||
// Window Buttons ===================================
|
||||
// QPoint triangle[3];
|
||||
int $14 = SCALE(14);// $15 = SCALE(15), $16 = dpi.$16;
|
||||
_INITPIX_(masks.winClose, $14,$14);
|
||||
p.setBrush(Qt::black);
|
||||
_CLOSE_ARROW_(masks.winClose, 0);
|
||||
p.end();
|
||||
_INITPIX_(masks.winMin,$14,$14);
|
||||
p.setBrush(Qt::black);
|
||||
_MIN_ARROW_(masks.winMin, 0);
|
||||
p.end();
|
||||
_INITPIX_(masks.winMax,$14,$14);
|
||||
p.setBrush(Qt::black);
|
||||
_MAX_ARROW_(masks.winMax, 0);
|
||||
p.end();
|
||||
/*
|
||||
shadows.winClose[0] = QPixmap($16, $16);
|
||||
shadows.winMin[0] = QPixmap($16, $16);
|
||||
shadows.winMax[0] = QPixmap($16, $16);
|
||||
shadows.winClose[0] = QPixmap($15, $15);
|
||||
shadows.winMin[0] = QPixmap($15, $15);
|
||||
shadows.winMax[0] = QPixmap($15, $15);
|
||||
*/
|
||||
// ================================================================
|
||||
}
|
||||
#undef fillRect
|
341
clients/oxygen/gradients.cpp
Normal file
341
clients/oxygen/gradients.cpp
Normal file
|
@ -0,0 +1,341 @@
|
|||
/***************************************************************************
|
||||
* Copyright (C) 2006-2007 by Thomas L<EFBFBD>bking *
|
||||
* thomas.luebking@web.de *
|
||||
* *
|
||||
* 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., *
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||||
***************************************************************************/
|
||||
|
||||
|
||||
/* ========= MAGIC NUMBERS ARE COOL ;) =================
|
||||
Ok, we want to cache the gradients, but unfortunately we have no idea about
|
||||
what kind of gradients will be demanded in the future
|
||||
Thus creating a 2 component map (uint for color and uint for size)
|
||||
would be some overhead and cause a lot of unused space in the dictionaries -
|
||||
while hashing by a string is stupid slow ;)
|
||||
|
||||
So we store all the gradients by a uint index
|
||||
Therefore we substitute the alpha component (byte << 24) of the demanded color
|
||||
with the demanded size
|
||||
As this would limit the size to 255/256 pixels we'll be a bit sloppy,
|
||||
depending on the users resolution (e.g. use 0 to store a gradient with 2px,
|
||||
usefull for demand of 1px or 2px) and shift the index
|
||||
(e.g. gradients from 0 to 6 px size will hardly be needed -
|
||||
maybe add statistics on this)
|
||||
So the handled size is actually demandedSize + (demandedSize % sizeSloppyness),
|
||||
beeing at least demanded size and the next sloppy size above at max
|
||||
====================================================== */
|
||||
static inline uint
|
||||
hash(int size, const QColor &c, int *sloppyAdd) {
|
||||
|
||||
uint magicNumber = 0;
|
||||
int sizeSloppyness = 1, frameBase = 0, frameSize = 20;
|
||||
while ((frameBase += frameSize) < size) {
|
||||
++sizeSloppyness;
|
||||
frameSize += 20;
|
||||
}
|
||||
|
||||
frameBase -=frameSize; frameSize -= 20;
|
||||
|
||||
*sloppyAdd = size % sizeSloppyness;
|
||||
if (!*sloppyAdd)
|
||||
*sloppyAdd = sizeSloppyness;
|
||||
|
||||
// first 11 bits to store the size, remaining 21 bits for the color (7bpc)
|
||||
magicNumber = (((frameSize + (size - frameBase)/sizeSloppyness) & 0xff) << 21) |
|
||||
(((c.red() >> 1) & 0x7f) << 14) |
|
||||
(((c.green() >> 1) & 0x7f) << 7 ) |
|
||||
((c.blue() >> 1) & 0x7f);
|
||||
|
||||
return magicNumber;
|
||||
}
|
||||
|
||||
static QPixmap*
|
||||
newPix(int size, Qt::Orientation o, QPoint *start, QPoint *stop) {
|
||||
QPixmap *pix;
|
||||
if (o == Qt::Horizontal) {
|
||||
pix = new QPixmap(size, 32);
|
||||
*start = QPoint(0,32); *stop = QPoint(pix->width(),32);
|
||||
}
|
||||
else {
|
||||
pix = new QPixmap(32, size);
|
||||
*start = QPoint(32, 0); *stop = QPoint(32, pix->height());
|
||||
}
|
||||
return pix;
|
||||
}
|
||||
|
||||
#define PREPARE_OXRENDER_GRADIENT QPoint start, stop; ColorArray colors; PointArray stops;\
|
||||
QPixmap *pix = newPix(size, o, &start, &stop)
|
||||
|
||||
#define MAKE_OXRENDER_GRADIENT OXPicture grad = OXRender::gradient(start, stop, colors, stops);\
|
||||
OXRender::composite (grad, X::None, *pix, 0, 0, 0, 0, 0, 0, pix->width(), pix->height());\
|
||||
OXRender::freePicture(grad)
|
||||
|
||||
static inline QPixmap*
|
||||
simpleGradient(const QColor &c, int size, Qt::Orientation o) {
|
||||
PREPARE_OXRENDER_GRADIENT;
|
||||
colors << c.light(100+config.gradientIntensity*60/100)
|
||||
<< c.dark(100+config.gradientIntensity*20/100);
|
||||
MAKE_OXRENDER_GRADIENT;
|
||||
return pix;
|
||||
}
|
||||
|
||||
static inline QPixmap *
|
||||
sunkenGradient(const QColor &c, int size, Qt::Orientation o) {
|
||||
PREPARE_OXRENDER_GRADIENT;
|
||||
colors << c.dark(100+config.gradientIntensity*20/100)
|
||||
<< c.light(100+config.gradientIntensity*60/100);
|
||||
MAKE_OXRENDER_GRADIENT;
|
||||
return pix;
|
||||
}
|
||||
|
||||
static inline QPixmap *
|
||||
buttonGradient(const QColor &c, int size, Qt::Orientation o) {
|
||||
|
||||
PREPARE_OXRENDER_GRADIENT;
|
||||
|
||||
int h,s,v, inc, dec;
|
||||
c.getHsv(&h,&s,&v);
|
||||
|
||||
// calc difference
|
||||
inc = 15; dec = 6;
|
||||
if (v+15 > 255) {
|
||||
inc = 255-v; dec += (15-inc);
|
||||
}
|
||||
|
||||
// make colors
|
||||
QColor ic;
|
||||
ic.setHsv(h,s,v+inc); colors << ic;
|
||||
ic.setHsv(h,s,v-dec); colors << ic;
|
||||
stops << 0 << 0.75;
|
||||
|
||||
MAKE_OXRENDER_GRADIENT;
|
||||
return pix;
|
||||
}
|
||||
|
||||
inline static void
|
||||
gl_ssColors(const QColor &c, QColor *bb, QColor *dd, bool glass = false) {
|
||||
|
||||
int h,s,v, ch,cs,cv, delta, add;
|
||||
|
||||
c.getHsv(&h,&s,&v);
|
||||
|
||||
// calculate the variation
|
||||
add = ((180-qGray(c.rgb()))>>1);
|
||||
if (add < 0) add = -add/2;
|
||||
if (glass)
|
||||
add = add>>4;
|
||||
|
||||
// the brightest color (top)
|
||||
cv = v+27+add;
|
||||
if (cv > 255) {
|
||||
delta = cv-255; cv = 255;
|
||||
cs = s - delta; if (cs < 0) cs = 0;
|
||||
ch = h - delta/6; if (ch < 0) ch = 360+ch;
|
||||
}
|
||||
else {
|
||||
ch = h; cs = s;
|
||||
}
|
||||
bb->setHsv(ch,cs,cv);
|
||||
|
||||
// the darkest color (lower center)
|
||||
cv = v - 14-add; if (cv < 0) cv = 0;
|
||||
cs = s*13/7; if (cs > 255) cs = 255;
|
||||
dd->setHsv(h,cs,cv);
|
||||
}
|
||||
|
||||
static inline QPixmap *
|
||||
gl_ssGradient(const QColor &c, int size, Qt::Orientation o, bool glass = false) {
|
||||
QColor bb,dd; // b = d = c;
|
||||
gl_ssColors(c, &bb, &dd, glass);
|
||||
QPoint start, stop;
|
||||
QPixmap *pix = newPix(size, o, &start, &stop);
|
||||
|
||||
#if 0
|
||||
ColorArray colors; PointArray stops;
|
||||
colors << bb << b << dd << d;
|
||||
stops << 0 << 0.5 << 0.5 << 1;
|
||||
#else
|
||||
// many xrender imps are unable to create gradients with #stops > 2
|
||||
// so we "fall back" to the qt software solution here - for the moment...
|
||||
QLinearGradient lg(start, stop);
|
||||
lg.setColorAt(0,bb); lg.setColorAt(0.5,c);
|
||||
lg.setColorAt(0.5, dd); lg.setColorAt(glass ? 1 : .90, bb);
|
||||
QPainter p(pix); p.fillRect(pix->rect(), lg); p.end();
|
||||
#endif
|
||||
return pix;
|
||||
}
|
||||
|
||||
static inline QPixmap *
|
||||
rGlossGradient(const QColor &c, int size) {
|
||||
QColor bb,dd; // b = d = c;
|
||||
gl_ssColors(c, &bb, &dd);
|
||||
QPixmap *pix = new QPixmap(size, size);
|
||||
|
||||
#if 0
|
||||
ColorArray colors; PointArray stops;
|
||||
colors << bb << b << dd << d;
|
||||
stops << 0 << 0.5 << 0.5 << 1;
|
||||
#else
|
||||
// many xrender imps are unable to create gradients with #stops > 2
|
||||
// so we "fall back" to the qt software solution here - for the moment...
|
||||
QRadialGradient rg(2*pix->width()/3, pix->height(), pix->height());
|
||||
rg.setColorAt(0,c); rg.setColorAt(0.8,dd);
|
||||
rg.setColorAt(0.8, c); rg.setColorAt(1, bb);
|
||||
QPainter p(pix); p.fillRect(pix->rect(), rg); p.end();
|
||||
#endif
|
||||
return pix;
|
||||
}
|
||||
|
||||
const QPixmap&
|
||||
OxygenStyle::gradient(const QColor &c, int size, Qt::Orientation o, GradientType type) const {
|
||||
// validity check
|
||||
if (size <= 0) {
|
||||
qWarning("NULL Pixmap requested, size was %d",size);
|
||||
return nullPix;
|
||||
}
|
||||
else if (size > 105883) { // this is where our dictionary reaches - should be enough for the moment ;)
|
||||
qWarning("gradient with more than 105883 steps requested, returning NULL pixmap");
|
||||
return nullPix;
|
||||
}
|
||||
|
||||
// very dark colors won't make nice buttons =)
|
||||
QColor iC = c;
|
||||
int v = colorValue(c);
|
||||
if (v < 80) {
|
||||
int h,s;
|
||||
c.getHsv(&h,&s,&v);
|
||||
iC.setHsv(h,s,80);
|
||||
}
|
||||
|
||||
// hash
|
||||
int sloppyAdd = 1;
|
||||
uint magicNumber = hash(size, iC, &sloppyAdd);
|
||||
|
||||
PixmapCache *cache =
|
||||
&(const_cast<OxygenStyle*>( this )->gradients[o == Qt::Horizontal][type]);
|
||||
QPixmap *pix = cache->object(magicNumber);
|
||||
if (pix)
|
||||
return *pix;
|
||||
|
||||
// no cache entry found, so let's create one
|
||||
size += sloppyAdd; // rather to big than to small ;)
|
||||
switch (type) {
|
||||
case GradButton:
|
||||
pix = buttonGradient(iC, size, o);
|
||||
break;
|
||||
case GradGlass:
|
||||
pix = gl_ssGradient(iC, size, o, true);
|
||||
break;
|
||||
case GradSimple:
|
||||
default:
|
||||
pix = simpleGradient(iC, size, o);
|
||||
break;
|
||||
case GradSunken:
|
||||
pix = sunkenGradient(iC, size, o);
|
||||
break;
|
||||
case GradGloss:
|
||||
pix = gl_ssGradient(iC, size, o);
|
||||
break;
|
||||
case GradRadialGloss:
|
||||
pix = rGlossGradient(iC, size);
|
||||
break;
|
||||
}
|
||||
|
||||
// cache for later
|
||||
cache->insert(magicNumber, pix, (pix->width()*pix->height()*pix->depth())>>3);
|
||||
return *pix;
|
||||
}
|
||||
|
||||
const QPixmap &OxygenStyle::groupLight(int height) const {
|
||||
if (height <= 0) {
|
||||
qWarning("NULL Pixmap requested, height was %d",height);
|
||||
return nullPix;
|
||||
}
|
||||
QPixmap *pix = _groupLight.object(height);
|
||||
if (pix)
|
||||
return *pix;
|
||||
|
||||
pix = new QPixmap(32, height); //golden mean relations
|
||||
pix->fill(Qt::transparent);
|
||||
QPoint start(0,0), stop(0,height);
|
||||
PointArray stops;
|
||||
ColorArray colors = ColorArray() << QColor(255,255,255,50) << QColor(255,255,255,0);
|
||||
MAKE_OXRENDER_GRADIENT;
|
||||
|
||||
// cache for later ;)
|
||||
PixmapCache *cache = &(const_cast<OxygenStyle*>( this )->_groupLight);
|
||||
cache->insert(height, pix);
|
||||
return *pix;
|
||||
}
|
||||
|
||||
const QPixmap &OxygenStyle::btnAmbient(int height) const {
|
||||
if (height <= 0) {
|
||||
qWarning("NULL Pixmap requested, height was %d",height);
|
||||
return nullPix;
|
||||
}
|
||||
QPixmap *pix = _btnAmbient.object(height);
|
||||
if (pix)
|
||||
return *pix;
|
||||
|
||||
pix = new QPixmap(16*height/9,height); //golden mean relations
|
||||
pix->fill(Qt::transparent);
|
||||
ColorArray colors = ColorArray() << QColor(255,255,255,128) << QColor(255,255,255,0);
|
||||
OXPicture grad = OXRender::gradient(QPoint(pix->width(), pix->height()),
|
||||
QPoint(pix->width()/2,pix->height()/2), colors);
|
||||
OXRender::composite (grad, None, *pix, 0, 0, 0, 0, 0, 0, pix->width(), pix->height());
|
||||
OXRender::freePicture(grad);
|
||||
|
||||
// cache for later ;)
|
||||
PixmapCache *cache = &(const_cast<OxygenStyle*>( this )->_btnAmbient);
|
||||
cache->insert(height, pix);
|
||||
return *pix;
|
||||
}
|
||||
|
||||
const QPixmap &OxygenStyle::tabShadow(int height, bool bottom) const {
|
||||
if (height <= 0) {
|
||||
qWarning("NULL Pixmap requested, height was %d",height);
|
||||
return nullPix;
|
||||
}
|
||||
uint val = height + bottom*0x80000000;
|
||||
QPixmap *pix = _tabShadow.object(val);
|
||||
if (pix)
|
||||
return *pix;
|
||||
|
||||
pix = new QPixmap(height/3,height);
|
||||
pix->fill(Qt::transparent);
|
||||
ColorArray colors = ColorArray() << QColor(0,0,0,75) << QColor(0,0,0,0);
|
||||
float hypo = sqrt(pow(pix->width(),2)+pow(pix->height(),2));
|
||||
float cosalpha = (float)(pix->height())/hypo;
|
||||
QPoint p1, p2;
|
||||
if (bottom) {
|
||||
p1 = QPoint(0, 0);
|
||||
p2 = QPoint((int)(pix->width()*pow(cosalpha, 2)),
|
||||
(int)(pow(pix->width(), 2)*cosalpha/hypo));
|
||||
}
|
||||
else {
|
||||
p1 = QPoint(0, pix->height());
|
||||
p2 = QPoint((int)(pix->width()*pow(cosalpha, 2)),
|
||||
(int)pix->height() - (int)(pow(pix->width(), 2)*cosalpha/hypo));
|
||||
}
|
||||
OXPicture grad = OXRender::gradient(p1, p2, colors);
|
||||
OXRender::composite (grad, None, *pix, 0, 0, 0, 0, 0, 0, pix->width(), pix->height());
|
||||
OXRender::freePicture(grad);
|
||||
|
||||
// cache for later ;)
|
||||
PixmapCache *cache = &(const_cast<OxygenStyle*>( this )->_tabShadow);
|
||||
cache->insert(val, pix);
|
||||
return *pix;
|
||||
}
|
199
clients/oxygen/inlinehelp.cpp
Normal file
199
clients/oxygen/inlinehelp.cpp
Normal file
|
@ -0,0 +1,199 @@
|
|||
/***************************************************************************
|
||||
* Copyright (C) 2006-2007 by Thomas L<EFBFBD>bking *
|
||||
* thomas.luebking@web.de *
|
||||
* *
|
||||
* 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., *
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef INLINEHELP_CPP
|
||||
#define INLINEHELP_CPP
|
||||
|
||||
#ifndef CLAMP
|
||||
#define CLAMP(x,l,u) (x) < (l) ? (l) :\
|
||||
(x) > (u) ? (u) :\
|
||||
(x)
|
||||
#endif
|
||||
|
||||
#ifndef QABS
|
||||
#define QABS(x) (x) > 0 ? (x) : (-(x))
|
||||
#endif
|
||||
|
||||
#ifndef _PRINTFLAGS_
|
||||
#define _PRINTFLAGS_ option ? qWarning("State Flags:\n%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s",\
|
||||
option->state & State_Active ? "Active, " : "",\
|
||||
option->state & State_AutoRaise ? "AutoRaise, " : "",\
|
||||
option->state & State_Bottom ? "Bottom, " : "",\
|
||||
option->state & State_Children ? "Children, " : "",\
|
||||
option->state & State_None ? "None, " : "",\
|
||||
option->state & State_DownArrow ? "DownArrow, " : "",\
|
||||
option->state & State_Editing ? "Editing, " : "",\
|
||||
option->state & State_Enabled ? "Enabled, " : "",\
|
||||
option->state & State_FocusAtBorder ? "FocusAtBorder, " : "",\
|
||||
option->state & State_HasFocus ? "HasFocus, " : "",\
|
||||
option->state & State_Horizontal ? "Horizontal, " : "",\
|
||||
option->state & State_Item ? "Item, " : "",\
|
||||
option->state & State_MouseOver ? "MouseOver, " : "",\
|
||||
option->state & State_NoChange ? "NoChange, " : "",\
|
||||
option->state & State_Off ? "Off, " : "",\
|
||||
option->state & State_On ? "On, " : "",\
|
||||
option->state & State_Open ? "Open, " : "",\
|
||||
option->state & State_Raised ? "Raised, " : "",\
|
||||
option->state & State_Selected ? "Selected, " : "",\
|
||||
option->state & State_Sibling ? "Sibling, " : "",\
|
||||
option->state & State_Sunken ? "Sunken, " : "",\
|
||||
option->state & State_Top ? "Top, " : "",\
|
||||
option->state & State_UpArrow ? "UpArrow, " : "",\
|
||||
option->state & State_KeyboardFocusChange ? "KeyboardFocusChange, " : "",\
|
||||
option->state & State_ReadOnly ? "ReadOnly, " : "") : qWarning("MISSING OPTIONS")
|
||||
#endif
|
||||
|
||||
/**Internal calculates hsv v from color, faster than calling qcolor.hsv if you only want v*/
|
||||
inline int colorValue(const QColor &c) {
|
||||
int v = c.red();
|
||||
if (c.green() > v) v = c.green();
|
||||
if (c.blue() > v) v = c.blue();
|
||||
return v;
|
||||
}
|
||||
|
||||
/**Internal, calcs weighted mid of two colors*/
|
||||
inline QColor midColor(const QColor &oc1, const QColor &c2, int w1 = 1, int w2 = 1) {
|
||||
int sum = (w1+w2);
|
||||
QColor c1 = oc1;
|
||||
int h,s, v = colorValue(c1);
|
||||
if (v < 70) {
|
||||
c1.getHsv(&h,&s,&v);
|
||||
c1.setHsv(h,s,70);
|
||||
}
|
||||
return QColor((w1*c1.red() + w2*c2.red())/sum,
|
||||
(w1*c1.green() + w2*c2.green())/sum,
|
||||
(w1*c1.blue() + w2*c2.blue())/sum,
|
||||
(w1*c1.alpha() + w2*c2.alpha())/sum);
|
||||
}
|
||||
|
||||
#define TMP_COLOR(_ROLE_) pal.color(QPalette::_ROLE_)
|
||||
#define TMP_CONF_COLOR(_ROLE_) pal.color(config._ROLE_)
|
||||
|
||||
/**Internal, calcs button color depending on state*/
|
||||
|
||||
inline QColor btnBgColor(const QPalette &pal, bool isEnabled, bool hover = false, int step = 0) {
|
||||
if (!isEnabled)
|
||||
return TMP_COLOR(Window);
|
||||
if (step)
|
||||
return midColor(TMP_CONF_COLOR(role_btn[0]),
|
||||
TMP_CONF_COLOR(role_btnHover[0]),
|
||||
8-step, step);
|
||||
if (hover)
|
||||
return TMP_CONF_COLOR(role_btnHover[0]);
|
||||
return TMP_CONF_COLOR(role_btn[0]).dark(103);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**Internal, calcs buttonText color depending on state*/
|
||||
inline QColor btnFgColor(const QPalette &pal, bool isEnabled, bool hover = false, int step = 0) {
|
||||
if (!isEnabled)
|
||||
return midColor(TMP_COLOR(Window), TMP_COLOR(WindowText), 1, 3);
|
||||
if (step)
|
||||
return midColor(TMP_CONF_COLOR(role_btn[1]),
|
||||
TMP_CONF_COLOR(role_btnHover[1]),
|
||||
6-step, step);
|
||||
if (hover)
|
||||
return TMP_CONF_COLOR(role_btnHover[1]);
|
||||
return TMP_CONF_COLOR(role_btn[1]);
|
||||
}
|
||||
|
||||
#undef TMP_COLOR
|
||||
#undef TMP_CONF_COLOR
|
||||
|
||||
/**Internal, calcs a contrasted color to a qcolor*/
|
||||
inline QColor emphasize(const QColor &c, int value = 10) {
|
||||
int h,s,v;
|
||||
QColor ret;
|
||||
c.getHsv(&h,&s,&v);
|
||||
if (v < 75+value) {
|
||||
ret.setHsv(h,s,CLAMP(85+value,85,255));
|
||||
return ret;
|
||||
}
|
||||
if (v > 200) {
|
||||
if (s > 30) {
|
||||
h -= 5; if (h < 0) h = 360 + h;
|
||||
s = (s<<3)/9;
|
||||
v += value;
|
||||
ret.setHsv(h,CLAMP(s,30,255),CLAMP(v,0,255));
|
||||
return ret;
|
||||
}
|
||||
if (v > 230) {
|
||||
ret.setHsv(h,s,CLAMP(v-value,0,255));
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
if (v > 128)
|
||||
ret.setHsv(h,s,CLAMP(v+value,0,255));
|
||||
else
|
||||
ret.setHsv(h,s,CLAMP(v-value,0,255));
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**Internal, calcs a lightned version of a qcolor*/
|
||||
inline QColor light(const QColor &c, int value)
|
||||
{
|
||||
int h,s,v;
|
||||
c.getHsv(&h,&s,&v);
|
||||
QColor ret;
|
||||
if (v < 255-value) {
|
||||
ret.setHsv(h,s,CLAMP(v+value,0,255)); //value could be negative
|
||||
return ret;
|
||||
}
|
||||
// psychovisual uplightning, i.e. shift hue and lower saturation
|
||||
if (s > 30) {
|
||||
h -= (value*5/20); if (h < 0) h = 400 + h;
|
||||
s = CLAMP((s<<3)/9,30,255);
|
||||
ret.setHsv(h,s,255);
|
||||
return ret;
|
||||
}
|
||||
else // hue shifting has no sense, half saturation (btw, white won't get brighter :)
|
||||
ret.setHsv(h,s>>1,255);
|
||||
return ret;
|
||||
}
|
||||
|
||||
inline bool verticalTabs(QTabBar::Shape shape) {
|
||||
return shape == QTabBar::RoundedEast ||
|
||||
shape == QTabBar::TriangularEast ||
|
||||
shape == QTabBar::RoundedWest ||
|
||||
shape == QTabBar::TriangularWest;
|
||||
}
|
||||
|
||||
#if 0
|
||||
/**Internal, checks if there's contrast between two colors*/
|
||||
static bool thereIsContrastBetween(const QColor &a, const QColor &b)
|
||||
{
|
||||
int ar,ag,ab,br,bg,bb;
|
||||
a.getRgb(&ar,&ag,&ab);
|
||||
b.getRgb(&br,&bg,&bb);
|
||||
|
||||
int diff = (299*(ar-br) + 587*(ag-bg) + 114*(ab-bb));
|
||||
|
||||
if (QABS(diff) < 91001)
|
||||
return false;
|
||||
|
||||
diff = qMax(ar,br) + qMax(ag,bg) + qMax(ab,bb)
|
||||
- (qMin(ar,br) + qMin(ag,bg) + qMin(ab,bb));
|
||||
|
||||
return (diff > 300);
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif //INLINEHELP_CPP
|
29
clients/oxygen/makros.h
Normal file
29
clients/oxygen/makros.h
Normal file
|
@ -0,0 +1,29 @@
|
|||
#ifndef OXYGEN_DEFS_H
|
||||
#define OXYGEN_DEFS_H
|
||||
|
||||
#define _IsNotHtmlWidget(w) ( w->objectName() != "__khtml" )
|
||||
#define _IsHtmlWidget(w) ( w->objectName() == "__khtml" )
|
||||
#define _IsViewportChild(w) w->parent() &&\
|
||||
( w->parent()->objectName() == "qt_viewport" || \
|
||||
w->parent()->objectName() == "qt_clipped_viewport" )
|
||||
|
||||
#define _HighContrastColor(c) (qGray(c.rgb()) < 128 ) ? Qt::white : Qt::black
|
||||
|
||||
#define _BLOCKEVENTS_(obj) obj->installEventFilter(eventKiller)
|
||||
#define _UNBLOCKEVENTS_(obj) obj->removeEventFilter(eventKiller)
|
||||
|
||||
#define _IsTabStack(w) ( w->objectName() == "qt_tabwidget_stackedwidget" )
|
||||
|
||||
#define SAVE_PEN QPen saved_pen = painter->pen();
|
||||
#define RESTORE_PEN painter->setPen(saved_pen);
|
||||
#define SAVE_BRUSH QBrush saved_brush = painter->brush();
|
||||
#define RESTORE_BRUSH painter->setBrush(saved_brush);
|
||||
#define SAVE_ANTIALIAS bool hadAntiAlias = painter->renderHints() & QPainter::Antialiasing;
|
||||
#define RESTORE_ANTIALIAS painter->setRenderHint(QPainter::Antialiasing, hadAntiAlias);
|
||||
|
||||
#define RECT option->rect
|
||||
#define PAL option->palette
|
||||
#define COLOR(_TYPE_) option->palette.color(QPalette::_TYPE_)
|
||||
#define CONF_COLOR(_TYPE_) option->palette.color(config._TYPE_)
|
||||
|
||||
#endif //OXYGEN_DEFS_H
|
220
clients/oxygen/oxrender.cpp
Normal file
220
clients/oxygen/oxrender.cpp
Normal file
|
@ -0,0 +1,220 @@
|
|||
/***************************************************************************
|
||||
* Copyright (C) 2006-2007 by Thomas Lübking *
|
||||
* thomas.luebking@web.de *
|
||||
* *
|
||||
* 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., *
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||||
***************************************************************************/
|
||||
|
||||
#include <QX11Info>
|
||||
#include <QPainter>
|
||||
#include <QRegion>
|
||||
#include <QWidget>
|
||||
#include <QtCore/QVarLengthArray>
|
||||
#include <cmath>
|
||||
#include "oxrender.h"
|
||||
|
||||
static Display *dpy = QX11Info::display();
|
||||
static Window root = RootWindow (dpy, DefaultScreen (dpy));
|
||||
|
||||
/* "qt_getClipRects" is friend enough to qregion... ;)*/
|
||||
inline void *qt_getClipRects( const QRegion &r, int &num )
|
||||
{
|
||||
return r.clipRectangles( num );
|
||||
}
|
||||
|
||||
static OXPicture createFill(Display *dpy, const XRenderColor *c)
|
||||
{
|
||||
XRenderPictureAttributes pa;
|
||||
OXPixmap pixmap = XCreatePixmap (dpy, root, 1, 1, 32);
|
||||
if (!pixmap)
|
||||
return X::None;
|
||||
pa.repeat = True;
|
||||
OXPicture fill = XRenderCreatePicture (dpy, pixmap, XRenderFindStandardFormat (dpy, PictStandardARGB32), CPRepeat, &pa);
|
||||
if (!fill)
|
||||
{
|
||||
XFreePixmap (dpy, pixmap);
|
||||
return X::None;
|
||||
}
|
||||
XRenderFillRectangle (dpy, PictOpSrc, fill, c, 0, 0, 1, 1);
|
||||
XFreePixmap (dpy, pixmap);
|
||||
return fill;
|
||||
}
|
||||
|
||||
void OXRender::composite(OXPicture src, OXPicture mask, OXPicture dst,
|
||||
int sx, int sy, int mx, int my, int dx, int dy,
|
||||
uint w, uint h, int op)
|
||||
{
|
||||
XRenderComposite (dpy, op, src, mask, dst, sx, sy, mx, my, dx, dy, w, h);
|
||||
}
|
||||
void OXRender::composite(OXPicture src, OXPicture mask, const QPixmap &dst,
|
||||
int sx, int sy, int mx, int my, int dx, int dy,
|
||||
uint w, uint h, int op)
|
||||
{
|
||||
XRenderComposite (dpy, op, src, mask, dst.x11PictureHandle(), sx, sy, mx, my, dx, dy, w, h);
|
||||
}
|
||||
void OXRender::composite(const QPixmap &src, OXPicture mask, const QPixmap &dst,
|
||||
int sx, int sy, int mx, int my, int dx, int dy,
|
||||
uint w, uint h, int op)
|
||||
{
|
||||
XRenderComposite (dpy, op, src.x11PictureHandle(), mask, dst.x11PictureHandle(), sx, sy, mx, my, dx, dy, w, h);
|
||||
}
|
||||
|
||||
bool OXRender::blend(const QPixmap &upper, QPixmap &lower, double opacity)
|
||||
{
|
||||
XRenderColor c = {0,0,0, (ushort)(opacity * 0xffff) };
|
||||
OXPicture alpha = createFill (dpy, &c);
|
||||
if (alpha == X::None)
|
||||
return false;
|
||||
XRenderComposite (dpy, PictOpOver, upper.x11PictureHandle(), alpha, lower.x11PictureHandle(), 0, 0, 0, 0, 0, 0, upper.width(), upper.height());
|
||||
XRenderFreePicture (dpy, alpha);
|
||||
return true;
|
||||
}
|
||||
|
||||
QPixmap OXRender::applyAlpha(const QPixmap &toThisPix, const QPixmap &fromThisPix, const QRect &rect, const QRect &alphaRect) {
|
||||
return applyAlpha(toThisPix, fromThisPix.x11PictureHandle(), rect, alphaRect);
|
||||
}
|
||||
|
||||
QPixmap OXRender::applyAlpha(const QPixmap &toThisPix, const OXPicture &fromThisPict, const QRect &rect, const QRect &alphaRect) {
|
||||
int sx,sy,ax,ay,w,h;
|
||||
if (rect.isNull()) {
|
||||
sx = sy = 0; w = toThisPix.width(); h = toThisPix.height();
|
||||
}
|
||||
else
|
||||
rect.getRect(&sx,&sy,&w,&h);
|
||||
if (alphaRect.isNull()) {
|
||||
ax = ay = 0;
|
||||
}
|
||||
else {
|
||||
ax = alphaRect.x(); ay = alphaRect.y();
|
||||
w = qMin(alphaRect.width(),w); h = qMin(alphaRect.height(),h);
|
||||
}
|
||||
|
||||
QPixmap pix(w,h);
|
||||
pix.fill(Qt::transparent);
|
||||
XRenderComposite (dpy, PictOpOver, toThisPix.x11PictureHandle(),
|
||||
fromThisPict, pix.x11PictureHandle(),
|
||||
sx, sy, ax, ay, 0, 0, w, h);
|
||||
return pix;
|
||||
}
|
||||
|
||||
void OXRender::setAlpha(QPixmap &pix, const OXPicture &alpha)
|
||||
{
|
||||
XRenderPictureAttributes pa;
|
||||
pa.alpha_map = alpha;
|
||||
pa.alpha_x_origin = pa.alpha_y_origin = 0;
|
||||
XRenderChangePicture(dpy, pix.x11PictureHandle(), CPAlphaMap|CPAlphaXOrigin|CPAlphaYOrigin, &pa);
|
||||
}
|
||||
|
||||
QPixmap OXRender::fade(const QPixmap &pix, double percent)
|
||||
{
|
||||
QPixmap newPix(pix.size());
|
||||
newPix.fill(Qt::transparent);
|
||||
blend(pix, newPix, percent);
|
||||
return newPix;
|
||||
}
|
||||
|
||||
void OXRender::setColor(XRenderColor &xc, double r, double g, double b, double a)
|
||||
{
|
||||
xc.red = ushort(r * 0xffff);
|
||||
xc.green = ushort(g * 0xffff);
|
||||
xc.blue = ushort(b * 0xffff);
|
||||
xc.alpha = ushort(a * 0xffff);
|
||||
}
|
||||
|
||||
void OXRender::setColor(XRenderColor &xc, QColor qc)
|
||||
{
|
||||
xc.red = qc.red()*0x101; xc.green = qc.green()*0x101;
|
||||
xc.blue = qc.blue()*0x101; xc.alpha = qc.alpha()*0x101;
|
||||
}
|
||||
|
||||
void OXRender::setGradient(XLinearGradient &lg, QPoint p1, QPoint p2)
|
||||
{
|
||||
lg.p1.x = p1.x(); lg.p1.y = p1.y();
|
||||
lg.p2.x = p2.x(); lg.p2.y = p2.y();
|
||||
}
|
||||
|
||||
void OXRender::setGradient(XLinearGradient &lg, XFixed x1, XFixed y1, XFixed x2, XFixed y2)
|
||||
{
|
||||
lg.p1.x = x1; lg.p1.y = y1;
|
||||
lg.p2.x = x2; lg.p2.y = y2;
|
||||
}
|
||||
|
||||
OXPicture OXRender::gradient(const QPoint start, const QPoint stop, const ColorArray &colors, const PointArray &stops)
|
||||
{
|
||||
XLinearGradient lg = {
|
||||
{ start.x() << 16, start.y() << 16 },
|
||||
{ stop.x() << 16, stop.y() << 16} };
|
||||
QVarLengthArray<XRenderColor> cs(colors.size());
|
||||
for (int i = 0; i < colors.size(); ++i)
|
||||
setColor(cs[i], colors.at(i));
|
||||
XFixed *stps;
|
||||
if (stops.size() < 2)
|
||||
{
|
||||
stps = new XFixed[2];
|
||||
stps[0] = 0; stps[1] = (1<<16);
|
||||
}
|
||||
else
|
||||
{
|
||||
int d = (1<<16);
|
||||
stps = new XFixed[stops.size()];
|
||||
for (int i = 0; i < stops.size(); ++i)
|
||||
{
|
||||
if (stops.at(i) < 0) continue;
|
||||
if (stops.at(i) > 1) break;
|
||||
stps[i] = stops.at(i)*d;
|
||||
}
|
||||
}
|
||||
XFlush (dpy);
|
||||
OXPicture lgp = XRenderCreateLinearGradient(dpy, &lg, stps, &cs[0], qMin(qMax(stops.size(),2),colors.size()));
|
||||
delete[] stps;
|
||||
return lgp;
|
||||
}
|
||||
|
||||
OXPicture OXRender::gradient(const QPoint c1, int r1, const QPoint c2, int r2, const ColorArray &colors, const PointArray &stops)
|
||||
{
|
||||
XRadialGradient rg = {
|
||||
{ c1.x() << 16, c1.y() << 16, r1 << 16 },
|
||||
{ c2.x() << 16, c2.y() << 16, r2 << 16 } };
|
||||
QVarLengthArray<XRenderColor> cs(colors.size());
|
||||
for (int i = 0; i < colors.size(); ++i)
|
||||
setColor(cs[i], colors.at(i));
|
||||
XFixed *stps;
|
||||
if (stops.size() < 2)
|
||||
{
|
||||
stps = new XFixed[2];
|
||||
stps[0] = 0; stps[1] = (1<<16);
|
||||
}
|
||||
else
|
||||
{
|
||||
int d = ((int)(sqrt(pow(c2.x()-c1.x(),2)+pow(c2.y()-c1.y(),2)))) << 16;
|
||||
stps = new XFixed[stops.size()];
|
||||
for (int i = 0; i < stops.size(); ++i)
|
||||
{
|
||||
if (stops.at(i) < 0) continue;
|
||||
if (stops.at(i) > 1) break;
|
||||
stps[i] = stops.at(i)*d;
|
||||
}
|
||||
}
|
||||
XFlush (dpy);
|
||||
OXPicture lgp = XRenderCreateRadialGradient(dpy, &rg, stps, &cs[0], qMin(qMax(stops.size(),2),colors.size()));
|
||||
delete[] stps;
|
||||
return lgp;
|
||||
}
|
||||
|
||||
void OXRender::freePicture(OXPicture pict)
|
||||
{
|
||||
XRenderFreePicture (dpy, pict);
|
||||
}
|
61
clients/oxygen/oxrender.h
Normal file
61
clients/oxygen/oxrender.h
Normal file
|
@ -0,0 +1,61 @@
|
|||
/***************************************************************************
|
||||
* Copyright (C) 2006-2007 by Thomas Lübking *
|
||||
* thomas.luebking@web.de *
|
||||
* *
|
||||
* 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., *
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef OXRENDER_H
|
||||
#define OXRENDER_H
|
||||
|
||||
#include <QPixmap>
|
||||
#include <QVector>
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/extensions/Xrender.h>
|
||||
#include <fixx11h.h>
|
||||
|
||||
typedef QVector<double> PointArray;
|
||||
typedef QVector<QColor> ColorArray;
|
||||
typedef Picture OXPicture;
|
||||
typedef Pixmap OXPixmap;
|
||||
|
||||
class OXRender
|
||||
{
|
||||
// public:
|
||||
// OXRender(){}
|
||||
public:
|
||||
static void composite(OXPicture src, OXPicture mask, OXPicture dst, int sx, int sy, int mx, int my, int dx, int dy, uint w, uint h, int op = PictOpSrc);
|
||||
static void composite(OXPicture src, OXPicture mask, const QPixmap &dst, int sx, int sy, int mx, int my, int dx, int dy, uint w, uint h, int op = PictOpSrc);
|
||||
static void composite(const QPixmap &src, OXPicture mask, const QPixmap &dst, int sx, int sy, int mx, int my, int dx, int dy, uint w, uint h, int op = PictOpSrc);
|
||||
static bool blend(const QPixmap &upper, QPixmap &lower, double opacity = 0.5);
|
||||
static QPixmap fade(const QPixmap &pix, double percent);
|
||||
static void setColor(XRenderColor &xc, double r, double g, double b, double a = 1);
|
||||
static void setColor(XRenderColor &xc, QColor qc);
|
||||
static void setAlpha(QPixmap &pix, const OXPicture &mask);
|
||||
static QPixmap applyAlpha(const QPixmap &toThisPix, const QPixmap &fromThisPix,
|
||||
const QRect &rect = QRect(), const QRect &alphaRect = QRect());
|
||||
static QPixmap applyAlpha(const QPixmap &toThisPix, const OXPicture &fromThisPict,
|
||||
const QRect &rect = QRect(), const QRect &alphaRect = QRect());
|
||||
static void setGradient(XLinearGradient &lg, QPoint p1, QPoint p2);
|
||||
static void setGradient(XLinearGradient &lg, XFixed x1, XFixed y1, XFixed x2, XFixed y2);
|
||||
static OXPicture gradient(const QPoint start, const QPoint stop, const ColorArray &colors, const PointArray &stops = PointArray());
|
||||
static OXPicture gradient(const QPoint c1, int r1, const QPoint c2, int r2, const ColorArray &colors, const PointArray &stops = PointArray());
|
||||
static void freePicture(OXPicture pict);
|
||||
};
|
||||
|
||||
#define Q2XRenderColor(_XRC_, _QC_) XRenderColor _XRC_; OXRender::setColor(_XRC_, _QC_)
|
||||
|
||||
#endif //OXRENDER_H
|
1226
clients/oxygen/oxygen.cpp
Normal file
1226
clients/oxygen/oxygen.cpp
Normal file
File diff suppressed because it is too large
Load diff
363
clients/oxygen/oxygen.h
Normal file
363
clients/oxygen/oxygen.h
Normal file
|
@ -0,0 +1,363 @@
|
|||
/***************************************************************************
|
||||
* Copyright (C) 2006-2007 by Thomas L<EFBFBD>bking *
|
||||
* thomas.luebking@web.de *
|
||||
* *
|
||||
* 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., *
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef OXYGEN_STYLE_H
|
||||
#define OXYGEN_STYLE_H
|
||||
|
||||
class QAbstractButton;
|
||||
class QHeaderView;
|
||||
class QMenuBar;
|
||||
class QPushButton;
|
||||
class QScrollBar;
|
||||
class QTabBar;
|
||||
class DynamicBrush;
|
||||
class QPaintEvent;
|
||||
class QFrame;
|
||||
// class GradientCache;
|
||||
|
||||
#include <QCache>
|
||||
#include <QHash>
|
||||
#include <QMap>
|
||||
#include <QCommonStyle>
|
||||
#include <QBitmap>
|
||||
#include <QRegion>
|
||||
#include <QWidget>
|
||||
#include <X11/Xlib.h>
|
||||
#include <fixx11h.h>
|
||||
#include "tileset.h"
|
||||
|
||||
namespace Oxygen {
|
||||
|
||||
enum BGMode { Plain = 0, Scanlines, Dummy, FullPix, VGradient1, HGradient1, VGradient2, HGradient2, Glass };
|
||||
enum Acceleration { None = 0, QtGradient, XRender, OpenGL };
|
||||
enum TabTransition {Jump = 0, CrossFade, ScanlineBlend, SlideIn, SlideOut, RollIn, RollOut, OpenVertically, CloseVertically, OpenHorizontally, CloseHorizontally };
|
||||
|
||||
class EventKiller : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
bool eventFilter( QObject *object, QEvent *event);
|
||||
};
|
||||
|
||||
class OxygenStyle;
|
||||
|
||||
class HoverFadeInfo {
|
||||
public:
|
||||
HoverFadeInfo(int s = 0, bool fI = true) {step = s; fadeIn = fI; }
|
||||
int step;
|
||||
bool fadeIn;
|
||||
};
|
||||
|
||||
class ComplexHoverFadeInfo {
|
||||
public:
|
||||
ComplexHoverFadeInfo() {
|
||||
activeSubControls = fadingInControls = fadingOutControls = QStyle::SC_None;
|
||||
}
|
||||
QStyle::SubControls activeSubControls, fadingInControls, fadingOutControls;
|
||||
QHash<QStyle::SubControl, int> steps;
|
||||
};
|
||||
|
||||
class IndexedFadeInfo {
|
||||
public:
|
||||
IndexedFadeInfo(long int index) { this->index = index; }
|
||||
long int index;
|
||||
QHash<long int, int> fadingInIndices, fadingOutIndices;
|
||||
int step(long int index);
|
||||
};
|
||||
|
||||
class TabAnimInfo : public QObject {
|
||||
Q_OBJECT
|
||||
public:
|
||||
TabAnimInfo(QObject *parent = 0, int currentTab = -1) :
|
||||
QObject(parent), lastTab(currentTab), animStep(0){}
|
||||
protected:
|
||||
bool eventFilter( QObject* object, QEvent* event );
|
||||
public:
|
||||
QList < QWidget* > autofillingWidgets;
|
||||
int lastTab, animStep;
|
||||
QPixmap tabPix[3];
|
||||
};
|
||||
|
||||
enum Orientation3D {Sunken = 0, Relief, Raised};
|
||||
enum GradientType {
|
||||
GradSimple = 0,
|
||||
GradSunken,
|
||||
GradGloss,
|
||||
GradGlass,
|
||||
GradRadialGloss,
|
||||
GradButton,
|
||||
NumGrads
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
int $1, $2, $3, $4, $5, $6, $7, $8, $9, $10;
|
||||
int $12, $13, $16, $32, $18, $20, $80;
|
||||
int ScrollBarExtent;
|
||||
int ScrollBarSliderMin;
|
||||
int SliderThickness;
|
||||
int SliderControl;
|
||||
int Indicator;
|
||||
int ExclusiveIndicator;
|
||||
} Dpi;
|
||||
|
||||
typedef struct Config {
|
||||
GradientType gradient, gradBtn, gradientStrong;
|
||||
BGMode bgMode;
|
||||
Acceleration acceleration;
|
||||
int structure;
|
||||
TabTransition tabTransition;
|
||||
int gradientIntensity;
|
||||
bool aqua, showMenuIcons, glassProgress, glassMenus, menuShadow;
|
||||
double scale;
|
||||
int checkType;
|
||||
QPalette::ColorRole role_progress[2], role_tab[2],
|
||||
role_btn[2], role_btnHover[2], role_popup[2];
|
||||
} Config;
|
||||
|
||||
class VisualFrame : public QWidget {
|
||||
Q_OBJECT
|
||||
public:
|
||||
VisualFrame(QFrame *parent, int top = 0, int left = 0, int right = 0, int bottom = 0);
|
||||
bool eventFilter ( QObject * o, QEvent * ev );
|
||||
void paintEvent ( QPaintEvent * event );
|
||||
protected:
|
||||
// void dragEnterEvent ( QDragEnterEvent * event ) { passDownEvent(event, event->globalPos()); }
|
||||
// void dragLeaveEvent ( QDragLeaveEvent * event ) { passDownEvent(event, event->globalPos()); }
|
||||
// void dragMoveEvent ( QDragMoveEvent * event ) { passDownEvent(event, event->globalPos()); }
|
||||
// void dropEvent ( QDropEvent * event ) { passDownEvent(event, event->globalPos()); }
|
||||
// void enterEvent ( QEvent * event ) { passDownEvent(event, event->globalPos()); }
|
||||
// void leaveEvent ( QEvent * event ) { passDownEvent(event, event->globalPos()); }
|
||||
void mouseDoubleClickEvent ( QMouseEvent * event );
|
||||
void mouseMoveEvent ( QMouseEvent * event );
|
||||
void mousePressEvent ( QMouseEvent * event );
|
||||
void mouseReleaseEvent ( QMouseEvent * event );
|
||||
void wheelEvent ( QWheelEvent * event );
|
||||
private:
|
||||
void passDownEvent(QEvent *ev, const QPoint &gMousePos);
|
||||
int off[4];
|
||||
};
|
||||
|
||||
class OxygenStyle : public QCommonStyle {
|
||||
Q_OBJECT
|
||||
public:
|
||||
enum WidgetState{Basic = 0, Hovered, Focused, Active};
|
||||
|
||||
OxygenStyle();
|
||||
~OxygenStyle();
|
||||
|
||||
//inheritance from QStyle
|
||||
void drawComplexControl ( ComplexControl control,
|
||||
const QStyleOptionComplex * option,
|
||||
QPainter * painter,
|
||||
const QWidget * widget = 0 ) const;
|
||||
|
||||
void drawControl ( ControlElement element,
|
||||
const QStyleOption * option,
|
||||
QPainter * painter,
|
||||
const QWidget * widget = 0 ) const;
|
||||
|
||||
/**what do they do?
|
||||
virtual void drawItemPixmap ( QPainter * painter, const QRect & rect, int alignment, const QPixmap & pixmap ) const;
|
||||
virtual void drawItemText ( QPainter * painter, const QRect & rect, int alignment, const QPalette & pal, bool enabled, const QString & text, QPalette::ColorRole textRole = QPalette::NoRole ) const;
|
||||
*/
|
||||
|
||||
void drawPrimitive ( PrimitiveElement elem,
|
||||
const QStyleOption * option,
|
||||
QPainter * painter,
|
||||
const QWidget * widget = 0 ) const;
|
||||
|
||||
QPixmap standardPixmap ( StandardPixmap standardPixmap,
|
||||
const QStyleOption * option = 0,
|
||||
const QWidget * widget = 0 ) const;
|
||||
|
||||
// what do they do? ========================================
|
||||
// QPixmap generatedIconPixmap ( QIcon::Mode iconMode,
|
||||
// const QPixmap & pixmap,
|
||||
// const QStyleOption * option ) const;
|
||||
// SubControl hitTestComplexControl ( ComplexControl control,
|
||||
// const QStyleOptionComplex * option,
|
||||
// const QPoint & pos,
|
||||
// const QWidget * widget = 0 ) const;
|
||||
// QRect itemPixmapRect ( const QRect & rect,
|
||||
// int alignment,
|
||||
// const QPixmap & pixmap ) const;
|
||||
// QRect itemTextRect ( const QFontMetrics & metrics,
|
||||
// const QRect & rect,
|
||||
// int alignment,
|
||||
// bool enabled,
|
||||
// const QString & text ) const;
|
||||
//=============================================================
|
||||
|
||||
int pixelMetric ( PixelMetric metric,
|
||||
const QStyleOption * option = 0,
|
||||
const QWidget * widget = 0 ) const;
|
||||
|
||||
void polish( QWidget *w );
|
||||
void polish( QApplication * );
|
||||
void polish( QPalette &pal );
|
||||
|
||||
QSize sizeFromContents ( ContentsType type,
|
||||
const QStyleOption * option,
|
||||
const QSize & contentsSize,
|
||||
const QWidget * widget = 0 ) const;
|
||||
|
||||
int styleHint ( StyleHint hint,
|
||||
const QStyleOption * option = 0,
|
||||
const QWidget * widget = 0,
|
||||
QStyleHintReturn * returnData = 0 ) const;
|
||||
|
||||
QRect subControlRect ( ComplexControl control,
|
||||
const QStyleOptionComplex * option,
|
||||
SubControl subControl,
|
||||
const QWidget * widget = 0 ) const;
|
||||
|
||||
QRect subElementRect ( SubElement element,
|
||||
const QStyleOption * option,
|
||||
const QWidget * widget = 0 ) const;
|
||||
|
||||
QPalette standardPalette () const;
|
||||
|
||||
void unPolish( QWidget *w );
|
||||
void unPolish( QApplication *a );
|
||||
|
||||
// from QObject
|
||||
bool eventFilter( QObject *object, QEvent *event );
|
||||
|
||||
signals:
|
||||
void MDIPopup(QPoint);
|
||||
|
||||
private slots:
|
||||
void fakeMouse();
|
||||
void handleIPC(int, int);
|
||||
|
||||
// animation slots ============================
|
||||
void progressbarDestroyed(QObject*);
|
||||
void updateProgressbars();
|
||||
|
||||
void tabChanged(int index);
|
||||
void updateTabAnimation();
|
||||
void tabDestroyed(QObject* obj);
|
||||
|
||||
void updateFades();
|
||||
void fadeDestroyed(QObject* obj);
|
||||
|
||||
void updateComplexFades();
|
||||
void complexFadeDestroyed(QObject* obj);
|
||||
|
||||
void updateIndexedFades();
|
||||
void indexedFadeDestroyed(QObject* obj);
|
||||
|
||||
//=========================================
|
||||
|
||||
private:
|
||||
OxygenStyle( const OxygenStyle & );
|
||||
OxygenStyle& operator=( const OxygenStyle & );
|
||||
const QPixmap &gradient(const QColor &c,
|
||||
int size,
|
||||
Qt::Orientation o,
|
||||
GradientType type = GradSimple) const;
|
||||
const QPixmap &btnAmbient(int height) const;
|
||||
const QPixmap &tabShadow(int height, bool bottom = false) const;
|
||||
const QPixmap &groupLight(int height) const;
|
||||
|
||||
void fillWithMask(QPainter *painter,
|
||||
const QRect &rect,
|
||||
const QBrush &brush,
|
||||
const Tile::Mask *mask,
|
||||
Tile::PosFlags pf = Tile::Full,
|
||||
bool justClip = false,
|
||||
QPoint offset = QPoint(),
|
||||
bool inverse = false,
|
||||
const QRect *outerRect = 0L) const;
|
||||
void fillWithMask(QPainter *painter,
|
||||
const QPoint &xy,
|
||||
const QBrush &brush,
|
||||
const QPixmap &mask,
|
||||
QPoint offset = QPoint()) const;
|
||||
|
||||
QColor mapFadeColor(const QColor &color, int index) const;
|
||||
void fadeIn(QWidget *widget);
|
||||
void fadeOut(QWidget *widget );
|
||||
QPixmap *tint(const QImage &img, const QColor& c) const;
|
||||
const Tile::Set &glow(const QColor & c, bool round = false) const;
|
||||
void readSettings();
|
||||
void generatePixmaps();
|
||||
void initMetrics();
|
||||
void makeStructure(int num, const QColor &c);
|
||||
int hoverStep(const QWidget *widget) const;
|
||||
const ComplexHoverFadeInfo *complexHoverFadeInfo(const QWidget *widget,
|
||||
SubControls activeSubControls) const;
|
||||
const IndexedFadeInfo *indexedFadeInfo(const QWidget *widget, long int index) const;
|
||||
int progressStep(const QWidget *w) const;
|
||||
|
||||
private:
|
||||
typedef QHash<QWidget*, HoverFadeInfo> HoverFades;
|
||||
typedef QCache<uint, QPixmap> PixmapCache;
|
||||
typedef QHash<uint, Tile::Set> TileCache;
|
||||
struct {
|
||||
Tile::Mask /*rect[3], round[3], */button, tab/*, group*/;
|
||||
QPixmap radio, radioIndicator, radioGroove, notch, slider[4];
|
||||
QPixmap winClose, winMin, winMax;
|
||||
QRegion popupCorner[4];
|
||||
} masks;
|
||||
struct {
|
||||
Tile::Set button[2][8], tab, sunken, group, lineEdit[2], raised, relief;
|
||||
QPixmap radio[2][2];
|
||||
QPixmap winClose[2], winMin[2], winMax[2];
|
||||
Tile::Line line[2][3];
|
||||
QPixmap slider[4][2][2];
|
||||
} shadows;
|
||||
struct {
|
||||
Tile::Set rect[3], round[3], button[2];
|
||||
} frames;
|
||||
struct {
|
||||
Tile::Line top;
|
||||
QPixmap slider[4];
|
||||
Tile::Mask button;
|
||||
} lights;
|
||||
|
||||
// pixmaps
|
||||
QPixmap *_scanlines[2];
|
||||
// cache
|
||||
// GradientCache *gradients[2][NumGrads];
|
||||
PixmapCache gradients[2][NumGrads];
|
||||
PixmapCache _btnAmbient, _tabShadow, _groupLight;
|
||||
TileCache glowCache;
|
||||
TileCache roundGlowCache;
|
||||
|
||||
|
||||
//anmiated progressbars
|
||||
bool animationUpdate;
|
||||
int complexStep;
|
||||
|
||||
// QPalette tooltipPalette;
|
||||
|
||||
// toolbar title functionality ========================
|
||||
QPoint cursorPos_;
|
||||
bool mouseButtonPressed_;
|
||||
bool internalEvent_;
|
||||
// ===========================
|
||||
DynamicBrush *_bgBrush;
|
||||
Pixmap popupPix;
|
||||
QTimer* timer;
|
||||
};
|
||||
|
||||
} // namespace Oxygen
|
||||
#endif //OXYGEN_STYLE_H
|
13
clients/oxygen/oxygen.pro
Normal file
13
clients/oxygen/oxygen.pro
Normal file
|
@ -0,0 +1,13 @@
|
|||
HEADERS = oxrender.h oxygen.h dynamicbrush.h \
|
||||
tileset.h debug.h
|
||||
SOURCES = oxrender.cpp oxygen.cpp tileset.cpp stylehint.cpp \
|
||||
sizefromcontents.cpp qsubcmetrics.cpp \
|
||||
pixelmetric.cpp stdpix.cpp \
|
||||
drawcomplexcontrol.cpp drawcontrol.cpp \
|
||||
drawprimitive.cpp dynamicbrush.cpp
|
||||
TEMPLATE = lib
|
||||
PLUGIN = true
|
||||
RESOURCES = oxygen.qrc
|
||||
CONFIG += qt x11 plugin
|
||||
QT += qt3support opengl
|
||||
VERSION = 0.1
|
7
clients/oxygen/oxygen.qrc
Normal file
7
clients/oxygen/oxygen.qrc
Normal file
|
@ -0,0 +1,7 @@
|
|||
<!DOCTYPE RCC><RCC version="1.0">
|
||||
<qresource>
|
||||
<file alias="leftCenter">../imagebase/leftCenter.png</file>
|
||||
<file alias="leftTile">../imagebase/leftTile.png</file>
|
||||
<file alias="glow">../imagebase/glow.png</file>
|
||||
</qresource>
|
||||
</RCC>
|
22
clients/oxygen/oxygen.themerc
Normal file
22
clients/oxygen/oxygen.themerc
Normal file
|
@ -0,0 +1,22 @@
|
|||
[Misc]
|
||||
Name=Oxygen
|
||||
Name[vi]=Oxy
|
||||
Name[xx]=xxOxygenxx
|
||||
ConfigPage=kstyle-oxygen-config
|
||||
Comment=A really cool style
|
||||
Comment[be]=Сапраўды круты стыль
|
||||
Comment[bg]=Наистина супер стил
|
||||
Comment[br]=Ur giz kool a-walc'h
|
||||
Comment[de]=Ein wirklich frischer Stil
|
||||
Comment[el]=Ένα πολύ όμορφο στυλ
|
||||
Comment[es]=Un estilo realmente bueno
|
||||
Comment[et]=Tõeliselt lahe stiil
|
||||
Comment[it]=Uno stile veramente carino
|
||||
Comment[nl]=Een erg gave stijl
|
||||
Comment[pt]=Um estilo realmente giro
|
||||
Comment[pt_BR]=Um estilo realmente giro
|
||||
Comment[sv]=En verkligt häftig stil
|
||||
Comment[tr]=Basit ve temiz bir stil
|
||||
Comment[xx]=xxA really cool stylexx
|
||||
[KDE]
|
||||
WidgetStyle=Oxygen
|
203
clients/oxygen/pixelmetric.cpp
Normal file
203
clients/oxygen/pixelmetric.cpp
Normal file
|
@ -0,0 +1,203 @@
|
|||
/***************************************************************************
|
||||
* Copyright (C) 2006-2007 by Thomas L<EFBFBD>bking *
|
||||
* thomas.luebking@web.de *
|
||||
* *
|
||||
* 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., *
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||||
***************************************************************************/
|
||||
|
||||
#include <QFrame>
|
||||
#include <QWidget>
|
||||
#include <QSlider>
|
||||
#include <QStyleOptionTabWidgetFrame>
|
||||
#include <QTabBar>
|
||||
#include <QTabWidget>
|
||||
#include "oxygen.h"
|
||||
|
||||
#include <QtDebug>
|
||||
|
||||
using namespace Oxygen;
|
||||
|
||||
extern Dpi dpi;
|
||||
|
||||
int OxygenStyle::pixelMetric ( PixelMetric pm, const QStyleOption * option, const QWidget * widget ) const
|
||||
{
|
||||
#if 1
|
||||
switch ( pm )
|
||||
{
|
||||
case PM_ButtonMargin: // Amount of whitespace between push button labels and the frame
|
||||
return dpi.$4;
|
||||
case PM_ButtonDefaultIndicator: // Width of the default-button indicator frame
|
||||
return dpi.$2;
|
||||
case PM_MenuButtonIndicator: // Width of the menu button indicator proportional to the widget height
|
||||
return dpi.$7;
|
||||
case PM_ButtonShiftHorizontal: // Horizontal contents shift of a button when the button is down
|
||||
case PM_ButtonShiftVertical: // Vertical contents shift of a button when the button is down
|
||||
return 0;
|
||||
case PM_DefaultFrameWidth: // Default frame width (usually 2)
|
||||
if (widget && widget->inherits("QComboBoxPrivateContainer"))
|
||||
return 1;
|
||||
if (widget && qobject_cast<const QFrame*>(widget) &&
|
||||
static_cast<const QFrame*>(widget)->frameShape() == QFrame::StyledPanel &&
|
||||
!widget->inherits("QTextEdit"))
|
||||
return dpi.$1;
|
||||
#warning stupid idea?
|
||||
return dpi.$1;
|
||||
case PM_SpinBoxFrameWidth: // Frame width of a spin box, defaults to PM_DefaultFrameWidth
|
||||
return dpi.$1;
|
||||
case PM_ComboBoxFrameWidth: // Frame width of a combo box, defaults to PM_DefaultFrameWidth.
|
||||
return dpi.$2;
|
||||
// case PM_MDIFrameWidth: // Frame width of an MDI window
|
||||
// case PM_MDIMinimizedWidth: // Width of a minimized MDI window
|
||||
case PM_MaximumDragDistance: // Some feels require the scroll bar or other sliders to jump back to the original position when the mouse pointer is too far away while dragging; a value of -1 disables this behavior
|
||||
return -1;
|
||||
case PM_ScrollBarExtent: // Width of a vertical scroll bar and the height of a horizontal scroll bar
|
||||
return (widget && widget->parentWidget() &&
|
||||
widget->parentWidget()->parentWidget() &&
|
||||
widget->parentWidget()->parentWidget()->inherits("QComboBoxListView")) ?
|
||||
dpi.$16 : dpi.ScrollBarExtent;
|
||||
case PM_ScrollBarSliderMin: // The minimum height of a vertical scroll bar's slider and the minimum width of a horizontal scroll bar's slider
|
||||
return dpi.ScrollBarSliderMin;
|
||||
case PM_SliderThickness: // Total slider thickness
|
||||
return dpi.SliderThickness;
|
||||
case PM_SliderControlThickness: // Thickness of the slider handle
|
||||
case PM_SliderLength: // Length of the slider
|
||||
return dpi.SliderControl;
|
||||
// case PM_SliderTickmarkOffset: // The offset between the tickmarks and the slider
|
||||
case PM_SliderSpaceAvailable: { // The available space for the slider to move
|
||||
if (!widget)
|
||||
return 0;
|
||||
if ( const QSlider *slider = qobject_cast<const QSlider*>(widget))
|
||||
if (slider->orientation() == Qt::Horizontal)
|
||||
return (widget->width() - dpi.SliderControl);
|
||||
else
|
||||
return (widget->height() - dpi.SliderControl);
|
||||
}
|
||||
case PM_DockWidgetSeparatorExtent: // Width of a separator in a horizontal dock window and the height of a separator in a vertical dock window
|
||||
return dpi.$10;
|
||||
case PM_DockWidgetHandleExtent: // Width of the handle in a horizontal dock window and the height of the handle in a vertical dock window
|
||||
return dpi.$6;
|
||||
case PM_DockWidgetFrameWidth: // Frame width of a dock window
|
||||
return dpi.$1;
|
||||
case PM_MenuBarPanelWidth: // Frame width of a menubar, defaults to PM_DefaultFrameWidth
|
||||
return 0;
|
||||
case PM_MenuBarItemSpacing: // Spacing between menubar items
|
||||
return dpi.$6;
|
||||
case PM_MenuBarHMargin: // Spacing between menubar items and left/right of bar
|
||||
return dpi.$6;
|
||||
case PM_MenuBarVMargin: // Spacing between menubar items and top/bottom of bar
|
||||
return 0;
|
||||
case PM_ToolBarFrameWidth: // Width of the frame around toolbars
|
||||
return dpi.$4;
|
||||
case PM_ToolBarHandleExtent: // Width of a toolbar handle in a horizontal toolbar and the height of the handle in a vertical toolbar
|
||||
return dpi.$6;
|
||||
case PM_ToolBarItemMargin: // Spacing between the toolbar frame and the items
|
||||
return dpi.$4;
|
||||
case PM_ToolBarItemSpacing: // Spacing between toolbar items
|
||||
return 0;
|
||||
case PM_ToolBarSeparatorExtent: // Width of a toolbar separator in a horizontal toolbar and the height of a separator in a vertical toolbar
|
||||
return dpi.$2;
|
||||
case PM_ToolBarExtensionExtent: // Width of a toolbar extension button in a horizontal toolbar and the height of the button in a vertical toolbar
|
||||
return dpi.$16;
|
||||
case PM_TabBarTabOverlap: // Number of pixels the tabs should overlap
|
||||
return 0;
|
||||
case PM_TabBarTabHSpace: // Extra space added to the tab width
|
||||
return dpi.$12;
|
||||
case PM_TabBarTabVSpace: // Extra space added to the tab height
|
||||
return dpi.$10;
|
||||
case PM_TabBarBaseHeight: // Height of the area between the tab bar and the tab pages
|
||||
case PM_TabBarBaseOverlap: { // Number of pixels the tab bar overlaps the tab bar base
|
||||
if (!widget)
|
||||
return dpi.$16;
|
||||
const QTabBar *tabBar = qobject_cast<const QTabBar*>(widget);
|
||||
if (qobject_cast<const QTabWidget*>(widget) &&
|
||||
!widget->children().isEmpty()) {
|
||||
foreach(QObject *obj, widget->children()) {
|
||||
if (qobject_cast<QTabBar*>(obj)) {
|
||||
tabBar = (QTabBar*)obj;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!tabBar || !tabBar->isVisible())
|
||||
return dpi.$16;
|
||||
if (const QStyleOptionTabWidgetFrame *twf =
|
||||
qstyleoption_cast<const QStyleOptionTabWidgetFrame *>(option)) {
|
||||
if (twf->shape == QTabBar::RoundedEast ||
|
||||
twf->shape == QTabBar::TriangularEast ||
|
||||
twf->shape == QTabBar::RoundedWest ||
|
||||
twf->shape == QTabBar::TriangularWest)
|
||||
return tabBar->width();
|
||||
}
|
||||
return tabBar->height();
|
||||
}
|
||||
case PM_TabBarScrollButtonWidth: //
|
||||
return dpi.$16;
|
||||
case PM_TabBarTabShiftHorizontal: // Horizontal pixel shift when a tab is selected
|
||||
return 0;
|
||||
case PM_TabBarTabShiftVertical: // Vertical pixel shift when a tab is selected
|
||||
return dpi.$2;
|
||||
// case PM_ProgressBarChunkWidth: // Width of a chunk in a progress bar indicator
|
||||
case PM_SplitterWidth: // Width of a splitter
|
||||
return dpi.$9;
|
||||
case PM_TitleBarHeight: // Height of the title bar
|
||||
return dpi.ExclusiveIndicator;
|
||||
case PM_IndicatorWidth: // Width of a check box indicator
|
||||
case PM_IndicatorHeight: // Height of a checkbox indicator
|
||||
return dpi.Indicator;
|
||||
case PM_ExclusiveIndicatorWidth: // Width of a radio button indicator
|
||||
case PM_ExclusiveIndicatorHeight: // Height of a radio button indicator
|
||||
return dpi.ExclusiveIndicator;
|
||||
case PM_MenuPanelWidth: // Border width (applied on all sides) for a QMenu
|
||||
return dpi.$3;
|
||||
case PM_MenuHMargin: // Additional border (used on left and right) for a QMenu
|
||||
return 0; //dpi.$2;
|
||||
case PM_MenuVMargin: // Additional border (used for bottom and top) for a QMenu
|
||||
return 0; //dpi.$1;
|
||||
// case PM_MenuScrollerHeight: // Height of the scroller area in a QMenu
|
||||
// case PM_MenuTearoffHeight: // Height of a tear off area in a QMenu
|
||||
// case PM_MenuDesktopFrameWidth: //
|
||||
// case PM_CheckListButtonSize: // Area (width/height) of the checkbox/radio button in a Q3CheckListItem
|
||||
// case PM_CheckListControllerSize: // Area (width/height) of the controller in a Q3CheckListItem
|
||||
// case PM_DialogButtonsSeparator: // Distance between buttons in a dialog buttons widget
|
||||
// case PM_DialogButtonsButtonWidth: // Minimum width of a button in a dialog buttons widget
|
||||
// case PM_DialogButtonsButtonHeight: // Minimum height of a button in a dialog buttons widget
|
||||
// case PM_HeaderMarkSize: //
|
||||
// case PM_HeaderGripMargin: //
|
||||
case PM_HeaderMargin: //
|
||||
return dpi.$2;
|
||||
case PM_SpinBoxSliderHeight: // The height of the optional spin box slider
|
||||
return dpi.$4;
|
||||
// case PM_DefaultTopLevelMargin: //
|
||||
// case PM_DefaultChildMargin: //
|
||||
// case PM_DefaultLayoutSpacing: //
|
||||
case PM_ToolBarIconSize: // Default tool bar icon size, defaults to PM_SmallIconSize
|
||||
return 32;
|
||||
case PM_SmallIconSize: // Default small icon size
|
||||
return 22;
|
||||
case PM_LargeIconSize: // Default large icon size
|
||||
return 32;
|
||||
case PM_FocusFrameHMargin: // Horizontal margin that the focus frame will outset the widget by.
|
||||
return dpi.$4;
|
||||
case PM_FocusFrameVMargin: // Vertical margin that the focus frame will outset the widget by.
|
||||
return dpi.$2;
|
||||
// case PM_IconViewIconSize: //
|
||||
// case PM_ListViewIconSize: //
|
||||
// case PM_ToolTipLabelFrameWidth: //
|
||||
default:
|
||||
#endif
|
||||
return QCommonStyle::pixelMetric( pm, option, widget );
|
||||
} // switch
|
||||
}
|
1213
clients/oxygen/qrc_oxygen.cpp
Normal file
1213
clients/oxygen/qrc_oxygen.cpp
Normal file
File diff suppressed because it is too large
Load diff
520
clients/oxygen/qsubcmetrics.cpp
Normal file
520
clients/oxygen/qsubcmetrics.cpp
Normal file
|
@ -0,0 +1,520 @@
|
|||
/***************************************************************************
|
||||
* Copyright (C) 2006-2007 by Thomas Lübking *
|
||||
* thomas.luebking@web.de *
|
||||
* *
|
||||
* 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., *
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||||
***************************************************************************/
|
||||
|
||||
#include <QAbstractItemView>
|
||||
#include <QApplication>
|
||||
#include <QComboBox>
|
||||
#include <QTabBar>
|
||||
#include <QStyleOption>
|
||||
#include <QStyleOptionTab>
|
||||
#include <limits.h>
|
||||
#include "oxygen.h"
|
||||
|
||||
using namespace Oxygen;
|
||||
extern Dpi dpi;
|
||||
|
||||
QRect OxygenStyle::subControlRect ( ComplexControl control, const QStyleOptionComplex * option, SubControl subControl, const QWidget * widget) const
|
||||
{
|
||||
QRect ret;
|
||||
switch (control) {
|
||||
case CC_SpinBox: // A spinbox, like QSpinBox
|
||||
if (const QStyleOptionSpinBox *spinbox =
|
||||
qstyleoption_cast<const QStyleOptionSpinBox *>(option)) {
|
||||
QSize bs = spinbox->rect.size();
|
||||
bs.setHeight(bs.height()/2);
|
||||
// 1.6 -approximate golden mean
|
||||
bs.setWidth(qMax(dpi.$18, qMin(bs.height(), bs.width() / 4)));
|
||||
// bs = bs.expandedTo(QApplication::globalStrut());
|
||||
int x = spinbox->rect.width() - bs.width();
|
||||
switch (subControl) {
|
||||
case SC_SpinBoxUp:
|
||||
ret = QRect(x, 0, bs.width(), bs.height());
|
||||
break;
|
||||
case SC_SpinBoxDown:
|
||||
ret = QRect(x, bs.height(), bs.width(), spinbox->rect.height()-bs.height());
|
||||
break;
|
||||
case SC_SpinBoxEditField: {
|
||||
int hfw = 0, vfw = 0;
|
||||
if (spinbox->frame) {
|
||||
hfw = dpi.$3; vfw = dpi.$1;
|
||||
}
|
||||
// in next line -1 and +2 is too offset some qt weirdness so spinbox and linedit have same height
|
||||
ret = QRect(hfw, vfw-1, x-dpi.$1, spinbox->rect.height() - 2*vfw + 2);
|
||||
break;
|
||||
}
|
||||
case SC_SpinBoxFrame:
|
||||
ret = spinbox->rect;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
ret = visualRect(spinbox->direction, spinbox->rect, ret);
|
||||
}
|
||||
case CC_ComboBox: // A combobox, like QComboBox
|
||||
if (const QStyleOptionComboBox *cb =
|
||||
qstyleoption_cast<const QStyleOptionComboBox *>(option)) {
|
||||
int x,y,wi,he;
|
||||
cb->rect.getRect(&x,&y,&wi,&he);
|
||||
int margin = 1;//(!cb->editable) ? dpi.$1 : (cb->frame ? dpi.$4 : 0);
|
||||
|
||||
switch (subControl) {
|
||||
case SC_ComboBoxFrame:
|
||||
ret = cb->rect;
|
||||
break;
|
||||
case SC_ComboBoxArrow:
|
||||
x += wi; wi = (int)((he - 2*margin)/1.1);//1.618
|
||||
x -= margin + wi; // golden mean
|
||||
// y += margin;
|
||||
ret.setRect(x, y, wi, he/* - 2*margin*/);
|
||||
break;
|
||||
case SC_ComboBoxEditField:
|
||||
wi -= (int)((he - 2*margin)/1.1) + 3*margin;
|
||||
ret.setRect(x+margin, y+margin, wi, he - 2*margin);
|
||||
break;
|
||||
case SC_ComboBoxListBoxPopup:
|
||||
ret = cb->rect;
|
||||
if (!cb->editable) { // shorten for the arrow
|
||||
wi -= (int)((he - 2*margin)/1.1) + 3*margin;
|
||||
ret.setRect(x+margin, y, wi, he);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
ret = visualRect(cb->direction, cb->rect, ret);
|
||||
}
|
||||
break;
|
||||
case CC_GroupBox:
|
||||
if (const QStyleOptionGroupBox *groupBox =
|
||||
qstyleoption_cast<const QStyleOptionGroupBox *>(option)) {
|
||||
switch (subControl) {
|
||||
case SC_GroupBoxFrame:
|
||||
ret = groupBox->rect;
|
||||
break;
|
||||
case SC_GroupBoxContents: {
|
||||
int top = dpi.$6;
|
||||
if (!groupBox->text.isEmpty())
|
||||
top += groupBox->fontMetrics.height();
|
||||
ret = groupBox->rect.adjusted(dpi.$3,top,-dpi.$3,-dpi.$7);
|
||||
break;
|
||||
}
|
||||
case SC_GroupBoxCheckBox: {
|
||||
int cbsz = pixelMetric(PM_IndicatorWidth, groupBox, widget);
|
||||
if (groupBox->direction == Qt::LeftToRight) {
|
||||
ret = groupBox->rect.adjusted(dpi.$5,dpi.$5,0,0);
|
||||
ret.setWidth(cbsz);
|
||||
}
|
||||
else {
|
||||
ret = groupBox->rect.adjusted(0,dpi.$5,-dpi.$5,0);
|
||||
ret.setLeft(ret.right()-cbsz);
|
||||
}
|
||||
ret.setHeight(cbsz);
|
||||
break;
|
||||
}
|
||||
case SC_GroupBoxLabel: {
|
||||
QFontMetrics fontMetrics = groupBox->fontMetrics;
|
||||
int h = fontMetrics.height()+dpi.$4;
|
||||
int tw = fontMetrics.size(Qt::TextShowMnemonic, groupBox->text + QLatin1Char(' ')).width();
|
||||
int marg = (groupBox->features & QStyleOptionFrameV2::Flat) ? 0 : dpi.$4;
|
||||
|
||||
ret = groupBox->rect.adjusted(marg, dpi.$4, -marg, 0);
|
||||
ret.setHeight(h);
|
||||
|
||||
// Adjusted rect for label + indicatorWidth + indicatorSpace
|
||||
ret = alignedRect(groupBox->direction, Qt::AlignHCenter, QSize(tw, h), ret);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case CC_ScrollBar: // A scroll bar, like QScrollBar
|
||||
if (const QStyleOptionSlider *scrollbar =
|
||||
qstyleoption_cast<const QStyleOptionSlider *>(option)) {
|
||||
int sbextent = pixelMetric(PM_ScrollBarExtent, scrollbar, widget);
|
||||
int maxlen = ((scrollbar->orientation == Qt::Horizontal) ?
|
||||
scrollbar->rect.width() : scrollbar->rect.height()) - (sbextent * 2);
|
||||
int sliderlen;
|
||||
|
||||
// calculate slider length
|
||||
if (scrollbar->maximum != scrollbar->minimum) {
|
||||
uint range = scrollbar->maximum - scrollbar->minimum;
|
||||
sliderlen = (qint64(scrollbar->pageStep) * maxlen) / (range + scrollbar->pageStep);
|
||||
|
||||
int slidermin = pixelMetric(PM_ScrollBarSliderMin, scrollbar, widget);
|
||||
if (sliderlen < slidermin || range > INT_MAX / 2)
|
||||
sliderlen = slidermin;
|
||||
if (sliderlen > maxlen)
|
||||
sliderlen = maxlen;
|
||||
}
|
||||
else
|
||||
sliderlen = maxlen;
|
||||
|
||||
int sliderstart = sliderPositionFromValue(scrollbar->minimum,
|
||||
scrollbar->maximum, scrollbar->sliderPosition, maxlen - sliderlen,
|
||||
scrollbar->upsideDown);
|
||||
switch (subControl) {
|
||||
case SC_ScrollBarSubLine: // top/left button
|
||||
if (scrollbar->orientation == Qt::Horizontal) {
|
||||
int buttonWidth = qMin(scrollbar->rect.width() / 2, sbextent);
|
||||
ret.setRect(scrollbar->rect.width() - 2*buttonWidth, 0, buttonWidth, sbextent);
|
||||
}
|
||||
else {
|
||||
int buttonHeight = qMin(scrollbar->rect.height() / 2, sbextent);
|
||||
ret.setRect(0, scrollbar->rect.height() - 2*buttonHeight, sbextent, buttonHeight);
|
||||
}
|
||||
break;
|
||||
case SC_ScrollBarAddLine: // bottom/right button
|
||||
if (scrollbar->orientation == Qt::Horizontal) {
|
||||
int buttonWidth = qMin(scrollbar->rect.width()/2, sbextent);
|
||||
ret.setRect(scrollbar->rect.width() - buttonWidth, 0, buttonWidth, sbextent);
|
||||
}
|
||||
else {
|
||||
int buttonHeight = qMin(scrollbar->rect.height()/2, sbextent);
|
||||
ret.setRect(0, scrollbar->rect.height() - buttonHeight, sbextent, buttonHeight);
|
||||
}
|
||||
break;
|
||||
case SC_ScrollBarSubPage: // between top/left button and slider
|
||||
if (scrollbar->orientation == Qt::Horizontal)
|
||||
ret.setRect(dpi.$2, 0, sliderstart, sbextent);
|
||||
else
|
||||
ret.setRect(0, dpi.$2, sbextent, sliderstart);
|
||||
break;
|
||||
case SC_ScrollBarAddPage: // between bottom/right button and slider
|
||||
if (scrollbar->orientation == Qt::Horizontal)
|
||||
ret.setRect(sliderstart + sliderlen - dpi.$2, 0,
|
||||
maxlen - sliderstart - sliderlen, sbextent);
|
||||
else
|
||||
ret.setRect(0, sliderstart + sliderlen - dpi.$3,
|
||||
sbextent, maxlen - sliderstart - sliderlen);
|
||||
break;
|
||||
case SC_ScrollBarGroove:
|
||||
if (scrollbar->orientation == Qt::Horizontal)
|
||||
ret.setRect(0, 0, scrollbar->rect.width() - sbextent * 2,
|
||||
scrollbar->rect.height());
|
||||
else
|
||||
ret.setRect(0, 0, scrollbar->rect.width(),
|
||||
scrollbar->rect.height() - sbextent * 2);
|
||||
break;
|
||||
case SC_ScrollBarSlider:
|
||||
if (scrollbar->orientation == Qt::Horizontal)
|
||||
ret.setRect(sliderstart, 0, sliderlen, sbextent);
|
||||
else
|
||||
ret.setRect(0, sliderstart, sbextent, sliderlen);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
ret = visualRect(scrollbar->direction, scrollbar->rect, ret);
|
||||
}
|
||||
break;
|
||||
// case CC_Slider: // A slider, like QSlider
|
||||
case CC_ToolButton: // A tool button, like QToolButton
|
||||
if (const QStyleOptionToolButton *tb =
|
||||
qstyleoption_cast<const QStyleOptionToolButton *>(option)) {
|
||||
int mbi = pixelMetric(PM_MenuButtonIndicator, tb, widget);
|
||||
int fw = pixelMetric(PM_DefaultFrameWidth, tb, widget);
|
||||
QRect ret = tb->rect.adjusted(fw,fw,-fw,0);
|
||||
switch (subControl) {
|
||||
case SC_ToolButton:
|
||||
if ((tb->features
|
||||
& (QStyleOptionToolButton::Menu | QStyleOptionToolButton::PopupDelay))
|
||||
== QStyleOptionToolButton::Menu)
|
||||
ret.adjust(0, 0, -(mbi+fw), 0);
|
||||
break;
|
||||
case SC_ToolButtonMenu:
|
||||
if ((tb->features
|
||||
& (QStyleOptionToolButton::Menu | QStyleOptionToolButton::PopupDelay))
|
||||
== QStyleOptionToolButton::Menu)
|
||||
ret.adjust(ret.width() - mbi, 0, 0, 0);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return visualRect(tb->direction, tb->rect, ret);
|
||||
}
|
||||
break;
|
||||
case CC_TitleBar: // A Title bar, like what is used in Q3Workspace
|
||||
if (const QStyleOptionTitleBar *tb =
|
||||
qstyleoption_cast<const QStyleOptionTitleBar *>(option)) {
|
||||
const int controlMargin = 0;
|
||||
const int controlHeight = tb->rect.height()/* - controlMargin *2*/;
|
||||
const int delta = 8*controlHeight/5;
|
||||
int offset = 0;
|
||||
|
||||
bool isMinimized = tb->titleBarState & Qt::WindowMinimized;
|
||||
bool isMaximized = tb->titleBarState & Qt::WindowMaximized;
|
||||
|
||||
switch (subControl) {
|
||||
case SC_TitleBarLabel:
|
||||
if (tb->titleBarFlags &
|
||||
(Qt::WindowTitleHint | Qt::WindowSystemMenuHint)) {
|
||||
ret = tb->rect;
|
||||
ret.adjust(delta, 0, 0, 0);
|
||||
if (tb->titleBarFlags & Qt::WindowSystemMenuHint)
|
||||
ret.adjust(delta, 0, -delta, 0);
|
||||
if (tb->titleBarFlags & Qt::WindowMinimizeButtonHint)
|
||||
ret.adjust(delta, 0, 0, 0);
|
||||
if (tb->titleBarFlags & Qt::WindowMaximizeButtonHint)
|
||||
ret.adjust(delta, 0, 0, 0);
|
||||
if (tb->titleBarFlags & Qt::WindowShadeButtonHint)
|
||||
ret.adjust(0, 0, -delta, 0);
|
||||
if (tb->titleBarFlags & Qt::WindowContextHelpButtonHint)
|
||||
ret.adjust(0, 0, -delta, 0);
|
||||
}
|
||||
break;
|
||||
case SC_TitleBarMaxButton:
|
||||
if (!isMaximized && (tb->titleBarFlags & Qt::WindowMaximizeButtonHint))
|
||||
offset += delta;
|
||||
else if (subControl == SC_TitleBarMaxButton)
|
||||
break;
|
||||
case SC_TitleBarMinButton:
|
||||
if (!isMinimized && (tb->titleBarFlags & Qt::WindowMinimizeButtonHint))
|
||||
offset += delta;
|
||||
else if (subControl == SC_TitleBarMinButton)
|
||||
break;
|
||||
case SC_TitleBarNormalButton:
|
||||
if (isMinimized && (tb->titleBarFlags & Qt::WindowMinimizeButtonHint))
|
||||
offset += delta;
|
||||
else if (isMaximized && (tb->titleBarFlags & Qt::WindowMaximizeButtonHint))
|
||||
offset += delta;
|
||||
else if (subControl == SC_TitleBarNormalButton)
|
||||
break;
|
||||
case SC_TitleBarCloseButton:
|
||||
if (tb->titleBarFlags & Qt::WindowSystemMenuHint)
|
||||
offset += controlMargin;
|
||||
else if (subControl == SC_TitleBarCloseButton)
|
||||
break;
|
||||
ret.setRect(tb->rect.left() + offset, tb->rect.top() + controlMargin, delta, controlHeight);
|
||||
break;
|
||||
|
||||
case SC_TitleBarContextHelpButton:
|
||||
if (tb->titleBarFlags & Qt::WindowContextHelpButtonHint)
|
||||
offset += delta;
|
||||
case SC_TitleBarShadeButton:
|
||||
if (!isMinimized && (tb->titleBarFlags & Qt::WindowShadeButtonHint))
|
||||
offset += delta;
|
||||
else if (subControl == SC_TitleBarShadeButton)
|
||||
break;
|
||||
case SC_TitleBarUnshadeButton:
|
||||
if (isMinimized && (tb->titleBarFlags & Qt::WindowShadeButtonHint))
|
||||
offset += delta;
|
||||
else if (subControl == SC_TitleBarUnshadeButton)
|
||||
break;
|
||||
case SC_TitleBarSysMenu:
|
||||
if (tb->titleBarFlags & Qt::WindowSystemMenuHint)
|
||||
offset += delta + controlMargin;
|
||||
else if (subControl == SC_TitleBarSysMenu)
|
||||
break;
|
||||
ret.setRect(tb->rect.right() - offset, tb->rect.top() + controlMargin, controlHeight, controlHeight);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
ret = visualRect(tb->direction, tb->rect, ret);
|
||||
}
|
||||
break;
|
||||
case CC_Q3ListView: // Used for drawing the Q3ListView class
|
||||
case CC_Dial: // A dial, like QDial
|
||||
default:
|
||||
ret = QCommonStyle::subControlRect ( control, option, subControl, widget);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
QRect OxygenStyle::subElementRect ( SubElement element, const QStyleOption * option, const QWidget * widget) const
|
||||
{
|
||||
switch (element) {
|
||||
case SE_PushButtonContents: // Area containing the label (icon with text or pixmap)
|
||||
return visualRect(option->direction, option->rect,
|
||||
option->rect.adjusted(dpi.$4,dpi.$4,-dpi.$4,-dpi.$4));
|
||||
// case SE_PushButtonFocusRect: // Area for the focus rect (usually larger than the contents rect)
|
||||
// case SE_CheckBoxIndicator: // Area for the state indicator (e.g., check mark)
|
||||
// case SE_CheckBoxContents: // Area for the label (text or pixmap)
|
||||
// case SE_CheckBoxFocusRect: // Area for the focus indicator
|
||||
// case SE_CheckBoxClickRect: // Clickable area, defaults to SE_CheckBoxFocusRect
|
||||
// case SE_RadioButtonIndicator: // Area for the state indicator
|
||||
// case SE_RadioButtonContents: // Area for the label
|
||||
// case SE_RadioButtonFocusRect: // Area for the focus indicator
|
||||
// case SE_RadioButtonClickRect: // Clickable area, defaults to SE_RadioButtonFocusRect
|
||||
// case SE_ComboBoxFocusRect: // Area for the focus indicator
|
||||
// case SE_SliderFocusRect: // Area for the focus indicator
|
||||
// case SE_Q3DockWindowHandleRect: // Area for the tear-off handle
|
||||
case SE_ProgressBarGroove: // Area for the groove
|
||||
return option->rect;//.adjusted(0,0,0,0);
|
||||
case SE_ProgressBarContents: // Area for the progress indicator
|
||||
case SE_ProgressBarLabel: // Area for the text label
|
||||
return option->rect.adjusted(dpi.$3,dpi.$4,-dpi.$3,-dpi.$5);
|
||||
// case SE_DialogButtonAccept: // Area for a dialog's accept button
|
||||
// case SE_DialogButtonReject: // Area for a dialog's reject button
|
||||
// case SE_DialogButtonApply: // Area for a dialog's apply button
|
||||
// case SE_DialogButtonHelp: // Area for a dialog's help button
|
||||
// case SE_DialogButtonAll: // Area for a dialog's all button
|
||||
// case SE_DialogButtonRetry: // Area for a dialog's retry button
|
||||
// case SE_DialogButtonAbort: // Area for a dialog's abort button
|
||||
// case SE_DialogButtonIgnore: // Area for a dialog's ignore button
|
||||
// case SE_DialogButtonCustom: // Area for a dialog's custom widget area (in the button row)
|
||||
case SE_HeaderArrow: { //
|
||||
int x,y,w,h;
|
||||
option->rect.getRect(&x,&y,&w,&h);
|
||||
int margin = dpi.$2;// ;) pixelMetric(QStyle::PM_HeaderMargin, opt, widget);
|
||||
QRect r;
|
||||
if (option->state & State_Horizontal)
|
||||
r.setRect(x + w - 2*margin - (h / 2), y + h/4 + margin, h / 2, h/2);
|
||||
else
|
||||
r.setRect(x + dpi.$5, y, h / 2, h / 2 - margin * 2);
|
||||
r = visualRect(option->direction, option->rect, r);
|
||||
return r;
|
||||
}
|
||||
// case SE_HeaderLabel: //
|
||||
// case SE_TabWidgetLeftCorner: //
|
||||
// case SE_TabWidgetRightCorner: //
|
||||
case SE_TabWidgetTabBar: //
|
||||
if (const QStyleOptionTabWidgetFrame *twf
|
||||
= qstyleoption_cast<const QStyleOptionTabWidgetFrame *>(option)) {
|
||||
QRect r(QPoint(0,0),twf->tabBarSize);
|
||||
int off = dpi.$10;
|
||||
switch (twf->shape) {
|
||||
case QTabBar::RoundedNorth:
|
||||
case QTabBar::TriangularNorth:
|
||||
// Constrain the size now, otherwise, center could get off the page
|
||||
// This of course repeated for all the other directions
|
||||
r.setWidth(qMin(r.width(), twf->rect.width() - 2*off
|
||||
- twf->leftCornerWidgetSize.width()
|
||||
- twf->rightCornerWidgetSize.width()));
|
||||
switch (styleHint(SH_TabBar_Alignment, twf, widget)) {
|
||||
default:
|
||||
case Qt::AlignLeft:
|
||||
r.moveTopLeft(QPoint(twf->leftCornerWidgetSize.width()+off, 0));
|
||||
break;
|
||||
case Qt::AlignCenter:
|
||||
r.moveTopLeft(QPoint(twf->rect.center().x() - r.width() / 2, 0));
|
||||
break;
|
||||
case Qt::AlignRight:
|
||||
r.moveTopLeft(QPoint(twf->rect.width() - twf->tabBarSize.width() - off
|
||||
- twf->rightCornerWidgetSize.width(), 0));
|
||||
break;
|
||||
}
|
||||
r = visualRect(twf->direction, twf->rect, r);
|
||||
break;
|
||||
case QTabBar::RoundedSouth:
|
||||
case QTabBar::TriangularSouth:
|
||||
r.setWidth(qMin(r.width(), twf->rect.width() - 2*off
|
||||
- twf->leftCornerWidgetSize.width()
|
||||
- twf->rightCornerWidgetSize.width()));
|
||||
switch (styleHint(SH_TabBar_Alignment, twf, widget)) {
|
||||
default:
|
||||
case Qt::AlignLeft:
|
||||
r.moveTopLeft(QPoint(twf->leftCornerWidgetSize.width() + off,
|
||||
twf->rect.height() - twf->tabBarSize.height()));
|
||||
break;
|
||||
case Qt::AlignCenter:
|
||||
r.moveTopLeft(QPoint(twf->rect.center().x() - r.width() / 2,
|
||||
twf->rect.height() - twf->tabBarSize.height()));
|
||||
break;
|
||||
case Qt::AlignRight:
|
||||
r.moveTopLeft(QPoint(twf->rect.width() - twf->tabBarSize.width() - off
|
||||
- twf->rightCornerWidgetSize.width(),
|
||||
twf->rect.height() - twf->tabBarSize.height()));
|
||||
break;
|
||||
}
|
||||
r = visualRect(twf->direction, twf->rect, r);
|
||||
break;
|
||||
case QTabBar::RoundedEast:
|
||||
case QTabBar::TriangularEast:
|
||||
r.setHeight(qMin(r.height(), twf->rect.height() - 2*off
|
||||
- twf->leftCornerWidgetSize.height()
|
||||
- twf->rightCornerWidgetSize.height()));
|
||||
switch (styleHint(SH_TabBar_Alignment, twf, widget)) {
|
||||
default:
|
||||
case Qt::AlignLeft:
|
||||
r.moveTopLeft(QPoint(twf->rect.width() - twf->tabBarSize.width(),
|
||||
twf->leftCornerWidgetSize.height() + off));
|
||||
break;
|
||||
case Qt::AlignCenter:
|
||||
r.moveTopLeft(QPoint(twf->rect.width() - twf->tabBarSize.width(),
|
||||
twf->rect.center().y() - r.height() / 2));
|
||||
break;
|
||||
case Qt::AlignRight:
|
||||
r.moveTopLeft(QPoint(twf->rect.width() - twf->tabBarSize.width(),
|
||||
twf->rect.height() - twf->tabBarSize.height()
|
||||
- twf->rightCornerWidgetSize.height() - off));
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case QTabBar::RoundedWest:
|
||||
case QTabBar::TriangularWest:
|
||||
r.setHeight(qMin(r.height(), twf->rect.height() - 2*off)
|
||||
- twf->leftCornerWidgetSize.height()
|
||||
- twf->rightCornerWidgetSize.height());
|
||||
switch (styleHint(SH_TabBar_Alignment, twf, widget)) {
|
||||
default:
|
||||
case Qt::AlignLeft:
|
||||
r.moveTopLeft(QPoint(0, twf->leftCornerWidgetSize.height() + off));
|
||||
break;
|
||||
case Qt::AlignCenter:
|
||||
r.moveTopLeft(QPoint(0, twf->rect.center().y() - r.height() / 2));
|
||||
break;
|
||||
case Qt::AlignRight:
|
||||
r.moveTopLeft(QPoint(0, twf->rect.height() - twf->tabBarSize.height()
|
||||
- twf->rightCornerWidgetSize.height() - off));
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return r;
|
||||
}
|
||||
case SE_TabWidgetTabContents: //
|
||||
if (const QStyleOptionTabWidgetFrame *twf =
|
||||
qstyleoption_cast<const QStyleOptionTabWidgetFrame *>(option)) {
|
||||
QRect r = option->rect; //subElementRect ( SE_TabWidgetTabPane, option, widget);
|
||||
// QStyleOptionTab tabopt;
|
||||
// tabopt.shape = twf->shape;
|
||||
const int margin = dpi.$4;
|
||||
// int baseHeight = pixelMetric(PM_TabBarBaseHeight, &tabopt, widget);
|
||||
switch (twf->shape) {
|
||||
case QTabBar::RoundedNorth:
|
||||
case QTabBar::TriangularNorth:
|
||||
r.adjust(margin, margin+twf->tabBarSize.height(), -margin, -margin);
|
||||
break;
|
||||
case QTabBar::RoundedSouth:
|
||||
case QTabBar::TriangularSouth:
|
||||
r.adjust(margin, margin, -margin, -margin-twf->tabBarSize.height());
|
||||
break;
|
||||
case QTabBar::RoundedEast:
|
||||
case QTabBar::TriangularEast:
|
||||
r.adjust(margin, margin, -margin-twf->tabBarSize.width(), -margin);
|
||||
break;
|
||||
case QTabBar::RoundedWest:
|
||||
case QTabBar::TriangularWest:
|
||||
r.adjust(margin+twf->tabBarSize.width(), margin, -margin, -margin);
|
||||
}
|
||||
return r;
|
||||
}
|
||||
case SE_TabWidgetTabPane: //
|
||||
return option->rect;//.adjusted(-10,0,10,0);
|
||||
case SE_ToolBoxTabContents: // Area for a toolbox tab's icon and label
|
||||
return QRect(); //kill the rect, we paint the content ourself
|
||||
// case SE_ViewItemCheckIndicator: // Area for a view item's check mark
|
||||
// case SE_TabBarTearIndicator: // Area for the tear indicator on a tab bar with scroll arrows.
|
||||
default:
|
||||
return QCommonStyle::subElementRect ( element, option, widget);
|
||||
}
|
||||
}
|
168
clients/oxygen/sizefromcontents.cpp
Normal file
168
clients/oxygen/sizefromcontents.cpp
Normal file
|
@ -0,0 +1,168 @@
|
|||
/***************************************************************************
|
||||
* Copyright (C) 2006-2007 by Thomas L<EFBFBD>bking thomas.luebking@web.de
|
||||
* Copyright (C) 2007 by Casper Boemann cbr@boemann.dk
|
||||
* *
|
||||
* 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., *
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||||
***************************************************************************/
|
||||
|
||||
#include <QStyleOptionComboBox>
|
||||
#include <QStyleOptionMenuItem>
|
||||
#include "oxygen.h"
|
||||
|
||||
#include <QtDebug>
|
||||
|
||||
using namespace Oxygen;
|
||||
extern Dpi dpi;
|
||||
|
||||
extern Config config;
|
||||
static const int windowsArrowHMargin = 6; // arrow horizontal margin
|
||||
|
||||
QSize OxygenStyle::sizeFromContents ( ContentsType ct, const QStyleOption * option, const QSize & contentsSize, const QWidget * widget ) const
|
||||
{
|
||||
switch ( ct ) {
|
||||
// case CT_CheckBox: // A check box, like QCheckBox
|
||||
case CT_ComboBox: // A combo box, like QComboBox
|
||||
if (const QStyleOptionComboBox *cb =
|
||||
qstyleoption_cast<const QStyleOptionComboBox *>(option)) {
|
||||
int hgt = contentsSize.height() - dpi.$1;
|
||||
if(!cb->editable)
|
||||
hgt += 2*dpi.$3;
|
||||
|
||||
return QSize(contentsSize.width()+dpi.$10+(int)(hgt/1.1), hgt);
|
||||
}
|
||||
// case CT_DialogButtons: //
|
||||
// return QSize((contentsSize.width()+16 < 80) ? 80 : contentsSize.width()+16, contentsSize.height()+10);
|
||||
// case CT_Q3DockWindow: //
|
||||
case CT_HeaderSection: // A header section, like QHeader
|
||||
if (const QStyleOptionHeader *hdr =
|
||||
qstyleoption_cast<const QStyleOptionHeader *>(option)) {
|
||||
QSize sz;
|
||||
int margin = dpi.$2;
|
||||
int iconSize = hdr->icon.isNull() ? 0 :
|
||||
pixelMetric(QStyle::PM_SmallIconSize, hdr, widget);
|
||||
QSize txt = hdr->fontMetrics.size(0, hdr->text);
|
||||
sz.setHeight(qMax(iconSize, txt.height()) + dpi.$4);
|
||||
sz.setWidth((iconSize?margin+iconSize:0) +
|
||||
(hdr->text.isNull()?0:margin+txt.width()) +
|
||||
((hdr->sortIndicator == QStyleOptionHeader::None) ? 0 :
|
||||
margin+8*option->rect.height()/5) + margin);
|
||||
return sz;
|
||||
}
|
||||
case CT_LineEdit: // A line edit, like QLineEdit
|
||||
return contentsSize ;//+ QSize(dpi.$2,dpi.$2);
|
||||
case CT_MenuBarItem: // A menu bar item, like the buttons in a QMenuBar
|
||||
return QSize(qMax(contentsSize.width()+dpi.$18, (contentsSize.height()+dpi.$8)*8/5), contentsSize.height()+dpi.$8);
|
||||
case CT_MenuItem: // A menu item, like QMenuItem
|
||||
if (const QStyleOptionMenuItem *menuItem =
|
||||
qstyleoption_cast<const QStyleOptionMenuItem *>(option)) {
|
||||
|
||||
if (menuItem->menuItemType == QStyleOptionMenuItem::Separator)
|
||||
return QSize(10, menuItem->text.isEmpty() ?
|
||||
dpi.$6 : menuItem->fontMetrics.lineSpacing());
|
||||
|
||||
bool checkable = menuItem->menuHasCheckableItems;
|
||||
int maxpmw = config.showMenuIcons*menuItem->maxIconWidth;
|
||||
int w = contentsSize.width();
|
||||
int h = qMax(contentsSize.height()+dpi.$2,
|
||||
menuItem->fontMetrics.lineSpacing());
|
||||
|
||||
if (config.showMenuIcons && !menuItem->icon.isNull())
|
||||
h = qMax(h,
|
||||
menuItem->icon.pixmap(pixelMetric(PM_SmallIconSize),
|
||||
QIcon::Normal).height() + dpi.$4);
|
||||
if (menuItem->text.contains('\t'))
|
||||
w += dpi.$12;
|
||||
if (maxpmw > 0)
|
||||
w += maxpmw + dpi.$6;
|
||||
if (checkable)
|
||||
w += 2*(h - dpi.$4)/3 + dpi.$7;
|
||||
w += (checkable + (maxpmw > 0))*dpi.$2;
|
||||
w += dpi.$12;
|
||||
if (menuItem->menuItemType == QStyleOptionMenuItem::SubMenu)
|
||||
w += 2 * windowsArrowHMargin;
|
||||
if (menuItem->menuItemType == QStyleOptionMenuItem::DefaultItem) {
|
||||
// adjust the font and add the difference in size.
|
||||
// it would be better if the font could be adjusted in the
|
||||
// getStyleOptions qmenu func!!
|
||||
QFontMetrics fm(menuItem->font);
|
||||
QFont fontBold = menuItem->font;
|
||||
fontBold.setBold(true);
|
||||
QFontMetrics fmBold(fontBold);
|
||||
w += fmBold.width(menuItem->text) - fm.width(menuItem->text);
|
||||
}
|
||||
return QSize(w, h);
|
||||
}
|
||||
break;
|
||||
case CT_PushButton: // A push button, like QPushButton
|
||||
if (const QStyleOptionButton *btn =
|
||||
qstyleoption_cast<const QStyleOptionButton *>(option)) {
|
||||
if (btn->text.isEmpty())
|
||||
// 4 px for shadow & outline + 1px padding -> 5px per side
|
||||
return ( QSize( contentsSize.width() + dpi.$10, contentsSize.height() + dpi.$10 ) );
|
||||
else {
|
||||
QSize sz = contentsSize;
|
||||
if (btn->icon.isNull())
|
||||
return QSize((sz.width()+dpi.$20 < dpi.$80) ? dpi.$80 : contentsSize.width()+dpi.$20,
|
||||
contentsSize.height()+dpi.$8);
|
||||
else
|
||||
return QSize((sz.width()+dpi.$20 < dpi.$80) ? dpi.$80 : contentsSize.width()+dpi.$20,
|
||||
contentsSize.height()+dpi.$10);
|
||||
}
|
||||
}
|
||||
// case CT_RadioButton: // A radio button, like QRadioButton
|
||||
// case CT_SizeGrip: // A size grip, like QSizeGrip
|
||||
|
||||
case CT_Menu: // A menu, like QMenu
|
||||
case CT_Q3Header: // A Qt 3 header section, like Q3Header
|
||||
case CT_MenuBar: // A menu bar, like QMenuBar
|
||||
case CT_ProgressBar: // A progress bar, like QProgressBar
|
||||
case CT_Slider: // A slider, like QSlider
|
||||
case CT_ScrollBar: // A scroll bar, like QScrollBar
|
||||
case CT_SpinBox: // A spin box, like QSpinBox
|
||||
return contentsSize;
|
||||
// case CT_Splitter: // A splitter, like QSplitter
|
||||
case CT_TabBarTab: // A tab on a tab bar, like QTabBar
|
||||
if (const QStyleOptionTab *tab =
|
||||
qstyleoption_cast<const QStyleOptionTab *>(option)) {
|
||||
switch (tab->shape) {
|
||||
case QTabBar::RoundedNorth: case QTabBar::TriangularNorth:
|
||||
case QTabBar::RoundedSouth: case QTabBar::TriangularSouth:
|
||||
return contentsSize + QSize(dpi.$8, 0);
|
||||
case QTabBar::RoundedEast: case QTabBar::TriangularEast:
|
||||
case QTabBar::RoundedWest: case QTabBar::TriangularWest:
|
||||
return contentsSize + QSize(0, dpi.$8);
|
||||
}
|
||||
}
|
||||
return contentsSize + QSize(dpi.$6, dpi.$6);
|
||||
case CT_TabWidget: // A tab widget, like QTabWidget
|
||||
return contentsSize + QSize(dpi.$8,dpi.$10);
|
||||
case CT_ToolButton: { // A tool button, like QToolButton
|
||||
const QStyleOptionToolButton *toolbutton
|
||||
= qstyleoption_cast<const QStyleOptionToolButton *>(option);
|
||||
// get ~goldem mean ratio
|
||||
int extraH = dpi.$8;
|
||||
if (toolbutton &&
|
||||
toolbutton->toolButtonStyle == Qt::ToolButtonTextUnderIcon)
|
||||
extraH = dpi.$10;
|
||||
int w = qMax(contentsSize.width()+dpi.$6, (contentsSize.height()+extraH)*7/5);
|
||||
if (toolbutton && (toolbutton->subControls & SC_ToolButtonMenu))
|
||||
w += pixelMetric(PM_MenuButtonIndicator, option, widget) + dpi.$8;
|
||||
return QSize(w, contentsSize.height()+extraH);
|
||||
}
|
||||
default: ;
|
||||
} // switch
|
||||
return QCommonStyle::sizeFromContents( ct, option, contentsSize, widget );
|
||||
}
|
185
clients/oxygen/stdpix.cpp
Normal file
185
clients/oxygen/stdpix.cpp
Normal file
|
@ -0,0 +1,185 @@
|
|||
/***************************************************************************
|
||||
* Copyright (C) 2006-2007 by Thomas Lübking *
|
||||
* thomas.luebking@web.de *
|
||||
* *
|
||||
* 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., *
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||||
***************************************************************************/
|
||||
|
||||
#include <QStyleOptionTitleBar>
|
||||
#include <QApplication>
|
||||
#include <QPainter>
|
||||
#include <QPen>
|
||||
#include "oxygen.h"
|
||||
|
||||
#define COLOR(_TYPE_) pal.color(QPalette::_TYPE_)
|
||||
|
||||
using namespace Oxygen;
|
||||
|
||||
extern Dpi dpi;
|
||||
extern Config config;
|
||||
|
||||
#include "inlinehelp.cpp"
|
||||
|
||||
QPixmap OxygenStyle::standardPixmap ( StandardPixmap standardPixmap, const QStyleOption * option, const QWidget * widget ) const
|
||||
{
|
||||
|
||||
QRect rect; QPalette pal; QPixmap pm;
|
||||
const QStyleOptionTitleBar *opt = qstyleoption_cast<const QStyleOptionTitleBar *>(option);
|
||||
if (opt) {
|
||||
pal = opt->palette;
|
||||
rect = opt->rect; rect.moveTo(0,0);
|
||||
pm = QPixmap(opt->rect.size());
|
||||
}
|
||||
else {
|
||||
rect = QRect(0,0,16,16);
|
||||
pal = qApp->palette();
|
||||
pm = QPixmap(rect.size());
|
||||
}
|
||||
#if 0
|
||||
QString key = QString::number(standardPixmap) + "@"
|
||||
+ QString::number(pm.width()) + "x" + QString::number(pm.height()) + ":"
|
||||
+ QString::number(midColor(pal.color(QPalette::WindowText), pal.color(QPalette::Window)).rgb());
|
||||
|
||||
if (QPixmapCache::find(key, pm))
|
||||
return pm;
|
||||
#endif
|
||||
pm.fill(Qt::transparent); // make transparent by default
|
||||
QPainter painter(&pm);
|
||||
bool sunken = false, isEnabled = false, hover = false;
|
||||
if (option) {
|
||||
sunken = option->state & State_Sunken;
|
||||
isEnabled = option->state & State_Enabled;
|
||||
hover = isEnabled && (option->state & State_MouseOver);
|
||||
}
|
||||
int sz = 2*qMin(rect.width(), rect.height())/3;
|
||||
QRect rndRect(0,0,sz,sz); bool foundRect = false;
|
||||
switch (standardPixmap) {
|
||||
case SP_DockWidgetCloseButton:
|
||||
case SP_TitleBarCloseButton:
|
||||
foundRect = true;
|
||||
rndRect.moveCenter(rect.center());
|
||||
case SP_TitleBarMinButton:
|
||||
if (!foundRect) {
|
||||
foundRect = true;
|
||||
rndRect.moveBottomLeft(rect.bottomLeft());
|
||||
}
|
||||
case SP_TitleBarNormalButton:
|
||||
case SP_TitleBarMaxButton:
|
||||
if (!foundRect)
|
||||
rndRect.moveTopRight(rect.topRight());
|
||||
painter.setRenderHint ( QPainter::Antialiasing );
|
||||
painter.setPen(Qt::NoPen);
|
||||
painter.setBrush(gradient(COLOR(Window), rect.height(), Qt::Vertical, GradSunken));
|
||||
painter.drawEllipse(rect);
|
||||
painter.setBrush(gradient(btnBgColor(pal, isEnabled, hover), rndRect.height(), Qt::Vertical, config.gradient));
|
||||
painter.setBrushOrigin(rndRect.topLeft());
|
||||
painter.drawEllipse(rndRect);
|
||||
break;
|
||||
case SP_TitleBarMenuButton: { // 0 Menu button on a title bar
|
||||
QFont fnt = painter.font();
|
||||
fnt.setPixelSize ( rect.height() );
|
||||
painter.setFont(fnt);
|
||||
painter.setPen(pal.color(QPalette::WindowText));
|
||||
painter.drawText(rect, Qt::AlignCenter, ";)");
|
||||
break;
|
||||
}
|
||||
case SP_TitleBarShadeButton: // 5 Shade button on title bars
|
||||
painter.drawPoint(rect.center().x(), rect.top());
|
||||
break;
|
||||
case SP_TitleBarUnshadeButton: // 6 Unshade button on title bars
|
||||
painter.drawPoint(rect.center().x(), rect.top());
|
||||
painter.drawPoint(rect.center());
|
||||
break;
|
||||
case SP_TitleBarContextHelpButton: { // 7 The Context help button on title bars
|
||||
QFont fnt = painter.font();
|
||||
fnt.setPixelSize ( rect.height() );
|
||||
painter.setFont(fnt);
|
||||
painter.drawText(rect, Qt::AlignCenter, "?");
|
||||
break;
|
||||
}
|
||||
case SP_MessageBoxInformation: { // 9 The "information" icon
|
||||
QFont fnt = painter.font(); fnt.setPixelSize ( rect.height()-2 ); painter.setFont(fnt);
|
||||
painter.setRenderHint ( QPainter::Antialiasing );
|
||||
painter.drawEllipse(rect);
|
||||
painter.drawText(rect, Qt::AlignHCenter | Qt::AlignBottom, "!");
|
||||
break;
|
||||
}
|
||||
case SP_MessageBoxWarning: { // 10 The "warning" icon
|
||||
QFont fnt = painter.font(); fnt.setPixelSize ( rect.height()-2 ); painter.setFont(fnt);
|
||||
painter.setRenderHint ( QPainter::Antialiasing );
|
||||
int hm = rect.x()+rect.width()/2;
|
||||
const QPoint points[4] = {
|
||||
QPoint(hm, rect.top()),
|
||||
QPoint(rect.left(), rect.bottom()),
|
||||
QPoint(rect.right(), rect.bottom()),
|
||||
QPoint(hm, rect.top())
|
||||
};
|
||||
painter.drawPolyline(points, 4);
|
||||
painter.drawLine(hm, rect.top()+4, hm, rect.bottom() - 6);
|
||||
painter.drawPoint(hm, rect.bottom() - 3);
|
||||
break;
|
||||
}
|
||||
// case SP_MessageBoxCritical: // 11 The "critical" icon
|
||||
// QFont fnt = painter.font(); fnt.setPixelSize ( rect.height() ); painter.setFont(fnt);
|
||||
// const QPoint points[3] =
|
||||
// {
|
||||
// QPoint(rect.width()/3, rect.top()),
|
||||
// QPoint(2*rect.width()/3, rect.top()),
|
||||
// QPoint(rect.right(), rect.height()/2),
|
||||
// QPoint(rect.right(), rect.bottom())
|
||||
// };
|
||||
// painter.drawPolyLine(points);
|
||||
// painter.drawText(rect, Qt::AlignCenter, "-");
|
||||
case SP_MessageBoxQuestion: { // 12 The "question" icon
|
||||
QFont fnt = painter.font(); fnt.setPixelSize ( rect.height() ); painter.setFont(fnt);
|
||||
painter.drawText(rect, Qt::AlignCenter, "?");
|
||||
break;
|
||||
}
|
||||
// case SP_DesktopIcon: // 13
|
||||
// case SP_TrashIcon: // 14
|
||||
// case SP_ComputerIcon: // 15
|
||||
// case SP_DriveFDIcon: // 16
|
||||
// case SP_DriveHDIcon: // 17
|
||||
// case SP_DriveCDIcon: // 18
|
||||
// case SP_DriveDVDIcon: // 19
|
||||
// case SP_DriveNetIcon: // 20
|
||||
// case SP_DirOpenIcon: // 21
|
||||
// case SP_DirClosedIcon: // 22
|
||||
// case SP_DirLinkIcon: // 23
|
||||
// case SP_FileIcon: // 24
|
||||
// case SP_FileLinkIcon: // 25
|
||||
// case SP_FileDialogStart: // 28
|
||||
// case SP_FileDialogEnd: // 29
|
||||
// case SP_FileDialogToParent: // 30
|
||||
// case SP_FileDialogNewFolder: // 31
|
||||
// case SP_FileDialogDetailedView: // 32
|
||||
// case SP_FileDialogInfoView: // 33
|
||||
// case SP_FileDialogContentsView: // 34
|
||||
// case SP_FileDialogListView: // 35
|
||||
// case SP_FileDialogBack: // 36
|
||||
/// case SP_ToolBarHorizontalExtensionButton: // 26 Extension button for horizontal toolbars
|
||||
/// case SP_ToolBarVerticalExtensionButton: // 27 Extension button for vertical toolbars
|
||||
default:
|
||||
return QCommonStyle::standardPixmap ( standardPixmap, option, widget );
|
||||
}
|
||||
painter.end();
|
||||
#if 0
|
||||
QPixmapCache::insert(key, pm);
|
||||
#endif
|
||||
return pm;
|
||||
}
|
||||
|
||||
#undef COLOR
|
152
clients/oxygen/stylehint.cpp
Normal file
152
clients/oxygen/stylehint.cpp
Normal file
|
@ -0,0 +1,152 @@
|
|||
/***************************************************************************
|
||||
* Copyright (C) 2006-2007 by Thomas Lübking *
|
||||
* thomas.luebking@web.de *
|
||||
* *
|
||||
* 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., *
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||||
***************************************************************************/
|
||||
|
||||
#include <QDialogButtonBox>
|
||||
#include <QEvent>
|
||||
#include <QFrame>
|
||||
#include <QStyleOptionComboBox>
|
||||
#include "oxygen.h"
|
||||
|
||||
using namespace Oxygen;
|
||||
|
||||
int OxygenStyle::styleHint ( StyleHint hint, const QStyleOption * option, const QWidget * widget, QStyleHintReturn * returnData ) const {
|
||||
switch (hint) {
|
||||
case SH_EtchDisabledText: // Disabled text is "etched" as it is on Windows.
|
||||
case SH_DitherDisabledText: //
|
||||
return false;
|
||||
// case SH_GUIStyle: // The GUI style to use.
|
||||
case SH_ScrollBar_MiddleClickAbsolutePosition: // A boolean value. If true, middle clicking on a scroll bar causes the slider to jump to that position. If false, middle clicking is ignored.
|
||||
return true;
|
||||
case SH_ScrollBar_LeftClickAbsolutePosition: // A boolean value. If true, left clicking on a scroll bar causes the slider to jump to that position. If false, left clicking will behave as appropriate for each control.
|
||||
return false;
|
||||
case SH_ScrollBar_ScrollWhenPointerLeavesControl: // A boolean value. If true, when clicking a scroll bar SubControl, holding the mouse button down and moving the pointer outside the SubControl, the scroll bar continues to scroll. If false, the scollbar stops scrolling when the pointer leaves the SubControl.
|
||||
return true;
|
||||
case SH_TabBar_Alignment: // The alignment for tabs in a QTabWidget. Possible values are Qt::AlignLeft, Qt::AlignCenter and Qt::AlignRight.
|
||||
return Qt::AlignLeft;
|
||||
case SH_Header_ArrowAlignment: // The placement of the sorting indicator may appear in list or table headers. Possible values are Qt::Left or Qt::Right.
|
||||
return Qt::AlignRight;
|
||||
case SH_Slider_SnapToValue: // Sliders snap to values while moving, as they do on Windows.
|
||||
return true;
|
||||
case SH_Slider_SloppyKeyEvents: // Key presses handled in a sloppy manner, i.e., left on a vertical slider subtracts a line.
|
||||
return true;
|
||||
case SH_ProgressDialog_CenterCancelButton: // Center button on progress dialogs, like Motif, otherwise right aligned.
|
||||
return false;
|
||||
case SH_ProgressDialog_TextLabelAlignment: // Type Qt::Alignment. Text label alignment in progress dialogs; Qt::Center on windows, Qt::VCenter otherwise.
|
||||
return Qt::AlignCenter;
|
||||
case SH_PrintDialog_RightAlignButtons: // Right align buttons in the print dialog, as done on Windows.
|
||||
return true;
|
||||
case SH_MainWindow_SpaceBelowMenuBar: // One or two pixel space between the menubar and the dockarea, as done on Windows.
|
||||
return 0;
|
||||
// case SH_FontDialog_SelectAssociatedText: // Select the text in the line edit, or when selecting an item from the listbox, or when the line edit receives focus, as done on Windows.
|
||||
// case SH_Menu_AllowActiveAndDisabled: // Allows disabled menu items to be active.
|
||||
case SH_Menu_SpaceActivatesItem: // Pressing the space bar activates the item, as done on Motif.
|
||||
return true;
|
||||
// case SH_Menu_SubMenuPopupDelay: // The number of milliseconds to wait before opening a submenu (256 on windows, 96 on Motif).
|
||||
case SH_Menu_Scrollable: // Whether popup menus must support scrolling.
|
||||
return true;
|
||||
case SH_Menu_SloppySubMenus: // Whether popupmenu's must support sloppy submenu; as implemented on Mac OS.
|
||||
return true;
|
||||
case SH_ScrollView_FrameOnlyAroundContents: // Whether scrollviews draw their frame only around contents (like Motif), or around contents, scroll bars and corner widgets (like Windows).
|
||||
return (!(widget && widget->inherits("QComboBoxListView")));
|
||||
// return true; // find solution for round corner end
|
||||
case SH_MenuBar_AltKeyNavigation: // Menu bars items are navigable by pressing Alt, followed by using the arrow keys to select the desired item.
|
||||
return true;
|
||||
case SH_ComboBox_ListMouseTracking: // Mouse tracking in combobox drop-down lists.
|
||||
case SH_Menu_MouseTracking: // Mouse tracking in popup menus.
|
||||
case SH_MenuBar_MouseTracking: // Mouse tracking in menubars.
|
||||
return true;
|
||||
case SH_Menu_FillScreenWithScroll: // Whether scrolling popups should fill the screen as they are scrolled.
|
||||
return false;
|
||||
case SH_ItemView_ChangeHighlightOnFocus: // Gray out selected items when losing focus.
|
||||
return true;
|
||||
// case SH_Widget_ShareActivation: // Turn on sharing activation with floating modeless dialogs.
|
||||
case SH_TabBar_SelectMouseType: // Which type of mouse event should cause a tab to be selected.
|
||||
return QEvent::MouseButtonRelease;
|
||||
// case SH_Q3ListViewExpand_SelectMouseType: // Which type of mouse event should cause a list view expansion to be selected.
|
||||
case SH_TabBar_PreferNoArrows: // Whether a tabbar should suggest a size to prevent scoll arrows.
|
||||
return false;
|
||||
case SH_ComboBox_Popup: // Allows popups as a combobox drop-down menu.
|
||||
return false;
|
||||
case SH_ComboBox_PopupFrameStyle:
|
||||
return QFrame::NoFrame; //QFrame::StyledPanel | QFrame::Plain;
|
||||
// case SH_Workspace_FillSpaceOnMaximize: // The workspace should maximize the client area.
|
||||
// case SH_TitleBar_NoBorder: // The title bar has no border.
|
||||
case SH_ScrollBar_StopMouseOverSlider: // Stops auto-repeat when the slider reaches the mouse position.
|
||||
return false;
|
||||
case SH_BlinkCursorWhenTextSelected: // Whether cursor should blink when text is selected.
|
||||
return false;
|
||||
// case SH_RichText_FullWidthSelection: // Whether richtext selections should extend to the full width of the document.
|
||||
case SH_GroupBox_TextLabelVerticalAlignment: // How to vertically align a groupbox's text label.
|
||||
return Qt::AlignTop;
|
||||
// case SH_GroupBox_TextLabelColor: // How to paint a groupbox's text label.
|
||||
// case SH_DialogButtons_DefaultButton: // Which button gets the default status in a dialog's button widget.
|
||||
case SH_DialogButtonLayout:
|
||||
return QDialogButtonBox::KdeLayout; //TODO: this should check what session type we are in
|
||||
case SH_ToolBox_SelectedPageTitleBold: // Boldness of the selected page title in a QToolBox.
|
||||
return true;
|
||||
case SH_LineEdit_PasswordCharacter: // The Unicode character to be used for passwords.
|
||||
return 42;
|
||||
// case SH_Table_GridLineColor: //
|
||||
case SH_UnderlineShortcut: // Whether shortcuts are underlined.
|
||||
return true;
|
||||
case SH_SpinBox_AnimateButton: // Animate a click when up or down is pressed in a spin box.
|
||||
return true;
|
||||
/// case SH_SpinBox_KeyPressAutoRepeatRate: // Auto-repeat interval for spinbox key presses.
|
||||
/// case SH_SpinBox_ClickAutoRepeatRate: // Auto-repeat interval for spinbox mouse clicks.
|
||||
case SH_ToolTipLabel_Opacity: // An integer indicating the opacity for the tip label, 0 is completely transparent, 255 is completely opaque.
|
||||
return 160;
|
||||
case SH_DrawMenuBarSeparator: // Indicates whether or not the menubar draws separators.
|
||||
return false;
|
||||
case SH_TitleBar_ModifyNotification: // Indicates if the titlebar should show a '*' for windows that are modified.
|
||||
return true;
|
||||
//TODO: häää???
|
||||
/// case SH_Button_FocusPolicy: // The default focus policy for buttons.
|
||||
case SH_MenuBar_DismissOnSecondClick: // A boolean indicating if a menu in the menubar should be dismissed when it is clicked on a second time. (Example: Clicking and releasing on the File Menu in a menubar and then immediately clicking on the File Menu again.)
|
||||
return true;
|
||||
//TODO: häää???
|
||||
/// case SH_MessageBox_UseBorderForButtonSpacing: // A boolean indicating what the to use the border of the buttons (computed as half the button height) for the spacing of the button in a message box.
|
||||
case SH_TitleBar_AutoRaise: // A boolean indicating whether controls on a title bar ought to update when the mouse is over them.
|
||||
return true;
|
||||
case SH_ToolButton_PopupDelay: // An int indicating the popup delay in milliseconds for menus attached to tool buttons.
|
||||
return 300;
|
||||
/// case SH_FocusFrame_Mask: // The mask of the focus frame.
|
||||
/// case SH_RubberBand_Mask: // The mask of the rubber band.
|
||||
/// case SH_WindowFrame_Mask: // The mask of the window frame.
|
||||
case SH_SpinControls_DisableOnBounds: // Determines if the spin controls will shown as disabled when reaching the spin range boundary.
|
||||
return true;
|
||||
/// case SH_Dial_BackgroundRole: // Defines the style's preferred background role (as QPalette::ColorRole) for a dial widget.
|
||||
|
||||
#warning commenting those two line to make it compile. check.
|
||||
// case SH_ScrollBar_BackgroundMode: // The backgroundMode() for a scroll bar.
|
||||
// return ((widget && widget->inherits("QComboBoxListView"))) ?
|
||||
// Qt::PaletteBase :
|
||||
// Qt::PaletteBackground;
|
||||
|
||||
/// case SH_ComboBox_LayoutDirection: // The layout direction for the combo box. By default it should be the same value as the QStyleOption's direction.
|
||||
/// case SH_ItemView_EllipsisLocation: // The location where ellipses should be added for item text that is too long to fit in an view item.
|
||||
/// case SH_ItemView_ShowDecorationSelected: // When an item in an item view is selected, also highlight the branch or other decoration.
|
||||
case SH_ItemView_ActivateItemOnSingleClick: // Emit the activated signal when the user single clicks on an item in an item in an item view. Otherwise the signal is emitted when the user double clicks on an item.
|
||||
return true;
|
||||
case SH_WizardStyle:
|
||||
return 2;//QWizard::MacStyle;
|
||||
default:
|
||||
return QCommonStyle::styleHint(hint, option, widget, returnData);
|
||||
} // switch
|
||||
}
|
81
clients/oxygen/t_render1.cpp
Normal file
81
clients/oxygen/t_render1.cpp
Normal file
|
@ -0,0 +1,81 @@
|
|||
|
||||
int rOff = 0, xOff, yOff, w, h;
|
||||
|
||||
r.getRect(&xOff, &yOff, &w, &h);
|
||||
int tlh = height(TopLeft), blh = height(BtmLeft),
|
||||
trh = height(TopRight), brh = height(BtmLeft),
|
||||
tlw = width(TopLeft), blw = width(BtmLeft),
|
||||
trw = width(TopRight), brw = width(BtmRight);
|
||||
|
||||
if (pf & Left)
|
||||
{
|
||||
w -= width(TopLeft);
|
||||
xOff += width(TopLeft);
|
||||
if (pf & (Top | Bottom) && tlh + blh > r.height()) // vertical edge overlap
|
||||
{
|
||||
tlh = (tlh*r.height())/(tlh+blh);
|
||||
blh = r.height() - tlh;
|
||||
}
|
||||
}
|
||||
if (pf & Right)
|
||||
{
|
||||
w -= width(TopRight);
|
||||
if (matches(Top | Bottom, pf) && trh + brh > r.height()) // vertical edge overlap
|
||||
{
|
||||
trh = (trh*r.height())/(trh+brh);
|
||||
brh = r.height() - trh;
|
||||
}
|
||||
}
|
||||
|
||||
if (pf & Top)
|
||||
{
|
||||
if (matches(Left | Right, pf) && w < 0) // horizontal edge overlap
|
||||
{
|
||||
tlw = tlw*r.width()/(tlw+trw);
|
||||
trw = r.width() - tlw;
|
||||
}
|
||||
rOff = r.right()-trw+1;
|
||||
yOff += tlh;
|
||||
h -= tlh;
|
||||
if (pf & Left) // upper left
|
||||
DRAW_PIXMAP(r.x(),r.y(),PIXMAP(TopLeft), 0, 0, tlw, tlh);
|
||||
if (pf & Right) // upper right
|
||||
DRAW_PIXMAP(rOff, r.y(), PIXMAP(TopRight), width(TopRight)-trw, 0,
|
||||
trw, trh);
|
||||
|
||||
// upper line
|
||||
if (w > 0 && !pixmap[TopMid].isNull())
|
||||
DRAW_TILED_PIXMAP(xOff, r.y(), w, tlh/*height(TopMid)*/, PIXMAP(TopMid));
|
||||
}
|
||||
if (pf & Bottom)
|
||||
{
|
||||
if (matches(Left | Right, pf) && w < 0) // horizontal edge overlap
|
||||
{
|
||||
blw = (blw*r.width())/(blw+brw);
|
||||
brw = r.width() - blw;
|
||||
}
|
||||
rOff = r.right()-brw+1;
|
||||
int bOff = r.bottom()-blh+1;
|
||||
h -= blh;
|
||||
if (pf & Left) // lower left
|
||||
DRAW_PIXMAP(r.x(), bOff, PIXMAP(BtmLeft), 0, height(BtmLeft)-blh,
|
||||
blw, blh);
|
||||
if (pf & Right) // lower right
|
||||
DRAW_PIXMAP(rOff, bOff, PIXMAP(BtmRight), width(BtmRight)-brw,
|
||||
height(BtmRight)-brh, brw, brh);
|
||||
|
||||
// lower line
|
||||
if (w > 0 && !pixmap[BtmMid].isNull())
|
||||
DRAW_TILED_PIXMAP(xOff, bOff, w, height(BtmMid), PIXMAP(BtmMid));
|
||||
}
|
||||
|
||||
if (h > 0)
|
||||
{
|
||||
if ((pf & Center) && (w > 0)) // center part
|
||||
DRAW_TILED_PIXMAP(xOff, yOff, w, h, pixmap[MidMid]);
|
||||
if (pf & Left && !pixmap[MidLeft].isNull()) // left line
|
||||
DRAW_TILED_PIXMAP(r.x(), yOff, width(MidLeft), h, PIXMAP(MidLeft));
|
||||
rOff = r.right()-width(MidRight)+1;
|
||||
if (pf & Right && !pixmap[MidRight].isNull()) // right line
|
||||
DRAW_TILED_PIXMAP(rOff, yOff, width(MidRight), h, PIXMAP(MidRight));
|
||||
}
|
650
clients/oxygen/tileset.cpp
Normal file
650
clients/oxygen/tileset.cpp
Normal file
|
@ -0,0 +1,650 @@
|
|||
/***************************************************************************
|
||||
* Copyright (C) 2006-2007 by Thomas Lübking *
|
||||
* thomas.luebking@web.de *
|
||||
* *
|
||||
* 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., *
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||||
***************************************************************************/
|
||||
|
||||
#include <QPainter>
|
||||
#include <cmath>
|
||||
#include "oxrender.h"
|
||||
#include "tileset.h"
|
||||
|
||||
#ifndef MIN
|
||||
#define MIN(x,y) ((x) < (y) ? (x) : (y))
|
||||
#endif
|
||||
|
||||
#ifndef MAX
|
||||
#define MAX(x,y) ((x) > (y) ? (x) : (y))
|
||||
#endif
|
||||
|
||||
using namespace Tile;
|
||||
|
||||
static QPixmap nullPix;
|
||||
|
||||
static bool isEmpty(const QPixmap &pix)
|
||||
{
|
||||
if (!pix.hasAlpha()) return false;
|
||||
QImage img = pix.toImage();
|
||||
uint *data = ( uint * ) img.bits();
|
||||
int total = img.width() * img.height();
|
||||
for ( int current = 0 ; current < total ; ++current )
|
||||
if (qAlpha(data[ current ]))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
static QPixmap invertAlpha(const QPixmap & pix)
|
||||
{
|
||||
if (pix.isNull()) return pix;
|
||||
QImage img = pix.toImage();
|
||||
QImage *dst = new QImage(img);
|
||||
uint *data = ( uint * ) img.bits();
|
||||
uint *ddata = ( uint * ) dst->bits();
|
||||
int total = img.width() * img.height();
|
||||
for ( int c = 0 ; c < total ; ++c )
|
||||
ddata[c] = qRgba( qRed(data[c]), qGreen(data[c]), qBlue(data[c]), 255-qAlpha(data[c]) );
|
||||
QPixmap ret = QPixmap::fromImage(*dst, 0);
|
||||
delete dst;
|
||||
return ret;
|
||||
}
|
||||
|
||||
Set::Set(const QPixmap &pix, int xOff, int yOff, int width, int height, int rx, int ry)
|
||||
{
|
||||
if (pix.isNull())
|
||||
{
|
||||
_isBitmap = false;
|
||||
return;
|
||||
}
|
||||
_isBitmap = pix.isQBitmap();
|
||||
rxf = pix.width()*rx;
|
||||
ryf = pix.height()*ry;
|
||||
|
||||
int rOff = pix.width() - xOff - width;
|
||||
int bOff = pix.height() - yOff - height;
|
||||
int amount = 32/width+1;
|
||||
int amount2 = 32/height+1;
|
||||
int i;
|
||||
|
||||
QPainter p;
|
||||
|
||||
#define initPixmap(_SECTION_,_WIDTH_,_HEIGHT_)\
|
||||
pixmap[_SECTION_] = QPixmap(_WIDTH_, _HEIGHT_);\
|
||||
pixmap[_SECTION_].fill(Qt::transparent); p.begin(&pixmap[_SECTION_])
|
||||
|
||||
#define finishPixmap(_SECTION_)\
|
||||
p.end();\
|
||||
if (isEmpty(pixmap[_SECTION_]))\
|
||||
pixmap[_SECTION_] = QPixmap()
|
||||
|
||||
initPixmap(TopLeft, xOff, yOff);
|
||||
p.drawPixmap(0, 0, pix, 0, 0, xOff, yOff);
|
||||
finishPixmap(TopLeft);
|
||||
|
||||
initPixmap(TopMid, amount*width, yOff);
|
||||
for (i = 0; i < amount; i++)
|
||||
p.drawPixmap(i*width, 0, pix, xOff, 0, width, yOff);
|
||||
finishPixmap(TopMid);
|
||||
|
||||
initPixmap(TopRight, rOff, yOff);
|
||||
p.drawPixmap(0, 0, pix, xOff+width, 0, rOff, yOff);
|
||||
finishPixmap(TopRight);
|
||||
|
||||
//----------------------------------
|
||||
initPixmap(MidLeft, xOff, amount2*height);
|
||||
for (i = 0; i < amount2; i++)
|
||||
p.drawPixmap(0, i*height, pix, 0, yOff, xOff, height);
|
||||
finishPixmap(MidLeft);
|
||||
|
||||
initPixmap(MidMid, amount*width, amount2*height);
|
||||
for (i = 0; i < amount; i++)
|
||||
for (int j = 0; j < amount2; j++)
|
||||
p.drawPixmap(i*width, j*height, pix, xOff, yOff, width, height);
|
||||
finishPixmap(MidMid);
|
||||
|
||||
initPixmap(MidRight, rOff, amount2*height);
|
||||
for (i = 0; i < amount2; i++)
|
||||
p.drawPixmap(0, i*height, pix, xOff+width, yOff, rOff, height);
|
||||
finishPixmap(MidRight);
|
||||
|
||||
//----------------------------------
|
||||
|
||||
initPixmap(BtmLeft, xOff, bOff);
|
||||
p.drawPixmap(0, 0, pix, 0, yOff+height, xOff, bOff);
|
||||
finishPixmap(BtmLeft);
|
||||
|
||||
initPixmap(BtmMid, amount*width, bOff);
|
||||
for (i = 0; i < amount; i++)
|
||||
p.drawPixmap(i*width, 0, pix, xOff, yOff+height, width, bOff);
|
||||
finishPixmap(BtmMid);
|
||||
|
||||
initPixmap(BtmRight, rOff, bOff);
|
||||
p.drawPixmap(0, 0, pix, xOff+width, yOff+height, rOff, bOff);
|
||||
finishPixmap(BtmRight);
|
||||
|
||||
#undef initPixmap
|
||||
#undef finishPixmap
|
||||
}
|
||||
|
||||
QRect Set::rect(const QRect &rect, PosFlags pf) const
|
||||
{
|
||||
QRect ret = rect;
|
||||
if (pf == Center)
|
||||
ret.adjust(width(MidLeft),height(TopMid),-width(TopMid),-height(BtmMid));
|
||||
else if (pf == Left)
|
||||
ret.setRight(ret.left()+width(MidLeft));
|
||||
else if (pf == Top)
|
||||
ret.setBottom(ret.top()+height(TopMid));
|
||||
else if (pf == Right)
|
||||
ret.setLeft(ret.right()-width(MidRight));
|
||||
else if (pf == Bottom)
|
||||
ret.setTop(ret.bottom()-height(BtmMid));
|
||||
return ret;
|
||||
}
|
||||
|
||||
void Set::render(const QRect &r, QPainter *p, PosFlags pf) const
|
||||
{
|
||||
#define PIXMAP(_TILE_) pixmap[_TILE_]
|
||||
#define DRAW_PIXMAP p->drawPixmap
|
||||
#define DRAW_TILED_PIXMAP p->drawTiledPixmap
|
||||
|
||||
#include "t_render1.cpp"
|
||||
#undef PIXMAP
|
||||
#undef DRAW_PIXMAP
|
||||
#undef DRAW_TILED_PIXMAP
|
||||
}
|
||||
|
||||
static Window root = RootWindow (QX11Info::display(), DefaultScreen (QX11Info::display()));
|
||||
|
||||
Picture Set::render(const QSize &s, PosFlags pf) const
|
||||
{
|
||||
return render(s.width(), s.height(), pf);
|
||||
}
|
||||
|
||||
Picture Set::render(int W, int H, PosFlags pf) const
|
||||
{
|
||||
Display *dpy = QX11Info::display();
|
||||
QRect r(0,0,W,H);
|
||||
Pixmap xpix = XCreatePixmap (dpy, root, W, H, 32);
|
||||
if (!pixmap)
|
||||
return X::None;
|
||||
Picture pict =
|
||||
XRenderCreatePicture (dpy, xpix,
|
||||
XRenderFindStandardFormat(dpy, PictStandardARGB32),
|
||||
0, 0);
|
||||
if (!pict) {
|
||||
XFreePixmap (dpy, xpix); return X::None;
|
||||
}
|
||||
|
||||
#define PIXMAP(_TILE_) pixmap[_TILE_]
|
||||
#define DRAW_PIXMAP(_DX_, _DY_, _PIX_, _SX_, _SY_, _W_, _H_) \
|
||||
XRenderComposite(dpy, PictOpSrc, _PIX_.x11PictureHandle(), X::None, pict,\
|
||||
_SX_, _SY_, 0, 0, _DX_, _DY_, _W_, _H_);
|
||||
// XCopyArea( dpy, _PIX_.handle(), pix->handle(), gc, _SX_, _SY_, _W_, _H_, _DX_, _DY_ )
|
||||
#define DRAW_TILED_PIXMAP(_DX_, _DY_, _W_, _H_, _PIX_)\
|
||||
for (int x = 0; x < _W_; x += _PIX_.width())\
|
||||
for (int y = 0; y < _H_; y += _PIX_.height())\
|
||||
XRenderComposite(dpy, PictOpSrc, _PIX_.x11PictureHandle(), X::None,\
|
||||
pict, 0, 0, 0, 0, x+_DX_, y+_DY_,\
|
||||
MIN(_PIX_.width(), _W_-x),\
|
||||
MIN(_PIX_.height(), _H_-y));
|
||||
|
||||
#include "t_render1.cpp"
|
||||
XFreePixmap (dpy, xpix);
|
||||
return pict;
|
||||
#undef PIXMAP
|
||||
#undef DRAW_PIXMAP
|
||||
#undef DRAW_TILED_PIXMAP
|
||||
}
|
||||
|
||||
void Set::outline(const QRect &r, QPainter *p, QColor c, bool strong, PosFlags pf) const
|
||||
{
|
||||
p->save();
|
||||
p->setRenderHint(QPainter::Antialiasing, false);
|
||||
QPen pen = p->pen();
|
||||
pen.setColor(c); pen.setWidth(1);
|
||||
p->setPen(pen);
|
||||
p->setBrush(Qt::NoBrush);
|
||||
QRect rect = r/*.adjusted(0,0,0,-1)*/;
|
||||
if (! (pf & Top))
|
||||
rect.setTop(rect.top()-100);
|
||||
else if (strong)
|
||||
p->drawLine(r.left()+width(TopLeft), r.top(), r.right()-width(TopRight), r.top());
|
||||
if (! (pf & Left))
|
||||
rect.setLeft(rect.left()-100);
|
||||
else if (strong)
|
||||
p->drawLine(r.left(), r.top()+height(TopRight), r.left(), r.bottom()-height(BtmRight));
|
||||
if (! (pf & Bottom))
|
||||
rect.setBottom(rect.bottom()+100);
|
||||
else if (strong)
|
||||
p->drawLine(r.left()+width(BtmLeft), r.bottom(), r.right()-width(BtmRight), r.bottom());
|
||||
if (! (pf & Right))
|
||||
rect.setRight(rect.right()+100);
|
||||
else if (strong)
|
||||
p->drawLine(r.right(), r.top()+height(TopRight), r.right(), r.bottom()-height(BtmRight));
|
||||
p->setClipRect(r);
|
||||
p->setRenderHint(QPainter::Antialiasing);
|
||||
p->drawRoundRect(rect, ceil((float)rxf/rect.width()), ceil((float)ryf/rect.height()));
|
||||
p->restore();
|
||||
}
|
||||
|
||||
Tile::Mask::Mask(const QPixmap &pix, int xOff, int yOff, int width, int height,
|
||||
int dx1, int dy1, int dx2, int dy2, int rx, int ry):
|
||||
Set(pix, xOff, yOff, width, height, rx, ry) {
|
||||
_dx[0] = dx1; _dx[1] = dx2; _dy[0] = dy1; _dy[1] = dy2;
|
||||
|
||||
pixmap[MidMid] = QPixmap();
|
||||
if (dx1 < 1) pixmap[MidLeft] = QPixmap();
|
||||
if (dx2 > -1) pixmap[MidRight] = QPixmap();
|
||||
if (dy1 < 1) pixmap[TopMid] = QPixmap();
|
||||
if (dy2 > -1) pixmap[BtmMid] = QPixmap();
|
||||
|
||||
for (int i = 0; i < 9; ++i)
|
||||
if (i != MidMid)
|
||||
inversePixmap[i] = invertAlpha(pixmap[i]);
|
||||
|
||||
_hasCorners = !pix.isNull();
|
||||
}
|
||||
|
||||
QRect Tile::Mask::bounds(const QRect &rect, PosFlags pf) const
|
||||
{
|
||||
QRect ret = rect;
|
||||
if (pf & Left)
|
||||
ret.setLeft(ret.left()+_dx[0]);
|
||||
if (pf & Top)
|
||||
ret.setTop(ret.top()+_dy[0]);
|
||||
if (pf & Right)
|
||||
ret.setRight(ret.right()+_dx[1]);
|
||||
if (pf & Bottom)
|
||||
ret.setBottom(ret.bottom()+_dy[1]);
|
||||
return ret;
|
||||
}
|
||||
|
||||
const QPixmap &Tile::Mask::corner(PosFlags pf, bool inverse) const
|
||||
{
|
||||
const QPixmap (*pics)[9] = inverse ? &inversePixmap : &pixmap;
|
||||
if (pf == (Top | Left))
|
||||
return (*pics)[TopLeft];
|
||||
if (pf == (Top | Right))
|
||||
return (*pics)[TopRight];
|
||||
if (pf == (Bottom | Right))
|
||||
return (*pics)[BtmRight];
|
||||
if (pf == (Bottom | Left))
|
||||
return (*pics)[BtmLeft];
|
||||
|
||||
qWarning("requested impossible corner %d",pf);
|
||||
return nullPix;
|
||||
}
|
||||
|
||||
QRegion Tile::Mask::clipRegion(const QRect &rect, PosFlags pf) const
|
||||
{
|
||||
QRegion ret(rect.adjusted(_dx[0], _dy[0], _dx[1], _dy[1]));
|
||||
int w,h;
|
||||
if (matches(Top | Left, pf)) {
|
||||
ret -= QRect(rect.x(), rect.y(), width(TopLeft), height(TopLeft));
|
||||
}
|
||||
if (matches(Top | Right, pf)) {
|
||||
w = width(TopRight);
|
||||
ret -= QRect(rect.right()-w+1, rect.y(), w, height(TopRight));
|
||||
}
|
||||
if (matches(Bottom | Left, pf)) {
|
||||
h = height(BtmLeft);
|
||||
ret -= QRect(rect.x(), rect.bottom()-h+1, width(BtmLeft), h);
|
||||
}
|
||||
if (matches(Bottom | Right, pf)) {
|
||||
w = width(BtmRight); h = height(BtmRight);
|
||||
ret -= QRect(rect.right()-w+1, rect.bottom()-h+1, w, h);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void Tile::Mask::render(const QRect &r, QPainter *p, const QBrush &fill,
|
||||
PosFlags oPf, bool justClip, QPoint offset, bool inverse,
|
||||
const QRect *outerRect) const
|
||||
{
|
||||
bool pixmode = !fill.texture().isNull();
|
||||
|
||||
if (justClip) {
|
||||
p->save();
|
||||
p->setClipRegion(clipRegion(r, oPf));
|
||||
if (pixmode)
|
||||
p->drawTiledPixmap(r, fill.texture(), offset);
|
||||
else
|
||||
p->fillRect(r, fill.color());
|
||||
p->restore();
|
||||
return;
|
||||
}
|
||||
// first the inner region
|
||||
//NOTE: using full alphablend can become enourmously slow due to VRAM size -
|
||||
// even on HW that has Render acceleration!
|
||||
if (!inverse || outerRect) {
|
||||
p->save();
|
||||
if (inverse) {
|
||||
QRegion cr = *outerRect; cr -= r;
|
||||
p->setClipRegion(cr, Qt::IntersectClip);
|
||||
}
|
||||
else
|
||||
p->setClipRegion(clipRegion(r, oPf), Qt::IntersectClip);
|
||||
if (pixmode)
|
||||
p->drawTiledPixmap(outerRect ? *outerRect : r, fill.texture(), offset);
|
||||
else
|
||||
p->fillRect(outerRect ? *outerRect : r, fill.color());
|
||||
p->restore();
|
||||
}
|
||||
if (!_hasCorners)
|
||||
return;
|
||||
|
||||
QPixmap filledPix;
|
||||
QPainter pixPainter;
|
||||
PosFlags pf = oPf & ~Center;
|
||||
const QPixmap (*pics)[9] = inverse ? &inversePixmap : &pixmap;
|
||||
QPoint off = r.topLeft()-offset;
|
||||
|
||||
#define PIXMAP(_TILE_) (*pics)[_TILE_]
|
||||
|
||||
#define MAKE_FILL(_PIX_, _OFF_)\
|
||||
filledPix = QPixmap(_PIX_.size());\
|
||||
if (pixmode) {\
|
||||
filledPix.fill(Qt::transparent);\
|
||||
pixPainter.begin(&filledPix);\
|
||||
pixPainter.drawTiledPixmap(filledPix.rect(), fill.texture(), _OFF_-off);\
|
||||
pixPainter.end();\
|
||||
}\
|
||||
else\
|
||||
filledPix.fill(fill.color());\
|
||||
filledPix = OXRender::applyAlpha(filledPix, _PIX_)
|
||||
|
||||
#define DRAW_PIXMAP(_DX_, _DY_, _PIX_, _SX_, _SY_, _W_, _H_) {\
|
||||
MAKE_FILL(_PIX_, QPoint(_DX_, _DY_));\
|
||||
p->drawPixmap(_DX_, _DY_, filledPix, _SX_, _SY_, _W_, _H_);\
|
||||
}// --skip semicolon
|
||||
|
||||
#define DRAW_TILED_PIXMAP(_DX_, _DY_, _W_, _H_, _PIX_) {\
|
||||
MAKE_FILL(_PIX_, QPoint(_DX_, _DY_));\
|
||||
p->drawTiledPixmap(_DX_, _DY_, _W_, _H_, filledPix);\
|
||||
}// --skip semicolon
|
||||
|
||||
#include "t_render1.cpp"
|
||||
#undef PIXMAP
|
||||
#undef MAKE_FILL
|
||||
#undef DRAW_PIXMAP
|
||||
#undef DRAW_TILED_PIXMAP
|
||||
|
||||
}
|
||||
|
||||
Line::Line(const QPixmap &pix, Qt::Orientation o, int d1, int d2) {
|
||||
_o = o;
|
||||
QPainter p;
|
||||
if (o == Qt::Horizontal) {
|
||||
_thickness = pix.height();
|
||||
pixmap[0] = QPixmap(d1,pix.height());
|
||||
pixmap[0].fill(Qt::transparent);
|
||||
p.begin(&pixmap[0]);
|
||||
p.drawPixmap(0,0,pix,0,0,d1,pix.height());
|
||||
p.end();
|
||||
|
||||
int d = pix.width()-d1+d2;
|
||||
pixmap[1] = QPixmap(MAX(32,d),pix.height());
|
||||
pixmap[1].fill(Qt::transparent);
|
||||
p.begin(&pixmap[1]);
|
||||
for (int i = 0; i+d <= width(1); i+=d)
|
||||
p.drawPixmap(i,0,pix,d1,0,MIN(d,width(1)-i),pix.height());
|
||||
p.end();
|
||||
|
||||
pixmap[2] = QPixmap(-d2,pix.height());
|
||||
pixmap[2].fill(Qt::transparent);
|
||||
p.begin(&pixmap[2]);
|
||||
p.drawPixmap(0,0,pix,pix.width()+d2,0,-d2,pix.height());
|
||||
p.end();
|
||||
}
|
||||
else {
|
||||
_thickness = pix.width();
|
||||
pixmap[0] = QPixmap(pix.width(),d1);
|
||||
pixmap[0].fill(Qt::transparent);
|
||||
p.begin(&pixmap[0]);
|
||||
p.drawPixmap(0,0,pix,0,0,pix.width(),d1);
|
||||
p.end();
|
||||
|
||||
int d = pix.height()-d1+d2;
|
||||
pixmap[1] = QPixmap(pix.width(), MAX(32,d));
|
||||
pixmap[1].fill(Qt::transparent);
|
||||
p.begin(&pixmap[1]);
|
||||
for (int i = 0; i+d < height(1); i+=d)
|
||||
p.drawPixmap(0,i,pix,0,d1,pix.width(),MIN(d,height(1)-i));
|
||||
p.end();
|
||||
|
||||
pixmap[2] = QPixmap(pix.width(),-d2);
|
||||
pixmap[2].fill(Qt::transparent);
|
||||
p.begin(&pixmap[2]);
|
||||
p.drawPixmap(0,0,pix,0,pix.height()+d2,pix.width(),-d2);
|
||||
p.end();
|
||||
}
|
||||
}
|
||||
|
||||
void Line::render(const QRect &rect, QPainter *p, PosFlags pf, bool btmRight) const {
|
||||
int d0,d2;
|
||||
if (_o == Qt::Horizontal) {
|
||||
int y = btmRight?rect.bottom()-_thickness-1:rect.y();
|
||||
d0 = (pf & Left) ? width(0) : 0;
|
||||
d2 = (pf & Right) ? width(2) : 0;
|
||||
if ((pf & Center) && rect.width() >= d0+d2)
|
||||
p->drawTiledPixmap(rect.x()+d0,y, rect.width()-d0-d2, height(1), pixmap[1]);
|
||||
else if (d0 || d2) {
|
||||
d0 = qMin(d0,d0*rect.width()/(d0+d2));
|
||||
d2 = qMin(d2,rect.width()-d0);
|
||||
}
|
||||
if (pf & Left)
|
||||
p->drawPixmap(rect.x(),y, pixmap[0],0,0,d0,height(0));
|
||||
if (pf & Right)
|
||||
p->drawPixmap(rect.right()+1-d2,y, pixmap[2], width(2)-d2,0,d2,height(2));
|
||||
}
|
||||
else {
|
||||
int x = btmRight?rect.right()-_thickness-1:rect.x();
|
||||
d0 = (pf & Top) ? height(0) : 0;
|
||||
d2 = (pf & Bottom) ? height(2) : 0;
|
||||
if ((pf & Center) && rect.height() >= d0+d2) {
|
||||
p->drawTiledPixmap(x,rect.y()+d0, width(1), rect.height()-d0-d2, pixmap[1]);
|
||||
}
|
||||
else if (d0 || d2) {
|
||||
d0 = qMin(d0,d0*rect.height()/(d0+d2));
|
||||
d2 = qMin(d2,rect.height()-d0);
|
||||
}
|
||||
if (pf & Top)
|
||||
p->drawPixmap(x,rect.y(),pixmap[0],0,0,width(0),d0);
|
||||
if (pf & Bottom)
|
||||
p->drawPixmap(x, rect.bottom()+1-d2,pixmap[2],0,height(2)-d2,width(2),d2);
|
||||
}
|
||||
}
|
||||
|
||||
#define FILL_PIX(_NUM_)\
|
||||
pixmap[_NUM_].fill(Qt::transparent);\
|
||||
p.begin(&pixmap[_NUM_]);\
|
||||
p.fillRect(pixmap[_NUM_].rect(), lg);\
|
||||
p.end()
|
||||
|
||||
#define MAKE_ARC(_NUM_,_CLR_,_X_,_Y_,_ANG_)\
|
||||
pixmap[_NUM_] = QPixmap(4,4);\
|
||||
pixmap[_NUM_].fill(Qt::transparent);\
|
||||
p.begin(&pixmap[_NUM_]);\
|
||||
p.setRenderHint(QPainter::Antialiasing);\
|
||||
p.setPen(_CLR_);\
|
||||
p.drawArc(_X_,_Y_,8,8,_ANG_<<4,90<<4);\
|
||||
p.setRenderHint(QPainter::Antialiasing, false);\
|
||||
p.end()
|
||||
|
||||
#define SET_GRAD(_C1_,_C2_)\
|
||||
stops.clear();\
|
||||
stops << QGradientStop(0, QColor(_C1_,_C1_,_C1_,_alpha))\
|
||||
<< QGradientStop(1, QColor(_C2_,_C2_,_C2_,_alpha));\
|
||||
lg.setStops(stops)
|
||||
|
||||
#ifndef CLAMP
|
||||
#define CLAMP(x,l,u) (x) < (l) ? (l) :\
|
||||
(x) > (u) ? (u) :\
|
||||
(x)
|
||||
#endif
|
||||
|
||||
Nuno::Nuno(int alpha)
|
||||
{
|
||||
QGradientStops stops;
|
||||
_alpha = alpha;
|
||||
QPainter p; QPen pen = p.pen();
|
||||
MAKE_ARC(0,QColor(255,255,255,_alpha),0,0,90); //tl
|
||||
QLinearGradient lg( 0, 0, 4, 4 );
|
||||
SET_GRAD(255,170); pen.setBrush(lg);
|
||||
MAKE_ARC(1,pen,-4,0,0); //tr
|
||||
lg.setStart(4,0); lg.setFinalStop(0,4);
|
||||
SET_GRAD(107,100); pen.setBrush(lg);
|
||||
MAKE_ARC(2,pen,-4,-4,270); //br
|
||||
lg.setStart(0,0); lg.setFinalStop(4,4);
|
||||
SET_GRAD(255,175); pen.setBrush(lg);
|
||||
MAKE_ARC(3,pen,0,-4,180); //bl
|
||||
|
||||
_alpha = alpha;
|
||||
|
||||
lg.setStart(0,0); lg.setFinalStop(37,0);
|
||||
|
||||
//bottom 1
|
||||
SET_GRAD(175,138);
|
||||
pixmap[4] = QPixmap(37,1);
|
||||
FILL_PIX(4);
|
||||
|
||||
//bottom 2
|
||||
SET_GRAD(136,100);
|
||||
pixmap[5] = QPixmap(37,1);
|
||||
FILL_PIX(5);
|
||||
|
||||
//right 1
|
||||
lg.setStart(1,0); lg.setFinalStop(1,31);
|
||||
SET_GRAD(170,139);
|
||||
pixmap[6] = QPixmap(1,31);
|
||||
FILL_PIX(6);
|
||||
|
||||
//right 2
|
||||
SET_GRAD(137,107);
|
||||
pixmap[7] = QPixmap(1,31);
|
||||
FILL_PIX(7);
|
||||
}
|
||||
|
||||
#undef FILL_PIX
|
||||
#undef MAKE_ARC
|
||||
|
||||
void Nuno::render(const QRect &r, QPainter *p, PosFlags pf) const
|
||||
{
|
||||
int xOff = 0, yOff = 0, rOff = 0, bOff = 0;
|
||||
|
||||
if (matches(Top|Left, pf))
|
||||
{
|
||||
p->drawPixmap(r.x(),r.y(),pixmap[0]);
|
||||
xOff = r.x()+width(0); yOff = r.y()+height(0);
|
||||
}
|
||||
|
||||
if (matches(Top|Right, pf))
|
||||
{
|
||||
p->drawPixmap(r.right()-width(1)+1,r.y(),pixmap[1]);
|
||||
rOff = r.right()-width(1)+1; yOff = r.y()+height(1);
|
||||
}
|
||||
|
||||
if (matches(Bottom|Left, pf))
|
||||
{
|
||||
p->drawPixmap(r.x(),r.bottom()-height(3)+1,pixmap[3]);
|
||||
xOff = r.x()+width(3); bOff = r.bottom()-height(3)+1;
|
||||
}
|
||||
|
||||
if (matches(Bottom|Right, pf))
|
||||
{
|
||||
p->drawPixmap(r.right()-width(2)+1,r.bottom()-height(2)+1,pixmap[2]);
|
||||
rOff = r.right()-width(2)+1; bOff = r.bottom()-height(2)+1;
|
||||
}
|
||||
p->save();
|
||||
if (xOff < rOff)
|
||||
{
|
||||
if (pf & Top)
|
||||
{
|
||||
p->setPen(QColor(255,255,255,_alpha));
|
||||
p->drawLine(xOff, r.y(), rOff, r.y());
|
||||
}
|
||||
if (pf & Bottom)
|
||||
{
|
||||
int w = rOff-xOff;
|
||||
if (w < width(4)+width(5))
|
||||
{
|
||||
QHash<int, QPixmap> *cache = &(const_cast<Nuno*>( this )->_lines[0]);
|
||||
QHash<int, QPixmap>::const_iterator it;
|
||||
it = cache->find(w);
|
||||
if (it == cache->end())
|
||||
{
|
||||
QPixmap pix(w,1); pix.fill(Qt::transparent);
|
||||
QLinearGradient lg( 0, 1, w, 1 );
|
||||
lg.setColorAt ( 0, QColor(175,175,175,_alpha) );
|
||||
lg.setColorAt ( 1, QColor(100,100,100,_alpha) );
|
||||
QPainter p(&pix); p.fillRect(0,0,w,1,lg); p.end();
|
||||
it = cache->insert(w, pix);
|
||||
}
|
||||
p->drawPixmap(xOff,r.bottom(),it.value());
|
||||
}
|
||||
else
|
||||
{
|
||||
p->drawPixmap(xOff,r.bottom(),pixmap[4]);
|
||||
p->drawPixmap(rOff-width(5),r.bottom(),pixmap[5]);
|
||||
if (w > width(4)+width(5))
|
||||
{
|
||||
p->setPen(QColor(137,137,137,_alpha));
|
||||
p->drawLine(xOff+width(4),r.bottom(),rOff-width(5)-1,r.bottom());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (yOff < bOff)
|
||||
{
|
||||
if (pf & Left)
|
||||
{
|
||||
p->setPen(QColor(255,255,255,_alpha));
|
||||
p->drawLine(r.x(), yOff, r.x(), bOff);
|
||||
}
|
||||
if (pf & Right)
|
||||
{
|
||||
int h = bOff-yOff;
|
||||
if (h < height(6)+height(7))
|
||||
{
|
||||
QHash<int, QPixmap> *cache = &(const_cast<Nuno*>( this )->_lines[1]);
|
||||
QHash<int, QPixmap>::const_iterator it;
|
||||
it = cache->find(h);
|
||||
if (it == cache->end())
|
||||
{
|
||||
QPixmap pix(1,h);
|
||||
QLinearGradient lg( 1, 0, 1, h ); pix.fill(Qt::transparent);
|
||||
lg.setColorAt ( 0, QColor(170,170,170,_alpha) );
|
||||
lg.setColorAt ( 1, QColor(107,107,107,_alpha) );
|
||||
QPainter p(&pix); p.fillRect(0,0,1,h,lg); p.end();
|
||||
it = cache->insert(h, pix);
|
||||
}
|
||||
p->drawPixmap(r.right(),yOff,it.value());
|
||||
}
|
||||
else
|
||||
{
|
||||
p->drawPixmap(r.right(),yOff,pixmap[6]);
|
||||
p->drawPixmap(r.right(),bOff-height(7),pixmap[7]);
|
||||
if (h > height(6)+height(7))
|
||||
{
|
||||
p->setPen(QColor(138,138,138,_alpha));
|
||||
p->drawLine(r.right(),yOff+height(6),r.right(),bOff-height(7)-1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
p->restore();
|
||||
}
|
121
clients/oxygen/tileset.h
Normal file
121
clients/oxygen/tileset.h
Normal file
|
@ -0,0 +1,121 @@
|
|||
/***************************************************************************
|
||||
* Copyright (C) 2006-2007 by Thomas Lübking *
|
||||
* thomas.luebking@web.de *
|
||||
* *
|
||||
* 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., *
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef TILESET_H
|
||||
#define TILESET_H
|
||||
|
||||
#include <QBitmap>
|
||||
#include <QRect>
|
||||
#include <QHash>
|
||||
#include <QX11Info>
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/extensions/Xrender.h>
|
||||
#include <fixx11h.h>
|
||||
|
||||
namespace Tile
|
||||
{
|
||||
|
||||
enum Section
|
||||
{ // DON'T CHANGE THE ORDER FOR NO REASON, i misuse them on the masks...
|
||||
TopLeft = 0, TopRight, BtmLeft, BtmRight,
|
||||
TopMid, BtmMid, MidLeft, MidMid, MidRight
|
||||
};
|
||||
enum Position
|
||||
{
|
||||
Top = 0x1, Left=0x2, Bottom=0x4, Right=0x8,
|
||||
Ring=0xf, Center=0x10, Full=0x1f
|
||||
};
|
||||
|
||||
typedef uint PosFlags;
|
||||
|
||||
inline static bool matches(PosFlags This, PosFlags That){return (This & That) == This;}
|
||||
|
||||
class Set
|
||||
{
|
||||
public:
|
||||
Set(const QPixmap &pix, int xOff, int yOff, int width, int height, int rx = 0, int ry = 0);
|
||||
Set(){}
|
||||
void render(const QRect &rect, QPainter *p, PosFlags pf = Ring) const;
|
||||
void outline(const QRect &rect, QPainter *p, QColor c, bool strong = false,
|
||||
PosFlags pf = Ring) const;
|
||||
Picture render(int width, int height, PosFlags pf = Ring) const;
|
||||
Picture render(const QSize &size, PosFlags pf = Ring) const;
|
||||
QRect rect(const QRect &rect, PosFlags pf) const;
|
||||
inline int width(Section sect) const {return pixmap[sect].width();}
|
||||
inline int height(Section sect) const {return pixmap[sect].height();}
|
||||
inline bool isQBitmap() const {return _isBitmap;}
|
||||
protected:
|
||||
QPixmap pixmap[9];
|
||||
private:
|
||||
int rxf, ryf;
|
||||
bool _isBitmap;
|
||||
};
|
||||
|
||||
class Mask : public Set
|
||||
{
|
||||
public:
|
||||
Mask(const QPixmap &pix, int xOff, int yOff, int width, int height,
|
||||
int dx1, int dy1, int dx2, int dy2, int rx = 0, int ry = 0);
|
||||
Mask(){_dx[0] = _dx[1] = _dy[0] = _dy[1] = 0; _hasCorners = false;}
|
||||
void render(const QRect &rect, QPainter *p, const QBrush &fill,
|
||||
PosFlags pf = Full, bool justClip = false,
|
||||
QPoint offset = QPoint(), bool inverse = false,
|
||||
const QRect *outerRect = 0L) const;
|
||||
QRect bounds(const QRect &rect, PosFlags pf = Full) const;
|
||||
const QPixmap &corner(PosFlags pf, bool inverse = false) const;
|
||||
QRegion clipRegion(const QRect &rect, PosFlags pf = Ring) const;
|
||||
inline bool hasCorners() const {return _hasCorners;}
|
||||
private:
|
||||
int _dx[2], _dy[2];
|
||||
QPixmap inversePixmap[9];
|
||||
bool _hasCorners;
|
||||
};
|
||||
|
||||
class Line
|
||||
{
|
||||
public:
|
||||
Line(const QPixmap &pix, Qt::Orientation o, int d1, int d2);
|
||||
Line(){}
|
||||
void render(const QRect &rect, QPainter *p, PosFlags pf = Full, bool btmRight = false) const;
|
||||
inline int thickness() const { return _thickness; }
|
||||
private:
|
||||
inline int width(int i) const {return pixmap[i].width();}
|
||||
inline int height(int i) const {return pixmap[i].height();}
|
||||
Qt::Orientation _o;
|
||||
QPixmap pixmap[3];
|
||||
int _thickness;
|
||||
};
|
||||
|
||||
class Nuno
|
||||
{
|
||||
public:
|
||||
Nuno(int alpha = 255);
|
||||
void render(const QRect &rect, QPainter *p, PosFlags pf = Ring) const;
|
||||
private:
|
||||
inline int width(int i) const {return pixmap[i].width();}
|
||||
inline int height(int i) const {return pixmap[i].height();}
|
||||
QPixmap pixmap[8];
|
||||
int _alpha;
|
||||
QHash<int, QPixmap> _lines[2];
|
||||
};
|
||||
|
||||
} // namespace Tile
|
||||
|
||||
#endif //TILESET_H
|
Loading…
Reference in a new issue