From b0263695595db848002728b3ebbd8b27fd08ca8c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sl=C3=A1vek=20Banko?= Date: Sat, 26 Mar 2016 20:11:54 +0100 Subject: [PATCH] Initial import of ia-ora 1.0.8 --- AUTHORS | 1 + COPYING | 340 +++ ChangeLog | 0 Doxyfile | 275 +++ INSTALL | 167 ++ Makefile.am | 22 + Makefile.cvs | 10 + NEWS | 0 README | 0 TODO | 0 configure.in.in | 6 + ia_ora.spec | 82 + src/Makefile.am | 1 + src/kwin/Makefile.am | 19 + src/kwin/config/Makefile.am | 14 + src/kwin/config/config.cpp | 102 + src/kwin/config/config.h | 55 + src/kwin/config/configdialog.ui | 53 + src/kwin/iaora.cpp | 665 ++++++ src/kwin/iaora.desktop | 5 + src/kwin/iaora.h | 126 ++ src/kwin/iaorabutton.cpp | 528 +++++ src/kwin/iaorabutton.h | 85 + src/kwin/iaoraclient.cpp | 514 +++++ src/kwin/iaoraclient.h | 73 + src/kwin/misc.cpp | 49 + src/kwin/misc.h | 28 + src/widget/Makefile.am | 26 + src/widget/bitmaps.h | 85 + src/widget/ia_ora.cpp | 3426 +++++++++++++++++++++++++++++++ src/widget/ia_ora.h | 308 +++ src/widget/ia_ora.themerc | 6 + 32 files changed, 7071 insertions(+) create mode 100644 AUTHORS create mode 100644 COPYING create mode 100644 ChangeLog create mode 100644 Doxyfile create mode 100644 INSTALL create mode 100644 Makefile.am create mode 100644 Makefile.cvs create mode 100644 NEWS create mode 100644 README create mode 100644 TODO create mode 100644 configure.in.in create mode 100644 ia_ora.spec create mode 100644 src/Makefile.am create mode 100644 src/kwin/Makefile.am create mode 100644 src/kwin/config/Makefile.am create mode 100644 src/kwin/config/config.cpp create mode 100644 src/kwin/config/config.h create mode 100644 src/kwin/config/configdialog.ui create mode 100644 src/kwin/iaora.cpp create mode 100644 src/kwin/iaora.desktop create mode 100644 src/kwin/iaora.h create mode 100644 src/kwin/iaorabutton.cpp create mode 100644 src/kwin/iaorabutton.h create mode 100644 src/kwin/iaoraclient.cpp create mode 100644 src/kwin/iaoraclient.h create mode 100644 src/kwin/misc.cpp create mode 100644 src/kwin/misc.h create mode 100644 src/widget/Makefile.am create mode 100644 src/widget/bitmaps.h create mode 100644 src/widget/ia_ora.cpp create mode 100644 src/widget/ia_ora.h create mode 100644 src/widget/ia_ora.themerc diff --git a/AUTHORS b/AUTHORS new file mode 100644 index 0000000..2fb489b --- /dev/null +++ b/AUTHORS @@ -0,0 +1 @@ +Laurent Montel diff --git a/COPYING b/COPYING new file mode 100644 index 0000000..5b6e7c6 --- /dev/null +++ b/COPYING @@ -0,0 +1,340 @@ + 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 + + 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. + + + Copyright (C) + + 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) year 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. + + , 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. diff --git a/ChangeLog b/ChangeLog new file mode 100644 index 0000000..e69de29 diff --git a/Doxyfile b/Doxyfile new file mode 100644 index 0000000..c74393a --- /dev/null +++ b/Doxyfile @@ -0,0 +1,275 @@ +# Doxyfile 1.4.1-KDevelop + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- +PROJECT_NAME = ia_ora.kdevelop +PROJECT_NUMBER = 0.1 +OUTPUT_DIRECTORY = +CREATE_SUBDIRS = NO +OUTPUT_LANGUAGE = English +USE_WINDOWS_ENCODING = NO +BRIEF_MEMBER_DESC = YES +REPEAT_BRIEF = YES +ABBREVIATE_BRIEF = "The $name class" \ + "The $name widget" \ + "The $name file" \ + is \ + provides \ + specifies \ + contains \ + represents \ + a \ + an \ + the +ALWAYS_DETAILED_SEC = NO +INLINE_INHERITED_MEMB = NO +FULL_PATH_NAMES = YES +STRIP_FROM_PATH = /home/montel/ +STRIP_FROM_INC_PATH = +SHORT_NAMES = NO +JAVADOC_AUTOBRIEF = NO +MULTILINE_CPP_IS_BRIEF = NO +DETAILS_AT_TOP = NO +INHERIT_DOCS = YES +DISTRIBUTE_GROUP_DOC = NO +TAB_SIZE = 8 +ALIASES = +OPTIMIZE_OUTPUT_FOR_C = NO +OPTIMIZE_OUTPUT_JAVA = NO +SUBGROUPING = YES +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- +EXTRACT_ALL = NO +EXTRACT_PRIVATE = NO +EXTRACT_STATIC = NO +EXTRACT_LOCAL_CLASSES = YES +EXTRACT_LOCAL_METHODS = NO +HIDE_UNDOC_MEMBERS = NO +HIDE_UNDOC_CLASSES = NO +HIDE_FRIEND_COMPOUNDS = NO +HIDE_IN_BODY_DOCS = NO +INTERNAL_DOCS = NO +CASE_SENSE_NAMES = YES +HIDE_SCOPE_NAMES = NO +SHOW_INCLUDE_FILES = YES +INLINE_INFO = YES +SORT_MEMBER_DOCS = YES +SORT_BRIEF_DOCS = NO +SORT_BY_SCOPE_NAME = NO +GENERATE_TODOLIST = YES +GENERATE_TESTLIST = YES +GENERATE_BUGLIST = YES +GENERATE_DEPRECATEDLIST= YES +ENABLED_SECTIONS = +MAX_INITIALIZER_LINES = 30 +SHOW_USED_FILES = YES +SHOW_DIRECTORIES = YES +FILE_VERSION_FILTER = +#--------------------------------------------------------------------------- +# configuration options related to warning and progress messages +#--------------------------------------------------------------------------- +QUIET = NO +WARNINGS = YES +WARN_IF_UNDOCUMENTED = YES +WARN_IF_DOC_ERROR = YES +WARN_NO_PARAMDOC = NO +WARN_FORMAT = "$file:$line: $text" +WARN_LOGFILE = +#--------------------------------------------------------------------------- +# configuration options related to the input files +#--------------------------------------------------------------------------- +INPUT = /home/montel/ia_ora +FILE_PATTERNS = *.c \ + *.cc \ + *.cxx \ + *.cpp \ + *.c++ \ + *.java \ + *.ii \ + *.ixx \ + *.ipp \ + *.i++ \ + *.inl \ + *.h \ + *.hh \ + *.hxx \ + *.hpp \ + *.h++ \ + *.idl \ + *.odl \ + *.cs \ + *.php \ + *.php3 \ + *.inc \ + *.m \ + *.mm \ + *.dox \ + *.C \ + *.CC \ + *.C++ \ + *.II \ + *.I++ \ + *.H \ + *.HH \ + *.H++ \ + *.CS \ + *.PHP \ + *.PHP3 \ + *.M \ + *.MM \ + *.C \ + *.H \ + *.tlh \ + *.diff \ + *.patch \ + *.moc \ + *.xpm \ + *.dox +RECURSIVE = yes +EXCLUDE = +EXCLUDE_SYMLINKS = NO +EXCLUDE_PATTERNS = +EXAMPLE_PATH = +EXAMPLE_PATTERNS = * +EXAMPLE_RECURSIVE = NO +IMAGE_PATH = +INPUT_FILTER = +FILTER_PATTERNS = +FILTER_SOURCE_FILES = NO +#--------------------------------------------------------------------------- +# configuration options related to source browsing +#--------------------------------------------------------------------------- +SOURCE_BROWSER = NO +INLINE_SOURCES = NO +STRIP_CODE_COMMENTS = YES +REFERENCED_BY_RELATION = YES +REFERENCES_RELATION = YES +VERBATIM_HEADERS = YES +#--------------------------------------------------------------------------- +# configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- +ALPHABETICAL_INDEX = NO +COLS_IN_ALPHA_INDEX = 5 +IGNORE_PREFIX = +#--------------------------------------------------------------------------- +# configuration options related to the HTML output +#--------------------------------------------------------------------------- +GENERATE_HTML = YES +HTML_OUTPUT = html +HTML_FILE_EXTENSION = .html +HTML_HEADER = +HTML_FOOTER = +HTML_STYLESHEET = +HTML_ALIGN_MEMBERS = YES +GENERATE_HTMLHELP = NO +CHM_FILE = +HHC_LOCATION = +GENERATE_CHI = NO +BINARY_TOC = NO +TOC_EXPAND = NO +DISABLE_INDEX = NO +ENUM_VALUES_PER_LINE = 4 +GENERATE_TREEVIEW = NO +TREEVIEW_WIDTH = 250 +#--------------------------------------------------------------------------- +# configuration options related to the LaTeX output +#--------------------------------------------------------------------------- +GENERATE_LATEX = YES +LATEX_OUTPUT = latex +LATEX_CMD_NAME = latex +MAKEINDEX_CMD_NAME = makeindex +COMPACT_LATEX = NO +PAPER_TYPE = a4wide +EXTRA_PACKAGES = +LATEX_HEADER = +PDF_HYPERLINKS = NO +USE_PDFLATEX = NO +LATEX_BATCHMODE = NO +LATEX_HIDE_INDICES = NO +#--------------------------------------------------------------------------- +# configuration options related to the RTF output +#--------------------------------------------------------------------------- +GENERATE_RTF = NO +RTF_OUTPUT = rtf +COMPACT_RTF = NO +RTF_HYPERLINKS = NO +RTF_STYLESHEET_FILE = +RTF_EXTENSIONS_FILE = +#--------------------------------------------------------------------------- +# configuration options related to the man page output +#--------------------------------------------------------------------------- +GENERATE_MAN = NO +MAN_OUTPUT = man +MAN_EXTENSION = .3 +MAN_LINKS = NO +#--------------------------------------------------------------------------- +# configuration options related to the XML output +#--------------------------------------------------------------------------- +GENERATE_XML = yes +XML_OUTPUT = xml +XML_SCHEMA = +XML_DTD = +XML_PROGRAMLISTING = YES +#--------------------------------------------------------------------------- +# configuration options for the AutoGen Definitions output +#--------------------------------------------------------------------------- +GENERATE_AUTOGEN_DEF = NO +#--------------------------------------------------------------------------- +# configuration options related to the Perl module output +#--------------------------------------------------------------------------- +GENERATE_PERLMOD = NO +PERLMOD_LATEX = NO +PERLMOD_PRETTY = YES +PERLMOD_MAKEVAR_PREFIX = +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- +ENABLE_PREPROCESSING = YES +MACRO_EXPANSION = NO +EXPAND_ONLY_PREDEF = NO +SEARCH_INCLUDES = YES +INCLUDE_PATH = +INCLUDE_FILE_PATTERNS = +PREDEFINED = +EXPAND_AS_DEFINED = +SKIP_FUNCTION_MACROS = YES +#--------------------------------------------------------------------------- +# Configuration::additions related to external references +#--------------------------------------------------------------------------- +TAGFILES = +GENERATE_TAGFILE = ia_ora.tag +ALLEXTERNALS = NO +EXTERNAL_GROUPS = YES +PERL_PATH = /usr/bin/perl +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- +CLASS_DIAGRAMS = YES +HIDE_UNDOC_RELATIONS = YES +HAVE_DOT = NO +CLASS_GRAPH = YES +COLLABORATION_GRAPH = YES +GROUP_GRAPHS = YES +UML_LOOK = NO +TEMPLATE_RELATIONS = NO +INCLUDE_GRAPH = YES +INCLUDED_BY_GRAPH = YES +CALL_GRAPH = NO +GRAPHICAL_HIERARCHY = YES +DIRECTORY_GRAPH = YES +DOT_IMAGE_FORMAT = png +DOT_PATH = +DOTFILE_DIRS = +MAX_DOT_GRAPH_WIDTH = 1024 +MAX_DOT_GRAPH_HEIGHT = 1024 +MAX_DOT_GRAPH_DEPTH = 1000 +DOT_TRANSPARENT = NO +DOT_MULTI_TARGETS = NO +GENERATE_LEGEND = YES +DOT_CLEANUP = YES +#--------------------------------------------------------------------------- +# Configuration::additions related to the search engine +#--------------------------------------------------------------------------- +SEARCHENGINE = NO diff --git a/INSTALL b/INSTALL new file mode 100644 index 0000000..02a4a07 --- /dev/null +++ b/INSTALL @@ -0,0 +1,167 @@ +Basic Installation +================== + + These are generic installation instructions. + + The `configure' shell script attempts to guess correct values for +various system-dependent variables used during compilation. It uses +those values to create a `Makefile' in each directory of the package. +It may also create one or more `.h' files containing system-dependent +definitions. Finally, it creates a shell script `config.status' that +you can run in the future to recreate the current configuration, a file +`config.cache' that saves the results of its tests to speed up +reconfiguring, and a file `config.log' containing compiler output +(useful mainly for debugging `configure'). + + If you need to do unusual things to compile the package, please try +to figure out how `configure' could check whether to do them, and mail +diffs or instructions to the address given in the `README' so they can +be considered for the next release. If at some point `config.cache' +contains results you don't want to keep, you may remove or edit it. + + The file `configure.in' is used to create `configure' by a program +called `autoconf'. You only need `configure.in' if you want to change +it or regenerate `configure' using a newer version of `autoconf'. + +The simplest way to compile this package is: + + 1. `cd' to the directory containing the package's source code and type + `./configure' to configure the package for your system. If you're + using `csh' on an old version of System V, you might need to type + `sh ./configure' instead to prevent `csh' from trying to execute + `configure' itself. + + Running `configure' takes a while. While running, it prints some + messages telling which features it is checking for. + + 2. Type `make' to compile the package. + + 3. Type `make install' to install the programs and any data files and + documentation. + + 4. You can remove the program binaries and object files from the + source code directory by typing `make clean'. + +Compilers and Options +===================== + + Some systems require unusual options for compilation or linking that +the `configure' script does not know about. You can give `configure' +initial values for variables by setting them in the environment. Using +a Bourne-compatible shell, you can do that on the command line like +this: + CC=c89 CFLAGS=-O2 LIBS=-lposix ./configure + +Or on systems that have the `env' program, you can do it like this: + env CPPFLAGS=-I/usr/local/include LDFLAGS=-s ./configure + +Compiling For Multiple Architectures +==================================== + + You can compile the package for more than one kind of computer at the +same time, by placing the object files for each architecture in their +own directory. To do this, you must use a version of `make' that +supports the `VPATH' variable, such as GNU `make'. `cd' to the +directory where you want the object files and executables to go and run +the `configure' script. `configure' automatically checks for the +source code in the directory that `configure' is in and in `..'. + + If you have to use a `make' that does not supports the `VPATH' +variable, you have to compile the package for one architecture at a time +in the source code directory. After you have installed the package for +one architecture, use `make distclean' before reconfiguring for another +architecture. + +Installation Names +================== + + By default, `make install' will install the package's files in +`/usr/local/bin', `/usr/local/man', etc. You can specify an +installation prefix other than `/usr/local' by giving `configure' the +option `--prefix=PATH'. + + You can specify separate installation prefixes for +architecture-specific files and architecture-independent files. If you +give `configure' the option `--exec-prefix=PATH', the package will use +PATH as the prefix for installing programs and libraries. +Documentation and other data files will still use the regular prefix. + + If the package supports it, you can cause programs to be installed +with an extra prefix or suffix on their names by giving `configure' the +option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. + +Optional Features +================= + + Some packages pay attention to `--enable-FEATURE' options to +`configure', where FEATURE indicates an optional part of the package. +They may also pay attention to `--with-PACKAGE' options, where PACKAGE +is something like `gnu-as' or `x' (for the X Window System). The +`README' should mention any `--enable-' and `--with-' options that the +package recognizes. + + For packages that use the X Window System, `configure' can usually +find the X include and library files automatically, but if it doesn't, +you can use the `configure' options `--x-includes=DIR' and +`--x-libraries=DIR' to specify their locations. + +Specifying the System Type +========================== + + There may be some features `configure' can not figure out +automatically, but needs to determine by the type of host the package +will run on. Usually `configure' can figure that out, but if it prints +a message saying it can not guess the host type, give it the +`--host=TYPE' option. TYPE can either be a short name for the system +type, such as `sun4', or a canonical name with three fields: + CPU-COMPANY-SYSTEM + +See the file `config.sub' for the possible values of each field. If +`config.sub' isn't included in this package, then this package doesn't +need to know the host type. + + If you are building compiler tools for cross-compiling, you can also +use the `--target=TYPE' option to select the type of system they will +produce code for and the `--build=TYPE' option to select the type of +system on which you are compiling the package. + +Sharing Defaults +================ + + If you want to set default values for `configure' scripts to share, +you can create a site shell script called `config.site' that gives +default values for variables like `CC', `cache_file', and `prefix'. +`configure' looks for `PREFIX/share/config.site' if it exists, then +`PREFIX/etc/config.site' if it exists. Or, you can set the +`CONFIG_SITE' environment variable to the location of the site script. +A warning: not all `configure' scripts look for a site script. + +Operation Controls +================== + + `configure' recognizes the following options to control how it +operates. + +`--cache-file=FILE' + Use and save the results of the tests in FILE instead of + `./config.cache'. Set FILE to `/dev/null' to disable caching, for + debugging `configure'. + +`--help' + Print a summary of the options to `configure', and exit. + +`--quiet' +`--silent' +`-q' + Do not print messages saying which checks are being made. + +`--srcdir=DIR' + Look for the package's source code in directory DIR. Usually + `configure' can determine that directory automatically. + +`--version' + Print the version of Autoconf used to generate the `configure' + script, and exit. + +`configure' also accepts some other, not widely useful, options. + diff --git a/Makefile.am b/Makefile.am new file mode 100644 index 0000000..8a2284f --- /dev/null +++ b/Makefile.am @@ -0,0 +1,22 @@ +SUBDIRS = $(TOPSUBDIRS) + +$(top_srcdir)/configure.in: configure.in.in $(top_srcdir)/subdirs + cd $(top_srcdir) && $(MAKE) -f admin/Makefile.common configure.in ; + +$(top_srcdir)/subdirs: + cd $(top_srcdir) && $(MAKE) -f admin/Makefile.common subdirs + +$(top_srcdir)/acinclude.m4: $(top_srcdir)/admin/acinclude.m4.in $(top_srcdir)/admin/libtool.m4.in + @cd $(top_srcdir) && cat admin/acinclude.m4.in admin/libtool.m4.in > acinclude.m4 + +MAINTAINERCLEANFILES = subdirs configure.in acinclude.m4 configure.files + +package-messages: + cd $(top_srcdir) && $(MAKE) -f admin/Makefile.common package-messages + $(MAKE) -C po merge + +EXTRA_DIST = admin COPYING configure.in.in + +dist-hook: + cd $(top_distdir) && perl admin/am_edit -padmin + cd $(top_distdir) && $(MAKE) -f admin/Makefile.common subdirs diff --git a/Makefile.cvs b/Makefile.cvs new file mode 100644 index 0000000..4c0afd1 --- /dev/null +++ b/Makefile.cvs @@ -0,0 +1,10 @@ +all: + @echo "This Makefile is only for the CVS repository" + @echo "This will be deleted before making the distribution" + @echo "" + $(MAKE) -f admin/Makefile.common cvs + +dist: + $(MAKE) -f admin/Makefile.common dist + +.SILENT: diff --git a/NEWS b/NEWS new file mode 100644 index 0000000..e69de29 diff --git a/README b/README new file mode 100644 index 0000000..e69de29 diff --git a/TODO b/TODO new file mode 100644 index 0000000..e69de29 diff --git a/configure.in.in b/configure.in.in new file mode 100644 index 0000000..ddca40b --- /dev/null +++ b/configure.in.in @@ -0,0 +1,6 @@ +#MIN_CONFIG(3.2.0) + +AM_INIT_AUTOMAKE(ia_ora-kde, 1.0.8) +AC_C_BIGENDIAN +AC_CHECK_KDEMAXPATHLEN + diff --git a/ia_ora.spec b/ia_ora.spec new file mode 100644 index 0000000..315e7fc --- /dev/null +++ b/ia_ora.spec @@ -0,0 +1,82 @@ +Summary: Ia Ora theme for kde +Name: ia_ora +Version: 1.0 +Release: %mkrel 2 +License: GPL +Group: Graphical desktop/Other +URL: http://www.mandrivalinux.com/ +BuildRequires: kdelibs-devel +BuildRequires: kdebase-devel >= 3.1.94-11mdk +Source0: %{name}.tar.bz2 +BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-buildroot + +%description +Mandriva Ia Ora theme + + +%package kde +Summary: Mandriva theme for KDE - Widget design +Group: Graphical desktop/KDE + +%description kde +Mandriva theme for KDE - Widget design + +%package kde-kwin +Summary: Mandriva theme for KDE - Window Decorations +Group: Graphical desktop/KDE + +%description kde-kwin +Mandriva theme for KDE - Window Decorations + + +%prep +%setup -q -n%name + +%build +make -f admin/Makefile.common cvs + +export QTDIR=%qtdir +export KDEDIR=%_prefix + +export LD_LIBRARY_PATH=$QTDIR/%_lib:$KDEDIR/%_lib:$LD_LIBRARY_PATH +export PATH=$QTDIR/bin:$KDEDIR/bin:$PATH + +%configure2_5x \ +%if "%{_lib}" != "lib" + --enable-libsuffix="%(A=%{_lib}; echo ${A/lib/})" \ +%endif + --with-xinerama +%make + +%install +rm -rf $RPM_BUILD_ROOT + +%makeinstall_std + + +%clean +rm -rf $RPM_BUILD_ROOT + +%files kde-kwin +%defattr(-,root,root,-) +%_libdir/kde3/kwin3_iaora.la +%_libdir/kde3/kwin3_iaora.so +%_libdir/kde3/kwin_iaora_config.la +%_libdir/kde3/kwin_iaora_config.so +%_datadir/apps/kwin/iaora.desktop + + + +%files kde +%defattr(-,root,root,-) +%_libdir/kde3/plugins/styles/ia_ora.la +%_libdir/kde3/plugins/styles/ia_ora.so +%_datadir/apps/kstyle/themes/ia_ora.themerc + +%changelog +* Thu Sep 07 2006 Laurent MONTEL 1.0-2 +- Some fixes + +* Mon Sep 04 2006 Laurent MONTEL 1.0-1 +- Initial package + diff --git a/src/Makefile.am b/src/Makefile.am new file mode 100644 index 0000000..cc6a276 --- /dev/null +++ b/src/Makefile.am @@ -0,0 +1 @@ +SUBDIRS=widget kwin diff --git a/src/kwin/Makefile.am b/src/kwin/Makefile.am new file mode 100644 index 0000000..5e52b07 --- /dev/null +++ b/src/kwin/Makefile.am @@ -0,0 +1,19 @@ +AUTOMAKE_OPTIONS = foreign + +SUBDIRS = config + +KDE_CXXFLAGS = -DQT_PLUGIN + +INCLUDES = -I$(srcdir)/../../lib $(all_includes) + +kwindir = $(kde_datadir)/kwin/ +kwin_DATA = iaora.desktop + +kde_module_LTLIBRARIES = kwin3_iaora.la +kwin3_iaora_la_SOURCES = iaora.cpp iaoraclient.cpp iaorabutton.cpp misc.cpp +kwin3_iaora_la_LDFLAGS = $(all_libraries) $(KDE_PLUGIN) -module +kwin3_iaora_la_LIBADD = $(LIB_KDEUI) -lkdecorations -lqt-mt -lkdecore -lkdefx +kwin3_iaora_la_METASOURCES = AUTO + +DISTCLEANFILES = $(kwin3_iaora_la_METASOURCES) + diff --git a/src/kwin/config/Makefile.am b/src/kwin/config/Makefile.am new file mode 100644 index 0000000..e4f9c03 --- /dev/null +++ b/src/kwin/config/Makefile.am @@ -0,0 +1,14 @@ +INCLUDES = $(all_includes) + +kde_module_LTLIBRARIES = kwin_iaora_config.la + +kwin_iaora_config_la_SOURCES = config.cpp configdialog.ui +kwin_iaora_config_la_LDFLAGS = $(all_libraries) $(KDE_PLUGIN) -module +kwin_iaora_config_la_LIBADD = $(LIB_KDEUI) -lqt-mt -lkdecore + +METASOURCES = AUTO +noinst_HEADERS = config.h +DISTCLEANFILES = $(METASOURCES) + +lnkdir = $(kde_datadir)/kwin + diff --git a/src/kwin/config/config.cpp b/src/kwin/config/config.cpp new file mode 100644 index 0000000..6320c23 --- /dev/null +++ b/src/kwin/config/config.cpp @@ -0,0 +1,102 @@ +/* + Copyright (C) 2006 Montel Laurent + based on plastik + Copyright (C) 2003 Sandro Giessl + + based on the window decoration "Web": + Copyright (C) 2001 Rik Hemsley (rikkus) + + 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 +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "config.h" +#include "configdialog.h" + +IaOraConfig::IaOraConfig(KConfig* config, QWidget* parent) + : QObject(parent), m_config(0), m_dialog(0) +{ + // create the configuration object + m_config = new KConfig("kwiniaorarc"); + KGlobal::locale()->insertCatalogue("kwin_clients"); + + // create and show the configuration dialog + m_dialog = new ConfigDialog(parent); + m_dialog->show(); + + // load the configuration + load(config); + + // setup the connections + connect(m_dialog->menuClose, SIGNAL(toggled(bool)), + this, SIGNAL(changed())); + connect(m_dialog->titleShadow, SIGNAL(toggled(bool)), + this, SIGNAL(changed())); +} + +IaOraConfig::~IaOraConfig() +{ + delete m_dialog; + delete m_config; +} + +void IaOraConfig::load(KConfig*) +{ + m_config->setGroup("General"); + + bool menuClose = m_config->readBoolEntry("CloseOnMenuDoubleClick", true); + m_dialog->menuClose->setChecked(menuClose); + bool titleShadow = m_config->readBoolEntry("TitleShadow", true); + m_dialog->titleShadow->setChecked(titleShadow); +} + +void IaOraConfig::save(KConfig*) +{ + m_config->setGroup("General"); + + m_config->writeEntry("CloseOnMenuDoubleClick", m_dialog->menuClose->isChecked() ); + m_config->writeEntry("TitleShadow", m_dialog->titleShadow->isChecked() ); + m_config->sync(); +} + +void IaOraConfig::defaults() +{ + m_dialog->menuClose->setChecked(false); + m_dialog->titleShadow->setChecked(true); +} + +////////////////////////////////////////////////////////////////////////////// +// Plugin Stuff // +////////////////////////////////////////////////////////////////////////////// + +extern "C" +{ + KDE_EXPORT QObject* allocate_config(KConfig* config, QWidget* parent) { + return (new IaOraConfig(config, parent)); + } +} + +#include "config.moc" diff --git a/src/kwin/config/config.h b/src/kwin/config/config.h new file mode 100644 index 0000000..9be0ea5 --- /dev/null +++ b/src/kwin/config/config.h @@ -0,0 +1,55 @@ +/* + Copyright (C) 2006 Montel Laurent + based on plastik + Copyright (C) 2003 Sandro Giessl + + based on the window decoration "Web": + Copyright (C) 2001 Rik Hemsley (rikkus) + + 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. + */ + +#ifndef KNIFTYCONFIG_H +#define KNIFTYCONFIG_H + +#include + +class QButtonGroup; +class QGroupBox; +class KConfig; +class ConfigDialog; + +class IaOraConfig : public QObject +{ + Q_OBJECT +public: + IaOraConfig(KConfig* config, QWidget* parent); + ~IaOraConfig(); + +signals: + void changed(); + +public slots: + void load(KConfig *config); + void save(KConfig *config); + void defaults(); + +private: + KConfig *m_config; + ConfigDialog *m_dialog; +}; + +#endif // KNIFTYCONFIG_H diff --git a/src/kwin/config/configdialog.ui b/src/kwin/config/configdialog.ui new file mode 100644 index 0000000..a6167b4 --- /dev/null +++ b/src/kwin/config/configdialog.ui @@ -0,0 +1,53 @@ + +ConfigDialog + + + ConfigDialog + + + + 0 + 0 + 535 + 88 + + + + Config Dialog + + + + unnamed + + + 0 + + + + titleShadow + + + Use shadowed &text + + + Check this option if you want the titlebar text to have a 3D look with a shadow behind it. + + + + + menuClose + + + Close windows by double clicking the menu button + + + Check this option if you want windows to be closed when you double click the menu button, similar to Microsoft Windows. + + + + + + titleShadow + + + diff --git a/src/kwin/iaora.cpp b/src/kwin/iaora.cpp new file mode 100644 index 0000000..887baff --- /dev/null +++ b/src/kwin/iaora.cpp @@ -0,0 +1,665 @@ +/* Ia Ora KWin window decoration + Copyright (C) 2006 Laurent Montel + Based on plastik code + Copyright (C) 2003-2005 Sandro Giessl + + based on the window decoration "Web": + Copyright (C) 2001 Rik Hemsley (rikkus) + + 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 +#include +#include +#include +#include +#include +#include + +#include "misc.h" +#include "iaora.h" +#include "iaora.moc" +#include "iaoraclient.h" +#include "iaorabutton.h" + +namespace KWinIaOra +{ + +IaOraHandler::IaOraHandler() +{ + memset(m_pixmaps, 0, sizeof(QPixmap*)*NumPixmaps*2*2); // set elements to 0 + memset(m_bitmaps, 0, sizeof(QBitmap*)*NumButtonIcons*2); + + reset(0); +} + +IaOraHandler::~IaOraHandler() +{ + for (int t=0; t < 2; ++t) + for (int a=0; a < 2; ++a) + for (int i=0; i < NumPixmaps; ++i) + delete m_pixmaps[t][a][i]; + for (int t=0; t < 2; ++t) + for (int i=0; i < NumButtonIcons; ++i) + delete m_bitmaps[t][i]; +} + +bool IaOraHandler::reset(unsigned long changed) +{ + // we assume the active font to be the same as the inactive font since the control + // center doesn't offer different settings anyways. + m_titleFont = KDecoration::options()->font(true, false); // not small + m_titleFontTool = KDecoration::options()->font(true, true); // small + + // check if we are in reverse layout mode + m_reverse = QApplication::reverseLayout(); + + // read in the configuration + readConfig(); + + // pixmaps probably need to be updated, so delete the cache. + for (int t=0; t < 2; ++t) { + for (int a=0; a < 2; ++a) { + for (int i=0; i < NumPixmaps; i++) { + if (m_pixmaps[t][a][i]) { + delete m_pixmaps[t][a][i]; + m_pixmaps[t][a][i] = 0; + } + } + } + } + for (int t=0; t < 2; ++t) { + for (int i=0; i < NumButtonIcons; i++) { + if (m_bitmaps[t][i]) { + delete m_bitmaps[t][i]; + m_bitmaps[t][i] = 0; + } + } + } + + // Do we need to "hit the wooden hammer" ? + bool needHardReset = true; + // TODO: besides the Color and Font settings I can maybe handle more changes + // without a hard reset. I will do this later... + if (changed & SettingColors || changed & SettingFont) + { + needHardReset = false; + } else if (changed & SettingButtons) { + // handled by KCommonDecoration + needHardReset = false; + } + + if (needHardReset) { + return true; + } else { + resetDecorations(changed); + return false; + } +} + +KDecoration* IaOraHandler::createDecoration( KDecorationBridge* bridge ) +{ + return new IaOraClient( bridge, this ); +} + +bool IaOraHandler::supports( Ability ability ) +{ + switch( ability ) + { + case AbilityAnnounceButtons: + case AbilityButtonMenu: + case AbilityButtonOnAllDesktops: + case AbilityButtonSpacer: + case AbilityButtonHelp: + case AbilityButtonMinimize: + case AbilityButtonMaximize: + case AbilityButtonClose: + case AbilityButtonAboveOthers: + case AbilityButtonBelowOthers: + case AbilityButtonShade: + return true; + default: + return false; + }; +} + +void IaOraHandler::readConfig() +{ + // create a config object + KConfig config("kwiniaorarc"); + config.setGroup("General"); + + // grab settings + m_titleShadow = config.readBoolEntry("TitleShadow", true); + + QFontMetrics fm(m_titleFont); // active font = inactive font + int titleHeightMin = config.readNumEntry("MinTitleHeight", 22); + // The title should strech with bigger font sizes! + m_titleHeight = QMAX(titleHeightMin, fm.height() + 4); // 4 px for the shadow etc. + // have an even title/button size so the button icons are fully centered... + if ( m_titleHeight%2 == 0) + m_titleHeight++; + + fm = QFontMetrics(m_titleFontTool); // active font = inactive font + int titleHeightToolMin = config.readNumEntry("MinTitleHeightTool", 22); + // The title should strech with bigger font sizes! + m_titleHeightTool = QMAX(titleHeightToolMin, fm.height() ); // don't care about the shadow etc. + // have an even title/button size so the button icons are fully centered... + if ( m_titleHeightTool%2 == 0) + m_titleHeightTool++; + + m_menuClose = config.readBoolEntry("CloseOnMenuDoubleClick", true); +} + +QColor IaOraHandler::getBorderColor( KWinIaOra::ColorType type, const bool active) +{ + //Force colors + switch (type) { + case Border1: + return QColor( "#EFF3F7" ); + break; + case Border2: + return QColor( "#DFE7EF" ); + break; + case Border3: + return QColor( "#C7D3DF" ); + break; + default: + return Qt::black; + } + return Qt::black; +} + +QColor IaOraHandler::getShadowColor() +{ + QColor col = KDecoration::options()->color(ColorTitleBar, true); + if ( col == QColor("#4964AE") ) + { + return QColor( "#000000" ); + } + //default Arctic color + else if ( col == QColor("#8ec7ff") ) + { + return QColor( "#666666" ); + } + else if ( col == QColor("7BAAE7") ) + { + return QColor( "#666666" ); + } + //default Orange color + else if ( col == QColor("#F7B610") ) + { + return QColor( "#666666" ); + } + //default Gray color + else if ( col == QColor("#c7d3df") ) + { + return QColor( "#333333" ); + } + return QColor( "#666666" ); +} + +QColor IaOraHandler::getGradientColor( KWinIaOra::ColorType type, const bool active) +{ + QColor col = KDecoration::options()->color(ColorTitleBar, active); + //default Blue color + if ( active ) + { + if ( col == QColor("#4964AE") ) + { + switch (type) { + case TitleGradient1: + return QColor("#8EA2CF"); + break; + case TitleGradient2: + return QColor("#415DA6"); + break; + case TitleGradient4: + return QColor("#4964AE"); + break; + case TitleGradient3: + return QColor("#21459C"); + break; + default: + return Qt::black; + } + } + //default Smooth color + else if ( col == QColor("#7BAAE7") ) + { + switch (type) { + case TitleGradient1: + return QColor("#ADCFFF"); + break; + case TitleGradient2: + return QColor("#5A8AD6"); + break; + case TitleGradient4: + return QColor("#7BAAE7"); + break; + case TitleGradient3: + return QColor("#427DC6"); + break; + default: + return Qt::black; + } + } + //default Orange color + else if ( col == QColor("#F7B610") ) + { + switch (type) { + case TitleGradient1: + return QColor("#FFCB10"); + break; + case TitleGradient2: + return QColor("#ffa208"); + break; + case TitleGradient4: + return QColor("#f7b610"); + break; + case TitleGradient3: + return QColor("#f79600"); + break; + default: + return Qt::black; + } + } + //default Arctic color + else if ( col == QColor("#8ec7ff") ) + { + switch (type) { + case TitleGradient1: + return QColor("#c7dfff"); + break; + case TitleGradient2: + return QColor("#79beff"); + break; + case TitleGradient4: + return QColor("#8ec7ff"); + break; + case TitleGradient3: + return QColor("#69b6ff"); + break; + default: + return Qt::black; + } + } + //default Gray color + else if ( col == QColor("#c7d3df") ) + { + switch (type) { + case TitleGradient1: + return QColor("#cfd7df"); + break; + case TitleGradient2: + return QColor("#a6b2c7"); + break; + case TitleGradient4: + return QColor("#c7d3df"); + break; + case TitleGradient3: + return QColor("#8692a6"); + break; + default: + return Qt::black; + } + } + else + { + switch (type) { + case TitleGradient1: + return col.light( 150 ); + break; + case TitleGradient2: + return col.dark( 112 ); + break; + case TitleGradient4: + return col; + break; + case TitleGradient3: + return col.dark( 130 ); + break; + default: + return Qt::black; + } + } + } + else + { + if ( col == QColor( "#EFF3F7" ) ) + { + switch (type) { + case TitleGradient1: + return QColor( "#DFE7EF" ); + break; + case TitleGradient2: + return QColor( "#C7D3DF" ); + break; + case TitleGradient4: + return QColor( "#CFD7DF" ); + break; + case TitleGradient3: + return QColor( "#B6C3CF" ); + break; + default: + return Qt::black; + } + } + else + { + //create algo + switch (type) { + case TitleGradient1: + return col.dark(107); + break; + case TitleGradient2: + return col.dark( 117 ); + break; + case TitleGradient4: + return col.dark( 115 ); + break; + case TitleGradient3: + return col.dark( 131 ); + break; + default: + return Qt::black; + } + } + + } + return Qt::black; +} + +QColor IaOraHandler::getColor(KWinIaOra::ColorType type, const bool active) +{ + switch (type) { + case TitleBorder: + return KDecoration::options()->color(ColorTitleBar, active); + case TitleGradient1: + case TitleGradient2: + case TitleGradient4: + case TitleGradient3: + return getGradientColor( type, active); + case Border1: + case Border2: + case Border3: + return getBorderColor( type, active); + case ShadeTitleLight: + return alphaBlendColors(KDecoration::options()->color(ColorTitleBar, active), + Qt::white, active?205:215); + //todo verify + case ShadeTitleDark: + return alphaBlendColors(KDecoration::options()->color(ColorTitleBar, active), + Qt::black, active?205:215); + break; + case TitleFont: + return KDecoration::options()->color(ColorFont, active); + default: + return Qt::black; + } +} + +void IaOraHandler::pretile( QPixmap *&pix, int size, Qt::Orientation dir ) const +{ + QPixmap *newpix; + QPainter p; + + if ( dir == Qt::Horizontal ) + newpix = new QPixmap( size, pix->height() ); + else + newpix = new QPixmap( pix->width(), size ); + + p.begin( newpix ); + p.drawTiledPixmap( newpix->rect(), *pix ) ; + p.end(); + + delete pix; + pix = newpix; +} + +const QPixmap &IaOraHandler::pixmap(Pixmaps type, bool active, bool toolWindow) +{ + if (m_pixmaps[toolWindow][active][type]) + return *m_pixmaps[toolWindow][active][type]; + + QPixmap *pm = 0; + + switch (type) { + case TitleBarTileTop: + { + pm = new QPixmap(1, 3); + QPainter painter(pm); + painter.setPen(getColor(TitleBorder, active)); + painter.drawPoint(0,0); + + painter.fillRect(0,1,pm->width(),pm->height()-1,getColor(TitleGradient1, active)); + painter.end(); + pretile(pm, 64, Qt::Horizontal); + break; + } + case TitleBarTile: + { + const int titleBarTileHeight = (toolWindow ? m_titleHeightTool : m_titleHeight) + 2; + // gradient used as well in TitleBarTileTop as TitleBarTile + const int gradientHeight = 2 + titleBarTileHeight; + QPixmap gradient(1, gradientHeight); + QPainter painter(&gradient); + KPixmap tempPixmap; + tempPixmap.resize(1, gradientHeight/2); + KPixmapEffect::gradient(tempPixmap, + getColor(TitleGradient1, active), + getColor(TitleGradient2, active), + KPixmapEffect::VerticalGradient); + painter.drawPixmap(0,0, tempPixmap); + tempPixmap.resize(1, gradientHeight - (gradientHeight/2)); + KPixmapEffect::gradient(tempPixmap, + getColor(TitleGradient3, active) , + getColor(TitleGradient4, active), + KPixmapEffect::VerticalGradient); + painter.drawPixmap(0,gradientHeight/2, tempPixmap); + painter.end(); + + pm = new QPixmap(1, titleBarTileHeight); + painter.begin(pm); + painter.drawPixmap(0, 0, gradient, 0,2); + painter.setPen(getColor(TitleGradient3, active).dark(110) ); + painter.drawPoint(0,titleBarTileHeight-1); + + painter.end(); + + pretile(pm, 64, Qt::Horizontal); + + break; + } + + case TitleBarLeft: + { + const int h = 4 + (toolWindow ? m_titleHeightTool : m_titleHeight) + 2; + + pm = new QPixmap(3, h); + QPainter painter(pm); + + painter.drawTiledPixmap(0,0, 3, 3, pixmap(TitleBarTileTop, active, toolWindow) ); + painter.drawTiledPixmap(0,3, 3, h-3, pixmap(TitleBarTile, active, toolWindow) ); + + painter.setPen(getColor(TitleBorder, active) ); + painter.drawLine(0,0, 0,h); + + break; + } + case TitleBarRight: + { + const int h = 4 + (toolWindow ? m_titleHeightTool : m_titleHeight) + 2; + + pm = new QPixmap(3, h); + QPainter painter(pm); + + painter.drawTiledPixmap(0,0, 3, 3, pixmap(TitleBarTileTop, active, toolWindow) ); + painter.drawTiledPixmap(0,3, 3, h-3, pixmap(TitleBarTile, active, toolWindow) ); + + painter.setPen(getColor(TitleBorder, active)); + painter.drawLine(2,0, 2,h); + + break; + } + + case BorderLeftTile: + { + pm = new QPixmap(3, 1); + QPainter painter(pm); + painter.setPen(getColor(Border3, active) ); + painter.drawPoint(0, 0); + painter.setPen(getColor(Border2, active) ); + painter.drawPoint(1, 0); + + painter.setPen(getColor(Border1, active) ); + painter.drawPoint(2,0); + painter.end(); + pretile(pm, 64, Qt::Vertical); + break; + } + + case BorderRightTile: + { + + pm = new QPixmap(3, 1); + QPainter painter(pm); + painter.setPen(getColor(Border1, active) ); + painter.drawPoint(0,0); + painter.setPen(getColor(Border2, active) ); + painter.drawPoint(1, 0); + painter.setPen(getColor(Border3, active) ); + painter.drawPoint(2, 0); + painter.end(); + pretile(pm, 64, Qt::Vertical); + + break; + } + + case BorderBottomLeft: + { + pm = new QPixmap(3, 3); + QPainter painter(pm); + painter.drawTiledPixmap(0,0,3,3, pixmap(BorderBottomTile, active, toolWindow) ); + painter.setPen(getColor(Border3, active) ); + painter.drawLine(0,0, 0,3); + + painter.setPen(getColor(Border1, active) ); + painter.drawLine(2,0, 2,0); + painter.end(); + + break; + } + + case BorderBottomRight: + { + + pm = new QPixmap(3, 3); + QPainter painter(pm); + painter.drawTiledPixmap(0,0,3,3, pixmap(BorderBottomTile, active, toolWindow) ); + painter.setPen(getColor(Border3, active) ); + painter.drawLine(2,0, 2,3); + painter.setPen(getColor(Border2, active) ); + painter.drawLine(1,0, 1,1); + + painter.setPen(getColor(Border1, active) ); + painter.drawLine(0,0, 0,0); + + painter.end(); + + break; + } + + case BorderBottomTile: + default: + { + pm = new QPixmap(1, 3); + QPainter painter(pm); + + painter.setPen(getColor(Border1, active) ); + painter.drawPoint(0,0); + painter.setPen(getColor(Border2, active) ); + painter.drawPoint(0,1); + painter.setPen(getColor(Border3, active) ); + painter.drawPoint(0, 2); + painter.end(); + + pretile(pm, 64, Qt::Horizontal); + + break; + } + } + + m_pixmaps[toolWindow][active][type] = pm; + return *pm; +} + +const QBitmap &IaOraHandler::buttonBitmap(ButtonIcon type, const QSize &size, bool toolWindow) +{ + int typeIndex = type; + + // btn icon size... + int reduceW = 0, reduceH = 0; + if(size.width()>14) { + reduceW = static_cast(2*(size.width()/3.5) ); + } + else + reduceW = 6; + if(size.height()>14) + reduceH = static_cast(2*(size.height()/3.5) ); + else + reduceH = 6; + + int w = size.width() - reduceW; + int h = size.height() - reduceH; + + if (m_bitmaps[toolWindow][typeIndex] && m_bitmaps[toolWindow][typeIndex]->size()==QSize(w,h) ) + return *m_bitmaps[toolWindow][typeIndex]; + + // no matching pixmap found, create a new one... + + delete m_bitmaps[toolWindow][typeIndex]; + m_bitmaps[toolWindow][typeIndex] = 0; + + QBitmap bmp = IconEngine::icon(type /*icon*/, QMIN(w,h) ); + QBitmap *bitmap = new QBitmap(bmp); + m_bitmaps[toolWindow][typeIndex] = bitmap; + return *bitmap; +} + + +// make the handler accessible to other classes... +static IaOraHandler *handler = 0; +IaOraHandler* Handler() +{ + return handler; +} + +} // KWinPlastik + +////////////////////////////////////////////////////////////////////////////// +// Plugin Stuff // +////////////////////////////////////////////////////////////////////////////// + +extern "C" +{ + KDE_EXPORT KDecorationFactory *create_factory() + { + KWinIaOra::handler = new KWinIaOra::IaOraHandler(); + return KWinIaOra::handler; + } +} diff --git a/src/kwin/iaora.desktop b/src/kwin/iaora.desktop new file mode 100644 index 0000000..7bece01 --- /dev/null +++ b/src/kwin/iaora.desktop @@ -0,0 +1,5 @@ +[Desktop Entry] +Encoding=UTF-8 +Icon= +Name=Ia ora +X-KDE-Library=kwin3_iaora diff --git a/src/kwin/iaora.h b/src/kwin/iaora.h new file mode 100644 index 0000000..3f8d757 --- /dev/null +++ b/src/kwin/iaora.h @@ -0,0 +1,126 @@ +/* IaOra KWin window decoration + Based on plastik theme + Copyright (C) 2003-2005 Sandro Giessl + + based on the window decoration "Web": + Copyright (C) 2001 Rik Hemsley (rikkus) + + 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. + */ + +#ifndef IAORA_H +#define IAORA_H + +#include + +#include +#include + +namespace KWinIaOra { + +enum ColorType { + TitleGradient1 = 0, // top + TitleGradient2, + TitleGradient3, // bottom + TitleGradient4, + ShadeTitleLight, + ShadeTitleDark, + Border1, + Border2, + Border3, + TitleFont, + TitleBorder +}; + +enum Pixmaps { + TitleBarTileTop=0, + TitleBarTile, + TitleBarLeft, + TitleBarRight, + BorderLeftTile, + BorderRightTile, + BorderBottomTile, + BorderBottomLeft, + BorderBottomRight, + NumPixmaps +}; + +enum ButtonIcon { + CloseIcon = 0, + MaxIcon, + MaxRestoreIcon, + MinIcon, + HelpIcon, + OnAllDesktopsIcon, + NotOnAllDesktopsIcon, + KeepAboveIcon, + NoKeepAboveIcon, + KeepBelowIcon, + NoKeepBelowIcon, + ShadeIcon, + UnShadeIcon, + NumButtonIcons +}; + +class IaOraHandler: public QObject, public KDecorationFactory +{ + Q_OBJECT +public: + IaOraHandler(); + ~IaOraHandler(); + virtual bool reset( unsigned long changed ); + + virtual KDecoration* createDecoration( KDecorationBridge* ); + virtual bool supports( Ability ability ); + + const QPixmap &pixmap(Pixmaps type, bool active, bool toolWindow); + const QBitmap &buttonBitmap(ButtonIcon type, const QSize &size, bool toolWindow); + + int titleHeight()const { return m_titleHeight; } + int titleHeightTool()const { return m_titleHeightTool; } + const QFont &titleFont() { return m_titleFont; } + const QFont &titleFontTool() { return m_titleFontTool; } + bool titleShadow()const { return m_titleShadow; } + bool menuClose()const { return m_menuClose; } + bool reverseLayout()const { return m_reverse; } + QColor getColor(KWinIaOra::ColorType type, const bool active = true); + QColor getGradientColor( KWinIaOra::ColorType type, const bool active); + QColor getBorderColor( KWinIaOra::ColorType type, const bool active); + QColor getShadowColor(); + +private: + void readConfig(); + + void pretile(QPixmap *&pix, int size, Qt::Orientation dir) const; + + bool m_titleShadow; + bool m_menuClose; + bool m_reverse; + int m_titleHeight; + int m_titleHeightTool; + QFont m_titleFont; + QFont m_titleFontTool; + + // pixmap cache + QPixmap *m_pixmaps[2][2][NumPixmaps]; // button pixmaps have normal+pressed state... + QBitmap *m_bitmaps[2][NumButtonIcons]; +}; + +IaOraHandler* Handler(); + +} // KWinPlastik + +#endif // IAORA_H diff --git a/src/kwin/iaorabutton.cpp b/src/kwin/iaorabutton.cpp new file mode 100644 index 0000000..fe9c3a6 --- /dev/null +++ b/src/kwin/iaorabutton.cpp @@ -0,0 +1,528 @@ +/* IaOra KWin window decoration + Copyright (C) 2006 Laurent Montel + based on plastik code + Copyright (C) 2003-2005 Sandro Giessl + + based on the window decoration "Web": + Copyright (C) 2001 Rik Hemsley (rikkus) + + 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 +#include +#include +#include +#include +#include + +#include "iaorabutton.h" +#include "iaorabutton.moc" +#include "iaoraclient.h" +#include "misc.h" + +namespace KWinIaOra +{ + + +IaOraButton::IaOraButton(ButtonType type, IaOraClient *parent, const char *name) + : KCommonDecorationButton(type, parent, name), + m_client(parent), + m_iconType(NumButtonIcons), + hover(false) +{ + setBackgroundMode(NoBackground); + +} + +IaOraButton::~IaOraButton() +{ +} + +void IaOraButton::reset(unsigned long changed) +{ + if (changed&DecorationReset || changed&ManualReset || changed&SizeChange || changed&StateChange) { + switch (type() ) { + case CloseButton: + m_iconType = CloseIcon; + break; + case HelpButton: + m_iconType = HelpIcon; + break; + case MinButton: + m_iconType = MinIcon; + break; + case MaxButton: + if (isOn()) { + m_iconType = MaxRestoreIcon; + } else { + m_iconType = MaxIcon; + } + break; + case OnAllDesktopsButton: + if (isOn()) { + m_iconType = NotOnAllDesktopsIcon; + } else { + m_iconType = OnAllDesktopsIcon; + } + break; + case ShadeButton: + if (isOn()) { + m_iconType = UnShadeIcon; + } else { + m_iconType = ShadeIcon; + } + break; + case AboveButton: + if (isOn()) { + m_iconType = NoKeepAboveIcon; + } else { + m_iconType = KeepAboveIcon; + } + break; + case BelowButton: + if (isOn()) { + m_iconType = NoKeepBelowIcon; + } else { + m_iconType = KeepBelowIcon; + } + break; + default: + m_iconType = NumButtonIcons; // empty... + break; + } + + this->update(); + } +} + + +void IaOraButton::enterEvent(QEvent *e) +{ + QButton::enterEvent(e); + + hover = true; + repaint(false); +} + +void IaOraButton::leaveEvent(QEvent *e) +{ + QButton::leaveEvent(e); + + hover = false; + repaint(false); +} + +void IaOraButton::drawButton(QPainter *painter) +{ + QRect r(0,0,width(),height()); + + bool active = m_client->isActive(); + KPixmap tempKPixmap; + + QPixmap buffer; + buffer.resize(width(), height()); + QPainter bP(&buffer); + + // fake the titlebar background + bP.drawTiledPixmap(0, 0, width(), width(), /*define color*/m_client->getTitleBarTile(active) ); + if (type() == MenuButton) + { + QPixmap menuIcon(m_client->icon().pixmap( QIconSet::Small, QIconSet::Normal)); + if (width() < menuIcon.width() || height() < menuIcon.height() ) { + menuIcon.convertFromImage( menuIcon.convertToImage().smoothScale(width(), height())); + } + bP.drawPixmap((width()-menuIcon.width())/2, (height()-menuIcon.height())/2, menuIcon); + } + else + { + int dX,dY; + const QBitmap &icon = Handler()->buttonBitmap(m_iconType, size(), decoration()->isToolWindow() ); + dX = r.x()+(r.width()-icon.width())/2; + dY = r.y()+(r.height()-icon.height())/2; + if (isDown() ) { + dY++; + } +#if 0 + if(!isDown() && Handler()->titleShadow() ) { + QColor shadowColor; + if (qGray(Handler()->getColor(TitleFont,active).rgb()) < 100) + shadowColor = QColor(255, 255, 255); + else + shadowColor = QColor(0,0,0); + //bP.setPen(alphaBlendColors(sourfaceTop, shadowColor, 180) ); + bP.drawPixmap(dX+1, dY+1, icon); + } +#endif + bP.setPen(Handler()->getColor(TitleFont,hover ? false : active) ); + bP.drawPixmap(dX, dY, icon,0,0,icon.width(),icon.height()/2); + bP.setPen(QColor("#CFD7DF") ); + bP.drawPixmap(dX, dY+icon.height()/2, icon,0,icon.height()/2,icon.width(),icon.height()); + } + bP.end(); + painter->drawPixmap(0, 0, buffer); +} + +QBitmap IconEngine::icon(ButtonIcon icon, int size) +{ + if (size%2 == 0) + --size; + + QBitmap bitmap(size,size); + bitmap.fill(Qt::color0); + QPainter p(&bitmap); + + p.setPen(Qt::color1); + + QRect r = bitmap.rect(); + + // line widths + int lwTitleBar = 1; + if (r.width() > 16) { + lwTitleBar = 4; + } else if (r.width() > 4) { + lwTitleBar = 2; + } + int lwArrow = 1; + if (r.width() > 16) { + lwArrow = 4; + } else if (r.width() > 7) { + lwArrow = 2; + } + + //QColor col1( "#FFFFFF" ); + //QColor col2( "#CFD7DF" ); + + switch(icon) { + case CloseIcon: + { + int lineWidth = 1; + if (r.width() > 16) { + lineWidth = 3; + } else if (r.width() > 4) { + lineWidth = 2; + } + + drawObject(p, DiagonalLine, r.x(), r.y(), r.width(), lineWidth); + drawObject(p, CrossDiagonalLine, r.x(), r.bottom(), r.width(), lineWidth); + + break; + } + + case MaxIcon: + { + int lineWidth2 = 1; // frame + if (r.width() > 16) { + lineWidth2 = 2; + } else if (r.width() > 4) { + lineWidth2 = 1; + } + + drawObject(p, HorizontalLine, r.x(), r.top(), r.width(), lwTitleBar); + drawObject(p, HorizontalLine, r.x(), r.bottom()-(lineWidth2-1), r.width(), lineWidth2); + drawObject(p, VerticalLine, r.x(), r.top(), r.height(), lineWidth2); + drawObject(p, VerticalLine, r.right()-(lineWidth2-1), r.top(), r.height(), lineWidth2); + + break; + } + + case MaxRestoreIcon: + { + int lineWidth2 = 1; // frame + if (r.width() > 16) { + lineWidth2 = 2; + } else if (r.width() > 4) { + lineWidth2 = 1; + } + + int margin1, margin2; + margin1 = margin2 = lineWidth2*2; + if (r.width() < 8) + margin1 = 1; + + // background window + drawObject(p, HorizontalLine, r.x(), r.top(), r.width()-margin1+1 +3 , lineWidth2); + drawObject(p, HorizontalLine, r.right()-margin2, r.bottom()-(lineWidth2-1)/*-margin1*/, margin2, lineWidth2); + drawObject(p, VerticalLine, r.x(), r.top(), margin2+3, lineWidth2); + drawObject(p, VerticalLine, r.right()-(lineWidth2-1), r.top(), r.height()-margin1+3, lineWidth2); + + // foreground window + drawObject(p, HorizontalLine, r.x(), r.top()+margin2, r.width()-margin2, lwTitleBar); + drawObject(p, HorizontalLine, r.x(), r.bottom()-(lineWidth2-1), r.width()-margin2, lineWidth2); + drawObject(p, VerticalLine, r.x(), r.top()+margin2, r.height(), lineWidth2); + drawObject(p, VerticalLine, r.right()-(lineWidth2-1)-margin2, r.top()+margin2, r.height(), lineWidth2); + break; + } + + case MinIcon: + { + int posY = r.height()/2-(lwTitleBar-1); + + drawObject(p, HorizontalLine, r.x()+1,posY, r.width()-2, lwTitleBar); + //grey 2 + //p.setPen( col2 ); + p.drawLine(r.x(),posY+1, r.x()+r.width()-1, posY+1); + p.drawLine(r.x()+1, posY+2, r.x()+r.width()-2, posY+2); + + break; + } + + case HelpIcon: + { + int center = r.x()+r.width()/2 -1; + int side = r.width()/4; + + // paint a question mark... code is quite messy, to be cleaned up later...! :o + + if (r.width() > 16) { + int lineWidth = 3; + + // top bar + drawObject(p, HorizontalLine, center-side+3, r.y(), 2*side-3-1, lineWidth); + // top bar rounding + drawObject(p, CrossDiagonalLine, center-side-1, r.y()+5, 6, lineWidth); + drawObject(p, DiagonalLine, center+side-3, r.y(), 5, lineWidth); + // right bar + drawObject(p, VerticalLine, center+side+2-lineWidth, r.y()+3, r.height()-(2*lineWidth+side+2+1), lineWidth); + // bottom bar + drawObject(p, CrossDiagonalLine, center, r.bottom()-2*lineWidth, side+2, lineWidth); + drawObject(p, HorizontalLine, center, r.bottom()-3*lineWidth+2, lineWidth, lineWidth); + // the dot + drawObject(p, HorizontalLine, center, r.bottom()-(lineWidth-1), lineWidth, lineWidth); + } else if (r.width() > 8) { + int lineWidth = 2; + + // top bar + drawObject(p, HorizontalLine, center-(side-1), r.y(), 2*side-1, lineWidth); + // top bar rounding + if (r.width() > 9) { + drawObject(p, CrossDiagonalLine, center-side-1, r.y()+3, 3, lineWidth); + } else { + drawObject(p, CrossDiagonalLine, center-side-1, r.y()+2, 3, lineWidth); + } + drawObject(p, DiagonalLine, center+side-1, r.y(), 3, lineWidth); + // right bar + drawObject(p, VerticalLine, center+side+2-lineWidth, r.y()+2, r.height()-(2*lineWidth+side+1), lineWidth); + // bottom bar + drawObject(p, CrossDiagonalLine, center, r.bottom()-2*lineWidth+1, side+2, lineWidth); + // the dot + drawObject(p, HorizontalLine, center, r.bottom()-(lineWidth-1), lineWidth, lineWidth); + } else { + int lineWidth = 1; + + // top bar + drawObject(p, HorizontalLine, center-(side-1), r.y(), 2*side, lineWidth); + // top bar rounding + drawObject(p, CrossDiagonalLine, center-side-1, r.y()+1, 2, lineWidth); + // right bar + drawObject(p, VerticalLine, center+side+1, r.y(), r.height()-(side+2+1), lineWidth); + // bottom bar + drawObject(p, CrossDiagonalLine, center, r.bottom()-2, side+2, lineWidth); + // the dot + drawObject(p, HorizontalLine, center, r.bottom(), 1, 1); + } + + break; + } + + case NotOnAllDesktopsIcon: + { + int lwMark = r.width()-lwTitleBar*2-2; + if (lwMark < 1) + lwMark = 3; + + drawObject(p, HorizontalLine, r.x()+(r.width()-lwMark)/2, r.y()+(r.height()-lwMark)/2, lwMark, lwMark); + + // Fall through to OnAllDesktopsIcon intended! + } + case OnAllDesktopsIcon: + { + // horizontal bars + drawObject(p, HorizontalLine, r.x()+lwTitleBar, r.y(), r.width()-2*lwTitleBar, lwTitleBar); + drawObject(p, HorizontalLine, r.x()+lwTitleBar, r.bottom()-(lwTitleBar-1), r.width()-2*lwTitleBar, lwTitleBar); + // vertical bars + drawObject(p, VerticalLine, r.x(), r.y()+lwTitleBar, r.height()-2*lwTitleBar, lwTitleBar); + drawObject(p, VerticalLine, r.right()-(lwTitleBar-1), r.y()+lwTitleBar, r.height()-2*lwTitleBar, lwTitleBar); + + + break; + } + + case NoKeepAboveIcon: + { + int center = r.x()+r.width()/2; + + // arrow + drawObject(p, CrossDiagonalLine, r.x(), center+2*lwArrow, center-r.x(), lwArrow); + drawObject(p, DiagonalLine, r.x()+center, r.y()+1+2*lwArrow, center-r.x(), lwArrow); + if (lwArrow>1) + drawObject(p, HorizontalLine, center-(lwArrow-2), r.y()+2*lwArrow, (lwArrow-2)*2, lwArrow); + + // Fall through to KeepAboveIcon intended! + } + case KeepAboveIcon: + { + int center = r.x()+r.width()/2; + + // arrow + drawObject(p, CrossDiagonalLine, r.x(), center, center-r.x(), lwArrow); + drawObject(p, DiagonalLine, r.x()+center, r.y()+1, center-r.x(), lwArrow); + if (lwArrow>1) + drawObject(p, HorizontalLine, center-(lwArrow-2), r.y(), (lwArrow-2)*2, lwArrow); + + break; + } + + case NoKeepBelowIcon: + { + int center = r.x()+r.width()/2; + + // arrow + drawObject(p, DiagonalLine, r.x(), center-2*lwArrow, center-r.x(), lwArrow); + drawObject(p, CrossDiagonalLine, r.x()+center, r.bottom()-1-2*lwArrow, center-r.x(), lwArrow); + if (lwArrow>1) + drawObject(p, HorizontalLine, center-(lwArrow-2), r.bottom()-(lwArrow-1)-2*lwArrow, (lwArrow-2)*2, lwArrow); + + // Fall through to KeepBelowIcon intended! + } + case KeepBelowIcon: + { + int center = r.x()+r.width()/2; + + // arrow + drawObject(p, DiagonalLine, r.x(), center, center-r.x(), lwArrow); + drawObject(p, CrossDiagonalLine, r.x()+center, r.bottom()-1, center-r.x(), lwArrow); + if (lwArrow>1) + drawObject(p, HorizontalLine, center-(lwArrow-2), r.bottom()-(lwArrow-1), (lwArrow-2)*2, lwArrow); + + break; + } + + case ShadeIcon: + { + drawObject(p, HorizontalLine, r.x(), r.y(), r.width(), lwTitleBar); + + break; + } + + case UnShadeIcon: + { + int lw1 = 1; + int lw2 = 1; + if (r.width() > 16) { + lw1 = 4; + lw2 = 2; + } else if (r.width() > 7) { + lw1 = 2; + lw2 = 1; + } + + int h = QMAX( (r.width()/2), (lw1+2*lw2) ); + + // horizontal bars + drawObject(p, HorizontalLine, r.x(), r.y(), r.width(), lw1); + drawObject(p, HorizontalLine, r.x(), r.x()+h-(lw2-1), r.width(), lw2); + // vertical bars + drawObject(p, VerticalLine, r.x(), r.y(), h, lw2); + drawObject(p, VerticalLine, r.right()-(lw2-1), r.y(), h, lw2); + + break; + } + + default: + break; + } + + p.end(); + + bitmap.setMask(bitmap); + + return bitmap; +} + +void IconEngine::drawObject(QPainter &p, Object object, int x, int y, int length, int lineWidth) +{ + switch(object) { + case DiagonalLine: + if (lineWidth <= 1) { + for (int i = 0; i < length; ++i) { + p.drawPoint(x+i,y+i); + } + } else if (lineWidth <= 2) { + for (int i = 0; i < length; ++i) { + p.drawPoint(x+i,y+i); + } + for (int i = 0; i < (length-1); ++i) { + p.drawPoint(x+1+i,y+i); + p.drawPoint(x+i,y+1+i); + } + } else { + for (int i = 1; i < (length-1); ++i) { + p.drawPoint(x+i,y+i); + } + for (int i = 0; i < (length-1); ++i) { + p.drawPoint(x+1+i,y+i); + p.drawPoint(x+i,y+1+i); + } + for (int i = 0; i < (length-2); ++i) { + p.drawPoint(x+2+i,y+i); + p.drawPoint(x+i,y+2+i); + } + } + break; + case CrossDiagonalLine: + if (lineWidth <= 1) { + for (int i = 0; i < length; ++i) { + p.drawPoint(x+i,y-i); + } + } else if (lineWidth <= 2) { + for (int i = 0; i < length; ++i) { + p.drawPoint(x+i,y-i); + } + for (int i = 0; i < (length-1); ++i) { + p.drawPoint(x+1+i,y-i); + p.drawPoint(x+i,y-1-i); + } + } else { + for (int i = 1; i < (length-1); ++i) { + p.drawPoint(x+i,y-i); + } + for (int i = 0; i < (length-1); ++i) { + p.drawPoint(x+1+i,y-i); + p.drawPoint(x+i,y-1-i); + } + for (int i = 0; i < (length-2); ++i) { + p.drawPoint(x+2+i,y-i); + p.drawPoint(x+i,y-2-i); + } + } + break; + case HorizontalLine: + for (int i = 0; i < lineWidth; ++i) { + p.drawLine(x,y+i, x+length-1, y+i); + } + break; + case VerticalLine: + for (int i = 0; i < lineWidth; ++i) { + p.drawLine(x+i,y, x+i, y+length-1); + } + break; + default: + break; + } +} + +} // KWinIaOra diff --git a/src/kwin/iaorabutton.h b/src/kwin/iaorabutton.h new file mode 100644 index 0000000..12e9a53 --- /dev/null +++ b/src/kwin/iaorabutton.h @@ -0,0 +1,85 @@ +/* Plastik KWin window decoration + Copyright (C) 2003-2005 Sandro Giessl + + based on the window decoration "Web": + Copyright (C) 2001 Rik Hemsley (rikkus) + + 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. + */ + +#ifndef IAORABUTTON_H +#define IAORABUTTON_H + +#include +#include +#include "iaora.h" + +#include + +class QTimer; + +namespace KWinIaOra { + +class IaOraClient; + +class IaOraButton : public KCommonDecorationButton +{ + Q_OBJECT +public: + IaOraButton(ButtonType type, IaOraClient *parent, const char *name); + ~IaOraButton(); + + void reset(unsigned long changed); + IaOraClient * client() { return m_client; } + + +private: + void enterEvent(QEvent *e); + void leaveEvent(QEvent *e); + void drawButton(QPainter *painter); + +private: + IaOraClient *m_client; + ButtonIcon m_iconType; + bool hover; +}; + +/** + * This class creates bitmaps which can be used as icons on buttons. The icons + * are "hardcoded". + * Over the previous "Gimp->xpm->QImage->recolor->SmoothScale->QPixmap" solution + * it has the important advantage that icons are more scalable and at the same + * time sharp and not blurred. + */ +class IconEngine +{ + public: + static QBitmap icon(ButtonIcon icon, int size); + + private: + enum Object { + HorizontalLine, + VerticalLine, + DiagonalLine, + CrossDiagonalLine + }; + + static void drawObject(QPainter &p, Object object, int x, int y, int length, int lineWidth); +}; + +} // namespace KWinIaOra + +#endif // IAORABUTTON_H diff --git a/src/kwin/iaoraclient.cpp b/src/kwin/iaoraclient.cpp new file mode 100644 index 0000000..7c1af84 --- /dev/null +++ b/src/kwin/iaoraclient.cpp @@ -0,0 +1,514 @@ +/* Ia Ora KWin window decoration + Copyright (c) 2006 Laurent Montel + based on plastik code + Copyright (C) 2003-2005 Sandro Giessl + + based on the window decoration "Web": + Copyright (C) 2001 Rik Hemsley (rikkus) + + 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 + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "iaoraclient.h" +#include "iaorabutton.h" +#include "misc.h" + +namespace KWinIaOra +{ + +IaOraClient::IaOraClient(KDecorationBridge* bridge, KDecorationFactory* factory) + : KCommonDecoration (bridge, factory), + s_titleFont(QFont() ) +{ + memset(m_captionPixmaps, 0, sizeof(QPixmap*)*2); +} + +IaOraClient::~IaOraClient() +{ + clearCaptionPixmaps(); +} + +QString IaOraClient::visibleName() const +{ + return i18n("Ia Ora"); +} + +QString IaOraClient::defaultButtonsLeft() const +{ + return "M"; +} + +QString IaOraClient::defaultButtonsRight() const +{ + return "IAX"; +} + +bool IaOraClient::decorationBehaviour(DecorationBehaviour behaviour) const +{ + switch (behaviour) { + case DB_MenuClose: + return Handler()->menuClose(); + + case DB_WindowMask: + return true; + + default: + return KCommonDecoration::decorationBehaviour(behaviour); + } +} + +int IaOraClient::layoutMetric(LayoutMetric lm, bool respectWindowState, const KCommonDecorationButton *btn) const +{ + bool maximized = maximizeMode()==MaximizeFull && !options()->moveResizeMaximizedWindows(); + + switch (lm) { + case LM_BorderLeft: + case LM_BorderRight: + case LM_BorderBottom: + { + if (respectWindowState && maximized) { + return 0; + } else { + return 3; + } + } + + case LM_TitleEdgeTop: + { + if (respectWindowState && maximized) { + return 0; + } else { + return 3; + } + } + + case LM_TitleEdgeBottom: + { + if (respectWindowState && maximized) { + return 1; + } else { + return 2; + } + } + + case LM_TitleEdgeLeft: + case LM_TitleEdgeRight: + { + //if (respectWindowState && maximized) { + return 1; + //} else { + //return 3; + //} + } + + case LM_TitleBorderLeft: + case LM_TitleBorderRight: + return 0; + + case LM_ButtonWidth: + case LM_ButtonHeight: + case LM_TitleHeight: + { + if (respectWindowState && isToolWindow()) { + return Handler()->titleHeightTool(); + } else { + return Handler()->titleHeight(); + } + } + + case LM_ButtonSpacing: + return 1; + + case LM_ButtonMarginTop: + return 0; + + case LM_ExplicitButtonSpacer: + return 3; + + default: + return KCommonDecoration::layoutMetric(lm, respectWindowState, btn); + } +} + +KCommonDecorationButton *IaOraClient::createButton(ButtonType type) +{ + switch (type) { + case MenuButton: + return new IaOraButton(MenuButton, this, "menu"); + + case OnAllDesktopsButton: + return new IaOraButton(OnAllDesktopsButton, this, "on_all_desktops"); + + case HelpButton: + return new IaOraButton(HelpButton, this, "help"); + + case MinButton: + return new IaOraButton(MinButton, this, "minimize"); + + case MaxButton: + return new IaOraButton(MaxButton, this, "maximize"); + + case CloseButton: + return new IaOraButton(CloseButton, this, "close"); + + case AboveButton: + return new IaOraButton(AboveButton, this, "above"); + + case BelowButton: + return new IaOraButton(BelowButton, this, "below"); + + case ShadeButton: + return new IaOraButton(ShadeButton, this, "shade"); + + default: + return 0; + } +} + +void IaOraClient::init() +{ + s_titleFont = isToolWindow() ? Handler()->titleFontTool() : Handler()->titleFont(); + + clearCaptionPixmaps(); + + KCommonDecoration::init(); +} + +QRegion IaOraClient::cornerShape(WindowCorner corner) +{ + int w = widget()->width(); + int h = widget()->height(); + + switch (corner) { + case WC_TopLeft: + if (layoutMetric(LM_TitleEdgeLeft) > 0) + return QRegion(0, 0, 1, 1);// + QRegion(1, 0, 1, 1); + else + return QRegion(); + + case WC_TopRight: + if (layoutMetric(LM_TitleEdgeRight) > 0) + return QRegion(w-1, 0, 1, 1);// + QRegion(w-2, 0, 1, 1); + else + return QRegion(); + + case WC_BottomLeft: + if (layoutMetric(LM_BorderBottom) > 0) + return QRegion(0, h-1, 1, 1); + else + return QRegion(); + + case WC_BottomRight: + if (layoutMetric(LM_BorderBottom) > 0) + return QRegion(w-1, h-1, 1, 1); + else + return QRegion(); + + default: + return QRegion(); + } + +} + +void IaOraClient::paintEvent(QPaintEvent *e) +{ + QRegion region = e->region(); + + IaOraHandler *handler = Handler(); + + if (oldCaption != caption() ) + clearCaptionPixmaps(); + + bool active = isActive(); + bool toolWindow = isToolWindow(); + + QPainter painter(widget() ); + + // often needed coordinates + QRect r = widget()->rect(); + + int r_w = r.width(); +// int r_h = r.height(); + int r_x, r_y, r_x2, r_y2; + r.coords(&r_x, &r_y, &r_x2, &r_y2); + const int borderLeft = layoutMetric(LM_BorderLeft); + const int borderRight = layoutMetric(LM_BorderRight); + const int borderBottom = layoutMetric(LM_BorderBottom); + const int titleHeight = layoutMetric(LM_TitleHeight); + const int titleEdgeTop = layoutMetric(LM_TitleEdgeTop); + const int titleEdgeBottom = layoutMetric(LM_TitleEdgeBottom); + const int titleEdgeLeft = layoutMetric(LM_TitleEdgeLeft); + const int titleEdgeRight = layoutMetric(LM_TitleEdgeRight); + + const int borderBottomTop = r_y2-borderBottom+1; + const int borderLeftRight = r_x+borderLeft-1; + const int borderRightLeft = r_x2-borderRight+1; + const int titleEdgeBottomBottom = r_y+titleEdgeTop+titleHeight+titleEdgeBottom-1; + + const int sideHeight = borderBottomTop-titleEdgeBottomBottom-1; + + QRect Rtitle = QRect(r_x+titleEdgeLeft+buttonsLeftWidth(), r_y+titleEdgeTop, + r_x2-titleEdgeRight-buttonsRightWidth()-(r_x+titleEdgeLeft+buttonsLeftWidth()), + titleEdgeBottomBottom-(r_y+titleEdgeTop) ); + + QRect tempRect; + + // topSpacer + if(titleEdgeTop > 0) + { + tempRect.setRect(r_x+2, r_y, r_w-2*2, titleEdgeTop ); + if (tempRect.isValid() && region.contains(tempRect) ) { + painter.drawTiledPixmap(tempRect, handler->pixmap(TitleBarTileTop, active, toolWindow) ); + } + } + + // leftTitleSpacer + int titleMarginLeft = 0; + int titleMarginRight = 0; + if(titleEdgeLeft > 0) + { + tempRect.setRect(r_x, r_y, borderLeft, titleEdgeTop+titleHeight+titleEdgeBottom); + if (tempRect.isValid() && region.contains(tempRect) ) { + painter.drawTiledPixmap(tempRect, handler->pixmap(TitleBarLeft, active, toolWindow) ); + titleMarginLeft = borderLeft; + } + } + + // rightTitleSpacer + if(titleEdgeRight > 0) + { + tempRect.setRect(borderRightLeft, r_y, borderRight, titleEdgeTop+titleHeight+titleEdgeBottom); + if (tempRect.isValid() && region.contains(tempRect) ) { + painter.drawTiledPixmap(tempRect, handler->pixmap(TitleBarRight, active, toolWindow) ); + titleMarginRight = borderRight; + } + } + + // titleSpacer + const QPixmap &caption = captionPixmap(); + if(Rtitle.width() > 0) + { + m_captionRect = captionRect(); // also update m_captionRect! + if (m_captionRect.isValid() && region.contains(m_captionRect) ) + { + painter.drawTiledPixmap(m_captionRect, caption); + } + + // left to the title + tempRect.setRect(r_x+titleMarginLeft, m_captionRect.top(), + m_captionRect.left() - (r_x+titleMarginLeft), m_captionRect.height() ); + if (tempRect.isValid() && region.contains(tempRect) ) { + painter.drawTiledPixmap(tempRect, handler->pixmap(TitleBarTile, active, toolWindow) ); + } + + // right to the title + tempRect.setRect(m_captionRect.right()+1, m_captionRect.top(), + (r_x2-titleMarginRight) - m_captionRect.right(), m_captionRect.height() ); + if (tempRect.isValid() && region.contains(tempRect) ) { + painter.drawTiledPixmap(tempRect, handler->pixmap(TitleBarTile, active, toolWindow) ); + } + + } + + // leftSpacer + if(borderLeft > 0 && sideHeight > 0) + { + tempRect.setCoords(r_x, titleEdgeBottomBottom+1, borderLeftRight, borderBottomTop-1); + if (tempRect.isValid() && region.contains(tempRect) ) { + painter.drawTiledPixmap(tempRect, handler->pixmap(BorderLeftTile, active, toolWindow) ); + } + } + + // rightSpacer + if(borderRight > 0 && sideHeight > 0) + { + tempRect.setCoords(borderRightLeft, titleEdgeBottomBottom+1, r_x2, borderBottomTop-1); + if (tempRect.isValid() && region.contains(tempRect) ) { + painter.drawTiledPixmap(tempRect, handler->pixmap(BorderRightTile, active, toolWindow) ); + } + } + + // bottomSpacer + if(borderBottom > 0) + { + int l = r_x; + int r = r_x2; + + tempRect.setRect(r_x, borderBottomTop, borderLeft, borderBottom); + if (tempRect.isValid() && region.contains(tempRect) ) { + painter.drawTiledPixmap(tempRect, handler->pixmap(BorderBottomLeft, active, toolWindow) ); + l = tempRect.right()+1; + } + + tempRect.setRect(borderRightLeft, borderBottomTop, borderLeft, borderBottom); + if (tempRect.isValid() && region.contains(tempRect) ) { + painter.drawTiledPixmap(tempRect, handler->pixmap(BorderBottomRight, active, toolWindow) ); + r = tempRect.left()-1; + } + + tempRect.setCoords(l, borderBottomTop, r, r_y2); + if (tempRect.isValid() && region.contains(tempRect) ) { + painter.drawTiledPixmap(tempRect, handler->pixmap(BorderBottomTile, active, toolWindow) ); + } + } +} + +QRect IaOraClient::captionRect() const +{ + const QPixmap &caption = captionPixmap(); + QRect r = widget()->rect(); + + const int titleHeight = layoutMetric(LM_TitleHeight); + const int titleEdgeBottom = layoutMetric(LM_TitleEdgeBottom); + const int titleEdgeTop = layoutMetric(LM_TitleEdgeTop); + const int titleEdgeLeft = layoutMetric(LM_TitleEdgeLeft); + const int marginLeft = layoutMetric(LM_TitleBorderLeft); + const int marginRight = layoutMetric(LM_TitleBorderRight); + + const int titleLeft = r.left() + titleEdgeLeft + buttonsLeftWidth() + marginLeft; + const int titleWidth = r.width() - + titleEdgeLeft - layoutMetric(LM_TitleEdgeRight) - + buttonsLeftWidth() - buttonsRightWidth() - + marginLeft - marginRight; + int tX, tW; // position/width of the title buffer + if (caption.width() > titleWidth) { + tW = titleWidth; + } else { + tW = caption.width(); + } + + if (caption.width() > titleWidth ) { + // Align left + tX = titleLeft; + } + else + tX = titleLeft+(titleWidth- caption.width() )/2; + return QRect(tX, r.top()+titleEdgeTop, tW, titleHeight+titleEdgeBottom); +} + +void IaOraClient::updateCaption() +{ + QRect oldCaptionRect = m_captionRect; + + if (oldCaption != caption() ) + clearCaptionPixmaps(); + + m_captionRect = IaOraClient::captionRect(); + + if (oldCaptionRect.isValid() && m_captionRect.isValid() ) + widget()->update(oldCaptionRect|m_captionRect); + else + widget()->update(); +} + +void IaOraClient::reset( unsigned long changed ) +{ + if (changed & SettingColors) + { + // repaint the whole thing + clearCaptionPixmaps(); + widget()->update(); + updateButtons(); + } else if (changed & SettingFont) { + // font has changed -- update title height and font + s_titleFont = isToolWindow() ? Handler()->titleFontTool() : Handler()->titleFont(); + + updateLayout(); + + // then repaint + clearCaptionPixmaps(); + widget()->update(); + } + + KCommonDecoration::reset(changed); +} + +const QPixmap &IaOraClient::getTitleBarTile(bool active) const +{ + return Handler()->pixmap(TitleBarTile, active, isToolWindow() ); +} + +const QPixmap &IaOraClient::captionPixmap() const +{ + bool active = isActive(); + + if (m_captionPixmaps[active]) { + return *m_captionPixmaps[active]; + } + + // not found, create new pixmap... + + const uint maxCaptionLength = 300; // truncate captions longer than this! + QString c(caption() ); + if (c.length() > maxCaptionLength) { + c.truncate(maxCaptionLength); + c.append(" [...]"); + } + + QFontMetrics fm(s_titleFont); + int captionWidth = fm.width(c); + int captionHeight = fm.height(); + + const int th = layoutMetric(LM_TitleHeight, false) + layoutMetric(LM_TitleEdgeBottom, false); + + QPainter painter; + + const int thickness = 2; + + QPixmap *captionPixmap = new QPixmap(captionWidth+2*thickness, th); + + painter.begin(captionPixmap); + painter.drawTiledPixmap(captionPixmap->rect(), + Handler()->pixmap(TitleBarTile, active, isToolWindow()) ); + + painter.setFont(s_titleFont); + QPoint tp(1, captionHeight-1); +// if(Handler()->titleShadow()) +// { +// painter.setPen(Handler()->getShadowColor()); +// painter.drawText(tp+QPoint(2,2), c); +// } + painter.setPen(Handler()->getColor(TitleFont,active) ); + painter.drawText(tp, c ); + painter.end(); + + m_captionPixmaps[active] = captionPixmap; + return *captionPixmap; +} + +void IaOraClient::clearCaptionPixmaps() +{ + for (int i = 0; i < 2; ++i) { + delete m_captionPixmaps[i]; + m_captionPixmaps[i] = 0; + } + + oldCaption = caption(); +} + +} // KWinIaOra diff --git a/src/kwin/iaoraclient.h b/src/kwin/iaoraclient.h new file mode 100644 index 0000000..5c66194 --- /dev/null +++ b/src/kwin/iaoraclient.h @@ -0,0 +1,73 @@ +/* Plastik KWin window decoration + Copyright (C) 2003-2005 Sandro Giessl + + based on the window decoration "Web": + Copyright (C) 2001 Rik Hemsley (rikkus) + + 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. + */ + +#ifndef IAORACLIENT_H +#define IAORACLIENT_H + +#include + +#include "iaora.h" + +namespace KWinIaOra { + +class IaOraButton; + +class IaOraClient : public KCommonDecoration +{ +public: + IaOraClient(KDecorationBridge* bridge, KDecorationFactory* factory); + ~IaOraClient(); + + virtual QString visibleName() const; + virtual QString defaultButtonsLeft() const; + virtual QString defaultButtonsRight() const; + virtual bool decorationBehaviour(DecorationBehaviour behaviour) const; + virtual int layoutMetric(LayoutMetric lm, bool respectWindowState = true, const KCommonDecorationButton * = 0) const; + virtual QRegion cornerShape(WindowCorner corner); + virtual KCommonDecorationButton *createButton(ButtonType type); + + virtual void init(); + virtual void reset( unsigned long changed ); + + virtual void paintEvent(QPaintEvent *e); + virtual void updateCaption(); + + const QPixmap &getTitleBarTile(bool active) const; + +private: + QRect captionRect() const; + + const QPixmap &captionPixmap() const; + void clearCaptionPixmaps(); + + mutable QPixmap *m_captionPixmaps[2]; + + QRect m_captionRect; + QString oldCaption; + + // settings... + QFont s_titleFont; +}; + +} // KwinIaora + +#endif // IAORACLIENT_H diff --git a/src/kwin/misc.cpp b/src/kwin/misc.cpp new file mode 100644 index 0000000..f050975 --- /dev/null +++ b/src/kwin/misc.cpp @@ -0,0 +1,49 @@ +/* Plastik KWin window decoration + Copyright (C) 2003 Sandro Giessl + + based on the window decoration "Web": + Copyright (C) 2001 Rik Hemsley (rikkus) + + 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 +#include + +#include +#include +#include + +#include "misc.h" + +QColor alphaBlendColors(const QColor &bgColor, const QColor &fgColor, const int a) +{ + + // normal button... + QRgb rgb = bgColor.rgb(); + QRgb rgb_b = fgColor.rgb(); + int alpha = a; + if(alpha>255) alpha = 255; + if(alpha<0) alpha = 0; + int inv_alpha = 255 - alpha; + + QColor result = QColor( qRgb(qRed(rgb_b)*inv_alpha/255 + qRed(rgb)*alpha/255, + qGreen(rgb_b)*inv_alpha/255 + qGreen(rgb)*alpha/255, + qBlue(rgb_b)*inv_alpha/255 + qBlue(rgb)*alpha/255) ); + + return result; +} + diff --git a/src/kwin/misc.h b/src/kwin/misc.h new file mode 100644 index 0000000..b304513 --- /dev/null +++ b/src/kwin/misc.h @@ -0,0 +1,28 @@ +/* Plastik KWin window decoration + Copyright (C) 2003 Sandro Giessl + + based on the window decoration "Web": + Copyright (C) 2001 Rik Hemsley (rikkus) + + 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. + */ + +#ifndef MISC_H +#define MISC_H + +QColor alphaBlendColors(const QColor &backgroundColor, const QColor &foregroundColor, const int alpha); + +#endif // MISC_H diff --git a/src/widget/Makefile.am b/src/widget/Makefile.am new file mode 100644 index 0000000..50d677f --- /dev/null +++ b/src/widget/Makefile.am @@ -0,0 +1,26 @@ +KDE_PLUGIN = -avoid-version -module -no-undefined $(KDE_NO_UNDEFINED) $(KDE_RPATH) $(KDE_MT_LDFLAGS) + +AM_CPPFLAGS = -DQT_PLUGIN + +INCLUDES = $(all_includes) +noinst_HEADERS = ia_ora.h bitmaps.h +kde_style_LTLIBRARIES = ia_ora.la +ia_ora_la_LDFLAGS = $(all_libraries) $(KDE_PLUGIN) -module +ia_ora_la_LIBADD = -lkdefx -lkdecore -lqt-mt +ia_ora_la_SOURCES = ia_ora.cpp +ia_ora_la_METASOURCES = AUTO + +# todo fix me install themerc file +ia_ora.lo: ia_ora.h ia_ora.moc + +ia_ora.moc : ia_ora.h + $(MOC) $(srcdir)/ia_ora.h -o ia_ora.moc + +BUILT_SOURCES = ia_ora.moc + +CLEANFILES = $(BUILT_SOURCES) + +ia_oradata_DATA = ia_ora.themerc +ia_oradatadir = $(kde_datadir)/kstyle/themes + +EXTRA_DIST = ia_ora.cpp ia_ora.h $(ia_oradata_DATA) diff --git a/src/widget/bitmaps.h b/src/widget/bitmaps.h new file mode 100644 index 0000000..8744288 --- /dev/null +++ b/src/widget/bitmaps.h @@ -0,0 +1,85 @@ +#ifndef __BITMAPS_H +#define __BITMAPS_H + +// Fix Qt's wacky image positions +static const char * const hc_minimize_toto_xpm[] = { +"12 12 2 1", +"# c #000000", +". c None", +"............", +"............", +"............", +"............", +"............", +"............", +"............", +"............", +"...######...", +"...######...", +"............", +"............"}; + +static const char * const hc_close_toto_xpm[] = { +"12 12 3 1", +"# c #000000", +". c None", +"; c #4dff50", +"............", +"..;;;;;;;;..", +".....##.....", +"..##....##..", +"...##..##...", +"....####....", +".....##.....", +"....####....", +"...##..##...", +"..##....##..", +"..;;.##.;;..", +"..##....##.."}; + + +static const QCOORD s_arrowUp[]={0,4,5,0, + 1,3,6,1, + 2,4,7,2, + 3,1,8,3, + 4,0,9,4}; + +static const QCOORD s_arrowDown[]={0,0,9,0, + 1,1,8,1, + 2,2,7,2, + 3,3,6,3, + 4,4,5,4}; + +static const QCOORD c_edit_arrow[]={-4,-5, 4, -5, + -4 ,-2, 4, -2, + -3 ,-1, 3, -1, + -2 ,0, 2, 0, + -1, 1, 1, 1, + 0, 2, 0, 2}; + +static const QCOORD c_arrow[]={-4 ,-2, 4, -2, + -3 ,-1, 3, -1, + -2 ,0, 2, 0, + -1, 1, 1, 1, + 0, 2, 0, 2}; + +const QCOORD u_spinarrow[]={ 0,-2, 0,-2, -1,-1, 1,-1, -2,0, 2,0 }; +const QCOORD d_spinarrow[]={ -2,-1, 2,-1, -1,0, 1,0, 0,1, 0,1 }; + + +const QCOORD u_arrow[]={ 0,-2, 0,-2, -1,-1, 1,-1, -2,0, 2,0, -3,1, 3,1 }; +const QCOORD d_arrow[]={ -3,-2, 3,-2, -2,-1, 2,-1, -1,0, 1,0, 0,1, 0,1 }; +const QCOORD l_arrow[]={ 1,-3, 1,-3, 0,-2, 1,-2, -1,-1, 1,-1, -2,0, 1,0, -1,1, 1,1, 0,2, 1,2, 1,3, 1,3 }; +const QCOORD r_arrow[]={ -2,-3, -2,-3, -2,-2, -1,-2, -2,-1, 0,-1, -2,0, 1,0, -2,1, 0,1, -2,2, -1,2, -2,3, -2,3 }; + +#define QCOORDARRLEN(x) sizeof(x)/(sizeof(QCOORD)*2) + + + + +static unsigned char menu_check_bits[] = { + 0x00,0x00,0x00,0x04,0x00,0x06,0x00,0x07,0x84,0x07,0xcc,0x03,0xfc,0x01,0xfc, + 0x00,0x78,0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; + + +#endif diff --git a/src/widget/ia_ora.cpp b/src/widget/ia_ora.cpp new file mode 100644 index 0000000..a508738 --- /dev/null +++ b/src/widget/ia_ora.cpp @@ -0,0 +1,3426 @@ +/* + * Copyright (C) 2007 Gustavo Pichorim Boiko + * Copyright (C) 2006 Laurent Montel + * + * based on KDE3 HighColor Style (version 1.0) + * Copyright (C) 2001-2002 Karol Szwed + * (C) 2001-2002 Fredrik Höglund + * + * renderGradient() code adapted from the Plastik stype + * Copyright (C) 2003 Sandro Giessl + * + * Drawing routines adapted from the KDE2 HCStyle, + * Copyright (C) 2000 Daniel M. Duley + * (C) 2000 Dirk Mueller + * (C) 2001 Martijn Klingens + * + * 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., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "ia_ora.h" +#include "ia_ora.moc" +#include "bitmaps.h" +#include +#include +#include +//#define USE_CROSS 1 + +// -- Style Plugin Interface ------------------------- +class ThemeMdvStylePlugin : public QStylePlugin +{ +public: + ThemeMdvStylePlugin() {} + ~ThemeMdvStylePlugin() {} + + QStringList keys() const + { + return QStringList() << "ia_ora"; + } + + QStyle* create( const QString& key ) + { + if ( key == "ia_ora" ) + return new MandrivaStyle( ); + return 0; + } +}; + +Q_EXPORT_PLUGIN( ThemeMdvStylePlugin ) +// --------------------------------------------------- + + +// ### Remove globals +QBitmap menuBmp; + +static bool scrollmin = false; +static bool scrollmax = false; + + +static const int itemFrame = 1; +static const int itemHMargin = 3; +static const int itemVMargin = 0; +static const int arrowHMargin = 6; +static const int rightBorder = 12; +static const char* kdeToolbarWidget = "kde toolbar widget"; +const int smallButMaxW = 27; +const int smallButMaxH = 20; + +// --------------------------------------------------------------------------- +MandrivaStyle::MandrivaColorData::~MandrivaColorData() +{ +} + +// --------------------------------------------------------------------------- + +MandrivaStyle::MandrivaStyle( ) + : KStyle( AllowMenuTransparency | FilledFrameWorkaround, WindowsStyleScrollBar ) + , m_dataCache (), formMode( false ),kickerMode(false) +{ + hoverWidget = 0L; + hoverControl = HoverNone; + m_dataCache.setAutoDelete(true); + horizontalLine = 0; + verticalLine = 0; + + // setup pixmap cache... + pixmapCache = new QIntCache(150000, 499); + pixmapCache->setAutoDelete(true); +} + + +MandrivaStyle::~MandrivaStyle() +{ + delete pixmapCache; + delete horizontalLine; + delete verticalLine; +} + + +MandrivaStyle::MandrivaColorData *MandrivaStyle::realizeData (const QColorGroup &cg) const +{ + MandrivaColorData *cdata; + //define mandriva color + cdata = new MandrivaColorData; + cdata->spotColor = cg.highlight().rgb(); + + //blue mdk color + //cg.base() == white + //G0 gb.background() + //B2 gb.hightlight + //Hardcode + if ( cg.background() == QColor( "#EFF3F7" ) ) + { + //Be sure to use design color + cdata->shades[0]=QColor( "#EFF3F7" ); + cdata->shades[1]=QColor( "#DFE7EF" ); + cdata->shades[2]=QColor( "#CFD7DF" ); + cdata->shades[3]=QColor( "#C7D3DF" ); + cdata->shades[4]=QColor( "#B6C3CF" ); + cdata->shades[5]=QColor( "#A6B2C7" ); + cdata->shades[6]=QColor( "#8692A6" ); + } + else + { + //create algo + cdata->shades[0]=cg.background(); + cdata->shades[1]=cdata->shades[0].dark(107); + cdata->shades[2]=cdata->shades[0].dark(115); + cdata->shades[3]=cdata->shades[0].dark(117); + cdata->shades[4]=cdata->shades[0].dark(131); + cdata->shades[5]=cdata->shades[0].dark(144); + cdata->shades[6]=cdata->shades[0].dark(178); + + } + if ( cg.highlight() == QColor("#4965AE" ) ) // Blue + { + cdata->blueMdkColor[0]=QColor("#A6B6E7" ); + cdata->blueMdkColor[1]=QColor("#8EA2CF" ); + cdata->blueMdkColor[2]=QColor("#4965AE" ); + cdata->blueMdkColor[3]=QColor("#415DA6" ); + cdata->blueMdkColor[4]=QColor("#21459C" ); + } + else if ( cg.highlight() == QColor("#8EC7FF" ) ) // Arctic + { + cdata->blueMdkColor[0]=QColor("#EFF7FF" ); + cdata->blueMdkColor[1]=QColor("#C7DFFF" ); + cdata->blueMdkColor[2]=QColor("#8EC7FF" ); + cdata->blueMdkColor[3]=QColor("#79BEFF" ); + cdata->blueMdkColor[4]=QColor("#69B6FF" ); + } + else if ( cg.highlight() == QColor("#7BAAE7" ) ) // Smooth + { + cdata->blueMdkColor[0]=QColor("#CEE3FF" ); + cdata->blueMdkColor[1]=QColor("#ADCFFF" ); + cdata->blueMdkColor[2]=QColor("#7BAAE7" ); + cdata->blueMdkColor[3]=QColor("#5A8AD6" ); + cdata->blueMdkColor[4]=QColor("#427DC6" ); + } + else if ( cg.highlight() == QColor("#F7B610" ) ) // Orange + { + cdata->blueMdkColor[0]=QColor("#FFDF10" ); + cdata->blueMdkColor[1]=QColor("#FFCB10" ); + cdata->blueMdkColor[2]=QColor("#F7B610" ); + cdata->blueMdkColor[3]=QColor("#FFA208" ); + cdata->blueMdkColor[4]=QColor("#F79600" ); + } + else if ( cg.highlight() == QColor("#CFD7DF" ) ) // Gray + { + cdata->blueMdkColor[0]=cdata->shades[1]; + cdata->blueMdkColor[1]=cdata->shades[2]; + cdata->blueMdkColor[2]=cdata->shades[3]; + cdata->blueMdkColor[3]=cdata->shades[4]; + cdata->blueMdkColor[4]=cdata->shades[5]; + } + + else + { + cdata->blueMdkColor[2]=cg.highlight(); + cdata->blueMdkColor[0]=cdata->blueMdkColor[2].light(150); + cdata->blueMdkColor[1]=cdata->blueMdkColor[2].light(137); + cdata->blueMdkColor[3]=cdata->blueMdkColor[2].dark(112); + cdata->blueMdkColor[4]=cdata->blueMdkColor[2].dark(130); + } + + if (cg.button() == cg.background()) + { + for (int i=0; i < 7; ++i) + cdata->buttonColor[i] = cdata->shades[i]; + } + else if ( cg.button() == QColor( "#EFF3F7" ) ) + { + //Be sure to use design color + cdata->buttonColor[0]=QColor( "#EFF3F7" ); + cdata->buttonColor[1]=QColor( "#DFE7EF" ); + cdata->buttonColor[2]=QColor( "#CFD7DF" ); + cdata->buttonColor[3]=QColor( "#C7D3DF" ); + cdata->buttonColor[4]=QColor( "#B6C3CF" ); + cdata->buttonColor[5]=QColor( "#A6B2C7" ); + cdata->buttonColor[6]=QColor( "#8692A6" ); + } + else + { + cdata->buttonColor[0]=cg.button(); + cdata->buttonColor[1]=cdata->buttonColor[0].dark(107); + cdata->buttonColor[2]=cdata->buttonColor[0].dark(115); + cdata->buttonColor[3]=cdata->buttonColor[0].dark(117); + cdata->buttonColor[4]=cdata->buttonColor[0].dark(131); + cdata->buttonColor[5]=cdata->buttonColor[0].dark(144); + cdata->buttonColor[6]=cdata->buttonColor[0].dark(178); + } + + return cdata; +} + +/* We assume this seldom collides, since we can only cache one at a time */ +static long hashColorGroup (const QColorGroup &cg) +{ + return cg.button().rgb();// << 8 ^ cg.button().rgb(); +} + + +const MandrivaStyle::MandrivaColorData *MandrivaStyle::lookupData (const QColorGroup &cg) const +{ + MandrivaColorData *cdata; + long h; + QIntCache *cache; + + h = hashColorGroup (cg); + + // Cast away the const crap + // Nasty, but how else would i do it? + cache = (QIntCache *)&m_dataCache; + + cdata = cache->find(h); + + if (cdata == 0 || !cdata->isGroup(cg)) + { + if (cdata != 0) + { + cache->remove (h); + } + + cdata = realizeData (cg); + cache->insert (h, cdata); + } + + return cdata; +} + +void MandrivaStyle::getShade (const QColorGroup &cg, int shadenr, QColor &res) const +{ + const MandrivaColorData *cdata = lookupData(cg); + + res = cdata->shades[shadenr]; +} + +void MandrivaStyle::updateHoverControl(const QPoint &pos) +{ + QRegion repaint; + enum Hover oldControl = hoverControl; + hoverControl = HoverNone; + + if (!hoverWidget) + return; + + if (hoverWidget->inherits("QScrollBar")) + { + QRect subline(querySubControlMetrics(CC_ScrollBar, hoverWidget, + SC_ScrollBarSubLine)), + addline(querySubControlMetrics(CC_ScrollBar, hoverWidget, + SC_ScrollBarAddLine)), + slider(querySubControlMetrics(CC_ScrollBar, hoverWidget, + SC_ScrollBarSlider)); + if (subline.contains(pos)) + hoverControl = HoverScrollBarSubLine; + else if (addline.contains(pos)) + hoverControl = HoverScrollBarAddLine; + else if (slider.contains(pos)) + hoverControl = HoverScrollBarSlider; + + if (hoverControl == HoverScrollBarSubLine + || oldControl == HoverScrollBarSubLine) + repaint += subline; + if (hoverControl == HoverScrollBarAddLine + || oldControl == HoverScrollBarAddLine) + repaint += addline; + if (hoverControl == HoverScrollBarSlider + || oldControl == HoverScrollBarSlider) + repaint += slider; + } + else if (hoverWidget->inherits("QComboBox")) + { + QComboBox *cb = static_cast(hoverWidget); + // for not editable combo, this is not necessary + if (!cb->editable()) + return; + + QRect comboArrow(querySubControlMetrics(CC_ComboBox, hoverWidget, + SC_ComboBoxArrow)), + comboEditField(querySubControlMetrics(CC_ComboBox, hoverWidget, + SC_ComboBoxEditField)); + + if (comboArrow.contains(pos)) + hoverControl = HoverComboBoxArrow; + else if (comboEditField.contains(pos)) + hoverControl = HoverComboBoxEdit; + + if (hoverControl == HoverComboBoxArrow + || oldControl == HoverComboBoxArrow) + repaint += comboArrow; + if (hoverControl == HoverComboBoxEdit + || oldControl == HoverComboBoxEdit) + repaint += comboEditField; + } + // if we are still in the same subcontrol, return + if (oldControl != hoverControl) + hoverWidget->repaint(repaint, false); +} + +void MandrivaStyle::polish(QApplication* app) +{ + if (!qstrcmp(app->argv()[0], "kicker")) + kickerMode = true; +} + +void MandrivaStyle::polish(QWidget* widget) +{ + // Put in order of highest occurance to maximize hit rate + if ( widget->inherits( "QComboBox" ) + || widget->inherits("QScrollBar") + || widget->inherits("QHeader") + || widget->inherits( "QSlider" ) + || widget->inherits( "QCheckBox" ) + || widget->inherits("QSplitterHandle")) + { + widget->installEventFilter(this); + if (widget->inherits( "QScrollBar" ) || widget->inherits( "QComboBox" )) + widget->setMouseTracking( true ); + } + else if (widget->inherits("QMenuBar") + || widget->inherits("QPopupMenu") ) + { + widget->setBackgroundMode(QWidget::NoBackground); + } + else if (widget->inherits("QPushButton") ) + { + widget->installEventFilter(this); + widget->setBackgroundMode( QWidget::PaletteBackground ); + } + else if ( widget->inherits( "KToolBarSeparator" ) || widget->inherits( "QToolBarSeparator" ) ) + { + widget->setBackgroundMode( QWidget::PaletteBackground ); + } + else if (widget->inherits("QToolBarExtensionWidget")) + { + widget->installEventFilter(this); + } + else if ( widget->parentWidget() && + ( ( widget->inherits( "QListBox" ) && widget->parentWidget()->inherits( "QComboBox" ) ) + || widget->inherits( "KCompletionBox" ) ) ) + { + QListBox* listbox = (QListBox*) widget; + listbox->setLineWidth( 1 ); + listbox->setBackgroundMode( NoBackground ); + widget->installEventFilter( this ); + } + else if ( !qstrcmp( widget->name(), kdeToolbarWidget) ) + { + widget->setBackgroundMode( NoBackground ); // We paint the whole background. + widget->installEventFilter(this); + } + KStyle::polish( widget ); +} + + +void MandrivaStyle::unPolish(QWidget* widget) +{ + QFont f = QApplication::font(); + QApplication::setFont( f, TRUE ); // get rid of the special fonts for special widget classes + + if ( widget->inherits( "QComboBox" ) + || widget->inherits("QScrollBar") + || widget->inherits("QHeader") + || widget->inherits( "QSlider" ) + || widget->inherits( "QCheckBox" ) + || widget->inherits("QSplitterHandle")) + { + widget->removeEventFilter(this); + } + else if ( widget->inherits("QMenuBar") + || widget->inherits("QPopupMenu")) + { + widget->setBackgroundMode(QWidget::PaletteBackground); + } + else if ( widget->inherits("QPushButton") ) + { + widget->removeEventFilter(this); + } + else if (widget->inherits("QToolBarExtensionWidget")) + { + widget->removeEventFilter(this); + } + else if ( widget->parentWidget() && + ( ( widget->inherits( "QListBox" ) && widget->parentWidget()->inherits( "QComboBox" ) ) + || widget->inherits( "KCompletionBox" ) ) ) + { + QListBox* listbox = (QListBox*) widget; + listbox->setLineWidth( 1 ); + listbox->setBackgroundMode( PaletteBackground ); + widget->removeEventFilter( this ); + widget->clearMask(); + } + //For toolbar internal separators, return to button, too (can't use qt_cast here since don't have access to the class) + else if ( widget->inherits( "KToolBarSeparator" ) || widget->inherits( "QToolBarSeparator" ) ) + { + widget->setBackgroundMode( QWidget::PaletteBackground ); + } + else if ( !qstrcmp( widget->name(), kdeToolbarWidget) ) + { + widget->setBackgroundMode( PaletteBackground ); + widget->removeEventFilter(this); + } + + KStyle::unPolish( widget ); +} + +/* reimp. */ +void MandrivaStyle::renderMenuBlendPixmap( KPixmap& pix, const QColorGroup &cg, + const QPopupMenu* /* popup */ ) const +{ + QColor col = cg.background(); + //FIXME !!!!!!!!!!!!!!! +#ifdef Q_WS_X11 // Only draw menu gradients on TrueColor, X11 visuals + if ( QPaintDevice::x11AppDepth() >= 24 ) + KPixmapEffect::gradient( pix, col.light(120), col.dark(115), + KPixmapEffect::HorizontalGradient ); + else +#endif + pix.fill( col ); +} + + +void MandrivaStyle::drawHandle( const MandrivaColorData *cdata, + QPainter *p, + const QRect &r, + const QColorGroup & /*cg*/, + SFlags flags, + const QStyleOption& /*opt*/, + bool /*drawBorder*/ /*for the future remove it*/, bool drawGradient) const +{ + int x,y,width,height; + r.rect(&x, &y, &width, &height); + int i = 0; + int delta=0; + //fix for handle toolbar, otherwise it's not center + if (!(flags & Style_Horizontal)) + { + + if ( drawGradient ) + renderGradient( p, QRect(x+2,y+2,width-4, height-4), + cdata->shades[2], cdata->shades[0],false); + if(width > 30) + { + delta = x + (width/2) - 11; + for(i = 0; i < 3; i++) + { + drawHandlePoint (cdata,p, (delta + 9*i), + y + QMAX((height-4)/2,0)); + } + } + else + { + drawHandlePoint (cdata, p, x + (width-4)/2 , + y + QMAX((height-4)/2,0)); + } + } + else + { + if( drawGradient ) + renderGradient(p, QRect(x+2,y+2,width-4, height-4), + cdata->shades[0],cdata->shades[2], true); + + if(height > 30) + { + delta = y + (height / 2) - 11; + for(i = 0; i < 3; i++) + { + drawHandlePoint (cdata, p, x + QMAX((width-4)/2,0), + delta+9*i); + } + } + else + { + drawHandlePoint (cdata,p, x + QMAX((width-4)/2,0), + y + (height-4) / 2); + } + } +} + +void MandrivaStyle::drawGroupBox(const MandrivaColorData *cdata, const QColorGroup & cg, QPainter *p, const QRect & r, bool /*active*/, bool sunken)const +{ + int x,y,w,h; + x=r.x(); y=r.y(); w=r.width(); h=r.height(); + int x2 = x+w-1; + int y2 = y+h-1; + p->setPen(cdata->shades[2]); + p->drawLine(x+1, y2, x2-1, y2); + p->drawLine(x2, y+1, x2, y2-1); + + + p->drawLine(x+1, y, x2-1, y); + p->drawLine(x, y+1, x, y2-1); + p->setPen( cg.background() ); + p->drawPoint( x, y ); + p->drawPoint( x, y2 ); + p->drawPoint( x2, y ); + p->drawPoint( x2, y2 ); + + p->setPen( sunken ?cg.base():cdata->shades[1] ); + p->drawLine( x+1, y+1, x2-1, y+1 ); + p->drawLine( x+1, y+2, x+1, y2-2 ); + + p->setPen( sunken ? cdata->shades[1] :cg.base() ); + p->drawLine( x+1, y2-1, x2-1, y2-1 ); + p->drawLine( x2-1, y+2, x2-1, y2-2 ); +} + +void MandrivaStyle::drawLineSeparator(const MandrivaColorData *cdata, + const QColorGroup & cg, QPainter *p, + const QRect & r, bool horizontal, + bool /*active*/, bool /*sunken*/, + bool skipOffset )const +{ + QRect line1, line2; + + p->fillRect(r, cg.background()); + if (horizontal) + { + int offset = 0; + + // remove 5 pixels from each side of the line + if (r.width() > 20 && skipOffset) + offset = 3; + + // draw the separator in the middle of the given rect + int middle = (r.top() + r.bottom()) / 2; + line1 = QRect(r.x() + offset, middle, r.width() - 2*offset, 1); + line2 = QRect(r.x() + offset, middle+1, r.width() - 2*offset, 1); + } + else + { + int offset = 0; + + // remove 5 pixels from each side of the line + if (r.height() > 20 && skipOffset) + offset = 3; + + // draw the separator in the middle of the given rect + int middle = (r.left() + r.right()) / 2; + line1 = QRect(middle, r.y() + offset, 1, r.height() - 2*offset); + line2 = QRect(middle+1, r.y() + offset, 1, r.height() - 2*offset); + } + + p->setPen(cdata->shades[2]); + p->drawLine(line1.left(), line1.top(), line1.right(), line1.bottom()); + + p->setPen( cg.base() ); + p->drawLine(line2.left(), line2.top(), line2.right(), line2.bottom()); +} + + +void MandrivaStyle::drawFrame( const MandrivaColorData *cdata, const QColorGroup & cg, QPainter *p, const QRect & r, bool active )const +{ + //use by checkbox,lineedit,spinbox,combobox + int x,y,w,h; + x=r.x(); y=r.y(); w=r.width(); h=r.height(); + int x2 = x+w-1; + int y2 = y+h-1; + + p->setPen(cdata->shades[4]); + p->drawLine(x+1, y2, x2-1, y2); + p->drawLine(x2, y+1, x2, y2-1); + + //Change color if it's active + if ( active ) + p->setPen( cdata->shades[5] ); + p->drawLine(x+1, y, x2-1, y); + p->drawLine(x, y+1, x, y2-1); + p->setPen( cg.background() ); + p->drawPoint( x, y ); + p->drawPoint( x, y2 ); + p->drawPoint( x2, y ); + p->drawPoint( x2, y2 ); +} +// This function draws primitive elements as well as their masks. +void MandrivaStyle::drawPrimitive( PrimitiveElement pe, + QPainter *p, + const QRect &r, + const QColorGroup &cg, + SFlags flags, + const QStyleOption& opt ) const +{ + int x, y, xw, yh; + x= r.x(); + y= r.y(); + xw = r.x()+r.width()-1; + yh = r.y()+r.height()-1; + bool down = flags & Style_Down; + bool on = flags & Style_On; + const MandrivaColorData *cdata = lookupData(cg); + bool sunken = flags & Style_Sunken; + + switch(pe) + { + case PE_PanelTabWidget: + { + p->save(); + p->setPen(cdata->shades[4]); + p->drawRect(r); + p->restore(); + break; + } + case PE_FocusRect: + { + p->save(); + p->setPen(cdata->shades[6]); + p->drawWinFocusRect( r ); + p->restore(); + break; + } + case PE_PanelMenuBar: // Menu + { + //FIXME + p->fillRect(r, cg.brush(QColorGroup::Background)); + + int x2 = r.x()+r.width()-1; + int y2 = r.y()+r.height()-1; + + p->setPen(cdata->shades[2]); + p->drawLine(x, y2, x2, y2); + + break; + } + + case PE_PanelDockWindow: // Toolbar + { + bool horiz = r.width() > r.height(); + + //Here, we just draw the border. + int x = r.x(); + int y = r.y(); + int x2 = r.x() + r.width() - 1; + int y2 = r.y() + r.height() - 1; + int lw = opt.isDefault() ? pixelMetric(PM_DefaultFrameWidth) + : opt.lineWidth(); + + //FIXME + if (lw) + { + //Gradient border colors. + //(Same as in gradients.cpp) + QColor gradTop = cg.base(); + QColor gradBot = cdata->shades[2]; + if (horiz) + { + //Top line + p->setPen(gradTop); + p->drawLine(x, y, x2, y); + + //Bottom line + p->setPen(gradBot); + p->drawLine(x, y2, x2, y2); + } + else + { + //Left line + p->setPen(gradTop); + p->drawLine(x, y, x, y2); + + //Right line + p->setPen(gradBot); + p->drawLine(x2, y, x2, y2); + } + } + break; + } + case PE_DockWindowSeparator: + { + bool horiz = flags & Style_Horizontal; + + drawLineSeparator( cdata, cg, p, r, !horiz, true, sunken ); + break; + } + + case PE_DockWindowResizeHandle: + case PE_Splitter: + { + QRect real(r); + real.addCoords( 1, 0,0 ,0); + QColor color = (hoverWidget == p->device())?cdata->shades[1]:cg.background(); + p->fillRect( r, color ); + p->setPen( cg.background() ); + p->drawPoint( r.x(), 0 ); + p->drawPoint( r.width()-1, 0 ); + p->drawPoint( r.x(), r.height()-1 ); + p->drawPoint( r.width()-1, r.height()-1 ); + + drawHandle( cdata, p,real,cg,flags,opt, false ); + break; + } + case PE_PanelLineEdit: + { + drawFrame( cdata, cg, p, r, true ); + break; + } + case PE_Panel: //QListBox and co + { + if(kickerMode) + break; + p->save(); + p->setPen(cdata->shades[4]); + p->drawRect(r); + p->restore(); + break; + } + case PE_StatusBarSection: + { + p->fillRect(r, cg.background()); + break; + } + case PE_PanelPopup: + case PE_WindowFrame: + { + int lw = /*opt.isDefault() ? pixelMetric(PM_DefaultFrameWidth) + : opt.lineWidth()*/1; + if (lw == 1 || lw == 2) + { + QPen oldPen = p->pen(); + int x,y,w,h; + r.rect(&x, &y, &w, &h); + int x2 = x+w-1; + int y2 = y+h-1; + p->setPen(sunken ? cg.light() : cdata->shades[2]); + p->drawLine(x, y2, x2, y2); + p->drawLine(x2, y, x2, y2); + p->setPen(sunken ? cdata->shades[2] : cg.light()); + p->drawLine(x, y, x2, y); + p->drawLine(x, y, x, y2); + p->setPen(sunken ? cg.midlight() : cdata->shades[2]); + p->drawLine(x+1, y2-1, x2-1, y2-1); + p->drawLine(x2-1, y+1, x2-1, y2-1); + p->setPen(sunken ? cdata->shades[2] : cg.midlight()); + p->drawLine(x+1, y+1, x2-1, y+1); + p->drawLine(x+1, y+1, x+1, y2-1); + if( lw == 2 ) + { + p->setPen(sunken ? cg.midlight() : cdata->shades[5]); + p->drawLine(x+2, y2-2, x2-2, y2-2); + p->drawLine(x2-1, y+2, x2-2, y2-2); + p->setPen(sunken ? cdata->shades[5] : cg.midlight()); + p->drawLine(x+2, y+2, x2-2, y+2); + p->drawLine(x+2, y+2, x+2, y2-2); + } + p->setPen(oldPen); + } + else + KStyle::drawPrimitive(pe, p, r, cg, flags, opt); + break; + } + case PE_GroupBoxFrame: + { + if ( opt.isDefault() || opt.lineWidth() <= 0 ) + break; + drawGroupBox( cdata, cg, p, r, true,sunken ); + break; + } +#if 0 + case PE_PanelGroupBox: + drawPrimitive( PE_GroupBoxFrame, p, r, cg, flags, opt ); + break; +#endif + case PE_Separator: + { + drawLineSeparator( cdata, cg, p, r, true, true, sunken ); + break; + } + case PE_HeaderArrow: + { + if ( flags & Style_Up ) + drawPrimitive( PE_ArrowUp, p, r, cg, Style_Enabled ); + else + drawPrimitive( PE_ArrowDown, p, r, cg, Style_Enabled ); + break; + } + case PE_HeaderSection: + { + bool horizontal = true; + bool isFirst = false; + if (p && p->device()->devType() == QInternal::Widget) { + QHeader* hdr = dynamic_cast(p->device()); + if (hdr) + { + horizontal = ( hdr->orientation() == Horizontal ); + isFirst = hdr->mapToIndex(hdr->sectionAt(r.x() ) ) == 0; + } + } + int x,y,w,h; + r.rect(&x, &y, &w, &h); + QPen oldPen = p->pen(); + + //TODO verify it + if (flags & Style_MouseOver) + renderGradient( p, QRect(x, y, w, h-1), + cdata->shades[0],cdata->shades[2], !horizontal ); + else if ( on ) + renderGradient(p, QRect(x, y, w, h-1), + cdata->shades[0],cdata->shades[2], !horizontal ); + else if ( down ) + renderGradient(p, QRect(x, y, w, h-1), + cdata->shades[2],cdata->shades[1], !horizontal ); + else + renderGradient( p, QRect(x, y, w, h-1), + cdata->shades[0],cdata->shades[2], !horizontal ); + + //don't draw separator for first eleemtn + if ( !isFirst ) + { + drawLineSeparator(cdata, cg, p, QRect(x,y,2,h), false, true, false, false); + } + p->setPen( oldPen ); + break; + } + case PE_ExclusiveIndicator: + { //radiobutton + bool enabled = flags & Style_Enabled; + p->setPen( cdata->shades[4] ); + p->setBrush( QBrush( enabled ? cg.base() : cdata->shades[0] ) ); + p->drawEllipse( r ); + bool specificBackground = excludeColor( cg.highlight(), enabled ); + + if (!(flags & Style_Off)) + { + if (flags & Style_On) //on + { + if ( specificBackground ) + p->setPen( enabled ? cdata->shades[6]:cdata->shades[3] ); + else + p->setPen( enabled ? cdata->blueMdkColor[2]:cdata->shades[3] ); + p->drawLine( x+5, y+3, xw-5, y+3 ); + p->drawLine( x+4, y+4, xw-4, y+4 ); + p->drawLine( x+3, y+5, xw-3, y+5 ); + + if ( specificBackground ) + p->setPen( enabled ? cdata->shades[6]:cdata->shades[5] ); + else + p->setPen( enabled ? cdata->blueMdkColor[4]:cdata->shades[5] ); + + + p->drawLine( x+3, y+6, xw-3, y+6 ); + p->drawLine( x+4, y+7, xw-4, y+7); + p->drawLine( x+5, y+8, xw-5, y+8 ); + } + } + break; + } + case PE_CheckListIndicator: + { + QCheckListItem *item = opt.checkListItem(); + if(!item) + return; + int x = r.x(), y = r.y(), w = r.width(), h = r.width(); + drawPrimitive(PE_Indicator, p, QRect(x-2, y-2 , w+3, h+3 ) , cg, flags ); + break; + } + //case PE_IndicatorMask: + case PE_Indicator: + { //checkbox + bool enabled = flags & Style_Enabled; + + //draw background use base color + QRect ar( x+1, y+1, x+11, y+10 ); + p->fillRect (ar, enabled ? cg.base() : cdata->shades[0]); + bool specificBackground = excludeColor( cg.highlight(), enabled ); + //TODO mouse over + if (!(flags & Style_Off)) + { + if (flags & Style_On) //on + { +#ifdef USE_CROSS + p->setPen( enabled ? cdata->blueMdkColor[2]:cdata->shades[3] ); + //TODO look at if we can use a qbitmap directly + p->drawLine( x+2, y+2, x+3, y+2 ); + p->drawLine( x+2, y+3, x+4, y+3 ); + p->drawLine( x+3, y+4, x+5, y+4 ); + p->drawLine( x+4, y+5, x+8, y+5 ); + p->drawLine( x+9, y+2, x+10, y+2 ); + p->drawLine( x+8, y+3, x+10, y+3 ); + p->drawLine( x+7, y+4, x+9, y+4 ); + p->setPen( enabled ? cdata->blueMdkColor[4] : cdata->shades[5]); + p->drawLine( x+4, y+6, x+8, y+6 ); + p->drawLine( x+3, y+7, x+5, y+7 ); + p->drawLine( x+2, y+8, x+4, y+8 ); + p->drawLine( x+2, y+9, x+3, y+9 ); + + p->drawLine( x+9, y+9, x+10, y+9 ); + p->drawLine( x+8, y+8, x+10, y+8 ); + p->drawLine( x+7, y+7, x+9, y+7 ); +#else + if (QApplication::reverseLayout() ) + { + if ( specificBackground ) + p->setPen( enabled ? cdata->shades[6]:cdata->shades[3] ); + else + p->setPen( enabled ? cdata->blueMdkColor[2]:cdata->shades[3] ); + + p->drawPoint( x+2,y+2 ); + p->drawLine( x+2,y+3,x+3,y+3 ); + p->drawLine( x+2,y+4,x+4,y+4 ); + p->drawLine( x+3,y+5,x+5,y+5 ); + p->drawLine( x+4,y+6,x+6,y+6 ); + p->drawPoint( x+10,y+5 ); + p->drawLine( x+9,y+6,x+10,y+6 ); + + if ( specificBackground ) + p->setPen( enabled ? Qt::black : cdata->shades[4]); + else + p->setPen( enabled ? cdata->blueMdkColor[4] : cdata->shades[4]); + p->drawLine( x+5,y+7,x+10,y+7 ); + p->drawLine( x+6,y+8,x+9,y+8 ); + p->drawLine( x+7,y+9,x+8,y+9 ); + + } + else + { + if ( specificBackground ) + p->setPen( enabled ? cdata->shades[6]:cdata->shades[3] ); + else + p->setPen( enabled ? cdata->blueMdkColor[2]:cdata->shades[3] ); + p->drawPoint( x+10,y+2 ); + p->drawLine( x+9,y+3,x+10,y+3 ); + p->drawLine( x+8,y+4,x+10,y+4 ); + p->drawLine( x+7,y+5,x+9,y+5 ); + p->drawLine( x+6,y+6,x+8,y+6 ); + p->drawPoint( x+2,y+5 ); + p->drawLine( x+2,y+6,x+3,y+6 ); + + if ( specificBackground ) + p->setPen( enabled ? Qt::black : cdata->shades[4]); + else + p->setPen( enabled ? cdata->blueMdkColor[4] : cdata->shades[4]); + + p->drawLine( x+2,y+7,x+7,y+7 ); + p->drawLine( x+3,y+8,x+6,y+8 ); + p->drawLine( x+4,y+9,x+5,y+9 ); + } +#endif + } + else //tristate + { + if ( specificBackground ) + p->setPen( enabled ? cdata->shades[6] : cdata->shades[3]); + else + p->setPen( enabled ? cdata->blueMdkColor[2] : cdata->shades[3]); + + p->drawLine( x+4, y+5, x+8, y+5 ); + p->drawLine( x+3, y+6, x+9, y+6 ); + if ( specificBackground ) + p->setPen( enabled ? Qt::black : cdata->shades[5]); + else + p->setPen( enabled ? cdata->blueMdkColor[4] : cdata->shades[5]); + p->drawLine( x+4, y+7, x+8, y+7 ); + } + } + drawFrame( cdata, cg, p, r,true ); + break; + } + case PE_SizeGrip: + { + int y = r.y(); + int x2 = r.width(); + int y2 = r.height(); + p->setPen( cdata->shades[2] ); + p->drawPoint( x2, y ); + p->drawPoint( x2-1, y+1 ); + p->drawLine( x2-2, y+2, x2-1, y+2 ); + p->drawLine( x2-3, y+3, x2-1, y+3 ); + p->drawLine( x2-4, y+4, x2-1, y+4 ); + p->drawLine( x2-5, y+5, x2-1, y+5 ); + p->drawLine( x2-6, y+6, x2-1, y+6 ); + p->drawLine( x2-7, y+7, x2-2, y+7 ); + p->drawLine( x2-8, y+8, x2-3, y+8 ); + p->drawLine( x2-9, y+9, x2-4, y+9 ); + p->drawLine( x2-10, y+10, x2-6, y+10 ); + p->drawLine( x2-11, y+11, x2-9, y+11 ); + + p->drawPoint( x2, y+12 ); + p->drawLine( x2-1, y+13,x2,y+13 ); + p->drawLine( x2-2, y+14,x2-1,y+14 ); + + //TODO draw last point + p->setPen( cdata->shades[3] ); + + p->drawLine( x2, y+1, x2, y2-3 ); + p->drawPoint( x2-1, y+7 ); + p->drawLine( x2-2, y+8, x2-1, y+8 ); + p->drawLine( x2-3, y+9, x2-1, y+9 ); + p->drawLine( x2-5, y+10, x2-1, y+10 ); + p->drawLine( x2-8, y+11, x2-1, y+11 ); + p->drawLine( x2-12, y+12, x2-1, y+12 ); + p->drawLine( x2-13, y+13, x2-2, y+13 ); + p->drawLine( x2-14, y+14, x2-3, y+14 ); + + p->setPen( cg.background() ); + p->drawPoint( x2, y2 ); + break; + } + case PE_SpinWidgetUp: + case PE_SpinWidgetDown: + { + p->save(); + QRect br; + QRect re( r ); + br.setRect( r.x() , r.y(), r.width()+1, r.height() ); + + bool down = flags & Style_Down; + bool on = flags & Style_On; + bool sunken = on || down; + //Verify + if ( on ) + renderGradient(p, br, + cdata->shades[0],cdata->shades[2], /*!horizontal*/ false); + else if ( down ) + renderGradient(p, br, + cdata->shades[2],cdata->shades[1], /*!horizontal*/ false); + else if( !sunken && (flags & Style_Enabled )) + renderGradient(p, br, + cdata->shades[2],cdata->shades[0], /*!horizontal*/false ); + + p->setPen( cdata->shades[5]); + p->drawLine( br.x()-1, br.y(), br.x()-1, br.x()+r.height() ); //TODO verify +1 ??? + if ( pe == PE_SpinWidgetUp ) + { + QRect tmp( re ); + tmp.addCoords( -1, -2, 1, 1 ); + p->drawRect( tmp ); + //p->drawLine(br.x()-1, br.y()+br.height(), br.x()+br.width()-1, br.y()+br.height() ); //TODO verify +1 ??? + p->setPen( cg.background() ); + //p->drawPoint( tmp.width()-1, tmp.y()+1 ) ; + } + else + { + QRect tmp( re ); + tmp.addCoords( -1, 0, 1, 1 ); + p->drawRect( tmp ); + + //p->drawLine(br.x()-1, br.y(), br.x()+br.width()-1, br.y() ); //TODO verify +1 ??? + p->setPen( cg.background() ); + //p->drawPoint( tmp.width()-5, tmp.height()-2 ) ; + } + int w = r.width(); + int sw = w-4; + if ( sw < 3 ) + break; + else if ( !(sw & 1) ) + sw--; + sw -= ( sw / 7 ) * 2; // Empty border + //TODO don't use same color for active/inactive + p->setPen( cg.buttonText() ); + p->setBrush( cg.buttonText() ); + QPointArray a; + if ( pe == PE_SpinWidgetDown ) + a.setPoints(QCOORDARRLEN(d_spinarrow), d_spinarrow); + else + { + //move one pixel up + re.addCoords( 0, 1,0,0); + a.setPoints(QCOORDARRLEN(u_spinarrow), u_spinarrow); + } + drawMandrivaArrow( a, p, re, cg, flags, opt ); + p->restore(); + break; + } + case PE_ScrollBarSlider: + { + bool horizontal = flags & Style_Horizontal; + + p->setPen( cdata->shades[5]); + if( scrollmin && scrollmax ) + { + QRect tmpRect(r); + if( !horizontal ) + tmpRect.addCoords(0,0,0,1); + else + tmpRect.addCoords(0,0,1,0); + + p->drawRect( tmpRect ); + } + else + p->drawRect( r ); + + p->setPen( cdata->shades[0]); + if ( horizontal ) + { + p->drawLine( r.x(), r.y()+1, r.x(), r.y()+r.height()-2 ); + p->drawLine( r.x()+r.width(), r.y() +1 , r.x()+r.width(), r.y()+r.height()-2 ); + } + else + { + p->drawLine( r.x()+1, r.y(), r.x()+r.width()-2, r.y() ); + p->drawLine( r.x()+1, r.y()+r.height()-1, r.x()+r.width()-2, r.y()+r.height()-1 ); + } + // if the mouse is over the slider, the first half of the gradient changes + bool mouseover = flags & Style_MouseOver; + + QRect tmpRect(r), firstHalf, secondHalf; + if (horizontal) + { + tmpRect.addCoords( 0, 1, 0, -1 ); + firstHalf = QRect(tmpRect.x(), tmpRect.y(), tmpRect.width(), tmpRect.height()/2); + secondHalf = QRect(tmpRect.x(), tmpRect.height()/2 + 1, + tmpRect.width(), tmpRect.height() - (tmpRect.height()/2)); + } + else + { + tmpRect.addCoords( 1, 0, -1, 0 ); + firstHalf = QRect(tmpRect.x(), tmpRect.y(), tmpRect.width()/2, tmpRect.height()); + secondHalf = QRect(tmpRect.width()/2 + 1, tmpRect.y(), + tmpRect.width() - (tmpRect.width()/2), tmpRect.height()); + } + + // first half of the gradient + // horizontal scrollbars need vertical gradients (that's the reason + // of the !horizontal as the last argument + renderGradient(p, firstHalf, mouseover ? cdata->blueMdkColor[0] : cdata->blueMdkColor[1], + cdata->blueMdkColor[3], !horizontal); + + // second half of the gradient + renderGradient(p, secondHalf, cdata->blueMdkColor[4], cdata->blueMdkColor[2], !horizontal); + + // draw the points if !scrollmin or !scrollmax + p->setPen( cg.background() ); + if (horizontal) + { + if ( !scrollmax ) + { + p->drawPoint( tmpRect.x()+ tmpRect.width()-1, tmpRect.y() ); + p->drawPoint( tmpRect.x()+tmpRect.width()-1, tmpRect.y()+tmpRect.height()-1 ); + } + if ( !scrollmin ) + { + p->drawPoint( tmpRect.x(), tmpRect.y() ); + p->drawPoint( tmpRect.x(), tmpRect.height() ); + } + } + else + { + if ( !scrollmax ) + { + p->drawPoint( tmpRect.x(), tmpRect.y()+tmpRect.height()-1 ); + p->drawPoint( tmpRect.width(), tmpRect.y()+tmpRect.height()-1 ); + } + if ( !scrollmin ) + { + p->drawPoint( tmpRect.x(), tmpRect.y() ); + p->drawPoint( tmpRect.width(), tmpRect.y() ); + } + } + + break; + } + case PE_ScrollBarAddPage: + case PE_ScrollBarSubPage: { + int x, y, w, h; + r.rect(&x, &y, &w, &h); + int x2 = x+w-1; + int y2 = y+h-1; + + p->setPen( cg.base()); + p->drawLine( x,y,x,y2 ); + p->drawLine( x2,y,x2,y2 ); + p->setPen( cdata->shades[5]); + + if (flags & Style_Horizontal) { + p->drawLine(x, y, x2, y); + p->drawLine(x, y2, x2, y2); + p->fillRect( QRect( x, y+1, w, h-2),cdata->shades[0] ); + } else { + p->drawLine(x, y, x, y2); + p->drawLine(x2, y, x2, y2); + p->fillRect( QRect( x+1, y, w-2, h),cdata->shades[0] ); + } + break; + } + + case PE_ScrollBarAddLine: + case PE_ScrollBarSubLine: + { + int x,y,w,h; + r.rect(&x, &y, &w, &h); + bool sunken = on || down; + bool mouseover = flags & Style_MouseOver; + bool horizontal = flags & Style_Horizontal; + + // draw the bounding rect + p->setPen( cdata->shades[5]); + p->drawRect( r ); + + // draw the gradient of the buttons + if (w > 4 && h > 4) + { + if (sunken) + renderGradient(p, QRect(x+1, y+1, w-2, h-2), + cdata->shades[2],cdata->shades[1], !horizontal); + else if ( flags & Style_Enabled ) + renderGradient(p, QRect(x+1, y+1, w-2, h-2), + cdata->shades[0], mouseover ? cdata->shades[1] : cdata->shades[2], !horizontal ); + } + + PrimitiveElement arrow; + // draw some points to get a kind of rounded corner + p->setPen( cg.background() ); + if (pe == PE_ScrollBarAddLine) + { + arrow = horizontal ? PE_ArrowRight : PE_ArrowDown; + if ( horizontal ) + { + p->drawPoint( r.x()+r.width()-1 ,r.y() ); + p->drawPoint( r.x()+r.width()-1 ,r.y()+r.height()-1 ); + } + else + { + p->drawPoint( r.x() ,r.y()+r.height()-1 ); + p->drawPoint( r.x()+r.width()-1 ,r.y()+r.height()-1 ); + } + } + else + { + arrow = horizontal ? PE_ArrowLeft : PE_ArrowUp; + if ( horizontal ) + { + p->drawPoint( r.x() ,r.y() ); + p->drawPoint( r.x() ,r.y()+r.height()-1 ); + } + else + { + p->drawPoint( r.x() ,r.y() ); + p->drawPoint( r.x()+r.width()-1 ,r.y() ); + } + } + + // draw the arrow + drawPrimitive( arrow, p, r, cg, flags ); + break; + } + + // BUTTONS + // ------------------------------------------------------------------- + case PE_ButtonDefault: //default button + case PE_ButtonCommand: // action button + case PE_ButtonDropDown: + case PE_ButtonTool: + { + drawButton(cdata,r,p,cg,flags); + break; + } + case PE_CheckMark: + { + if (menuBmp.isNull()) + { + menuBmp = QBitmap( 12 , 12, menu_check_bits, true); + menuBmp.setMask(menuBmp); + } + int x,y; + x=r.x(); y=r.y(); + + if (!(flags & Style_Off)) + { + p->setPen( on ? cdata->blueMdkColor[2] : cg.highlightedText () ); + p->drawPixmap(x+3, y+3, menuBmp); + } + + break; + } + + //FIXME !!!!!!!!!!!!!!!!!!!! scrollbar + case PE_ButtonBevel: + { + int x,y,w,h; + r.rect(&x, &y, &w, &h); + bool sunken = on || down; + int x2 = x+w-1; + int y2 = y+h-1; + + // Outer frame + p->setPen(cg.shadow()); + p->drawRect(r); + + // Bevel + p->setPen(sunken ? cg.mid() : cg.light()); + p->drawLine(x+1, y+1, x2-1, y+1); + p->drawLine(x+1, y+1, x+1, y2-1); + p->setPen(sunken ? cg.light() : cg.mid()); + p->drawLine(x+2, y2-1, x2-1, y2-1); + p->drawLine(x2-1, y+2, x2-1, y2-1); + if (w > 4 && h > 4) { + if (sunken) + p->fillRect(x+2, y+2, w-4, h-4, cg.button()); + /*else + renderGradient( p, QRect(x+2, y+2, w-4, h-4), + cg.button(), flags & Style_Horizontal );*/ + } + break; + } + + default: + { + if (pe >= PE_ArrowUp && pe <= PE_ArrowLeft) + { + QPointArray a; + //array point define into bitmap.h + switch(pe) { + case PE_ArrowUp: + a.setPoints(QCOORDARRLEN(u_arrow), u_arrow); + break; + + case PE_ArrowDown: + a.setPoints(QCOORDARRLEN(d_arrow), d_arrow); + break; + + case PE_ArrowLeft: + a.setPoints(QCOORDARRLEN(l_arrow), l_arrow); + break; + + default: + a.setPoints(QCOORDARRLEN(r_arrow), r_arrow); + } + drawMandrivaArrow( a, p, r, cg, flags, opt ); + } + else + KStyle::drawPrimitive( pe, p, r, cg, flags, opt ); + } + } //switch +} + +void MandrivaStyle::drawMandrivaArrow( QPointArray a, QPainter *p, + const QRect &r, + const QColorGroup &cg, + SFlags flags, + const QStyleOption& /*opt*/ ) const +{ + QPen oldPen = p->pen(); + a.translate( r.x() + r.width() / 2, r.y() + r.height() / 2 ); + p->setPen(flags & Style_Enabled ? cg.buttonText() : cg.mid() ); + p->drawLineSegments( a ); + p->setPen( oldPen ); // restore pen +} + +void MandrivaStyle::drawKStylePrimitive( KStylePrimitive pe, + QPainter* p, + const QWidget* widget, + const QRect &r, + const QColorGroup &cg, + SFlags flags, + const QStyleOption &opt ) const +{ + const MandrivaColorData *cdata = lookupData(cg); + switch(pe) + { + // GENERAL/KICKER HANDLE + // ------------------------------------------------------------------- + case KPE_GeneralHandle: + { + drawHandle( cdata, p,r,cg,flags,opt,false ); + break; + } + + // TOOLBAR HANDLE + // ------------------------------------------------------------------- + case KPE_ToolBarHandle: + { + QRect real(r); + real.addCoords( -1, 0,0,0); + drawHandle( cdata, p,r,cg,flags,opt,true ); + break; + } + // SLIDER GROOVE + // ------------------------------------------------------------------- + case KPE_SliderGroove: + { + const QSlider* sl = static_cast< const QSlider* >( widget ); + bool horizontal = sl->orientation() == Horizontal; + //TODO fixme + p->fillRect( QRect( r.x()+1, r.y()+1, r.width()-2, r.height()-2 ),cdata->shades[0] ); + p->setPen( cdata->shades[1] ); + + int pos = sl->sliderStart(); + + if ( horizontal ) + { + //bidi + if (QApplication::reverseLayout() ) + p->fillRect( QRect( pos, 1, r.right(), r.height()-2 ),cdata->shades[3] ); + else + p->fillRect( QRect( 1, 1, pos, r.height()-2 ),cdata->shades[3] ); + for ( int i = 12; i < r.width() ; ) + { + p->drawLine( i, r.y()+1, i, r.height()-2 ); + i+=12; + } + } + else + { + p->fillRect( QRect( 1, pos, r.width()-2, r.height() ),cdata->shades[3] ); + for ( int i = 12; i < r.height() ; ) + { + p->drawLine( r.x(), i, r.width(), i ); + i+=12; + } + } + drawFrame( cdata, cg, p, r,true /*flags ? */); + break; + } + + // SLIDER HANDLE + // ------------------------------------------------------------------- + case KPE_SliderHandle: + { + const QSlider* sl = static_cast< const QSlider* >( widget ); + bool horizontal = sl->orientation() == Horizontal; + bool mouseOver = (widget == hoverWidget); + int x = r.x(); + int y = r.y(); + int x2 = r.right(); + int y2 = y+r.height(); + p->setPen( mouseOver ? cdata->blueMdkColor[1] : cdata->blueMdkColor[2]); + if ( horizontal ) + { + p->drawLine( x+1, y, x2-1, y ); + p->drawLine( x, y+1, x2, y+1 ); + p->drawLine( x, y+2, x2, y+2 ); + + p->setPen( mouseOver ? cdata->blueMdkColor[2] : cdata->blueMdkColor[4]); + p->drawLine( x, y+4, x2, y+4 ); + p->drawLine( x, y+3, x2, y+3 ); + p->drawLine( x+1, y+5, x2-1, y+5 ); + + //draw cross + int newposx = x+r.width()/2; + + p->drawLine( newposx-1, y+1, newposx+1,y+1 ); + p->drawLine( newposx-2, y+2, newposx+2,y+2 ); + + p->setPen( mouseOver ? cdata->blueMdkColor[1] : cdata->blueMdkColor[2]); + p->drawLine( newposx-2, y+3, newposx+2,y+3 ); + p->drawLine( newposx-1, y+4, newposx+1,y+4 ); + } + else //test into kmix + { + p->drawLine( x, y+1, x, y2-1 ); + p->drawLine( x+1, y, x+1, y2 ); + p->drawLine( x+2, y, x+2, y2 ); + + + p->setPen( mouseOver ? cdata->blueMdkColor[2] : cdata->blueMdkColor[4]); + p->drawLine( x+3, y, x+3, y2 ); + p->drawLine( x+4, y, x+4, y2 ); + p->drawLine( x+5, y+1, x+5, y2-1 ); + + + //draw cross + int newposy = y+r.height()/2; + + p->drawLine( x+1, newposy-1, x+1, newposy+1); + p->drawLine( x+2, newposy-2, x+2, newposy+2); + + p->setPen( mouseOver ? cdata->blueMdkColor[1] : cdata->blueMdkColor[2]); + p->drawLine( x+3, newposy-2, x+3, newposy+2); + p->drawLine( x+4, newposy-1, x+4, newposy+1); + + } + break; + } + // copied and slightly modified from KStyle. + case KPE_ListViewBranch: + { + // Typical Windows style listview branch element (dotted line). + + // Create the dotline pixmaps if not already created + if ( !verticalLine ) + { + // make 128*1 and 1*128 bitmaps that can be used for + // drawing the right sort of lines. + verticalLine = new QBitmap( 1, 129, true ); + horizontalLine = new QBitmap( 128, 1, true ); + QPointArray a( 64 ); + QPainter p2; + p2.begin( verticalLine ); + + int i; + for( i=0; i < 64; i++ ) + a.setPoint( i, 0, i*2+1 ); + p2.setPen( cdata->shades[4] ); + p2.drawPoints( a ); + p2.end(); + QApplication::flushX(); + verticalLine->setMask( *verticalLine ); + + p2.begin( horizontalLine ); + for( i=0; i < 64; i++ ) + a.setPoint( i, i*2+1, 0 ); + p2.setPen( cdata->shades[4] ); + p2.drawPoints( a ); + p2.end(); + QApplication::flushX(); + horizontalLine->setMask( *horizontalLine ); + } + + p->setPen( cg.mid() ); + + if (flags & Style_Horizontal) + { + int point = r.x(); + int other = r.y(); + int end = r.x()+r.width(); + int thickness = r.height(); + + while( point < end ) + { + int i = 128; + if ( i+point > end ) + i = end-point; + p->drawPixmap( point, other, *horizontalLine, 0, 0, i, thickness ); + point += i; + } + + } + else + { + int point = r.y(); + int other = r.x(); + int end = r.y()+r.height(); + int thickness = r.width(); + int pixmapoffset = (flags & Style_NoChange) ? 0 : 1; // ### Hackish + + while( point < end ) + { + int i = 128; + if ( i+point > end ) + i = end-point; + p->drawPixmap( other, point, *verticalLine, 0, pixmapoffset, thickness, i ); + point += i; + } + } + + break; + } + default: + KStyle::drawKStylePrimitive( pe, p, widget, r, cg, flags, opt); + } +} + +void MandrivaStyle::drawControl( ControlElement element, + QPainter *p, + const QWidget *widget, + const QRect &r, + const QColorGroup &cg, + SFlags flags, + const QStyleOption& opt ) const +{ + const MandrivaColorData *cdata = lookupData(cg); + switch (element) + { + case CE_CheckBox: + { + drawPrimitive (PE_Indicator, p, r, cg, flags); + break; + } + //progressbar + case CE_ProgressBarContents: + { + const QProgressBar* pb = (const QProgressBar*)widget; + QRect backend = subRect(SR_ProgressBarContents, widget); + double progress = pb->progress(); + bool reverse = QApplication::reverseLayout(); + int steps = pb->totalSteps(); + + if (!pb || !backend.isValid()) + return; + //necessary to fill all background + //TODO fix it + p->fillRect(backend , cg.background() ); + + //draw border + drawPrimitive( PE_PanelLineEdit, p, r, cg ); + + QRect cr(backend); + cr.addCoords( 1, 1, -2, -2 ); + + // Draw progress bar gradient + if (progress > 0 || steps == 0) + { + double pg = (steps == 0) ? 0.1 : progress / steps; + int width = QMIN(cr.width(), (int)(pg * cr.width())); + if (steps == 0) + width = QMIN(width,20); //Don't cross squares + + if (steps == 0) + { //Busy indicator + + if (width < 1) width = 1; //A busy indicator with width 0 is kind of useless + + int remWidth = cr.width() - width; //Never disappear completely + if (remWidth <= 0) remWidth = 1; //Do something non-crashy when too small... + + int pstep = int(progress) % ( 2 * remWidth ); + + if ( pstep > remWidth ) + { + //Bounce about.. We're remWidth + some delta, we want to be remWidth - delta... + // - ( (remWidth + some delta) - 2* remWidth ) = - (some deleta - remWidth) = remWidth - some delta.. + pstep = - (pstep - 2 * remWidth ); + } + if( reverse ) + renderGradient(p, QRect(cr.x() + cr.width() - width - pstep, cr.y(), width, cr.height()), + cdata->shades[2],cdata->shades[1], false); + else + renderGradient(p, cr, + cdata->shades[2],cdata->shades[1], false); + p->setPen(cdata->shades[5]); + p->drawLine( backend.x(), backend.y(), backend.width()+1, backend.y()); + p->drawLine( backend.x(), backend.y(), backend.x(), backend.height()); + return; + + } + if( reverse ) + { + //convert it as after + //TODO Verify it + QPixmap gradient(1, cr.height()+1); + QPainter painter(&gradient); + KPixmap tempPixmap; + tempPixmap.resize(1, cr.height()/2+1); + KPixmapEffect::gradient(tempPixmap, + cdata->blueMdkColor[1], + cdata->blueMdkColor[3], + KPixmapEffect::VerticalGradient); + painter.drawPixmap(0,0, tempPixmap); + tempPixmap.resize(1, cr.height()+1); + KPixmapEffect::gradient(tempPixmap, + cdata->blueMdkColor[4], + cdata->blueMdkColor[2], + KPixmapEffect::VerticalGradient); + painter.drawPixmap(0, cr.height()/2 +1, tempPixmap); + painter.end(); + QRect tmp( cr.width()-width+1, cr.y(),width+1,cr.height() ); + tmp.addCoords( 0, 0, 0, 1 ); + p->drawTiledPixmap( tmp , gradient ); + bool changed = false; + p->setPen( cdata->shades[1]); + for ( int i = 12; i < cr.width() ; ) + { + if ( !changed && ( i >cr.width() -width ) ) + { + p->setPen( cdata->blueMdkColor[2] ); + changed = true; + } + p->drawLine( i, r.y()+1, i, r.height()-2 ); + i+=12; + } + p->setPen(cg.background() ); + p->drawPoint( cr.width() -width +1, r.y()+1 ); + p->drawPoint( cr.width() -width + 1, r.height()-2 ); + + } + else + { + QPixmap gradient(1, cr.height()+1); + QPainter painter(&gradient); + KPixmap tempPixmap; + tempPixmap.resize(1, cr.height()/2+1); + KPixmapEffect::gradient(tempPixmap, + cdata->blueMdkColor[1], + cdata->blueMdkColor[3], + KPixmapEffect::VerticalGradient); + painter.drawPixmap(0,0, tempPixmap); + tempPixmap.resize(1, cr.height()+1); + KPixmapEffect::gradient(tempPixmap, + cdata->blueMdkColor[4], + cdata->blueMdkColor[2], + KPixmapEffect::VerticalGradient); + painter.drawPixmap(0, cr.height()/2 +1, tempPixmap); + painter.end(); + QRect tmp( cr.x(), cr.y(),width-1,cr.height() ); + tmp.addCoords( 0, 0, 0, 1 ); + p->drawTiledPixmap( tmp , gradient ); + bool changed = false; + p->setPen( cdata->blueMdkColor[2] ); + for ( int i = 12; i < cr.width() ; ) + { + if ( !changed && ( i >width ) ) + { + p->setPen( cdata->shades[1] ); + changed = true; + } + p->drawLine( i, r.y()+1, i, r.height()-2 ); + i+=12; + } + p->setPen(cg.background() ); + p->drawPoint( width-1, r.y()+1 ); + p->drawPoint( width-1, r.height()-2 ); + } + } + break; + } + case CE_ProgressBarLabel: + { + const QProgressBar * pb = (const QProgressBar *) widget; + const int unit_width = pixelMetric( PM_ProgressBarChunkWidth, pb ); + int u = r.width() / unit_width; + int p_v = pb->progress(); + int t_s = pb->totalSteps(); + if ( u > 0 && pb->progress() >= INT_MAX / u && t_s >= u ) + { + // scale down to something usable. + p_v /= u; + t_s /= u; + } + // QColor("#4965AE" ) powerpack + if ( pb->percentageVisible() && pb->totalSteps() ) + { + int nu = ( u * p_v + t_s/2 ) / t_s; + int x = unit_width * nu; + if (pb->indicatorFollowsStyle() || pb->centerIndicator()) + { + if(cg.highlight() == QColor("#4965AE" )) + p->setPen( QColor("#FFFFFF")); + else + p->setPen( QColor( "#000000" ) ); + + p->setClipRect( r.x(), r.y(), x, r.height() ); + p->drawText( r, AlignCenter | SingleLine, pb->progressString() ); + + if ( pb->progress() != pb->totalSteps() ) + { + p->setClipRect( r.x() + x, r.y(), r.width() - x, r.height() ); + //second part of progress bar => black + p->setPen( /*cg.highlight()*/QColor( "#000000" ) ); + p->drawText( r, AlignCenter | SingleLine, pb->progressString() ); + } + } + else + { + if(cg.highlight() == QColor("#4965AE" )) + p->setPen( QColor("#FFFFFF")); + else + p->setPen( QColor( "#000000" ) ); + p->drawText( r, AlignCenter | SingleLine, pb->progressString() ); + } + } + break; + } + case CE_ToolButtonLabel: + { + KStyle::drawControl(element, p, widget, r, cg, flags, opt); + break; + } + + case CE_MenuBarEmptyArea: + case CE_DockWindowEmptyArea: + { + p->fillRect(r, cg.background() ); + break; + } + case CE_TabBarTab: + { + const QTabBar* tb = static_cast< const QTabBar* >( widget ); + int x, y, xw, yh; + int offset= 0; + x= r.x(); + y= r.y(); + //verify it + xw = r.x()+r.width()-1; + yh = r.y()+r.height()-1; + + //necessary to define type of tab + TabPosition pos; + if (tb->count() == 1) + pos = Single; + else if ((tb->indexOf(opt.tab()->identifier()) == 0)) + pos = First; + else if (tb->indexOf(opt.tab()->identifier()) == tb->count() - 1) + pos = Last; + else + pos = Middle; + + bool bottom = tb->shape() == QTabBar::RoundedBelow || + tb->shape() == QTabBar::TriangularBelow; + + if ( !bottom ) + { + if (flags & Style_Selected ) + { + p->fillRect( r, tb->palette().active().brush( QColorGroup::Background )); + //blue-2 + p->setPen( cdata->blueMdkColor[2]); + p->drawLine( x+2, y, xw-2, y ); + p->drawLine( x+1, y+1, xw-1, y+1 ); + //blue-4 + p->setPen( cdata->blueMdkColor[4] ); + p->drawLine( x, y+2, xw, y+2 ); + p->drawLine( x, y+3, xw, y+3 ); + p->setPen( cdata->shades[4] ); + p->drawLine( xw,y+4,xw,yh); + if ( pos==First ) + p->drawLine( x,y+4,x,yh); + else if ( ( pos==Last || pos == Single ) && QApplication::reverseLayout() ) + p->drawLine( xw, y+4, xw, yh ); + } + else + { + offset = 3; + //grey1 + p->fillRect( QRect(x,y+offset,r.width()-1,yh), cdata->shades[1]); + //grey5 + p->setPen( cdata->shades[5]); + p->drawLine( x+2,y+offset-1,xw-2,y+offset-1); + p->drawPoint(x+1, y+offset ); + p->drawPoint(xw-1, y+offset ); + p->drawLine( xw, y+offset+1, xw, yh ); + p->drawLine( x, y+offset+1, x, yh ); + p->setPen( cdata->shades[4]); + p->drawLine( x, yh, xw,yh); + } + } + else + { + if (flags & Style_Selected ) + { + p->fillRect( r, tb->palette().active().brush( QColorGroup::Background )); + + p->setPen( cdata->blueMdkColor[2] ); + p->drawLine( x, yh-3, xw, yh-3 ); + p->drawLine( x, yh-2, xw, yh-2 ); + + p->setPen( cdata->blueMdkColor[4] ); + p->drawLine( x+1, yh-1, xw-1, yh-1 ); + p->drawLine( x+2, yh, xw-2, yh ); + p->setPen( cdata->shades[4] ); + p->drawLine( xw,y,xw,yh-4); + if ( pos==First ) + p->drawLine( x,y,x,yh-4); + else if ( ( pos==Last || pos == Single ) && QApplication::reverseLayout() ) + p->drawLine( x, y, x, yh-4 ); //CHECK + } + else + { + offset = 3; + //grey1 + p->fillRect( QRect(x,y,r.width()-1,yh-offset), cdata->shades[1]); + //grey5 + p->setPen( cdata->shades[5]); + + p->drawLine( x+2,yh-offset+1,xw-2,yh-offset+1); + p->drawPoint(x+1, yh-offset ); + p->drawPoint(xw-1, yh-offset ); + p->drawLine( xw, y, xw, yh-4 ); + p->drawLine( x, y, x, yh-4 ); + p->setPen( cdata->shades[4]); + p->drawLine( x, y, xw,y); + } + } + break; + } + //CHECK + case CE_MenuBarItem: + { + QMenuBar *mb = (QMenuBar*)widget; + QMenuItem *mi = opt.menuItem(); + QRect pr = mb->rect(); + + bool active = flags & Style_Active; + bool focused = flags & Style_HasFocus; + bool down = flags & Style_Down; + + QColor textColor = cg.text(); + if ( active && focused && down ) + { + //top half + QRect half_rect = r; + half_rect.setHeight(r.height()/2); + renderGradient(p, half_rect, cdata->blueMdkColor[1], cdata->blueMdkColor[3], false); + //bottom half + half_rect.setHeight(r.height() - half_rect.height()); + half_rect.moveBottom(r.bottom()); + renderGradient(p, half_rect, cdata->blueMdkColor[4], cdata->blueMdkColor[2], false); + textColor = cg.highlightedText(); + // create the fake rounded corners + QPen oldPen = p->pen(); + p->setPen(cg.background()); + p->drawPoint(r.topLeft()); + p->drawPoint(r.topRight()); + p->drawPoint(r.bottomLeft()); + p->drawPoint(r.bottomRight()); + p->setPen(oldPen); + } + else + renderGradient(p, r, cg.background(), cg.background(),false); + + drawItem( p, r, AlignCenter | AlignVCenter | ShowPrefix + | DontClip | SingleLine, cg, flags & Style_Enabled, + mi->pixmap(), mi->text(), -1, &textColor ); + + break; + } + + +// POPUPMENU ITEM +// ------------------------------------------------------------------- + case CE_PopupMenuItem: + { + const QPopupMenu *popupmenu = (const QPopupMenu *) widget; + + QMenuItem *mi = opt.menuItem(); + if ( !mi ) + { + // Don't leave blank holes if we set NoBackground for the QPopupMenu. + // This only happens when the popupMenu spans more than one column. + if (! (widget->erasePixmap() && !widget->erasePixmap()->isNull()) ) + p->fillRect(r, cg.brush(QColorGroup::Background) ); + break; + } + + int tab = opt.tabWidth(); + int checkcol = opt.maxIconWidth(); + bool enabled = mi->isEnabled(); + bool checkable = popupmenu->isCheckable(); + bool active = flags & Style_Active; + bool etchtext = styleHint( SH_EtchDisabledText ); + bool reverse = QApplication::reverseLayout(); + int x, y, w, h; + r.rect( &x, &y, &w, &h ); + + if ( checkable ) + checkcol = QMAX( checkcol, 20 ); + + // Are we a menu item separator? + if ( mi->isSeparator() ) + { + drawLineSeparator( cdata, cg, p, r, true, active, false ); + break; + } + // Draw the menu item background + if( active && (flags & Style_Enabled)) + { + //top half + QRect half_rect = r; + half_rect.setHeight(r.height()/2); + renderGradient(p, half_rect, cdata->blueMdkColor[1], cdata->blueMdkColor[3], false); + //bottom half + half_rect.setHeight(r.height() - half_rect.height()); + half_rect.moveBottom(r.bottom()); + renderGradient(p, half_rect, cdata->blueMdkColor[4], cdata->blueMdkColor[2], false); + // create the fake rounded corners + QPen oldPen = p->pen(); + p->setPen(cg.background()); + p->drawPoint(r.topLeft()); + p->drawPoint(r.topRight()); + p->drawPoint(r.bottomLeft()); + p->drawPoint(r.bottomRight()); + p->setPen(oldPen); + } + + // Draw the transparency pixmap + else if ( widget->erasePixmap() && !widget->erasePixmap()->isNull() ) + p->drawPixmap( x, y, *widget->erasePixmap(), x, y, w, h ); + // Draw a solid background + else + p->fillRect( r, cg.background() ); + + + // Do we have an icon? +#if 0 + if ( ( (widget && !qstrcmp(widget->name(),"KMenu" )) || + (widget->parentWidget() && !qstrcmp(widget->parentWidget()->name(),"KMenu" )) ) + && +#endif + if( mi->iconSet() ) + { + QIconSet::Mode mode; + QRect cr = visualRect( QRect(x, y, checkcol, h), r ); + + // Select the correct icon from the iconset + if ( active ) + mode = enabled ? QIconSet::Active : QIconSet::Disabled; + else + mode = enabled ? QIconSet::Normal : QIconSet::Disabled; +#if 0 //don't check menu + // Do we have an icon and are checked at the same time? + // Then draw a "pressed" background behind the icon + if ( checkable && !active && mi->isChecked() ) + { + qDrawShadePanel( p, cr.x(), cr.y(), cr.width(), cr.height(), + cg, true, 1, &cg.brush(QColorGroup::Midlight) ); + } +#endif + //TEST IT !!!!!!!!!!!!!! + if ( checkable && mi->isChecked() ) + {//don't display icon when button is checkable + int cx = reverse ? x+w - checkcol : x; + // Draw the checkmark + SFlags cflags = Style_Default; + cflags |= active ? Style_Enabled : Style_On; + drawPrimitive( PE_CheckMark, p, QRect( cx + itemFrame, y + itemFrame, + checkcol - itemFrame*2, h - itemFrame*2), cg, cflags ); + } + else + { + // Draw the icon + QPixmap pixmap = mi->iconSet()->pixmap( QIconSet::Small, mode ); + QRect pmr( 0, 0, pixmap.width(), pixmap.height() ); + pmr.moveCenter( cr.center() ); + p->drawPixmap( pmr.topLeft(), pixmap ); + } + } + // Are we checked? (This time without an icon) + else if ( (checkable && mi->isChecked()) ) + { + int cx = reverse ? x+w - checkcol : x; +#if 0 //don't create a checked button + // We only have to draw the background if the menu item is inactive + // if it's active the "pressed" background is already drawn + if ( ! active ) + qDrawShadePanel( p, cx, y, checkcol, h, cg, true, 1, + &cg.brush(QColorGroup::Midlight) ); +#endif + // Draw the checkmark + SFlags cflags = Style_Default; + cflags |= active ? Style_Enabled : Style_On; + drawPrimitive( PE_CheckMark, p, QRect( cx + itemFrame, y + itemFrame, + checkcol - itemFrame*2, h - itemFrame*2), cg, cflags ); + } + + // Time to draw the menu item label... + int xm = itemFrame + checkcol + itemHMargin; // X position margin + + int xp = reverse ? // X position + x + tab + rightBorder + itemHMargin + itemFrame - 1 : + x + xm; + + int offset = reverse ? -1 : 1; // Shadow offset for etched text + + // Label width (minus the width of the accelerator portion) + int tw = w - xm - tab - arrowHMargin - itemHMargin * 3 - itemFrame + 1; + + // Set the color for enabled and disabled text + // (used for both active and inactive menu items) + p->setPen( enabled ? cg.buttonText() : cg.mid() ); + + // This color will be used instead of the above if the menu item + // is active and disabled at the same time. (etched text) + QColor discol = cg.mid(); + + // Does the menu item draw it's own label? + if ( mi->custom() ) + { + int m = itemVMargin; + // Save the painter state in case the custom + // paint method changes it in some way + QPen oldPen = p->pen(); + + + // Draw etched text if we're inactive and the menu item is disabled + if ( etchtext && !enabled && !active ) + { + p->setPen( cg.light() ); + mi->custom()->paint( p, cg, active, enabled, xp+offset, y+m+1, tw, h-2*m ); + p->setPen( discol ); + } + mi->custom()->paint( p, cg, active, enabled, xp, y+m, tw, h-2*m ); + p->setPen( oldPen ); // restore pen + + } + else + { + // The menu item doesn't draw it's own label + QString s = mi->text(); + + // Does the menu item have a text label? + if ( !s.isNull() ) + { + int t = s.find( '\t' ); + int m = itemVMargin; + int text_flags = AlignVCenter | ShowPrefix | DontClip | SingleLine; + text_flags |= reverse ? AlignRight : AlignLeft; + + //QColor draw = cg.text(); + QColor draw = (active && enabled) ? cg.highlightedText () : cg.text(); + p->setPen(draw); + + + // Does the menu item have a tabstop? (for the accelerator text) + if ( t >= 0 ) + { + int tabx = reverse ? x + rightBorder + itemHMargin + itemFrame : + x + w - tab - rightBorder - itemHMargin - itemFrame; + + // Draw the right part of the label (accelerator text) + if ( etchtext && !enabled && !active ) + { + // Draw etched text if we're inactive and the menu item is disabled + p->setPen( cg.light() ); + p->drawText( tabx+offset, y+m+1, tab, h-2*m, text_flags, s.mid( t+1 ) ); + p->setPen( discol ); + } + p->drawText( tabx, y+m, tab, h-2*m, text_flags, s.mid( t+1 ) ); + s = s.left( t ); + } + + // Draw the left part of the label (or the whole label + // if there's no accelerator) + if ( etchtext && !enabled && !active ) + { + // Etched text again for inactive disabled menu items... + p->setPen( cg.light() ); + p->drawText( xp+offset, y+m+1, tw, h-2*m, text_flags, s, t ); + p->setPen( discol ); + } + + p->drawText( xp, y+m, tw, h-2*m, text_flags, s, t ); + } + + // The menu item doesn't have a text label + // Check if it has a pixmap instead + else if ( mi->pixmap() ) + { + QPixmap *pixmap = mi->pixmap(); + + // Draw the pixmap + if ( pixmap->depth() == 1 ) + p->setBackgroundMode( OpaqueMode ); + + int diffw = ( ( w - pixmap->width() ) / 2 ) + + ( ( w - pixmap->width() ) % 2 ); + p->drawPixmap( x+diffw, y+itemFrame, *pixmap ); + + if ( pixmap->depth() == 1 ) + p->setBackgroundMode( TransparentMode ); + } + } + + // Does the menu item have a submenu? + if ( mi->popup() ) + { + PrimitiveElement arrow = reverse ? PE_ArrowLeft : PE_ArrowRight; + int dim = pixelMetric(PM_MenuButtonIndicator)- itemFrame; + QRect vr = visualRect( QRect( x + w - arrowHMargin - itemFrame - dim, + y + h / 2 - dim / 2, dim, dim), r ); + + // Draw an arrow at the far end of the menu item + if ( active ) + { + if ( enabled ) + discol = cg.buttonText(); + + QColorGroup g2( cg.highlightedText ()/*white*/, cg.highlight(), /*white*/cg.highlightedText (), /*white*/cg.highlightedText (), + enabled ? cg.highlightedText () : discol, /*discol*/cg.highlightedText (), cg.highlightedText () ); + + drawPrimitive( arrow, p, vr, g2, Style_Enabled ); + } + else + drawPrimitive( arrow, p, vr, cg, + enabled ? Style_Enabled : Style_Default ); + } + break; + } + case CE_PushButtonLabel: + { + const QPushButton* button = (const QPushButton*)widget; + bool active = button->isOn() || button->isDown(); + int x, y, w, h; + r.rect( &x, &y, &w, &h ); + + // Shift button contents if pushed. + if ( active ) + { + x += pixelMetric(PM_ButtonShiftHorizontal, widget); + y += pixelMetric(PM_ButtonShiftVertical, widget); + flags |= Style_Sunken; + } + + // Does the button have a popup menu? + if ( button->isMenuButton() ) + { + int dx = pixelMetric( PM_MenuButtonIndicator, widget ); + drawPrimitive( PE_ArrowDown, p, QRect(x + w - dx - 2, y + 2, dx, h - 4), + cg, flags, opt ); + w -= dx; + } + + // Draw the icon if there is one + if ( button->iconSet() && !button->iconSet()->isNull() ) + { + QIconSet::Mode mode = QIconSet::Disabled; + QIconSet::State state = QIconSet::Off; + + if (button->isEnabled()) + mode = button->hasFocus() ? QIconSet::Active : QIconSet::Normal; + if (button->isToggleButton() && button->isOn()) + state = QIconSet::On; + + QPixmap pixmap = button->iconSet()->pixmap( QIconSet::Small, mode, state ); + + // Center the iconset if there's no text or pixmap + if (button->text().isEmpty() && !button->pixmap()) + p->drawPixmap( x + (w - pixmap.width()) / 2, + y + (h - pixmap.height()) / 2, pixmap ); + else + p->drawPixmap( x + 4, y + (h - pixmap.height()) / 2, pixmap ); + + int pw = pixmap.width(); + x += pw + 4; + w -= pw + 4; + } + // Make the label indicate if the button is a default button or not + if ( active || button->isDefault() ) + { + // Draw "fake" bold text - this enables the font metrics to remain + // the same as computed in QPushButton::sizeHint(), but gives + // a reasonable bold effect. + //change color of text + drawItem( p, QRect(x, y, w, h), AlignCenter | ShowPrefix, + button->colorGroup(), + button->isEnabled(), + button->pixmap(), + button->text(), -1, + /*button->isDefault() ? &cdata->blueMdkColor[4] :*/ &button->colorGroup().buttonText() ); + +#if 0 + // Normal Text + for(i=0; i<2; i++) + drawItem( p, QRect(x+i, y, w, h), AlignCenter | ShowPrefix, + button->colorGroup(), + button->isEnabled(), + i == 0 ? button->pixmap() : NULL, + button->text(), -1, + &button->colorGroup().buttonText() ); +#endif + } + else + { + drawItem( p, QRect(x, y, w, h), AlignCenter | ShowPrefix, + button->colorGroup(), + button->isEnabled(), button->pixmap(), + button->text(), -1, + &button->colorGroup().buttonText() ); + } + // Draw a focus rect if the button has focus + if ( flags & Style_HasFocus ) + drawPrimitive( PE_FocusRect, p, + QStyle::visualRect(subRect(SR_PushButtonFocusRect, widget), widget), + cg, flags ); + break; + } + case CE_PushButton: + { + const QPushButton* btn = static_cast< const QPushButton* >( widget ); + if ( widget == hoverWidget ) + flags |= Style_MouseOver; + if (isFormWidget(btn)) + formMode = true; + + drawPrimitive( btn->isDefault( ) ? PE_ButtonDefault : PE_ButtonCommand, p, r, cg, flags ); + } + break; + default: + KStyle::drawControl(element, p, widget, r, cg, flags, opt); + } +} + +void MandrivaStyle::drawControlMask( ControlElement element, + QPainter *p, + const QWidget *widget, + const QRect &r, + const QStyleOption& opt ) const +{ + switch (element) + { + case CE_TabBarTab: + case CE_TabBarLabel: + { + p->fillRect(r,color1); + break; + } + default: + KStyle::drawControlMask(element, p, widget, r, opt); + } +} + +void MandrivaStyle::drawComboboxArrow( QPainter *p, + const QWidget *widget, + const QRect &ar, + const QColorGroup &cg, + SFlags flags, + SCFlags active)const +{ + const QComboBox * cb = (const QComboBox *) widget; + bool editableCombo = cb->editable(); + // Are we enabled? + if ( widget->isEnabled() ) + flags |= Style_Enabled; + + // Are we "pushed" ? + if ( active & Style_Sunken ) + flags |= Style_Sunken; + p->setPen( cg.text() ); + //Don't apply background color otherwise it + //destroys gradient. + //p->setBackgroundColor( cg.button() ); + QPointArray a; + if ( editableCombo ) + a.setPoints(QCOORDARRLEN(c_edit_arrow), c_edit_arrow); + else + a.setPoints(QCOORDARRLEN(c_arrow), c_arrow); + + if ( flags & Style_Down ) + p->translate( pixelMetric( PM_ButtonShiftHorizontal ), + pixelMetric( PM_ButtonShiftVertical ) ); + + if ( flags & Style_Enabled ) + { + if ( QApplication::reverseLayout() ) + { + a.translate( editableCombo ? ar.x() + ar.width() / 2 +1 : ar.x() + ar.width() / 2 +4 , + editableCombo ? ar.y() + ar.height() / 2 + 1 : ar.y() + ar.height() / 2 ); + } + else + { + a.translate( editableCombo ? ar.x() + ar.width() / 2 +1 : ar.x() + ar.width() / 2 -3, + editableCombo ? ar.y() + ar.height() / 2 + 1 : ar.y() + ar.height() / 2 ); + } + p->setPen( cg.buttonText() ); + p->drawLineSegments( a ); + } + else + { + if ( QApplication::reverseLayout() ) + { + a.translate( editableCombo ? ar.x() + ar.width() / 2 + 1 : ar.x() + ar.width() / 2 +4, + editableCombo ? ar.y() + ar.height() / 2 + 1: ar.y() + ar.height() / 2 ); + } + else + { + a.translate( editableCombo ? ar.x() + ar.width() / 2 + 1 : ar.x() + ar.width() / 2 -3, + editableCombo ? ar.y() + ar.height() / 2 + 1: ar.y() + ar.height() / 2 ); + } + p->setPen( cg.light() ); + p->drawLineSegments( a ); + a.translate( -1, -1 ); + p->setPen( cg.mid() ); + p->drawLineSegments( a ); + } +} + +void MandrivaStyle::drawComplexControl( ComplexControl control, + QPainter *p, + const QWidget *widget, + const QRect &r, + const QColorGroup &cg, + SFlags flags, + SCFlags controls, + SCFlags active, + const QStyleOption& opt ) const +{ + const MandrivaColorData *cdata = lookupData(cg); + switch(control) + { + case CC_SpinWidget: + { + const QSpinWidget* sw = static_cast< const QSpinWidget* >( widget ); + QRect br = visualRect( querySubControlMetrics( CC_SpinWidget, widget, SC_SpinWidgetButtonField ), widget ); + //FIXME + p->fillRect( r, widget->isEnabled() ? cg.base() : cg.background() ); + + if ( controls & SC_SpinWidgetButtonField ) + { + if ( controls & SC_SpinWidgetUp) + { + QColorGroup ucg = sw->isUpEnabled() ? cg : sw->palette().disabled(); + drawPrimitive( PE_SpinWidgetUp,p, QRect(br.x()+1 , br.y()+1 , br.width()-2 , br.height() / 2 ), ucg, flags, opt); + } + if ( controls & SC_SpinWidgetDown) + { + QColorGroup dcg = sw->isDownEnabled() ? cg : sw->palette().disabled(); + + drawPrimitive( PE_SpinWidgetDown,p, QRect( br.x()+1 , br.y() + br.height() / 2 , br.width()-2, br.height()/ 2 -1 ), dcg, flags, opt); + } + } + if ( controls & SC_SpinWidgetFrame ) + drawPrimitive( PE_PanelLineEdit, p, r, cg ); + + break; + } + case CC_ToolButton: + { + const QToolButton *tb = (const QToolButton *) widget; + + QRect button, menuarea; + button = querySubControlMetrics(control, widget, SC_ToolButton, opt); + menuarea = querySubControlMetrics(control, widget, SC_ToolButtonMenu, opt); + + SFlags bflags = flags, + mflags = flags; + + // don't want to have the buttoncolor as the background... + p->fillRect(r, cg.background()); + bflags &= ~Style_MouseOver; + + if (active & SC_ToolButton) + bflags |= Style_Down; + + if (active & SC_ToolButtonMenu) + mflags |= Style_Down; + + if (controls & SC_ToolButton) + { + // If we're pressed, on, or raised... + if (bflags & (Style_Down | Style_On | Style_Raised) || widget==hoverWidget ) + { + drawPrimitive(PE_ButtonTool, p, button, cg, bflags, opt); + } + else if (tb->parentWidget() && + tb->parentWidget()->backgroundPixmap() && + !tb->parentWidget()->backgroundPixmap()->isNull()) + { + QPixmap pixmap = *(tb->parentWidget()->backgroundPixmap()); + p->drawTiledPixmap( r, pixmap, tb->pos() ); + } + } + + // Draw a toolbutton menu indicator if required + if (controls & SC_ToolButtonMenu) + { + if (mflags & (Style_Down | Style_On | Style_Raised)) + drawPrimitive(PE_ButtonDropDown, p, menuarea, cg, mflags, opt); + + drawPrimitive(PE_ArrowDown, p, menuarea, cg, mflags, opt); + } + + if (tb->hasFocus() && !tb->focusProxy()) + { + QRect fr = tb->rect(); + fr.addCoords(2, 2, -2, -2); + drawPrimitive(PE_FocusRect, p, fr, cg); + } + + // Set the color for the ToolButton menu indicator + p->setPen(cg.buttonText() ); + + break; + } + + case CC_ScrollBar: + { + const QScrollBar *scrollbar = (const QScrollBar *) widget; + QRect addline, subline, addpage, subpage, slider, first, last; + bool maxedOut = (scrollbar->minValue() == scrollbar->maxValue()); + scrollmin = ( scrollbar->minValue() == scrollbar->value() ); + scrollmax = (( scrollbar->maxValue() == scrollbar->value() )|| maxedOut); + subline = querySubControlMetrics(control, widget, SC_ScrollBarSubLine, opt); + addline = querySubControlMetrics(control, widget, SC_ScrollBarAddLine, opt); + subpage = querySubControlMetrics(control, widget, SC_ScrollBarSubPage, opt); + addpage = querySubControlMetrics(control, widget, SC_ScrollBarAddPage, opt); + slider = querySubControlMetrics(control, widget, SC_ScrollBarSlider, opt); + + first = querySubControlMetrics(control, widget, SC_ScrollBarFirst, opt); + last = querySubControlMetrics(control, widget, SC_ScrollBarLast, opt); + + if ((controls & SC_ScrollBarSubLine) && subline.isValid()) + { + int flags = Style_Enabled; + if (active == SC_ScrollBarSubLine) + flags |= Style_Down; + if (scrollbar->orientation() == Qt::Horizontal) + flags |= Style_Horizontal; + if (hoverWidget == widget && hoverControl == HoverScrollBarSubLine) + flags |= Style_MouseOver; + drawPrimitive(PE_ScrollBarSubLine, p, subline, cg, flags); + } + if ((controls & SC_ScrollBarAddLine) && addline.isValid()) + { + int flags = Style_Enabled; + if (active == SC_ScrollBarAddLine) + flags |= Style_Down; + if (scrollbar->orientation() == Qt::Horizontal) + flags |= Style_Horizontal; + if (hoverWidget == widget && hoverControl == HoverScrollBarAddLine) + flags |= Style_MouseOver; + drawPrimitive(PE_ScrollBarAddLine, p, addline, cg, flags); + } + if ((controls & SC_ScrollBarSubPage) && subpage.isValid()) + drawPrimitive(PE_ScrollBarSubPage, p, subpage, cg, + Style_Enabled | ((active == SC_ScrollBarSubPage) ? + Style_Down : Style_Default) | + ((scrollbar->orientation() == Qt::Horizontal) ? + Style_Horizontal : 0)); + if ((controls & SC_ScrollBarAddPage) && addpage.isValid()) + drawPrimitive(PE_ScrollBarAddPage, p, addpage, cg, + ((maxedOut) ? Style_Default : Style_Enabled) | + ((active == SC_ScrollBarAddPage) ? + Style_Down : Style_Default) | + ((scrollbar->orientation() == Qt::Horizontal) ? + Style_Horizontal : 0)); + if ((controls & SC_ScrollBarFirst) && first.isValid()) + drawPrimitive(PE_ScrollBarFirst, p, first, cg, + Style_Enabled | ((active == SC_ScrollBarFirst) ? + Style_Down : Style_Default) | + ((scrollbar->orientation() == Qt::Horizontal) ? + Style_Horizontal : 0)); + if ((controls & SC_ScrollBarLast) && last.isValid()) + drawPrimitive(PE_ScrollBarLast, p, last, cg, + Style_Enabled | ((active == SC_ScrollBarLast) ? + Style_Down : Style_Default) | + ((scrollbar->orientation() == Qt::Horizontal) ? + Style_Horizontal : 0)); + if ((controls & SC_ScrollBarSlider) && slider.isValid()) + { + int flags = Style_Enabled; + if (active == SC_ScrollBarSlider) + flags |= Style_Down; + if (scrollbar->orientation() == Qt::Horizontal) + flags |= Style_Horizontal; + if (hoverWidget == widget && hoverControl == HoverScrollBarSlider) + flags |= Style_MouseOver; + drawPrimitive(PE_ScrollBarSlider, p, slider, cg, flags); + + // ### perhaps this should not be able to accept focus if maxedOut? + if (scrollbar->hasFocus()) + { + QRect fr(slider.x() + 2, slider.y() + 2, + slider.width() - 5, slider.height() - 5); + drawPrimitive(PE_FocusRect, p, fr, cg, Style_Default); + } + } + break; + } + // COMBOBOX + // ------------------------------------------------------------------- + case CC_ComboBox: + { + const QComboBox * cb = (const QComboBox *) widget; + if (isFormWidget(cb)) + formMode = true; + // Draw box and arrow + bool reverse = QApplication::reverseLayout(); + if ( widget == hoverWidget ) + flags |= Style_MouseOver; + bool widgetEnabled = ( widget->isEnabled() ); + bool sunken = cb->listBox() ? cb->listBox()->isShown() : false; + + //TODO not editable + if( cb->editable()) + { + if ((controls & SC_ComboBoxFrame )) + { + drawFrame( cdata, cg, p, r,true /*flags ? */); + } + + if( (controls & SC_ComboBoxEditField )) + { + QRect ar = QStyle::visualRect(querySubControlMetrics(CC_ComboBox, widget, SC_ComboBoxEditField), widget ); + + drawPrimitive( PE_PanelLineEdit, p, ar, cg ); + } + //if ( controls & SC_ComboBoxListBoxPopup ) + //{ + //TODO + //} + if( (controls & SC_ComboBoxArrow )) + { + QRect ar = QStyle::visualRect(querySubControlMetrics(CC_ComboBox, widget, SC_ComboBoxArrow), widget ); + bool mouseOver = (flags & Style_MouseOver) && (hoverControl == HoverComboBoxArrow); + if ( sunken ) + renderGradient(p, QRect(ar.x()+1, ar.y()+1, ar.width()-1, ar.height()-2), cdata->shades[2], cdata->shades[0], false); + else if ( mouseOver ) // FIXME: should highlight only when the mouse is over the arrow + renderGradient(p, QRect(ar.x()+1, ar.y()+1, ar.width()-1, ar.height()-2), Qt::white, cdata->shades[1], false); + else + renderGradient(p, QRect(ar.x()+1, ar.y()+1, ar.width()-1, ar.height()-2), cdata->shades[0],cdata->shades[2], false); + + if ( widgetEnabled ) + { + if ( reverse ) + { + p->setPen( cg.base() ); + p->drawLine( ar.x()+1, ar.y()+1,ar.x()+ar.width()-1, ar.y()+1 ); + p->drawLine( ar.width()-1, ar.y()+1, ar.width()-1, ar.height()-2 ); + + p->setPen( cdata->shades[1]); + p->drawLine( ar.x(), ar.y()+1,ar.x(), ar.height()-2 ); + p->drawLine( ar.x(), ar.height()-2, ar.x()+ar.width()-1, ar.height()-2 ); + } + else + { + p->setPen( cg.base() ); + p->drawLine( ar.x()+1, ar.y()+1,ar.x()+ar.width()-1, ar.y()+1 ); + p->drawLine( ar.x()+1, ar.y()+1, ar.x()+1, ar.height()-2 ); + + p->setPen( cdata->shades[1]); + p->drawLine( ar.x()+ar.width()-1, ar.y()+1,ar.x()+ar.width()-1, ar.height()-2 ); + p->drawLine( ar.x()+1, ar.height()-2, ar.x()+ar.width()-1, ar.height()-2 ); + } + } + p->setPen( widgetEnabled ? cdata->shades[5] :cdata->shades[4] ); + if ( reverse) + p->drawLine( ar.width(), ar.y()+1, ar.width(), ar.height()-2 ); + else + p->drawLine( ar.x(), ar.y()+1, ar.x(), ar.height()-2 ); + + drawComboboxArrow( p,widget,ar,cg,flags,active); + } + } + else + { + QPen oldPen = p->pen(); + + // Get the button bounding box + QRect ar = QStyle::visualRect(querySubControlMetrics(CC_ComboBox, widget, SC_ComboBoxArrow), widget ); + drawButton( cdata,r,p,cg,flags | (sunken ? Style_Down : Style_Default)); + + //test reverse ! + if( reverse ) + { + p->setPen(cg.base()); + p->drawLine( ar.width()-1,ar.y()+5,ar.width()-1,ar.height()-6); + p->setPen( cdata->shades[2]); + p->drawLine( ar.width(),ar.y()+5,ar.width(),ar.height()-6); + } + else + { + p->setPen(cg.base()); + p->drawLine( ar.x()-1,ar.y()+5,ar.x()-1,ar.height()-6); + p->setPen(cdata->shades[2]); + p->drawLine( ar.x()-2,ar.y()+5,ar.x()-2,ar.height()-6); + } + + drawComboboxArrow( p,widget,ar,cg,flags,active); + p->setPen( oldPen );// restore pen + + } + break; + } + default: + KStyle::drawComplexControl(control, p, widget, + r, cg, flags, controls, active, opt); + } +} + +QRect MandrivaStyle::querySubControlMetrics( ComplexControl control, + const QWidget* widget, + SubControl subcontrol, + const QStyleOption& opt ) const +{ + switch (control) + { + case CC_SpinWidget: + { + switch ( subcontrol ) + { + case SC_SpinWidgetButtonField: + return QRect( widget->width() -14 , 0, 14, widget->height() ); + default: + return KStyle::querySubControlMetrics( control, widget, subcontrol, opt ); + } + } + //TODO verify it. + case CC_ComboBox: + { + int arrow = 11; + + switch ( subcontrol ) + { + case SC_ComboBoxFrame: + return QRect( 0, 0, widget->width(), widget->height() ); + case SC_ComboBoxArrow: + { + const QComboBox * cb = (const QComboBox *) widget; + return QRect( cb->editable() ? ( widget->width() - arrow - 11 ) : ( widget->width() - arrow- 7 ) , 0, arrow+10 , widget->height() ); + } + case SC_ComboBoxEditField: + { + if ( widget->width() < 36 || widget->height() < 22 ) + return QRect( 5, 1, widget->width() - arrow-12, widget->height()); + else if ( static_cast< const QComboBox* >( widget )->editable() ) + return QRect( 1,1, widget->width() - arrow-12, widget->height() - 2 ); + else //TODO verify it + return QRect( 5, 1, widget->width() - arrow-12, widget->height() - 2); + } + default: + return KStyle::querySubControlMetrics( control, widget, subcontrol, opt ); + } + break; + } + case CC_Slider: + { + const QSlider* sl = static_cast< const QSlider* >( widget ); + bool horizontal = sl->orientation() == Horizontal; + QSlider::TickSetting ticks = sl->tickmarks(); + int pos = sl->sliderStart(); + int handleSize = pixelMetric( PM_SliderThickness, widget ); + int len = pixelMetric( PM_SliderLength, widget ); + switch ( subcontrol ) + { + case SC_SliderHandle: + if ( horizontal ) + { + if ( ticks == QSlider::Both ) + return QRect( pos, ( sl->height() - handleSize ) / 2, len, handleSize ); + else if ( ticks == QSlider::Above ) + return QRect( pos, sl->height() - handleSize, len, handleSize ); + return QRect( pos, 0, len, handleSize ); + } + else + { + if ( ticks == QSlider::Both ) + return QRect( ( sl->width() - handleSize ) / 2, pos, handleSize, len ); + else if ( ticks == QSlider::Above ) + return QRect( sl->width() - handleSize, pos, handleSize, len ); + return QRect( 0, pos, handleSize, len ); + } + default: + break; + } + break; + } + default: + break; + } + return KStyle::querySubControlMetrics( control, widget, subcontrol, opt ); +} + +void MandrivaStyle::drawComplexControlMask( ComplexControl control, + QPainter *p, + const QWidget *widget, + const QRect &r, + const QStyleOption& opt ) const +{ +//TODO verify +//#if 0 + switch (control) + { + // COMBOBOX & TOOLBUTTON MASKS + // ------------------------------------------------------------------- + case CC_ComboBox: + case CC_ToolButton: + { + int x1, y1, x2, y2; + r.coords( &x1, &y1, &x2, &y2 ); + QCOORD corners[] = { x1,y1, x2,y1, x1,y2, x2,y2 }; + p->fillRect( r, color1 ); + p->setPen( color0 ); + p->drawPoints( QPointArray(4, corners) ); + break; + } + + default: + KStyle::drawComplexControlMask(control, p, widget, r, opt); + } +//#endif + //KStyle::drawComplexControlMask(control, p, widget, r, opt); +} + + +int MandrivaStyle::pixelMetric(PixelMetric m, const QWidget *widget) const +{ + switch(m) + { + case PM_SplitterWidth: + return 6; //Perhaps 6 + case PM_ButtonMargin: + return 2; + case PM_DefaultFrameWidth: + return 1; + case PM_MenuButtonIndicator: + return 13; + case PM_SliderLength: + return 31; + case PM_SliderControlThickness: //VERIFY it + return 6; + case PM_SliderThickness: //VERIFY it + return 6; + case PM_ExclusiveIndicatorWidth: // Radiobutton size + return 13; + case PM_ExclusiveIndicatorHeight: + return 12; + case PM_SpinBoxFrameWidth: + return 1; + case PM_CheckListButtonSize: //TODO FIXME §!!!!!!!!!!!!!!! + return 10; + case PM_ScrollBarSliderMin: + return 21; + case PM_ScrollBarExtent: + return 14; //scrollbar width verify arrow position + //checkBox + case PM_IndicatorWidth: + return 13; + case PM_IndicatorHeight: + return 12; + case PM_TabBarTabShiftVertical: + return 0; + default: + return KStyle::pixelMetric(m, widget); + } +} + + +QSize MandrivaStyle::sizeFromContents( ContentsType contents, + const QWidget* widget, + const QSize &contentSize, + const QStyleOption& opt ) const +{ + switch (contents) + { + //define progressbar default size + case CT_ProgressBar: + return QSize( contentSize.width(), 20 ) ; + case CT_SpinBox: + return QSize( contentSize.width(), contentSize.height()+1); + case CT_LineEdit: { + return contentSize + QSize (1, 1); //add +1 to rect + } + case CT_SizeGrip: + { + return QSize( 15, 15 ); + } + case CT_ToolButton: + { + bool onToolbar = widget->parentWidget() && widget->parentWidget()->inherits( "QToolBar" ); + if (!onToolbar) //Behaves like a button, so scale appropriately to the border + { + int w = contentSize.width(); + int h = contentSize.height(); + return QSize( w + 12, h + 10 ); + } + else + { + return KStyle::sizeFromContents( contents, widget, contentSize, opt ); + } + } + case CT_ComboBox: + { + const QComboBox* combobox = (const QComboBox*) widget; + int h = contentSize.height(); + + if ( h < 22 ) + h = 22; + + int arrow = 11; + return QSize( contentSize.width() + arrow + (combobox->editable() ? 26 : 22), + combobox->editable() ? h : contentSize.height() + 10 ); + } + // PUSHBUTTON SIZE + // ------------------------------------------------------------------ + case CT_PushButton: + { + const QPushButton* button = (const QPushButton*) widget; + int w = contentSize.width(); + int h = contentSize.height(); + int bm = pixelMetric( PM_ButtonMargin, widget ); + int fw = pixelMetric( PM_DefaultFrameWidth, widget ) * 2; + + w += bm + fw + 6; // ### Add 6 to make way for bold font. + h += bm + fw; + + // Ensure we stick to standard width and heights. + if ( button->isDefault() || button->autoDefault() ) + { + if ( w < 80 && !button->pixmap() ) + w = 80; + } + + if ( h < 30 ) + h = 30; + + return QSize( w, h ); + } + case CT_PopupMenuItem: + { + if ( ! widget || opt.isDefault() ) + return contentSize; + + const QPopupMenu *popup = (const QPopupMenu *) widget; + bool checkable = popup->isCheckable(); + QMenuItem *mi = opt.menuItem(); + int maxpmw = opt.maxIconWidth(); + int w = contentSize.width(), h = contentSize.height(); + + if ( mi->custom() ) + { + w = mi->custom()->sizeHint().width(); + h = mi->custom()->sizeHint().height(); + if ( ! mi->custom()->fullSpan() ) + h += 2*itemVMargin + 2*itemFrame; + } + else if ( mi->widget() ) + { + // do NOT remove this as it ends up doing wrong things + // this if is here to stop processing the item + } + else if ( mi->isSeparator() ) + { + w = 30; // Arbitrary + h = 2; + } + else + { + if ( mi->pixmap() ) + h = QMAX( h, mi->pixmap()->height() + 2*itemFrame ); + else + { + // Ensure that the minimum height for text-only menu items + // is the same as the icon size used by KDE. + h = QMAX( h, 16 + 2*itemFrame ); + h = QMAX( h, popup->fontMetrics().height() + + 2*itemVMargin + 2*itemFrame ); + } + + if ( mi->iconSet() ) + h = QMAX( h, mi->iconSet()->pixmap( + QIconSet::Small, QIconSet::Normal).height() + + 2 * itemFrame ); + } + + if ( ! mi->text().isNull() && mi->text().find('\t') >= 0 ) + w += 12; + else if ( mi->popup() ) + w += 2 * arrowHMargin; + + if ( maxpmw ) + w += maxpmw + 6; + if ( checkable && maxpmw < 20 ) + w += 20 - maxpmw; + if ( checkable || maxpmw > 0 ) + w += 12; + + w += rightBorder; + + return QSize( w, h ); + } + + default: + return KStyle::sizeFromContents( contents, widget, contentSize, opt ); + } +} + +//Why ? why create virtual function ? +// Fix Qt's wacky image alignment +QPixmap MandrivaStyle::stylePixmap(StylePixmap stylepixmap, + const QWidget* widget, + const QStyleOption& opt) const +{ + return KStyle::stylePixmap(stylepixmap, widget, opt); +} + +bool MandrivaStyle::eventFilter( QObject *object, QEvent *event ) +{ + if (KStyle::eventFilter( object, event )) + return true; + QToolBar* toolbar; + //Hover highlight on buttons and combos + if ( object->inherits("QPushButton") + || object->inherits("QComboBox") + || object->inherits("QScrollBar") + || object->inherits("QHeader") + || object->inherits("QSlider") + || object->inherits("QCheckBox") + || object->inherits("QSplitterHandle")) + { + if ( (event->type() == QEvent::Enter) && static_cast(object)->isEnabled()) + { + QWidget* button = static_cast(object); + hoverWidget = button; + button->repaint( false ); + } + else if ( (event->type() == QEvent::Leave) && (object == hoverWidget) ) + { + QWidget* button = static_cast(object); + hoverWidget = 0; + hoverControl = HoverNone; + button->repaint( false ); + } + if ((object->inherits("QScrollBar") || object->inherits("QComboBox")) + && event->type() == QEvent::MouseMove) + { + QWidget *button = static_cast(object); + QMouseEvent *e = static_cast(event); + // updateHoverControl will trigger a repainting if necessary + updateHoverControl(e->pos()); + } + + } + else if (object->inherits("QListBox")) + { + if ( event->type() == QEvent::Show || event->type() == QEvent::Hide) + { + QWidget *w = static_cast(object); + if (w->parentWidget() && w->parentWidget()->inherits("QComboBox")) + w->parentWidget()->repaint(false); + } + } + else if ( object->parent() && !qstrcmp( object->name(), kdeToolbarWidget ) ) + { + // Draw a gradient background for custom widgets in the toolbar + // that have specified a "kde toolbar widget" name. + + if (event->type() == QEvent::Paint ) + { + // Find the top-level toolbar of this widget, since it may be nested in other + // widgets that are on the toolbar. + QWidget *widget = static_cast(object); + QWidget *parent = static_cast(object->parent()); + int x_offset = widget->x(), y_offset = widget->y(); + while (parent && parent->parent() && !qstrcmp( parent->name(), kdeToolbarWidget ) ) + { + x_offset += parent->x(); + y_offset += parent->y(); + parent = static_cast(parent->parent()); + } + + QRect r = widget->rect(); + QRect pr = parent->rect(); + bool horiz_grad = pr.width() < pr.height(); + + // Check if the parent is a QToolbar, and use its orientation, else guess. + QToolBar* tb = dynamic_cast(parent); + if (tb) horiz_grad = tb->orientation() == Qt::Vertical; + + QPainter p( widget ); + renderGradient(&p, r, parent->colorGroup().background(),parent->colorGroup().background(), horiz_grad);/*, + x_offset, y_offset, pr.width(), pr.height());*/ + //FIXME: check this code later + return false; // Now draw the contents + } + } + else if ( object->parent() && + (toolbar = dynamic_cast(object->parent())) ) + { + + // We need to override the paint event to draw a + // gradient on a QToolBarExtensionWidget. + if ( event->type() == QEvent::Paint ) + { + QWidget *widget = static_cast(object); + QRect wr = widget->rect(), tr = toolbar->rect(); + QPainter p( widget ); + renderGradient(&p, wr, toolbar->colorGroup().background(),toolbar->colorGroup().background(), + toolbar->orientation() == Qt::Vertical);/*, + wr.x(), wr.y(), tr.width() - 2, tr.height() - 2);*/ + //FIXME: check this code later + p.setPen( toolbar->colorGroup().dark() ); + if ( toolbar->orientation() == Qt::Horizontal ) + p.drawLine( wr.width()-1, 0, wr.width()-1, wr.height()-1 ); + else + p.drawLine( 0, wr.height()-1, wr.width()-1, wr.height()-1 ); + return true; + } + } + return false; +} + +//*************** +// renderGradient from PlastikStyle +void MandrivaStyle::renderGradient(QPainter *painter, + const QRect &rect, + const QColor &c1, + const QColor &c2, + bool horizontal) const +{ + if((rect.width() <= 0)||(rect.height() <= 0)) + return; + + // generate a quite unique key for this surface. + CacheEntry search(cGradientTile, + horizontal ? rect.width() : 0, + horizontal ? 0 : rect.height(), + c1.rgb(), c2.rgb(), horizontal ); + int key = search.key(); + + CacheEntry *cacheEntry; + if( (cacheEntry = pixmapCache->find(key)) ) + { + if( search == *cacheEntry ) // match! we can draw now... + { + if(cacheEntry->pixmap) + painter->drawTiledPixmap(rect, *(cacheEntry->pixmap) ); + + return; + } + else + { + // Remove old entry in case of a conflict! + // This shouldn't happen very often, see comment in CacheEntry. + pixmapCache->remove(key); + } + } + + // there wasn't anything matching in the cache, create the pixmap now... + QPixmap *result = new QPixmap(horizontal ? rect.width() : 10, + horizontal ? 10 : rect.height()); + QPainter p(result); + + int r_w = result->rect().width(); + int r_h = result->rect().height(); + int r_x, r_y, r_x2, r_y2; + result->rect().coords(&r_x, &r_y, &r_x2, &r_y2); + + int rDiff, gDiff, bDiff; + int rc, gc, bc; + + register int x, y; + + rDiff = ( c2.red()) - (rc = c1.red()); + gDiff = ( c2.green()) - (gc = c1.green()); + bDiff = ( c2.blue()) - (bc = c1.blue()); + + register int rl = rc << 16; + register int gl = gc << 16; + register int bl = bc << 16; + + int rdelta = ((1<<16) / (horizontal ? r_w : r_h)) * rDiff; + int gdelta = ((1<<16) / (horizontal ? r_w : r_h)) * gDiff; + int bdelta = ((1<<16) / (horizontal ? r_w : r_h)) * bDiff; + + // these for-loops could be merged, but the if's in the inner loop + // would make it slow + if(!horizontal) + { + for ( y = 0; y < r_h; y++ ) + { + rl += rdelta; + gl += gdelta; + bl += bdelta; + + p.setPen(QColor(rl>>16, gl>>16, bl>>16)); + p.drawLine(r_x, r_y+y, r_x2, r_y+y); + } + } + else + { + for( x = 0; x < r_w; x++) + { + rl += rdelta; + gl += gdelta; + bl += bdelta; + + p.setPen(QColor(rl>>16, gl>>16, bl>>16)); + p.drawLine(r_x+x, r_y, r_x+x, r_y2); + } + } + + p.end(); + + // draw the result... + painter->drawTiledPixmap(rect, *result); + + // insert into cache using the previously created key. + CacheEntry *toAdd = new CacheEntry(search); + toAdd->pixmap = result; + bool insertOk = pixmapCache->insert( key, toAdd, result->width()*result->height()*result->depth()/8 ); + + if(!insertOk) + delete result; +} + +void MandrivaStyle::drawButton( const MandrivaColorData *cdata, const QRect & r, QPainter *p,const QColorGroup &cg, SFlags flags)const +{ + QPen oldPen = p->pen(); + bool down = flags & Style_Down; + bool on = flags & Style_On; + bool enabled = flags & Style_Enabled; + bool mouseOver = flags & Style_MouseOver; + bool defaultButton = flags & Style_ButtonDefault; + + bool sunken = on || down; + int x, y, xw, yh; + x= r.x(); + y= r.y(); + xw = r.x()+r.width()-1; + yh = r.y()+r.height()-1; + + if ( !formMode ) + { + if ( !defaultButton || ( defaultButton &&enabled ) ) + { + p->setPen( cg.background() ); + p->drawRect( r ); + //replace background into round + //left/top + p->drawPoint( x+1, y+1 ); + p->drawPoint( x+2, y+1 ); + p->drawPoint( x+1, y+2 ); + + //right/top + p->drawPoint( xw-2, y+1 ); + p->drawPoint( xw-1, y+1 ); + p->drawPoint( xw-1, y+2 ); + + //right/bottom + p->drawPoint( x+1, yh-2); + p->drawPoint( x+2, yh-1); + p->drawPoint( x+1, yh-1); + + + //left/bottom + p->drawPoint( xw-2, yh-1 ); + p->drawPoint( xw-1, yh-1 ); + p->drawPoint( xw-1, yh-2 ); + + } + else + { + p->setPen( cdata->blueMdkColor[4] ); + p->drawLine( x+3, y, xw-3, y ); + p->drawLine( x, y+3, x, yh-3 ); + p->drawLine( x+3, yh, xw-3, yh ); + p->drawLine( xw, y+3, xw, yh-3 ); + + p->drawPoint( x+2, y+1 ); + p->drawPoint( x+1, y+2 ); + + p->drawPoint( x+1, yh-2 ); + p->drawPoint( x+2, yh-1 ); + + p->drawPoint( xw-2, y+1 ); + p->drawPoint( xw-1, y+2 ); + + p->drawPoint( xw-1, yh-2 ); + p->drawPoint( xw-2, yh-1 ); + + p->setPen( cg.background() ); + //left/top + p->drawLine( x, y, x+2, y ); + p->drawLine( x, y+1, x+1, y+1 ); + p->drawPoint( x, y+2 ); + //right/top + p->drawLine( xw-2, y, xw, y ); + p->drawLine( xw-1, y+1, xw, y+1 ); + p->drawPoint( xw, y+2 ); + + //left/bottom + p->drawLine( x, yh-1, x+1, yh-1 ); + p->drawLine( x, yh, x+2, yh ); + p->drawPoint( x, yh-2 ); + + //right/bottom + p->drawLine( xw-1, yh-1, xw, yh-1 ); + p->drawLine( xw-2, yh, xw, yh ); + p->drawPoint( xw, yh-2 ); + + + + } + } + //FIX toggle button + p->setPen( enabled ? cdata->buttonColor[5] : cdata->buttonColor[4] ); + //VERIFY it + p->drawLine( x+3, y+1, xw-3, y+1 ); + p->drawLine( x+1, y+3, x+1, yh-3 ); + p->drawPoint( x+2, y+2 ); + + p->setPen( cdata->buttonColor[4] ); + p->drawLine( x+3, yh-1, xw-3, yh-1 ); + p->drawLine( xw-1,y+3,xw-1,yh-3 ); + p->drawPoint( x+2, yh-2 ); + p->drawPoint( xw-2, yh-2 ); + p->drawPoint( xw-2, y+2 ); + + p->setPen( ( down||sunken ) ? cg.base() : cdata->buttonColor[1] ); + p->drawLine( xw-2, y+3, xw-2, yh-3 ); + p->drawLine( x+3, yh-2, xw-3, yh-2 ); + + + p->setPen( ( down || sunken ) ? cdata->buttonColor[2]: cg.base() ); + p->drawLine( x+3, y+2, xw-3, y+2 ); + p->drawLine( x+2, y+3, x+2, yh-3 ); + + + if ( on ) + renderGradient(p, QRect(x+3, y+3, xw-5, yh-5), + cdata->buttonColor[0] ,mouseOver ? cdata->buttonColor[1] : cdata->buttonColor[2], false); + else if ( down ||sunken ) + renderGradient(p, QRect(x+3, y+3, xw-4, yh-4), + cdata->buttonColor[2] ,cdata->buttonColor[1], false); + else + renderGradient(p, QRect(x+3, y+3, xw-5, yh-5), + cdata->buttonColor[0] ,mouseOver ? cdata->buttonColor[1] :cdata->buttonColor[2], false); + + p->setPen( oldPen ); // restore pen + +} + +QRect MandrivaStyle::subRect(SubRect r, const QWidget *widget) const +{ + switch ( r ) + { + case SR_ProgressBarContents: + { + QRect wrect( widget->rect()); + return QRect( wrect.x() , wrect.y() , wrect.width(), wrect.height()); + } + case SR_PushButtonFocusRect: + { + const QPushButton* button = (const QPushButton*) widget; + QRect wrect(widget->rect()); + if (button->isDefault() || button->autoDefault()) + return QRect(wrect.x() + 6, wrect.y() + 4, wrect.width() - 12, wrect.height() - 8); + else + return QRect(wrect.x() + 4 , wrect.y() + 5, wrect.width() - 9, wrect.height() - 8); + + break; + } + case SR_ComboBoxFocusRect: + { + return querySubControlMetrics( CC_ComboBox, widget, SC_ComboBoxEditField ); + } + default: + return KStyle::subRect( r, widget ); + } +} + +//define handle point +void MandrivaStyle::drawHandlePoint ( const MandrivaColorData *cdata,QPainter *p, int x, int y)const +{ + //blue-4 + p->save(); + p->setPen( cdata->blueMdkColor[4]); + //optimise it and use drawLine; + p->drawPoint(x+1,y); + p->drawPoint(x+2,y); + p->drawPoint(x,y+1); + p->drawPoint(x+1,y+1); + p->drawPoint(x+2,y+1); + p->drawPoint(x+3,y+1); + + //blue-2 + p->setPen( cdata->blueMdkColor[2]); + p->drawPoint(x, y+2 ); + p->drawPoint( x+1, y+2 ); + p->drawPoint( x+1, y+3 ); + + //blue-1 + p->setPen( cdata->blueMdkColor[1] ); + p->drawPoint( x+2, y+2 ); + p->drawPoint( x+3, y+2 ); + p->drawPoint( x+2, y+3 ); + p->restore(); +} + +bool MandrivaStyle::excludeColor(const QColor &col, bool active) const +{ + if ( active ) + { + if ( col == QColor( "#F7B610" ) + || col == QColor( "#8EC7FF" ) + || col == QColor( "#C7D3DF" ) ) + return true; + + } + return false; +} + +bool MandrivaStyle::isFormWidget(const QWidget* widget) const +{ + //Form widgets are in the KHTMLView, but that has 2 further inner levels + //of widgets - QClipperWidget, and outside of that, QViewportWidget + QWidget* potentialClipPort = widget->parentWidget(); + if ( !potentialClipPort || potentialClipPort->isTopLevel() ) + return false; + + QWidget* potentialViewPort = potentialClipPort->parentWidget(); + if (!potentialViewPort || potentialViewPort->isTopLevel() || + qstrcmp(potentialViewPort->name(), "qt_viewport") ) + return false; + + QWidget* potentialKHTML = potentialViewPort->parentWidget(); + if (!potentialKHTML || potentialKHTML->isTopLevel() || + qstrcmp(potentialKHTML->className(), "KHTMLView") ) + return false; + + + return true; +} + +// vim: ts=4 et sw=4 diff --git a/src/widget/ia_ora.h b/src/widget/ia_ora.h new file mode 100644 index 0000000..1e96ccc --- /dev/null +++ b/src/widget/ia_ora.h @@ -0,0 +1,308 @@ +/* + * Copyright (C) 2007 Gustavo Pichorim Boiko + * Copyright (C) 2006 Laurent Montel + * + * renderGradient() code adapted from the Plastik stype + * Copyright (C) 2003 Sandro Giessl + * + * based on KDE3 HighColor Style (version 1.0) + * Copyright (C) 2001-2002 Karol Szwed + * (C) 2001-2002 Fredrik Höglund + * + * Drawing routines adapted from the KDE2 HCStyle, + * Copyright (C) 2000 Daniel M. Duley + * (C) 2000 Dirk Mueller + * (C) 2001 Martijn Klingens + * + * 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., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + + +#ifndef __MANDRIVASTYLE_H +#define __MANDRIVASTYLE_H + +#include +#include +#include +#include +#include +#include + +class QPopupMenu; + + +class MandrivaStyle : public KStyle +{ + Q_OBJECT + +public: + MandrivaStyle(); + virtual ~MandrivaStyle(); + + void polish( QWidget* widget ); + void unPolish( QWidget* widget ); + void polish( QApplication *app ); + void renderMenuBlendPixmap( KPixmap& pix, const QColorGroup &cg, + const QPopupMenu* popup ) const; + + void drawKStylePrimitive( KStylePrimitive kpe, + QPainter* p, + const QWidget* widget, + const QRect &r, + const QColorGroup &cg, + SFlags flags = Style_Default, + const QStyleOption& = QStyleOption::Default ) const; + + void drawPrimitive( PrimitiveElement pe, + QPainter* p, + const QRect &r, + const QColorGroup &cg, + SFlags flags = Style_Default, + const QStyleOption& = QStyleOption::Default ) const; + + void drawControl( ControlElement element, + QPainter *p, + const QWidget *widget, + const QRect &r, + const QColorGroup &cg, + SFlags flags = Style_Default, + const QStyleOption& = QStyleOption::Default ) const; + + void drawControlMask( ControlElement element, + QPainter *p, + const QWidget *widget, + const QRect &r, + const QStyleOption& = QStyleOption::Default ) const; + + void drawComplexControl( ComplexControl control, + QPainter *p, + const QWidget *widget, + const QRect &r, + const QColorGroup &cg, + SFlags flags = Style_Default, + SCFlags controls = SC_All, + SCFlags active = SC_None, + const QStyleOption& = QStyleOption::Default ) const; + + void drawComplexControlMask( ComplexControl control, + QPainter *p, + const QWidget *widget, + const QRect &r, + const QStyleOption& = QStyleOption::Default ) const; + + int pixelMetric( PixelMetric m, + const QWidget *widget = 0 ) const; + + QSize sizeFromContents( ContentsType contents, + const QWidget *widget, + const QSize &contentSize, + const QStyleOption& opt ) const; + + QRect subRect( SubRect r, + const QWidget *widget ) const; + + // Fix Qt3's wacky image positions + QPixmap stylePixmap( StylePixmap stylepixmap, + const QWidget *widget = 0, + const QStyleOption& = QStyleOption::Default ) const; + + QRect querySubControlMetrics( ComplexControl control, + const QWidget* widget, + SubControl subcontrol, + const QStyleOption& opt = QStyleOption::Default ) const; + +protected: + enum Hover + { + HoverNone = 0, + // scrollbar + HoverScrollBarSlider, + HoverScrollBarAddLine, + HoverScrollBarSubLine, + HoverScrollBarAddPage, + HoverScrollBarSubPage, + HoverScrollBarFirst, + HoverScrollBarLast, + // combobox + HoverComboBoxArrow, + HoverComboBoxEdit + }; + + + bool eventFilter( QObject *object, QEvent *event ); + + void renderGradient(QPainter* p, + const QRect& r, + const QColor& ca, + const QColor& cb , + bool horizontal) const; + + QWidget *hoverWidget; + enum Hover hoverControl; + + struct MandrivaColorData + { + ~MandrivaColorData(); + QRgb spotColor; + + // gradient color + //rename to grey + QColor shades[7]; + + // five blue color + QColor blueMdkColor[5]; + + // button gradients + QColor buttonColor[7]; + + + QColor radioColor; + + bool isGroup (const QColorGroup &cg) + { + return cg.button() == buttonColor[0] && cg.highlight().rgb() == spotColor; + } + }; + +private: + enum TabPosition {Single = 0,First,Last, Middle}; + + // Disable copy constructor and = operator + MandrivaStyle( const MandrivaStyle & ); + MandrivaStyle& operator=( const MandrivaStyle & ); + + void drawButton( const MandrivaColorData *cdata, + const QRect & r, QPainter *p, + const QColorGroup &cg, + SFlags flags) const; + + void drawHandlePoint ( const MandrivaColorData *cdata, + QPainter *p, + int x, + int y) const; + + void drawHandle( const MandrivaColorData *cdata, + QPainter *p, + const QRect &r, + const QColorGroup &cg, + SFlags flags, + const QStyleOption& opt, + bool drawBorderAndGradient, + bool drawGradient = false ) const; + + void drawGroupBox(const MandrivaColorData *cdata, + const QColorGroup & cg, + QPainter *p, + const QRect & r, + bool active, + bool sunken )const; + + void drawLineSeparator(const MandrivaColorData *cdata, + const QColorGroup & cg, + QPainter *p, + const QRect & r, + bool horiziontal, + bool active, + bool sunken, + bool skipOffset = true) const; + + void drawFrame( const MandrivaColorData *cdata, + const QColorGroup & cg, + QPainter *p, + const QRect & r, + bool active) const; + + void drawComboboxArrow( QPainter *p, + const QWidget *widget, + const QRect &r, + const QColorGroup &cg, + SFlags flags, + SCFlags active)const; + + void drawMandrivaArrow( QPointArray a, QPainter *p, + const QRect &r, + const QColorGroup &cg, + SFlags flags, + const QStyleOption& opt ) const; + + + MandrivaColorData *realizeData (const QColorGroup &cg) const; + const MandrivaColorData *lookupData (const QColorGroup &cg) const; + bool isFormWidget(const QWidget* widget) const; + bool excludeColor(const QColor &col, bool active) const; + void getShade (const QColorGroup &cg, int shadenr, QColor &res) const; + void updateHoverControl(const QPoint &pos); + QIntCache m_dataCache; + static const double shading[8]; + mutable bool formMode; + bool kickerMode; + // For KPE_ListViewBranch + mutable QBitmap *verticalLine; + mutable QBitmap *horizontalLine; + + // pixmap cache. + enum CacheEntryType + { + cSurface, + cGradientTile, + cAlphaDot + }; + struct CacheEntry + { + CacheEntryType type; + int width; + int height; + QRgb c1Rgb; + QRgb c2Rgb; + bool horizontal; + + QPixmap* pixmap; + + CacheEntry(CacheEntryType t, int w, int h, QRgb c1, QRgb c2 = 0, + bool hor = false, QPixmap* p = 0 ): + type(t), width(w), height(h), c1Rgb(c1), c2Rgb(c2), horizontal(hor), pixmap(p) + {} + + ~CacheEntry() + { + delete pixmap; + } + + int key() + { + // create an int key from the properties which is used to refer to entries in the QIntCache. + // the result may not be 100% correct as we don't have so much space in one integer -- use + // == operator after find to make sure we got the right one. :) + return horizontal ^ (type<<1) ^ (width<<5) ^ (height<<10) ^ (c1Rgb<<19) ^ (c2Rgb<<22); + } + + bool operator == (const CacheEntry& other) + { + bool match = (type == other.type) && + (width == other.width) && + (height == other.height) && + (c1Rgb == other.c1Rgb) && + (c1Rgb == other.c1Rgb) && + (horizontal == other.horizontal); + return match; + } + }; + QIntCache *pixmapCache; + +}; + +#endif + +// vim: ts=4 et sw=4 diff --git a/src/widget/ia_ora.themerc b/src/widget/ia_ora.themerc new file mode 100644 index 0000000..e85be6c --- /dev/null +++ b/src/widget/ia_ora.themerc @@ -0,0 +1,6 @@ +[Misc] +Name=Ia Ora +Comment=Mandriva Widget Style +[KDE] +WidgetStyle=ia_ora +