Import Oxygen windec into kdebase

svn path=/trunk/KDE/kdebase/workspace/; revision=676051
This commit is contained in:
Casper Boemann 2007-06-15 20:11:33 +00:00
parent afd0dae2a8
commit 83cd5b0ba2
29 changed files with 11321 additions and 0 deletions

View 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 )

View 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

View 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
View 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);

View 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, &copy, 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, &copy, 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, &copy, 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
}

File diff suppressed because it is too large Load diff

View 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
}

File diff suppressed because it is too large Load diff

View 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

View 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

View 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;
}

View 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
View 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
View 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
View 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

File diff suppressed because it is too large Load diff

363
clients/oxygen/oxygen.h Normal file
View 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
View 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

View 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>

View 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

View 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
}

File diff suppressed because it is too large Load diff

View 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);
}
}

View 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
View 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

View 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
}

View 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
View 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
View 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