Import the Nitrogen window decoration AS IS from KDE-Look with

permission from hpereiradacosta.

svn path=/trunk/KDE/kdebase/workspace/; revision=1014262
This commit is contained in:
Lucas Murray 2009-08-22 08:24:06 +00:00
parent 35f7ad4ad4
commit a92f204309
43 changed files with 7900 additions and 0 deletions

View file

@ -6,6 +6,7 @@ add_subdirectory( kde2 )
add_subdirectory( keramik )
add_subdirectory( laptop )
add_subdirectory( modernsystem )
add_subdirectory( nitrogen )
add_subdirectory( oxygen )
add_subdirectory( ozone )
add_subdirectory( quartz )

View file

@ -0,0 +1,72 @@
# $Id: CMakeLists.txt,v 1.30 2009/07/05 18:27:08 hpereira Exp $
find_package (KDE4 REQUIRED)
add_definitions (-DQT3_SUPPORT -DQT3_SUPPORT_WARNINGS)
set(CPACK_PACKAGE_NAME "kde4-windeco-nitrogen" )
set(CPACK_SOURCE_PACKAGE_NAME "kde4-windeco-nitrogen" )
set(CPACK_SOURCE_GENERATOR TGZ)
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Kde4 Nitrogen window decoration")
set(CPACK_PACKAGE_VENDOR "hugo.pereira@free.fr")
set(CPACK_PACKAGE_VERSION_MAJOR "2")
set(CPACK_PACKAGE_VERSION_MINOR "3")
set(CPACK_PACKAGE_VERSION_PATCH "5")
set(CPACK_PACKAGE_INSTALL_DIRECTORY "CMake ${CMake_VERSION_MAJOR}.${CMake_VERSION_MINOR}")
include (CPack)
include (KDE4Defaults)
include (MacroLibrary)
add_definitions (${QT_DEFINITIONS} ${KDE4_DEFINITIONS})
include_directories (${KDE4_INCLUDES} ${CMAKE_BINARY_DIR})
########### add version number into compilation defines
add_definitions ( -DAPP_VERSION=\\\"${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR}.${CPACK_PACKAGE_VERSION_PATCH}\\\")
add_subdirectory( config )
########### next target ###############
set(kwin_nitrogen_SRCS
lib/helper.cpp
lib/tileset.cpp
nitrogen.cpp
nitrogenbutton.cpp
nitrogenclient.cpp
nitrogenconfiguration.cpp
nitrogenexception.cpp
nitrogenexceptionlist.cpp
nitrogensizegrip.cpp
x11util.cpp
)
kde4_add_plugin(kwin3_nitrogen ${kwin_nitrogen_SRCS})
target_link_libraries(
kwin3_nitrogen
${KDE4_KDEUI_LIBS}
${X11_X11_LIB}
${X11_Xrender_LIB}
kdecorations
)
install(TARGETS kwin3_nitrogen DESTINATION ${PLUGIN_INSTALL_DIR} )
########### next target ###############
set( conversion_SRCS
nitrogenconfiguration.cpp
nitrogenexception.cpp
nitrogenexceptionlist.cpp
nitrogenconvertexceptions.cpp
)
kde4_add_executable(nitrogen-convert-exceptions ${conversion_SRCS})
target_link_libraries(
nitrogen-convert-exceptions
${KDE4_KDEUI_LIBS}
)
install(TARGETS nitrogen-convert-exceptions DESTINATION ${INSTALL_TARGETS_DEFAULT_ARGS} )
########### install files ###############
install( FILES nitrogenclient.desktop DESTINATION ${DATA_INSTALL_DIR}/kwin/ )

339
clients/nitrogen/COPYING Normal file
View file

@ -0,0 +1,339 @@
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Library General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
Appendix: How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) 19yy <name of author>
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.
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) 19yy name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
<signature of Ty Coon>, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Library General
Public License instead of this License.

48
clients/nitrogen/INSTALL Normal file
View file

@ -0,0 +1,48 @@
// $Id: INSTALL,v 1.2 2009/02/25 21:33:45 hpereira Exp $
/******************************************************************************
*
* Copyright (C) 2002 Hugo PEREIRA <mailto: hugo.pereira@free.fr>
*
* This 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 software 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
* software; if not, write to the Free Software Foundation, Inc., 59 Temple
* Place, Suite 330, Boston, MA 02111-1307 USA
*
*
*******************************************************************************/
How to install
--------------
I/ Get a tarball of latest release and unpack
---------------------------------------------
> gtar -xzvf kde4-windeco-nitrogen-X.X.X-Source.tar.gz
or
> tar -xzvf kde4-windeco-nitrogen-X.X.X-Source.tar.gz
II/ compile the sources.
------------------------
To compile and install
> cd kde4-windeco-nitrogen-X.X.X-Source
> cmake -DCMAKE_INSTALL_PREFIX=`kde4-config --prefix` .
> make
> sudo make install
You should then be able to change the window decoration style from kde4 system-settings window.
send comments/problems to hugo.pereira@free.fr

3
clients/nitrogen/README Normal file
View file

@ -0,0 +1,3 @@
This decoration is a fork of the oxygen/ozone decoration, that allows notably to resize window border.
Suggestions, bug report: hugo.pereira@free.fr

View file

@ -0,0 +1,36 @@
# $Id: CMakeLists.txt,v 1.8 2009/06/21 19:57:19 hpereira Exp $
include_directories( ${KDEBASE_WORKSPACE_SOURCE_DIR}/kwin/lib )
find_package (KDE4 REQUIRED)
add_definitions (-DQT3_SUPPORT -DQT3_SUPPORT_WARNINGS)
include (KDE4Defaults)
include (MacroLibrary)
add_definitions (${QT_DEFINITIONS} ${KDE4_DEFINITIONS})
include_directories (${KDE4_INCLUDES} ${CMAKE_BINARY_DIR})
########### next target ###############
set(kwin_nitrogen_config_PART_SRCS
config.cpp
itemmodel.cpp
../nitrogenconfiguration.cpp
../nitrogenexception.cpp
../nitrogenexceptionlist.cpp
nitrogenconfigurationui.cpp
nitrogenexceptiondialog.cpp
nitrogenexceptionlistdialog.cpp
nitrogenexceptionmodel.cpp
)
kde4_add_plugin(kwin_nitrogen_config ${kwin_nitrogen_config_PART_SRCS})
target_link_libraries(
kwin_nitrogen_config
${KDE4_KDEUI_LIBS}
${QT_QTGUI_LIBRARY}
)
install(TARGETS kwin_nitrogen_config DESTINATION ${PLUGIN_INSTALL_DIR} )

View file

@ -0,0 +1,216 @@
/*
* Nitrogen KWin client configuration module
*
* Copyright (C) 2008 Lubos Lunak <l.lunak@kde.org>
*
* Based on the Quartz configuration module,
* Copyright (c) 2001 Karol Szwed <gallium@kde.org>
*
* 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; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
// $Id: config.cpp,v 1.25 2009/07/05 20:45:40 hpereira Exp $
#include <KAboutData>
#include <KAboutApplicationDialog>
#include <KConfigGroup>
#include <KGlobal>
#include <KLocale>
#include <kstandarddirs.h>
#include <QTextStream>
#include "config.h"
#include "config.moc"
#include "nitrogenexceptionlistdialog.h"
#include "../nitrogenconfiguration.h"
//_______________________________________________________________________
extern "C"
{
KDE_EXPORT QObject* allocate_config( KConfig* conf, QWidget* parent )
{ return ( new Nitrogen::Config( conf, parent ) ); }
}
namespace Nitrogen
{
//_______________________________________________________________________
Config::Config( KConfig*, QWidget* parent ): QObject( parent )
{
KGlobal::locale()->insertCatalog("kwin_clients");
configuration_ = new KConfig( "nitrogenrc" );
KConfigGroup configurationGroup( configuration_, "Windeco");
user_interface_ = new NitrogenConfigurationUI( parent );
connect( user_interface_->titleAlignment, SIGNAL(currentIndexChanged(int)), SIGNAL(changed()) );
connect( user_interface_->buttonSize, SIGNAL(currentIndexChanged(int)), SIGNAL(changed()) );
connect( user_interface_->buttonType, SIGNAL(currentIndexChanged(int)), SIGNAL(changed()) );
connect( user_interface_->frameBorder, SIGNAL(currentIndexChanged(int)), SIGNAL(changed()) );
connect( user_interface_->blendColor, SIGNAL(currentIndexChanged(int)), SIGNAL(changed()) );
connect( user_interface_->showStripes, SIGNAL(clicked()), SIGNAL(changed()) );
connect( user_interface_->drawSeparator, SIGNAL(clicked()), SIGNAL(changed()) );
connect( user_interface_->overwriteColors, SIGNAL(clicked()), SIGNAL(changed()) );
connect( user_interface_->drawSizeGrip, SIGNAL(clicked()), SIGNAL(changed()) );
connect( user_interface_->useOxygenShadows, SIGNAL(clicked()), SIGNAL(changed()) );
connect( user_interface_->showExceptions, SIGNAL(clicked()), SLOT( showExceptions() ) );
NitrogenConfiguration::checkUseCompiz();
if( NitrogenConfiguration::useCompiz() )
{ user_interface_->useOxygenShadows->setEnabled( false ); }
load( configurationGroup );
user_interface_->show();
}
//_______________________________________________________________________
Config::~Config()
{
delete user_interface_;
delete configuration_;
}
//_______________________________________________________________________
void Config::load( const KConfigGroup& )
{
// load standard configuration
KConfigGroup configurationGroup( configuration_, "Windeco");
loadConfiguration( NitrogenConfiguration( configurationGroup ) );
exceptions_.read( *configuration_ );
if( exceptions_.empty() )
{ exceptions_ = NitrogenExceptionList::defaultList(); }
}
//_______________________________________________________________________
void Config::save( KConfigGroup& )
{
// save standard configuration
KConfigGroup configurationGroup( configuration_, "Windeco");
configurationGroup.writeEntry( NitrogenConfig::TITLE_ALIGNMENT, user_interface_->titleAlignment->currentText() );
configurationGroup.writeEntry( NitrogenConfig::BUTTON_SIZE, user_interface_->buttonSize->currentText() );
configurationGroup.writeEntry( NitrogenConfig::BUTTON_TYPE, user_interface_->buttonType->currentText() );
configurationGroup.writeEntry( NitrogenConfig::BLEND_COLOR, user_interface_->blendColor->currentText() );
configurationGroup.writeEntry( NitrogenConfig::FRAME_BORDER, user_interface_->frameBorder->currentText() );
configurationGroup.writeEntry( NitrogenConfig::SHOW_STRIPES, user_interface_->showStripes->isChecked() );
configurationGroup.writeEntry( NitrogenConfig::DRAW_SEPARATOR, user_interface_->drawSeparator->isChecked() );
configurationGroup.writeEntry( NitrogenConfig::OVERWRITE_COLORS, user_interface_->overwriteColors->isChecked() );
configurationGroup.writeEntry( NitrogenConfig::DRAW_SIZE_GRIP, user_interface_->drawSizeGrip->isChecked() );
configurationGroup.writeEntry( NitrogenConfig::USE_OXYGEN_SHADOWS, user_interface_->useOxygenShadows->isChecked() );
// write number of exceptions
exceptions_.write( *configuration_ );
configuration_->sync();
}
//_______________________________________________________________________
void Config::defaults()
{
// install default configuration
loadConfiguration( NitrogenConfiguration() );
// install default exceptions
exceptions_ = NitrogenExceptionList::defaultList();
// emit changed signal
emit changed();
}
//_______________________________________________________________________
void Config::loadConfiguration( const NitrogenConfiguration& configuration )
{
user_interface_->titleAlignment->setCurrentIndex( user_interface_->titleAlignment->findText( configuration.titleAlignmentName() ) );
user_interface_->buttonSize->setCurrentIndex( user_interface_->buttonSize->findText( configuration.buttonSizeName() ) );
user_interface_->buttonType->setCurrentIndex( user_interface_->buttonType->findText( configuration.buttonTypeName() ) );
user_interface_->blendColor->setCurrentIndex( user_interface_->blendColor->findText( configuration.blendColorName() ) );
user_interface_->frameBorder->setCurrentIndex( user_interface_->frameBorder->findText( configuration.frameBorderName() ) );
user_interface_->showStripes->setChecked( configuration.showStripes() );
user_interface_->drawSeparator->setChecked( configuration.drawSeparator() );
user_interface_->overwriteColors->setChecked( configuration.overwriteColors() );
user_interface_->drawSizeGrip->setChecked( configuration.drawSizeGrip() );
user_interface_->useOxygenShadows->setChecked( configuration.useOxygenShadows() );
}
//_______________________________________________________________________
void Config::showExceptions( void )
{
// get default configuration (from current)
KConfigGroup configurationGroup( configuration_, "Windeco");
// create dialog
NitrogenExceptionListDialog dialog(
dynamic_cast<QWidget*>(parent()),
NitrogenConfiguration( configurationGroup ) );
dialog.setExceptions( exceptions_ );
if( !dialog.exec() ) return;
// get new exception list from dialog
NitrogenExceptionList new_exceptions = dialog.exceptions();
// compare to current.
if( new_exceptions == exceptions_ ) return;
else {
// update and emit change signal if they differ
exceptions_ = new_exceptions;
emit changed();
}
}
//_______________________________________________________________________
void Config::aboutNitrogen( void )
{
KAboutData aboutData( "nitrogen", 0,
ki18n( "Nitrogen" ), APP_VERSION,
ki18n( "Oxygen based Window decoration for KDE" ), KAboutData::License_GPL,
KLocalizedString(),
KLocalizedString(),
( "http://www.kde-look.org/content/show.php/Nitrogen?content=99551" ) );
aboutData.addAuthor(
ki18n( "Hugo Pereira Da Costa" ), ki18n( "Developper" ),
"hugo.pereira@free.fr",
"http://hugo.pereira.free.fr/index.php" );
aboutData.addCredit( ki18n( "Oxygen team" ) );
// create dialog
KAboutApplicationDialog( &aboutData, 0 ).exec();
}
}

View file

@ -0,0 +1,94 @@
#ifndef nitrogen_config_h
#define nitrogen_config_h
// $Id: config.h,v 1.7 2009/06/24 01:43:14 hpereira Exp $
/*
* Nitrogen KWin client configuration module
*
* Copyright (C) 2008 Lubos Lunak <l.lunak@kde.org>
*
* Based on the Quartz configuration module,
* Copyright (c) 2001 Karol Szwed <gallium@kde.org>
*
* 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; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#include <KConfig>
#include "nitrogenconfigurationui.h"
#include "../nitrogenexceptionlist.h"
namespace Nitrogen {
class NitrogenConfiguration;
// nitrogen configuration object
class Config: public QObject
{
Q_OBJECT
public:
//! constructor
Config( KConfig* conf, QWidget* parent );
//! destructor
~Config();
signals:
//! emmited whenever configuration is changed
void changed();
public slots:
//! load configuration
void load( const KConfigGroup& conf );
//! save configuration
void save( KConfigGroup& conf );
//! restore defaults
void defaults();
private slots:
//! raise exception list
void showExceptions( void );
//! about nitrogen
void aboutNitrogen( void );
private:
//! load configuration
void loadConfiguration( const NitrogenConfiguration& );
//! user interface
NitrogenConfigurationUI *user_interface_;
//! kconfiguration object
KConfig *configuration_;
//! internal list of exceptions
NitrogenExceptionList exceptions_;
};
} //namespace Nitrogen
#endif

View file

@ -0,0 +1,73 @@
// $Id: itemmodel.cpp,v 1.1 2009/03/25 17:44:24 hpereira Exp $
/******************************************************************************
*
* Copyright (C) 2002 Hugo PEREIRA <mailto: hugo.pereira@free.fr>
*
* This 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 software 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
* software; if not, write to the Free Software Foundation, Inc., 59 Temple
* Place, Suite 330, Boston, MA 02111-1307 USA
*
*
*******************************************************************************/
/*!
\file ItemModel.h
\brief Job model. Stores job information for display in lists
\author Hugo Pereira
\version $Revision: 1.1 $
\date $Date: 2009/03/25 17:44:24 $
*/
#include "itemmodel.h"
using namespace std;
//_______________________________________________________________
ItemModel::ItemModel( QObject* parent ):
QAbstractItemModel( parent ),
sort_column_(0),
sort_order_( Qt::AscendingOrder )
{}
//____________________________________________________________
void ItemModel::sort( int column, Qt::SortOrder order )
{
// store column and order
sort_column_ = column;
sort_order_ = order;
// emit signals and call private methods
emit layoutAboutToBeChanged();
_sort( column, order );
emit layoutChanged();
}
//____________________________________________________________
QModelIndexList ItemModel::indexes( int column, const QModelIndex& parent ) const
{
QModelIndexList out;
int rows( rowCount( parent ) );
for( int row = 0; row < rows; row++ )
{
QModelIndex index( this->index( row, column, parent ) );
if( !index.isValid() ) continue;
out.push_back( index );
out += indexes( column, index );
}
return out;
}

View file

@ -0,0 +1,114 @@
#ifndef ItemModel_h
#define ItemModel_h
// $Id: itemmodel.h,v 1.2 2009/03/25 23:45:37 hpereira Exp $
/******************************************************************************
*
* Copyright (C) 2002 Hugo PEREIRA <mailto: hugo.pereira@free.fr>
*
* This 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 software 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
* software; if not, write to the Free Software Foundation, Inc., 59 Temple
* Place, Suite 330, Boston, MA 02111-1307 USA
*
*
*******************************************************************************/
/*!
\file ItemModel.h
\author Hugo Pereira
\version $Revision: 1.2 $
\date $Date: 2009/03/25 23:45:37 $
*/
#include <QAbstractItemModel>
//! Job model. Stores job information for display in lists
class ItemModel : public QAbstractItemModel
{
public:
//! constructor
ItemModel(QObject *parent = 0);
//! destructor
virtual ~ItemModel()
{}
//! return all indexes in model starting from parent [recursive]
QModelIndexList indexes( int column = 0, const QModelIndex& parent = QModelIndex() ) const;
//!@name sorting
//@{
//! sort
virtual void sort( void )
{ sort( sortColumn(), sortOrder() ); }
//! sort
virtual void sort( int column, Qt::SortOrder order = Qt::AscendingOrder );
//! current sorting column
const int& sortColumn( void ) const
{ return sort_column_; }
//! current sort order
const Qt::SortOrder& sortOrder( void ) const
{ return sort_order_; }
//@}
protected:
//! this sort columns without calling the layout changed callbacks
void _sort( void )
{ _sort( sortColumn(), sortOrder() ); }
//! private sort, with no signals emmitted
virtual void _sort( int column, Qt::SortOrder order ) = 0;
//! used to sort items in list
class SortFTor
{
public:
//! constructor
SortFTor( const int& type, Qt::SortOrder order = Qt::AscendingOrder ):
type_( type ),
order_( order )
{}
protected:
//! column
int type_;
//! order
Qt::SortOrder order_;
};
private:
//! sorting column
int sort_column_;
//! sorting order
Qt::SortOrder sort_order_;
};
#endif

View file

@ -0,0 +1,389 @@
#ifndef ListModel_h
#define ListModel_h
// $Id: listmodel.h,v 1.2 2009/04/01 20:49:53 hpereira Exp $
/******************************************************************************
*
* Copyright (C) 2002 Hugo PEREIRA <mailto: hugo.pereira@free.fr>
*
* This 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 software 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
* software; if not, write to the Free Software Foundation, Inc., 59 Temple
* Place, Suite 330, Boston, MA 02111-1307 USA
*
*
*******************************************************************************/
/*!
\file ListModel.h
\brief templatized list model
\author Hugo Pereira
\version $Revision: 1.2 $
\date $Date: 2009/04/01 20:49:53 $
*/
#include <algorithm>
#include <assert.h>
#include <set>
#include <vector>
#include "itemmodel.h"
//! Job model. Stores job information for display in lists
template<class T> class ListModel : public ItemModel
{
public:
//! value type
typedef T ValueType;
//! reference
typedef T& Reference;
//! pointer
typedef T* Pointer;
//! list of vector
typedef std::vector<ValueType> List;
//! list of vector
typedef std::set<ValueType> Set;
//! constructor
ListModel(QObject *parent = 0):
ItemModel( parent )
{}
//! destructor
virtual ~ListModel()
{}
//!@name methods reimplemented from base class
//@{
//! flags
virtual Qt::ItemFlags flags(const QModelIndex &index) const
{
if (!index.isValid()) return 0;
return Qt::ItemIsEnabled | Qt::ItemIsSelectable;
}
//! unique index for given row, column and parent index
virtual QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const
{
// check if index is valid
if( !hasIndex( row, column, parent ) ) return QModelIndex();
// return invalid index if parent is valid
if( parent.isValid() ) return QModelIndex();
// check against values_
return ( row < (int) values_.size() ) ? createIndex( row, column ):QModelIndex();
}
//! index of parent
virtual QModelIndex parent(const QModelIndex &) const
{ return QModelIndex(); }
//! number of rows below given index
virtual int rowCount(const QModelIndex &parent = QModelIndex()) const
{ return parent.isValid() ? 0:values_.size(); }
//@}
//!@name selection
//@{
//! clear internal list selected items
virtual void clearSelectedIndexes( void )
{ selection_.clear(); }
//! store index internal selection state
virtual void setIndexSelected( const QModelIndex& index, bool value )
{
if( value ) selection_.push_back( get(index) );
else selection_.erase( std::remove( selection_.begin(), selection_.end(), get(index) ), selection_.end() );
}
//! get list of internal selected items
virtual QModelIndexList selectedIndexes( void ) const
{
QModelIndexList out;
for( typename List::const_iterator iter = selection_.begin(); iter != selection_.end(); iter++ )
{
QModelIndex index( ListModel::index( *iter ) );
if( index.isValid() ) out.push_back( index );
}
return out;
}
//@}
//!@name interface
//@{
//! add value
virtual void add( const ValueType& value )
{
emit layoutAboutToBeChanged();
_add( value );
_sort();
emit layoutChanged();
}
//! add values
virtual void add( const List& values )
{
// check if not empty
// this avoids sending useless signals
if( values.empty() ) return;
emit layoutAboutToBeChanged();
for( typename List::const_iterator iter = values.begin(); iter != values.end(); iter++ )
{ _add( *iter ); }
_sort();
emit layoutChanged();
}
//! add values
/*! this method uses a Set to add the values. It speeds up the updating of existing values */
virtual void add( Set values )
{
emit layoutAboutToBeChanged();
for( typename List::iterator iter = values_.begin(); iter != values_.end(); iter++ )
{
// see if current iterator is found in values set
typename Set::iterator found_iter( values.find( *iter ) );
if( found_iter != values.end() )
{
*iter = *found_iter;
values.erase( found_iter );
}
}
// insert remaining values at the end
values_.insert( values_.end(), values.begin(), values.end() );
_sort();
emit layoutChanged();
}
//! insert values
virtual void insert( const QModelIndex& index, const ValueType& value )
{
emit layoutAboutToBeChanged();
_insert( index, value );
emit layoutChanged();
}
//! insert values
virtual void insert( const QModelIndex& index, const List& values )
{
emit layoutAboutToBeChanged();
// need to loop in reverse order so that the "values" ordering is preserved
for( typename List::const_reverse_iterator iter = values.rbegin(); iter != values.rend(); iter++ )
_insert( index, *iter );
emit layoutChanged();
}
//! insert values
virtual void replace( const QModelIndex& index, const ValueType& value )
{
if( !index.isValid() ) add( value );
else {
emit layoutAboutToBeChanged();
setIndexSelected( index, false );
values_[index.row()] = value;
setIndexSelected( index, true );
emit layoutChanged();
}
}
//! remove
virtual void remove( const ValueType& value )
{
emit layoutAboutToBeChanged();
_remove( value );
emit layoutChanged();
return;
}
//! remove
virtual void remove( const List& values )
{
// check if not empty
// this avoids sending useless signals
if( values.empty() ) return;
emit layoutAboutToBeChanged();
for( typename List::const_iterator iter = values.begin(); iter != values.end(); iter++ )
{ _remove( *iter ); }
emit layoutChanged();
return;
}
//! clear
virtual void clear( void )
{ set( List() ); }
//! update values from list
/*!
values that are not found in current are removed
new values are set to the end.
This is slower than the "set" method, but the selection is not cleared in the process
*/
virtual void update( List values )
{
emit layoutAboutToBeChanged();
// store values to be removed
List removed_values;
// update values that are common to both lists
for( typename List::iterator iter = values_.begin(); iter != values_.end(); iter++ )
{
// see if iterator is in list
typename List::iterator found_iter( std::find( values.begin(), values.end(), *iter ) );
if( found_iter == values.end() ) removed_values.push_back( *iter );
else {
*iter = *found_iter;
values.erase( found_iter );
}
}
// remove values that have not been found in new list
for( typename List::const_iterator iter = removed_values.begin(); iter != removed_values.end(); iter++ )
{ _remove( *iter ); }
// add remaining values
for( typename List::const_iterator iter = values.begin(); iter != values.end(); iter++ )
{ _add( *iter ); }
_sort();
emit layoutChanged();
}
//! set all values
virtual void set( const List& values )
{
emit layoutAboutToBeChanged();
values_ = values;
selection_.clear();
_sort();
emit layoutChanged();
return;
}
//! return all values
const List& get( void ) const
{ return values_; }
//! return value for given index
virtual ValueType get( const QModelIndex& index ) const
{ return (index.isValid() && index.row() < int(values_.size()) ) ? values_[index.row()]:ValueType(); }
//! return value for given index
virtual ValueType& get( const QModelIndex& index )
{
assert( index.isValid() && index.row() < int( values_.size() ) );
return values_[index.row()];
}
//! return all values
List get( const QModelIndexList& indexes ) const
{
List out;
for( QModelIndexList::const_iterator iter = indexes.begin(); iter != indexes.end(); iter++ )
{ if( iter->isValid() && iter->row() < int(values_.size()) ) out.push_back( get( *iter ) ); }
return out;
}
//! return index associated to a given value
virtual QModelIndex index( const ValueType& value, int column = 0 ) const
{
for( unsigned int row=0; row<values_.size(); row++ )
{ if( value == values_[row] ) return index( row, column ); }
return QModelIndex();
}
//@}
protected:
//! return all values
List& _get( void )
{ return values_; }
//! add, without update
virtual void _add( const ValueType& value )
{
typename List::iterator iter = std::find( values_.begin(), values_.end(), value );
if( iter == values_.end() ) values_.push_back( value );
else *iter = value;
}
//! add, without update
virtual void _insert( const QModelIndex& index, const ValueType& value )
{
if( !index.isValid() ) add( value );
int row = 0;
typename List::iterator iter( values_.begin() );
for( ;iter != values_.end() && row != index.row(); iter++, row++ ){}
values_.insert( iter, value );
}
//! remove, without update
virtual void _remove( const ValueType& value )
{
values_.erase( std::remove( values_.begin(), values_.end(), value ), values_.end() );
selection_.erase( std::remove( selection_.begin(), selection_.end(), value ), selection_.end() );
}
private:
//! values
List values_;
//! selection
List selection_;
};
#endif

View file

@ -0,0 +1,201 @@
// $Id: nitrogenconfigurationui.cpp,v 1.20 2009/07/05 20:45:40 hpereira Exp $
/******************************************************************************
*
* Copyright (C) 2002 Hugo PEREIRA <mailto: hugo.pereira@free.fr>
*
* This 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 software 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
* software; if not, write to the Free Software Foundation, Inc., 59 Temple
* Place, Suite 330, Boston, MA 02111-1307 USA
*
*
*******************************************************************************/
/*!
\file nitrogenconfigurationui.cpp
\brief window decoration configuration user interface
\author Hugo Pereira
\version $Revision: 1.20 $
\date $Date: 2009/07/05 20:45:40 $
*/
#include <kdeversion.h>
#include <QLabel>
#include <QLayout>
#include <QSpacerItem>
#include <QGroupBox>
#include <KLocale>
#include <iostream>
#include "../nitrogenconfiguration.h"
#include "nitrogenconfigurationui.h"
#include "nitrogenconfigurationui.moc"
namespace Nitrogen
{
//_________________________________________________________
NitrogenConfigurationUI::NitrogenConfigurationUI( QWidget* parent ):
QWidget( parent ),
titleAlignment(0),
buttonSize(0),
buttonType(0),
frameBorder(0),
blendColor(0),
drawSeparator(0),
showStripes(0),
drawSizeGrip(0)
{ setupUI(); }
//_________________________________________________________
void NitrogenConfigurationUI::setupUI( void )
{
std::cout << "NitrogenConfigurationUI::setupUI.\n" << std::endl;
QVBoxLayout* mainLayout = new QVBoxLayout( this );
mainLayout->setSpacing(6);
mainLayout->setMargin(0);
QHBoxLayout* hboxLayout = new QHBoxLayout();
hboxLayout->setSpacing(6);
mainLayout->addLayout(hboxLayout);
// left box for comboboxes
QGroupBox* box;
hboxLayout->addWidget( box = new QGroupBox( "Layout", this ) );
QGridLayout* gridLayout = new QGridLayout();
gridLayout->setSpacing(6);
box->setLayout( gridLayout );
// title alignment
QLabel* label;
gridLayout->addWidget( label = new QLabel( tr2i18n("Title alignment:"), box ), 0, 0, 1, 1 );
gridLayout->addWidget( titleAlignment = new QComboBox(box), 0, 1, 1, 1 );
titleAlignment->setObjectName(QString::fromUtf8("titleAlignment"));
titleAlignment->insertItems(0, QStringList()
<< NitrogenConfiguration::titleAlignmentName( Qt::AlignLeft )
<< NitrogenConfiguration::titleAlignmentName( Qt::AlignHCenter )
<< NitrogenConfiguration::titleAlignmentName( Qt::AlignRight )
);
label->setAlignment( Qt::AlignRight|Qt::AlignVCenter );
label->setBuddy( titleAlignment );
// button size
gridLayout->addWidget( label = new QLabel( tr2i18n("Button size:"), box ), 1, 0, 1, 1 );
gridLayout->addWidget( buttonSize = new QComboBox(box), 1, 1, 1, 1 );
buttonSize->setObjectName(QString::fromUtf8("buttonSize"));
buttonSize->insertItems(0, QStringList()
<< NitrogenConfiguration::buttonSizeName( NitrogenConfiguration::ButtonSmall )
<< NitrogenConfiguration::buttonSizeName( NitrogenConfiguration::ButtonDefault )
<< NitrogenConfiguration::buttonSizeName( NitrogenConfiguration::ButtonLarge )
<< NitrogenConfiguration::buttonSizeName( NitrogenConfiguration::ButtonHuge )
);
label->setAlignment( Qt::AlignRight|Qt::AlignVCenter );
label->setBuddy( buttonSize );
// button type
gridLayout->addWidget( label = new QLabel( tr2i18n("Button type:"), box ), 2, 0, 1, 1 );
gridLayout->addWidget( buttonType = new QComboBox(box), 2, 1, 1, 1 );
buttonType->setObjectName(QString::fromUtf8("buttonType"));
buttonType->insertItems(0, QStringList()
<< NitrogenConfiguration::buttonTypeName( NitrogenConfiguration::ButtonKde42 )
<< NitrogenConfiguration::buttonTypeName( NitrogenConfiguration::ButtonKde43 )
);
label->setAlignment( Qt::AlignRight|Qt::AlignVCenter );
label->setBuddy( buttonType );
// frame border
gridLayout->addWidget( label = new QLabel( tr2i18n("Border size:"), box ), 3, 0, 1, 1);
gridLayout->addWidget( frameBorder = new QComboBox(box), 3, 1, 1, 1);
frameBorder->setObjectName(QString::fromUtf8("frameBorder"));
frameBorder->insertItems(0, QStringList()
<< NitrogenConfiguration::frameBorderName( NitrogenConfiguration::BorderNone )
<< NitrogenConfiguration::frameBorderName( NitrogenConfiguration::BorderTiny )
<< NitrogenConfiguration::frameBorderName( NitrogenConfiguration::BorderSmall )
<< NitrogenConfiguration::frameBorderName( NitrogenConfiguration::BorderDefault )
<< NitrogenConfiguration::frameBorderName( NitrogenConfiguration::BorderLarge )
);
label->setAlignment( Qt::AlignRight|Qt::AlignVCenter );
label->setBuddy( frameBorder );
// title bar blending
gridLayout->addWidget( label = new QLabel( tr2i18n("Title bar blending:" ), box ), 4, 0, 1, 1 );
gridLayout->addWidget( blendColor = new QComboBox(box), 4, 1, 1, 1 );
blendColor->setObjectName(QString::fromUtf8("blendColor"));
blendColor->insertItems(0, QStringList()
<< NitrogenConfiguration::blendColorName( NitrogenConfiguration::NoBlending )
<< NitrogenConfiguration::blendColorName( NitrogenConfiguration::RadialBlending )
);
label->setAlignment( Qt::AlignRight|Qt::AlignVCenter );
label->setBuddy( blendColor );
// right is for checkboxes
hboxLayout->addWidget( box = new QGroupBox( "Flags", this ) );
QVBoxLayout* vboxLayout = new QVBoxLayout();
box->setLayout( vboxLayout );
// oxygen shadow
vboxLayout->addWidget( useOxygenShadows = new QCheckBox( tr2i18n("&Use oxygen shadows", 0 ), this ) );
useOxygenShadows->setObjectName(QString::fromUtf8("useOxygenShadows"));
useOxygenShadows->setWhatsThis(tr2i18n(
"When this option is enabled, oxygen signature blue glow is used for the active window shadow.", 0));
// draw separator
vboxLayout->addWidget( drawSeparator = new QCheckBox( tr2i18n("Draw separator between title bar and window contents", 0), this ) );
drawSeparator->setObjectName(QString::fromUtf8("drawSeparator"));
drawSeparator->setWhatsThis(tr2i18n(
"When enabled, this option makes an horizontal separator appear between the window title bar and the window contents.", 0));
// show stripes
vboxLayout->addWidget( showStripes = new QCheckBox( tr2i18n("Show stripes next to the title", 0), this) );
showStripes->setObjectName(QString::fromUtf8("showStripes"));
showStripes->setWhatsThis(tr2i18n(
"When enabled, this option increases the visibility of the window titlebar by showing stripes", 0));
// overwrite colors
vboxLayout->addWidget( overwriteColors = new QCheckBox( tr2i18n("Overwrite default title bar colors", 0), this) );
overwriteColors->setObjectName(QString::fromUtf8("overwriteColors"));
overwriteColors->setWhatsThis(tr2i18n(
"When enabled, window colors are used in place of default title bar colors to draw the decoration", 0));
// draw size grip
vboxLayout->addWidget( drawSizeGrip = new QCheckBox( tr2i18n("Draw size grip widget in bottom-right corner of windows", 0), this ) );
drawSizeGrip->setObjectName(QString::fromUtf8("drawSizeGrip"));
drawSizeGrip->setWhatsThis(tr2i18n(
"When this option is enabled, a small triangular widget is drawn in bottom-right corner of every window \n"
"that allow to resize the window. This the \"No Border\" border size is selected.", 0));
// exceptions
mainLayout->addLayout( hboxLayout = new QHBoxLayout() );
hboxLayout->addStretch( 1 );
hboxLayout->addWidget( showExceptions = new QPushButton( tr2i18n("Exceptions ..." ), box ) );
showExceptions->setToolTip(tr2i18n("Raise a dialog to store blending type exceptions based on window title.", 0));
// about
// this is disabled until I find a suitable icon for nitrogen.
// hboxLayout->addWidget( aboutNitrogen = new QPushButton( tr2i18n("About Nitrogen" ), box ) );
QMetaObject::connectSlotsByName(this);
};
};

View file

@ -0,0 +1,98 @@
#ifndef nitrogenconfigurationui_h
#define nitrogenconfigurationui_h
// $Id: nitrogenconfigurationui.h,v 1.11 2009/07/05 20:45:40 hpereira Exp $
/******************************************************************************
*
* Copyright (C) 2002 Hugo PEREIRA <mailto: hugo.pereira@free.fr>
*
* This 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 software 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
* software; if not, write to the Free Software Foundation, Inc., 59 Temple
* Place, Suite 330, Boston, MA 02111-1307 USA
*
*
*******************************************************************************/
/*!
\file nitrogenconfigurationui.h
\brief window decoration configuration user interface
\author Hugo Pereira
\version $Revision: 1.11 $
\date $Date: 2009/07/05 20:45:40 $
*/
#include <kdeversion.h>
#include <QWidget>
#include <QComboBox>
#include <QCheckBox>
#include <QPushButton>
namespace Nitrogen
{
//_____________________________________________
class NitrogenConfigurationUI: public QWidget
{
Q_OBJECT
public:
//! constructor
NitrogenConfigurationUI( QWidget* );
//! setup ui
void setupUI( void );
//! title alignment
QComboBox *titleAlignment;
//! button size
QComboBox* buttonSize;
//! button size
QComboBox* buttonType;
//! frame border
QComboBox *frameBorder;
//! blend color
QComboBox *blendColor;
//! draw separator
QCheckBox *drawSeparator;
//! show stripes
QCheckBox *showStripes;
//! overwrite colors
QCheckBox *overwriteColors;
//! size grip
QCheckBox *drawSizeGrip;
//! nitrogen shadow
QCheckBox *useOxygenShadows;
//! about nitrogen
QPushButton *aboutNitrogen;
//! raise exceptions
QPushButton *showExceptions;
};
};
#endif

View file

@ -0,0 +1,242 @@
// $Id: nitrogenexceptiondialog.cpp,v 1.12 2009/07/05 16:15:31 hpereira Exp $
/******************************************************************************
*
* Copyright (C) 2002 Hugo PEREIRA <mailto: hugo.pereira@free.fr>
*
* This 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 software 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
* software; if not, write to the Free Software Foundation, Inc., 59 Temple
* Place, Suite 330, Boston, MA 02111-1307 USA
*
*
*******************************************************************************/
#include <QGroupBox>
#include <QLabel>
#include <QLayout>
#include <KLocale>
#include "nitrogenexceptiondialog.h"
namespace Nitrogen
{
//___________________________________________
NitrogenExceptionDialog::NitrogenExceptionDialog( QWidget* parent ):
KDialog( parent )
{
// define buttons
setButtons( Ok|Cancel );
showButtonSeparator( true );
// main widget
QWidget* widget = new QWidget( this );
setMainWidget( widget );
widget->setLayout( new QVBoxLayout() );
widget->layout()->setSpacing(5);
widget->layout()->setMargin(0);
// exception definition
QGroupBox* box;
widget->layout()->addWidget( box = new QGroupBox( tr2i18n( "Definition" ), widget ) );
QGridLayout* gridLayout = new QGridLayout();
gridLayout->setSpacing(5);
gridLayout->setMargin(5);
box->setLayout( gridLayout );
QLabel *label;
// exception type
gridLayout->addWidget( label = new QLabel( tr2i18n( "Exception type: " ), box ), 0, 0, 1, 1 );
gridLayout->addWidget( type_combobox_ = new QComboBox(box), 0, 1, 1, 1 );
type_combobox_->insertItems(0, QStringList()
<< NitrogenException::typeName( NitrogenException::WindowClassName )
<< NitrogenException::typeName( NitrogenException::WindowTitle ) );
type_combobox_->setToolTip( tr2i18n(
"Select here the window caracteristic used to \n"
"identify windows to which the exception apply." ) );
label->setAlignment( Qt::AlignRight );
// regular expression
gridLayout->addWidget( label = new QLabel( tr2i18n( "Regular expression to match: " ), box ), 1, 0, 1, 1 );
gridLayout->addWidget( editor_ = new KLineEdit( box ), 1, 1, 1, 1 );
editor_->setClearButtonShown( true );
editor_->setToolTip( tr2i18n(
"Type here the regular expression used to \n"
"identify windows to which the exception apply." ) );
label->setAlignment( Qt::AlignRight );
// decoration flags
widget->layout()->addWidget( box = new QGroupBox( tr2i18n( "Decoration" ), widget ) );
gridLayout = new QGridLayout();
gridLayout->setSpacing(5);
gridLayout->setMargin(5);
box->setLayout( gridLayout );
QCheckBox* checkbox;
// border size
gridLayout->addWidget( checkbox = new QCheckBox( tr2i18n("Border size:" ), box ), 2, 0, 1, 1 );
gridLayout->addWidget( frame_border_combobox_ = new QComboBox(box), 2, 1, 1, 1 );
frame_border_combobox_->insertItems(0, QStringList()
<< NitrogenException::frameBorderName( NitrogenException::BorderNone )
<< NitrogenException::frameBorderName( NitrogenException::BorderTiny )
<< NitrogenException::frameBorderName( NitrogenException::BorderSmall )
<< NitrogenException::frameBorderName( NitrogenException::BorderDefault )
<< NitrogenException::frameBorderName( NitrogenException::BorderLarge ) );
frame_border_combobox_->setEnabled( false );
checkboxes_.insert( std::make_pair( NitrogenException::FrameBorder, checkbox ) );
checkbox->setToolTip( "If checked, specified frame border is used in place of default value." );
connect( checkbox, SIGNAL( toggled( bool ) ), frame_border_combobox_, SLOT( setEnabled( bool ) ) );
// blend color
gridLayout->addWidget( checkbox = new QCheckBox( tr2i18n("Title bar blending:" ), box ), 3, 0, 1, 1 );
gridLayout->addWidget( blend_combobox_ = new QComboBox(box), 3, 1, 1, 1 );
blend_combobox_->insertItems(0, QStringList()
<< NitrogenException::blendColorName( NitrogenException::NoBlending )
<< NitrogenException::blendColorName( NitrogenException::RadialBlending ) );
blend_combobox_->setEnabled( false );
checkboxes_.insert( std::make_pair( NitrogenException::BlendColor, checkbox ) );
checkbox->setToolTip( "If checked, specified blending color is used in title bar in place of default value." );
connect( checkbox, SIGNAL( toggled( bool ) ), blend_combobox_, SLOT( setEnabled( bool ) ) );
// separator
gridLayout->addWidget( label = new QLabel( tr2i18n( "Draw separator :" ), box ), 4, 0, 1, 1 );
gridLayout->addWidget( draw_separator_combobox_ = new ComboBox( box ), 4, 1, 1, 1 );
label->setAlignment( Qt::AlignRight|Qt::AlignVCenter );
// stripes
gridLayout->addWidget( label = new QLabel( tr2i18n( "Show stripes :" ), box ), 5, 0, 1, 1 );
gridLayout->addWidget( show_stripes_combobox_ = new ComboBox( box ), 5, 1, 1, 1 );
label->setAlignment( Qt::AlignRight|Qt::AlignVCenter );
// overwrite colors
gridLayout->addWidget( label = new QLabel( tr2i18n( "Overwrite default title bar colors:" ), box ), 6, 0, 1, 1 );
gridLayout->addWidget( overwrite_colors_combobox_ = new ComboBox( box ), 6, 1, 1, 1 );
label->setAlignment( Qt::AlignRight|Qt::AlignVCenter );
// size grip
gridLayout->addWidget( label = new QLabel( tr2i18n( "Draw size grip :" ), box ), 7, 0, 1, 1 );
gridLayout->addWidget( draw_size_grip_combobox_ = new ComboBox( box ), 7, 1, 1, 1 );
label->setAlignment( Qt::AlignRight|Qt::AlignVCenter );
}
//___________________________________________
void NitrogenExceptionDialog::setException( NitrogenException exception )
{
// store exception internally
exception_ = exception;
// type
type_combobox_->setCurrentIndex( type_combobox_->findText( exception.typeName() ) );
// regular expression
editor_->setText( exception.regExp().pattern() );
// border size
frame_border_combobox_->setCurrentIndex( frame_border_combobox_->findText( exception.frameBorderName() ) );
// blend color
blend_combobox_->setCurrentIndex( blend_combobox_->findText( exception.blendColorName() ) );
// flags
draw_separator_combobox_->setValue( exception.mask() & NitrogenException::DrawSeparator, exception.drawSeparator() );
show_stripes_combobox_->setValue( exception.mask() & NitrogenException::ShowStripes, exception.showStripes() );
overwrite_colors_combobox_->setValue( exception.mask() & NitrogenException::OverwriteColors, exception.overwriteColors() );
draw_size_grip_combobox_->setValue( exception.mask() & NitrogenException::DrawSizeGrip, exception.drawSizeGrip() );
// mask
for( CheckBoxMap::iterator iter = checkboxes_.begin(); iter != checkboxes_.end(); iter++ )
{ iter->second->setChecked( exception.mask() & iter->first ); }
}
//___________________________________________
NitrogenException NitrogenExceptionDialog::exception( void ) const
{
NitrogenException exception( exception_ );
exception.setType( NitrogenException::type( type_combobox_->currentText() ) );
exception.regExp().setPattern( editor_->text() );
exception.setFrameBorder( NitrogenException::frameBorder( frame_border_combobox_->currentText() ) );
exception.setBlendColor( NitrogenException::blendColor( blend_combobox_->currentText() ) );
// mask
unsigned int mask = NitrogenException::None;
for( CheckBoxMap::const_iterator iter = checkboxes_.begin(); iter != checkboxes_.end(); iter++ )
{ if( iter->second->isChecked() ) mask |= iter->first; }
// separator
if( !draw_separator_combobox_->isDefault() )
{
mask |= NitrogenException::DrawSeparator;
exception.setDrawSeparator( draw_separator_combobox_->isChecked() );
}
// stripes
if( !show_stripes_combobox_->isDefault() )
{
mask |= NitrogenException::ShowStripes;
exception.setShowStripes( show_stripes_combobox_->isChecked() );
}
// overwrite colors
if( !overwrite_colors_combobox_->isDefault() )
{
mask |= NitrogenException::OverwriteColors;
exception.setOverwriteColors( overwrite_colors_combobox_->isChecked() );
}
// size grip
if( !draw_size_grip_combobox_->isDefault() )
{
mask |= NitrogenException::DrawSizeGrip;
exception.setDrawSizeGrip( draw_size_grip_combobox_->isChecked() );
}
exception.setMask( mask );
return exception;
}
//___________________________________________
const QString NitrogenExceptionDialog::ComboBox::Default( "Default" );
const QString NitrogenExceptionDialog::ComboBox::Yes( "Yes" );
const QString NitrogenExceptionDialog::ComboBox::No( "No" );
//___________________________________________
NitrogenExceptionDialog::ComboBox::ComboBox( QWidget* parent ):
QComboBox( parent )
{ insertItems( 0, QStringList() << Default << Yes << No ); }
//___________________________________________
void NitrogenExceptionDialog::ComboBox::setValue( bool enabled, bool checked )
{
if( !enabled ) setCurrentIndex( findText( Default ) );
else setCurrentIndex( findText( checked ? Yes:No ) );
}
//___________________________________________
bool NitrogenExceptionDialog::ComboBox::isDefault( void ) const
{ return currentText() == Default; }
//___________________________________________
bool NitrogenExceptionDialog::ComboBox::isChecked( void ) const
{ return currentText() == Yes; }
};

View file

@ -0,0 +1,117 @@
#ifndef nitrogenexceptiondialog_h
#define nitrogenexceptiondialog_h
// $Id: nitrogenexceptiondialog.h,v 1.6 2009/07/05 16:15:31 hpereira Exp $
/******************************************************************************
*
* Copyright (C) 2002 Hugo PEREIRA <mailto: hugo.pereira@free.fr>
*
* This 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 software 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
* software; if not, write to the Free Software Foundation, Inc., 59 Temple
* Place, Suite 330, Boston, MA 02111-1307 USA
*
*
*******************************************************************************/
#include <KDialog>
#include <KLineEdit>
#include <QComboBox>
#include <QCheckBox>
#include <map>
#include "../nitrogenexception.h"
namespace Nitrogen
{
//! nitrogen exceptions list
class NitrogenExceptionDialog: public KDialog
{
public:
//! constructor
NitrogenExceptionDialog( QWidget* parent );
//! set exception
void setException( NitrogenException );
//! get exception
NitrogenException exception( void ) const;
private:
//! line editor
KLineEdit* editor_;
//! blend combobox
QComboBox* type_combobox_;
//! border size
QComboBox* frame_border_combobox_;
//! blend combobox
QComboBox* blend_combobox_;
//! map mask and checkbox
typedef std::map< NitrogenException::AttributesMask, QCheckBox*> CheckBoxMap;
//! map mask and checkbox
CheckBoxMap checkboxes_;
//! internal exception
NitrogenException exception_;
//! local combobox to handle configuration checkboxes
class ComboBox: public QComboBox
{
public:
static const QString Default;
static const QString Yes;
static const QString No;
//! constructor
ComboBox( QWidget* parent );
//! set value
void setValue( bool enabled, bool checked );
//! true if default is selected
bool isDefault( void ) const;
//! true if yes is checkd
bool isChecked( void ) const;
};
//! draw separator
ComboBox* draw_separator_combobox_;
//! stripes
ComboBox* show_stripes_combobox_;
//! overwrite colors
ComboBox* overwrite_colors_combobox_;
//! size grip
ComboBox* draw_size_grip_combobox_;
};
};
#endif

View file

@ -0,0 +1,346 @@
// $Id: nitrogenexceptionlistdialog.cpp,v 1.9 2009/05/25 21:05:19 hpereira Exp $
/******************************************************************************
*
* Copyright (C) 2002 Hugo PEREIRA <mailto: hugo.pereira@free.fr>
*
* This 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 software 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
* software; if not, write to the Free Software Foundation, Inc., 59 Temple
* Place, Suite 330, Boston, MA 02111-1307 USA
*
*
*******************************************************************************/
/*!
\file NitrogenExceptionListDialog.cpp
\brief Generic dialog with a FileInfo list
\author Hugo Pereira
\version $Revision: 1.9 $
\date $Date: 2009/05/25 21:05:19 $
*/
#include <QLayout>
#include <KLocale>
#include <KMessageBox>
#include "nitrogenexceptiondialog.h"
#include "nitrogenexceptionlistdialog.h"
#include "nitrogenexceptionlistdialog.moc"
//__________________________________________________________
namespace Nitrogen
{
//__________________________________________________________
NitrogenExceptionListDialog::NitrogenExceptionListDialog( QWidget* parent, NitrogenConfiguration default_configuration ):
KDialog( parent ),
default_configuration_( default_configuration )
{
// define buttons
setButtons( Ok|Cancel );
// main widget
QWidget* widget = new QWidget( this );
setMainWidget( widget );
// layout
QHBoxLayout* h_layout = new QHBoxLayout();
h_layout->setMargin(0);
h_layout->setSpacing(5);
widget->setLayout( h_layout );
// list
h_layout->addWidget( list_ = new QTreeView( widget ) );
_list().setAllColumnsShowFocus( true );
_list().setRootIsDecorated( false );
_list().setSortingEnabled( false );
_list().setModel( &_model() );
_list().sortByColumn( NitrogenExceptionModel::TYPE );
// button layout
QVBoxLayout* v_layout = new QVBoxLayout();
v_layout->setMargin(0);
v_layout->setSpacing(5);
h_layout->addLayout( v_layout );
KIconLoader* icon_loader = KIconLoader::global();
v_layout->addWidget( up_button_ = new KPushButton(
KIcon( "arrow-up", icon_loader ),
tr2i18n("Move &Up"), widget ) );
v_layout->addWidget( down_button_ = new KPushButton(
KIcon( "arrow-down", icon_loader ),
tr2i18n("Move &Down"), widget ) );
v_layout->addWidget( add_button_ = new KPushButton(
KIcon( "list-add", icon_loader ),
tr2i18n("&Add"), widget ) );
v_layout->addWidget( remove_button_ = new KPushButton(
KIcon( "list-remove", icon_loader ),
tr2i18n("&Remove"), widget ) );
v_layout->addWidget( edit_button_ = new KPushButton(
KIcon( "edit-rename", icon_loader ),
tr2i18n("&Edit"), widget ) );
v_layout->addStretch();
connect( add_button_, SIGNAL( clicked() ), SLOT( _add() ) );
connect( edit_button_, SIGNAL( clicked() ), SLOT( _edit() ) );
connect( remove_button_, SIGNAL( clicked() ), SLOT( _remove() ) );
connect( up_button_, SIGNAL( clicked() ), SLOT( _up() ) );
connect( down_button_, SIGNAL( clicked() ), SLOT( _down() ) );
connect( &_list(), SIGNAL( activated( const QModelIndex& ) ), SLOT( _edit() ) );
connect( &_list(), SIGNAL( clicked( const QModelIndex& ) ), SLOT( _toggle( const QModelIndex& ) ) );
connect( _list().selectionModel(), SIGNAL( selectionChanged(const QItemSelection &, const QItemSelection &) ), SLOT( _updateButtons() ) );
resize( 500, 250 );
_updateButtons();
_resizeColumns();
}
//__________________________________________________________
void NitrogenExceptionListDialog::setExceptions( const NitrogenExceptionList& exceptions )
{
_model().set( NitrogenExceptionModel::List( exceptions.begin(), exceptions.end() ) );
_resizeColumns();
}
//__________________________________________________________
NitrogenExceptionList NitrogenExceptionListDialog::exceptions( void ) const
{
NitrogenExceptionModel::List exceptions( _model().get() );
NitrogenExceptionList out;
for( NitrogenExceptionModel::List::const_iterator iter = exceptions.begin(); iter != exceptions.end(); iter++ )
{ out.push_back( *iter ); }
return out;
}
//__________________________________________________________
void NitrogenExceptionListDialog::_updateButtons( void )
{
bool has_selection( !_list().selectionModel()->selectedRows().empty() );
remove_button_->setEnabled( has_selection );
edit_button_->setEnabled( has_selection );
up_button_->setEnabled( has_selection && !_list().selectionModel()->isRowSelected( 0, QModelIndex() ) );
down_button_->setEnabled( has_selection && !_list().selectionModel()->isRowSelected( _model().rowCount()-1, QModelIndex() ) );
}
//_______________________________________________________
void NitrogenExceptionListDialog::_add( void )
{
// map dialog
NitrogenExceptionDialog dialog( this );
dialog.setException( default_configuration_ );
if( dialog.exec() == QDialog::Rejected ) return;
// retrieve exception and check
NitrogenException exception( dialog.exception() );
if( !_checkException( exception ) ) return;
// create new item
_model().add( exception );
// make sure item is selected
QModelIndex index( _model().index( exception ) );
if( index != _list().selectionModel()->currentIndex() )
{
_list().selectionModel()->select( index, QItemSelectionModel::Clear|QItemSelectionModel::Select|QItemSelectionModel::Rows );
_list().selectionModel()->setCurrentIndex( index, QItemSelectionModel::Current|QItemSelectionModel::Rows );
}
_resizeColumns();
return;
}
//_______________________________________________________
void NitrogenExceptionListDialog::_edit( void )
{
// retrieve selection
QModelIndex current( _list().selectionModel()->currentIndex() );
if( !current.isValid() ) return;
NitrogenException& exception( _model().get( current ) );
// create dialog
NitrogenExceptionDialog dialog( this );
dialog.setException( exception );
// map dialog
if( dialog.exec() == QDialog::Rejected ) return;
NitrogenException new_exception = dialog.exception();
if( !_checkException( new_exception ) ) return;
*&exception = new_exception;
_resizeColumns();
return;
}
//_______________________________________________________
void NitrogenExceptionListDialog::_remove( void )
{
// remove
_model().remove( _model().get( _list().selectionModel()->selectedRows() ) );
_resizeColumns();
return;
}
//_______________________________________________________
void NitrogenExceptionListDialog::_toggle( const QModelIndex& index )
{
if( !index.isValid() ) return;
if( index.column() != NitrogenExceptionModel::ENABLED ) return;
// get matching exception
NitrogenException& exception( _model().get( index ) );
exception.setEnabled( !exception.enabled() );
_model().add( exception );
}
//_______________________________________________________
void NitrogenExceptionListDialog::_up( void )
{
NitrogenExceptionModel::List selection( _model().get( _list().selectionModel()->selectedRows() ) );
if( selection.empty() ) { return; }
// retrieve selected indexes in list and store in model
QModelIndexList selected_indexes( _list().selectionModel()->selectedRows() );
NitrogenExceptionModel::List selected_exceptions( _model().get( selected_indexes ) );
NitrogenExceptionModel::List current_exceptions( _model().get() );
NitrogenExceptionModel::List new_exceptions;
for( NitrogenExceptionModel::List::const_iterator iter = current_exceptions.begin(); iter != current_exceptions.end(); iter++ )
{
// check if new list is not empty, current index is selected and last index is not.
// if yes, move.
if(
!( new_exceptions.empty() ||
selected_indexes.indexOf( _model().index( *iter ) ) == -1 ||
selected_indexes.indexOf( _model().index( new_exceptions.back() ) ) != -1
) )
{
NitrogenException last( new_exceptions.back() );
new_exceptions.pop_back();
new_exceptions.push_back( *iter );
new_exceptions.push_back( last );
} else new_exceptions.push_back( *iter );
}
_model().set( new_exceptions );
// restore selection
_list().selectionModel()->select( _model().index( selected_exceptions.front() ), QItemSelectionModel::Clear|QItemSelectionModel::Select|QItemSelectionModel::Rows );
for( NitrogenExceptionModel::List::const_iterator iter = selected_exceptions.begin(); iter != selected_exceptions.end(); iter++ )
{ _list().selectionModel()->select( _model().index( *iter ), QItemSelectionModel::Select|QItemSelectionModel::Rows ); }
return;
}
//_______________________________________________________
void NitrogenExceptionListDialog::_down( void )
{
NitrogenExceptionModel::List selection( _model().get( _list().selectionModel()->selectedRows() ) );
if( selection.empty() )
{ return; }
// retrieve selected indexes in list and store in model
QModelIndexList selected_indexes( _list().selectionModel()->selectedIndexes() );
NitrogenExceptionModel::List selected_exceptions( _model().get( selected_indexes ) );
NitrogenExceptionModel::List current_exceptions( _model().get() );
NitrogenExceptionModel::List new_exceptions;
for( NitrogenExceptionModel::List::reverse_iterator iter = current_exceptions.rbegin(); iter != current_exceptions.rend(); iter++ )
{
// check if new list is not empty, current index is selected and last index is not.
// if yes, move.
if(
!( new_exceptions.empty() ||
selected_indexes.indexOf( _model().index( *iter ) ) == -1 ||
selected_indexes.indexOf( _model().index( new_exceptions.back() ) ) != -1
) )
{
NitrogenException last( new_exceptions.back() );
new_exceptions.pop_back();
new_exceptions.push_back( *iter );
new_exceptions.push_back( last );
} else new_exceptions.push_back( *iter );
}
_model().set( NitrogenExceptionModel::List( new_exceptions.rbegin(), new_exceptions.rend() ) );
// restore selection
_list().selectionModel()->select( _model().index( selected_exceptions.front() ), QItemSelectionModel::Clear|QItemSelectionModel::Select|QItemSelectionModel::Rows );
for( NitrogenExceptionModel::List::const_iterator iter = selected_exceptions.begin(); iter != selected_exceptions.end(); iter++ )
{ _list().selectionModel()->select( _model().index( *iter ), QItemSelectionModel::Select|QItemSelectionModel::Rows ); }
return;
}
//_______________________________________________________
void NitrogenExceptionListDialog::_resizeColumns( void ) const
{
_list().resizeColumnToContents( NitrogenExceptionModel::ENABLED );
_list().resizeColumnToContents( NitrogenExceptionModel::TYPE );
_list().resizeColumnToContents( NitrogenExceptionModel::REGEXP );
}
//_______________________________________________________
bool NitrogenExceptionListDialog::_checkException( NitrogenException& exception )
{
while( !exception.regExp().isValid() )
{
KMessageBox::error( this, "Regular Expression syntax is incorrect" );
NitrogenExceptionDialog dialog( this );
dialog.setException( exception );
if( dialog.exec() == QDialog::Rejected ) return false;
exception = dialog.exception();
}
return true;
}
};

View file

@ -0,0 +1,137 @@
#ifndef _NitrogenExceptionListDialog_h_
#define _NitrogenExceptionListDialog_h_
// $Id: nitrogenexceptionlistdialog.h,v 1.5 2009/04/02 03:48:34 hpereira Exp $
/******************************************************************************
*
* Copyright (C) 2002 Hugo PEREIRA <mailto: hugo.pereira@free.fr>
*
* This 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 software 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
* software; if not, write to the Free Software Foundation, Inc., 59 Temple
* Place, Suite 330, Boston, MA 02111-1307 USA
*
*
*******************************************************************************/
/*!
\file NitrogenExceptionListDialog.h
\brief Generic dialog with a FileInfo list
\author Hugo Pereira
\version $Revision: 1.5 $
\date $Date: 2009/04/02 03:48:34 $
*/
#include <KPushButton>
#include <QTreeView>
#include <KDialog>
#include "nitrogenexceptionmodel.h"
#include "../nitrogenexceptionlist.h"
//! QDialog used to commit selected files
namespace Nitrogen
{
class NitrogenExceptionListDialog: public KDialog
{
//! Qt meta object
Q_OBJECT
public:
//! constructor
NitrogenExceptionListDialog( QWidget*, NitrogenConfiguration default_configuration = NitrogenConfiguration() );
//! set exceptions
void setExceptions( const NitrogenExceptionList& );
//! get exceptions
NitrogenExceptionList exceptions( void ) const;
protected:
//! list
QTreeView& _list() const
{ return *list_; }
//! model
const NitrogenExceptionModel& _model() const
{ return model_; }
//! model
NitrogenExceptionModel& _model()
{ return model_; }
protected slots:
//! update button states
virtual void _updateButtons( void );
//! add
virtual void _add( void );
//! edit
virtual void _edit( void );
//! remove
virtual void _remove( void );
//! toggle
virtual void _toggle( const QModelIndex& );
//! move up
virtual void _up( void );
//! move down
virtual void _down( void );
private:
//! resize columns
void _resizeColumns( void ) const;
//! check exception
bool _checkException( NitrogenException& );
//! default configuration
NitrogenConfiguration default_configuration_;
//! list of files
QTreeView* list_;
//! model
NitrogenExceptionModel model_;
//! add
KPushButton* add_button_;
//! edit
KPushButton* edit_button_;
//! remove
KPushButton* remove_button_;
//! move up
KPushButton* up_button_;
//! move down
KPushButton* down_button_;
};
};
#endif

View file

@ -0,0 +1,99 @@
// $Id: nitrogenexceptionmodel.cpp,v 1.10 2009/05/25 21:05:19 hpereira Exp $
/******************************************************************************
*
* Copyright (C) 2002 Hugo PEREIRA <mailto: hugo.pereira@free.fr>
*
* This 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 software 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
* software; if not, write to the Free Software Foundation, Inc., 59 Temple
* Place, Suite 330, Boston, MA 02111-1307 USA
*
*
*******************************************************************************/
/*!
\file NitrogenExceptionModel.cpp
\brief model for object exceptions
\author Hugo Pereira
\version $Revision: 1.10 $
\date $Date: 2009/05/25 21:05:19 $
*/
#include <QPalette>
#include "nitrogenexceptionmodel.h"
namespace Nitrogen
{
//_______________________________________________
const QString NitrogenExceptionModel::column_titles_[ NitrogenExceptionModel::n_columns ] =
{
"",
"Exception Type",
"Regular Expression"
};
//__________________________________________________________________
QVariant NitrogenExceptionModel::data( const QModelIndex& index, int role ) const
{
// check index, role and column
if( !index.isValid() ) return QVariant();
// retrieve associated file info
const NitrogenException& exception( get(index) );
// return text associated to file and column
if( role == Qt::DisplayRole )
{
switch( index.column() )
{
case TYPE: return exception.typeName();
case REGEXP: return exception.regExp().pattern();
default: return QVariant();
break;
}
} else if( role == Qt::CheckStateRole && index.column() == ENABLED ) {
return exception.enabled() ? Qt::Checked : Qt::Unchecked;
} else if( role == Qt::ToolTipRole && index.column() == ENABLED ) {
return "Enable/disable this exception";
}
return QVariant();
}
//__________________________________________________________________
QVariant NitrogenExceptionModel::headerData(int section, Qt::Orientation orientation, int role) const
{
if(
orientation == Qt::Horizontal &&
role == Qt::DisplayRole &&
section >= 0 &&
section < n_columns )
{ return column_titles_[section]; }
// return empty
return QVariant();
}
};

View file

@ -0,0 +1,88 @@
#ifndef _nitrogenexceptionmodel_h_
#define _nitrogenexceptionmodel_h_
// $Id: nitrogenexceptionmodel.h,v 1.8 2009/05/25 21:05:19 hpereira Exp $
/******************************************************************************
*
* Copyright (C) 2002 Hugo PEREIRA <mailto: hugo.pereira@free.fr>
*
* This 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 software 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
* software; if not, write to the Free Software Foundation, Inc., 59 Temple
* Place, Suite 330, Boston, MA 02111-1307 USA
*
*
*******************************************************************************/
/*!
\file NitrogenExceptionModel.h
\brief model for object counters
\author Hugo Pereira
\version $Revision: 1.8 $
\date $Date: 2009/05/25 21:05:19 $
*/
#include "listmodel.h"
#include "../nitrogenexception.h"
namespace Nitrogen
{
//! qlistview for object counters
class NitrogenExceptionModel: public ListModel<NitrogenException>
{
public:
//! number of columns
enum { n_columns = 3 };
//! column type enumeration
enum ColumnType {
ENABLED,
TYPE,
REGEXP
};
//!@name methods reimplemented from base class
//@{
// return data for a given index
virtual QVariant data(const QModelIndex &index, int role) const;
//! header data
virtual QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const;
//! number of columns for a given index
virtual int columnCount(const QModelIndex& ) const
{ return n_columns; }
//@}
protected:
//! sort
virtual void _sort( int, Qt::SortOrder )
{}
private:
//! column titles
static const QString column_titles_[ n_columns ];
};
};
#endif

View file

@ -0,0 +1,666 @@
// $Id: helper.cpp,v 1.20 2009/06/24 02:51:35 hpereira Exp $
/*
* Copyright 2008 Long Huynh Huu <long.upcase@googlemail.com>
* Copyright 2007 Matthew Woehlke <mw_triad@users.sourceforge.net>
* Copyright 2007 Casper Boemann <cbr@boemann.dk>
* Copyright 2007 Fredrik Höglund <fredrik@kde.org>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License version 2 as published by the Free Software Foundation.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#include <KGlobalSettings>
#include <KColorUtils>
#include <KColorScheme>
#include <QWidget>
#include <QPainter>
#include <math.h>
#include "helper.h"
const double NitrogenHelper::_shadowGain = 1.5;
//_______________________________________________________________________________________________________________
NitrogenHelper::NitrogenHelper(const QByteArray &componentName):
_componentData(componentName, 0, KComponentData::SkipMainComponentRegistration)
{
_config = _componentData.config();
_contrast = KGlobalSettings::contrastF(_config);
_bgcontrast = 0.3;
m_backgroundCache.setMaxCost(64);
m_windecoButtonCache.setMaxCost(64);
m_windecoButtonGlowCache.setMaxCost(64);
}
//_______________________________________________________________________________________________________________
KSharedConfigPtr NitrogenHelper::config() const
{ return _config; }
//_______________________________________________________________________________________________________________
void NitrogenHelper::reloadConfig()
{
double old_contrast = _contrast;
_config->reparseConfiguration();
_contrast = KGlobalSettings::contrastF(_config);
// contrast changed, invalidate our caches
if (_contrast != old_contrast) invalidateCaches();
}
//_______________________________________________________________________________________________________________
void NitrogenHelper::renderWindowBackground(
QPainter *p,
const QRect &clipRect,
const QWidget *widget,
const QPalette & pal,
int gradient_shift )
{
if (clipRect.isValid()) {
p->save();
p->setClipRegion(clipRect,Qt::IntersectClip);
}
QRect r = widget->window()->rect();
// use an additional pixmap for buffering
// to avoid flicker observe when painting large (wide) windows
QPixmap pixmap( r.size() );
{
QPainter p( &pixmap );
if (clipRect.isValid()) p.setClipRegion(clipRect);
// get coordinates relative to the client area
const QWidget* w = widget;
int x = 0;
int y = 0;
// get window
while (!w->isWindow())
{
x += w->geometry().x();
y += w->geometry().y();
w = w->window();
}
QColor color = pal.color( w->backgroundRole() );
int splitY = qMin(300, 3*r.height()/4);
QRect upperRect = QRect(-x, -y, r.width(), splitY);
QPixmap tile = verticalGradient(color, splitY);
p.drawTiledPixmap(upperRect, tile);
QRect lowerRect = QRect(-x, splitY-y, r.width(), r.height() - splitY);
p.fillRect(lowerRect, backgroundBottomColor(color));
int radialW = qMin(600, r.width());
// on first paint the frame may not have been done yet, so just fixate it
QRect radialRect = QRect((r.width() - radialW)/2 - x, -y, radialW, 64+gradient_shift);
if (clipRect.intersects(radialRect))
{
tile = radialGradient(color, radialW, gradient_shift );
p.drawPixmap(radialRect, tile);
}
}
p->drawPixmap( r, pixmap );
if (clipRect.isValid()) p->restore();
}
//_______________________________________________________________________________________________________________
void NitrogenHelper::invalidateCaches()
{
m_backgroundCache.clear();
m_windecoButtonCache.clear();
m_windecoButtonGlowCache.clear();
}
//_______________________________________________________________________________________________________________
bool NitrogenHelper::lowThreshold(const QColor &color)
{
QColor darker = KColorScheme::shade(color, KColorScheme::MidShade, 0.5);
return KColorUtils::luma(darker) > KColorUtils::luma(color);
}
//_______________________________________________________________________________________________________________
QColor NitrogenHelper::alphaColor(QColor color, double alpha)
{
if (alpha < 1.0) color.setAlphaF( qMax(0.0, alpha) * color.alphaF() );
return color;
}
//_______________________________________________________________________________________________________________
QColor NitrogenHelper::backgroundRadialColor(const QColor &color) const
{
return lowThreshold(color) ?
KColorScheme::shade(color, KColorScheme::LightShade, 0.0):
KColorScheme::shade(color, KColorScheme::LightShade, _bgcontrast);
}
//_______________________________________________________________________________________________________________
QColor NitrogenHelper::backgroundTopColor(const QColor &color) const
{
return lowThreshold(color) ?
KColorScheme::shade(color, KColorScheme::MidlightShade, 0.0):
KColorScheme::shade(color, KColorScheme::MidlightShade, _bgcontrast);
}
//_______________________________________________________________________________________________________________
QColor NitrogenHelper::backgroundBottomColor(const QColor &color) const
{
QColor midColor = KColorScheme::shade(color, KColorScheme::MidShade, 0.0);
if (lowThreshold(color)) return midColor;
double by = KColorUtils::luma(color), my = KColorUtils::luma(midColor);
return KColorUtils::shade(color, (my - by) * _bgcontrast);
}
//_______________________________________________________________________________________________________________
QColor NitrogenHelper::calcLightColor(const QColor &color) const
{ return KColorScheme::shade(color, KColorScheme::LightShade, _contrast); }
//_______________________________________________________________________________________________________________
QColor NitrogenHelper::calcDarkColor(const QColor &color) const
{
return lowThreshold(color) ?
KColorUtils::mix(calcLightColor(color), color, 0.2 + 0.8 * _contrast):
KColorScheme::shade(color, KColorScheme::MidShade, _contrast);
}
//_______________________________________________________________________________________________________________
QColor NitrogenHelper::calcShadowColor(const QColor &color) const
{
return
KColorScheme::shade(KColorUtils::mix(QColor(255,255,255),color, color.alpha()*(1/255.0)),
KColorScheme::ShadowShade, _contrast);
}
//_______________________________________________________________________________________________________________
QColor NitrogenHelper::backgroundColor(const QColor &color, int height, int y)
{
double h = height * 0.5;
if (y > height>>1) {
double a = double(y) / h;
return KColorUtils::mix(backgroundTopColor(color), color, a);
} else {
double a = (double(y) - h) / h;
return KColorUtils::mix(color, backgroundBottomColor(color), a);
}
}
//_______________________________________________________________________________________________________________
QPixmap NitrogenHelper::verticalGradient(const QColor &color, int height)
{
quint64 key = (quint64(color.rgba()) << 32) | height | 0x8000;
QPixmap *pixmap = m_backgroundCache.object(key);
if (!pixmap)
{
pixmap = new QPixmap(32, height);
QLinearGradient gradient(0, 0, 0, height);
gradient.setColorAt(0.0, backgroundTopColor(color));
gradient.setColorAt(0.5, color);
gradient.setColorAt(1.0, backgroundBottomColor(color));
QPainter p(pixmap);
p.setCompositionMode(QPainter::CompositionMode_Source);
p.fillRect(pixmap->rect(), gradient);
m_backgroundCache.insert(key, pixmap);
}
return *pixmap;
}
//_______________________________________________________________________________________________________________
QPixmap NitrogenHelper::radialGradient(const QColor &color, int width, int y_offset )
{
quint64 key = (quint64(color.rgba()) << 32) | width | 0xb000;
QPixmap *pixmap = m_backgroundCache.object(key);
if (!pixmap)
{
pixmap = new QPixmap(width, 64+y_offset);
pixmap->fill(Qt::transparent);
QColor radialColor = backgroundRadialColor(color);
// create gradient
QRadialGradient gradient(64, 0, 64);
radialColor.setAlpha(255); gradient.setColorAt(0, radialColor);
radialColor.setAlpha(101); gradient.setColorAt(0.5, radialColor);
radialColor.setAlpha(37); gradient.setColorAt(0.75, radialColor);
radialColor.setAlpha(0); gradient.setColorAt(1, radialColor);
// need some tr
QPainter p(pixmap);
p.translate( 0, y_offset );
p.scale(width/128.0,1);
p.fillRect(QRect(0,0,128,64+y_offset).translated(0, -y_offset ), gradient);
m_backgroundCache.insert(key, pixmap);
}
return *pixmap;
}
//_______________________________________________________________________________________________________________
void NitrogenHelper::drawShadow(QPainter &p, const QColor &color, int size) const
{
double m = double(size-2)*0.5;
const double offset = 0.8;
double k0 = (m-4.0) / m;
QRadialGradient shadowGradient(m+1.0, m+offset+1.0, m);
for (int i = 0; i < 8; i++) { // sinusoidal gradient
double k1 = (k0 * double(8 - i) + double(i)) * 0.125;
double a = (cos(3.14159 * i * 0.125) + 1.0) * 0.25;
shadowGradient.setColorAt(k1, alphaColor(color, a * _shadowGain));
}
shadowGradient.setColorAt(1.0, alphaColor(color, 0.0));
p.setBrush(shadowGradient);
p.drawEllipse(QRectF(0, 0, size, size));
}
//_______________________________________________________________________________________________________________
QLinearGradient NitrogenHelper::decoGradient(const QRect &r, const QColor &color)
{
QColor light = KColorScheme::shade(color, KColorScheme::LightShade, _contrast * 0.7);
QColor dark = KColorScheme::shade(color, KColorScheme::DarkShade, _contrast * 0.7);
double y = KColorUtils::luma(color);
double yd = KColorUtils::luma(dark);
double yl = KColorUtils::luma(light);
QLinearGradient gradient(r.topLeft(), r.bottomLeft());
if (yd > y)
{
gradient.setColorAt(0.2, color);
gradient.setColorAt(0.8, dark);
}
else if (yl < y)
{
gradient.setColorAt(0.2, light);
gradient.setColorAt(0.8, color);
}
else
{
gradient.setColorAt(0.2, dark);
gradient.setColorAt(0.5, color);
gradient.setColorAt(0.8, light);
}
return gradient;
}
//_______________________________________________________________________________________________________________
QPixmap NitrogenHelper::windecoButton(const QColor &color, bool pressed, Nitrogen::NitrogenConfiguration::ButtonType type, int size)
{
quint64 key = (quint64(color.rgba()) << 32) | (size << 1) | pressed;
QPixmap *pixmap = m_windecoButtonCache.object(key);
if (!pixmap)
{
pixmap = new QPixmap(size, size);
pixmap->fill(Qt::transparent);
QPainter p(pixmap);
p.setRenderHints(QPainter::Antialiasing);
p.setPen(Qt::NoPen);
double u = double(size)/22.0;
if( type == Nitrogen::NitrogenConfiguration::ButtonKde42 )
{
QColor light = calcLightColor(color);
QColor dark = alphaColor(calcShadowColor(color), 0.6);
QRectF rect(0.0, 0.0, size, size);
QRectF buttonRect = rect.adjusted(3*u,3*u,-3*u,-3*u);
p.setBrush(color);
p.drawEllipse(buttonRect);
p.setBrush(Qt::NoBrush);
QLinearGradient darkgr(QPointF(1.0*u, 0.0), QPointF(20.0*u, 0.0));
darkgr.setColorAt(0.0, Qt::transparent);
darkgr.setColorAt(0.5, dark);
darkgr.setColorAt(1.0, Qt::transparent);
QLinearGradient lightgr(QPointF(1.0*u, 0.0), QPointF(20.0*u, 0.0));
lightgr.setColorAt(0.0, Qt::transparent);
lightgr.setColorAt(0.5, light);
lightgr.setColorAt(1.0, Qt::transparent);
p.setPen(QPen(darkgr, 1.5*u));
p.drawEllipse(buttonRect);
p.setPen(QPen(lightgr, 1.5*u));
if (!pressed) p.drawEllipse(buttonRect.adjusted(0.0, 1.0, 0.0, 1.0));
else p.drawEllipse(buttonRect.adjusted(1.0, 1.5, -1.0, 1.0));
} else {
QColor light = calcLightColor(color);
QColor dark = calcDarkColor(color);
QColor shadow = calcShadowColor(color);
QRectF rect(0.0, 0.0, size, size);
QRectF buttonRect = rect.adjusted(2*u,2*u,-2*u,-2*u);
QLinearGradient fill(QPointF(0.0, 0.0*u), QPointF(0.0, 21.0*u));
fill.setColorAt(0.0, alphaColor(light, 0.7));
fill.setColorAt(1.0, alphaColor(dark, 0.7));
p.setBrush(fill);
p.drawEllipse(buttonRect);
p.setBrush(Qt::NoBrush);
// shadow
if (pressed)
{
p.setPen(alphaColor(dark, 0.4));
p.drawEllipse(buttonRect.adjusted(0.9, 0.6, -0.7, -0.7).adjusted(1.7,1.7,-1.7,-1.7));
p.setPen(alphaColor(dark, 0.8));
p.drawEllipse(buttonRect.adjusted(0.9, 0.6, -0.7, -0.7).adjusted(1.2,1.2,-1.2,-1.2));
}
p.setPen(QPen(KColorUtils::mix(dark, shadow, 0.12), 2.0));
p.drawEllipse(buttonRect.adjusted(0.9, 0.6, -0.7, -0.7).adjusted(0,0.1,0,-0.1));
p.setPen(QPen(KColorUtils::mix(dark, shadow, 0.6), 1.2));
p.drawEllipse(buttonRect.adjusted(1.0, 1.4, -0.8, -0.8));
// reflection
QLinearGradient lightgr(QPointF(0.0, 0.0*u), QPointF(0.0, 21.0*u));
lightgr.setColorAt(0.0, Qt::transparent);
lightgr.setColorAt(1.0, light);
p.setPen(QPen(lightgr, 1.7));
p.drawEllipse(buttonRect.adjusted(0.0, -0.5, -0.1, 0.0));
}
m_windecoButtonCache.insert(key, pixmap);
}
return *pixmap;
}
//_______________________________________________________________________________________________________________
QPixmap NitrogenHelper::windecoButtonGlow(const QColor &color, int size)
{
quint64 key = (quint64(color.rgba()) << 32) | size;
QPixmap *pixmap = m_windecoButtonGlowCache.object(key);
if (!pixmap)
{
pixmap = new QPixmap(size, size);
pixmap->fill(Qt::transparent);
QPainter p(pixmap);
p.setRenderHints(QPainter::Antialiasing);
p.setPen(Qt::NoPen);
double u = size/21.0;
QRectF rect(0.0, 0.0, size, size);
QRectF buttonRect = rect.adjusted(2*u,2*u,-2*u,-2*u);
//mask
p.setBrush(QColor(0,0,0,125));
p.drawEllipse(rect.adjusted(u, 0, -u, -2*u));
//glow
QColor dark = calcDarkColor(color);
QColor light = calcLightColor(color);
QRadialGradient glow(QPointF(size/2.0, size/2.0 + 0.25), size/2.0);
glow.setColorAt(12.0 / 21.0, Qt::transparent);
glow.setColorAt(16.0 / 21.0, dark);
glow.setColorAt(18.0 / 21.0, alphaColor(light, 0.25));
glow.setColorAt(20.0 / 21.0, Qt::transparent);
p.setCompositionMode(QPainter::CompositionMode_SourceIn);
p.setBrush(glow);
p.drawEllipse(rect);
m_windecoButtonGlowCache.insert(key, pixmap);
}
return *pixmap;
}
//_______________________________________________________________________________________________________________
QPixmap NitrogenHelper::glow(const QColor &color, int size, int rsize)
{
QPixmap pixmap(rsize, rsize);
pixmap.fill(QColor(0,0,0,0));
QPainter p(&pixmap);
p.setRenderHints(QPainter::Antialiasing);
p.setPen(Qt::NoPen);
p.setWindow(0,0,size,size);
QRectF r(0, 0, size, size);
double m = double(size)*0.5;
const double width = 3.0;
const double bias = _glowBias * double(size) / double(rsize);
double k0 = (m-width+bias) / m;
QRadialGradient glowGradient(m, m, m);
for (int i = 0; i < 8; i++)
{
// inverse parabolic gradient
double k1 = (k0 * double(8 - i) + double(i)) * 0.125;
double a = 1.0 - sqrt(i * 0.125);
glowGradient.setColorAt(k1, alphaColor(color, a));
}
glowGradient.setColorAt(1.0, alphaColor(color, 0.0));
// glow
p.setBrush(glowGradient);
p.drawEllipse(r);
// mask
p.setCompositionMode(QPainter::CompositionMode_DestinationOut);
p.setBrush(QBrush(Qt::black));
p.drawEllipse(r.adjusted(width, width, -width, -width));
p.end();
return pixmap;
}
//_______________________________________________________________________________________________________________
void NitrogenHelper::drawFloatFrame(
QPainter *p,
const QRect r,
const QColor &color,
bool drawUglyShadow,
bool isActive,
const QColor &frameColor,
int frameBorder ) const
{
p->setRenderHint(QPainter::Antialiasing);
QRect frame = r;
frame.adjust(1,1,-1,-1);
int x,y,w,h;
frame.getRect(&x, &y, &w, &h);
QColor light = calcLightColor(backgroundTopColor(color));
QColor dark = calcLightColor(backgroundBottomColor(color));
QColor glow = KColorUtils::mix(QColor(128,128,128),frameColor,0.7);
p->setBrush(Qt::NoBrush);
if (drawUglyShadow && frameBorder >= 1 )
{
if(isActive)
{
//window active - it's a glow - not a shadow
p->setPen(glow);
// top
p->drawLine(QPointF(x+4, y-0.5), QPointF(x+w-4, y-0.5));
p->drawArc(QRectF(x-0.5, y-0.5, 11, 11),90*16, 90*16);
p->drawArc(QRectF(x+w-11+0.5, y-0.5, 11, 11), 0, 90*16);
if( frameBorder >= 3 )
{
p->drawLine(QPointF(x-0.5, y+4), QPointF(x-0.5, y+h-4));
p->drawLine(QPointF(x+w+0.5, y+4), QPointF(x+w+0.5, y+h-4));
p->drawArc(QRectF(0.5, y+h-11+0.5, 11, 11),180*16, 90*16);
p->drawArc(QRectF(x+w-11+0.5, y+h-11+0.5, 11, 11),270*16, 90*16);
// bottom
p->drawLine(QPointF(x+4, y+h+0.5), QPointF(x+w-4, y+h+0.5));
} else {
p->drawLine(QPointF(x-0.5, y+4), QPointF(x-0.5, y+h+0.5));
p->drawLine(QPointF(x+w+0.5, y+4), QPointF(x+w+0.5, y+h+0.5));
p->drawLine(QPointF(x-0.5, y+h+0.5), QPointF(x+w+0.5, y+h+0.5));
}
light = KColorUtils::mix(light, frameColor);
dark = KColorUtils::mix(dark, frameColor);
} else {
//window inactive - draw something resembling shadow
QColor shadow = KColorUtils::darken(color, 0.0, 0.0); // fully desaturate
p->setPen(KColorUtils::darken(shadow, 0.2));
p->drawLine(QPointF(x+4, y-0.5), QPointF(x+w-4, y-0.5));
p->drawArc(QRectF(x-0.5, y-0.5, 11, 11),90*16, 90*16);
p->drawArc(QRectF(x+w-11+0.5, y-0.5, 11, 11), 0, 90*16);
if( frameBorder >= 3 )
{
p->setPen(KColorUtils::darken(shadow, 0.35));
p->drawLine(QPointF(x-0.5, y+4), QPointF(x-0.5, y+h-4));
p->drawLine(QPointF(x+w+0.5, y+4), QPointF(x+w+0.5, y+h-4));
p->setPen(KColorUtils::darken(shadow, 0.45));
p->drawArc(QRectF(0.5, y+h-11+0.5, 11, 11),180*16, 90*16);
p->drawArc(QRectF(x+w-11+0.5, y+h-11+0.5, 11, 11),270*16, 90*16);
p->setPen(KColorUtils::darken(shadow, 0.6));
p->drawLine(QPointF(x+4, y+h+0.5), QPointF(x+w-4, y+h+0.5));
} else {
p->setPen(KColorUtils::darken(shadow, 0.35));
p->drawLine(QPointF(x-0.5, y+4), QPointF(x-0.5, y+h-0.5));
p->drawLine(QPointF(x+w+0.5, y+4), QPointF(x+w+0.5, y+h-0.5));
p->setPen(KColorUtils::darken(shadow, 0.6));
p->drawLine(QPointF(x+0.5, y+h+0.5), QPointF(x+w-0.5, y+h+0.5));
}
}
}
if( frameBorder >= 5 )
{
p->setPen(QPen(light, 0.8));
p->drawLine(QPointF(x+4, y+0.6), QPointF(x+w-4, y+0.6));
QLinearGradient lg = QLinearGradient(0.0, 1.5, 0.0, 4.5);
lg.setColorAt(0, light);
lg.setColorAt(1, dark);
p->setPen(QPen(lg, 0.8));
p->drawArc(QRectF(x+0.6, y+0.6, 9, 9),90*16, 90*16);
p->drawArc(QRectF(x+w-9-0.6, y+0.6, 9, 9), 0, 90*16);
p->drawLine(QPointF(x+0.6, y+4), QPointF(x+0.6, y+h-4));
p->drawLine(QPointF(x+w-0.6, y+4), QPointF(x+w-0.6, y+h-4));
}
return;
}
//_______________________________________________________________________________________________________________
void NitrogenHelper::drawSeparator(QPainter *p, const QRect &rect, const QColor &color, Qt::Orientation orientation) const
{
QColor light = calcLightColor(color);
QColor dark = calcDarkColor(color);
bool antialias = p->testRenderHint(QPainter::Antialiasing);
p->setRenderHint(QPainter::Antialiasing,false);
QPoint start,end,offset;
if (orientation == Qt::Horizontal) {
start = QPoint(rect.x(),rect.y()+rect.height()/2-1);
end = QPoint(rect.right(),rect.y()+rect.height()/2-1);
offset = QPoint(0,1);
} else {
start = QPoint(rect.x()+rect.width()/2-1,rect.y());
end = QPoint(rect.x()+rect.width()/2-1,rect.bottom());
offset = QPoint(1,0);
light.setAlpha(150);
}
QLinearGradient lg(start,end);
lg.setColorAt(0.3, dark);
lg.setColorAt(0.7, dark);
dark.setAlpha(0);
lg.setColorAt(0.0, dark);
lg.setColorAt(1.0, dark);
p->setPen(QPen(lg,1));
if (orientation == Qt::Horizontal) p->drawLine(start,end);
else p->drawLine(start+offset,end+offset);
lg = QLinearGradient(start,end);
lg.setColorAt(0.3, light);
lg.setColorAt(0.7, light);
light.setAlpha(0);
lg.setColorAt(0.0, light);
lg.setColorAt(1.0, light);
p->setPen(QPen(lg,1));
if (orientation == Qt::Horizontal) p->drawLine(start+offset,end+offset);
else {
p->drawLine(start,end);
p->drawLine(start+offset*2,end+offset*2);
}
p->setRenderHint(QPainter::Antialiasing, antialias);
}

View file

@ -0,0 +1,126 @@
// $Id: helper.h,v 1.6 2009/05/29 14:34:07 hpereira Exp $
/*
* Copyright 2008 Long Huynh Huu <long.upcase@googlemail.com>
* Copyright 2007 Matthew Woehlke <mw_triad@users.sourceforge.net>
* Copyright 2007 Casper Boemann <cbr@boemann.dk>
* Copyright 2007 Fredrik Höglund <fredrik@kde.org>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License version 2 as published by the Free Software Foundation.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#ifndef __NITROGEN_HELPER_H
#define __NITROGEN_HELPER_H
#include <ksharedconfig.h>
#include <kcomponentdata.h>
#include <QtGui/QColor>
#include <QtGui/QPixmap>
#include <QtGui/QLinearGradient>
#include <QtCore/QCache>
#include "../nitrogenconfiguration.h"
#define _glowBias 0.9 // not likely to be configurable
// WARNING - NitrogenHelper must be a K_GLOBAL_STATIC!
class NitrogenHelper
{
public:
//! constructor
explicit NitrogenHelper(const QByteArray& );
//! destructor
virtual ~NitrogenHelper() {}
//! configuration
KSharedConfigPtr config() const;
//! reload configuration
void reloadConfig();
//! window backbround
void renderWindowBackground(
QPainter *p,
const QRect &clipRect,
const QWidget *widget,
const QPalette & pal,
int gradient_shift = 0
);
//! clear cache
virtual void invalidateCaches();
//!@name color calculations
// @{
static bool lowThreshold(const QColor &color);
static QColor alphaColor(QColor color, double alpha);
QColor calcLightColor(const QColor &color) const;
QColor calcDarkColor(const QColor &color) const;
QColor calcShadowColor(const QColor &color) const;
QColor backgroundColor(const QColor &color, int height, int y);
QColor backgroundRadialColor(const QColor &color) const;
QColor backgroundTopColor(const QColor &color) const;
QColor backgroundBottomColor(const QColor &color) const;
//@}
//!@name gradients
//@{
QPixmap verticalGradient(const QColor &color, int height);
QPixmap radialGradient(const QColor &color, int width, int y_offset = 0);
QLinearGradient decoGradient(const QRect &r, const QColor &color);
//@}
//! buttons
QPixmap windecoButton(const QColor &color, bool pressed, Nitrogen::NitrogenConfiguration::ButtonType type, int size = 21);
QPixmap windecoButtonGlow(const QColor &color, int size = 21);
//! frame
void drawFloatFrame(
QPainter *p,
const QRect r,
const QColor &color,
bool drawUglyShadow=true,
bool isActive=false,
const QColor &frameColor=QColor(),
int frameBorder = 5
) const;
//! separator
void drawSeparator(QPainter *p, const QRect &r, const QColor &color, Qt::Orientation orientation) const;
protected:
void drawShadow(QPainter&, const QColor&, int size) const;
static QPixmap glow(const QColor&, int size, int rsize);
static const double _shadowGain;
KComponentData _componentData;
KSharedConfigPtr _config;
qreal _contrast;
qreal _bgcontrast;
// cache
QCache<quint64, QPixmap> m_backgroundCache;
QCache<quint64, QPixmap> m_windecoButtonCache;
QCache<quint64, QPixmap> m_windecoButtonGlowCache;
};
#endif // __NITROGEN_HELPER_H

View file

@ -0,0 +1,132 @@
/*
* Copyright 2008 Long Huynh Huu <long.upcase@googlemail.com>
* Copyright 2007 Matthew Woehlke <mw_triad@users.sourceforge.net>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License version 2 as published by the Free Software Foundation.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#include <QtGui/QPainter>
#include "tileset.h"
void TileSet::initPixmap(int s, const QPixmap &pix, int w, int h, const QRect &region)
{
if (w != region.width() || h != region.height()) {
QPixmap tile = pix.copy(region);
_pixmap[s] = QPixmap(w, h);
_pixmap[s].fill(QColor(0,0,0,0));
QPainter p(&_pixmap[s]);
p.drawTiledPixmap(0, 0, w, h, tile);
}
else {
_pixmap[s] = pix.copy(region);
}
}
TileSet::TileSet(const QPixmap &pix, int w1, int h1, int w2, int h2)
: _w1(w1), _h1(h1)
{
if (pix.isNull())
return;
_w3 = pix.width() - (w1 + w2);
_h3 = pix.height() - (h1 + h2);
int w = w2; while (w < 32 && w2 > 0) w += w2;
int h = h2; while (h < 32 && h2 > 0) h += h2;
initPixmap(0, pix, _w1, _h1, QRect(0, 0, _w1, _h1));
initPixmap(1, pix, w, _h1, QRect(_w1, 0, w2, _h1));
initPixmap(2, pix, _w3, _h1, QRect(_w1+w2, 0, _w3, _h1));
initPixmap(3, pix, _w1, h, QRect(0, _h1, _w1, h2));
initPixmap(4, pix, w, h, QRect(_w1, _h1, w2, h2));
initPixmap(5, pix, _w3, h, QRect(_w1+w2, _h1, _w3, h2));
initPixmap(6, pix, _w1, _h3, QRect(0, _h1+h2, _w1, _h3));
initPixmap(7, pix, w, _h3, QRect(_w1, _h1+h2, w2, _h3));
initPixmap(8, pix, _w3, _h3, QRect(_w1+w2, _h1+h2, _w3, _h3));
}
TileSet::TileSet(const QPixmap &pix, int w1, int h1, int w3, int h3, int x1, int y1, int w2, int h2)
: _w1(w1), _h1(h1), _w3(w3), _h3(h3)
{
if (pix.isNull())
return;
int x2 = pix.width() - _w3;
int y2 = pix.height() - _h3;
int w = w2; while (w < 32 && w2 > 0) w += w2;
int h = h2; while (h < 32 && h2 > 0) h += h2;
initPixmap(0, pix, _w1, _h1, QRect(0, 0, _w1, _h1));
initPixmap(1, pix, w, _h1, QRect(x1, 0, w2, _h1));
initPixmap(2, pix, _w3, _h1, QRect(x2, 0, _w3, _h1));
initPixmap(3, pix, _w1, h, QRect(0, y1, _w1, h2));
initPixmap(4, pix, w, h, QRect(x1, y1, w2, h2));
initPixmap(5, pix, _w3, h, QRect(x2, y1, _w3, h2));
initPixmap(6, pix, _w1, _h3, QRect(0, y2, _w1, _h3));
initPixmap(7, pix, w, _h3, QRect(x1, y2, w2, _h3));
initPixmap(8, pix, _w3, _h3, QRect(x2, y2, _w3, _h3));
}
TileSet::TileSet(const TileSet &other)
: _w1(other._w1), _h1(other._h1), _w3(other._w3), _h3(other._h3)
{
for (int i=0; i<9; i++) {
_pixmap[i] = other._pixmap[i];
}
}
TileSet& TileSet::operator=(const TileSet &other)
{
_w1 = other._w1;
_w3 = other._w3;
_h1 = other._h1;
_h3 = other._h3;
for (int i=0; i<9; i++) {
_pixmap[i] = other._pixmap[i];
}
return *this;
}
inline bool bits(TileSet::Tiles flags, TileSet::Tiles testFlags)
{
return (flags & testFlags) == testFlags;
}
void TileSet::render(const QRect &r, QPainter *p, Tiles t) const
{
if (_pixmap[0].isNull())
return;
int x0, y0, w, h;
r.getRect(&x0, &y0, &w, &h);
w -= _w1 + _w3;
h -= _h1 + _h3;
int x1 = x0 + _w1;
int x2 = x1 + w;
int y1 = y0 + _h1;
int y2 = y1 + h;
if (bits(t, Top|Left)) p->drawPixmap(x0, y0, _pixmap[0]);
if (bits(t, Top|Right)) p->drawPixmap(x2, y0, _pixmap[2]);
if (bits(t, Bottom|Left)) p->drawPixmap(x0, y2, _pixmap[6]);
if (bits(t, Bottom|Right)) p->drawPixmap(x2, y2, _pixmap[8]);
if (t & Top) p->drawTiledPixmap(x1, y0, w, _h1, _pixmap[1]);
if (t & Bottom) p->drawTiledPixmap(x1, y2, w, _h3, _pixmap[7]);
if (t & Left) p->drawTiledPixmap(x0, y1, _w1, h, _pixmap[3]);
if (t & Right) p->drawTiledPixmap(x2, y1, _w3, h, _pixmap[5]);
if (t & Center) p->drawTiledPixmap(x1, y1, w, h, _pixmap[4]);
}

View file

@ -0,0 +1,102 @@
/*
* Copyright 2007 Matthew Woehlke <mw_triad@users.sourceforge.net>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License version 2 as published by the Free Software Foundation.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#ifndef TILESET_H
#define TILESET_H
#include <QtGui/QPixmap>
#include <QtCore/QRect>
class TileSet
{
public:
/**
* Create a TileSet from a pixmap. The size of the bottom/right chunks is
* whatever is left over from the other chunks, whose size is specified
* in the required parameters.
*
* @param w1 width of the left chunks
* @param h1 height of the top chunks
* @param w2 width of the not-left-or-right chunks
* @param h2 height of the not-top-or-bottom chunks
*/
TileSet(const QPixmap&, int w1, int h1, int w2, int h2);
/**
* Create a TileSet from a pixmap. The size of the top/left and bottom/right
* chunks is specified, with the middle chunks created from the specified
* portion of the pixmap. This allows the middle chunks to overlap the outer
* chunks (or to not use all pixels). The top/left and bottom/right chunks
* are carved out of the corners of the pixmap.
*
* @param w1 width of the left chunks
* @param h1 height of the top chunks
* @param w3 width of the right chunks
* @param h3 height of bottom chunks
* @param x2 x-coordinate of the top of the not-left-or-right chunks
* @param y2 y-coordinate of the left of the not-top-or-bottom chunks
* @param w2 width of the not-left-or-right chunks
* @param h2 height of the not-top-or-bottom chunks
*/
TileSet(const QPixmap &pix, int w1, int h1, int w3, int h3, int x2, int y2, int w2, int h2);
TileSet() : _empty(true) {}
TileSet(const TileSet&);
virtual ~TileSet() {}
TileSet& operator=(const TileSet&);
/**
* Flags specifying what sides to draw in ::render. Corners are drawn when
* the sides forming that corner are drawn, e.g. Top|Left draws the
* top-center, center-left, and top-left chunks. The center-center chunk is
* only drawn when Center is requested.
*/
enum Tile {
Top = 0x1,
Left = 0x2,
Right = 0x8,
Bottom = 0x4,
Center = 0x10,
Ring = 0x0f,
Horizontal = 0x1a,
Vertical = 0x15,
Full = 0x1f
};
Q_DECLARE_FLAGS(Tiles, Tile)
/**
* Fills the specified rect with tiled chunks. Corners are never tiled,
* edges are tiled in one direction, and the center chunk is tiled in both
* directions. Partial tiles are used as needed so that the entire rect is
* perfectly filled. Filling is performed as if all chunks are being drawn.
*/
void render(const QRect&, QPainter*, Tiles = Ring) const;
protected:
void initPixmap(int s, const QPixmap&, int w, int h, const QRect &region);
bool _empty;
QPixmap _pixmap[9];
int _w1, _h1, _w3, _h3;
};
Q_DECLARE_OPERATORS_FOR_FLAGS(TileSet::Tiles)
#endif //TILESET_H

View file

@ -0,0 +1,20 @@
# Copyright 1999-2009 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
# $Header: /phenix/u/hpereira/repository/kde/kde4-windeco-nitrogen/nitrogen.ebuild,v 1.1 2009/05/26 21:55:20 hpereira Exp $
EAPI="2"
inherit kde4-base
MY_P="kde4-windeco-${P}-Source"
DESCRIPTION="A window decoration for KDE 4.2.x"
HOMEPAGE="http://www.kde-look.org/content/show.php/Nitrogen?content=99551"
SRC_URI="http://www.kde-look.org/CONTENT/content-files/99551-${MY_P}.tar.gz"
S="${WORKDIR}/${MY_P}"
LICENSE="GPL-2"
SLOT="0"
KEYWORDS="~amd64 ~x86"
IUSE="debug"

View file

@ -0,0 +1,484 @@
//////////////////////////////////////////////////////////////////////////////
// Nitrogenbutton.h
// -------------------
// Nitrogen window decoration for KDE.
// -------------------
// Copyright (c) 2006, 2007 Riccardo Iaconelli <riccardo@kde.org>
// Copyright (c) 2009, 2010 Hugo Pereira <hugo.pereira@free.fr>
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//////////////////////////////////////////////////////////////////////////////
#include <assert.h>
#include <kconfiggroup.h>
#include <kdeversion.h>
#include <kwindowinfo.h>
#include <QApplication>
#include <QDir>
#include <QPainter>
#include <QTextStream>
#include "nitrogen.h"
#include "nitrogen.moc"
#include "nitrogenclient.h"
extern "C"
{
KDE_EXPORT KDecorationFactory* create_factory()
{ return new Nitrogen::NitrogenFactory(); }
}
namespace Nitrogen
{
// referenced from definition in Nitrogendclient.cpp
NitrogenHelper *nitrogenHelper();
// initialize static members
bool NitrogenFactory::initialized_ = false;
NitrogenConfiguration NitrogenFactory::defaultConfiguration_;
NitrogenExceptionList NitrogenFactory::exceptions_;
//___________________________________________________
NitrogenFactory::NitrogenFactory()
{
readConfig();
setInitialized( true );
}
//___________________________________________________
NitrogenFactory::~NitrogenFactory()
{ setInitialized( false ); }
//___________________________________________________
KDecoration* NitrogenFactory::createDecoration(KDecorationBridge* bridge )
{
NitrogenClient* client( new NitrogenClient( bridge, this ) );
connect( this, SIGNAL( configurationChanged() ), client, SLOT( resetConfiguration() ) );
return client->decoration();
}
//___________________________________________________
bool NitrogenFactory::reset(unsigned long changed)
{
QTextStream( stdout ) << "NitrogenConfig::reset." << endl;
// read in the configuration
setInitialized( false );
bool configuration_changed = readConfig();
setInitialized( true );
if( configuration_changed || (changed & (SettingDecoration | SettingButtons | SettingBorder)) )
{
emit configurationChanged();
return true;
} else {
emit configurationChanged();
resetDecorations(changed);
return false;
}
}
//___________________________________________________
bool NitrogenFactory::readConfig()
{
QTextStream( stdout ) << "NitrogenConfig::readConfig." << endl;
// create a config object
KConfig config("nitrogenrc");
KConfigGroup group( config.group("Windeco") );
NitrogenConfiguration configuration( group );
bool changed = !( configuration == defaultConfiguration() );
// check configurations
changed |= (NitrogenConfiguration::useCompiz() == NitrogenConfiguration::checkUseCompiz());
// read exceptionsreadConfig
NitrogenExceptionList exceptions( config );
if( !( exceptions == exceptions_ ) )
{
exceptions_ = exceptions;
changed = true;
}
if( changed )
{
nitrogenHelper()->invalidateCaches();
setDefaultConfiguration( configuration );
return true;
} else return false;
}
//_________________________________________________________________
bool NitrogenFactory::supports( Ability ability ) const
{
switch( ability )
{
// announce
case AbilityAnnounceButtons:
case AbilityAnnounceColors:
// buttons
case AbilityButtonMenu:
case AbilityButtonHelp:
case AbilityButtonMinimize:
case AbilityButtonMaximize:
case AbilityButtonClose:
case AbilityButtonOnAllDesktops:
case AbilityButtonAboveOthers:
case AbilityButtonBelowOthers:
case AbilityButtonSpacer:
case AbilityButtonShade:
// // colors
// case AbilityColorTitleBack:
// case AbilityColorTitleFore:
// case AbilityColorFrame:
// compositing
#if KDE_IS_VERSION(4,2,92)
case AbilityProvidesShadow: // TODO: UI option to use default shadows instead
case AbilityUsesAlphaChannel:
return !NitrogenConfiguration::useCompiz();
#else
case AbilityCompositingShadow:
return !NitrogenConfiguration::useCompiz();
#endif
// no colors supported at this time
default:
return false;
};
}
#if !KDE_IS_VERSION(4,2,92)
//////////////////////////////////////////////////////////////////////////////
// Shadows (kde4.2 version)
//_________________________________________________________________
QList< QList<QImage> > NitrogenFactory::shadowTextures()
{
QList< QList<QImage> > textureLists;
// in compiz mode, no textures are used
if( NitrogenConfiguration::useCompiz() )
{ return textureLists; }
textureLists.append( makeTextures( defaultConfiguration().useOxygenShadows() ? Active:Inactive ) );
textureLists.append( makeTextures( Inactive ) );
return textureLists;
}
//_________________________________________________________________
QList<QImage> NitrogenFactory::makeTextures( NitrogenFactory::Activity state ) const
{
#define shadowFuzzyness 10
#define shadowSize 10
// palette
QPalette palette = qApp->palette();
palette.setCurrentColorGroup(QPalette::Active);
// shadow size
qreal size = 25.5;
// prepare pixmap and painter
QPixmap shadow( size*2, size*2 );
shadow.fill( Qt::transparent );
QPainter p( &shadow );
p.setRenderHint( QPainter::Antialiasing );
p.setPen( Qt::NoPen );
// prepare colors
QColor color = palette.window().color();
QColor light = nitrogenHelper()->calcLightColor(nitrogenHelper()->backgroundTopColor(color));
QColor dark = nitrogenHelper()->calcDarkColor(nitrogenHelper()->backgroundBottomColor(color));
QLinearGradient lg = QLinearGradient(0.0, size-4.5, 0.0, size+4.5);
if( defaultConfiguration().frameBorder() <= NitrogenConfiguration::BorderTiny )
{
lg.setColorAt(0, nitrogenHelper()->backgroundTopColor(color) );
lg.setColorAt(0.52, nitrogenHelper()->backgroundTopColor(color));
lg.setColorAt(1.0, nitrogenHelper()->backgroundBottomColor(color) );
} else {
lg.setColorAt(0.52, light);
lg.setColorAt(1.0, dark);
}
switch( state )
{
case Active:
{
QColor glow = KDecoration::options()->color(ColorFrame);
QColor glow2 = KDecoration::options()->color(ColorTitleBar);
QRadialGradient rg( size, size, size );
QColor c = color;
c.setAlpha( 255 ); rg.setColorAt( 4.4/size, c );
c = glow;
c.setAlpha( 220 ); rg.setColorAt( 4.5/size, c );
c.setAlpha( 180 ); rg.setColorAt( 5/size, c );
c.setAlpha( 25 ); rg.setColorAt( 5.5/size, c );
c.setAlpha( 0 ); rg.setColorAt( 6.5/size, c );
p.setBrush( rg );
p.drawRect( shadow.rect() );
rg = QRadialGradient( size, size, size );
c = color;
c.setAlpha( 255 ); rg.setColorAt( 4.4/size, c );
c = glow2;
c.setAlpha( 0.58*255 ); rg.setColorAt( 4.5/size, c );
c.setAlpha( 0.43*255 ); rg.setColorAt( 5.5/size, c );
c.setAlpha( 0.30*255 ); rg.setColorAt( 6.5/size, c );
c.setAlpha( 0.22*255 ); rg.setColorAt( 7.5/size, c );
c.setAlpha( 0.15*255 ); rg.setColorAt( 8.5/size, c );
c.setAlpha( 0.08*255 ); rg.setColorAt( 11.5/size, c );
c.setAlpha( 0); rg.setColorAt( 14.5/size, c );
p.setBrush( rg );
p.drawRect( shadow.rect() );
// draw the corner of the window - actually all 4 corners as one circle
p.setBrush( Qt::NoBrush );
p.setPen(QPen(lg, 0.8));
p.drawEllipse(QRectF(size-4, size-4, 8, 8));
// cut out the part of the texture that is under the window
p.setCompositionMode( QPainter::CompositionMode_DestinationOut );
p.setBrush( QColor( 0, 0, 0, 255 ));
p.setPen( Qt::NoPen );
p.drawEllipse(QRectF(size-3, size-3, 6, 6));
p.drawRect(QRectF(size-3, size-1, 6, 2));
p.drawRect(QRectF(size-1, size-3, 2, 6));
p.end();
return makeTextures( shadow );
}
case Inactive:
{
//---------------------------------------------------------------
// Inactive shadow texture
QRadialGradient rg( size, size+4, size );
QColor c( Qt::black );
c.setAlpha( 0.12*255 ); rg.setColorAt( 4.5/size, c );
c.setAlpha( 0.11*255 ); rg.setColorAt( 6.6/size, c );
c.setAlpha( 0.075*255 ); rg.setColorAt( 8.5/size, c );
c.setAlpha( 0.06*255 ); rg.setColorAt( 11.5/size, c );
c.setAlpha( 0.035*255 ); rg.setColorAt( 14.5/size, c );
c.setAlpha( 0.025*255 ); rg.setColorAt( 17.5/size, c );
c.setAlpha( 0.01*255 ); rg.setColorAt( 21.5/size, c );
c.setAlpha( 0.0*255 ); rg.setColorAt( 25.5/size, c );
p.setBrush( rg );
p.drawRect( shadow.rect() );
rg = QRadialGradient( size, size+2, size );
c = QColor( Qt::black );
c.setAlpha( 0.25*255 ); rg.setColorAt( 4.5/size, c );
c.setAlpha( 0.20*255 ); rg.setColorAt( 5.5/size, c );
c.setAlpha( 0.13*255 ); rg.setColorAt( 7.5/size, c );
c.setAlpha( 0.06*255 ); rg.setColorAt( 8.5/size, c );
c.setAlpha( 0.015*255 ); rg.setColorAt( 11.5/size, c );
c.setAlpha( 0.0*255 ); rg.setColorAt( 14.5/size, c );
p.setBrush( rg );
p.drawRect( shadow.rect() );
rg = QRadialGradient( size, size+0.2, size );
c = QColor( Qt::black );
c.setAlpha( 0.35*255 ); rg.setColorAt( 0/size, c );
c.setAlpha( 0.32*255 ); rg.setColorAt( 4.5/size, c );
c.setAlpha( 0.22*255 ); rg.setColorAt( 5.0/size, c );
c.setAlpha( 0.03*255 ); rg.setColorAt( 5.5/size, c );
c.setAlpha( 0.0*255 ); rg.setColorAt( 6.5/size, c );
p.setBrush( rg );
p.drawRect( shadow.rect() );
rg = QRadialGradient( size, size, size );
c = color;
c.setAlpha( 255 ); rg.setColorAt( 4.0/size, c );
c.setAlpha( 0 ); rg.setColorAt( 4.01/size, c );
p.setBrush( rg );
p.drawRect( shadow.rect() );
// draw the corner of the window - actually all 4 corners as one circle
p.setBrush( Qt::NoBrush );
p.setPen(QPen(lg, 0.8));
p.drawEllipse(QRectF(size-4, size-4, 8, 8));
// cut out the part of the texture that is under the window
p.setCompositionMode( QPainter::CompositionMode_DestinationOut );
p.setBrush( QColor( 0, 0, 0, 255 ));
p.setPen( Qt::NoPen );
p.drawEllipse(QRectF(size-3, size-3, 6, 6));
p.drawRect(QRectF(size-3, size-1, 6, 2));
p.drawRect(QRectF(size-1, size-3, 2, 6));
p.end();
return makeTextures( shadow );
}
default:
return QList<QImage>();
}
}
//______________________________________________________
QImage NitrogenFactory::makeTexture( const QPixmap& pixmap, const QRect& rect ) const
{
QPixmap dump( rect.size() );
dump.fill( Qt::transparent );
QPainter painter( &dump );
painter.drawPixmap( QPoint(0, 0), pixmap, rect );
painter.end();
return dump.toImage();
}
//___________________________________________________________
QList<QImage> NitrogenFactory::makeTextures( const QPixmap& shadow ) const
{
QList<QImage> textures;
int w = shadow.width() / 2;
int h = shadow.height() / 2;
textures.append( makeTexture( shadow, QRect( 0, h+1, w, h ) ) );
textures.append( makeTexture( shadow, QRect( w, h+1, 1, h ) ) );
textures.append( makeTexture( shadow, QRect( w+1, h+1, w, h ) ) );
textures.append( makeTexture( shadow, QRect( 0, h, w, 1 ) ) );
textures.append( makeTexture( shadow, QRect( w+1, h, w, 1 ) ) );
textures.append( makeTexture( shadow, QRect( 0, 0, w, h ) ) );
textures.append( makeTexture( shadow, QRect( w, 0, 1, h ) ) );
textures.append( makeTexture( shadow, QRect( w+1, 0, w, h ) ) );
return textures;
}
//_________________________________________________________________
int NitrogenFactory::shadowTextureList( ShadowType type ) const
{
switch( type ) {
case ShadowBorderedInactive: return 1;
default: return 0;
}
abort(); // Should never be reached
}
//_________________________________________________________________
QList<QRect> NitrogenFactory::shadowQuads( ShadowType, QSize ) const
{ return QList<QRect>(); }
//____________________________________________________________________
double NitrogenFactory::shadowOpacity( ShadowType ) const
{ return 1.0; }
#endif
//____________________________________________________________________
NitrogenConfiguration NitrogenFactory::configuration( const NitrogenClient& client )
{
QString window_title;
QString class_name;
for( NitrogenExceptionList::const_iterator iter = exceptions_.begin(); iter != exceptions_.end(); iter++ )
{
// discard disabled exceptions
if( !iter->enabled() ) continue;
/*
decide which value is to be compared
to the regular expression, based on exception type
*/
QString value;
switch( iter->type() )
{
case NitrogenException::WindowTitle:
{
value = window_title.isEmpty() ? (window_title = client.caption()):window_title;
break;
}
case NitrogenException::WindowClassName:
{
if( class_name.isEmpty() )
{
// retrieve class name
KWindowInfo info( client.windowId(), 0, NET::WM2WindowClass );
QString window_class_name( info.windowClassName() );
QString window_class( info.windowClassClass() );
class_name = window_class_name + " " + window_class;
}
value = class_name;
break;
}
default: assert( false );
}
if( iter->regExp().indexIn( value ) < 0 ) continue;
NitrogenConfiguration configuration( defaultConfiguration() );
// propagate all features found in mask to the output configuration
if( iter->mask() & NitrogenException::FrameBorder ) configuration.setFrameBorder( iter->frameBorder() );
if( iter->mask() & NitrogenException::BlendColor ) configuration.setBlendColor( iter->blendColor() );
if( iter->mask() & NitrogenException::DrawSeparator ) configuration.setDrawSeparator( iter->drawSeparator() );
if( iter->mask() & NitrogenException::ShowStripes ) configuration.setShowStripes( iter->showStripes() );
if( iter->mask() & NitrogenException::OverwriteColors ) configuration.setOverwriteColors( iter->overwriteColors() );
if( iter->mask() & NitrogenException::DrawSizeGrip ) configuration.setDrawSizeGrip( iter->drawSizeGrip() );
return configuration;
}
return defaultConfiguration();
}
} //namespace Nitrogen

View file

@ -0,0 +1,20 @@
# Copyright 1999-2009 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
# $Header: /phenix/u/hpereira/repository/kde/kde4-windeco-nitrogen/nitrogen.ebuild,v 1.1 2009/05/26 21:55:20 hpereira Exp $
EAPI="2"
inherit kde4-base
MY_P="kde4-windeco-${P}-Source"
DESCRIPTION="A window decoration for KDE 4.2.x"
HOMEPAGE="http://www.kde-look.org/content/show.php/Nitrogen?content=99551"
SRC_URI="http://www.kde-look.org/CONTENT/content-files/99551-${MY_P}.tar.gz"
S="${WORKDIR}/${MY_P}"
LICENSE="GPL-2"
SLOT="0"
KEYWORDS="~amd64 ~x86"
IUSE="debug"

166
clients/nitrogen/nitrogen.h Normal file
View file

@ -0,0 +1,166 @@
#ifndef nitrogen_h
#define nitrogen_h
// $Id: nitrogen.h,v 1.16 2009/07/05 20:47:44 hpereira Exp $
// Copyright (c) 2006, 2007 Riccardo Iaconelli <ruphy@fsfe.org>
// Copyright (c) 2009, 2010 Hugo Pereira <hugo.pereira@free.fr>
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
#include <QObject>
#include <kdecorationfactory.h>
#include <kdeversion.h>
#include "nitrogenconfiguration.h"
#include "nitrogenexceptionlist.h"
// TODO:
// should review implementation not to use static objects
namespace Nitrogen
{
class NitrogenClient;
//! button size
// enum { NITROGEN_BUTTONSIZE = 22 };
//! buttons
enum ButtonType
{
ButtonHelp=0,
ButtonMax,
ButtonMin,
ButtonClose,
ButtonMenu,
ButtonSticky,
ButtonAbove,
ButtonBelow,
ButtonShade,
ButtonTypeCount
};
#if KDE_IS_VERSION(4,2,92)
static const qreal SHADOW_WIDTH = 25.5;
#endif
Q_DECLARE_FLAGS(ButtonTypes, ButtonType)
//! window decoration factory
class NitrogenFactory: public QObject, public KDecorationFactoryUnstable
{
Q_OBJECT
public:
//! constructor
NitrogenFactory();
//! destructor
virtual ~NitrogenFactory();
//! create decoration
virtual KDecoration *createDecoration(KDecorationBridge *b);
//! configuration reset
virtual bool reset(unsigned long changed);
//! configuration capabilities
virtual bool supports( Ability ability ) const;
#if !KDE_IS_VERSION(4,2,92)
//! shadow textures
virtual QList< QList<QImage> > shadowTextures();
//! shadow textures
virtual int shadowTextureList( ShadowType type ) const;
//! shadow rectangles
virtual QList<QRect> shadowQuads( ShadowType type, QSize size ) const;
//! shadow opacity
virtual double shadowOpacity( ShadowType type ) const;
#endif
//! true if initialized
static bool initialized()
{ return initialized_; }
//! get configuration for a give client
static NitrogenConfiguration configuration( const NitrogenClient& );
signals:
//! configuration has changed
void configurationChanged( void );
private:
//! read configuration from KConfig
bool readConfig();
#if !KDE_IS_VERSION(4,2,92)
//! make texture from a given image
QImage makeTexture( const QPixmap&, const QRect& ) const;
//! make texture from a given image
QList<QImage> makeTextures( const QPixmap& ) const;
// active state
enum Activity
{
Active,
Inactive
};
//! make texture from a given image
QList<QImage> makeTextures( Activity ) const;
#endif
//! default configuration
static NitrogenConfiguration defaultConfiguration( void )
{ return defaultConfiguration_; }
//! initialization
static void setInitialized( bool value )
{ initialized_ = value; }
//! set default configuration
static void setDefaultConfiguration( NitrogenConfiguration value )
{ defaultConfiguration_ = value; }
//! initialization flag
static bool initialized_;
//! default configuration
static NitrogenConfiguration defaultConfiguration_;
//! exceptions
static NitrogenExceptionList exceptions_;
//! true if compiz is used
static bool useCompiz_;
};
};
#endif

View file

@ -0,0 +1,345 @@
// $Id: nitrogenbutton.cpp,v 1.20 2009/07/01 22:29:25 hpereira Exp $
//////////////////////////////////////////////////////////////////////////////
// Nitrogenbutton.cpp
// -------------------
// Nitrogen window decoration for KDE. Buttons.
// -------------------
// Copyright (c) 2006, 2007 Riccardo Iaconelli <riccardo@kde.org>
// Copyright (c) 2006, 2007 Casper Boemann <cbr@boemann.dk>
// Copyright (c) 2009, 2010 Hugo Pereira <hugo.pereira@free.fr>
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//////////////////////////////////////////////////////////////////////////////
#include <cmath>
#include <QPainterPath>
#include <QPainter>
#include <QPen>
#include <QBitmap>
#include <QTextStream>
#include <KGlobal>
#include <KColorUtils>
#include <KColorScheme>
#include <kcommondecoration.h>
#include "nitrogenbutton.h"
#include "nitrogenclient.h"
#include "nitrogen.h"
namespace Nitrogen
{
//_______________________________________________
NitrogenButton::NitrogenButton(NitrogenClient &parent,
const QString& tip, ButtonType type):
KCommonDecorationButton((::ButtonType)type, &parent),
client_(parent),
helper_( parent.helper() ),
type_(type),
colorCacheInvalid_(true)
{
setAutoFillBackground(false);
setAttribute(Qt::WA_OpaquePaintEvent, false);
{
unsigned int size( client_.configuration().buttonSize() );
setFixedSize( size, size );
}
setCursor(Qt::ArrowCursor);
setToolTip(tip);
}
//_______________________________________________
NitrogenButton::~NitrogenButton()
{}
//declare function from Nitrogenclient.cpp
QColor reduceContrast(const QColor &c0, const QColor &c1, double t);
//_______________________________________________
QColor NitrogenButton::buttonDetailColor(const QPalette &palette)
{
if (client_.isActive()) return palette.color(QPalette::Active, QPalette::ButtonText);
else {
if (colorCacheInvalid_)
{
QColor ab = palette.color(QPalette::Active, QPalette::Button);
QColor af = palette.color(QPalette::Active, QPalette::ButtonText);
QColor nb = palette.color(QPalette::Inactive, QPalette::Button);
QColor nf = palette.color(QPalette::Inactive, QPalette::ButtonText);
colorCacheInvalid_ = false;
cachedButtonDetailColor_ = reduceContrast(nb, nf, qMax(qreal(2.5), KColorUtils::contrastRatio(ab, KColorUtils::mix(ab, af, 0.4))));
}
return cachedButtonDetailColor_;
}
}
//___________________________________________________
QSize NitrogenButton::sizeHint() const
{
unsigned int size( client_.configuration().buttonSize() );
return QSize( size, size );
}
//___________________________________________________
void NitrogenButton::enterEvent(QEvent *e)
{
KCommonDecorationButton::enterEvent(e);
if (status_ != Nitrogen::Pressed) status_ = Nitrogen::Hovered;
update();
}
//___________________________________________________
void NitrogenButton::leaveEvent(QEvent *e)
{
KCommonDecorationButton::leaveEvent(e);
status_ = Nitrogen::Normal;
update();
}
//___________________________________________________
void NitrogenButton::mousePressEvent(QMouseEvent *e)
{
status_ = Nitrogen::Pressed;
update();
KCommonDecorationButton::mousePressEvent(e);
}
//___________________________________________________
void NitrogenButton::mouseReleaseEvent(QMouseEvent *e)
{
status_ = Nitrogen::Normal;
update();
KCommonDecorationButton::mouseReleaseEvent(e);
}
//___________________________________________________
void NitrogenButton::paintEvent(QPaintEvent *event)
{
QPainter painter(this);
painter.setClipRect(this->rect().intersected( event->rect() ) );
QPalette palette = NitrogenButton::palette();
if( client_.isActive() ) palette.setCurrentColorGroup(QPalette::Active);
else palette.setCurrentColorGroup(QPalette::Inactive);
client_.renderWindowBackground( &painter, rect(), this, palette );
// draw dividing line
painter.setRenderHints(QPainter::Antialiasing);
QRect frame = client_.widget()->rect();
int x = -this->geometry().x()+1;
int w = frame.width()-2;
const int titleHeight = client_.layoutMetric(KCommonDecoration::LM_TitleHeight);
QColor color = ( client_.configuration().overwriteColors() ) ?
palette.window().color() :
client_.options()->color( KDecorationDefines::ColorTitleBar, client_.isActive());
QColor light = helper_.calcLightColor( color );
QColor dark = helper_.calcDarkColor( color );
dark.setAlpha(120);
if(client_.isActive() && client_.configuration().drawSeparator() )
{ helper_.drawSeparator(&painter, QRect(x, titleHeight-1.5, w, 2), color, Qt::Horizontal); }
if (type_ == ButtonMenu)
{
// we paint the mini icon using 0.72xbuttonsize() as a scale
// this roughtly corresponds to 16 for default button size
double scale = 0.72;
const QPixmap& pixmap( client_.icon().pixmap( scale*width() ) );
double offset = 0.5*(width()-pixmap.width() );
painter.drawPixmap(offset, offset, pixmap );
return;
}
color = buttonDetailColor(palette);
if(status_ == Nitrogen::Hovered || status_ == Nitrogen::Pressed)
{
if(type_ == ButtonClose) color = KColorScheme(palette.currentColorGroup()).foreground(KColorScheme::NegativeText).color();
else color = KColorScheme(palette.currentColorGroup()).decoration(KColorScheme::HoverColor).color();
}
// translate buttons up if window is not maximized
if(client_.maximizeMode() == NitrogenClient::MaximizeRestore)
{ painter.translate( 0, -1 ); }
// button shape color
QColor bt = client_.configuration().overwriteColors() ?
palette.window().color():
client_.options()->color(KDecorationDefines::ColorTitleBar, client_.isActive());
// draw button shape
painter.drawPixmap(0, 0, helper_.windecoButton(bt, status_ == Nitrogen::Pressed, client_.configuration().buttonType(), (21.0*client_.configuration().buttonSize())/22 ) );
// draw glow on hover
if( status_ == Nitrogen::Hovered )
{ painter.drawPixmap(0, 0, helper_.windecoButtonGlow(color, (21.0*client_.configuration().buttonSize())/22)); }
// draw button icon
if (client_.isActive())
{
QLinearGradient lg = helper_.decoGradient( QRect( 4, 4, 13, 13 ), color);
painter.setRenderHints(QPainter::Antialiasing);
painter.setBrush(Qt::NoBrush);
qreal width( client_.configuration().buttonType() == NitrogenConfiguration::ButtonKde43 ? 1.4:2.2 );
painter.setPen(QPen(lg, width, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin));
drawIcon(&painter, palette, type_);
} else {
QLinearGradient lg = helper_.decoGradient( QRect( 0, 0, 13, 13 ), color);
painter.setRenderHints(QPainter::Antialiasing);
painter.setBrush(Qt::NoBrush);
painter.setPen(QPen(lg, 3.0, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin));
drawIcon(&painter, palette, type_);
painter.setPen(QPen( palette.color( backgroundRole() ), 1.0, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin));
drawIcon(&painter, palette, type_);
}
}
//___________________________________________________
void NitrogenButton::drawIcon(QPainter *painter, QPalette &palette, ButtonType &type)
{
painter->save();
painter->setWindow( 0, 0, 22, 22 );
QPen newPen = painter->pen();
switch(type)
{
case ButtonSticky:
if(isChecked()) {
newPen.setColor(KColorScheme(palette.currentColorGroup()).decoration(KColorScheme::HoverColor).color());
painter->setPen(newPen);
}
painter->drawPoint(QPointF(10.5,10.5));
break;
case ButtonHelp:
painter->translate(1.5, 1.5);
painter->drawArc(7,5,4,4,135*16, -180*16);
painter->drawArc(9,8,4,4,135*16,45*16);
painter->drawPoint(9,12);
painter->translate(-1.5, -1.5);
break;
case ButtonMin:
painter->drawLine(QPointF( 7.5, 9.5), QPointF(10.5,12.5));
painter->drawLine(QPointF(10.5,12.5), QPointF(13.5, 9.5));
break;
case ButtonMax:
switch(client_.maximizeMode())
{
case NitrogenClient::MaximizeRestore:
case NitrogenClient::MaximizeVertical:
case NitrogenClient::MaximizeHorizontal:
painter->drawLine(QPointF( 7.5,11.5), QPointF(10.5, 8.5));
painter->drawLine(QPointF(10.5, 8.5), QPointF(13.5,11.5));
break;
case NitrogenClient::MaximizeFull:
{
painter->translate(1.5, 1.5);
QPoint points[4] = {QPoint(9, 6), QPoint(12, 9), QPoint(9, 12), QPoint(6, 9)};
painter->drawPolygon(points, 4);
painter->translate(-1.5, -1.5);
break;
}
}
break;
case ButtonClose:
painter->drawLine(QPointF( 7.5,7.5), QPointF(13.5,13.5));
painter->drawLine(QPointF(13.5,7.5), QPointF( 7.5,13.5));
break;
case ButtonAbove:
if(isChecked()) {
QPen newPen = painter->pen();
newPen.setColor(KColorScheme(palette.currentColorGroup()).decoration(KColorScheme::HoverColor).color());
painter->setPen(newPen);
}
painter->drawLine(QPointF( 7.5,14), QPointF(10.5,11));
painter->drawLine(QPointF(10.5,11), QPointF(13.5,14));
painter->drawLine(QPointF( 7.5,10), QPointF(10.5, 7));
painter->drawLine(QPointF(10.5, 7), QPointF(13.5,10));
break;
case ButtonBelow:
if(isChecked()) {
QPen newPen = painter->pen();
newPen.setColor(KColorScheme(palette.currentColorGroup()).decoration(KColorScheme::HoverColor).color());
painter->setPen(newPen);
}
painter->drawLine(QPointF( 7.5,11), QPointF(10.5,14));
painter->drawLine(QPointF(10.5,14), QPointF(13.5,11));
painter->drawLine(QPointF( 7.5, 7), QPointF(10.5,10));
painter->drawLine(QPointF(10.5,10), QPointF(13.5, 7));
break;
case ButtonShade:
if (!isChecked())
{
// shade button
painter->drawLine(QPointF( 7.5, 7.5), QPointF(10.5,10.5));
painter->drawLine(QPointF(10.5,10.5), QPointF(13.5, 7.5));
painter->drawLine(QPointF( 7.5,13.0), QPointF(13.5,13.0));
} else {
// unshade button
painter->drawLine(QPointF( 7.5,10.5), QPointF(10.5, 7.5));
painter->drawLine(QPointF(10.5, 7.5), QPointF(13.5,10.5));
painter->drawLine(QPointF( 7.5,13.0), QPointF(13.5,13.0));
}
break;
default:
break;
}
painter->restore();
return;
}
}

View file

@ -0,0 +1,123 @@
#ifndef nitrogenbutton_h
#define nitrogenbutton_h
// $Id: nitrogenbutton.h,v 1.8 2009/06/20 23:13:23 hpereira Exp $
//////////////////////////////////////////////////////////////////////////////
// Nitrogenbutton.h
// -------------------
// Nitrogen window decoration for KDE. Buttons.
// -------------------
// Copyright (c) 2006, 2007 Riccardo Iaconelli <ruphy@fsfe.org>
// Copyright (c) 2009, 2010 Hugo Pereira <hugo.pereira@free.fr>
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//////////////////////////////////////////////////////////////////////////////
#include <kcommondecoration.h>
#include "nitrogen.h"
#include "nitrogenclient.h"
namespace Nitrogen
{
class NitrogenClient;
enum ButtonStatus {
Normal,
Hovered,
Pressed
};
Q_DECLARE_FLAGS(ButtonState, ButtonStatus)
class NitrogenButton : public KCommonDecorationButton
{
public:
//! constructor
explicit NitrogenButton(NitrogenClient &parent,
const QString &tip=NULL,
ButtonType type=ButtonHelp);
//! destructor
~NitrogenButton();
//! destructor
QSize sizeHint() const;
//! last button mouse
// int lastMousePress() const
// {return lastmouse_;}
//! reset
void reset(long unsigned int)
{repaint();}
//! button type
ButtonType type( void ) const
{ return type_; }
protected:
//! press event
void mousePressEvent(QMouseEvent* );
//! release event
void mouseReleaseEvent(QMouseEvent* );
//! enter event
void enterEvent( QEvent* );
//! leave event
void leaveEvent(QEvent* );
//! paint
void paintEvent(QPaintEvent* );
private:
//! draw icon
void drawIcon(QPainter*, QPalette&, ButtonType& );
//! color
QColor buttonDetailColor(const QPalette& );
private:
//! parent client
NitrogenClient &client_;
//! helper
NitrogenHelper &helper_;
//! button type
ButtonType type_;
//! button status
ButtonState status_;
//! last button mouse pressed
int lastmouse_;
bool colorCacheInvalid_;
QColor cachedButtonDetailColor_;
};
} //namespace Nitrogen
#endif

View file

@ -0,0 +1,978 @@
// $Id: nitrogenclient.cpp,v 1.42 2009/07/05 21:48:27 hpereira Exp $
//////////////////////////////////////////////////////////////////////////////
// nitrogenclient.cpp
// -------------------
// Nitrogen window decoration for KDE
// -------------------
// Copyright (c) 2006, 2007 Casper Boemann <cbr@boemann.dk>
// Copyright (c) 2006, 2007 Riccardo Iaconelli <riccardo@kde.org>
// Copyright (c) 2009, 2010 Hugo Pereira <hugo.pereira@free.fr>
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//////////////////////////////////////////////////////////////////////////////
#include <cassert>
#include <cmath>
#include <iostream>
#include <kdeversion.h>
#include <KGlobal>
#include <KLocale>
#include <KColorUtils>
#include <QPainter>
#include <QTextStream>
#include <QApplication>
#include "nitrogen.h"
#include "nitrogenbutton.h"
#include "nitrogenclient.h"
#include "nitrogenclient.moc"
#include "nitrogensizegrip.h"
using namespace std;
namespace Nitrogen
{
K_GLOBAL_STATIC_WITH_ARGS(NitrogenHelper, globalHelper, ("nitrogenDeco"))
//___________________________________________
NitrogenHelper *nitrogenHelper()
{ return globalHelper; }
//___________________________________________
static void oxkwincleanupBefore()
{
NitrogenHelper *h = globalHelper;
h->invalidateCaches();
}
//___________________________________________
void renderDot(QPainter *p, const QPointF &point, qreal diameter)
{
p->drawEllipse(QRectF(point.x()-diameter/2, point.y()-diameter/2, diameter, diameter));
}
//___________________________________________
NitrogenClient::NitrogenClient(KDecorationBridge *b, KDecorationFactory *f):
KCommonDecorationUnstable(b, f),
colorCacheInvalid_(true),
size_grip_( 0 ),
helper_(*globalHelper),
initialized_( false )
{ qAddPostRoutine(oxkwincleanupBefore); }
//___________________________________________
NitrogenClient::~NitrogenClient()
{
// delete sizegrip if any
if( hasSizeGrip() ) deleteSizeGrip();
}
//___________________________________________
QString NitrogenClient::visibleName() const
{ return i18n("nitrogen"); }
//___________________________________________
void NitrogenClient::init()
{
KCommonDecoration::init();
#if KDE_IS_VERSION(4,2,92)
widget()->setAttribute(Qt::WA_NoSystemBackground );
widget()->setAttribute( Qt::WA_OpaquePaintEvent );
widget()->setAutoFillBackground( false );
#else
widget()->setAttribute(Qt::WA_NoSystemBackground, !isPreview() );
widget()->setAttribute( Qt::WA_OpaquePaintEvent, !isPreview() );
widget()->setAutoFillBackground( isPreview() );
#endif
initialized_ = true;
resetConfiguration();
}
//___________________________________________
bool NitrogenClient::isMaximized() const
{ return maximizeMode()==MaximizeFull && !options()->moveResizeMaximizedWindows(); }
//___________________________________________
bool NitrogenClient::decorationBehaviour(DecorationBehaviour behaviour) const
{
switch (behaviour)
{
case DB_MenuClose:
return true;
case DB_WindowMask:
return false;
default:
return KCommonDecoration::decorationBehaviour(behaviour);
}
}
//___________________________________________
int NitrogenClient::layoutMetric(LayoutMetric lm, bool respectWindowState, const KCommonDecorationButton *btn) const
{
bool maximized( isMaximized() );
int frameBorder( configuration().frameBorder() );
int buttonSize( configuration().buttonSize() );
switch (lm)
{
case LM_BorderLeft:
case LM_BorderRight:
case LM_BorderBottom:
{
if (respectWindowState && maximized) {
return 0;
} else if( configuration().frameBorder() == 0 && isPreview() ) {
return 1;
} else {
return frameBorder;
}
}
case LM_TitleEdgeTop:
{
if (respectWindowState && maximized) {
return 0;
} else {
return qMax( 3, frameBorder-2 );
}
}
case LM_TitleEdgeBottom:
{
return 0;
}
case LM_TitleEdgeLeft:
case LM_TitleEdgeRight:
{
if (respectWindowState && maximized) {
return 0;
} else {
return 6;
}
}
case LM_TitleBorderLeft:
case LM_TitleBorderRight:
return 5;
case LM_ButtonWidth:
case LM_ButtonHeight:
case LM_TitleHeight:
{
if (respectWindowState && isToolWindow()) {
return buttonSize;
} else {
return buttonSize;
}
}
case LM_ButtonSpacing:
return 1;
case LM_ButtonMarginTop:
return 0;
#if KDE_IS_VERSION(4,2,92)
// outer margin for shadow/glow
case LM_OuterPaddingLeft:
case LM_OuterPaddingRight:
case LM_OuterPaddingTop:
case LM_OuterPaddingBottom:
if( NitrogenConfiguration::useCompiz() ) return 0;
else return SHADOW_WIDTH;
#endif
default:
return KCommonDecoration::layoutMetric(lm, respectWindowState, btn);
}
}
//_________________________________________________
int NitrogenClient::borderWidth( void ) const
{
return
layoutMetric( LM_BorderLeft )+
layoutMetric( LM_BorderRight );
}
//_________________________________________________
int NitrogenClient::borderHeight( void ) const
{
return
layoutMetric( LM_TitleHeight ) +
layoutMetric( LM_TitleEdgeTop ) +
layoutMetric( LM_TitleEdgeBottom ) +
layoutMetric( LM_BorderBottom );
}
//_________________________________________________________
KCommonDecorationButton *NitrogenClient::createButton(::ButtonType type)
{
switch (type) {
case MenuButton:
return new NitrogenButton(*this, i18n("Menu"), ButtonMenu);
case HelpButton:
return new NitrogenButton(*this, i18n("Help"), ButtonHelp);
case MinButton:
return new NitrogenButton(*this, i18n("Minimize"), ButtonMin);
case MaxButton:
return new NitrogenButton(*this, i18n("Maximize"), ButtonMax);
case CloseButton:
return new NitrogenButton(*this, i18n("Close"), ButtonClose);
case AboveButton:
return new NitrogenButton(*this, i18n("Keep Above Others"), ButtonAbove);
case BelowButton:
return new NitrogenButton(*this, i18n("Keep Below Others"), ButtonBelow);
case OnAllDesktopsButton:
return new NitrogenButton(*this, i18n("On All Desktops"), ButtonSticky);
case ShadeButton:
return new NitrogenButton(*this, i18n("Shade Button"), ButtonShade);
default:
return 0;
}
}
//_________________________________________________________
QColor reduceContrast(const QColor &c0, const QColor &c1, double t)
{
double s = KColorUtils::contrastRatio(c0, c1);
if (s < t)
return c1;
double l = 0.0, h = 1.0;
double x = s, a;
QColor r = c1;
for (int maxiter = 16; maxiter; --maxiter)
{
a = 0.5 * (l + h);
r = KColorUtils::mix(c0, c1, a);
x = KColorUtils::contrastRatio(c0, r);
if (fabs(x - t) < 0.01) break;
if (x > t) h = a;
else l = a;
}
return r;
}
//_________________________________________________________
QRegion NitrogenClient::calcMask( void ) const
{
if( isMaximized() )
{ return widget()->rect(); }
QRect frame( widget()->rect() );
// dimensions
int w=frame.width();
int h=frame.height();
// multipliers
int left = 1;
int right = 1;
int top = 1;
int bottom = 1;
// disable bottom corners when border frame is too small
if( configuration().frameBorder() <= NitrogenConfiguration::BorderTiny ) bottom = 0;
#if KDE_IS_VERSION(4,2,92)
int sw = layoutMetric( LM_OuterPaddingLeft );
int sh = layoutMetric( LM_OuterPaddingTop );
w -= sw + layoutMetric( LM_OuterPaddingRight );
h -= sh + layoutMetric( LM_OuterPaddingBottom );
QRegion mask(sw + 5*left, sh + 0*top, w-5*(left+right), h-0*(top+bottom));
mask += QRegion(sw + 0*left, sh + 5*top, w-0*(left+right), h-5*(top+bottom));
mask += QRegion(sw + 2*left, sh + 2*top, w-2*(left+right), h-2*(top+bottom));
mask += QRegion(sw + 3*left, sh + 1*top, w-3*(left+right), h-1*(top+bottom));
mask += QRegion(sw + 1*left, sh + 3*top, w-1*(left+right), h-3*(top+bottom));
return mask;
#else
if (!shadowsActive()) {
QRegion mask (4*left, 0*top, w-4*(left+right), h);
mask += QRegion(0*left, 4*top, w-0*(left+right), h-4*(top+bottom));
mask += QRegion(2*left, 1*top, w-2*(left+right), h-1*(top+bottom));
mask += QRegion(1*left, 2*top, w-1*(left+right), h-2*(top+bottom));
return mask;
} else {
QRegion mask(5*left, 0*top, w-5*(left+right), h-0*(top+bottom));
mask += QRegion(0*left, 5*top, w-0*(left+right), h-5*(top+bottom));
mask += QRegion(2*left, 2*top, w-2*(left+right), h-2*(top+bottom));
mask += QRegion(3*left, 1*top, w-3*(left+right), h-1*(top+bottom));
mask += QRegion(1*left, 3*top, w-1*(left+right), h-3*(top+bottom));
return mask;
}
#endif
}
//_________________________________________________________
QColor NitrogenClient::titlebarTextColor(const QPalette &palette)
{
if( !configuration().overwriteColors() )
{
return options()->color(ColorFont, isActive());
} else if (isActive()) {
return palette.color(QPalette::Active, QPalette::WindowText);
} else {
if(colorCacheInvalid_)
{
QColor ab = palette.color(QPalette::Active, QPalette::Window);
QColor af = palette.color(QPalette::Active, QPalette::WindowText);
QColor nb = palette.color(QPalette::Inactive, QPalette::Window);
QColor nf = palette.color(QPalette::Inactive, QPalette::WindowText);
colorCacheInvalid_ = false;
cachedTitlebarTextColor_ = reduceContrast(nb, nf, qMax(qreal(2.5), KColorUtils::contrastRatio(ab, KColorUtils::mix(ab, af, 0.4))));
}
return cachedTitlebarTextColor_;
}
}
//_________________________________________________________
void NitrogenClient::renderWindowBackground( QPainter* painter, const QRect& rect, const QWidget* widget, const QPalette& palette ) const
{
//if( configuration().blendColor() == NitrogenConfiguration::NoBlending || isPreview() )
if( configuration().blendColor() == NitrogenConfiguration::NoBlending )
{
painter->fillRect( rect, backgroundPalette( widget, palette ).color( widget->window()->backgroundRole() ) );
} else {
int offset( configuration().buttonSize() - 22 );
#if KDE_IS_VERSION(4,2,92)
offset += layoutMetric( LM_OuterPaddingBottom );
#endif
helper().renderWindowBackground(painter, rect, widget, backgroundPalette( widget, palette ), offset );
}
}
//_________________________________________________________
void NitrogenClient::activeChange( void )
{
// update size grip so that it gets the right color
if( hasSizeGrip() )
{
sizeGrip().updateBackgroundColor();
sizeGrip().update();
}
KCommonDecorationUnstable::activeChange();
}
//_________________________________________________________
QPalette NitrogenClient::backgroundPalette( const QWidget* widget, QPalette palette ) const
{
if( !configuration().overwriteColors() )
{ palette.setColor( widget->window()->backgroundRole(), options()->color( KDecorationDefines::ColorTitleBar, isActive() ) ); }
return palette;
}
//________________________________________________________________
void NitrogenClient::drawStripes(QPainter *p, QPalette &palette, const int start, const int end, const int topMargin)
{
QColor color( KDecoration::options()->color(ColorTitleBar) );
QLinearGradient scratchlg(QPoint(start,0), QPoint(end,0));
scratchlg.setColorAt(0.0, Qt::transparent);
scratchlg.setColorAt(0.05, helper().calcDarkColor(color) );
scratchlg.setColorAt(1.0, Qt::transparent);
QPen pen1(scratchlg, 0.5);
QLinearGradient scratchlg2(QPoint(start,0), QPoint(end,0));
scratchlg2.setColorAt(0.0, Qt::transparent);
scratchlg2.setColorAt(0.05, helper().calcLightColor(palette.color(QPalette::Window)) );
scratchlg2.setColorAt(1.0, Qt::transparent);
QPen pen2(scratchlg2, 0.5);
bool antialiasing = p->testRenderHint(QPainter::Antialiasing);
p->setRenderHint(QPainter::Antialiasing, false);
const int titleHeight = layoutMetric(LM_TitleHeight);
double voffset = 4.0*configuration().buttonSize()/22;
double scale = double(titleHeight-voffset)/4;
double base = titleHeight + topMargin;
for (int i = 0; i < 3; ++i)
{
// calculate offset for each stripe.
int offset = int(base - voffset) - int(scale)*(i+1);
p->setPen(pen1);
p->drawLine(QPoint(start, offset), QPoint(end, offset));
p->setPen(pen2);
p->drawLine(QPoint(start, offset+1), QPoint(end, offset+1));
}
p->setRenderHint(QPainter::Antialiasing, antialiasing);
}
//________________________________________________________________
void NitrogenClient::updateWindowShape()
{
#if KDE_IS_VERSION(4,2,92)
if(isMaximized() || ( compositingActive() && !NitrogenConfiguration::useCompiz() ) )
{
clearMask();
} else
#endif
{
setMask( calcMask() );
}
}
#if !KDE_IS_VERSION(4,2,92)
//________________________________________________________________
QList<QRect> NitrogenClient::shadowQuads( ShadowType ) const
{
QSize size = widget()->size();
int outside=21, underlap=4, cornersize=25;
// These are underlap under the decoration so the corners look nicer 10px on the outside
QList<QRect> quads;
quads.append(QRect(-outside, size.height()-underlap, cornersize, cornersize));
quads.append(QRect(underlap, size.height()-underlap, size.width()-2*underlap, cornersize));
quads.append(QRect(size.width()-underlap, size.height()-underlap, cornersize, cornersize));
quads.append(QRect(-outside, underlap, cornersize, size.height()-2*underlap));
quads.append(QRect(size.width()-underlap, underlap, cornersize, size.height()-2*underlap));
quads.append(QRect(-outside, -outside, cornersize, cornersize));
quads.append(QRect(underlap, -outside, size.width()-2*underlap, cornersize));
quads.append(QRect(size.width()-underlap, -outside, cornersize, cornersize));
return quads;
}
//________________________________________________________________
double NitrogenClient::shadowOpacity( ShadowType type ) const
{
switch( type ) {
case ShadowBorderedActive:
if( isActive() ) return 1.0;
else return 0.0;
case ShadowBorderedInactive:
if( isActive() ) return 0.0;
else return 1.0;
default:
abort();
}
return 0;
}
#endif
//___________________________________________
void NitrogenClient::resetConfiguration( void )
{
if( !initialized_ ) return;
configuration_ = NitrogenFactory::configuration( *this );
QTextStream( stdout ) << "NitrogenClient::resetConfiguration - useCompiz: " << NitrogenConfiguration::useCompiz() << endl;
// handle size grip
if( configuration_.drawSizeGrip() )
{
if( !hasSizeGrip() ) createSizeGrip();
} else if( hasSizeGrip() ) deleteSizeGrip();
}
//_________________________________________________________
void NitrogenClient::paintEvent( QPaintEvent* event )
{
// factory
if(!( initialized_ && NitrogenFactory::initialized() ) ) return;
// palette
QPalette palette = widget()->palette();
palette.setCurrentColorGroup( (isActive() ) ? QPalette::Active : QPalette::Inactive );
// painter
QPainter painter(widget());
painter.setClipRegion( event->region() );
// define frame
QRect frame = widget()->rect();
// base color
QColor color = ( configuration().overwriteColors() ) ?
palette.window().color() :
options()->color( ColorTitleBar, isActive());
#if KDE_IS_VERSION(4,2,92)
// draw shadows
if( compositingActive() && !( NitrogenConfiguration::useCompiz() || isMaximized() ) )
{
shadowTiles(
color,KDecoration::options()->color(ColorTitleBar),
SHADOW_WIDTH, configuration().useOxygenShadows() && isActive() )->render( frame.adjusted( 4, 4, -4, -4),
&painter, TileSet::Ring);
}
// adjust frame to match outer margins
frame.adjust(
layoutMetric( LM_OuterPaddingLeft ),
layoutMetric( LM_OuterPaddingTop ),
-layoutMetric( LM_OuterPaddingRight ),
-layoutMetric( LM_OuterPaddingBottom ) );
// adjust mask
if( (compositingActive() && !NitrogenConfiguration::useCompiz()) || isPreview() )
{
int x, y, w, h;
frame.getRect(&x, &y, &w, &h);
// multipliers
int left = 1;
int right = 1;
int top = 1;
int bottom = 1;
// disable bottom corners when border frame is too small
if( configuration().frameBorder() <= NitrogenConfiguration::BorderTiny ) bottom = 0;
QRegion mask( x+5*left, y+0*top, w-5*(left+right), h-0*(top+bottom));
mask += QRegion(x+0*left, y+5*top, w-0*(left+right), h-5*(top+bottom));
mask += QRegion(x+2*left, y+2*top, w-2*(left+right), h-2*(top+bottom));
mask += QRegion(x+3*left, y+1*top, w-3*(left+right), h-1*(top+bottom));
mask += QRegion(x+1*left, y+3*top, w-1*(left+right), h-3*(top+bottom));
painter.setClipRegion( mask );
}
#endif
// window background
renderWindowBackground( &painter, frame, widget(), palette );
// clipping
if( compositingActive() && !NitrogenConfiguration::useCompiz() ) painter.setClipping(false);
// in preview mode and when frame border is 0,
// one still draw a small rect around, unless kde is recent enough,
// useOxygenShadow is set to true,
// and copositing is active
// (that makes a lot of ifs)
#if KDE_IS_VERSION(4,2,92)
if(
isPreview() && configuration().frameBorder() == 0 &&
( !compositingActive() || NitrogenConfiguration::useCompiz() ) )
#else
if( isPreview() && configuration().frameBorder() == 0 )
#endif
{
painter.save();
painter.setBrush( Qt::NoBrush );
painter.setPen( QPen( helper().calcDarkColor( widget()->palette().window().color() ), 1 ) );
QPainterPath path;
QPoint first( frame.topLeft()+QPoint( 0, 6 ) );
path.moveTo( first );
path.quadTo( frame.topLeft(), frame.topLeft()+QPoint( 6, 0 ) );
path.lineTo( frame.topRight()-QPoint( 6, 0 ) );
path.quadTo( frame.topRight(), frame.topRight()+QPoint( 0, 6 ) );
path.lineTo( frame.bottomRight() );
path.lineTo( frame.bottomLeft() );
path.lineTo( first );
painter.drawPath( path );
painter.restore();
}
// dimensions
const int titleHeight = layoutMetric(LM_TitleHeight);
const int titleTop = layoutMetric(LM_TitleEdgeTop) + frame.top();
const int titleEdgeLeft = layoutMetric(LM_TitleEdgeLeft);
const int marginLeft = layoutMetric(LM_TitleBorderLeft);
const int marginRight = layoutMetric(LM_TitleBorderRight);
const int titleLeft = frame.left() + titleEdgeLeft + buttonsLeftWidth() + marginLeft;
const int titleWidth = frame.width() -
titleEdgeLeft - layoutMetric(LM_TitleEdgeRight) -
buttonsLeftWidth() - buttonsRightWidth() -
marginLeft - marginRight;
// draw title text
painter.setPen( titlebarTextColor( backgroundPalette( widget(), palette ) ) );
painter.setFont( options()->font(isActive(), false) );
painter.drawText(titleLeft, titleTop-1, titleWidth, titleHeight, configuration().titleAlignment() | Qt::AlignVCenter, caption() );
painter.setRenderHint(QPainter::Antialiasing);
// adjust if there are shadows
#if KDE_IS_VERSION(4,2,92)
if (compositingActive()) frame.adjust(-1,-1,1,1);
#else
if (shadowsActive()) frame.adjust(-1,-1, 1, 1);
#endif
// dimensions
int x,y,w,h;
frame.getRect(&x, &y, &w, &h);
// separator
if( isActive() && configuration().drawSeparator() )
{ helper().drawSeparator(&painter, QRect(x, titleTop+titleHeight-1.5, w, 2), color, Qt::Horizontal); }
// draw stripes as indicator for active windows
if( isActive() && configuration().showStripes() )
{
Qt::Alignment align = configuration().titleAlignment();
if (widget()->layoutDirection() == Qt::RightToLeft)
{
if (align == Qt::AlignLeft) align = Qt::AlignRight;
else if (align == Qt::AlignRight) align = Qt::AlignLeft;
}
if (align & Qt::AlignLeft) {
int left = titleLeft + QFontMetrics(options()->font(isActive(), false)).width( caption() ) + 4;
int right = titleLeft + titleWidth;
drawStripes(&painter, palette, left, right, titleTop);
} else if (align & Qt::AlignRight) {
int left = titleLeft;
int right = titleLeft + titleWidth - QFontMetrics(options()->font(isActive(), false)).width( caption() ) - 4;
drawStripes(&painter, palette, right, left, titleTop);
} else if (align & Qt::AlignHCenter) {
int textWidth = QFontMetrics(options()->font(isActive(), false)).width( caption() );
int left = titleLeft;
int centerLeft = titleLeft + titleWidth/2 - textWidth/2 - 4;
int centerRight = titleLeft + titleWidth/2 + textWidth/2 + 4;
int right = titleLeft + titleWidth;
drawStripes(&painter, palette, centerLeft, left, titleTop);
drawStripes(&painter, palette, centerRight, right, titleTop);
}
}
// shadow and resize handles
if( !isMaximized() )
{
#if KDE_IS_VERSION(4,2,92)
helper().drawFloatFrame(
&painter, frame, color, !compositingActive(), isActive(),
KDecoration::options()->color(ColorTitleBar),
configuration().frameBorder()
);
#else
helper().drawFloatFrame(
&painter, frame, color, !shadowsActive(), isActive(),
KDecoration::options()->color(ColorTitleBar),
configuration().frameBorder()
);
#endif
if( isResizable() && configuration().frameBorder() >= NitrogenConfiguration::BorderSmall )
{
// Draw the 3-dots resize handles
qreal cenY = h / 2 + x + 0.5;
qreal posX = w + y - 2.5;
painter.setPen(Qt::NoPen);
painter.setBrush(QColor(0, 0, 0, 66));
renderDot(&painter, QPointF(posX, cenY - 3), 1.8);
renderDot(&painter, QPointF(posX, cenY), 1.8);
renderDot(&painter, QPointF(posX, cenY + 3), 1.8);
// Draw the 3-dots resize handles
if( !configuration().drawSizeGrip() )
{
painter.translate(x + w-9, y + h-9);
renderDot(&painter, QPointF(2.5, 6.5), 1.8);
renderDot(&painter, QPointF(5.5, 5.5), 1.8);
renderDot(&painter, QPointF(6.5, 2.5), 1.8);
}
}
}
}
//________________________________________________________________
NitrogenConfiguration NitrogenClient::configuration( void ) const
{ return configuration_; }
//_________________________________________________________________
void NitrogenClient::createSizeGrip( void )
{
assert( !hasSizeGrip() );
if( (!isPreview()) && isResizable() && windowId() != 0 )
{ size_grip_ = new NitrogenSizeGrip( this ); }
}
//_________________________________________________________________
void NitrogenClient::deleteSizeGrip( void )
{
assert( hasSizeGrip() );
size_grip_->deleteLater();
size_grip_ = 0;
}
//_________________________________________________________________
#if KDE_IS_VERSION(4,2,92)
TileSet *NitrogenClient::shadowTiles(const QColor& color, const QColor& glow, qreal size, bool active)
{
ShadowTilesOption opt;
opt.active = active;
opt.width = size;
opt.windowColor = color;
opt.glowColor = glow;
ShadowTilesOption currentOpt = active ? shadowTilesOption_ : glowTilesOption_;
bool optionChanged = true;
if (currentOpt.active == opt.active
&& currentOpt.width == opt.width
&& opt.windowColor == opt.windowColor
&& opt.glowColor == opt.glowColor)
optionChanged = false;
if (active && glowTiles_ && !optionChanged)
return glowTiles_;
else if (!active && shadowTiles_ && !optionChanged)
return shadowTiles_;
TileSet *tileSet = 0;
//---------------------------------------------------------------
// Create new glow/shadow tiles
QColor light = helper().calcLightColor( helper().backgroundTopColor(color) );
QColor dark = helper().calcDarkColor(helper().backgroundBottomColor(color));
QPixmap shadow = QPixmap( size*2, size*2 );
shadow.fill( Qt::transparent );
// draw the corner of the window - actually all 4 corners as one circle
QLinearGradient lg = QLinearGradient(0.0, size-4.5, 0.0, size+4.5);
if( configuration().frameBorder() <= NitrogenConfiguration::BorderTiny )
{
lg.setColorAt(0, helper().backgroundTopColor(color) );
lg.setColorAt(0.52, helper().backgroundTopColor(color));
lg.setColorAt(1.0, helper().backgroundBottomColor(color) );
} else {
lg.setColorAt(0.52, light);
lg.setColorAt(1.0, dark);
}
QPainter p( &shadow );
p.setRenderHint( QPainter::Antialiasing );
p.setPen( Qt::NoPen );
if (active)
{
//---------------------------------------------------------------
// Active shadow texture
QRadialGradient rg( size, size, size );
QColor c = color;
c.setAlpha( 255 ); rg.setColorAt( 4.4/size, c );
c.setAlpha( 220 ); rg.setColorAt( 4.5/size, c );
c.setAlpha( 180 ); rg.setColorAt( 5/size, c );
c.setAlpha( 25 ); rg.setColorAt( 5.5/size, c );
c.setAlpha( 0 ); rg.setColorAt( 6.5/size, c );
p.setBrush( rg );
p.drawRect( shadow.rect() );
rg = QRadialGradient( size, size, size );
c = color;
c.setAlpha( 255 ); rg.setColorAt( 4.4/size, c );
c = glow;
c.setAlpha( 0.58*255 ); rg.setColorAt( 4.5/size, c );
c.setAlpha( 0.43*255 ); rg.setColorAt( 5.5/size, c );
c.setAlpha( 0.30*255 ); rg.setColorAt( 6.5/size, c );
c.setAlpha( 0.22*255 ); rg.setColorAt( 7.5/size, c );
c.setAlpha( 0.15*255 ); rg.setColorAt( 8.5/size, c );
c.setAlpha( 0.08*255 ); rg.setColorAt( 11.5/size, c );
c.setAlpha( 0); rg.setColorAt( 14.5/size, c );
p.setRenderHint( QPainter::Antialiasing );
p.setBrush( rg );
p.drawRect( shadow.rect() );
p.setBrush( Qt::NoBrush );
p.setPen(QPen(lg, 0.8));
p.drawEllipse(QRectF(size-4, size-4, 8, 8));
p.end();
tileSet = new TileSet(shadow, size, size, 1, 1);
glowTilesOption_ = opt;
glowTiles_ = tileSet;
} else {
//---------------------------------------------------------------
// Inactive shadow texture
QRadialGradient rg = QRadialGradient( size, size+4, size );
QColor c = QColor( Qt::black );
c.setAlpha( 0.12*255 ); rg.setColorAt( 4.5/size, c );
c.setAlpha( 0.11*255 ); rg.setColorAt( 6.6/size, c );
c.setAlpha( 0.075*255 ); rg.setColorAt( 8.5/size, c );
c.setAlpha( 0.06*255 ); rg.setColorAt( 11.5/size, c );
c.setAlpha( 0.035*255 ); rg.setColorAt( 14.5/size, c );
c.setAlpha( 0.025*255 ); rg.setColorAt( 17.5/size, c );
c.setAlpha( 0.01*255 ); rg.setColorAt( 21.5/size, c );
c.setAlpha( 0.0*255 ); rg.setColorAt( 25.5/size, c );
p.setRenderHint( QPainter::Antialiasing );
p.setPen( Qt::NoPen );
p.setBrush( rg );
p.drawRect( shadow.rect() );
rg = QRadialGradient( size, size+2, size );
c = QColor( Qt::black );
c.setAlpha( 0.25*255 ); rg.setColorAt( 4.5/size, c );
c.setAlpha( 0.20*255 ); rg.setColorAt( 5.5/size, c );
c.setAlpha( 0.13*255 ); rg.setColorAt( 7.5/size, c );
c.setAlpha( 0.06*255 ); rg.setColorAt( 8.5/size, c );
c.setAlpha( 0.015*255 ); rg.setColorAt( 11.5/size, c );
c.setAlpha( 0.0*255 ); rg.setColorAt( 14.5/size, c );
p.setRenderHint( QPainter::Antialiasing );
p.setPen( Qt::NoPen );
p.setBrush( rg );
p.drawRect( shadow.rect() );
rg = QRadialGradient( size, size+0.2, size );
c = color;
c = QColor( Qt::black );
c.setAlpha( 0.35*255 ); rg.setColorAt( 0/size, c );
c.setAlpha( 0.32*255 ); rg.setColorAt( 4.5/size, c );
c.setAlpha( 0.22*255 ); rg.setColorAt( 5.0/size, c );
c.setAlpha( 0.03*255 ); rg.setColorAt( 5.5/size, c );
c.setAlpha( 0.0*255 ); rg.setColorAt( 6.5/size, c );
p.setRenderHint( QPainter::Antialiasing );
p.setPen( Qt::NoPen );
p.setBrush( rg );
p.drawRect( shadow.rect() );
rg = QRadialGradient( size, size, size );
c = color;
c.setAlpha( 255 ); rg.setColorAt( 4.0/size, c );
c.setAlpha( 0 ); rg.setColorAt( 4.01/size, c );
p.setRenderHint( QPainter::Antialiasing );
p.setPen( Qt::NoPen );
p.setBrush( rg );
p.drawRect( shadow.rect() );
// draw the corner of the window - actually all 4 corners as one circle
p.setBrush( Qt::NoBrush );
p.setPen(QPen(lg, 0.8));
p.drawEllipse(QRectF(size-4, size-4, 8, 8));
p.end();
tileSet = new TileSet(shadow, size, size, 1, 1);
shadowTilesOption_ = opt;
shadowTiles_ = tileSet;
}
return tileSet;
}
#endif
}

View file

@ -0,0 +1,5 @@
# KDE Desktop Entry
[Desktop Entry]
Name=Nitrogen
Name[x-test]=xxNitrogenxx
X-KDE-Library=kwin3_nitrogen

View file

@ -0,0 +1,179 @@
#ifndef nitrogenclient_h
#define nitrogenclient_h
// $Id: nitrogenclient.h,v 1.13 2009/07/05 17:56:25 hpereira Exp $
/******************************************************************************
*
* Copyright (C) 2002 Hugo PEREIRA <mailto: hugo.pereira@free.fr>
*
* This 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 software 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
* software; if not, write to the Free Software Foundation, Inc., 59 Temple
* Place, Suite 330, Boston, MA 02111-1307 USA
*
*
*******************************************************************************/
#include <kcommondecoration.h>
#include "kdeversion.h"
#include "nitrogenconfiguration.h"
#include "lib/helper.h"
#include "lib/tileset.h"
namespace Nitrogen
{
class NitrogenSizeGrip;
class NitrogenClient : public KCommonDecorationUnstable
{
Q_OBJECT
public:
//! constructor
NitrogenClient(KDecorationBridge *b, KDecorationFactory *f);
//! destructor
virtual ~NitrogenClient();
virtual QString visibleName() const;
virtual KCommonDecorationButton *createButton(::ButtonType type);
virtual bool decorationBehaviour(DecorationBehaviour behaviour) const;
//! true if window is maximized
virtual bool isMaximized( void ) const;
//! dimensions
virtual int layoutMetric(LayoutMetric lm, bool respectWindowState = true, const KCommonDecorationButton * = 0) const;
//! border width
/*! full border width, left and right */
virtual int borderWidth( void ) const;
//! border height
/*! full border height, top and bottom */
virtual int borderHeight( void ) const;
//! window shape
virtual void updateWindowShape();
//! initialization
virtual void init();
#if !KDE_IS_VERSION(4,2,92)
virtual QList<QRect> shadowQuads( ShadowType type ) const;
virtual double shadowOpacity( ShadowType type ) const;
#endif
//! return associated configuration
NitrogenConfiguration configuration( void ) const;
//! helper class
NitrogenHelper& helper( void ) const
{ return helper_; }
//! window background
virtual void renderWindowBackground( QPainter*, const QRect&, const QWidget*, const QPalette& ) const;
//! triggered when window activity is changed
virtual void activeChange();
public slots:
//! reset configuration
void resetConfiguration( void );
protected:
//! paint
void paintEvent( QPaintEvent* );
//! shadows
TileSet *shadowTiles(const QColor& color, const QColor& glow, qreal size, bool active);
private:
struct ShadowTilesOption {
QColor windowColor;
QColor glowColor;
qreal width;
bool active;
};
//! palette background
QPalette backgroundPalette( const QWidget*, QPalette ) const;
//! draw
void drawStripes(QPainter*, QPalette&, const int, const int, const int);
//! calculate mask
QRegion calcMask( void ) const;
//! text color
QColor titlebarTextColor(const QPalette&);
//!@name size grip
//@{
//! create size grip
void createSizeGrip( void );
//! delete size grip
void deleteSizeGrip( void );
// size grip
bool hasSizeGrip( void ) const
{ return (bool)size_grip_; }
//! size grip
NitrogenSizeGrip& sizeGrip( void ) const
{ return *size_grip_; }
//@}
//! configuration
NitrogenConfiguration configuration_;
//! used to invalidate color cache
bool colorCacheInvalid_;
//! stored color
QColor cachedTitlebarTextColor_;
//! size grip widget
NitrogenSizeGrip* size_grip_;
#if KDE_IS_VERSION(4,2,92)
ShadowTilesOption shadowTilesOption_;
ShadowTilesOption glowTilesOption_;
TileSet *shadowTiles_;
TileSet *glowTiles_;
#endif
//! helper
NitrogenHelper& helper_;
//! true when initialized
bool initialized_;
};
} // namespace Nitrogen
#endif // EXAMPLECLIENT_H

View file

@ -0,0 +1,296 @@
// $Id: nitrogenconfiguration.cpp,v 1.20 2009/07/05 20:50:42 hpereira Exp $
/******************************************************************************
*
* Copyright (C) 2002 Hugo PEREIRA <mailto: hugo.pereira@free.fr>
*
* This 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 software 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
* software; if not, write to the Free Software Foundation, Inc., 59 Temple
* Place, Suite 330, Boston, MA 02111-1307 USA
*
*
*******************************************************************************/
/*!
\file nitrogenconfiguration.cpp
\brief encapsulated window decoration configuration
\author Hugo Pereira
\version $Revision: 1.20 $
\date $Date: 2009/07/05 20:50:42 $
*/
#include <QDBusMessage>
#include <QDBusConnection>
#include <QProcess>
#include <kdeversion.h>
#include "nitrogenconfiguration.h"
namespace Nitrogen
{
//__________________________________________________
bool NitrogenConfiguration::useCompiz_;
//__________________________________________________
NitrogenConfiguration::NitrogenConfiguration( void ):
titleAlignment_( Qt::AlignLeft ),
buttonSize_( ButtonDefault ),
buttonType_( ButtonKde42 ),
frameBorder_( BorderDefault ),
blendColor_( RadialBlending ),
showStripes_( false ),
drawSeparator_( false ),
overwriteColors_( true ),
drawSizeGrip_( false ),
useOxygenShadows_( true )
{}
//__________________________________________________
NitrogenConfiguration::NitrogenConfiguration( KConfigGroup group )
{
// used to set default values when entries are not found in kconfig
NitrogenConfiguration defaultConfiguration;
// title alignment
setTitleAlignment( titleAlignment(
group.readEntry( NitrogenConfig::TITLE_ALIGNMENT,
defaultConfiguration.titleAlignmentName() ) ) );
// button size
setButtonSize( buttonSize(
group.readEntry( NitrogenConfig::BUTTON_SIZE,
defaultConfiguration.buttonSizeName() ) ) );
// button type
setButtonType( buttonType(
group.readEntry( NitrogenConfig::BUTTON_TYPE,
defaultConfiguration.buttonTypeName() ) ) );
// frame border
setFrameBorder( frameBorder(
group.readEntry( NitrogenConfig::FRAME_BORDER,
defaultConfiguration.frameBorderName() ) ) );
// blend color
setBlendColor( blendColor(
group.readEntry( NitrogenConfig::BLEND_COLOR,
defaultConfiguration.blendColorName() ) ) );
// show stripes
setShowStripes( group.readEntry(
NitrogenConfig::SHOW_STRIPES,
defaultConfiguration.showStripes() ) );
// draw separator
setDrawSeparator( group.readEntry(
NitrogenConfig::DRAW_SEPARATOR,
defaultConfiguration.drawSeparator() ) );
// overwrite color
setOverwriteColors( group.readEntry(
NitrogenConfig::OVERWRITE_COLORS,
defaultConfiguration.overwriteColors() ) );
// size grip
setDrawSizeGrip( group.readEntry(
NitrogenConfig::DRAW_SIZE_GRIP,
defaultConfiguration.drawSizeGrip() ) );
// oxygen shadows
setUseOxygenShadows( group.readEntry(
NitrogenConfig::USE_OXYGEN_SHADOWS,
defaultConfiguration.useOxygenShadows() ) );
}
//__________________________________________________
bool NitrogenConfiguration::checkUseCompiz( void )
{
#if KDE_IS_VERSION(4,2,92)
// for some reason, org.kde.compiz does not appear
// in dbus list with kde 4.3
QProcess p;
p.start( "ps", QStringList() << "-A" );
p.waitForFinished();
QString output( p.readAll() );
return ( useCompiz_ = ( output.indexOf( QRegExp( "\\b(compiz)\\b" ) ) >= 0 ) );
#else
QDBusMessage message = QDBusMessage::createMethodCall(
"org.freedesktop.compiz",
"/org/freedesktop/compiz",
"org.freedesktop.compiz",
"getPlugins" );
QDBusMessage reply = QDBusConnection::sessionBus().call( message );
return ( useCompiz_ = ( reply.type() == QDBusMessage::ReplyMessage && !reply.arguments().empty() ) );
#endif
}
//__________________________________________________
void NitrogenConfiguration::write( KConfigGroup& group ) const
{
group.writeEntry( NitrogenConfig::TITLE_ALIGNMENT, titleAlignmentName() );
group.writeEntry( NitrogenConfig::BUTTON_SIZE, buttonSizeName() );
group.writeEntry( NitrogenConfig::BUTTON_TYPE, buttonTypeName() );
group.writeEntry( NitrogenConfig::BLEND_COLOR, blendColorName() );
group.writeEntry( NitrogenConfig::FRAME_BORDER, frameBorderName() );
group.writeEntry( NitrogenConfig::SHOW_STRIPES, showStripes() );
group.writeEntry( NitrogenConfig::DRAW_SEPARATOR, drawSeparator() );
group.writeEntry( NitrogenConfig::OVERWRITE_COLORS, overwriteColors() );
group.writeEntry( NitrogenConfig::DRAW_SIZE_GRIP, drawSizeGrip() );
group.writeEntry( NitrogenConfig::USE_OXYGEN_SHADOWS, useOxygenShadows() );
}
//__________________________________________________
QString NitrogenConfiguration::titleAlignmentName( Qt::Alignment value )
{
switch( value )
{
case Qt::AlignLeft: return "Left";
case Qt::AlignHCenter: return "Center";
case Qt::AlignRight: return "Right";
default: return NitrogenConfiguration().titleAlignmentName();
}
return QString();
}
//__________________________________________________
Qt::Alignment NitrogenConfiguration::titleAlignment( QString value )
{
if (value == "Left") return Qt::AlignLeft;
else if (value == "Center") return Qt::AlignHCenter;
else if (value == "Right") return Qt::AlignRight;
else return NitrogenConfiguration().titleAlignment();
}
//__________________________________________________
QString NitrogenConfiguration::buttonSizeName( ButtonSize value )
{
switch( value )
{
case ButtonSmall: return "Small";
case ButtonDefault: return "Default";
case ButtonLarge: return "Large";
case ButtonHuge: return "Huge";
default: return NitrogenConfiguration().buttonSizeName();
}
return QString();
}
//__________________________________________________
NitrogenConfiguration::ButtonSize NitrogenConfiguration::buttonSize( QString value )
{
if( value == "Small" ) return ButtonSmall;
else if( value == "Default" ) return ButtonDefault;
else if( value == "Large" ) return ButtonLarge;
else if( value == "Huge" ) return ButtonHuge;
else return NitrogenConfiguration().buttonSize();
}
//__________________________________________________
QString NitrogenConfiguration::buttonTypeName( ButtonType value )
{
switch( value )
{
case ButtonKde42: return "Kde 4.2";
case ButtonKde43: return "Kde 4.3";
default: return NitrogenConfiguration().buttonTypeName();
}
return QString();
}
//__________________________________________________
NitrogenConfiguration::ButtonType NitrogenConfiguration::buttonType( QString value )
{
if( value == "Kde 4.2" ) return ButtonKde42;
else if( value == "Kde 4.3" ) return ButtonKde43;
else return NitrogenConfiguration().buttonType();
}
//__________________________________________________
QString NitrogenConfiguration::frameBorderName( FrameBorder value )
{
switch( value )
{
case BorderNone: return "No Border";
case BorderTiny: return "Tiny";
case BorderSmall: return "Small";
case BorderDefault: return "Default";
case BorderLarge: return "Large";
default: return NitrogenConfiguration().frameBorderName();
}
return QString();
}
//__________________________________________________
NitrogenConfiguration::FrameBorder NitrogenConfiguration::frameBorder( QString value )
{
if( value == "No Border" ) return BorderNone;
else if( value == "Tiny" ) return BorderTiny;
else if( value == "Small" ) return BorderSmall;
else if( value == "Default" ) return BorderDefault;
else if( value == "Large" ) return BorderLarge;
else return NitrogenConfiguration().frameBorder();
}
//__________________________________________________
QString NitrogenConfiguration::blendColorName( BlendColorType value )
{
switch( value )
{
case NoBlending: return "No Blending";
case RadialBlending: return "Radial Blending";
default: return NitrogenConfiguration().blendColorName();
}
return QString();
}
//__________________________________________________
NitrogenConfiguration::BlendColorType NitrogenConfiguration::blendColor( QString value )
{
if( value == "No Blending" ) return NoBlending;
else if( value == "Radial Blending" ) return RadialBlending;
else if( value == "Window Contents" ) return RadialBlending;
else return NitrogenConfiguration().blendColor();
}
//________________________________________________________
bool NitrogenConfiguration::operator == (const NitrogenConfiguration& other ) const
{
return
titleAlignment() == other.titleAlignment() &&
buttonSize() == other.buttonSize() &&
buttonType() == other.buttonType() &&
frameBorder() == other.frameBorder() &&
blendColor() == other.blendColor() &&
showStripes() == other.showStripes() &&
drawSeparator() == other.drawSeparator() &&
overwriteColors() == other.overwriteColors() &&
drawSizeGrip() == other.drawSizeGrip() &&
useOxygenShadows() == other.useOxygenShadows();
}
};

View file

@ -0,0 +1,290 @@
#ifndef nitrogenconfiguration_h
#define nitrogenconfiguration_h
// $Id: nitrogenconfiguration.h,v 1.17 2009/07/05 20:47:44 hpereira Exp $
/******************************************************************************
*
* Copyright (C) 2002 Hugo PEREIRA <mailto: hugo.pereira@free.fr>
*
* This 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 software 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
* software; if not, write to the Free Software Foundation, Inc., 59 Temple
* Place, Suite 330, Boston, MA 02111-1307 USA
*
*
*******************************************************************************/
/*!
\file nitrogenconfiguration.h
\brief encapsulated window decoration configuration
\author Hugo Pereira
\version $Revision: 1.17 $
\date $Date: 2009/07/05 20:47:44 $
*/
#include <KConfigGroup>
namespace NitrogenConfig
{
static const QString TITLE_ALIGNMENT = "TitleAlignment";
static const QString BUTTON_SIZE = "ButtonSize";
static const QString BUTTON_TYPE = "ButtonType";
static const QString SHOW_STRIPES = "ShowStripes";
static const QString DRAW_SEPARATOR = "DrawSeparator";
static const QString OVERWRITE_COLORS = "OverwriteColors";
static const QString FRAME_BORDER = "FrameBorder";
static const QString BLEND_COLOR = "BlendColor";
static const QString DRAW_SIZE_GRIP = "DrawSizeGrip";
static const QString USE_OXYGEN_SHADOWS = "UseOxygenShadows";
}
namespace Nitrogen
{
class NitrogenConfiguration
{
public:
//! button type
enum ButtonType
{
ButtonKde42,
ButtonKde43
};
//! button size enumeration
enum ButtonSize
{
ButtonSmall = 18,
ButtonDefault = 22,
ButtonLarge = 32,
ButtonHuge = 48
};
//! frame border enumeration
enum FrameBorder
{
BorderNone = 0,
BorderTiny = 1,
BorderSmall = 3,
BorderDefault = 5,
BorderLarge = 8
};
//! blend color enumeration
enum BlendColorType {
NoBlending,
RadialBlending
};
//! default constructor
NitrogenConfiguration( void );
//! constructor from KConfig
NitrogenConfiguration( KConfigGroup );
//! destructor
virtual ~NitrogenConfiguration( void )
{}
//! equal to operator
bool operator == ( const NitrogenConfiguration& ) const;
//! true if compiz is used as a window decoration
static bool useCompiz( void )
{ return useCompiz_; }
//! check if compiz is used
static bool checkUseCompiz( void );
//! write to kconfig group
virtual void write( KConfigGroup& ) const;
//!@name title alignment
//@{
static QString titleAlignmentName( Qt::Alignment );
static Qt::Alignment titleAlignment( QString );
virtual Qt::Alignment titleAlignment() const
{ return titleAlignment_; }
virtual QString titleAlignmentName() const
{ return titleAlignmentName( titleAlignment() ); }
virtual void setTitleAlignment( Qt::Alignment value )
{ titleAlignment_ = value; }
virtual void setTitleAlignment( QString value )
{ titleAlignment_ = titleAlignment( value ); }
//@}
//!@name button size
//@{
static QString buttonSizeName( ButtonSize );
static ButtonSize buttonSize( QString );
virtual ButtonSize buttonSize( void ) const
{ return buttonSize_; }
virtual QString buttonSizeName( void ) const
{ return buttonSizeName( buttonSize() ); }
virtual void setButtonSize( ButtonSize value )
{ buttonSize_ = value; }
//@}
//!@name button size
//@{
static QString buttonTypeName( ButtonType );
static ButtonType buttonType( QString );
virtual ButtonType buttonType( void ) const
{ return buttonType_; }
virtual QString buttonTypeName( void ) const
{ return buttonTypeName( buttonType() ); }
virtual void setButtonType( ButtonType value )
{ buttonType_ = value; }
//@}
//!@name frame border
//@{
static QString frameBorderName( FrameBorder );
static FrameBorder frameBorder( QString );
virtual FrameBorder frameBorder() const
{ return frameBorder_; }
virtual QString frameBorderName( void ) const
{ return frameBorderName( frameBorder() ); }
virtual void setFrameBorder( FrameBorder value )
{ frameBorder_ = value; }
virtual void setFrameBorder( QString value )
{ frameBorder_ = frameBorder( value ); }
//@}
//!@name blend color
//@{
static QString blendColorName( BlendColorType );
static BlendColorType blendColor( QString );
virtual BlendColorType blendColor( void ) const
{ return blendColor_; }
virtual QString blendColorName( void ) const
{ return blendColorName( blendColor() ); }
virtual void setBlendColor( BlendColorType value )
{ blendColor_ = value; }
virtual void setBlendColor( QString value )
{ blendColor_ = blendColor( value ); }
//@}
//! stripes
virtual bool showStripes( void ) const
{ return showStripes_; }
//! stripes
virtual void setShowStripes( bool value )
{ showStripes_ = value; }
//! separator
virtual bool drawSeparator( void ) const
{ return drawSeparator_; }
//! separator
virtual void setDrawSeparator( bool value )
{ drawSeparator_ = value; }
//! overwrite colors
virtual bool overwriteColors( void ) const
{ return overwriteColors_; }
//! overwrite colors
virtual void setOverwriteColors( bool value )
{ overwriteColors_ = value; }
//! draw size grip
virtual bool drawSizeGrip( void ) const
{ return drawSizeGrip_; }
//! draw size grip
virtual void setDrawSizeGrip( bool value )
{ drawSizeGrip_ = value; }
//! oxygen shadows
virtual bool useOxygenShadows( void ) const
{ return useOxygenShadows_; }
//! oxygen shadows
virtual void setUseOxygenShadows( bool value )
{ useOxygenShadows_ = value; }
private:
//! title alignment
Qt::Alignment titleAlignment_;
//! button size
ButtonSize buttonSize_;
//! button type
ButtonType buttonType_;
//! blend color
FrameBorder frameBorder_;
//! frame border
BlendColorType blendColor_;
//! stripes
bool showStripes_;
//! separator
bool drawSeparator_;
//! overwrite colors
bool overwriteColors_;
//! size grip
bool drawSizeGrip_;
//! oxygen shadows
bool useOxygenShadows_;
//! compiz
static bool useCompiz_;
};
};
#endif

View file

@ -0,0 +1,140 @@
// $Id: nitrogenconvertexceptions.cpp,v 1.1 2009/06/24 01:55:51 hpereira Exp $
/******************************************************************************
*
* Copyright (C) 2002 Hugo PEREIRA <mailto: hugo.pereira@free.fr>
*
* This 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 software 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
* software; if not, write to the Free Software Foundation, Inc., 59 Temple
* Place, Suite 330, Boston, MA 02111-1307 USA
*
*
*******************************************************************************/
#include <kstandarddirs.h>
#include <QCoreApplication>
#include <QDomDocument>
#include <QDomElement>
#include <QFile>
#include <QString>
#include <QTextStream>
#include "nitrogenexception.h"
#include "nitrogenexceptionlist.h"
using namespace std;
using namespace Nitrogen;
namespace NitrogenXml
{
static const QString EXCEPTION_LIST = "exception_list";
static const QString EXCEPTION = "exception";
static const QString ENABLED = "enabled";
static const QString TYPE = "type";
static const QString PATTERN = "pattern";
static const QString MASK = "mask";
};
//__________________________________________________________
NitrogenException readException( QDomElement element )
{
NitrogenException out;
// parse attributes
QDomNamedNodeMap attributes( element.attributes() );
for( unsigned int i=0; i<attributes.length(); i++ )
{
QDomAttr attribute( attributes.item( i ).toAttr() );
if( attribute.isNull() ) continue;
else if( attribute.name() == NitrogenXml::ENABLED ) out.setEnabled( attribute.value().toUInt() );
else if( attribute.name() == NitrogenXml::TYPE ) out.setType( NitrogenException::type( attribute.value() ) );
else if( attribute.name() == NitrogenXml::PATTERN ) out.regExp().setPattern( attribute.value() );
else if( attribute.name() == NitrogenConfig::FRAME_BORDER ) out.setFrameBorder( attribute.value() );
else if( attribute.name() == NitrogenConfig::BLEND_COLOR ) out.setBlendColor( attribute.value() );
else if( attribute.name() == NitrogenConfig::DRAW_SEPARATOR ) out.setDrawSeparator( attribute.value().toInt() );
else if( attribute.name() == NitrogenConfig::SHOW_STRIPES ) out.setShowStripes( attribute.value().toInt() );
else if( attribute.name() == NitrogenConfig::DRAW_SIZE_GRIP ) out.setDrawSizeGrip( attribute.value().toInt() );
else if( attribute.name() == NitrogenXml::MASK ) out.setMask( attribute.value().toUInt() );
// this is kept for backward compatibility
else if( attribute.name() == "blend_color" ) out.setBlendColor( attribute.value() );
}
return out;
}
//__________________________________________________________
NitrogenExceptionList readExceptions( QDomDocument document )
{
NitrogenExceptionList out;
// parse
QDomElement doc_element = document.documentElement();
for(QDomNode node = doc_element.firstChild(); !node.isNull(); node = node.nextSibling() )
{
QDomElement element = node.toElement();
if( element.isNull() ) continue;
if( element.tagName() == NitrogenXml::EXCEPTION )
{ out.push_back( readException( element ) ); }
}
return out;
}
//__________________________________________________________
int main( int argc, char *argv[] )
{
// the core application is needed to have locale, fonts, etc. set properly, notably for QSting
// not having it might result in lost accents and special characters.
QCoreApplication application( argc, argv );
// generate filename
QString filename = KStandardDirs::locateLocal( "config", "nitrogen_xml_rc" );
QTextStream( stdout ) << "nitrogen-convert-exceptions - reading file " << filename << endl;
// open and get DomDocument
QFile file( filename );
if ( !file.open( QIODevice::ReadOnly ) )
{
QTextStream( stdout ) << "nitrogen-convert-exceptions - invalid file" << endl;
return 0;
}
// read dom document
QDomDocument document;
if ( !document.setContent( &file ) )
{
file.close();
QTextStream( stdout ) << "nitrogen-convert-exceptions - invalid file" << endl;
return 0;
}
NitrogenExceptionList exceptions( readExceptions( document ) );
QTextStream( stdout ) << "nitrogen-convert-exceptions - read " << exceptions.size() << " exceptions" << endl;
// write to kconfig
KConfig configuration( "nitrogenrc" );
exceptions.write( configuration );
configuration.sync();
return 0;
}

View file

@ -0,0 +1,92 @@
// $Id: nitrogenexception.cpp,v 1.11 2009/06/21 19:57:19 hpereira Exp $
/******************************************************************************
*
* Copyright (C) 2002 Hugo PEREIRA <mailto: hugo.pereira@free.fr>
*
* This 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 software 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
* software; if not, write to the Free Software Foundation, Inc., 59 Temple
* Place, Suite 330, Boston, MA 02111-1307 USA
*
*
*******************************************************************************/
#include <assert.h>
#include "nitrogenexception.h"
namespace Nitrogen
{
//_______________________________________________________
NitrogenException::NitrogenException( KConfigGroup group ):
NitrogenConfiguration( group )
{
// used to set default values when entries are not found in kconfig
NitrogenException default_configuration;
// exception type
setType( type(
group.readEntry( NitrogenConfig::TYPE,
default_configuration.typeName() ) ) );
// exception pattern
regExp().setPattern( group.readEntry( NitrogenConfig::PATTERN, QString() ) );
// enability
setEnabled(
group.readEntry( NitrogenConfig::ENABLED,
default_configuration.enabled() ) );
// exception mask
setMask(
group.readEntry( NitrogenConfig::MASK,
default_configuration.mask() ) );
}
//_______________________________________________________
void NitrogenException::write( KConfigGroup& group ) const
{
NitrogenConfiguration::write( group );
group.writeEntry( NitrogenConfig::TYPE, typeName() );
group.writeEntry( NitrogenConfig::PATTERN, regExp().pattern() );
group.writeEntry( NitrogenConfig::ENABLED, enabled() );
group.writeEntry( NitrogenConfig::MASK, mask() );
}
//_______________________________________________________
QString NitrogenException::typeName( Type type )
{
switch( type )
{
case WindowTitle: return "Window Title";
case WindowClassName: return "Window Class Name";
default: assert( false );
}
return QString();
}
//_______________________________________________________
NitrogenException::Type NitrogenException::type( QString value )
{
if( value == "Window Title" ) return WindowTitle;
else if( value == "Window Class Name" ) return WindowClassName;
else return WindowClassName;
}
};

View file

@ -0,0 +1,181 @@
#ifndef nitrogenexception_h
#define nitrogenexception_h
// $Id: nitrogenexception.h,v 1.12 2009/06/24 01:43:14 hpereira Exp $
/******************************************************************************
*
* Copyright (C) 2002 Hugo PEREIRA <mailto: hugo.pereira@free.fr>
*
* This 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 software 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
* software; if not, write to the Free Software Foundation, Inc., 59 Temple
* Place, Suite 330, Boston, MA 02111-1307 USA
*
*
*******************************************************************************/
#include <QRegExp>
#include "nitrogenconfiguration.h"
namespace NitrogenConfig
{
//! needed for exceptions
static const QString TYPE = "Type";
static const QString PATTERN = "Pattern";
static const QString ENABLED = "Enabled";
static const QString MASK = "Mask";
};
namespace Nitrogen
{
//! nitrogen exception
class NitrogenException: public NitrogenConfiguration
{
public:
//! exception type
enum Type
{
WindowTitle,
WindowClassName
};
//! mask
enum AttributesMask
{
None = 0,
TitleAlignment = 1<<0,
ShowStripes = 1<<1,
DrawSeparator = 1<<2,
OverwriteColors = 1<<3,
FrameBorder = 1<<4,
BlendColor = 1<<5,
DrawSizeGrip = 1<<6,
All = TitleAlignment|ShowStripes|DrawSeparator|OverwriteColors|FrameBorder|BlendColor|DrawSizeGrip
};
//! constructor
NitrogenException( NitrogenConfiguration configuration = NitrogenConfiguration() ):
NitrogenConfiguration( configuration ),
enabled_( true ),
type_( WindowClassName ),
mask_( None )
{}
//! constructor
NitrogenException( KConfigGroup );
//! destructor
virtual ~NitrogenException( void )
{}
//! equal to operator
bool operator == (const NitrogenException& exception ) const
{
return
enabled() == exception.enabled() &&
type() == exception.type() &&
regExp().pattern() == exception.regExp().pattern() &&
mask() == exception.mask() &&
NitrogenConfiguration::operator == ( exception );
}
//! less than operator
bool operator < (const NitrogenException& exception ) const
{
if( enabled() != exception.enabled() ) return enabled() < exception.enabled();
else if( mask() != exception.mask() ) return mask() < exception.mask();
else if( type() != exception.type() ) return type() < exception.type();
else return regExp().pattern() < exception.regExp().pattern();
}
//! write to kconfig group
virtual void write( KConfigGroup& ) const;
//!@name enability
//@{
bool enabled( void ) const
{ return enabled_; }
void setEnabled( bool enabled )
{ enabled_ = enabled; }
//@}
//!@name exception type
//@{
static QString typeName( Type );
static Type type( QString name );
virtual QString typeName( void ) const
{ return typeName( type() ); }
virtual Type type( void ) const
{ return type_; }
virtual void setType( Type value )
{ type_ = value; }
//@}
//!@name regular expression
//@{
virtual QRegExp regExp( void ) const
{ return reg_exp_; }
virtual QRegExp& regExp( void )
{ return reg_exp_; }
//@}
//! mask
//!@{
unsigned int mask( void ) const
{ return mask_; }
void setMask( unsigned int mask )
{ mask_ = mask; }
//@}
private:
//! enability
bool enabled_;
//! exception type
Type type_;
//! regular expression to match window caption
QRegExp reg_exp_;
//! attributes mask
unsigned int mask_;
};
};
#endif

View file

@ -0,0 +1,105 @@
// $Id: nitrogenexceptionlist.cpp,v 1.6 2009/06/24 01:43:14 hpereira Exp $
/******************************************************************************
*
* Copyright (C) 2002 Hugo PEREIRA <mailto: hugo.pereira@free.fr>
*
* This 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 software 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
* software; if not, write to the Free Software Foundation, Inc., 59 Temple
* Place, Suite 330, Boston, MA 02111-1307 USA
*
*
*******************************************************************************/
#include <QTextStream>
#include "nitrogenexceptionlist.h"
namespace Nitrogen
{
//______________________________________________________________
void NitrogenExceptionList::read( const KConfig& config )
{
clear();
for( int index = 0; true; index++ )
{
KConfigGroup group( &config, exceptionGroupName( index ) );
if( group.exists() )
{
NitrogenException exception( group );
if( exception.regExp().isValid() ) push_back( exception );
QTextStream( stdout ) << "NitrogenExceptionList::read - read exception " << exception.regExp().pattern() << endl;
} else break;
}
}
//______________________________________________________________
void NitrogenExceptionList::write( KConfig& config )
{
// remove previous group
for( int index = 0; true ;index++ )
{
KConfigGroup group( &config, exceptionGroupName( index ) );
if( group.exists() ) group.deleteGroup();
else break;
}
// also add exceptions
int index(0);
for( NitrogenExceptionList::const_iterator iter = begin(); iter != end(); iter++, index++ )
{
KConfigGroup group( &config, exceptionGroupName( index ) );
iter->write( group );
}
}
//______________________________________________________________
NitrogenExceptionList NitrogenExceptionList::defaultList( void )
{
NitrogenExceptionList out;
// default exception that covers most commonly used gtk based applications
NitrogenException exception;
exception.setType( NitrogenException::WindowClassName );
exception.regExp().setPattern( "(Firefox)|(Thunderbird)|(Gimp)" );
exception.setBlendColor( NitrogenException::NoBlending );
exception.setMask( NitrogenException::BlendColor );
exception.setEnabled( true );
out.push_back( exception );
return out;
}
//_______________________________________________________________________
QString NitrogenExceptionList::exceptionGroupName( int index )
{
QString out;
QTextStream( &out ) << "Windeco Exception " << index;
return out;
}
};

View file

@ -0,0 +1,65 @@
#ifndef nitrogenexceptionlist_h
#define nitrogenexceptionlist_h
// $Id: nitrogenexceptionlist.h,v 1.4 2009/06/21 19:57:19 hpereira Exp $
/******************************************************************************
*
* Copyright (C) 2002 Hugo PEREIRA <mailto: hugo.pereira@free.fr>
*
* This 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 software 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
* software; if not, write to the Free Software Foundation, Inc., 59 Temple
* Place, Suite 330, Boston, MA 02111-1307 USA
*
*
*******************************************************************************/
#include <KConfig>
#include <QList>
#include "nitrogenexception.h"
namespace Nitrogen
{
//! nitrogen exceptions list
class NitrogenExceptionList: public QList<NitrogenException>
{
public:
//! default constructor
NitrogenExceptionList( void )
{}
//! default constructor
NitrogenExceptionList( const KConfig& config )
{ read( config ); }
//! read from KConfig
void read( const KConfig& );
//! write to kconfig
void write( KConfig& );
//! default exception list
static NitrogenExceptionList defaultList( void );
//! generate exception group name for given exception index
static QString exceptionGroupName( int index );
};
}
#endif

View file

@ -0,0 +1,259 @@
// $Id: nitrogensizegrip.cpp,v 1.20 2009/07/05 19:47:57 hpereira Exp $
/******************************************************************************
*
* Copyright (C) 2002 Hugo PEREIRA <mailto: hugo.pereira@free.fr>
*
* This 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 software 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
* software; if not, write to the Free Software Foundation, Inc., 59 Temple
* Place, Suite 330, Boston, MA 02111-1307 USA
*
*
*******************************************************************************/
#include <cassert>
#include <QApplication>
#include <QPainter>
#include <QPolygon>
#include <QTextStream>
#include <QTimer>
#include <kdeversion.h>
#include "nitrogenbutton.h"
#include "nitrogenclient.h"
#include "nitrogensizegrip.h"
#include "x11util.h"
#include <QX11Info>
#include <X11/Xlib.h>
namespace Nitrogen
{
//_____________________________________________
NitrogenSizeGrip::NitrogenSizeGrip( NitrogenClient* client ):
QWidget( client->widget() ),
client_( client ),
decoration_offset_( false )
{
// cursor
setCursor( Qt::SizeFDiagCursor );
setAutoFillBackground( true );
// size
setFixedSize( QSize( GRIP_SIZE, GRIP_SIZE ) );
// mask
QPolygon p;
p << QPoint( 0, GRIP_SIZE )
<< QPoint( GRIP_SIZE, 0 )
<< QPoint( GRIP_SIZE, GRIP_SIZE )
<< QPoint( 0, GRIP_SIZE );
setMask( QRegion( p ) );
// embed
embed();
updateBackgroundColor();
updatePosition();
// event filter
client->widget()->installEventFilter( this );
// show
show();
}
//_____________________________________________
NitrogenSizeGrip::~NitrogenSizeGrip( void )
{}
//_____________________________________________
void NitrogenSizeGrip::updateBackgroundColor( void )
{
QPalette palette = client().widget()->palette();
// active color
palette.setCurrentColorGroup( client().isActive() ? QPalette::Active:QPalette::Inactive );
// get relevant colors
QColor base( client().configuration().overwriteColors() ?
palette.button().color().darker(250) :
client().options()->color( NitrogenClient::ColorTitleBar, client().isActive() ) );
palette.setColor( backgroundRole(), base );
setPalette( palette );
XMapRaised( QX11Info::display(), winId() );
}
//_____________________________________________
void NitrogenSizeGrip::embed( void )
{
WId window_id = client().windowId();
assert( window_id );
WId current = window_id;
while( true )
{
WId root, parent = 0;
WId *children = 0L;
uint child_count = 0;
XQueryTree(QX11Info::display(), current, &root, &parent, &children, &child_count);
if( parent && parent != root && parent != current ) current = parent;
else break;
}
// if the current window is the window_id
// (i.e. if the client is top-level)
// the decoration_offset_ flag is set to true, meaning that decoration borders
// are taken into account when placing the widget.
#if KDE_IS_VERSION(4,2,92)
decoration_offset_ = ( current == window_id );
#else
decoration_offset_ = NitrogenConfiguration::useCompiz();
#endif
// reparent
XReparentWindow( QX11Info::display(), winId(), current, 0, 0 );
}
//_____________________________________________
bool NitrogenSizeGrip::eventFilter( QObject* object, QEvent* event )
{
if( object != client().widget() ) return false;
if ( event->type() == QEvent::Resize) updatePosition();
return false;
}
//_____________________________________________
void NitrogenSizeGrip::paintEvent( QPaintEvent* )
{
QPalette palette = client().widget()->palette();
palette.setCurrentColorGroup( (client().isActive() ) ? QPalette::Active : QPalette::Inactive );
// get relevant colors
QColor base( client().configuration().overwriteColors() ?
palette.button().color() :
client().options()->color( NitrogenClient::ColorTitleBar, client().isActive() ) );
QColor dark( base.darker(250) );
QColor light( base.darker(150) );
// create and configure painter
QPainter painter(this);
painter.setRenderHints(QPainter::Antialiasing );
painter.setPen( Qt::NoPen );
painter.setBrush( base );
// polygon
QPolygon p;
p << QPoint( 0, GRIP_SIZE )
<< QPoint( GRIP_SIZE, 0 )
<< QPoint( GRIP_SIZE, GRIP_SIZE )
<< QPoint( 0, GRIP_SIZE );
painter.drawPolygon( p );
// diagonal border
painter.setBrush( Qt::NoBrush );
painter.setPen( QPen( dark, 3 ) );
painter.drawLine( QPoint( 0, GRIP_SIZE ), QPoint( GRIP_SIZE, 0 ) );
// side borders
painter.setPen( QPen( light, 1.5 ) );
painter.drawLine( QPoint( 1, GRIP_SIZE ), QPoint( GRIP_SIZE, GRIP_SIZE ) );
painter.drawLine( QPoint( GRIP_SIZE, 1 ), QPoint( GRIP_SIZE, GRIP_SIZE ) );
painter.end();
}
//_____________________________________________
void NitrogenSizeGrip::mousePressEvent( QMouseEvent* event )
{
switch (event->button())
{
case Qt::RightButton:
{
hide();
QTimer::singleShot(5000, this, SLOT(show()));
break;
}
case Qt::MidButton:
{
hide();
break;
}
case Qt::LeftButton:
if( rect().contains( event->pos() ) )
{
// check client window id
if( !client().windowId() ) break;
// get matching screen
int screen( client().widget()->x11Info().screen() );
client().widget()->setFocus();
// post event
X11Util::get().moveResizeWidget( client().windowId(), screen, event->globalPos(), X11Util::_NET_WM_MOVERESIZE_SIZE_BOTTOMRIGHT );
}
break;
default: break;
}
return;
}
//_______________________________________________________________________________
void NitrogenSizeGrip::updatePosition( void )
{
QPoint position(
client().width() - GRIP_SIZE - OFFSET,
client().height() - GRIP_SIZE - OFFSET );
if( decoration_offset_ )
{ position-= QPoint( client().borderWidth(), client().borderHeight() ); }
#if KDE_IS_VERSION(4,2,92)
else {
position -= QPoint(
client().layoutMetric( NitrogenClient::LM_BorderRight ),
client().layoutMetric( NitrogenClient::LM_BorderBottom ) );
}
#endif
move( position );
}
};

View file

@ -0,0 +1,101 @@
#ifndef nitrogensizegrip_h
#define nitrogensizegrip_h
// $Id: nitrogensizegrip.h,v 1.8 2009/07/05 16:15:31 hpereira Exp $
/******************************************************************************
*
* Copyright (C) 2002 Hugo PEREIRA <mailto: hugo.pereira@free.fr>
*
* This 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 software 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
* software; if not, write to the Free Software Foundation, Inc., 59 Temple
* Place, Suite 330, Boston, MA 02111-1307 USA
*
*
*******************************************************************************/
#include <QWidget>
#include <QPaintEvent>
#include <QMouseEvent>
#include <QMouseEvent>
namespace Nitrogen
{
class NitrogenClient;
//! implements size grip for all widgets
class NitrogenSizeGrip: public QWidget
{
public:
//! constructor
NitrogenSizeGrip( NitrogenClient* );
//! constructor
virtual ~NitrogenSizeGrip( void );
//! event filter
virtual bool eventFilter( QObject*, QEvent* );
public slots:
//! update background color
void updateBackgroundColor( void );
protected slots:
//! embed into parent widget
void embed( void );
protected:
//!@name event handlers
//@{
//! paint
virtual void paintEvent( QPaintEvent* );
//! mouse press
virtual void mousePressEvent( QMouseEvent* );
//@}
//! client
NitrogenClient& client( void ) const
{ return *client_; }
//! update position
void updatePosition( void );
private:
//! grip size
enum {
OFFSET = 1,
GRIP_SIZE = 15
};
// nitrogen client
NitrogenClient* client_;
//! true when decoration offset must be accounted for when moving the widget
bool decoration_offset_;
};
};
#endif

View file

@ -0,0 +1,175 @@
// $Id: x11util.cpp,v 1.4 2009/07/03 00:36:20 hpereira Exp $
/******************************************************************************
*
* Copyright (C) 2002 Hugo PEREIRA <mailto: hugo.pereira@free.fr>
*
* This 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 software 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
* software; if not, write to the Free Software Foundation, Inc., 59 Temple
* Place, Suite 330, Boston, MA 02111-1307 USA
*
*
*******************************************************************************/
/*!
\file X11Util.h
\brief some X11 specific utilities
\author Hugo Pereira
\version $Revision: 1.4 $
\date $Date: 2009/07/03 00:36:20 $
*/
#include "x11util.h"
using namespace std;
namespace Nitrogen
{
//________________________________________________________________________
X11Util& X11Util::get( void )
{
static X11Util singleton;
return singleton;
}
//________________________________________________________________________
X11Util::X11Util( void )
{
_initializeAtomNames();
}
//________________________________________________________________________
bool X11Util::isSupported( const Atoms& atom )
{
#ifdef Q_WS_X11
SupportedAtomMap::const_iterator iter( _supportedAtoms().find( atom ) );
if( iter != _supportedAtoms().end() ) return iter->second;
Display* display( QX11Info::display() );
Atom net_supported( findAtom( _NET_SUPPORTED ) );
Atom searched( findAtom( atom ) );
Atom actual;
int format;
unsigned char *data;
unsigned long offset = 0;
while( 1 )
{
unsigned long n, left;
XGetWindowProperty( display, QX11Info::appRootWindow(),
net_supported, offset, 1L,
false, XA_ATOM, &actual,
&format, &n, &left,
(unsigned char **) &data);
if( data == None ) break;
// try cast data to atom
Atom found( *(Atom*)data );
if( found == searched )
{
supported_atoms_[atom] = true;
return true;
}
if( !left ) break;
else offset ++;
}
supported_atoms_[atom] = false;
#endif
return false;
}
//________________________________________________________________________
bool X11Util::moveResizeWidget(
WId id,
int screen,
QPoint position,
X11Util::Direction direction,
Qt::MouseButton button )
{
#ifdef Q_WS_X11
// check
if( !isSupported( _NET_WM_MOVERESIZE ) ) return false;
Display* display( QX11Info::display() );
Atom net_wm_moveresize( findAtom( _NET_WM_MOVERESIZE ) );
XEvent event;
event.xclient.type = ClientMessage;
event.xclient.message_type = net_wm_moveresize;
event.xclient.display = display;
event.xclient.window = id;
event.xclient.format = 32;
event.xclient.data.l[0] = position.x();
event.xclient.data.l[1] = position.y();
event.xclient.data.l[2] = direction;
event.xclient.data.l[3] = button;
event.xclient.data.l[4] = 0;
XUngrabPointer( display, QX11Info::appTime() );
XSendEvent(display,
QX11Info::appRootWindow( screen ),
false,
SubstructureRedirectMask | SubstructureNotifyMask, &event);
return true;
#else
return false;
#endif
}
//________________________________________________________________________
void X11Util::_initializeAtomNames( void )
{
atom_names_[_NET_SUPPORTED] = "_NET_SUPPORTED";
atom_names_[_NET_WM_STATE] = "_NET_WM_STATE";
atom_names_[_NET_WM_MOVERESIZE] = "_NET_WM_MOVERESIZE";
return;
}
#ifdef Q_WS_X11
//________________________________________________________________________
Atom X11Util::findAtom( const Atoms& atom )
{
// find atom in map
AtomMap::iterator iter( _atoms().find( atom ) );
if( iter != _atoms().end() ) return iter->second;
// create atom if not found
Display* display( QX11Info::display() );
Atom out( XInternAtom(display, qPrintable( atom_names_[atom] ), false ) );
atoms_[atom] = out;
return out;
}
}
#endif

137
clients/nitrogen/x11util.h Normal file
View file

@ -0,0 +1,137 @@
#ifndef X11Util_h
#define X11Util_h
// $Id: x11util.h,v 1.4 2009/07/03 00:36:20 hpereira Exp $
/******************************************************************************
*
* Copyright (C) 2002 Hugo PEREIRA <mailto: hugo.pereira@free.fr>
*
* This 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 software 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
* software; if not, write to the Free Software Foundation, Inc., 59 Temple
* Place, Suite 330, Boston, MA 02111-1307 USA
*
*
*******************************************************************************/
/*!
\file X11Util.h
\brief some X11 specific utilities
\author Hugo Pereira
\version $Revision: 1.4 $
\date $Date: 2009/07/03 00:36:20 $
*/
#include <QWidget>
#include <map>
#ifdef Q_WS_X11
#include <QX11Info>
#include <X11/Xlib.h>
#include <X11/Xatom.h>
#include <X11/Xutil.h>
#endif
namespace Nitrogen
{
class X11Util
{
public:
//! singleton
static X11Util& get( void );
//! Atoms enumeration
enum Atoms
{
_NET_SUPPORTED,
_NET_WM_STATE,
_NET_WM_MOVERESIZE
};
enum Direction
{
_NET_WM_MOVERESIZE_SIZE_TOPLEFT=0,
_NET_WM_MOVERESIZE_SIZE_TOP=1,
_NET_WM_MOVERESIZE_SIZE_TOPRIGHT=2,
_NET_WM_MOVERESIZE_SIZE_RIGHT=3,
_NET_WM_MOVERESIZE_SIZE_BOTTOMRIGHT=4,
_NET_WM_MOVERESIZE_SIZE_BOTTOM=5,
_NET_WM_MOVERESIZE_SIZE_BOTTOMLEFT=6,
_NET_WM_MOVERESIZE_SIZE_LEFT=7,
_NET_WM_MOVERESIZE_MOVE=8,
_NET_WM_MOVERESIZE_SIZE_KEYBOARD=9,
_NET_WM_MOVERESIZE_MOVE_KEYBOARD=10,
};
//! supported atoms
bool isSupported( const Atoms& atom );
//! move/resize widget using X11 window manager
/*! returns true on success */
bool moveResizeWidget( WId, int screen, QPoint, Direction, Qt::MouseButton button = Qt::LeftButton );
#ifdef Q_WS_X11
//! find atom
Atom findAtom( const Atoms& atom );
#endif
private:
//! constructor
X11Util( void );
//! atom names
typedef std::map<Atoms, QString> AtomNameMap;
//! atom names
void _initializeAtomNames( void );
//! atom names
const AtomNameMap& _atomNames( void ) const
{ return atom_names_; }
AtomNameMap atom_names_;
//! supported atoms
typedef std::map<Atoms, bool > SupportedAtomMap;
//! supported atoms
const SupportedAtomMap& _supportedAtoms( void ) const
{ return supported_atoms_; }
SupportedAtomMap supported_atoms_;
#ifdef Q_WS_X11
//! atom map
typedef std::map<Atoms, Atom> AtomMap;
//! atoms
// const AtomMap& _atoms( void ) const
AtomMap& _atoms( void )
{ return atoms_; }
//! atoms
AtomMap atoms_;
#endif
};
};
#endif