murrine r2 - in trunk: . src
- From: acimitan svn gnome org
- To: svn-commits-list gnome org
- Subject: murrine r2 - in trunk: . src
- Date: Mon, 11 Feb 2008 23:01:50 +0000 (GMT)
Author: acimitan
Date: Mon Feb 11 23:01:49 2008
New Revision: 2
URL: http://svn.gnome.org/viewvc/murrine?rev=2&view=rev
Log:
First commit
Added:
trunk/AUTHORS
trunk/COPYING
trunk/CREDITS
trunk/ChangeLog
trunk/INSTALL
trunk/MAINTAINERS
trunk/Makefile.am
trunk/NEWS
trunk/README
trunk/autogen.sh (contents, props changed)
trunk/configure.ac
trunk/murrine.pc.in
trunk/src/
trunk/src/animation.c
trunk/src/animation.h
trunk/src/cairo-support.c
trunk/src/cairo-support.h
trunk/src/config.h.in
trunk/src/murrine_draw.c
trunk/src/murrine_draw.h
trunk/src/murrine_draw_rgba.c
trunk/src/murrine_draw_rgba.h
trunk/src/murrine_rc_style.c
trunk/src/murrine_rc_style.h
trunk/src/murrine_style.c
trunk/src/murrine_style.h
trunk/src/murrine_theme_main.c
trunk/src/murrine_types.h
trunk/src/support.c
trunk/src/support.h
Added: trunk/AUTHORS
==============================================================================
--- (empty file)
+++ trunk/AUTHORS Mon Feb 11 23:01:49 2008
@@ -0,0 +1,15 @@
+"Murrine Gtk2 Cairo Engine"
+Copyright (C) 2007 Andrea Cimitan
+
+Licensed under the GNU GPL License
+
+Murrine is based on:
+ Candido:
+ Andrea Cimitan - andrea cimitan gmail com
+ Rezlooks:
+ Doug Whiteley - dougwhiteley gmail com
+ Clearlooks:
+ Richard Stellingwerff - remenic gmail com
+ Daniel Borgmann - daniel borgmann gmail com
+
+(See CREDITS file for other contributors)
Added: trunk/COPYING
==============================================================================
--- (empty file)
+++ trunk/COPYING Mon Feb 11 23:01:49 2008
@@ -0,0 +1,340 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 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.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+ Gnomovision version 69, Copyright (C) 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.
+
+ <signature of Ty Coon>, 1 April 1989
+ Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs. If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library. If this is what you want to do, use the GNU Library General
+Public License instead of this License.
Added: trunk/CREDITS
==============================================================================
--- (empty file)
+++ trunk/CREDITS Mon Feb 11 23:01:49 2008
@@ -0,0 +1,7 @@
+Cimi's thanks:
+
+Doug Whitely - for the permission to edit his theme and for the little help.
+
+Oliver Tobin - for his support to refine my theme.
+
+Benjiamin Berg - for all his bugfixes... and a lot more... thanks!!!
Added: trunk/INSTALL
==============================================================================
--- (empty file)
+++ trunk/INSTALL Mon Feb 11 23:01:49 2008
@@ -0,0 +1,236 @@
+Installation Instructions
+*************************
+
+Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005 Free
+Software Foundation, Inc.
+
+This file is free documentation; the Free Software Foundation gives
+unlimited permission to copy, distribute and modify it.
+
+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, and a
+file `config.log' containing compiler output (useful mainly for
+debugging `configure').
+
+ It can also use an optional file (typically called `config.cache'
+and enabled with `--cache-file=config.cache' or simply `-C') that saves
+the results of its tests to speed up reconfiguring. (Caching is
+disabled by default to prevent problems with accidental use of stale
+cache files.)
+
+ 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 you are using the cache, and at
+some point `config.cache' contains results you don't want to keep, you
+may remove or edit it.
+
+ The file `configure.ac' (or `configure.in') is used to create
+`configure' by a program called `autoconf'. You only need
+`configure.ac' 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 awhile. While running, it prints some
+ messages telling which features it is checking for.
+
+ 2. Type `make' to compile the package.
+
+ 3. Optionally, type `make check' to run any self-tests that come with
+ the package.
+
+ 4. Type `make install' to install the programs and any data files and
+ documentation.
+
+ 5. You can remove the program binaries and object files from the
+ source code directory by typing `make clean'. To also remove the
+ files that `configure' created (so you can compile the package for
+ a different kind of computer), type `make distclean'. There is
+ also a `make maintainer-clean' target, but that is intended mainly
+ for the package's developers. If you use it, you may have to get
+ all sorts of other programs in order to regenerate files that came
+ with the distribution.
+
+Compilers and Options
+=====================
+
+Some systems require unusual options for compilation or linking that the
+`configure' script does not know about. Run `./configure --help' for
+details on some of the pertinent environment variables.
+
+ You can give `configure' initial values for configuration parameters
+by setting variables in the command line or in the environment. Here
+is an example:
+
+ ./configure CC=c89 CFLAGS=-O2 LIBS=-lposix
+
+ *Note Defining Variables::, for more details.
+
+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 support 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' installs the package's commands under
+`/usr/local/bin', include files under `/usr/local/include', etc. You
+can specify an installation prefix other than `/usr/local' by giving
+`configure' the option `--prefix=PREFIX'.
+
+ You can specify separate installation prefixes for
+architecture-specific files and architecture-independent files. If you
+pass the option `--exec-prefix=PREFIX' to `configure', the package uses
+PREFIX as the prefix for installing programs and libraries.
+Documentation and other data files still use the regular prefix.
+
+ In addition, if you use an unusual directory layout you can give
+options like `--bindir=DIR' to specify different values for particular
+kinds of files. Run `configure --help' for a list of the directories
+you can set and what kinds of files go in them.
+
+ 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' cannot figure out automatically,
+but needs to determine by the type of machine the package will run on.
+Usually, assuming the package is built to be run on the _same_
+architectures, `configure' can figure that out, but if it prints a
+message saying it cannot guess the machine type, give it the
+`--build=TYPE' option. TYPE can either be a short name for the system
+type, such as `sun4', or a canonical name which has the form:
+
+ CPU-COMPANY-SYSTEM
+
+where SYSTEM can have one of these forms:
+
+ OS KERNEL-OS
+
+ 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 machine type.
+
+ If you are _building_ compiler tools for cross-compiling, you should
+use the option `--target=TYPE' to select the type of system they will
+produce code for.
+
+ If you want to _use_ a cross compiler, that generates code for a
+platform different from the build platform, you should specify the
+"host" platform (i.e., that on which the generated programs will
+eventually be run) with `--host=TYPE'.
+
+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.
+
+Defining Variables
+==================
+
+Variables not defined in a site shell script can be set in the
+environment passed to `configure'. However, some packages may run
+configure again during the build, and the customized values of these
+variables may be lost. In order to avoid this problem, you should set
+them in the `configure' command line, using `VAR=value'. For example:
+
+ ./configure CC=/usr/local2/bin/gcc
+
+causes the specified `gcc' to be used as the C compiler (unless it is
+overridden in the site shell script). Here is a another example:
+
+ /bin/bash ./configure CONFIG_SHELL=/bin/bash
+
+Here the `CONFIG_SHELL=/bin/bash' operand causes subsequent
+configuration-related scripts to be executed by `/bin/bash'.
+
+`configure' Invocation
+======================
+
+`configure' recognizes the following options to control how it operates.
+
+`--help'
+`-h'
+ Print a summary of the options to `configure', and exit.
+
+`--version'
+`-V'
+ Print the version of Autoconf used to generate the `configure'
+ script, and exit.
+
+`--cache-file=FILE'
+ Enable the cache: use and save the results of the tests in FILE,
+ traditionally `config.cache'. FILE defaults to `/dev/null' to
+ disable caching.
+
+`--config-cache'
+`-C'
+ Alias for `--cache-file=config.cache'.
+
+`--quiet'
+`--silent'
+`-q'
+ Do not print messages saying which checks are being made. To
+ suppress all normal output, redirect it to `/dev/null' (any error
+ messages will still be shown).
+
+`--srcdir=DIR'
+ Look for the package's source code in directory DIR. Usually
+ `configure' can determine that directory automatically.
+
+`configure' also accepts some other, not widely useful, options. Run
+`configure --help' for more details.
+
Added: trunk/MAINTAINERS
==============================================================================
--- (empty file)
+++ trunk/MAINTAINERS Mon Feb 11 23:01:49 2008
@@ -0,0 +1,3 @@
+Andrea Cimitan
+E-mail: andrea cimitan gmail com
+Userid: acimitan
Added: trunk/Makefile.am
==============================================================================
--- (empty file)
+++ trunk/Makefile.am Mon Feb 11 23:01:49 2008
@@ -0,0 +1,28 @@
+INCLUDES = $(GTK_CFLAGS)
+
+enginedir = $(libdir)/gtk-2.0/$(GTK_VERSION)/engines
+engine_LTLIBRARIES = libmurrine.la
+
+EXTRA_DIST = ./src/config.h.in
+
+libmurrine_la_SOURCES = \
+ ./src/animation.c \
+ ./src/animation.h \
+ ./src/cairo-support.c \
+ ./src/cairo-support.h \
+ ./src/config.h \
+ ./src/support.c \
+ ./src/support.h \
+ ./src/murrine_rc_style.c \
+ ./src/murrine_rc_style.h \
+ ./src/murrine_style.c \
+ ./src/murrine_style.h \
+ ./src/murrine_theme_main.c \
+ ./src/murrine_draw.c \
+ ./src/murrine_draw_rgba.c \
+ ./src/murrine_draw.h \
+ ./src/murrine_types.h
+
+libmurrine_la_LDFLAGS = -module -avoid-version -no-undefined
+libmurrine_la_LIBADD = $(GTK_LIBS)
+
Added: trunk/NEWS
==============================================================================
--- (empty file)
+++ trunk/NEWS Mon Feb 11 23:01:49 2008
@@ -0,0 +1 @@
+See Changelog for news.
Added: trunk/README
==============================================================================
--- (empty file)
+++ trunk/README Mon Feb 11 23:01:49 2008
@@ -0,0 +1,9 @@
+This is Murrine GTK+ engine. This source code provides only the engine, get the themes @ gnomelook.org.
+
+Do the normal dance to install:
+
+ (./autogen.sh ; ) ./configure (generally --prefix=/usr, try --enable-animation); make ; make install
+
+To uninstall:
+
+ make uninstall
Added: trunk/autogen.sh
==============================================================================
--- (empty file)
+++ trunk/autogen.sh Mon Feb 11 23:01:49 2008
@@ -0,0 +1,65 @@
+#!/bin/sh
+# Run this to generate all the initial makefiles, etc.
+
+srcdir=`dirname $0`
+test -z "$srcdir" && srcdir=.
+DIE=0
+
+THEDIR=`pwd`
+cd $srcdir
+
+(autoconf --version) < /dev/null > /dev/null 2>&1 || {
+ echo
+ echo "You must have autoconf installed to compile GTK+."
+ echo "Download the appropriate package for your distribution,"
+ echo "or get the source tarball at http://ftp.gnu.org/gnu/autoconf/"
+ DIE=1
+}
+
+if automake-1.10 --version < /dev/null > /dev/null 2>&1 ; then
+ AUTOMAKE=automake-1.10
+ ACLOCAL=aclocal-1.10
+elif automake-1.9 --version < /dev/null > /dev/null 2>&1 ; then
+ AUTOMAKE=automake-1.9
+ ACLOCAL=aclocal-1.9
+elif automake-1.8 --version < /dev/null > /dev/null 2>&1 ; then
+ AUTOMAKE=automake-1.8
+ ACLOCAL=aclocal-1.8
+elif automake-1.7 --version < /dev/null > /dev/null 2>&1 ; then
+ AUTOMAKE=automake-1.7
+ ACLOCAL=aclocal-1.7
+else
+ echo
+ echo "You must have automake 1.7.x installed to compile $PROJECT."
+ echo "Install the appropriate package for your distribution,"
+ echo "or get the source tarball at http://ftp.gnu.org/gnu/automake/"
+ DIE=1
+fi
+
+(libtool --version) < /dev/null > /dev/null 2>&1 || {
+ echo
+ echo "You must have libtool installed to compile GTK+."
+ echo "Get http://ftp.gnu.org/gnu/libtool/libtool-1.5.10.tar.gz"
+ echo "(or a newer version if it is available)"
+ DIE=1
+}
+if test "$DIE" -eq 1; then
+ exit 1
+fi
+
+if test -z "$*"; then
+ echo "I am going to run ./configure with no arguments - if you wish "
+ echo "to pass any to it, please specify them on the $0 command line."
+fi
+
+libtoolize --force --copy
+
+$ACLOCAL $ACLOCAL_FLAGS
+autoconf
+$AUTOMAKE --add-missing
+cd $THEDIR
+
+$srcdir/configure --enable-maintainer-mode "$@"
+
+echo
+echo "Now type 'make' to compile themes"
Added: trunk/configure.ac
==============================================================================
--- (empty file)
+++ trunk/configure.ac Mon Feb 11 23:01:49 2008
@@ -0,0 +1,56 @@
+AC_INIT([murrine], [0.60])
+AC_CONFIG_SRCDIR([README])
+
+AM_INIT_AUTOMAKE
+
+dnl Initialize maintainer mode
+AM_MAINTAINER_MODE
+
+AC_PROG_CC
+AM_PROG_CC_STDC
+AC_PROG_INSTALL
+AC_PROG_MAKE_SET
+
+dnl Initialize libtool
+AM_DISABLE_STATIC
+AC_LIBTOOL_WIN32_DLL
+AM_PROG_LIBTOOL
+
+AC_ARG_ENABLE(animation, [ --enable-animation compile murrine with animation support], [animation=$enableval], [animation="no"], )
+AC_ARG_ENABLE(macmenu, [ --enable-macmenu compile murrine with mac menubar patches], [macmenu=$enableval], [macmenu="no"], )
+AC_ARG_ENABLE(animationtoleft, [ --enable-animationtoleft compile murrine with progressbar animation from right to left], [animationtoleft=$enableval], [animationtoleft="no"], )
+
+PKG_CHECK_MODULES(GTK, gtk+-2.0 >= 2.8.0,,
+ AC_MSG_ERROR([GTK+-2.8 is required to compile murrine]))
+
+AC_SUBST(GTK_CFLAGS)
+AC_SUBST(GTK_LIBS)
+
+GTK_VERSION=`$PKG_CONFIG --variable=gtk_binary_version gtk+-2.0`
+AC_SUBST(GTK_VERSION)
+
+AC_SUBST(BUILD_ENGINES)
+AC_SUBST(BUILD_THEMES)
+
+if test $animation = "yes"; then
+ AC_DEFINE_UNQUOTED(HAVE_ANIMATION, 1, [Defines whether to compile with animation support])
+fi
+
+if test $macmenu = "yes"; then
+ AC_DEFINE_UNQUOTED(HAVE_MACMENU, 1, [Defines whether to compile with mac menubar patches])
+fi
+
+if test $animationtoleft = "yes"; then
+ AC_DEFINE_UNQUOTED(HAVE_ANIMATIONTOLEFT, 1, [Defines whether to compile with progressbar animation from right to left])
+fi
+
+AM_CONFIG_HEADER([src/config.h])
+
+AC_CONFIG_FILES([
+Makefile
+murrine.pc
+])
+
+AC_OUTPUT
+
+echo "Now run make."
Added: trunk/murrine.pc.in
==============================================================================
--- (empty file)
+++ trunk/murrine.pc.in Mon Feb 11 23:01:49 2008
@@ -0,0 +1,9 @@
+prefix= prefix@
+exec_prefix= exec_prefix@
+libdir= libdir@
+includedir= includedir@
+
+Name: murrine
+Description: Murrine GTK+ Theme Engine
+Version: @VERSION@
+Requires: gtk+-2.0
Added: trunk/src/animation.c
==============================================================================
--- (empty file)
+++ trunk/src/animation.c Mon Feb 11 23:01:49 2008
@@ -0,0 +1,328 @@
+/* Murrine theme engine
+ * Copyright (C) 2007 Andrea Cimitan
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * 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; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ */
+
+#include "animation.h"
+
+#ifdef HAVE_ANIMATION
+#include <glib/gtimer.h>
+
+struct _AnimationInfo
+{
+ GTimer *timer;
+
+ gdouble start_modifier;
+ gdouble stop_time;
+ GtkWidget *widget;
+};
+typedef struct _AnimationInfo AnimationInfo;
+
+struct _SignalInfo
+{
+ GtkWidget *widget;
+ gulong handler_id;
+};
+typedef struct _SignalInfo SignalInfo;
+
+static GSList *connected_widgets = NULL;
+static GHashTable *animated_widgets = NULL;
+static int animation_timer_id = 0;
+
+static gboolean animation_timeout_handler (gpointer data);
+
+/* This forces a redraw on a widget */
+static gboolean
+force_widget_redraw (GtkWidget *widget)
+{
+ if (GTK_IS_PROGRESS_BAR (widget))
+ gtk_widget_queue_resize (widget);
+ else
+ gtk_widget_queue_draw (widget);
+}
+
+/* ensures that the timer is running */
+static void
+start_timer ()
+{
+ if (animation_timer_id == 0)
+ animation_timer_id = g_timeout_add (ANIMATION_DELAY, animation_timeout_handler, NULL);
+}
+
+/* ensures that the timer is stopped */
+static void
+stop_timer ()
+{
+ if (animation_timer_id != 0)
+ {
+ g_source_remove(animation_timer_id);
+ animation_timer_id = 0;
+ }
+}
+
+
+/* destroys an AnimationInfo structure including the GTimer */
+static void
+animation_info_destroy (AnimationInfo *animation_info)
+{
+ g_timer_destroy (animation_info->timer);
+ g_free (animation_info);
+}
+
+/* This function does not unref the weak reference, because the object
+ * is beeing destroyed currently. */
+static void
+on_animated_widget_destruction (gpointer data, GObject *object)
+{
+ /* steal the animation info from the hash table (destroying it would
+ * result in the weak reference to be unrefed, which does not work
+ * as the widget is already destroyed. */
+ g_hash_table_steal (animated_widgets, object);
+ animation_info_destroy ((AnimationInfo*) data);
+}
+
+/* This function also needs to unref the weak reference. */
+static void
+destroy_animation_info_and_weak_unref (gpointer data)
+{
+ AnimationInfo *animation_info = data;
+
+ /* force a last redraw. This is so that if the animation is removed,
+ * the widget is left in a sane state. */
+ force_widget_redraw (animation_info->widget);
+
+ g_object_weak_unref (G_OBJECT (animation_info->widget), on_animated_widget_destruction, data);
+ animation_info_destroy (animation_info);
+}
+
+/* Find and return a pointer to the data linked to this widget, if it exists */
+static AnimationInfo*
+lookup_animation_info (const GtkWidget *widget)
+{
+ if (animated_widgets)
+ return g_hash_table_lookup (animated_widgets, widget);
+
+ return NULL;
+}
+
+/* Create all the relevant information for the animation, and insert it into the hash table. */
+static void
+add_animation (const GtkWidget *widget, gdouble stop_time)
+{
+ AnimationInfo *value;
+
+ /* object already in the list, do not add it twice */
+ if (lookup_animation_info (widget))
+ return;
+
+ if (animated_widgets == NULL)
+ animated_widgets = g_hash_table_new_full (g_direct_hash, g_direct_equal,
+ NULL, destroy_animation_info_and_weak_unref);
+
+ value = g_new(AnimationInfo, 1);
+
+ value->widget = (GtkWidget*) widget;
+
+ value->timer = g_timer_new ();
+ value->stop_time= stop_time;
+ value->start_modifier = 0.0;
+
+ g_object_weak_ref (G_OBJECT (widget), on_animated_widget_destruction, value);
+ g_hash_table_insert (animated_widgets, (GtkWidget*) widget, value);
+
+ start_timer ();
+}
+
+/* update the animation information for each widget. This will also queue a redraw
+ * and stop the animation if it is done. */
+static gboolean
+update_animation_info (gpointer key, gpointer value, gpointer user_data)
+{
+ AnimationInfo *animation_info = value;
+ GtkWidget *widget = key;
+ gdouble elapsed;
+
+ if ((widget == NULL) || (animation_info == NULL))
+ g_assert_not_reached ();
+
+ /* remove the widget from the hash table if it is not drawable */
+ if (!GTK_WIDGET_DRAWABLE (widget))
+ return TRUE;
+
+ if (GTK_IS_PROGRESS_BAR (widget))
+ {
+ gfloat fraction = gtk_progress_bar_get_fraction (GTK_PROGRESS_BAR (widget));
+
+ /* stop animation for filled/not filled progress bars */
+ if (fraction <= 0.0 || fraction >= 1.0)
+ return TRUE;
+ }
+
+ force_widget_redraw (widget);
+
+ /* stop at stop_time */
+ if (animation_info->stop_time != 0 &&
+ g_timer_elapsed (animation_info->timer, NULL) > animation_info->stop_time)
+ return TRUE;
+
+ return FALSE;
+}
+
+/* This gets called by the glib main loop every once in a while. */
+static gboolean
+animation_timeout_handler (gpointer data)
+{
+ /* enter threads as update_animation_info will use gtk/gdk. */
+ gdk_threads_enter ();
+
+ /*g_print("** TICK **\n");*/
+ g_hash_table_foreach_remove (animated_widgets, update_animation_info, NULL);
+
+ /* leave again */
+ gdk_threads_leave ();
+
+ if(g_hash_table_size(animated_widgets)==0)
+ {
+ stop_timer ();
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static void
+on_checkbox_toggle (GtkWidget *widget, gpointer data)
+{
+ AnimationInfo *animation_info = lookup_animation_info (widget);
+
+ if (animation_info != NULL)
+ {
+ gfloat elapsed = g_timer_elapsed (animation_info->timer, NULL);
+
+ animation_info->start_modifier = elapsed - animation_info->start_modifier;
+ }
+ else
+ {
+ add_animation (widget, CHECK_ANIMATION_TIME);
+ }
+}
+
+static void
+on_connected_widget_destruction (gpointer data, GObject *widget)
+{
+ connected_widgets = g_slist_remove (connected_widgets, data);
+ g_free (data);
+}
+
+static void
+disconnect_all_signals ()
+{
+ GSList * item = connected_widgets;
+ while (item != NULL)
+ {
+ SignalInfo *signal_info = (SignalInfo*) item->data;
+
+ g_signal_handler_disconnect (signal_info->widget, signal_info->handler_id);
+ g_object_weak_unref (G_OBJECT (signal_info->widget), on_connected_widget_destruction, signal_info);
+ g_free (signal_info);
+
+ item = g_slist_next (item);
+ }
+
+ g_slist_free (connected_widgets);
+ connected_widgets = NULL;
+}
+
+/* helper function for murrine_animation_connect_checkbox */
+static gint
+find_signal_info (gconstpointer signal_info, gconstpointer widget)
+{
+ if (((SignalInfo*)signal_info)->widget == widget)
+ return 0;
+ else
+ return 1;
+}
+
+
+/* external interface */
+
+/* adds a progress bar */
+void
+murrine_animation_progressbar_add (GtkWidget *progressbar)
+{
+ gdouble fraction = gtk_progress_bar_get_fraction (GTK_PROGRESS_BAR (progressbar));
+
+ if (fraction < 1.0 && fraction > 0.0)
+ add_animation ((GtkWidget*) progressbar, 0.0);
+}
+
+/* hooks up the signals for check and radio buttons */
+void
+murrine_animation_connect_checkbox (GtkWidget *widget)
+{
+ if (GTK_IS_CHECK_BUTTON (widget))
+ {
+ if (!g_slist_find_custom (connected_widgets, widget, find_signal_info))
+ {
+ SignalInfo * signal_info = g_new (SignalInfo, 1);
+
+ signal_info->widget = widget;
+ signal_info->handler_id = g_signal_connect ((GObject*)widget, "toggled", G_CALLBACK (on_checkbox_toggle), NULL);
+
+ connected_widgets = g_slist_append (connected_widgets, signal_info);
+ g_object_weak_ref (G_OBJECT (widget), on_connected_widget_destruction, signal_info);
+ }
+ }
+}
+
+/* returns TRUE if the widget is animated, and FALSE otherwise */
+gboolean
+murrine_animation_is_animated (GtkWidget *widget)
+{
+ return lookup_animation_info (widget) != NULL ? TRUE : FALSE;
+}
+
+/* returns the elapsed time for the animation */
+gdouble
+murrine_animation_elapsed (gpointer data)
+{
+ AnimationInfo *animation_info = lookup_animation_info (data);
+
+ if (animation_info)
+ return g_timer_elapsed (animation_info->timer, NULL)
+ - animation_info->start_modifier;
+ else
+ return 0.0;
+}
+
+/* cleans up all resources of the animation system */
+void
+murrine_animation_cleanup ()
+{
+ disconnect_all_signals ();
+
+ if (animated_widgets != NULL)
+ {
+ g_hash_table_destroy (animated_widgets);
+ animated_widgets = NULL;
+ }
+
+ stop_timer ();
+}
+
+#endif /* HAVE_ANIMATION */
Added: trunk/src/animation.h
==============================================================================
--- (empty file)
+++ trunk/src/animation.h Mon Feb 11 23:01:49 2008
@@ -0,0 +1,35 @@
+/* Murrine theme engine
+ * Copyright (C) 2007 Andrea Cimitan
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * 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; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ */
+
+#include "config.h"
+
+#ifdef HAVE_ANIMATION
+#include <gtk/gtk.h>
+
+#define MRN_IS_PROGRESS_BAR(widget) GTK_IS_PROGRESS_BAR(widget) && widget->allocation.x != -1 && widget->allocation.y != -1
+#define ANIMATION_DELAY 100
+#define CHECK_ANIMATION_TIME 0.5
+
+G_GNUC_INTERNAL void murrine_animation_progressbar_add (GtkWidget *progressbar);
+G_GNUC_INTERNAL void murrine_animation_connect_checkbox (GtkWidget *widget);
+G_GNUC_INTERNAL gboolean murrine_animation_is_animated (GtkWidget *widget);
+G_GNUC_INTERNAL gdouble murrine_animation_elapsed (gpointer data);
+G_GNUC_INTERNAL void murrine_animation_cleanup ();
+#endif /* HAVE_ANIMATION */
Added: trunk/src/cairo-support.c
==============================================================================
--- (empty file)
+++ trunk/src/cairo-support.c Mon Feb 11 23:01:49 2008
@@ -0,0 +1,670 @@
+/* Murrine theme engine
+ * Copyright (C) 2007 Andrea Cimitan
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * 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; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ */
+
+#include "cairo-support.h"
+#include "support.h"
+#include <math.h>
+
+#include "murrine_types.h"
+
+G_GNUC_INTERNAL void
+murrine_rgb_to_hls (gdouble *r,
+ gdouble *g,
+ gdouble *b)
+{
+ gdouble min;
+ gdouble max;
+ gdouble red;
+ gdouble green;
+ gdouble blue;
+ gdouble h, l, s;
+ gdouble delta;
+
+ red = *r;
+ green = *g;
+ blue = *b;
+
+ if (red > green)
+ {
+ if (red > blue)
+ max = red;
+ else
+ max = blue;
+
+ if (green < blue)
+ min = green;
+ else
+ min = blue;
+ }
+ else
+ {
+ if (green > blue)
+ max = green;
+ else
+ max = blue;
+
+ if (red < blue)
+ min = red;
+ else
+ min = blue;
+ }
+
+ l = (max + min) / 2;
+ if (fabs(max - min) < 0.0001)
+ {
+ h = 0;
+ s = 0;
+ }
+ else
+ {
+ if (l <= 0.5)
+ s = (max - min) / (max + min);
+ else
+ s = (max - min) / (2 - max - min);
+
+ delta = max -min;
+ if (red == max)
+ h = (green - blue) / delta;
+ else if (green == max)
+ h = 2 + (blue - red) / delta;
+ else if (blue == max)
+ h = 4 + (red - green) / delta;
+
+ h *= 60;
+ if (h < 0.0)
+ h += 360;
+ }
+
+ *r = h;
+ *g = l;
+ *b = s;
+}
+
+G_GNUC_INTERNAL void
+murrine_hls_to_rgb (gdouble *h,
+ gdouble *l,
+ gdouble *s)
+{
+ gdouble hue;
+ gdouble lightness;
+ gdouble saturation;
+ gdouble m1, m2;
+ gdouble r, g, b;
+
+ lightness = *l;
+ saturation = *s;
+
+ if (lightness <= 0.5)
+ m2 = lightness * (1 + saturation);
+ else
+ m2 = lightness + saturation - lightness * saturation;
+
+ m1 = 2 * lightness - m2;
+
+ if (saturation == 0)
+ {
+ *h = lightness;
+ *l = lightness;
+ *s = lightness;
+ }
+ else
+ {
+ hue = *h + 120;
+ while (hue > 360)
+ hue -= 360;
+ while (hue < 0)
+ hue += 360;
+
+ if (hue < 60)
+ r = m1 + (m2 - m1) * hue / 60;
+ else if (hue < 180)
+ r = m2;
+ else if (hue < 240)
+ r = m1 + (m2 - m1) * (240 - hue) / 60;
+ else
+ r = m1;
+
+ hue = *h;
+ while (hue > 360)
+ hue -= 360;
+ while (hue < 0)
+ hue += 360;
+
+ if (hue < 60)
+ g = m1 + (m2 - m1) * hue / 60;
+ else if (hue < 180)
+ g = m2;
+ else if (hue < 240)
+ g = m1 + (m2 - m1) * (240 - hue) / 60;
+ else
+ g = m1;
+
+ hue = *h - 120;
+ while (hue > 360)
+ hue -= 360;
+ while (hue < 0)
+ hue += 360;
+
+ if (hue < 60)
+ b = m1 + (m2 - m1) * hue / 60;
+ else if (hue < 180)
+ b = m2;
+ else if (hue < 240)
+ b = m1 + (m2 - m1) * (240 - hue) / 60;
+ else
+ b = m1;
+
+ *h = r;
+ *l = g;
+ *s = b;
+ }
+}
+
+void
+murrine_shade (const MurrineRGB * a, MurrineRGB * b, float k)
+{
+ double red;
+ double green;
+ double blue;
+
+ red = a->r;
+ green = a->g;
+ blue = a->b;
+
+ if (k == 1.0)
+ {
+ b->r = red;
+ b->g = green;
+ b->b = blue;
+ return;
+ }
+
+ murrine_rgb_to_hls (&red, &green, &blue);
+
+ green *= k;
+ if (green > 1.0)
+ green = 1.0;
+ else if (green < 0.0)
+ green = 0.0;
+
+ blue *= k;
+ if (blue > 1.0)
+ blue = 1.0;
+ else if (blue < 0.0)
+ blue = 0.0;
+
+ murrine_hls_to_rgb (&red, &green, &blue);
+
+ b->r = red;
+ b->g = green;
+ b->b = blue;
+}
+
+void
+murrine_mix_color (const MurrineRGB *color1, const MurrineRGB *color2,
+ gdouble mix_factor, MurrineRGB *composite)
+{
+ g_return_if_fail (color1 && color2 && composite);
+
+ composite->r = color1->r * (1-mix_factor) + color2->r * mix_factor;
+ composite->g = color1->g * (1-mix_factor) + color2->g * mix_factor;
+ composite->b = color1->b * (1-mix_factor) + color2->b * mix_factor;
+}
+
+void
+murrine_gdk_color_to_rgb (GdkColor *c, double *r, double *g, double *b)
+{
+ *r = (double)c->red / (double)65535;
+ *g = (double)c->green / (double)65535;
+ *b = (double)c->blue / (double)65535;
+}
+
+void
+murrine_get_parent_bg (const GtkWidget *widget, MurrineRGB *color)
+{
+ GtkStateType state_type;
+ const GtkWidget *parent;
+ GdkColor *gcolor;
+
+ if (widget == NULL)
+ return;
+
+ parent = widget->parent;
+
+ while (parent && GTK_WIDGET_NO_WINDOW (parent) && !((GTK_IS_NOTEBOOK (parent)) || (GTK_IS_TOOLBAR (parent))))
+ parent = parent->parent;
+
+ if (parent == NULL)
+ return;
+
+ state_type = GTK_WIDGET_STATE (parent);
+
+ gcolor = &parent->style->bg[state_type];
+
+ murrine_gdk_color_to_rgb (gcolor, &color->r, &color->g, &color->b);
+}
+
+void
+murrine_set_color_rgb (cairo_t *cr, const MurrineRGB *color)
+{
+ g_return_if_fail (cr && color);
+
+ cairo_set_source_rgb (cr, color->r, color->g, color->b);
+}
+
+void
+murrine_set_color_rgba (cairo_t *cr, const MurrineRGB *color, double alpha)
+{
+ g_return_if_fail (cr && color);
+
+ cairo_set_source_rgba (cr, color->r, color->g, color->b, alpha);
+}
+
+void
+murrine_rounded_corner (cairo_t *cr,
+ double x,
+ double y,
+ int radius, uint8 corner)
+{
+ if (radius < 1)
+ {
+ cairo_line_to (cr, x, y);
+ }
+ else
+ {
+ switch (corner)
+ {
+ case MRN_CORNER_NONE:
+ cairo_line_to (cr, x, y);
+ break;
+ case MRN_CORNER_TOPLEFT:
+ cairo_arc (cr, x + radius, y + radius, radius, G_PI, G_PI * 3/2);
+ break;
+ case MRN_CORNER_TOPRIGHT:
+ cairo_arc (cr, x - radius, y + radius, radius, G_PI * 3/2, G_PI * 2);
+ break;
+ case MRN_CORNER_BOTTOMRIGHT:
+ cairo_arc (cr, x - radius, y - radius, radius, 0, G_PI * 1/2);
+ break;
+ case MRN_CORNER_BOTTOMLEFT:
+ cairo_arc (cr, x + radius, y - radius, radius, G_PI * 1/2, G_PI);
+ break;
+
+ default:
+ /* A bitfield and not a sane value ... */
+ g_assert_not_reached ();
+ cairo_line_to (cr, x, y);
+ return;
+ }
+ }
+}
+
+void
+murrine_rounded_rectangle_fast (cairo_t *cr,
+ double x, double y, double w, double h,
+ uint8 corners)
+{
+ const float RADIUS_CORNERS = 0.35;
+
+ if (corners & MRN_CORNER_TOPLEFT)
+ cairo_move_to (cr, x+RADIUS_CORNERS, y);
+ else
+ cairo_move_to (cr, x, y);
+
+ if (corners & MRN_CORNER_TOPRIGHT)
+ {
+ cairo_line_to (cr, x+w-RADIUS_CORNERS, y);
+ cairo_move_to (cr, x+w, y+RADIUS_CORNERS);
+ }
+ else
+ cairo_line_to (cr, x+w, y);
+
+ if (corners & MRN_CORNER_BOTTOMRIGHT)
+ {
+ cairo_line_to (cr, x+w, y+h-RADIUS_CORNERS);
+ cairo_move_to (cr, x+w-RADIUS_CORNERS, y+h);
+ }
+ else
+ cairo_line_to (cr, x+w, y+h);
+
+ if (corners & MRN_CORNER_BOTTOMLEFT)
+ {
+ cairo_line_to (cr, x+RADIUS_CORNERS, y+h);
+ cairo_move_to (cr, x, y+h-RADIUS_CORNERS);
+ }
+ else
+ cairo_line_to (cr, x, y+h);
+
+ if (corners & MRN_CORNER_TOPLEFT)
+ cairo_line_to (cr, x, y+RADIUS_CORNERS);
+ else
+ {
+ if (corners == MRN_CORNER_NONE)
+ cairo_close_path (cr);
+ else
+ cairo_line_to (cr, x, y);
+ }
+}
+
+void
+clearlooks_rounded_rectangle (cairo_t *cr,
+ double x, double y, double w, double h,
+ int radius, uint8 corners)
+{
+ if (radius < 1)
+ {
+ cairo_rectangle (cr, x, y, w, h);
+ return;
+ }
+
+ if (corners & MRN_CORNER_TOPLEFT)
+ cairo_move_to (cr, x+radius, y);
+ else
+ cairo_move_to (cr, x, y);
+
+ if (corners & MRN_CORNER_TOPRIGHT)
+ cairo_arc (cr, x+w-radius, y+radius, radius, M_PI * 1.5, M_PI * 2);
+ else
+ cairo_line_to (cr, x+w, y);
+
+ if (corners & MRN_CORNER_BOTTOMRIGHT)
+ cairo_arc (cr, x+w-radius, y+h-radius, radius, 0, M_PI * 0.5);
+ else
+ cairo_line_to (cr, x+w, y+h);
+
+ if (corners & MRN_CORNER_BOTTOMLEFT)
+ cairo_arc (cr, x+radius, y+h-radius, radius, M_PI * 0.5, M_PI);
+ else
+ cairo_line_to (cr, x, y+h);
+
+ if (corners & MRN_CORNER_TOPLEFT)
+ cairo_arc (cr, x+radius, y+radius, radius, M_PI, M_PI * 1.5);
+ else
+ cairo_line_to (cr, x, y);
+}
+
+void
+murrine_rounded_rectangle (cairo_t *cr,
+ double x, double y, double w, double h,
+ int radius, uint8 corners)
+{
+ radius < 2 ? radius < 1 ? cairo_rectangle (cr, x, y, w, h) :
+ murrine_rounded_rectangle_fast (cr, x, y, w, h, corners) :
+ clearlooks_rounded_rectangle (cr, x, y, w, h, radius, corners);
+}
+
+void
+murrine_draw_flat_highlight (cairo_t *cr,
+ int x, int y, int width, int height)
+{
+ cairo_rectangle (cr, x, y, width, height/2);
+}
+
+void
+murrine_draw_curved_highlight (cairo_t *cr,
+ double curve_pos, int width, int height)
+{
+ cairo_move_to (cr, curve_pos, height-curve_pos);
+ cairo_curve_to (cr, curve_pos, height/2+height/5, height/5, height/2, height/2, height/2);
+ cairo_line_to (cr, width-height/2, height/2);
+ cairo_curve_to (cr, width-curve_pos-height/5, height/2, width-curve_pos-0.5, height/2-height/5, width-curve_pos, curve_pos);
+ cairo_line_to (cr, curve_pos, curve_pos);
+ cairo_line_to (cr, curve_pos, height-curve_pos);
+ cairo_close_path (cr);
+}
+
+void
+murrine_draw_curved_highlight_top (cairo_t *cr,
+ double curve_pos, int width, int height)
+{
+ cairo_move_to (cr, curve_pos, curve_pos);
+ cairo_curve_to (cr, curve_pos, height/2-height/5, height/5, height/2, height/2, height/2);
+ cairo_line_to (cr, width-height/2, height/2);
+ cairo_curve_to (cr, width-curve_pos-height/5, height/2, width-curve_pos-0.5, height/2-height/5, width-curve_pos, curve_pos);
+ cairo_close_path (cr);
+}
+
+void
+murrine_draw_curved_highlight_bottom (cairo_t *cr,
+ double curve_pos, int width, int height)
+{
+ cairo_move_to (cr, curve_pos, height-curve_pos);
+ cairo_curve_to (cr, curve_pos, height/2+height/5, height/5, height/2, height/2, height/2);
+ cairo_line_to (cr, width-height/2, height/2);
+ cairo_curve_to (cr, width-curve_pos-height/5, height/2, width-curve_pos-0.5, height/2+height/5, width-curve_pos, height-curve_pos);
+ cairo_close_path (cr);
+}
+
+void
+murrine_draw_innerborder (cairo_t *cr,
+ const MurrineRGB *highlight_color,
+ const MurrineRGB *fill,
+ MurrineGradients mrn_gradient,
+ double x, double y, int width, int height,
+ boolean gradients, boolean horizontal,
+ int glazestyle, int radius, uint8 corners)
+{
+ cairo_pattern_t *pattern;
+ MurrineRGB shade1, shade2, shade3, shade4;
+ MurrineRGB fill_shade;
+ double alpha_value = 1.0;
+ if (mrn_gradient.use_rgba)
+ {
+ alpha_value = mrn_gradient.rgba_opacity;
+ }
+
+ if (gradients)
+ {
+ if (mrn_gradient.has_gradient_stop)
+ {
+ murrine_shade (highlight_color, &shade1, mrn_gradient.gradient_stop_1);
+ murrine_shade (highlight_color, &shade2, mrn_gradient.gradient_stop_2);
+ murrine_shade (highlight_color, &shade3, mrn_gradient.gradient_stop_3);
+ murrine_shade (highlight_color, &shade4, mrn_gradient.gradient_stop_4);
+ murrine_shade (fill, &fill_shade, mrn_gradient.gradient_stop_4);
+ }
+ else
+ {
+ murrine_shade (highlight_color, &shade1, 1.1);
+ murrine_shade (highlight_color, &shade2, 1.0);
+ murrine_shade (highlight_color, &shade3, 1.0);
+ murrine_shade (highlight_color, &shade4, 1.1);
+ murrine_shade (fill, &fill_shade, 1.1);
+ }
+ }
+ else
+ {
+ murrine_shade (highlight_color, &shade1, 1.0);
+ murrine_shade (highlight_color, &shade2, 1.0);
+ murrine_shade (highlight_color, &shade3, 1.0);
+ murrine_shade (highlight_color, &shade4, 1.0);
+ murrine_shade (fill, &fill_shade, 1.0);
+ }
+
+ double fill_pos = 1.0-(1.0/(!horizontal ? (double)(width) : (double)(height)));
+ if (corners == MRN_CORNER_ALL && radius > 2)
+ fill_pos = 1.0-((((double)radius-1.0)/2.0)/(!horizontal ? (double)(width) : (double)(height)));
+
+ radius < 2 ? cairo_rectangle (cr, x, y, width, height) :
+ clearlooks_rounded_rectangle (cr, x, y, width, height, radius-1, corners);
+
+ pattern = cairo_pattern_create_linear (x, y, !horizontal ? width+x : x, !horizontal ? y : height+y);
+ cairo_pattern_add_color_stop_rgba (pattern, 0.0, shade1.r, shade1.g, shade1.b, 0.5*alpha_value);
+ cairo_pattern_add_color_stop_rgba (pattern, 0.5, shade2.r, shade2.g, shade2.b, 0.5*alpha_value);
+ cairo_pattern_add_color_stop_rgba (pattern, 0.5, shade3.r, shade3.g, shade3.b, 0.5*alpha_value);
+ cairo_pattern_add_color_stop_rgba (pattern, fill_pos, shade4.r, shade4.g, shade4.b, 0.5*alpha_value);
+ cairo_pattern_add_color_stop_rgba (pattern, fill_pos, fill_shade.r, fill_shade.g, fill_shade.b, 0.0);
+ cairo_pattern_add_color_stop_rgba (pattern, 1.0, fill_shade.r, fill_shade.g, fill_shade.b, 0.0);
+ cairo_set_source (cr, pattern);
+ cairo_pattern_destroy (pattern);
+
+ cairo_stroke (cr);
+
+ if (glazestyle == 2)
+ {
+ murrine_set_gradient (cr, fill, mrn_gradient, x, y, 0, height, mrn_gradient.gradients, FALSE);
+ cairo_move_to (cr, width+x, y+0.5);
+ cairo_line_to (cr, width+x, height+y);
+ cairo_line_to (cr, x-0.5, height+y);
+ cairo_stroke (cr);
+ }
+}
+
+void
+murrine_set_gradient (cairo_t *cr,
+ const MurrineRGB *color,
+ MurrineGradients mrn_gradient,
+ double x, double y, int width, int height,
+ boolean gradients, boolean alpha)
+{
+ double alpha_value = 1.0;
+ if (mrn_gradient.use_rgba)
+ {
+ alpha_value = mrn_gradient.rgba_opacity;
+ }
+ else if (alpha)
+ {
+ alpha_value *= 0.8;
+ }
+
+ if (gradients)
+ {
+ cairo_pattern_t *pattern;
+ MurrineRGB shade1, shade2, shade3, shade4;
+
+ if (mrn_gradient.has_gradient_stop)
+ {
+ murrine_shade (color, &shade1, mrn_gradient.gradient_stop_1);
+ murrine_shade (color, &shade2, mrn_gradient.gradient_stop_2);
+ murrine_shade (color, &shade3, mrn_gradient.gradient_stop_3);
+ murrine_shade (color, &shade4, mrn_gradient.gradient_stop_4);
+ }
+ else
+ {
+ murrine_shade (color, &shade1, 1.1);
+ murrine_shade (color, &shade2, 1.0);
+ murrine_shade (color, &shade3, 1.0);
+ murrine_shade (color, &shade4, 1.1);
+ }
+
+ pattern = cairo_pattern_create_linear (x, y, width+x, height+y);
+ if (mrn_gradient.use_rgba)
+ {
+ cairo_pattern_add_color_stop_rgba (pattern, 0.0, shade1.r, shade1.g, shade1.b, alpha_value);
+ cairo_pattern_add_color_stop_rgba (pattern, 0.5, shade2.r, shade2.g, shade2.b, alpha_value);
+ cairo_pattern_add_color_stop_rgba (pattern, 0.5, shade3.r, shade3.g, shade3.b, alpha_value);
+ cairo_pattern_add_color_stop_rgba (pattern, 1.0, shade4.r, shade4.g, shade4.b, alpha_value);
+ }
+ else
+ {
+ if (!alpha)
+ {
+ cairo_pattern_add_color_stop_rgb (pattern, 0.0, shade1.r, shade1.g, shade1.b);
+ cairo_pattern_add_color_stop_rgb (pattern, 0.5, shade2.r, shade2.g, shade2.b);
+ cairo_pattern_add_color_stop_rgb (pattern, 0.5, shade3.r, shade3.g, shade3.b);
+ cairo_pattern_add_color_stop_rgb (pattern, 1.0, shade4.r, shade4.g, shade4.b);
+ }
+ else
+ {
+ cairo_pattern_add_color_stop_rgba (pattern, 0.0, shade1.r, shade1.g, shade1.b, alpha_value);
+ cairo_pattern_add_color_stop_rgba (pattern, 0.5, shade2.r, shade2.g, shade2.b, alpha_value);
+ cairo_pattern_add_color_stop_rgba (pattern, 0.5, shade3.r, shade3.g, shade3.b, alpha_value);
+ cairo_pattern_add_color_stop_rgba (pattern, 1.0, shade4.r, shade4.g, shade4.b, alpha_value);
+ }
+ }
+ cairo_set_source (cr, pattern);
+ cairo_pattern_destroy (pattern);
+ }
+ else
+ {
+ if (alpha_value < 1.0)
+ murrine_set_color_rgba (cr, color, alpha_value);
+ else
+ murrine_set_color_rgb (cr, color);
+ }
+}
+
+void
+rotate_mirror_translate (cairo_t *cr,
+ double radius, double x, double y,
+ boolean mirror_horizontally, boolean mirror_vertically)
+{
+ cairo_matrix_t matrix_rotate;
+ cairo_matrix_t matrix_mirror;
+ cairo_matrix_t matrix_result;
+
+ double r_cos = cos(radius);
+ double r_sin = sin(radius);
+
+ cairo_matrix_init (&matrix_rotate, r_cos, r_sin, r_sin, r_cos, x, y);
+
+ cairo_matrix_init (&matrix_mirror,
+ mirror_horizontally ? -1 : 1, 0, 0,
+ mirror_vertically ? -1 : 1, 0, 0);
+
+ cairo_matrix_multiply (&matrix_result, &matrix_mirror, &matrix_rotate);
+
+ cairo_set_matrix (cr, &matrix_result);
+}
+
+void
+murrine_exchange_axis (cairo_t *cr,
+ gint *x,
+ gint *y,
+ gint *width,
+ gint *height)
+{
+ gint tmp;
+ cairo_matrix_t matrix;
+
+ cairo_translate (cr, *x, *y);
+ cairo_matrix_init (&matrix, 0, 1, 1, 0, 0, 0);
+
+ cairo_transform (cr, &matrix);
+
+ /* swap width/height */
+ tmp = *width;
+ *x = 0;
+ *y = 0;
+ *width = *height;
+ *height = tmp;
+}
+
+double
+get_decreased_ratio (double old, double factor)
+{
+ if (old > 1.0)
+ return ((old-1.0)/factor + 1.0);
+ else if (old < 1.0)
+ return (1.0 - (1.0-old)/factor);
+
+ return old;
+}
+
+double
+get_increased_ratio (double old, double factor)
+{
+ if (old > 1.0)
+ return ((old-1.0)*factor + 1.0);
+ else if (old < 1.0)
+ return (1.0 - (1.0-old)*factor);
+
+ return old;
+}
Added: trunk/src/cairo-support.h
==============================================================================
--- (empty file)
+++ trunk/src/cairo-support.h Mon Feb 11 23:01:49 2008
@@ -0,0 +1,102 @@
+/* Murrine theme engine
+ * Copyright (C) 2007 Andrea Cimitan
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * 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; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ */
+
+#include <gtk/gtk.h>
+#include <math.h>
+
+#include "murrine_types.h"
+
+G_GNUC_INTERNAL void murrine_shade (const MurrineRGB *a, MurrineRGB *b,
+ float k);
+
+G_GNUC_INTERNAL void murrine_mix_color (const MurrineRGB *color1, const MurrineRGB *color2,
+ gdouble mix_factor, MurrineRGB *composite);
+
+G_GNUC_INTERNAL void murrine_gdk_color_to_rgb (GdkColor *c,
+ double *r, double *g, double *b);
+
+G_GNUC_INTERNAL void murrine_get_parent_bg (const GtkWidget *widget,
+ MurrineRGB *color);
+
+G_GNUC_INTERNAL void murrine_set_color_rgb (cairo_t *cr,
+ const MurrineRGB *color);
+
+G_GNUC_INTERNAL void murrine_set_color_rgba (cairo_t *cr,
+ const MurrineRGB *color,
+ double alpha);
+
+G_GNUC_INTERNAL void rotate_mirror_translate (cairo_t *cr,
+ double radius, double x, double y,
+ boolean mirror_horizontally, boolean mirror_vertically);
+
+G_GNUC_INTERNAL double get_decreased_ratio (double old, double factor);
+
+G_GNUC_INTERNAL double get_increased_ratio (double old, double factor);
+
+G_GNUC_INTERNAL void murrine_exchange_axis (cairo_t *cr,
+ gint *x,
+ gint *y,
+ gint *width,
+ gint *height);
+
+G_GNUC_INTERNAL void murrine_rounded_corner (cairo_t *cr,
+ double x, double y,
+ int radius, uint8 corner);
+
+G_GNUC_INTERNAL void clearlooks_rounded_rectangle (cairo_t *cr,
+ double x, double y, double w, double h,
+ int radius, uint8 corners);
+
+G_GNUC_INTERNAL void murrine_rounded_rectangle (cairo_t *cr,
+ double x, double y, double w, double h,
+ int radius, uint8 corners);
+
+G_GNUC_INTERNAL void murrine_rounded_rectangle_fast (cairo_t *cr,
+ double x, double y, double w, double h,
+ uint8 corners);
+
+G_GNUC_INTERNAL void murrine_draw_innerborder (cairo_t *cr,
+ const MurrineRGB *highlight_color, const MurrineRGB *fill,
+ MurrineGradients mrn_gradient,
+ double x, double y, int width, int height,
+ boolean gradients, boolean horizontal,
+ int glazestyle, int radius, uint8 corners);
+
+G_GNUC_INTERNAL void murrine_set_gradient (cairo_t *cr,
+ const MurrineRGB *color,
+ MurrineGradients mrn_gradient,
+ double x, double y, int width, int height,
+ boolean gradients, boolean alpha);
+
+G_GNUC_INTERNAL void murrine_draw_flat_highlight (cairo_t *cr,
+ int x, int y, int width, int height);
+
+G_GNUC_INTERNAL void murrine_draw_curved_highlight (cairo_t *cr,
+ double curve_pos,
+ int width, int height);
+
+G_GNUC_INTERNAL void murrine_draw_curved_highlight_top (cairo_t *cr,
+ double curve_pos,
+ int width, int height);
+
+G_GNUC_INTERNAL void murrine_draw_curved_highlight_bottom (cairo_t *cr,
+ double curve_pos,
+ int width, int height);
+
Added: trunk/src/config.h.in
==============================================================================
--- (empty file)
+++ trunk/src/config.h.in Mon Feb 11 23:01:49 2008
@@ -0,0 +1,64 @@
+/* src/config.h.in. Generated from configure.ac by autoheader. */
+
+/* Defines whether to compile with animation support */
+#undef HAVE_ANIMATION
+
+/* Defines whether to compile with progressbar animation from right to left */
+#undef HAVE_ANIMATIONTOLEFT
+
+/* Define to 1 if you have the <dlfcn.h> header file. */
+#undef HAVE_DLFCN_H
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#undef HAVE_INTTYPES_H
+
+/* Defines whether to compile with mac menubar patches */
+#undef HAVE_MACMENU
+
+/* Define to 1 if you have the <memory.h> header file. */
+#undef HAVE_MEMORY_H
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#undef HAVE_STDINT_H
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#undef HAVE_STDLIB_H
+
+/* Define to 1 if you have the <strings.h> header file. */
+#undef HAVE_STRINGS_H
+
+/* Define to 1 if you have the <string.h> header file. */
+#undef HAVE_STRING_H
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#undef HAVE_SYS_STAT_H
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#undef HAVE_SYS_TYPES_H
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#undef HAVE_UNISTD_H
+
+/* Name of package */
+#undef PACKAGE
+
+/* Define to the address where bug reports for this package should be sent. */
+#undef PACKAGE_BUGREPORT
+
+/* Define to the full name of this package. */
+#undef PACKAGE_NAME
+
+/* Define to the full name and version of this package. */
+#undef PACKAGE_STRING
+
+/* Define to the one symbol short name of this package. */
+#undef PACKAGE_TARNAME
+
+/* Define to the version of this package. */
+#undef PACKAGE_VERSION
+
+/* Define to 1 if you have the ANSI C header files. */
+#undef STDC_HEADERS
+
+/* Version number of package */
+#undef VERSION
Added: trunk/src/murrine_draw.c
==============================================================================
--- (empty file)
+++ trunk/src/murrine_draw.c Mon Feb 11 23:01:49 2008
@@ -0,0 +1,2402 @@
+/* Murrine theme engine
+ * Copyright (C) 2007 Andrea Cimitan
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * 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; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ */
+
+#include "murrine_draw.h"
+#include "murrine_style.h"
+#include "murrine_types.h"
+
+#include "support.h"
+#include "cairo-support.h"
+
+#include <cairo.h>
+
+#define M_PI 3.14159265358979323846
+
+static void
+murrine_draw_inset (cairo_t *cr,
+ const MurrineRGB *bg_color,
+ double x, double y, double w, double h,
+ double radius, uint8 corners)
+{
+ MurrineRGB shadow;
+ MurrineRGB highlight;
+
+ /* not really sure of shading ratios... we will think */
+ murrine_shade (bg_color, &shadow, 0.6);
+ murrine_shade (bg_color, &highlight, 1.4);
+
+ /* highlight */
+ cairo_move_to (cr, x + w + (radius * -0.2928932188), y - (radius * -0.2928932188)); /* 0.2928932... 1-sqrt(2)/2 gives middle of curve */
+
+ if (corners & MRN_CORNER_TOPRIGHT)
+ cairo_arc (cr, x + w - radius, y + radius, radius, M_PI * 1.75, M_PI * 2);
+ else
+ cairo_line_to (cr, x + w, y);
+
+ if (corners & MRN_CORNER_BOTTOMRIGHT)
+ cairo_arc (cr, x + w - radius, y + h - radius, radius, 0, M_PI * 0.5);
+ else
+ cairo_line_to (cr, x + w, y + h);
+
+ if (corners & MRN_CORNER_BOTTOMLEFT)
+ cairo_arc (cr, x + radius, y + h - radius, radius, M_PI * 0.5, M_PI * 0.75);
+ else
+ cairo_line_to (cr, x, y + h);
+
+ murrine_set_color_rgba (cr, &highlight, 0.45);
+ cairo_stroke (cr);
+
+ /* shadow */
+ cairo_move_to (cr, x + (radius * 0.2928932188), y + h + (radius * -0.2928932188));
+
+ if (corners & MRN_CORNER_BOTTOMLEFT)
+ cairo_arc (cr, x + radius, y + h - radius, radius, M_PI * 0.75, M_PI);
+ else
+ cairo_line_to (cr, x, y + h);
+
+ if (corners & MRN_CORNER_TOPLEFT)
+ cairo_arc (cr, x + radius, y + radius, radius, M_PI, M_PI * 1.5);
+ else
+ cairo_line_to (cr, x, y);
+
+ if (corners & MRN_CORNER_TOPRIGHT)
+ cairo_arc (cr, x + w - radius, y + radius, radius, M_PI * 1.5, M_PI * 1.75);
+ else
+ cairo_line_to (cr, x + w, y);
+
+ murrine_set_color_rgba (cr, &shadow, 0.15);
+ cairo_stroke (cr);
+}
+
+static void
+murrine_draw_highlight_and_shade (cairo_t *cr,
+ const MurrineColors *colors,
+ const ShadowParameters *widget,
+ int width, int height, int radius)
+{
+ MurrineRGB highlight;
+ MurrineRGB shadow;
+ uint8 corners = widget->corners;
+ double x = 1.0;
+ double y = 1.0;
+
+ murrine_shade (&colors->bg[0], &highlight, 1.04);
+ murrine_shade (&colors->bg[0], &shadow, 0.96);
+
+ width -= 3;
+ height -= 3;
+
+ cairo_save (cr);
+
+ /* Top/Left highlight */
+ if (corners & MRN_CORNER_BOTTOMLEFT)
+ cairo_move_to (cr, x, y+height-radius);
+ else
+ cairo_move_to (cr, x, y+height);
+
+ murrine_rounded_corner (cr, x, y, radius, corners & MRN_CORNER_TOPLEFT);
+
+ if (corners & MRN_CORNER_TOPRIGHT)
+ cairo_line_to (cr, x+width-radius, y);
+ else
+ cairo_line_to (cr, x+width, y);
+
+ if (widget->shadow & MRN_SHADOW_OUT)
+ murrine_set_color_rgb (cr, &highlight);
+ else
+ murrine_set_color_rgb (cr, &shadow);
+
+ cairo_stroke (cr);
+
+ /* Bottom/Right highlight -- this includes the corners */
+ cairo_move_to (cr, x+width-radius, y); /* topright and by radius to the left */
+ murrine_rounded_corner (cr, x+width, y, radius, corners & MRN_CORNER_TOPRIGHT);
+ murrine_rounded_corner (cr, x+width, y+height, radius, corners & MRN_CORNER_BOTTOMRIGHT);
+ murrine_rounded_corner (cr, x, y+height, radius, corners & MRN_CORNER_BOTTOMLEFT);
+
+ if (widget->shadow & MRN_SHADOW_OUT)
+ murrine_set_color_rgb (cr, &shadow);
+ else
+ murrine_set_color_rgb (cr, &highlight);
+
+ cairo_stroke (cr);
+
+ cairo_restore (cr);
+}
+
+static void
+murrine_draw_button (cairo_t *cr,
+ const MurrineColors *colors,
+ const WidgetParameters *widget,
+ int x, int y, int width, int height,
+ boolean horizontal)
+{
+ double xoffset = 0, yoffset = 0;
+ MurrineRGB fill = colors->bg[widget->state_type];
+ MurrineRGB border_disabled = colors->shade[5];
+ MurrineRGB border_normal;
+ MurrineRGB highlight;
+
+ double custom_highlight_ratio = widget->highlight_ratio;
+ MurrineGradients mrn_gradient_custom = widget->mrn_gradient;
+
+ if (widget->disabled)
+ {
+ mrn_gradient_custom.gradient_stop_1 = get_decreased_ratio (widget->mrn_gradient.gradient_stop_1, 3.0);
+ mrn_gradient_custom.gradient_stop_2 = get_decreased_ratio (widget->mrn_gradient.gradient_stop_2, 3.0);
+ mrn_gradient_custom.gradient_stop_3 = get_decreased_ratio (widget->mrn_gradient.gradient_stop_3, 3.0);
+ mrn_gradient_custom.gradient_stop_4 = get_decreased_ratio (widget->mrn_gradient.gradient_stop_4, 3.0);
+ custom_highlight_ratio = get_decreased_ratio (widget->highlight_ratio, 2.0);
+ }
+
+ if (widget->is_default)
+ murrine_mix_color (&fill, &colors->spot[1], 0.2, &fill);
+
+ if (!horizontal)
+ murrine_exchange_axis (cr, &x, &y, &width, &height);
+
+ murrine_shade (&colors->shade[6], &border_normal, 0.95);
+ murrine_shade (&fill, &highlight, custom_highlight_ratio);
+
+ cairo_translate (cr, x, y);
+ cairo_set_line_width (cr, 1.0);
+
+ if (widget->xthickness > 1)
+ xoffset = 1;
+ if (widget->ythickness > 1)
+ yoffset = 1;
+
+ /* Start drawing the inset/shadow */
+ if (!widget->active && !widget->disabled)
+ {
+ murrine_rounded_rectangle (cr, xoffset, yoffset, width-(xoffset*2), height-(yoffset*2), widget->roundness, widget->corners);
+ murrine_set_color_rgba (cr, widget->disabled ? &border_disabled : &border_normal, 0.18);
+ cairo_stroke (cr);
+ }
+ else
+ murrine_draw_inset (cr, &widget->parentbg, 0.5, 0.5, width-1, height-1, widget->roundness+1, widget->corners);
+
+ murrine_mix_color (widget->disabled ? &border_disabled : &border_normal , &fill, 0.4,
+ widget->disabled ? &border_disabled : &border_normal);
+
+ /* Default button */
+ if (widget->is_default)
+ {
+ murrine_rounded_rectangle (cr, xoffset, yoffset, width-(xoffset*2), height-(yoffset*2), widget->roundness, widget->corners);
+ murrine_set_color_rgba (cr, &colors->spot[1], 0.5);
+ cairo_stroke (cr);
+ murrine_shade (&border_normal, &border_normal, 0.8);
+ }
+
+ /* Draw the bg */
+ if (widget->roundness < 2)
+ cairo_rectangle (cr, xoffset + 1, yoffset + 1, width-(xoffset*2)-2, height-(yoffset*2)-2);
+ else
+ murrine_rounded_rectangle (cr, xoffset+0.5, yoffset+0.5, width-(xoffset*2)-1, height-(yoffset*2)-1, widget->roundness+1, widget->corners);
+ murrine_set_gradient (cr, &fill, mrn_gradient_custom, xoffset+1, yoffset+1, 0, height-(yoffset*2)-2, widget->mrn_gradient.gradients, FALSE);
+
+ cairo_save (cr);
+ if (widget->roundness > 1)
+ cairo_clip_preserve (cr);
+
+ int curve_pos = 1;
+ if (widget->glazestyle != 4)
+ curve_pos = 2;
+
+ /* Draw the glass effect */
+ if (widget->glazestyle > 0)
+ {
+ cairo_set_fill_rule (cr, CAIRO_FILL_RULE_EVEN_ODD);
+ widget->glazestyle == 2 ? cairo_fill_preserve (cr) : cairo_fill (cr);
+ if (widget->glazestyle < 3)
+ murrine_draw_curved_highlight (cr, curve_pos, width, height);
+ else
+ murrine_draw_curved_highlight_top (cr, curve_pos, width, height);
+ }
+ else
+ {
+ cairo_fill (cr);
+ murrine_draw_flat_highlight (cr, xoffset + 1, yoffset + 1, width-(xoffset*2)-2, height-(yoffset*2)-2);
+ }
+
+ murrine_set_gradient (cr, &highlight, mrn_gradient_custom, xoffset+1, yoffset+1, 0, height-(yoffset*2)-2, widget->mrn_gradient.gradients, TRUE);
+ cairo_fill (cr);
+
+ if (widget->glazestyle == 4)
+ {
+ murrine_draw_curved_highlight_bottom (cr, curve_pos, width, height);
+ MurrineRGB shadow;
+ murrine_shade (&fill, &shadow, 1.0/custom_highlight_ratio);
+ murrine_set_gradient (cr, &shadow, mrn_gradient_custom, xoffset+1, yoffset+1, 0, height-(yoffset*2)-2, widget->mrn_gradient.gradients, TRUE);
+ cairo_fill (cr);
+ }
+
+ /* Draw the white inner border */
+ if (widget->glazestyle != 4 && !widget->active)
+ {
+ murrine_shade (&fill, &highlight, widget->innerborder_ratio*custom_highlight_ratio);
+ if (horizontal)
+ {
+ murrine_draw_innerborder (cr, &highlight, &fill, mrn_gradient_custom,
+ xoffset + 1.5, yoffset + 1.5,
+ width-(xoffset*2)-3, height-(yoffset*2)-3,
+ widget->mrn_gradient.gradients, horizontal,
+ widget->glazestyle, widget->roundness, widget->corners);
+ }
+ else
+ {
+ murrine_exchange_axis (cr, &x, &y, &width, &height);
+ murrine_draw_innerborder (cr, &highlight, &fill, mrn_gradient_custom,
+ xoffset + 1.5, yoffset + 1.5,
+ width-(xoffset*2)-3, height-(yoffset*2)-3,
+ widget->mrn_gradient.gradients, horizontal,
+ widget->glazestyle, widget->roundness, widget->corners);
+ murrine_exchange_axis (cr, &x, &y, &width, &height);
+ }
+ }
+ cairo_restore (cr);
+
+ /* Draw pressed button shadow */
+ if (widget->active)
+ {
+ cairo_pattern_t *pattern;
+ MurrineRGB shadow;
+
+ murrine_shade (&fill, &shadow, 0.94);
+
+ cairo_save (cr);
+
+ if (widget->roundness < 2)
+ cairo_rectangle (cr, xoffset + 1, yoffset + 1, width-(xoffset*2)-2, height-(yoffset*2)-2);
+ else
+ clearlooks_rounded_rectangle (cr, xoffset+1, yoffset+1, width-(xoffset*2)-2, height-(yoffset*2)-2, widget->roundness-1,
+ widget->corners & (MRN_CORNER_TOPLEFT | MRN_CORNER_TOPRIGHT | MRN_CORNER_BOTTOMLEFT));
+
+ cairo_clip (cr);
+
+ cairo_rectangle (cr, xoffset+1, yoffset+1, width-(xoffset*2)-2, 3);
+ pattern = cairo_pattern_create_linear (xoffset+1, yoffset+1, xoffset+1, yoffset+4);
+ cairo_pattern_add_color_stop_rgba (pattern, 0.0, shadow.r, shadow.g, shadow.b, 0.58);
+ cairo_pattern_add_color_stop_rgba (pattern, 1.0, shadow.r, shadow.g, shadow.b, 0.0);
+ cairo_set_source (cr, pattern);
+ cairo_fill (cr);
+ cairo_pattern_destroy (pattern);
+
+ cairo_rectangle (cr, xoffset+1, yoffset+1, 3, height-(yoffset*2)-2);
+ pattern = cairo_pattern_create_linear (xoffset+1, yoffset+1, xoffset+4, yoffset+1);
+ cairo_pattern_add_color_stop_rgba (pattern, 0.0, shadow.r, shadow.g, shadow.b, 0.58);
+ cairo_pattern_add_color_stop_rgba (pattern, 1.0, shadow.r, shadow.g, shadow.b, 0.0);
+ cairo_set_source (cr, pattern);
+ cairo_fill (cr);
+ cairo_pattern_destroy (pattern);
+
+ cairo_restore (cr);
+ }
+
+ /* Draw the border */
+ murrine_set_color_rgb (cr, widget->disabled ? &border_disabled : &border_normal);
+ murrine_rounded_rectangle (cr, xoffset+0.5, yoffset+0.5, width-(xoffset*2)-1, height-(yoffset*2)-1, widget->roundness, widget->corners);
+ cairo_stroke (cr);
+}
+
+static void
+murrine_draw_entry (cairo_t *cr,
+ const MurrineColors *colors,
+ const WidgetParameters *widget,
+ int x, int y, int width, int height)
+{
+ const MurrineRGB *base = &colors->base[widget->state_type];
+ MurrineRGB *border;
+ int radius = CLAMP (widget->roundness, 0, 3);
+
+ if (widget->focus)
+ border = (MurrineRGB*)&colors->spot[2];
+ else
+ border = (MurrineRGB*)&colors->shade[widget->disabled ? 4 : 6];
+
+ cairo_translate (cr, x+0.5, y+0.5);
+ cairo_set_line_width (cr, 1.0);
+
+ /* Fill the background (shouldn't have to) */
+ cairo_rectangle (cr, -0.5, -0.5, width, height);
+ murrine_set_color_rgb (cr, &widget->parentbg);
+ cairo_fill (cr);
+
+ /* Fill the entry's base color (why isn't is large enough by default?) */
+ cairo_rectangle (cr, 1.5, 1.5, width-4, height-4);
+ murrine_set_color_rgb (cr, base);
+ cairo_fill (cr);
+
+ murrine_draw_inset (cr, &widget->parentbg, 0, 0, width-1, height-1, radius+1, widget->corners);
+
+ /* Draw the focused border */
+ if (widget->focus)
+ {
+ cairo_rectangle (cr, 2, 2, width-5, height-5);
+ murrine_set_color_rgb (cr, &colors->spot[1]);
+ cairo_stroke(cr);
+ }
+ else
+ {
+ MurrineRGB shadow;
+ murrine_shade (border, &shadow, 0.925);
+
+ cairo_move_to (cr, 2, height-3);
+ cairo_line_to (cr, 2, 2);
+ cairo_line_to (cr, width-3, 2);
+
+ murrine_set_color_rgba (cr, &shadow, widget->disabled ? 0.05 : 0.15);
+ cairo_stroke (cr);
+ }
+
+ /* Draw the border */
+ murrine_set_color_rgb (cr, border);
+ murrine_rounded_rectangle (cr, 1, 1, width-3, height-3, radius, widget->corners);
+ cairo_stroke (cr);
+}
+
+static void
+murrine_draw_spinbutton_down (cairo_t *cr,
+ const MurrineColors *colors,
+ const WidgetParameters *widget,
+ int x, int y, int width, int height)
+{
+ MurrineRGB shadow;
+ murrine_shade (&colors->bg[0], &shadow, 0.8);
+
+ cairo_pattern_t *pattern;
+
+ cairo_translate (cr, x+1, y+1);
+
+ cairo_rectangle (cr, 1, 1, width-4, height-4);
+
+ pattern = cairo_pattern_create_linear (0, 0, 0, height);
+ cairo_pattern_add_color_stop_rgb (pattern, 0.0, shadow.r, shadow.g, shadow.b);
+ cairo_pattern_add_color_stop_rgba (pattern, 1.0, shadow.r, shadow.g, shadow.b, 0.0);
+
+ cairo_set_source (cr, pattern);
+ cairo_fill (cr);
+
+ cairo_pattern_destroy (pattern);
+}
+
+static void
+murrine_scale_draw_gradient (cairo_t *cr,
+ const MurrineRGB *c1,
+ const MurrineRGB *c2,
+ int x, int y, int width, int height,
+ boolean alpha)
+{
+ if (alpha)
+ murrine_set_color_rgba (cr, c1, 0.4);
+ else
+ murrine_set_color_rgb (cr, c1);
+
+ cairo_rectangle (cr, x, y, width, height);
+ cairo_fill (cr);
+
+ cairo_rectangle (cr, x, y, width, height);
+ murrine_set_color_rgba (cr, c2, 0.8);
+ cairo_stroke (cr);
+}
+
+static void
+murrine_draw_scale_trough (cairo_t *cr,
+ const MurrineColors *colors,
+ const WidgetParameters *widget,
+ const SliderParameters *slider,
+ int x, int y, int width, int height)
+{
+ int fill_x, fill_y, fill_width, fill_height; /* Fill x,y,w,h */
+ int trough_width, trough_height;
+ double translate_x, translate_y;
+ int fill_size = slider->fill_size;
+ int TROUGH_SIZE = 6;
+
+ if (slider->horizontal)
+ {
+ if (fill_size > width-3)
+ fill_size = width-3;
+
+ fill_x = slider->inverted ? width - fill_size - 3 : 0;
+ fill_y = 0;
+ fill_width = fill_size;
+ fill_height = TROUGH_SIZE-2;
+
+ trough_width = width-3;
+ trough_height = TROUGH_SIZE-2;
+
+ translate_x = x + 0.5;
+ translate_y = y + 0.5 + (height/2) - (TROUGH_SIZE/2);
+ }
+ else
+ {
+ if (fill_size > height-3)
+ fill_size = height-3;
+
+ fill_x = 0;
+ fill_y = slider->inverted ? height - fill_size - 3 : 0;
+ fill_width = TROUGH_SIZE-2;
+ fill_height = fill_size;
+
+ trough_width = TROUGH_SIZE-2;
+ trough_height = height-3;
+
+ translate_x = x + 0.5 + (width/2) - (TROUGH_SIZE/2);
+ translate_y = y + 0.5;
+ }
+
+ cairo_set_line_width (cr, 1.0);
+ cairo_translate (cr, translate_x, translate_y);
+
+ murrine_draw_inset (cr, &widget->parentbg, 0, 0, trough_width+2, trough_height+2, 0, 0);
+
+ cairo_translate (cr, 1, 1);
+
+ murrine_scale_draw_gradient (cr, &colors->shade[1],
+ &colors->shade[4], /* border */
+ 0, 0, trough_width, trough_height,
+ TRUE);
+
+ murrine_scale_draw_gradient (cr, &colors->spot[1],
+ &colors->spot[2], /* border */
+ fill_x, fill_y, fill_width, fill_height,
+ FALSE);
+}
+
+static void
+murrine_draw_slider_handle (cairo_t *cr,
+ const MurrineColors *colors,
+ const WidgetParameters *widget,
+ int x, int y, int width, int height,
+ boolean horizontal)
+{
+ MurrineRGB handle;
+ murrine_shade (&colors->shade[6], &handle, 0.95);
+
+ murrine_mix_color (&handle, &colors->bg[widget->state_type], 0.4, &handle);
+
+ if (!horizontal)
+ {
+ rotate_mirror_translate (cr, M_PI/2, x, y, FALSE, FALSE);
+ int tmp = height; height = width; width = tmp;
+ }
+
+ int num_handles = 2;
+ if (width%2 != 0)
+ num_handles = 3;
+
+ int bar_x = width/2 - num_handles;
+ cairo_translate (cr, 0.5, 0.5);
+ int i;
+ for (i=0; i<num_handles; i++)
+ {
+ cairo_move_to (cr, bar_x, 3.5);
+ cairo_line_to (cr, bar_x, height-4.5);
+ murrine_set_color_rgb (cr, &handle);
+ cairo_stroke (cr);
+ bar_x += 3;
+ }
+}
+
+static void
+murrine_draw_progressbar_trough (cairo_t *cr,
+ const MurrineColors *colors,
+ const WidgetParameters *widget,
+ int x, int y, int width, int height)
+{
+ const MurrineRGB *border = &colors->shade[3];
+
+ cairo_set_line_width (cr, 1.0);
+
+ /* Fill with bg color */
+ cairo_rectangle (cr, x, y, width, height);
+ murrine_set_color_rgb (cr, &colors->bg[widget->state_type]);
+ cairo_fill (cr);
+
+ /* Create trough box */
+ cairo_rectangle (cr, x+1, y+1, width-2, height-2);
+ murrine_set_color_rgba (cr, &colors->shade[1], 0.4);
+ cairo_fill (cr);
+
+ /* Draw border */
+ cairo_rectangle (cr, x+0.5, y+0.5, width-1, height-1);
+ murrine_set_color_rgba (cr, border, 0.8);
+ cairo_stroke (cr);
+}
+
+static void
+murrine_draw_progressbar_fill (cairo_t *cr,
+ const MurrineColors *colors,
+ const WidgetParameters *widget,
+ const ProgressBarParameters *progressbar,
+ int x, int y, int width, int height,
+ gint offset)
+{
+ boolean is_horizontal = progressbar->orientation < 2;
+ double tile_pos = 0;
+ double stroke_width;
+ int x_step;
+ const MurrineRGB *fill = &colors->spot[1];
+ const MurrineRGB *border = &colors->spot[2];
+ MurrineRGB highlight;
+
+ murrine_shade (fill, &highlight, widget->highlight_ratio);
+
+ cairo_rectangle (cr, x, y, width, height);
+
+ if (is_horizontal)
+ {
+ if (progressbar->orientation == MRN_ORIENTATION_LEFT_TO_RIGHT)
+ rotate_mirror_translate (cr, 0, x, y, FALSE, FALSE);
+ else
+ rotate_mirror_translate (cr, 0, x+width, y, TRUE, FALSE);
+ }
+ else
+ {
+ int tmp = height; height = width; width = tmp;
+
+ x = x + 1;
+ y = y - 1;
+ width = width + 2;
+ height = height - 2;
+
+ if (progressbar->orientation == MRN_ORIENTATION_TOP_TO_BOTTOM)
+ rotate_mirror_translate (cr, M_PI/2, x, y, FALSE, FALSE);
+ else
+ rotate_mirror_translate (cr, M_PI/2, x, y+width, TRUE, FALSE);
+ }
+
+ cairo_save (cr);
+ cairo_clip (cr);
+
+ stroke_width = height*2;
+ x_step = (((float)stroke_width/10)*offset);
+ cairo_set_line_width (cr, 1.0);
+ cairo_save (cr);
+ cairo_rectangle (cr, 1.5, 0.5, width-2, height-1);
+
+ /* Draw fill */
+ murrine_set_gradient (cr, fill, widget->mrn_gradient, 1.5, 0.5, 0, height-1, widget->mrn_gradient.gradients, FALSE);
+
+ /* Draw the glass effect */
+ if (widget->glazestyle > 0)
+ {
+ widget->glazestyle == 2 ? cairo_fill_preserve (cr) : cairo_fill (cr);
+ if (widget->glazestyle < 3)
+ murrine_draw_curved_highlight (cr, 1, width, height);
+ else
+ murrine_draw_curved_highlight_top (cr, 1, width, height);
+ }
+ else
+ {
+ cairo_fill (cr);
+ murrine_draw_flat_highlight (cr, 1.5, 0.5, width-2, height);
+ }
+
+ murrine_set_gradient (cr, &highlight, widget->mrn_gradient, 1.5, 0.5, 0, height-1, widget->mrn_gradient.gradients, TRUE);
+ cairo_fill (cr);
+
+ if (widget->glazestyle == 4)
+ {
+ murrine_draw_curved_highlight_bottom (cr, 1, width, height+1);
+ MurrineRGB shadow;
+ murrine_shade (fill, &shadow, 1.0/widget->highlight_ratio);
+ murrine_set_gradient (cr, &shadow, widget->mrn_gradient, 1.5, 0.5, 0, height-1, widget->mrn_gradient.gradients, TRUE);
+ cairo_fill (cr);
+ }
+
+ murrine_shade (fill, &highlight, widget->highlight_ratio*widget->innerborder_ratio);
+ murrine_draw_innerborder (cr, &highlight, fill, widget->mrn_gradient,
+ 2.5, 1.5,
+ width-5, height-3,
+ widget->mrn_gradient.gradients, TRUE,
+ widget->glazestyle, 0, MRN_CORNER_NONE);
+
+ /* Draw strokes */
+ while (tile_pos <= width+x_step-2)
+ {
+ cairo_move_to (cr, stroke_width/2-x_step, 0);
+ cairo_line_to (cr, stroke_width-x_step, 0);
+ cairo_line_to (cr, stroke_width/2-x_step, height);
+ cairo_line_to (cr, -x_step, height);
+
+ cairo_translate (cr, stroke_width, 0);
+ tile_pos += stroke_width;
+ }
+
+ murrine_set_color_rgba (cr, border, 0.15);
+ cairo_fill (cr);
+ cairo_restore (cr);
+
+ /* Draw the border */
+ murrine_set_color_rgba (cr, border, 0.8);
+ cairo_rectangle (cr, 1.5, 0.5, width-3, height-1);
+ cairo_stroke (cr);
+}
+
+static void
+murrine_draw_optionmenu (cairo_t *cr,
+ const MurrineColors *colors,
+ const WidgetParameters *widget,
+ const OptionMenuParameters *optionmenu,
+ int x, int y, int width, int height)
+{
+ int offset = widget->ythickness + 1;
+
+ boolean horizontal = TRUE;
+ if (((float)width/height<0.5) || (widget->glazestyle > 0 && width<height))
+ horizontal = FALSE;
+
+ widget->style_functions->draw_button (cr, colors, widget, x, y, width, height, horizontal);
+
+ /* Draw the separator */
+ MurrineRGB *dark = (MurrineRGB*)&colors->shade[6];
+
+ cairo_set_line_width (cr, 1.0);
+ cairo_translate (cr, optionmenu->linepos+0.5, 1);
+
+ cairo_move_to (cr, 0.0, offset);
+ cairo_line_to (cr, 0.0, height - offset - widget->ythickness + 1);
+ murrine_set_color_rgba (cr, dark, 0.4);
+ cairo_stroke (cr);
+}
+
+static void
+murrine_draw_menubar (cairo_t *cr,
+ const MurrineColors *colors,
+ const WidgetParameters *widget,
+ int x, int y, int width, int height,
+ int menubarstyle)
+{
+ cairo_translate (cr, x, y);
+ cairo_rectangle (cr, 0, 0, width, height);
+ const MurrineRGB *fill = &colors->bg[0];
+
+ if (menubarstyle == 1) /* Glass menubar */
+ {
+ MurrineRGB highlight;
+ murrine_set_gradient (cr, fill, widget->mrn_gradient, 0, 0, 0, height, widget->mrn_gradient.gradients, FALSE);
+ murrine_shade (fill, &highlight, widget->highlight_ratio);
+ /* The glass effect */
+ if (widget->glazestyle > 0)
+ {
+ widget->glazestyle == 2 ? cairo_fill_preserve (cr) : cairo_fill (cr);
+ if (widget->glazestyle < 3)
+ murrine_draw_curved_highlight (cr, 0, width, height);
+ else
+ murrine_draw_curved_highlight_top (cr, 0, width, height);
+ }
+ else
+ {
+ cairo_fill (cr);
+ murrine_draw_flat_highlight (cr, 0, 0, width, height);
+ }
+
+ murrine_set_gradient (cr, &highlight, widget->mrn_gradient, 0, 0, 0, height, widget->mrn_gradient.gradients, TRUE);
+ cairo_fill (cr);
+
+ if (widget->glazestyle == 4)
+ {
+ murrine_draw_curved_highlight_bottom (cr, 0, width, height);
+ MurrineRGB shadow;
+ murrine_shade (fill, &shadow, 1.0/widget->highlight_ratio);
+ murrine_set_color_rgb (cr, &shadow);
+ cairo_fill (cr);
+ }
+
+ if (widget->glazestyle == 2)
+ {
+ murrine_draw_innerborder (cr, &highlight, fill, widget->mrn_gradient,
+ 1.5, 1.5,
+ width-3, height-3,
+ widget->mrn_gradient.gradients, TRUE,
+ widget->glazestyle, widget->roundness, widget->corners);
+ }
+ }
+ else if (menubarstyle == 2) /* Gradient menubar */
+ {
+ cairo_pattern_t *pattern;
+ MurrineRGB lower;
+ murrine_shade (fill, &lower, 0.95);
+ pattern = cairo_pattern_create_linear (0, 0, 0, height);
+ if (!widget->mrn_gradient.use_rgba)
+ {
+ cairo_pattern_add_color_stop_rgb (pattern, 0.0, fill->r, fill->g, fill->b);
+ cairo_pattern_add_color_stop_rgb (pattern, 1.0, lower.r, lower.g, lower.b);
+ }
+ else
+ {
+ cairo_pattern_add_color_stop_rgba (pattern, 0.0, fill->r, fill->g, fill->b, 0.7);
+ cairo_pattern_add_color_stop_rgba (pattern, 1.0, lower.r, lower.g, lower.b, 0.7);
+ }
+ cairo_set_source (cr, pattern);
+ cairo_fill (cr);
+ cairo_pattern_destroy (pattern);
+ }
+ else if (menubarstyle == 3) /* Striped menubar */
+ {
+ cairo_pattern_t *pattern;
+ MurrineRGB low, top;
+ murrine_shade (fill, &top, 0.9);
+ murrine_shade (fill, &low, 1.1);
+ pattern = cairo_pattern_create_linear (0, 0, 0, height);
+ cairo_pattern_add_color_stop_rgb (pattern, 0.0, top.r, top.g, top.b);
+ cairo_pattern_add_color_stop_rgb (pattern, 1.0, low.r, low.g, low.b);
+ cairo_set_source (cr, pattern);
+ cairo_fill (cr);
+ cairo_pattern_destroy (pattern);
+ int counter = -height;
+ cairo_set_line_width (cr, 1.0);
+ murrine_shade (&low, &low, 0.9);
+ murrine_set_color_rgb (cr, &low);
+ while (counter < width)
+ {
+ cairo_move_to (cr, counter, height);
+ cairo_line_to (cr, counter+height, 0);
+ cairo_stroke (cr);
+ counter += 5;
+ }
+ }
+ else /* Flat menubar */
+ {
+ murrine_set_color_rgb (cr, fill);
+ cairo_fill (cr);
+ }
+
+ /* Draw bottom line */
+ if (menubarstyle == 1 && widget->glazestyle == 2)
+ cairo_rectangle (cr, 0.5, 0.5, width-1, height-1);
+#ifndef HAVE_MACMENU
+ else
+ {
+ cairo_set_line_width (cr, 1.0);
+ cairo_move_to (cr, 0, height-0.5);
+ cairo_line_to (cr, width, height-0.5);
+ }
+ murrine_set_color_rgb (cr, &colors->shade[3]);
+ cairo_stroke (cr);
+#endif
+}
+
+static void
+murrine_get_frame_gap_clip (int x, int y, int width, int height,
+ const FrameParameters *frame,
+ MurrineRectangle *bevel,
+ MurrineRectangle *border)
+{
+ if (frame->gap_side == MRN_GAP_TOP)
+ {
+ MURRINE_RECTANGLE_SET ((*bevel), 1.5 + frame->gap_x, -0.5,
+ frame->gap_width - 3, 2.0);
+ MURRINE_RECTANGLE_SET ((*border), 0.5 + frame->gap_x, -0.5,
+ frame->gap_width - 2, 2.0);
+ }
+ else if (frame->gap_side == MRN_GAP_BOTTOM)
+ {
+ MURRINE_RECTANGLE_SET ((*bevel), 1.5 + frame->gap_x, height - 2.5,
+ frame->gap_width - 3, 2.0);
+ MURRINE_RECTANGLE_SET ((*border), 0.5 + frame->gap_x, height - 1.5,
+ frame->gap_width - 2, 2.0);
+ }
+ else if (frame->gap_side == MRN_GAP_LEFT)
+ {
+ MURRINE_RECTANGLE_SET ((*bevel), -0.5, 1.5 + frame->gap_x,
+ 2.0, frame->gap_width - 3);
+ MURRINE_RECTANGLE_SET ((*border), -0.5, 0.5 + frame->gap_x,
+ 1.0, frame->gap_width - 2);
+ }
+ else if (frame->gap_side == MRN_GAP_RIGHT)
+ {
+ MURRINE_RECTANGLE_SET ((*bevel), width - 2.5, 1.5 + frame->gap_x,
+ 2.0, frame->gap_width - 3);
+ MURRINE_RECTANGLE_SET ((*border), width - 1.5, 0.5 + frame->gap_x,
+ 1.0, frame->gap_width - 2);
+ }
+}
+
+static void
+murrine_draw_frame (cairo_t *cr,
+ const MurrineColors *colors,
+ const WidgetParameters *widget,
+ const FrameParameters *frame,
+ int x, int y, int width, int height)
+{
+ MurrineRGB *border = frame->border;
+ MurrineRectangle bevel_clip;
+ MurrineRectangle frame_clip;
+
+ const MurrineRGB *dark = &colors->shade[3];
+
+ MurrineRGB highlight, shadow_color;
+ murrine_shade (&colors->bg[0], &highlight, 1.04);
+ murrine_shade (&colors->bg[0], &shadow_color, 0.96);
+
+ if (frame->shadow == MRN_SHADOW_NONE)
+ return;
+
+ if (frame->gap_x != -1)
+ murrine_get_frame_gap_clip (x, y, width, height,
+ frame, &bevel_clip, &frame_clip);
+
+ cairo_set_line_width (cr, 1.0);
+ cairo_translate (cr, x+0.5, y+0.5);
+
+ /* save everything */
+ cairo_save (cr);
+
+ /* Set clip for the bevel */
+ if (frame->gap_x != -1)
+ {
+ /* Set clip for gap */
+ cairo_set_fill_rule (cr, CAIRO_FILL_RULE_EVEN_ODD);
+ cairo_rectangle (cr, -0.5, -0.5, width, height);
+ cairo_rectangle (cr, bevel_clip.x, bevel_clip.y, bevel_clip.width, bevel_clip.height);
+ cairo_clip (cr);
+ }
+
+ /* Draw the bevel */
+ if (frame->shadow == MRN_SHADOW_ETCHED_IN || frame->shadow == MRN_SHADOW_ETCHED_OUT)
+ {
+ murrine_set_color_rgb (cr, &highlight);
+ if (frame->shadow == MRN_SHADOW_ETCHED_IN)
+ murrine_rounded_rectangle (cr, 1, 1, width-2, height-2, widget->roundness, widget->corners);
+ else
+ murrine_rounded_rectangle (cr, 0, 0, width-2, height-2, widget->roundness, widget->corners);
+ cairo_stroke (cr);
+ }
+ else if (frame->shadow != MRN_SHADOW_NONE && frame->shadow != MRN_SHADOW_FLAT)
+ {
+ ShadowParameters shadow;
+ shadow.corners = widget->corners;
+ shadow.shadow = frame->shadow;
+ cairo_move_to (cr, 1, height-2);
+ cairo_line_to (cr, 1, 1);
+ cairo_line_to (cr, width-1.5, 1);
+ if (frame->shadow & MRN_SHADOW_OUT)
+ murrine_set_color_rgb (cr, &highlight);
+ else
+ murrine_set_color_rgb (cr, &shadow_color);
+ cairo_stroke (cr);
+ cairo_move_to (cr, width-2, 1.5);
+ cairo_line_to (cr, width-2, height-2);
+ cairo_line_to (cr, 0, height-2);
+ if (frame->shadow & MRN_SHADOW_OUT)
+ murrine_set_color_rgb (cr, &shadow_color);
+ else
+ murrine_set_color_rgb (cr, &highlight);
+ cairo_stroke (cr);
+ }
+
+ /* restore the previous clip region */
+ cairo_restore (cr);
+ cairo_save (cr);
+ if (frame->gap_x != -1)
+ {
+ /* Set clip for gap */
+ cairo_set_fill_rule (cr, CAIRO_FILL_RULE_EVEN_ODD);
+ cairo_rectangle (cr, -0.5, -0.5, width, height);
+ cairo_rectangle (cr, frame_clip.x, frame_clip.y, frame_clip.width, frame_clip.height);
+ cairo_clip (cr);
+ }
+
+ /* Draw frame */
+ if (frame->shadow == MRN_SHADOW_ETCHED_IN || frame->shadow == MRN_SHADOW_ETCHED_OUT)
+ {
+ murrine_set_color_rgb (cr, dark);
+ if (frame->shadow == MRN_SHADOW_ETCHED_IN)
+ murrine_rounded_rectangle (cr, 0, 0, width-2, height-2, widget->roundness, widget->corners);
+ else
+ murrine_rounded_rectangle (cr, 1, 1, width-2, height-2, widget->roundness, widget->corners);
+ }
+ else
+ {
+ murrine_set_color_rgb (cr, border);
+ murrine_rounded_rectangle (cr, 0, 0, width-1, height-1, widget->roundness, widget->corners);
+ }
+ cairo_stroke (cr);
+ cairo_restore (cr);
+}
+
+static void
+murrine_draw_tab (cairo_t *cr,
+ const MurrineColors *colors,
+ const WidgetParameters *widget,
+ const TabParameters *tab,
+ int x, int y, int width, int height)
+{
+ const float RADIUS = 3.0;
+ int corners;
+ double strip_size;
+ const MurrineRGB *stripe_fill = &colors->spot[1];
+ const MurrineRGB *stripe_border = &colors->spot[2];
+ const MurrineRGB *fill;
+ MurrineRGB *border1;
+ cairo_pattern_t* pattern;
+
+ fill = &colors->bg[widget->state_type];
+
+ if (!widget->active)
+ border1 = (MurrineRGB*)&colors->shade[5];
+ else
+ border1 = (MurrineRGB*)&colors->shade[4];
+
+ /* Set clip */
+ cairo_rectangle (cr, x, y, width, height);
+ cairo_clip (cr);
+ cairo_new_path (cr);
+
+ /* Translate and set line width */
+ cairo_set_line_width (cr, 1.0);
+ cairo_translate (cr, x+0.5, y+0.5);
+
+ /* Make the tabs slightly bigger than they should be, to create a gap */
+ /* And calculate the strip size too, while you're at it */
+ if (tab->gap_side == MRN_GAP_TOP || tab->gap_side == MRN_GAP_BOTTOM)
+ {
+ height += RADIUS;
+ strip_size = (tab->gap_side == MRN_GAP_TOP ? 2.0/height : 2.0/(height-2));
+
+ if (tab->gap_side == MRN_GAP_TOP)
+ {
+ cairo_translate (cr, 0.0, -3.0); /* gap at the other side */
+ corners = MRN_CORNER_BOTTOMLEFT | MRN_CORNER_BOTTOMRIGHT;
+ }
+ else
+ corners = MRN_CORNER_TOPLEFT | MRN_CORNER_TOPRIGHT;
+ }
+ else
+ {
+ width += RADIUS;
+ strip_size = (tab->gap_side == MRN_GAP_LEFT ? 2.0/width : 2.0/(width-2));
+
+ if (tab->gap_side == MRN_GAP_LEFT)
+ {
+ cairo_translate (cr, -3.0, 0.0); /* gap at the other side */
+ corners = MRN_CORNER_TOPRIGHT | MRN_CORNER_BOTTOMRIGHT;
+ }
+ else
+ corners = MRN_CORNER_TOPLEFT | MRN_CORNER_BOTTOMLEFT;
+ }
+
+ /* Set tab shape */
+ if (widget->roundness < 2)
+ cairo_rectangle (cr, 0, 0, width-1, height-1);
+ else
+ clearlooks_rounded_rectangle (cr, 0, 0, width-1, height-1, widget->roundness, corners);
+
+ /* Draw fill */
+ murrine_set_color_rgb (cr, fill);
+ cairo_fill (cr);
+
+ /* Draw highlight */
+ if (!widget->active)
+ {
+ ShadowParameters shadow;
+
+ shadow.shadow = MRN_SHADOW_OUT;
+ shadow.corners = widget->corners;
+
+ murrine_draw_highlight_and_shade (cr, colors, &shadow,
+ width,
+ height, widget->roundness-1);
+ }
+
+ if (widget->active)
+ {
+ MurrineRGB shade1, shade2, shade3, shade4;
+
+ MurrineGradients mrn_gradient_custom = widget->mrn_gradient;
+ mrn_gradient_custom.gradient_stop_1 = get_decreased_ratio (widget->mrn_gradient.gradient_stop_1, 3.0);
+ mrn_gradient_custom.gradient_stop_2 = get_decreased_ratio (widget->mrn_gradient.gradient_stop_2, 3.0);
+ mrn_gradient_custom.gradient_stop_3 = get_decreased_ratio (widget->mrn_gradient.gradient_stop_3, 3.0);
+ mrn_gradient_custom.gradient_stop_4 = get_decreased_ratio (widget->mrn_gradient.gradient_stop_4, 3.0);
+
+ double custom_highlight_ratio = widget->highlight_ratio;
+ custom_highlight_ratio = get_decreased_ratio (widget->highlight_ratio, 2.0);
+
+ if (mrn_gradient_custom.gradients)
+ {
+ if (mrn_gradient_custom.has_gradient_stop)
+ {
+ murrine_shade (fill, &shade1, mrn_gradient_custom.gradient_stop_1*custom_highlight_ratio);
+ murrine_shade (fill, &shade2, mrn_gradient_custom.gradient_stop_2*custom_highlight_ratio);
+ murrine_shade (fill, &shade3, mrn_gradient_custom.gradient_stop_3);
+ murrine_shade (fill, &shade4, mrn_gradient_custom.gradient_stop_4);
+ }
+ else
+ {
+ murrine_shade (fill, &shade1, 1.1*custom_highlight_ratio);
+ murrine_shade (fill, &shade2, 1.0*custom_highlight_ratio);
+ murrine_shade (fill, &shade3, 1.0);
+ murrine_shade (fill, &shade4, 1.1);;
+ }
+ }
+ else
+ {
+ murrine_shade (fill, &shade1, 1.0*custom_highlight_ratio);
+ murrine_shade (fill, &shade2, 1.0*custom_highlight_ratio);
+ murrine_shade (fill, &shade3, 1.0);
+ murrine_shade (fill, &shade4, 1.0);
+ }
+
+ switch (tab->gap_side)
+ {
+ case MRN_GAP_TOP:
+ pattern = cairo_pattern_create_linear (0, height-2, 0, 0);
+ break;
+ case MRN_GAP_BOTTOM:
+ pattern = cairo_pattern_create_linear (0, 1, 0, height);
+ break;
+ case MRN_GAP_LEFT:
+ pattern = cairo_pattern_create_linear (width-2, 0, 1, 0);
+ break;
+ case MRN_GAP_RIGHT:
+ pattern = cairo_pattern_create_linear (1, 0, width-2, 0);
+ break;
+ }
+
+ if (widget->roundness < 2)
+ cairo_rectangle (cr, 0, 0, width-1, height-1);
+ else
+ clearlooks_rounded_rectangle (cr, 0, 0, width-1, height-1, widget->roundness, corners);
+
+ cairo_pattern_add_color_stop_rgb (pattern, 0.0, shade1.r, shade1.g, shade1.b);
+ cairo_pattern_add_color_stop_rgb (pattern, 0.4, shade2.r, shade2.g, shade2.b);
+ cairo_pattern_add_color_stop_rgb (pattern, 0.4, shade3.r, shade3.g, shade3.b);
+ cairo_pattern_add_color_stop_rgb (pattern, 1.0, shade4.r, shade4.g, shade4.b);
+ cairo_set_source (cr, pattern);
+ cairo_fill (cr);
+ cairo_pattern_destroy (pattern);
+
+ cairo_set_line_width (cr, 1.0);
+ murrine_set_color_rgba (cr, &colors->shade[0], 0.2);
+
+ if (widget->roundness < 2)
+ cairo_rectangle (cr, 1, 1, width-3, height-3);
+ else
+ clearlooks_rounded_rectangle (cr, 1, 1, width-3, height-3, widget->roundness, corners);
+
+ cairo_stroke (cr);
+ }
+ else
+ {
+ /* Draw shade */
+ switch (tab->gap_side)
+ {
+ case MRN_GAP_TOP:
+ pattern = cairo_pattern_create_linear (0, height-2, 0, 0);
+ break;
+ case MRN_GAP_BOTTOM:
+ pattern = cairo_pattern_create_linear (0, 0, 0, height);
+ break;
+ case MRN_GAP_LEFT:
+ pattern = cairo_pattern_create_linear (width-2, 0, 0, 0);
+ break;
+ case MRN_GAP_RIGHT:
+ pattern = cairo_pattern_create_linear (0, 0, width, 0);
+ break;
+ }
+
+ if (widget->roundness < 2)
+ cairo_rectangle (cr, 0, 0, width-1, height-1);
+ else
+ clearlooks_rounded_rectangle (cr, 0, 0, width-1, height-1, widget->roundness, corners);
+
+ cairo_pattern_add_color_stop_rgb (pattern, 0.0, stripe_fill->r, stripe_fill->g, stripe_fill->b);
+ cairo_pattern_add_color_stop_rgb (pattern, strip_size, stripe_fill->r, stripe_fill->g, stripe_fill->b);
+ cairo_pattern_add_color_stop_rgba (pattern, strip_size, fill->r, fill->g, fill->b, 0.0);
+ cairo_set_source (cr, pattern);
+ cairo_fill (cr);
+ cairo_pattern_destroy (pattern);
+ }
+
+ murrine_rounded_rectangle (cr, 0, 0, width-1, height-1, widget->roundness, corners);
+
+ if (widget->active)
+ {
+ murrine_set_color_rgb (cr, border1);
+ cairo_stroke (cr);
+ }
+ else
+ {
+ switch (tab->gap_side)
+ {
+ case MRN_GAP_TOP:
+ pattern = cairo_pattern_create_linear (2, height-2, 2, 2);
+ break;
+ case MRN_GAP_BOTTOM:
+ pattern = cairo_pattern_create_linear (2, 2, 2, height);
+ break;
+ case MRN_GAP_LEFT:
+ pattern = cairo_pattern_create_linear (width-2, 2, 2, 2);
+ break;
+ case MRN_GAP_RIGHT:
+ pattern = cairo_pattern_create_linear (2, 2, width, 2);
+ break;
+ }
+
+ cairo_pattern_add_color_stop_rgb (pattern, 0.0, stripe_border->r, stripe_border->g, stripe_border->b);
+ cairo_pattern_add_color_stop_rgb (pattern, strip_size, stripe_border->r, stripe_border->g, stripe_border->b);
+ cairo_pattern_add_color_stop_rgb (pattern, strip_size, stripe_border->r, stripe_border->g, stripe_border->b);
+ cairo_pattern_add_color_stop_rgb (pattern, 0.8, border1->r, border1->g, border1->b);
+ cairo_set_source (cr, pattern);
+ cairo_stroke (cr);
+ cairo_pattern_destroy (pattern);
+ }
+}
+
+static void
+murrine_draw_separator (cairo_t *cr,
+ const MurrineColors *colors,
+ const WidgetParameters *widget,
+ const SeparatorParameters *separator,
+ int x, int y, int width, int height)
+{
+ const MurrineRGB *dark = &colors->shade[3];
+ MurrineRGB highlight;
+ murrine_shade (dark, &highlight, 1.3);
+
+ if (separator->horizontal)
+ {
+ cairo_set_line_width (cr, 1.0);
+ cairo_translate (cr, x, y+0.5);
+
+ cairo_move_to (cr, 0.0, 0.0);
+ cairo_line_to (cr, width+1, 0.0);
+ murrine_set_color_rgb (cr, dark);
+ cairo_stroke (cr);
+
+#ifndef HAVE_MACMENU
+ cairo_move_to (cr, 0.0, 1.0);
+ cairo_line_to (cr, width, 1.0);
+ murrine_set_color_rgb (cr, &highlight);
+ cairo_stroke (cr);
+#endif
+ }
+ else
+ {
+ cairo_set_line_width (cr, 1.0);
+ cairo_translate (cr, x+0.5, y);
+
+ cairo_move_to (cr, 0.0, 0.0);
+ cairo_line_to (cr, 0.0, height);
+ murrine_set_color_rgb (cr, dark);
+ cairo_stroke (cr);
+
+#ifndef HAVE_MACMENU
+ cairo_move_to (cr, 1.0, 0.0);
+ cairo_line_to (cr, 1.0, height);
+ murrine_set_color_rgb (cr, &highlight);
+ cairo_stroke (cr);
+#endif
+ }
+}
+
+static void
+murrine_draw_combo_separator (cairo_t *cr,
+ const MurrineColors *colors,
+ const WidgetParameters *widget,
+ int x, int y, int width, int height)
+{
+ const MurrineRGB *dark = &colors->shade[6];
+
+ cairo_set_line_width (cr, 1.0);
+ cairo_translate (cr, x+0.5, y);
+
+ cairo_move_to (cr, 0.0, 0.0);
+ cairo_line_to (cr, 0.0, height+1);
+ murrine_set_color_rgba (cr, dark, 0.4);
+ cairo_stroke (cr);
+}
+
+static void
+murrine_draw_list_view_header (cairo_t *cr,
+ const MurrineColors *colors,
+ const WidgetParameters *widget,
+ const ListViewHeaderParameters *header,
+ int x, int y, int width, int height)
+{
+ const MurrineRGB *fill = &colors->bg[widget->state_type];
+ const MurrineRGB *border = &colors->shade[3];
+ MurrineRGB highlight;
+ murrine_shade (border, &highlight, 1.3);
+
+ cairo_translate (cr, x, y);
+ cairo_set_line_width (cr, 1.0);
+
+ if (header->order == MRN_ORDER_FIRST)
+ {
+ cairo_move_to (cr, 0.5, height-1);
+ cairo_line_to (cr, 0.5, 0.5);
+ }
+ else
+ cairo_move_to (cr, 0.0, 0.5);
+
+ cairo_line_to (cr, width, 0.5);
+ murrine_set_color_rgb (cr, &highlight);
+ cairo_stroke (cr);
+
+ /* Effects */
+ if (header->style > 0)
+ {
+ MurrineRGB highlight_header;
+ murrine_shade (fill, &highlight_header, widget->highlight_ratio);
+ /* Glassy header */
+ if (header->style == 1)
+ {
+ cairo_rectangle (cr, 0, 0, width, height);
+ murrine_set_gradient (cr, fill, widget->mrn_gradient, 0, 0, 0, height, widget->mrn_gradient.gradients, FALSE);
+ /* Glass effect */
+ if (widget->glazestyle > 0)
+ {
+ widget->glazestyle == 2 ? cairo_fill_preserve (cr) : cairo_fill (cr);
+ if (widget->glazestyle < 3)
+ murrine_draw_curved_highlight (cr, 0, width, height);
+ else
+ murrine_draw_curved_highlight_top (cr, 0, width, height);
+ }
+ else
+ {
+ cairo_fill (cr);
+ murrine_draw_flat_highlight (cr, 0 , 0 , width, height);
+ }
+
+ murrine_set_gradient (cr, &highlight_header, widget->mrn_gradient, 0, 0, 0, height, widget->mrn_gradient.gradients, TRUE);
+ cairo_fill (cr);
+
+ if (widget->glazestyle == 4)
+ {
+ murrine_draw_curved_highlight_bottom (cr, 0, width, height);
+ MurrineRGB shadow;
+ murrine_shade (fill, &shadow, 1.0/widget->highlight_ratio);
+ murrine_set_gradient (cr, &shadow, widget->mrn_gradient, 0, 0, 0, height, widget->mrn_gradient.gradients, TRUE);
+ cairo_fill (cr);
+ }
+
+ if (widget->glazestyle == 2)
+ {
+ murrine_draw_innerborder (cr, &highlight, fill, widget->mrn_gradient,
+ 0.5, 0.5,
+ width-2, height-2,
+ widget->mrn_gradient.gradients, TRUE,
+ widget->glazestyle, widget->roundness, widget->corners);
+ }
+ }
+ /* Raised */
+ else if (header->style == 2)
+ {
+ border = (MurrineRGB*)&colors->shade[4];
+ MurrineRGB shadow_header;
+ murrine_shade (fill, &shadow_header, 0.925);
+
+ if (!widget->mrn_gradient.gradients)
+ {
+ murrine_set_color_rgb (cr, &shadow_header);
+ cairo_rectangle (cr, 0.0, height-3.0, width, 2.0);
+ }
+ else
+ {
+ cairo_pattern_t *pattern;
+ pattern = cairo_pattern_create_linear (0.0, height-4.0, 0.0, height-1.0);
+ cairo_pattern_add_color_stop_rgba (pattern, 0.0, shadow_header.r, shadow_header.g, shadow_header.b, 0.0);
+ cairo_pattern_add_color_stop_rgb (pattern, 1.0, shadow_header.r, shadow_header.g, shadow_header.b);
+ cairo_set_source (cr, pattern);
+ cairo_pattern_destroy (pattern);
+ cairo_rectangle (cr, 0.0, height-4.0, width, 3.0);
+ }
+ cairo_fill (cr);
+ }
+ }
+ /* Draw bottom border */
+ cairo_move_to (cr, 0.0, height-0.5);
+ cairo_line_to (cr, width, height-0.5);
+ murrine_set_color_rgb (cr, border);
+ cairo_stroke (cr);
+
+ /* Draw resize grip */
+ if (header->order != MRN_ORDER_LAST || header->resizable)
+ {
+ if (header->style == 1 && widget->glazestyle > 0)
+ {
+ cairo_set_line_width (cr, 1.0);
+ cairo_translate (cr, width-0.5, 0);
+
+ cairo_move_to (cr, 0, 0);
+ cairo_line_to (cr, 0, height);
+ murrine_set_color_rgb (cr, border);
+ cairo_stroke (cr);
+ }
+ else
+ {
+ SeparatorParameters separator;
+ separator.horizontal = FALSE;
+
+ murrine_draw_separator (cr, colors, widget, &separator, width-1.5, 4.0, 2, height-8.0);
+ }
+ }
+}
+
+/* We can't draw transparent things here, since it will be called on the same
+ * surface multiple times, when placed on a handlebox_bin or dockitem_bin */
+static void
+murrine_draw_toolbar (cairo_t *cr,
+ const MurrineColors *colors,
+ const WidgetParameters *widget,
+ const ToolbarParameters *toolbar,
+ int x, int y, int width, int height)
+{
+ const MurrineRGB *dark = &colors->shade[3];
+ const MurrineRGB *fill = &colors->bg[0];
+ MurrineRGB top;
+ murrine_shade (dark, &top, 1.3);
+
+ cairo_set_line_width (cr, 1.0);
+ cairo_translate (cr, x, y);
+ cairo_rectangle (cr, 0, 0, width, height);
+
+#ifdef HAVE_MACMENU
+ murrine_set_color_rgb (cr, fill);
+ cairo_fill (cr);
+#else
+ /* Glass toolbar */
+ if (toolbar->style == 1)
+ {
+ MurrineRGB highlight;
+ murrine_set_gradient (cr, fill, widget->mrn_gradient, 0, 0, 0, height, widget->mrn_gradient.gradients, FALSE);
+ murrine_shade (fill, &highlight, widget->highlight_ratio);
+ /* Glass effect */
+ if (widget->glazestyle > 0)
+ {
+ widget->glazestyle == 2 ? cairo_fill_preserve (cr) : cairo_fill (cr);
+ if (widget->glazestyle < 3)
+ murrine_draw_curved_highlight (cr, 0, width, height);
+ else
+ murrine_draw_curved_highlight_top (cr, 0, width, height);
+ }
+ else
+ {
+ cairo_fill (cr);
+ murrine_draw_flat_highlight (cr, 0, 0, width, height);
+ }
+
+ murrine_set_gradient (cr, &highlight, widget->mrn_gradient, 0, 0, 0, height, widget->mrn_gradient.gradients, TRUE);
+ cairo_fill (cr);
+
+ if (widget->glazestyle == 4)
+ {
+ murrine_draw_curved_highlight_bottom (cr, 0, width, height);
+ MurrineRGB shadow;
+ murrine_shade (fill, &shadow, 1.0/widget->highlight_ratio);
+ murrine_set_color_rgb (cr, &shadow);
+ cairo_fill (cr);
+ }
+ }
+ else if (toolbar->style == 2)
+ {
+ cairo_pattern_t *pattern;
+ MurrineRGB lower;
+ murrine_shade (fill, &lower, 0.95);
+ pattern = cairo_pattern_create_linear (0, 0, 0, height);
+ cairo_pattern_add_color_stop_rgb (pattern, 0.0, fill->r, fill->g, fill->b);
+ cairo_pattern_add_color_stop_rgb (pattern, 1.0, lower.r, lower.g, lower.b);
+ cairo_set_source (cr, pattern);
+ cairo_fill (cr);
+ cairo_pattern_destroy (pattern);
+ }
+ else /* Flat toolbar */
+ {
+ murrine_set_color_rgb (cr, fill);
+ cairo_fill (cr);
+ /* Draw highlight */
+ if (!toolbar->topmost)
+ {
+ cairo_move_to (cr, 0, 0.5);
+ cairo_line_to (cr, width, 0.5);
+ murrine_set_color_rgb (cr, &top);
+ cairo_stroke (cr);
+ }
+ }
+#endif
+
+ /* Draw shadow */
+ cairo_move_to (cr, 0, height-0.5);
+ cairo_line_to (cr, width, height-0.5);
+ murrine_set_color_rgb (cr, dark);
+ cairo_stroke (cr);
+}
+
+static void
+murrine_draw_menuitem (cairo_t *cr,
+ const MurrineColors *colors,
+ const WidgetParameters *widget,
+ int x, int y, int width, int height,
+ int menuitemstyle)
+{
+ const MurrineRGB *fill = &colors->spot[1];
+ const MurrineRGB *border = &colors->spot[2];
+ MurrineRGB highlight;
+ murrine_shade (fill, &highlight, widget->highlight_ratio);
+
+ cairo_translate (cr, x, y);
+ cairo_set_line_width (cr, 1.0);
+ if (widget->roundness < 2)
+ cairo_rectangle (cr, 0, 0, width, height);
+ else
+ clearlooks_rounded_rectangle (cr, 0, 0, width, height, widget->roundness, widget->corners);
+ murrine_set_gradient (cr, fill, widget->mrn_gradient, 0, 0, 0, height, widget->mrn_gradient.gradients, FALSE);
+
+ /* Striped */
+ if (menuitemstyle == 2)
+ {
+ cairo_fill (cr);
+ double tile_pos = 0;
+ double stroke_width;
+ int x_step;
+ stroke_width = height*2;
+ cairo_save (cr);
+ x_step = (((float)stroke_width/10));
+ /* Draw strokes */
+ while (tile_pos <= width+x_step-2)
+ {
+ cairo_move_to (cr, stroke_width/2-x_step, 0);
+ cairo_line_to (cr, stroke_width-x_step, 0);
+ cairo_line_to (cr, stroke_width/2-x_step, height);
+ cairo_line_to (cr, -x_step, height);
+ cairo_translate (cr, stroke_width, 0);
+ tile_pos += stroke_width;
+ }
+ murrine_set_color_rgba (cr, border, 0.15);
+ cairo_fill (cr);
+ cairo_restore (cr);
+ }
+ /* Glassy */
+ else if (menuitemstyle != 0)
+ {
+ if (widget->roundness > 1)
+ cairo_clip_preserve (cr);
+ /* Glass effect */
+ if (widget->glazestyle > 0)
+ {
+ widget->glazestyle == 2 ? cairo_fill_preserve (cr) : cairo_fill (cr);
+ if (widget->glazestyle < 3)
+ murrine_draw_curved_highlight (cr, 0, width, height);
+ else
+ murrine_draw_curved_highlight_top (cr, 0, width, height);
+ }
+ else
+ {
+ cairo_fill (cr);
+ murrine_draw_flat_highlight (cr, 0, 0, width, height);
+ }
+ murrine_set_gradient (cr, &highlight, widget->mrn_gradient, 0, 0, 0, height, widget->mrn_gradient.gradients, TRUE);
+ cairo_fill (cr);
+
+ if (widget->glazestyle == 4)
+ {
+ murrine_draw_curved_highlight_bottom (cr, 0, width, height);
+ MurrineRGB shadow;
+ murrine_shade (&colors->spot[1], &shadow, 1.0/widget->highlight_ratio);
+ murrine_set_gradient (cr, &shadow, widget->mrn_gradient, 0, 0, 0, height, widget->mrn_gradient.gradients, TRUE);
+ cairo_fill (cr);
+ }
+
+ if (widget->glazestyle == 2)
+ {
+ murrine_draw_innerborder (cr, &highlight, fill, widget->mrn_gradient,
+ 1.5, 1.5,
+ width-3, height-3,
+ widget->mrn_gradient.gradients, TRUE,
+ widget->glazestyle, widget->roundness, widget->corners);
+ }
+ }
+ else
+ {
+ cairo_fill (cr);
+ murrine_rounded_rectangle (cr, 0.5, 0.5, width-1, height-1, widget->roundness, widget->corners);
+ murrine_set_color_rgba (cr, border, 0.15);
+ cairo_fill_preserve (cr);
+ }
+ murrine_rounded_rectangle (cr, 0.5, 0.5, width-1, height-1, widget->roundness, widget->corners);
+ murrine_set_color_rgba (cr, border, 0.8);
+ cairo_stroke (cr);
+}
+
+static void
+murrine_draw_scrollbar_trough (cairo_t *cr,
+ const MurrineColors *colors,
+ const WidgetParameters *widget,
+ const ScrollBarParameters *scrollbar,
+ int x, int y, int width, int height)
+{
+ const MurrineRGB *bg = &colors->shade[scrollbar->stepperstyle < 1 ? 1 : 0];
+ const MurrineRGB *border = &colors->shade[scrollbar->stepperstyle < 1 ? 3 : 4];
+
+ cairo_set_line_width (cr, 1.0);
+
+ if (scrollbar->horizontal)
+ {
+ int tmp = height;
+ rotate_mirror_translate (cr, M_PI/2, x, y, FALSE, FALSE);
+ height = width;
+ width = tmp;
+ }
+ else
+ {
+ cairo_translate (cr, x, y);
+ }
+
+ /* Draw fill */
+ clearlooks_rounded_rectangle (cr, 1, 0, width-2, height, widget->roundness, widget->corners);
+ murrine_set_color_rgba (cr, bg, 0.4);
+ cairo_fill (cr);
+
+ /* Draw border */
+ murrine_rounded_rectangle (cr, 0.5, 0.5, width-1, height-1, widget->roundness, widget->corners);
+ murrine_set_color_rgba (cr, border, 0.8);
+ cairo_stroke (cr);
+}
+
+static void
+murrine_draw_scrollbar_stepper (cairo_t *cr,
+ const MurrineColors *colors,
+ const WidgetParameters *widget,
+ const ScrollBarParameters *scrollbar,
+ int x, int y, int width, int height)
+{
+ const MurrineRGB *fill = &colors->bg[widget->state_type];
+ MurrineRGB border_normal;
+ MurrineRGB highlight;
+
+ murrine_shade (&colors->shade[6], &border_normal, 0.95);
+ murrine_shade (fill, &highlight, widget->highlight_ratio);
+
+ if (!scrollbar->horizontal)
+ murrine_exchange_axis (cr, &x, &y, &width, &height);
+
+ /* Border color */
+ murrine_mix_color (&border_normal, fill, 0.4, &border_normal);
+
+ cairo_translate (cr, x, y);
+ cairo_set_line_width (cr, 1.0);
+
+ /* Draw the bg */
+ if (widget->roundness < 2)
+ cairo_rectangle (cr, 1, 1, width-2, height-2);
+ else
+ murrine_rounded_rectangle (cr, 0.5, 0.5, width-1, height-1, widget->roundness+1, widget->corners);
+ murrine_set_gradient (cr, fill, widget->mrn_gradient, 1, 1, 0, height-2, widget->mrn_gradient.gradients, FALSE);
+
+ cairo_save (cr);
+
+ int curve_pos = 1;
+ if (widget->glazestyle != 4)
+ curve_pos = 2;
+ /* Draw the glass effect */
+ if (widget->glazestyle > 0)
+ {
+ cairo_set_fill_rule (cr, CAIRO_FILL_RULE_EVEN_ODD);
+ widget->glazestyle == 2 ? cairo_fill_preserve (cr) : cairo_fill (cr);
+ if (widget->glazestyle < 3)
+ murrine_draw_curved_highlight (cr, curve_pos, width, height);
+ else
+ murrine_draw_curved_highlight_top (cr, curve_pos, width, height);
+ }
+ else
+ {
+ cairo_fill (cr);
+ murrine_draw_flat_highlight (cr, 1, 1, width-2, height-2);
+ }
+
+ murrine_set_gradient (cr, &highlight, widget->mrn_gradient, 1, 1, 0, height-2, widget->mrn_gradient.gradients, TRUE);
+ cairo_fill (cr);
+
+ if (widget->glazestyle == 4)
+ {
+ murrine_draw_curved_highlight_bottom (cr, curve_pos, width, height);
+ MurrineRGB shadow;
+ murrine_shade (fill, &shadow, 1.0/widget->highlight_ratio);
+ murrine_set_gradient (cr, &shadow, widget->mrn_gradient, 1, 1, 0, height-2, widget->mrn_gradient.gradients, TRUE);
+ cairo_fill (cr);
+ }
+
+ /* Draw the white inner border */
+ if (widget->glazestyle != 4)
+ {
+ murrine_shade (fill, &highlight, widget->innerborder_ratio*widget->highlight_ratio);
+ murrine_draw_innerborder (cr, &highlight, fill, widget->mrn_gradient,
+ 1.5, 1.5,
+ width-3, height-3,
+ widget->mrn_gradient.gradients, TRUE,
+ widget->glazestyle, widget->roundness, widget->corners);
+ }
+
+ cairo_reset_clip (cr);
+ cairo_restore (cr);
+
+ murrine_set_color_rgb (cr, &border_normal);
+ /* Draw the border */
+ murrine_rounded_rectangle (cr, 0.5, 0.5, width-1, height-1, widget->roundness, widget->corners);
+ cairo_stroke (cr);
+}
+
+static void
+murrine_draw_scrollbar_slider (cairo_t *cr,
+ const MurrineColors *colors,
+ const WidgetParameters *widget,
+ const ScrollBarParameters *scrollbar,
+ int x, int y, int width, int height)
+{
+ if (scrollbar->stepperstyle < 1)
+ {
+ if (scrollbar->junction & MRN_JUNCTION_BEGIN)
+ {
+ if (scrollbar->horizontal)
+ {
+ x -= 1;
+ width += 1;
+ }
+ else
+ {
+ y -= 1;
+ height += 1;
+ }
+ }
+ if (scrollbar->junction & MRN_JUNCTION_END)
+ {
+ if (scrollbar->horizontal)
+ width += 1;
+ else
+ height += 1;
+ }
+ }
+
+ /* Set colors */
+ MurrineRGB fill;
+ if (scrollbar->has_color)
+ fill = scrollbar->color;
+ else
+ fill = colors->bg[0];
+
+ MurrineRGB border;
+ murrine_shade (&colors->shade[6], &border, 0.95);
+ MurrineRGB highlight;
+
+ if (widget->prelight)
+ murrine_shade (&fill, &fill, 1.06);
+
+ murrine_shade (&fill, &highlight, widget->highlight_ratio);
+ /* Draw the border */
+ murrine_mix_color (&border, &fill, 0.4, &border);
+
+ if (scrollbar->horizontal)
+ cairo_translate (cr, x, y);
+
+ else
+ {
+ int tmp = height;
+ rotate_mirror_translate (cr, M_PI/2, x, y, FALSE, FALSE);
+ height = width;
+ width = tmp;
+ }
+
+ cairo_set_line_width (cr, 1.0);
+
+ murrine_rounded_rectangle_fast (cr, 0.5, 0.5, width-1, height-1, widget->corners);
+ murrine_set_color_rgb (cr, &border);
+ cairo_stroke (cr);
+
+ cairo_rectangle (cr, 1, 1, width-2, height-2);
+ murrine_set_gradient (cr, &fill, widget->mrn_gradient, 1, 1, 0, height-2, widget->mrn_gradient.gradients, FALSE);
+
+ /* Draw the glass effect */
+ if (widget->glazestyle > 0)
+ {
+ widget->glazestyle == 2 ? cairo_fill_preserve (cr) : cairo_fill (cr);
+ if (widget->glazestyle < 3)
+ murrine_draw_curved_highlight (cr, 1, width, height);
+ else
+ murrine_draw_curved_highlight_top (cr, 1, width, height);
+ }
+ else
+ {
+ cairo_fill (cr);
+ murrine_draw_flat_highlight (cr, 1, 1, width-2, height-2);
+ }
+
+ murrine_set_gradient (cr, &highlight, widget->mrn_gradient, 1, 1, 0, height-2, widget->mrn_gradient.gradients, TRUE);
+ cairo_fill (cr);
+
+ if (widget->glazestyle == 4)
+ {
+ murrine_draw_curved_highlight_bottom (cr, 1, width, height);
+ MurrineRGB shadow;
+ murrine_shade (&fill, &shadow, 1.0/widget->highlight_ratio);
+ murrine_set_color_rgb (cr, &shadow);
+ cairo_fill (cr);
+ }
+
+ if (widget->glazestyle != 4)
+ {
+ murrine_shade (&fill, &highlight, widget->innerborder_ratio*widget->highlight_ratio);
+ murrine_draw_innerborder (cr, &highlight, &fill, widget->mrn_gradient,
+ 1.5, 1.5,
+ width-3, height-3,
+ widget->mrn_gradient.gradients, TRUE,
+ widget->glazestyle, 0, MRN_CORNER_NONE);
+ }
+
+ /* Draw the options */
+ MurrineRGB style;
+ if (scrollbar->style > 0)
+ murrine_shade (&fill, &style, 0.55);
+
+ /* Draw the circles */
+ if (scrollbar->style == 1)
+ {
+ int circ_radius = 2;
+ int circ_space = 5;
+ int i;
+ int x1 = circ_space+circ_radius;
+ int y1 = height/2;
+ for (i = circ_space; i < width-circ_space; i += 2*circ_radius+circ_space)
+ {
+ cairo_move_to (cr, i, 1);
+ cairo_arc (cr, x1, y1, circ_radius, 0, M_PI*2);
+
+ x1 += 2*circ_radius+circ_space;
+
+ cairo_close_path (cr);
+ murrine_set_color_rgba (cr, &style, 0.15);
+ cairo_fill (cr);
+ }
+ }
+ if (scrollbar->style > 2)
+ {
+ /* Draw the diagonal strokes */
+ if (scrollbar->style < 5)
+ {
+ cairo_save (cr);
+ cairo_rectangle (cr, 1, 1, width-2, height-2);
+ cairo_clip (cr);
+ cairo_new_path (cr);
+ int counter = -width;
+ cairo_set_line_width (cr, 5); /* stroke width */
+ murrine_set_color_rgba (cr, &style, 0.08);
+ while (counter < height)
+ {
+ cairo_move_to (cr, width, counter);
+ cairo_line_to (cr, 0, counter+width);
+ cairo_stroke (cr);
+ counter += 12;
+ }
+ cairo_restore (cr);
+ }
+ /* Draw the horizontal strokes */
+ if (scrollbar->style > 4)
+ {
+ int stroke_width = 7;
+ int stroke_space = 5;
+ int i;
+ murrine_set_color_rgba (cr, &style, 0.08);
+ for (i = stroke_space; i < width-stroke_space; i += stroke_width+stroke_space)
+ {
+ cairo_move_to (cr, i, 1);
+ cairo_rel_line_to (cr, 0, height-2);
+ cairo_rel_line_to (cr, stroke_width, 0);
+ cairo_rel_line_to (cr, 0, -(height-2));
+ cairo_fill (cr);
+ }
+ }
+ }
+ /* Draw the handle */
+ if (scrollbar->style > 0 && scrollbar->style % 2 == 0 )
+ {
+ int bar_x = width/2 - 4;
+ cairo_translate (cr, 0.5, 0.5);
+ int i;
+ for (i=0; i<3; i++)
+ {
+ cairo_move_to (cr, bar_x, 4.5);
+ cairo_line_to (cr, bar_x, height-5.5);
+ murrine_set_color_rgb (cr, &border);
+ cairo_stroke (cr);
+
+ bar_x += 3;
+ }
+ }
+}
+
+static void
+murrine_draw_selected_cell (cairo_t *cr,
+ const MurrineColors *colors,
+ const WidgetParameters *widget,
+ int x, int y, int width, int height)
+{
+ cairo_set_line_cap (cr, CAIRO_LINE_CAP_SQUARE);
+ cairo_set_line_join (cr, CAIRO_LINE_JOIN_MITER);
+
+ MurrineRGB fill;
+ cairo_save (cr);
+
+ cairo_translate (cr, x, y);
+
+ if (widget->focus)
+ fill = colors->base[widget->state_type];
+ else
+ fill = colors->base[GTK_STATE_ACTIVE];
+
+ murrine_set_gradient (cr, &fill, widget->mrn_gradient, 0, 0, 0, height, widget->mrn_gradient.gradients, FALSE);
+ cairo_rectangle (cr, 0, 0, width, height);
+ cairo_fill (cr);
+
+ MurrineRGB border;
+ murrine_shade (&fill, &border, (!widget->mrn_gradient.gradients ? 0.9 : 0.95));
+
+ cairo_move_to (cr, 0, 0.5);
+ cairo_rel_line_to (cr, width, 0);
+ cairo_move_to (cr, 0, height-0.5);
+ cairo_rel_line_to (cr, width, 0);
+
+ murrine_set_color_rgb (cr, &border);
+ cairo_stroke (cr);
+
+ cairo_restore (cr);
+}
+
+static void
+murrine_draw_statusbar (cairo_t *cr,
+ const MurrineColors *colors,
+ const WidgetParameters *widget,
+ int x, int y, int width, int height)
+{
+ const MurrineRGB *dark = &colors->shade[3];
+ MurrineRGB highlight;
+ murrine_shade (dark, &highlight, 1.3);
+
+ cairo_set_line_width (cr, 1);
+ cairo_translate (cr, x, y+0.5);
+ cairo_move_to (cr, 0, 0);
+ cairo_line_to (cr, width, 0);
+ murrine_set_color_rgb (cr, dark);
+ cairo_stroke (cr);
+
+ cairo_translate (cr, 0, 1);
+ cairo_move_to (cr, 0, 0);
+ cairo_line_to (cr, width, 0);
+ murrine_set_color_rgb (cr, &highlight);
+ cairo_stroke (cr);
+}
+
+static void
+murrine_draw_menu_frame (cairo_t *cr,
+ const MurrineColors *colors,
+ const WidgetParameters *widget,
+ int x, int y, int width, int height,
+ int menustyle)
+{
+ const MurrineRGB *border = &colors->shade[5];
+
+ cairo_translate (cr, x, y);
+ cairo_set_line_width (cr, 1);
+ cairo_rectangle (cr, 0.5, 0.5, width-1, height-1);
+ murrine_set_color_rgb (cr, border);
+ cairo_stroke (cr);
+
+ if (menustyle == 1)
+ {
+ MurrineRGB *fill = (MurrineRGB*)&colors->spot[1];
+ MurrineRGB border2;
+ murrine_shade (fill, &border2, 0.5);
+
+ cairo_rectangle (cr, 0.5, 0.5, 3, height-1);
+ murrine_set_color_rgb (cr, &border2);
+ cairo_stroke_preserve (cr);
+
+ murrine_set_color_rgb (cr, fill);
+ cairo_fill (cr);
+ }
+}
+
+static void
+murrine_draw_tooltip (cairo_t *cr,
+ const MurrineColors *colors,
+ const WidgetParameters *widget,
+ int x, int y, int width, int height)
+{
+ MurrineRGB border, highlight;
+
+ MurrineGradients mrn_gradient_custom = widget->mrn_gradient;
+
+ mrn_gradient_custom.gradient_stop_1 = get_decreased_ratio (widget->mrn_gradient.gradient_stop_1, 2.0);
+ mrn_gradient_custom.gradient_stop_2 = get_decreased_ratio (widget->mrn_gradient.gradient_stop_2, 2.0);
+ mrn_gradient_custom.gradient_stop_3 = get_decreased_ratio (widget->mrn_gradient.gradient_stop_3, 2.0);
+ mrn_gradient_custom.gradient_stop_4 = get_decreased_ratio (widget->mrn_gradient.gradient_stop_4, 2.0);
+
+ murrine_shade (&colors->bg[widget->state_type], &border, 0.6);
+ murrine_shade (&colors->bg[widget->state_type], &highlight, 1.0);
+
+ cairo_save (cr);
+
+ cairo_translate (cr, x, y);
+ cairo_set_line_width (cr, 1.0);
+
+ murrine_set_gradient (cr, &colors->bg[widget->state_type], mrn_gradient_custom, 0, 0, 0, height, widget->mrn_gradient.gradients, FALSE);
+ cairo_rectangle (cr, 0, 0, width, height);
+ cairo_fill (cr);
+
+ murrine_set_gradient (cr, &highlight, mrn_gradient_custom, 0, 0, 0, height, widget->mrn_gradient.gradients, TRUE);
+ cairo_rectangle (cr, 0, 0, width, height/2);
+ cairo_fill (cr);
+
+ murrine_set_color_rgb (cr, &border);
+ cairo_rectangle (cr, 0.5, 0.5, width-1, height-1);
+ cairo_stroke (cr);
+
+ cairo_restore (cr);
+}
+
+static void
+murrine_draw_handle (cairo_t *cr,
+ const MurrineColors *colors,
+ const WidgetParameters *widget,
+ const HandleParameters *handle,
+ int x, int y, int width, int height)
+{
+ const MurrineRGB *dark = &colors->shade[4];
+
+ int bar_height;
+ int bar_width = 4;
+ int i, bar_y = 1;
+ int num_bars, bar_spacing;
+ num_bars = 3;
+ bar_spacing = 3;
+ bar_height = num_bars * bar_spacing;
+
+ if (handle->horizontal)
+ {
+ int tmp = height;
+ rotate_mirror_translate (cr, M_PI/2, x + 0.5 + width/2 - bar_height/2, y + height/2 - bar_width/2, FALSE, FALSE);
+ height = width;
+ width = tmp;
+ }
+ else
+ {
+ cairo_translate (cr, x + width/2 - bar_width/2, y + height/2 - bar_height/2 + 0.5);
+ }
+
+ cairo_set_line_width (cr, 1.0);
+
+ for (i=0; i<num_bars; i++)
+ {
+ cairo_move_to (cr, 0, bar_y);
+ cairo_line_to (cr, bar_width, bar_y);
+ murrine_set_color_rgb (cr, dark);
+ cairo_stroke (cr);
+
+ bar_y += bar_spacing;
+ }
+}
+
+static void
+murrine_draw_normal_arrow (cairo_t *cr,
+ const MurrineRGB *color,
+ double x, double y, double width, double height)
+{
+ double arrow_width;
+ double arrow_height;
+ double line_width_2;
+
+ cairo_save (cr);
+
+ arrow_width = MIN (height * 2.0 + MAX (1.0, ceil (height * 2.0 / 6.0 * 2.0) / 2.0) / 2.0, width);
+ line_width_2 = MAX (1.0, ceil (arrow_width / 6.0 * 2.0) / 2.0) / 2.0;
+ arrow_height = arrow_width / 2.0 + line_width_2;
+
+ cairo_translate (cr, x, y - arrow_height / 2.0);
+
+ cairo_move_to (cr, -arrow_width / 2.0, line_width_2);
+ cairo_line_to (cr, -arrow_width / 2.0 + line_width_2, 0);
+ /* cairo_line_to (cr, 0, arrow_height - line_width_2); */
+ cairo_arc_negative (cr, 0, arrow_height - 2*line_width_2 - 2*line_width_2 * sqrt(2), 2*line_width_2, M_PI_2 + M_PI_4, M_PI_4);
+ cairo_line_to (cr, arrow_width / 2.0 - line_width_2, 0);
+ cairo_line_to (cr, arrow_width / 2.0, line_width_2);
+ cairo_line_to (cr, 0, arrow_height);
+ cairo_close_path (cr);
+
+ murrine_set_color_rgb (cr, color);
+ cairo_fill (cr);
+
+ cairo_restore (cr);
+}
+
+static void
+murrine_draw_combo_arrow (cairo_t *cr,
+ const MurrineRGB *color,
+ double x, double y, double width, double height)
+{
+ double arrow_width = MIN (height * 2 / 3.0, width);
+ double arrow_height = arrow_width / 2.0;
+ double gap_size = 1.0 * arrow_height;
+
+ cairo_save (cr);
+ cairo_translate (cr, x, y - (arrow_height + gap_size) / 2.0);
+ cairo_rotate (cr, M_PI);
+ murrine_draw_normal_arrow (cr, color, 0, 0, arrow_width, arrow_height);
+ cairo_restore (cr);
+
+ murrine_draw_normal_arrow (cr, color, x, y + (arrow_height + gap_size) / 2.0, arrow_width, arrow_height);
+}
+
+static void
+_murrine_draw_arrow (cairo_t *cr,
+ const MurrineRGB *color,
+ MurrineDirection dir, MurrineArrowType type,
+ double x, double y, double width, double height)
+{
+ double rotate;
+
+ if (dir == MRN_DIRECTION_LEFT)
+ rotate = M_PI*1.5;
+ else if (dir == MRN_DIRECTION_RIGHT)
+ rotate = M_PI*0.5;
+ else if (dir == MRN_DIRECTION_UP)
+ rotate = M_PI;
+ else if (dir == MRN_DIRECTION_DOWN)
+ rotate = 0;
+ else
+ return;
+
+ if (type == MRN_ARROW_NORMAL)
+ {
+ cairo_translate (cr, x, y);
+ cairo_rotate (cr, -rotate);
+ murrine_draw_normal_arrow (cr, color, 0, 0, width, height);
+ }
+ else if (type == MRN_ARROW_COMBO)
+ {
+ cairo_translate (cr, x, y);
+ murrine_draw_combo_arrow (cr, color, 0, 0, width, height);
+ }
+}
+
+static void
+murrine_draw_arrow (cairo_t *cr,
+ const MurrineColors *colors,
+ const WidgetParameters *widget,
+ const ArrowParameters *arrow,
+ int x, int y, int width, int height)
+{
+ MurrineRGB color = colors->fg[widget->state_type];
+ murrine_mix_color (&color, &colors->bg[widget->state_type], 0.2, &color);
+ gdouble tx, ty;
+
+ tx = x + width/2.0;
+ ty = y + height/2.0;
+
+ if (widget->disabled)
+ {
+ _murrine_draw_arrow (cr, &colors->shade[0],
+ arrow->direction, arrow->type,
+ tx+0.5, ty+0.5, width, height);
+ }
+
+ cairo_identity_matrix (cr);
+
+ _murrine_draw_arrow (cr, &color, arrow->direction, arrow->type,
+ tx, ty, width, height);
+}
+
+static void
+murrine_draw_radiobutton (cairo_t * cr,
+ const MurrineColors *colors,
+ const WidgetParameters *widget,
+ const OptionParameters *status,
+ int x, int y, int width, int height,
+ double trans)
+{
+ const MurrineRGB *border;
+ const MurrineRGB *dot;
+
+ width = height = 15;
+
+ if (widget->state_type == GTK_STATE_INSENSITIVE)
+ {
+ border = &colors->shade[3];
+ dot = &colors->shade[3];
+ }
+ else
+ {
+ border = &colors->shade[5];
+ if (status->draw_bullet)
+ border = &colors->spot[2];
+ dot = &colors->text[widget->state_type];
+ }
+ MurrineRGB shadow;
+ murrine_shade (border, &shadow, 0.9);
+
+ cairo_translate (cr, x, y);
+
+ cairo_set_line_width (cr, 2);
+ cairo_arc (cr, 7, 7, 6, 0, M_PI*2);
+ murrine_set_color_rgba (cr, &shadow, 0.15);
+ cairo_stroke (cr);
+
+ cairo_set_line_width (cr, 1.0);
+
+ cairo_arc (cr, 7, 7, 5.5, 0, M_PI*2);
+
+ if (widget->state_type != GTK_STATE_INSENSITIVE)
+ {
+ const MurrineRGB *bg = &colors->base[0];
+ if (status->draw_bullet)
+ bg = &colors->spot[1];
+ if (widget->glazestyle != 2)
+ {
+ MurrineRGB highlight;
+ murrine_shade (bg, &highlight, widget->highlight_ratio);
+ murrine_set_gradient (cr, &highlight, widget->mrn_gradient, 0, 0, 0, 14, widget->mrn_gradient.gradients, FALSE);
+ }
+ else
+ murrine_set_gradient (cr, bg, widget->mrn_gradient, 0, 0, 0, 14, widget->mrn_gradient.gradients, FALSE);
+ cairo_fill_preserve (cr);
+ }
+
+ murrine_set_color_rgb (cr, border);
+ cairo_stroke (cr);
+
+ cairo_arc (cr, 7, 7, 5, 0, M_PI*2);
+ cairo_clip (cr);
+
+ if (widget->state_type != GTK_STATE_INSENSITIVE)
+ {
+ const MurrineRGB *bg = &colors->base[0];
+ if (status->draw_bullet)
+ bg = &colors->spot[1];
+
+ cairo_rectangle (cr, 0, 7, width, height);
+ if (widget->glazestyle == 2)
+ {
+ MurrineRGB highlight;
+ murrine_shade (bg, &highlight, widget->highlight_ratio);
+ murrine_set_gradient (cr, &highlight, widget->mrn_gradient, 0, 0, 0, 14, widget->mrn_gradient.gradients, FALSE);
+ }
+ else
+ murrine_set_gradient (cr, bg, widget->mrn_gradient, 0, 0, 0, 14, widget->mrn_gradient.gradients, FALSE);
+ cairo_fill (cr);
+ }
+
+ /* inconsistent state is missing? */
+ if (status->draw_bullet)
+ {
+ cairo_arc (cr, 7, 7, 2, 0, M_PI*2);
+ /* murrine_set_color_rgb (cr, dot); */
+ murrine_set_color_rgba (cr, dot, trans);
+ cairo_fill (cr);
+ }
+
+ cairo_restore (cr);
+}
+
+static void
+murrine_draw_checkbox (cairo_t * cr,
+ const MurrineColors *colors,
+ const WidgetParameters *widget,
+ const OptionParameters *status,
+ int x, int y, int width, int height,
+ double trans)
+{
+ const MurrineRGB *border;
+ const MurrineRGB *dot;
+
+ width = height = 13;
+
+ if (widget->state_type == GTK_STATE_INSENSITIVE)
+ {
+ border = &colors->shade[3];
+ dot = &colors->shade[3];
+ }
+ else
+ {
+ border = &colors->shade[5];
+ if (status->draw_bullet)
+ border = &colors->spot[2];
+ dot = &colors->text[widget->state_type];
+ }
+ MurrineRGB shadow;
+ murrine_shade (border, &shadow, 0.9);
+
+ cairo_translate (cr, x, y);
+ cairo_set_line_width (cr, 1.0);
+
+ if (widget->xthickness > 2 && widget->ythickness > 2)
+ {
+ cairo_rectangle (cr, 0.5, 0.5, width-1, height-1);
+ murrine_set_color_rgba (cr, &shadow, 0.15);
+ cairo_stroke (cr);
+
+ /* Draw the rectangle for the checkbox itself */
+ cairo_rectangle (cr, 1.5, 1.5, width-3, height-3);
+ }
+ else
+ {
+ cairo_rectangle (cr, 0.5, 0.5, width-1, height-1);
+ }
+
+
+ if (widget->state_type != GTK_STATE_INSENSITIVE)
+ {
+ const MurrineRGB *bg = &colors->base[0];
+ if (status->draw_bullet)
+ bg = &colors->spot[1];
+
+ if (widget->glazestyle == 2)
+ {
+ MurrineRGB highlight;
+ murrine_shade (bg, &highlight, widget->highlight_ratio);
+ murrine_set_gradient (cr, &highlight, widget->mrn_gradient, 0, 0, 0, 14, widget->mrn_gradient.gradients, FALSE);
+ }
+ else
+ murrine_set_gradient (cr, bg, widget->mrn_gradient, 0, 0, 0, 14, widget->mrn_gradient.gradients, FALSE);
+ cairo_fill_preserve (cr);
+ }
+
+ murrine_set_color_rgb (cr, border);
+ cairo_stroke (cr);
+
+ if (widget->state_type != GTK_STATE_INSENSITIVE)
+ {
+ const MurrineRGB *bg = &colors->base[0];
+ if (status->draw_bullet)
+ bg = &colors->spot[1];
+
+ MurrineRGB highlight;
+ murrine_shade (bg, &highlight, widget->highlight_ratio);
+ if (widget->xthickness > 2 && widget->ythickness > 2)
+ cairo_rectangle (cr, 2, 2, width-4, (height-4)/2);
+ else
+ cairo_rectangle (cr, 1, 1, width-2, (height-2)/2);
+
+ if (widget->glazestyle != 2)
+ {
+ MurrineRGB highlight;
+ murrine_shade (bg, &highlight, widget->highlight_ratio);
+ murrine_set_gradient (cr, &highlight, widget->mrn_gradient, 0, 0, 0, 14, widget->mrn_gradient.gradients, FALSE);
+ }
+ else
+ murrine_set_gradient (cr, bg, widget->mrn_gradient, 0, 0, 0, 14, widget->mrn_gradient.gradients, FALSE);
+ cairo_fill (cr);
+ }
+
+ cairo_scale (cr, width / 13.0, height / 13.0);
+ if (status->draw_bullet)
+ {
+ if (status->inconsistent) /* Inconsistent */
+ {
+ cairo_set_line_width (cr, 2.0);
+ cairo_move_to (cr, 3, height*0.5);
+ cairo_line_to (cr, width-3, height*0.5);
+ }
+ else
+ {
+ cairo_translate (cr, -2, 0);
+ /*
+ if (widget && widget->parent && GTK_IS_MENU(widget->parent))
+ cairo_translate (cr, 0, 0);
+ */
+ cairo_move_to (cr, 4, 8);
+ cairo_rel_line_to (cr, 5, 4);
+ cairo_rel_curve_to (cr, 1.4, -5, -1, -1, 5.7, -12.5);
+ cairo_rel_curve_to (cr, -4, 4, -4, 4, -6.7, 9.3);
+ cairo_rel_line_to (cr, -2.3, -2.5);
+ }
+
+ murrine_set_color_rgba (cr, dot, trans);
+ cairo_fill (cr);
+ }
+}
+
+static void
+murrine_draw_resize_grip (cairo_t *cr,
+ const MurrineColors *colors,
+ const WidgetParameters *widget,
+ const ResizeGripParameters *grip,
+ int x, int y, int width, int height)
+{
+ const MurrineRGB *dark = &colors->shade[3];
+ MurrineRGB highlight;
+ murrine_shade (dark, &highlight, 1.3);
+ int lx, ly;
+
+ cairo_set_line_width (cr, 1.0);
+
+ for (ly=0; ly<4; ly++) /* vertically, four rows of dots */
+ {
+ for (lx=0; lx<=ly; lx++) /* horizontally */
+ {
+ int ny = (3.5-ly) * 3;
+ int nx = lx * 3;
+
+ murrine_set_color_rgb (cr, &highlight);
+ cairo_rectangle (cr, x+width-nx-1, y+height-ny-1, 2, 2);
+ cairo_fill (cr);
+
+ murrine_set_color_rgb (cr, dark);
+ cairo_rectangle (cr, x+width-nx-1, y+height-ny-1, 1, 1);
+ cairo_fill (cr);
+ }
+ }
+}
+
+void
+murrine_register_style_murrine (MurrineStyleFunctions *functions)
+{
+ g_assert (functions);
+
+ functions->draw_button = murrine_draw_button;
+ functions->draw_scale_trough = murrine_draw_scale_trough;
+ functions->draw_progressbar_trough = murrine_draw_progressbar_trough;
+ functions->draw_progressbar_fill = murrine_draw_progressbar_fill;
+ functions->draw_entry = murrine_draw_entry;
+ functions->draw_slider_handle = murrine_draw_slider_handle;
+ functions->draw_spinbutton_down = murrine_draw_spinbutton_down;
+ functions->draw_optionmenu = murrine_draw_optionmenu;
+ functions->draw_combo_separator = murrine_draw_combo_separator;
+ functions->draw_menubar = murrine_draw_menubar;
+ functions->draw_tab = murrine_draw_tab;
+ functions->draw_frame = murrine_draw_frame;
+ functions->draw_separator = murrine_draw_separator;
+ functions->draw_list_view_header = murrine_draw_list_view_header;
+ functions->draw_toolbar = murrine_draw_toolbar;
+ functions->draw_tooltip = murrine_draw_tooltip;
+ functions->draw_menuitem = murrine_draw_menuitem;
+ functions->draw_selected_cell = murrine_draw_selected_cell;
+ functions->draw_scrollbar_stepper = murrine_draw_scrollbar_stepper;
+ functions->draw_scrollbar_slider = murrine_draw_scrollbar_slider;
+ functions->draw_scrollbar_trough = murrine_draw_scrollbar_trough;
+ functions->draw_statusbar = murrine_draw_statusbar;
+ functions->draw_menu_frame = murrine_draw_menu_frame;
+ functions->draw_tooltip = murrine_draw_tooltip;
+ functions->draw_handle = murrine_draw_handle;
+ functions->draw_resize_grip = murrine_draw_resize_grip;
+ functions->draw_arrow = murrine_draw_arrow;
+ functions->draw_checkbox = murrine_draw_checkbox;
+ functions->draw_radiobutton = murrine_draw_radiobutton;
+}
Added: trunk/src/murrine_draw.h
==============================================================================
--- (empty file)
+++ trunk/src/murrine_draw.h Mon Feb 11 23:01:49 2008
@@ -0,0 +1,35 @@
+/* Murrine theme engine
+ * Copyright (C) 2007 Andrea Cimitan
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * 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; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ */
+
+#ifndef MURRINE_DRAW_H
+#define MURRINE_DRAW_H
+
+#include "murrine_style.h"
+#include "murrine_types.h"
+
+#include <gtk/gtk.h>
+#include <gdk/gdk.h>
+
+#include <cairo.h>
+
+G_GNUC_INTERNAL void murrine_register_style_murrine (MurrineStyleFunctions *functions);
+G_GNUC_INTERNAL void murrine_register_style_rgba (MurrineStyleFunctions *functions);
+
+#endif /* MURRINE_DRAW_H */
Added: trunk/src/murrine_draw_rgba.c
==============================================================================
--- (empty file)
+++ trunk/src/murrine_draw_rgba.c Mon Feb 11 23:01:49 2008
@@ -0,0 +1,1959 @@
+/* Murrine theme engine
+ * Copyright (C) 2007 Andrea Cimitan
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * 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; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ */
+
+#include "murrine_draw.h"
+#include "murrine_style.h"
+#include "murrine_types.h"
+
+#include "support.h"
+#include "cairo-support.h"
+
+#include <cairo.h>
+
+#define M_PI 3.14159265358979323846
+
+static void
+murrine_draw_inset (cairo_t *cr,
+ const MurrineRGB *bg_color,
+ double x, double y, double w, double h,
+ double radius, uint8 corners)
+{
+ MurrineRGB highlight, shadow;
+
+ murrine_shade (bg_color, &highlight, 1.15);
+ murrine_shade (bg_color, &shadow, 0.4);
+
+ /* highlight */
+ cairo_move_to (cr, x + w + (radius * -0.2928932188), y - (radius * -0.2928932188)); /* 0.2928932... 1-sqrt(2)/2 gives middle of curve */
+
+ if (corners & MRN_CORNER_TOPRIGHT)
+ cairo_arc (cr, x + w - radius, y + radius, radius, M_PI * 1.75, M_PI * 2);
+ else
+ cairo_line_to (cr, x + w, y);
+
+ if (corners & MRN_CORNER_BOTTOMRIGHT)
+ cairo_arc (cr, x + w - radius, y + h - radius, radius, 0, M_PI * 0.5);
+ else
+ cairo_line_to (cr, x + w, y + h);
+
+ if (corners & MRN_CORNER_BOTTOMLEFT)
+ cairo_arc (cr, x + radius, y + h - radius, radius, M_PI * 0.5, M_PI * 0.75);
+ else
+ cairo_line_to (cr, x, y + h);
+
+ murrine_set_color_rgba (cr, &highlight, 0.48);
+ cairo_stroke (cr);
+
+ /* shadow */
+ cairo_move_to (cr, x + (radius * 0.2928932188), y + h + (radius * -0.2928932188));
+
+ if (corners & MRN_CORNER_BOTTOMLEFT)
+ cairo_arc (cr, x + radius, y + h - radius, radius, M_PI * 0.75, M_PI);
+ else
+ cairo_line_to (cr, x, y + h);
+
+ if (corners & MRN_CORNER_TOPLEFT)
+ cairo_arc (cr, x + radius, y + radius, radius, M_PI, M_PI * 1.5);
+ else
+ cairo_line_to (cr, x, y);
+
+ if (corners & MRN_CORNER_TOPRIGHT)
+ cairo_arc (cr, x + w - radius, y + radius, radius, M_PI * 1.5, M_PI * 1.75);
+ else
+ cairo_line_to (cr, x + w, y);
+
+ murrine_set_color_rgba (cr, &shadow, 0.12);
+ cairo_stroke (cr);
+}
+
+static void
+murrine_draw_highlight_and_shade (cairo_t *cr,
+ const MurrineColors *colors,
+ const ShadowParameters *widget,
+ int width, int height, int radius)
+{
+ MurrineRGB highlight;
+ MurrineRGB shadow;
+ uint8 corners = widget->corners;
+ double x = 1.0;
+ double y = 1.0;
+
+ murrine_shade (&colors->bg[0], &highlight, 1.15);
+ murrine_shade (&colors->bg[0], &shadow, 0.4);
+
+ width -= 3;
+ height -= 3;
+
+ cairo_save (cr);
+
+ /* Top/Left highlight */
+ if (corners & MRN_CORNER_BOTTOMLEFT)
+ cairo_move_to (cr, x, y+height-radius);
+ else
+ cairo_move_to (cr, x, y+height);
+
+ murrine_rounded_corner (cr, x, y, radius, corners & MRN_CORNER_TOPLEFT);
+
+ if (corners & MRN_CORNER_TOPRIGHT)
+ cairo_line_to (cr, x+width-radius, y);
+ else
+ cairo_line_to (cr, x+width, y);
+
+ if (widget->shadow & MRN_SHADOW_OUT)
+ murrine_set_color_rgba (cr, &highlight, 0.5);
+ else
+ murrine_set_color_rgba (cr, &shadow, 0.13);
+
+ cairo_stroke (cr);
+
+ /* Bottom/Right highlight -- this includes the corners */
+ cairo_move_to (cr, x+width-radius, y); /* topright and by radius to the left */
+ murrine_rounded_corner (cr, x+width, y, radius, corners & MRN_CORNER_TOPRIGHT);
+ murrine_rounded_corner (cr, x+width, y+height, radius, corners & MRN_CORNER_BOTTOMRIGHT);
+ murrine_rounded_corner (cr, x, y+height, radius, corners & MRN_CORNER_BOTTOMLEFT);
+
+ if (widget->shadow & MRN_SHADOW_OUT)
+ murrine_set_color_rgba (cr, &shadow, 0.13);
+ else
+ murrine_set_color_rgba (cr, &highlight, 0.5);
+
+ cairo_stroke (cr);
+
+ cairo_restore (cr);
+}
+
+static void
+murrine_rgba_draw_button (cairo_t *cr,
+ const MurrineColors *colors,
+ const WidgetParameters *widget,
+ int x, int y, int width, int height,
+ boolean horizontal)
+{
+ double xoffset = 0, yoffset = 0;
+ MurrineRGB fill = colors->bg[widget->state_type];
+ MurrineRGB border_disabled = colors->shade[6];
+ MurrineRGB border_normal;
+ MurrineRGB highlight;
+
+ double custom_highlight_ratio = widget->highlight_ratio;
+ MurrineGradients mrn_gradient_custom = widget->mrn_gradient;
+
+ if (widget->disabled)
+ {
+ mrn_gradient_custom.gradient_stop_1 = get_decreased_ratio (widget->mrn_gradient.gradient_stop_1, 3.0);
+ mrn_gradient_custom.gradient_stop_2 = get_decreased_ratio (widget->mrn_gradient.gradient_stop_2, 3.0);
+ mrn_gradient_custom.gradient_stop_3 = get_decreased_ratio (widget->mrn_gradient.gradient_stop_3, 3.0);
+ mrn_gradient_custom.gradient_stop_4 = get_decreased_ratio (widget->mrn_gradient.gradient_stop_4, 3.0);
+ custom_highlight_ratio = get_decreased_ratio (widget->highlight_ratio, 2.0);
+ }
+
+ if (widget->is_default)
+ murrine_mix_color (&fill, &colors->spot[1], 0.2, &fill);
+
+ if (!horizontal)
+ murrine_exchange_axis (cr, &x, &y, &width, &height);
+
+ murrine_shade (&colors->shade[8], &border_normal, 0.95);
+ murrine_shade (&fill, &highlight, custom_highlight_ratio);
+
+ cairo_translate (cr, x, y);
+ cairo_set_line_width (cr, 1.0);
+
+ if (widget->xthickness > 1)
+ xoffset = 1;
+ if (widget->ythickness > 1)
+ yoffset = 1;
+
+ if (!widget->active)
+ {
+ murrine_rounded_rectangle (cr, xoffset, yoffset, width-(xoffset*2), height-(yoffset*2), widget->roundness, widget->corners);
+ murrine_set_color_rgba (cr, widget->disabled ? &border_disabled : &border_normal, 0.16);
+ cairo_stroke (cr);
+ }
+
+ murrine_mix_color (widget->disabled ? &border_disabled : &border_normal , &widget->parentbg, 0.2,
+ widget->disabled ? &border_disabled : &border_normal);
+
+ murrine_mix_color (widget->disabled ? &border_disabled : &border_normal , &fill, 0.25,
+ widget->disabled ? &border_disabled : &border_normal);
+
+ /* Default button */
+ if (widget->is_default)
+ {
+ murrine_rounded_rectangle (cr, xoffset, yoffset, width-(xoffset*2), height-(yoffset*2), widget->roundness, widget->corners);
+ murrine_set_color_rgba (cr, &colors->spot[1], 0.6);
+ cairo_stroke (cr);
+ murrine_shade (&border_normal, &border_normal, 0.8);
+ }
+
+ /* Draw the bg */
+ if (widget->roundness < 2)
+ cairo_rectangle (cr, xoffset + 1, yoffset + 1, width-(xoffset*2)-2, height-(yoffset*2)-2);
+ else
+ clearlooks_rounded_rectangle (cr, xoffset+0.5, yoffset+0.5, width-(xoffset*2)-1, height-(yoffset*2)-1, widget->roundness+1, widget->corners);
+ murrine_set_gradient (cr, &fill, mrn_gradient_custom, xoffset+1, yoffset+1, 0, height-(yoffset*2)-2, widget->mrn_gradient.gradients, FALSE);
+
+ cairo_save (cr);
+ cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
+
+ if (widget->roundness > 1)
+ cairo_clip_preserve (cr);
+
+ int curve_pos = 1;
+ if (widget->glazestyle != 4)
+ curve_pos = 2;
+
+ /* Draw the glass effect */
+ if (widget->glazestyle > 0)
+ {
+ cairo_set_fill_rule (cr, CAIRO_FILL_RULE_EVEN_ODD);
+ widget->glazestyle == 2 ? cairo_fill_preserve (cr) : cairo_fill (cr);
+ if (widget->glazestyle < 3)
+ murrine_draw_curved_highlight (cr, curve_pos, width, height);
+ else
+ murrine_draw_curved_highlight_top (cr, curve_pos, width, height);
+ }
+ else
+ {
+ cairo_fill (cr);
+ murrine_draw_flat_highlight (cr, xoffset + 1, yoffset + 1, width-(xoffset*2)-2, height-(yoffset*2)-2);
+ }
+
+ murrine_set_gradient (cr, &highlight, mrn_gradient_custom, xoffset+1, yoffset+1, 0, height-(yoffset*2)-2, widget->mrn_gradient.gradients, TRUE);
+ cairo_fill (cr);
+
+ if (widget->glazestyle == 4)
+ {
+ murrine_draw_curved_highlight_bottom (cr, curve_pos, width, height);
+ MurrineRGB shadow;
+ murrine_shade (&fill, &shadow, 1.0/custom_highlight_ratio);
+ murrine_set_gradient (cr, &shadow, mrn_gradient_custom, xoffset+1, yoffset+1, 0, height-(yoffset*2)-2, widget->mrn_gradient.gradients, TRUE);
+ cairo_fill (cr);
+ }
+
+ cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
+
+ /* Draw the white inner border */
+ if (widget->glazestyle != 4 && !widget->active)
+ {
+ murrine_shade (&fill, &highlight, widget->innerborder_ratio*custom_highlight_ratio);
+ if (horizontal)
+ {
+ murrine_draw_innerborder (cr, &highlight, &fill, mrn_gradient_custom,
+ xoffset + 1.5, yoffset + 1.5,
+ width-(xoffset*2)-3, height-(yoffset*2)-3,
+ widget->mrn_gradient.gradients, horizontal,
+ widget->glazestyle, widget->roundness, widget->corners);
+ }
+ else
+ {
+ murrine_exchange_axis (cr, &x, &y, &width, &height);
+ murrine_draw_innerborder (cr, &highlight, &fill, mrn_gradient_custom,
+ xoffset + 1.5, yoffset + 1.5,
+ width-(xoffset*2)-3, height-(yoffset*2)-3,
+ widget->mrn_gradient.gradients, horizontal,
+ widget->glazestyle, widget->roundness, widget->corners);
+ murrine_exchange_axis (cr, &x, &y, &width, &height);
+ }
+ }
+
+ cairo_restore (cr);
+
+ /* Draw pressed button shadow */
+ if (widget->active)
+ {
+ cairo_pattern_t *pattern;
+ MurrineRGB shadow;
+
+ murrine_shade (&fill, &shadow, 0.94);
+
+ cairo_save (cr);
+
+ if (widget->roundness < 2)
+ cairo_rectangle (cr, xoffset + 1, yoffset + 1, width-(xoffset*2)-2, height-(yoffset*2)-2);
+ else
+ clearlooks_rounded_rectangle (cr, xoffset+1, yoffset+1, width-(xoffset*2)-2, height-(yoffset*2)-2, widget->roundness-1,
+ widget->corners & (MRN_CORNER_TOPLEFT | MRN_CORNER_TOPRIGHT | MRN_CORNER_BOTTOMLEFT));
+
+ cairo_clip (cr);
+
+ cairo_rectangle (cr, xoffset+1, yoffset+1, width-(xoffset*2)-2, 3);
+ pattern = cairo_pattern_create_linear (xoffset+1, yoffset+1, xoffset+1, yoffset+4);
+ cairo_pattern_add_color_stop_rgba (pattern, 0.0, shadow.r, shadow.g, shadow.b, 0.58);
+ cairo_pattern_add_color_stop_rgba (pattern, 1.0, shadow.r, shadow.g, shadow.b, 0.0);
+ cairo_set_source (cr, pattern);
+ cairo_fill (cr);
+ cairo_pattern_destroy (pattern);
+
+ cairo_rectangle (cr, xoffset+1, yoffset+1, 3, height-(yoffset*2)-2);
+ pattern = cairo_pattern_create_linear (xoffset+1, yoffset+1, xoffset+4, yoffset+1);
+ cairo_pattern_add_color_stop_rgba (pattern, 0.0, shadow.r, shadow.g, shadow.b, 0.58);
+ cairo_pattern_add_color_stop_rgba (pattern, 1.0, shadow.r, shadow.g, shadow.b, 0.0);
+ cairo_set_source (cr, pattern);
+ cairo_fill (cr);
+ cairo_pattern_destroy (pattern);
+
+ cairo_restore (cr);
+
+ murrine_draw_inset (cr, &widget->parentbg, xoffset-0.5, yoffset-0.5, width-(xoffset*2)+1, height-(yoffset*2)+1, widget->roundness+1, widget->corners);
+ }
+
+ /* Draw the border */
+ murrine_set_color_rgb (cr, widget->disabled ? &border_disabled : &border_normal);
+ murrine_rounded_rectangle (cr, xoffset+0.5, yoffset+0.5, width-(xoffset*2)-1, height-(yoffset*2)-1, widget->roundness, widget->corners);
+ cairo_stroke (cr);
+}
+
+static void
+murrine_rgba_draw_entry (cairo_t *cr,
+ const MurrineColors *colors,
+ const WidgetParameters *widget,
+ int x, int y, int width, int height)
+{
+ const MurrineRGB *base = &colors->base[widget->state_type];
+ MurrineRGB border = colors->shade[widget->disabled ? 4 : 5];
+ int xoffset, yoffset = 0;
+ int radius = CLAMP (widget->roundness, 0, 3);
+
+ if (widget->xthickness > 1)
+ xoffset = 1;
+ if (widget->ythickness > 1)
+ yoffset = 1;
+
+ murrine_shade (&border, &border, 0.92);
+
+ cairo_translate (cr, x+0.5, y+0.5);
+ cairo_set_line_width (cr, 1.0);
+
+ /* Draw (erase) the background */
+ /* // CLEARING should be useless... testing
+ cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR);
+ cairo_paint (cr);
+ */
+ cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
+
+ /* Fill the background (shouldn't have to) */
+ cairo_rectangle (cr, -0.5, -0.5, width, height);
+ murrine_set_color_rgba (cr, &widget->parentbg, WINDOW_OPACITY);
+ cairo_fill (cr);
+
+ /* Fill the entry's base color (why isn't is large enough by default?) */
+ cairo_rectangle (cr, 1.5, 1.5, width-3, height-3);
+ murrine_set_color_rgba (cr, base, ENTRY_OPACITY);
+ cairo_fill (cr);
+
+ cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
+
+ murrine_draw_inset (cr, &widget->parentbg, 0, 0, width-1, height-1, radius+1, widget->corners);
+
+ /* Draw the focused border */
+ if (widget->focus)
+ {
+ cairo_rectangle (cr, 2, 2, width-5, height-5);
+ murrine_set_color_rgba (cr, &colors->spot[1], 0.6);
+ cairo_stroke(cr);
+ }
+ else
+ {
+ MurrineRGB highlight;
+ murrine_shade (base, &highlight, 1.15);
+
+ cairo_move_to (cr, 2, height-3);
+ cairo_line_to (cr, 2, 2);
+ cairo_line_to (cr, width-3, 2);
+
+ murrine_set_color_rgba (cr, &highlight, widget->disabled ? 0.3 : 0.6);
+ cairo_stroke (cr);
+ }
+
+ /* Draw the border */
+ if (widget->focus)
+ murrine_set_color_rgb (cr, &colors->spot[2]);
+ else
+ murrine_set_color_rgb (cr, &border);
+
+ murrine_rounded_rectangle (cr, 1, 1, width-3, height-3, radius, widget->corners);
+ cairo_stroke (cr);
+}
+
+static void
+murrine_scale_draw_gradient (cairo_t *cr,
+ const MurrineRGB *c1,
+ const MurrineRGB *c2,
+ int x, int y, int width, int height,
+ boolean alpha)
+{
+ if (alpha)
+ murrine_set_color_rgba (cr, c1, 0.4);
+ else
+ murrine_set_color_rgb (cr, c1);
+
+ cairo_rectangle (cr, x, y, width, height);
+ cairo_fill (cr);
+
+ cairo_rectangle (cr, x, y, width, height);
+ murrine_set_color_rgba (cr, c2, 0.82);
+ cairo_stroke (cr);
+}
+
+static void
+murrine_rgba_draw_scale_trough (cairo_t *cr,
+ const MurrineColors *colors,
+ const WidgetParameters *widget,
+ const SliderParameters *slider,
+ int x, int y, int width, int height)
+{
+ int fill_x, fill_y, fill_width, fill_height; /* Fill x,y,w,h */
+ int trough_width, trough_height;
+ double translate_x, translate_y;
+ int fill_size = slider->fill_size;
+ int TROUGH_SIZE = 6;
+
+ if (slider->horizontal)
+ {
+ if (fill_size > width-3)
+ fill_size = width-3;
+
+ fill_x = slider->inverted ? width - fill_size - 3 : 0;
+ fill_y = 0;
+ fill_width = fill_size;
+ fill_height = TROUGH_SIZE-2;
+
+ trough_width = width-3;
+ trough_height = TROUGH_SIZE-2;
+
+ translate_x = x + 0.5;
+ translate_y = y + 0.5 + (height/2) - (TROUGH_SIZE/2);
+ }
+ else
+ {
+ if (fill_size > height-3)
+ fill_size = height-3;
+
+ fill_x = 0;
+ fill_y = slider->inverted ? height - fill_size - 3 : 0;
+ fill_width = TROUGH_SIZE-2;
+ fill_height = fill_size;
+
+ trough_width = TROUGH_SIZE-2;
+ trough_height = height-3;
+
+ translate_x = x + 0.5 + (width/2) - (TROUGH_SIZE/2);
+ translate_y = y + 0.5;
+ }
+
+ cairo_set_line_width (cr, 1.0);
+ cairo_translate (cr, translate_x, translate_y);
+
+ murrine_draw_inset (cr, &widget->parentbg, 0, 0, trough_width+2, trough_height+2, 0, 0);
+
+ cairo_translate (cr, 1, 1);
+
+ murrine_scale_draw_gradient (cr, &colors->shade[1],
+ &colors->shade[5], /* border */
+ 0, 0, trough_width, trough_height,
+ TRUE);
+
+ murrine_scale_draw_gradient (cr, &colors->spot[1],
+ &colors->spot[2], /* border */
+ fill_x, fill_y, fill_width, fill_height,
+ FALSE);
+}
+
+static void
+murrine_rgba_draw_progressbar_trough (cairo_t *cr,
+ const MurrineColors *colors,
+ const WidgetParameters *widget,
+ int x, int y, int width, int height)
+{
+ const MurrineRGB *border = &colors->shade[4];
+
+ cairo_set_line_width (cr, 1.0);
+ cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
+
+ /* Fill with bg color */
+ cairo_rectangle (cr, x, y, width, height);
+ murrine_set_color_rgba (cr, &colors->bg[widget->state_type], 0.8);
+ cairo_fill (cr);
+
+ cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
+
+ /* Create trough box */
+ cairo_rectangle (cr, x+1, y+1, width-2, height-2);
+ murrine_set_color_rgba (cr, &colors->shade[1], 0.8);
+ cairo_fill (cr);
+
+ /* Draw border */
+ cairo_rectangle (cr, x+0.5, y+0.5, width-1, height-1);
+ murrine_set_color_rgba (cr, border, 0.8);
+ cairo_stroke (cr);
+}
+
+static void
+murrine_rgba_draw_progressbar_fill (cairo_t *cr,
+ const MurrineColors *colors,
+ const WidgetParameters *widget,
+ const ProgressBarParameters *progressbar,
+ int x, int y, int width, int height,
+ gint offset)
+{
+ boolean is_horizontal = progressbar->orientation < 2;
+ double tile_pos = 0;
+ double stroke_width;
+ int x_step;
+ const MurrineRGB *fill = &colors->spot[1];
+ const MurrineRGB *border = &colors->spot[2];
+ MurrineRGB highlight;
+
+ murrine_shade (fill, &highlight, widget->highlight_ratio);
+
+ cairo_rectangle (cr, x, y, width, height);
+
+ if (is_horizontal)
+ {
+ if (progressbar->orientation == MRN_ORIENTATION_LEFT_TO_RIGHT)
+ rotate_mirror_translate (cr, 0, x, y, FALSE, FALSE);
+ else
+ rotate_mirror_translate (cr, 0, x+width, y, TRUE, FALSE);
+ }
+ else
+ {
+ int tmp = height; height = width; width = tmp;
+
+ x = x + 1;
+ y = y - 1;
+ width = width + 2;
+ height = height - 2;
+
+ if (progressbar->orientation == MRN_ORIENTATION_TOP_TO_BOTTOM)
+ rotate_mirror_translate (cr, M_PI/2, x, y, FALSE, FALSE);
+ else
+ rotate_mirror_translate (cr, M_PI/2, x, y+width, TRUE, FALSE);
+ }
+
+ cairo_save (cr);
+ cairo_clip (cr);
+
+ stroke_width = height*2;
+ x_step = (((float)stroke_width/10)*offset);
+ cairo_set_line_width (cr, 1.0);
+
+ cairo_save (cr);
+ cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
+
+ cairo_rectangle (cr, 1.5, 0.5, width-2, height-1);
+
+ /* Draw fill */
+ murrine_set_gradient (cr, fill, widget->mrn_gradient, 1.5, 0.5, 0, height-1, widget->mrn_gradient.gradients, FALSE);
+
+ /* Draw the glass effect */
+ if (widget->glazestyle > 0)
+ {
+ widget->glazestyle == 2 ? cairo_fill_preserve (cr) : cairo_fill (cr);
+ if (widget->glazestyle < 3)
+ murrine_draw_curved_highlight (cr, 1, width, height);
+ else
+ murrine_draw_curved_highlight_top (cr, 1, width, height);
+ }
+ else
+ {
+ cairo_fill (cr);
+ murrine_draw_flat_highlight (cr, 1.5, 0.5, width-2, height);
+ }
+
+ murrine_set_gradient (cr, &highlight, widget->mrn_gradient, 1.5, 0.5, 0, height-1, widget->mrn_gradient.gradients, TRUE);
+ cairo_fill (cr);
+
+ if (widget->glazestyle == 4)
+ {
+ murrine_draw_curved_highlight_bottom (cr, 1, width, height+1);
+ MurrineRGB shadow;
+ murrine_shade (fill, &shadow, 1.0/widget->highlight_ratio);
+ murrine_set_gradient (cr, &shadow, widget->mrn_gradient, 1.5, 0.5, 0, height-1, widget->mrn_gradient.gradients, TRUE);
+ cairo_fill (cr);
+ }
+
+ cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
+
+ murrine_shade (fill, &highlight, widget->highlight_ratio*widget->innerborder_ratio);
+ murrine_draw_innerborder (cr, &highlight, fill, widget->mrn_gradient,
+ 2.5, 1.5,
+ width-5, height-3,
+ widget->mrn_gradient.gradients, TRUE,
+ widget->glazestyle, 0, MRN_CORNER_NONE);
+
+ /* Draw strokes */
+ while (tile_pos <= width+x_step-2)
+ {
+ cairo_move_to (cr, stroke_width/2-x_step, 0);
+ cairo_line_to (cr, stroke_width-x_step, 0);
+ cairo_line_to (cr, stroke_width/2-x_step, height);
+ cairo_line_to (cr, -x_step, height);
+
+ cairo_translate (cr, stroke_width, 0);
+ tile_pos += stroke_width;
+ }
+
+ murrine_set_color_rgba (cr, border, 0.15);
+ cairo_fill (cr);
+ cairo_restore (cr);
+
+ /* Draw the border */
+ murrine_set_color_rgba (cr, border, 0.8);
+ cairo_rectangle (cr, 1.5, 0.5, width-3, height-1);
+ cairo_stroke (cr);
+}
+
+static void
+murrine_rgba_draw_menubar (cairo_t *cr,
+ const MurrineColors *colors,
+ const WidgetParameters *widget,
+ int x, int y, int width, int height,
+ int menubarstyle)
+{
+ const MurrineRGB *fill = &colors->bg[0];
+
+ cairo_translate (cr, x, y);
+ cairo_rectangle (cr, 0, 0, width, height);
+
+ cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
+
+ /* Glass menubar */
+ if (menubarstyle == 1)
+ {
+ /* XXX: should use another gradient rgba_opacity */
+ MurrineRGB highlight;
+ murrine_set_gradient (cr, fill, widget->mrn_gradient, 0, 0, 0, height, widget->mrn_gradient.gradients, FALSE);
+ murrine_shade (fill, &highlight, widget->highlight_ratio);
+
+ if (widget->glazestyle > 0)
+ {
+ widget->glazestyle == 2 ? cairo_fill_preserve (cr) : cairo_fill (cr);
+ if (widget->glazestyle < 3)
+ murrine_draw_curved_highlight (cr, 0, width, height);
+ else
+ murrine_draw_curved_highlight_top (cr, 0, width, height);
+ }
+ else
+ {
+ cairo_fill (cr);
+ murrine_draw_flat_highlight (cr, 0, 0, width, height);
+ }
+
+ murrine_set_gradient (cr, &highlight, widget->mrn_gradient, 0, 0, 0, height, widget->mrn_gradient.gradients, TRUE);
+ cairo_fill (cr);
+
+ if (widget->glazestyle == 4)
+ {
+ murrine_draw_curved_highlight_bottom (cr, 0, width, height);
+ MurrineRGB shadow;
+ murrine_shade (fill, &shadow, 1.0/widget->highlight_ratio);
+ murrine_set_color_rgb (cr, &shadow);
+ cairo_fill (cr);
+ }
+
+ cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
+
+ if (widget->glazestyle == 2)
+ {
+ murrine_draw_innerborder (cr, &highlight, fill, widget->mrn_gradient,
+ 1.5, 1.5,
+ width-3, height-3,
+ widget->mrn_gradient.gradients, TRUE,
+ widget->glazestyle, widget->roundness, widget->corners);
+ }
+ }
+ else if (menubarstyle == 2) /* Gradient menubar */
+ {
+ cairo_pattern_t *pattern;
+ MurrineRGB lower;
+ murrine_shade (fill, &lower, 0.95);
+ pattern = cairo_pattern_create_linear (0, 0, 0, height);
+ cairo_pattern_add_color_stop_rgba (pattern, 0.0, fill->r, fill->g, fill->b, MENUBAR_OPACITY);
+ cairo_pattern_add_color_stop_rgba (pattern, 1.0, lower.r, lower.g, lower.b, MENUBAR_OPACITY);
+ cairo_set_source (cr, pattern);
+ cairo_fill (cr);
+ cairo_pattern_destroy (pattern);
+
+ cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
+ }
+ else if (menubarstyle == 3) /* Striped menubar */
+ {
+ cairo_pattern_t *pattern;
+ MurrineRGB low, top;
+ murrine_shade (fill, &top, 0.9);
+ murrine_shade (fill, &low, 1.1);
+ pattern = cairo_pattern_create_linear (0, 0, 0, height);
+ cairo_pattern_add_color_stop_rgba (pattern, 0.0, top.r, top.g, top.b, MENUBAR_STRIPED_OPACITY);
+ cairo_pattern_add_color_stop_rgba (pattern, 1.0, low.r, low.g, low.b, MENUBAR_STRIPED_OPACITY);
+ cairo_set_source (cr, pattern);
+ cairo_fill (cr);
+
+ cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
+
+ cairo_pattern_destroy (pattern);
+ int counter = -height;
+ cairo_set_line_width (cr, 1.0);
+ murrine_shade (&low, &low, 0.9);
+ murrine_set_color_rgba (cr, &low, MENUBAR_STRIPED_OPACITY);
+ while (counter < width)
+ {
+ cairo_move_to (cr, counter, height);
+ cairo_line_to (cr, counter+height, 0);
+ cairo_stroke (cr);
+ counter += 5;
+ }
+ }
+ else /* Flat menubar */
+ {
+ murrine_set_color_rgba (cr, fill, MENUBAR_OPACITY);
+ cairo_fill (cr);
+
+ cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
+ }
+
+ /* Draw bottom line */
+ if (menubarstyle == 1 && widget->glazestyle == 2)
+ cairo_rectangle (cr, 0.5, 0.5, width-1, height-1);
+#ifndef HAVE_MACMENU
+ else
+ {
+ cairo_set_line_width (cr, 1.0);
+ cairo_move_to (cr, 0, height-0.5);
+ cairo_line_to (cr, width, height-0.5);
+ }
+
+ murrine_set_color_rgb (cr, &colors->shade[4]);
+ cairo_stroke (cr);
+#endif
+}
+
+static void
+murrine_rgba_draw_toolbar (cairo_t *cr,
+ const MurrineColors *colors,
+ const WidgetParameters *widget,
+ const ToolbarParameters *toolbar,
+ int x, int y, int width, int height)
+{
+ const MurrineRGB *dark = &colors->shade[4];
+ const MurrineRGB *fill = &colors->bg[0];
+ const MurrineRGB *top = &colors->shade[0];
+
+ cairo_translate (cr, x, y);
+ cairo_rectangle (cr, 0, 0, width, height);
+
+ cairo_set_line_width (cr, 1.0);
+ cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
+
+#ifdef HAVE_MACMENU
+ murrine_set_color_rgba (cr, fill, WINDOW_OPACITY);
+ cairo_fill (cr);
+ cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
+#else
+ /* Glass toolbar */
+ if (toolbar->style == 1)
+ {
+ /* XXX: should use another gradient rgba_opacity */
+ MurrineRGB highlight;
+ murrine_set_gradient (cr, fill, widget->mrn_gradient, 0, 0, 0, height, widget->mrn_gradient.gradients, FALSE);
+ murrine_shade (fill, &highlight, widget->highlight_ratio);
+
+ /* Glass effect */
+ if (widget->glazestyle > 0)
+ {
+ widget->glazestyle == 2 ? cairo_fill_preserve (cr) : cairo_fill (cr);
+ if (widget->glazestyle < 3)
+ murrine_draw_curved_highlight (cr, 0, width, height);
+ else
+ murrine_draw_curved_highlight_top (cr, 0, width, height);
+ }
+ else
+ {
+ cairo_fill (cr);
+ murrine_draw_flat_highlight (cr, 0, 0, width, height);
+ }
+
+ murrine_set_gradient (cr, &highlight, widget->mrn_gradient, 0, 0, 0, height, widget->mrn_gradient.gradients, TRUE);
+ cairo_fill (cr);
+
+ if (widget->glazestyle == 4)
+ {
+ murrine_draw_curved_highlight_bottom (cr, 0, width, height);
+ MurrineRGB shadow;
+ murrine_shade (fill, &shadow, 1.0/widget->highlight_ratio);
+ murrine_set_color_rgb (cr, &shadow);
+ cairo_fill (cr);
+ }
+
+ cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
+ }
+ else if (toolbar->style == 2)
+ {
+ cairo_pattern_t *pattern;
+ MurrineRGB lower;
+ murrine_shade (fill, &lower, 0.95);
+ pattern = cairo_pattern_create_linear (0, 0, 0, height);
+ cairo_pattern_add_color_stop_rgba (pattern, 0.0, fill->r, fill->g, fill->b, TOOLBAR_OPACITY);
+ cairo_pattern_add_color_stop_rgba (pattern, 1.0, lower.r, lower.g, lower.b, TOOLBAR_OPACITY);
+ cairo_set_source (cr, pattern);
+ cairo_fill (cr);
+ cairo_pattern_destroy (pattern);
+
+ cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
+ }
+ else /* Flat toolbar */
+ {
+ murrine_set_color_rgba (cr, fill, TOOLBAR_OPACITY);
+ cairo_fill (cr);
+
+ cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
+
+ /* Draw highlight */
+ if (!toolbar->topmost)
+ {
+ cairo_move_to (cr, 0, 0.5);
+ cairo_line_to (cr, width, 0.5);
+ murrine_set_color_rgba (cr, top, 0.5);
+ cairo_stroke (cr);
+ }
+ }
+#endif
+
+ /* Draw shadow */
+ cairo_move_to (cr, 0, height-0.5);
+ cairo_line_to (cr, width, height-0.5);
+ murrine_set_color_rgb (cr, dark);
+ cairo_stroke (cr);
+}
+
+static void
+murrine_get_frame_gap_clip (int x, int y, int width, int height,
+ const FrameParameters *frame,
+ MurrineRectangle *bevel,
+ MurrineRectangle *border)
+{
+ if (frame->gap_side == MRN_GAP_TOP)
+ {
+ MURRINE_RECTANGLE_SET ((*bevel), 1.5 + frame->gap_x, -0.5,
+ frame->gap_width - 3, 2.0);
+ MURRINE_RECTANGLE_SET ((*border), 0.5 + frame->gap_x, -0.5,
+ frame->gap_width - 2, 2.0);
+ }
+ else if (frame->gap_side == MRN_GAP_BOTTOM)
+ {
+ MURRINE_RECTANGLE_SET ((*bevel), 1.5 + frame->gap_x, height - 2.5,
+ frame->gap_width - 3, 2.0);
+ MURRINE_RECTANGLE_SET ((*border), 0.5 + frame->gap_x, height - 1.5,
+ frame->gap_width - 2, 2.0);
+ }
+ else if (frame->gap_side == MRN_GAP_LEFT)
+ {
+ MURRINE_RECTANGLE_SET ((*bevel), -0.5, 1.5 + frame->gap_x,
+ 2.0, frame->gap_width - 3);
+ MURRINE_RECTANGLE_SET ((*border), -0.5, 0.5 + frame->gap_x,
+ 1.0, frame->gap_width - 2);
+ }
+ else if (frame->gap_side == MRN_GAP_RIGHT)
+ {
+ MURRINE_RECTANGLE_SET ((*bevel), width - 2.5, 1.5 + frame->gap_x,
+ 2.0, frame->gap_width - 3);
+ MURRINE_RECTANGLE_SET ((*border), width - 1.5, 0.5 + frame->gap_x,
+ 1.0, frame->gap_width - 2);
+ }
+}
+
+static void
+murrine_rgba_draw_frame (cairo_t *cr,
+ const MurrineColors *colors,
+ const WidgetParameters *widget,
+ const FrameParameters *frame,
+ int x, int y, int width, int height)
+{
+ MurrineRGB *border = frame->border;
+ MurrineRectangle bevel_clip;
+ MurrineRectangle frame_clip;
+
+ const MurrineRGB *dark = &colors->shade[5];
+
+ MurrineRGB highlight, shadow_color;
+
+ murrine_shade (&colors->bg[0], &highlight, 1.15);
+ murrine_shade (&colors->bg[0], &shadow_color, 0.4);
+
+ if (frame->shadow == MRN_SHADOW_NONE)
+ return;
+
+ if (frame->gap_x != -1)
+ murrine_get_frame_gap_clip (x, y, width, height,
+ frame, &bevel_clip, &frame_clip);
+
+ cairo_set_line_width (cr, 1.0);
+ cairo_translate (cr, x+0.5, y+0.5);
+
+ /* save everything */
+ cairo_save (cr);
+
+ /* Set clip for the bevel */
+ if (frame->gap_x != -1)
+ {
+ /* Set clip for gap */
+ cairo_set_fill_rule (cr, CAIRO_FILL_RULE_EVEN_ODD);
+ cairo_rectangle (cr, -0.5, -0.5, width, height);
+ cairo_rectangle (cr, bevel_clip.x, bevel_clip.y, bevel_clip.width, bevel_clip.height);
+ cairo_clip (cr);
+ }
+
+ /* Draw the bevel */
+ if (frame->shadow == MRN_SHADOW_ETCHED_IN || frame->shadow == MRN_SHADOW_ETCHED_OUT)
+ {
+ if (frame->shadow == MRN_SHADOW_ETCHED_IN)
+ murrine_rounded_rectangle (cr, 1, 1, width-2, height-2, widget->roundness, widget->corners);
+ else
+ murrine_rounded_rectangle (cr, 0, 0, width-2, height-2, widget->roundness, widget->corners);
+ murrine_set_color_rgba (cr, &highlight, 0.5);
+ cairo_stroke (cr);
+ }
+ else if (frame->shadow != MRN_SHADOW_NONE && frame->shadow != MRN_SHADOW_FLAT)
+ {
+ ShadowParameters shadow;
+ shadow.corners = widget->corners;
+ shadow.shadow = frame->shadow;
+ cairo_move_to (cr, 1, height-2);
+ cairo_line_to (cr, 1, 1);
+ cairo_line_to (cr, width-1.5, 1);
+ if (frame->shadow & MRN_SHADOW_OUT)
+ murrine_set_color_rgba (cr, &highlight, 0.5);
+ else
+ murrine_set_color_rgba (cr, &shadow_color, 0.13);
+ cairo_stroke (cr);
+ cairo_move_to (cr, width-2, 1.5);
+ cairo_line_to (cr, width-2, height-2);
+ cairo_line_to (cr, 0, height-2);
+ if (frame->shadow & MRN_SHADOW_OUT)
+ murrine_set_color_rgba (cr, &shadow_color, 0.13);
+ else
+ murrine_set_color_rgba (cr, &highlight, 0.5);
+ cairo_stroke (cr);
+ }
+
+ /* restore the previous clip region */
+ cairo_restore (cr);
+ cairo_save (cr);
+ if (frame->gap_x != -1)
+ {
+ /* Set clip for gap */
+ cairo_set_fill_rule (cr, CAIRO_FILL_RULE_EVEN_ODD);
+ cairo_rectangle (cr, -0.5, -0.5, width, height);
+ cairo_rectangle (cr, frame_clip.x, frame_clip.y, frame_clip.width, frame_clip.height);
+ cairo_clip (cr);
+ }
+
+ /* Draw frame */
+ if (frame->shadow == MRN_SHADOW_ETCHED_IN || frame->shadow == MRN_SHADOW_ETCHED_OUT)
+ {
+ murrine_set_color_rgb (cr, dark);
+ if (frame->shadow == MRN_SHADOW_ETCHED_IN)
+ murrine_rounded_rectangle (cr, 0, 0, width-2, height-2, widget->roundness, widget->corners);
+ else
+ murrine_rounded_rectangle (cr, 1, 1, width-2, height-2, widget->roundness, widget->corners);
+ }
+ else
+ {
+ murrine_set_color_rgb (cr, border);
+ murrine_rounded_rectangle (cr, 0, 0, width-1, height-1, widget->roundness, widget->corners);
+ }
+ cairo_stroke (cr);
+ cairo_restore (cr);
+}
+
+static void
+murrine_rgba_draw_separator (cairo_t *cr,
+ const MurrineColors *colors,
+ const WidgetParameters *widget,
+ const SeparatorParameters *separator,
+ int x, int y, int width, int height)
+{
+ const MurrineRGB *dark = &colors->shade[4];
+ const MurrineRGB *highlight = &colors->shade[0];
+
+ if (separator->horizontal)
+ {
+ cairo_set_line_width (cr, 1.0);
+ cairo_translate (cr, x, y+0.5);
+
+ cairo_move_to (cr, 0.0, 0.0);
+ cairo_line_to (cr, width+1, 0.0);
+ murrine_set_color_rgb (cr, dark);
+ cairo_stroke (cr);
+
+#ifndef HAVE_MACMENU
+ cairo_move_to (cr, 0.0, 1.0);
+ cairo_line_to (cr, width, 1.0);
+ murrine_set_color_rgba (cr, highlight, 0.5);
+ cairo_stroke (cr);
+#endif
+ }
+ else
+ {
+ cairo_set_line_width (cr, 1.0);
+ cairo_translate (cr, x+0.5, y);
+
+ cairo_move_to (cr, 0.0, 0.0);
+ cairo_line_to (cr, 0.0, height);
+ murrine_set_color_rgb (cr, dark);
+ cairo_stroke (cr);
+
+#ifndef HAVE_MACMENU
+ cairo_move_to (cr, 1.0, 0.0);
+ cairo_line_to (cr, 1.0, height);
+ murrine_set_color_rgba (cr, highlight, 0.5);
+ cairo_stroke (cr);
+#endif
+ }
+}
+
+static void
+murrine_rgba_draw_tab (cairo_t *cr,
+ const MurrineColors *colors,
+ const WidgetParameters *widget,
+ const TabParameters *tab,
+ int x, int y, int width, int height)
+{
+ const float RADIUS = 3.0;
+ int corners;
+ double strip_size;
+ const MurrineRGB *stripe_fill = &colors->spot[1];
+ const MurrineRGB *stripe_border = &colors->spot[2];
+ const MurrineRGB *fill;
+ MurrineRGB *border;
+ cairo_pattern_t* pattern;
+
+ fill = &colors->bg[widget->state_type];
+
+ if (!widget->active)
+ border = (MurrineRGB*)&colors->shade[5];
+ else
+ border = (MurrineRGB*)&colors->shade[4];
+
+ /* Set clip */
+ cairo_rectangle (cr, x, y, width, height);
+ cairo_clip (cr);
+ cairo_new_path (cr);
+
+ /* Translate and set line width */
+ cairo_set_line_width (cr, 1.0);
+ cairo_translate (cr, x+0.5, y+0.5);
+
+ /* Make the tabs slightly bigger than they should be, to create a gap */
+ /* And calculate the strip size too, while you're at it */
+ if (tab->gap_side == MRN_GAP_TOP || tab->gap_side == MRN_GAP_BOTTOM)
+ {
+ height += RADIUS;
+ strip_size = (tab->gap_side == MRN_GAP_TOP ? 2.0/height : 2.0/(height-2));
+
+ if (tab->gap_side == MRN_GAP_TOP)
+ {
+ cairo_translate (cr, 0.0, -3.0); /* gap at the other side */
+ corners = MRN_CORNER_BOTTOMLEFT | MRN_CORNER_BOTTOMRIGHT;
+ }
+ else
+ corners = MRN_CORNER_TOPLEFT | MRN_CORNER_TOPRIGHT;
+ }
+ else
+ {
+ width += RADIUS;
+ strip_size = (tab->gap_side == MRN_GAP_LEFT ? 2.0/width : 2.0/(width-2));
+
+ if (tab->gap_side == MRN_GAP_LEFT)
+ {
+ cairo_translate (cr, -3.0, 0.0); /* gap at the other side */
+ corners = MRN_CORNER_TOPRIGHT | MRN_CORNER_BOTTOMRIGHT;
+ }
+ else
+ corners = MRN_CORNER_TOPLEFT | MRN_CORNER_BOTTOMLEFT;
+ }
+
+/* murrine_set_color_rgba (cr, &colors->bg[0], 0.0); */
+/* /* Draw (erase) the background */
+/* cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
+ cairo_paint (cr); */
+
+ /* Set tab shape */
+ if (widget->roundness < 2)
+ cairo_rectangle (cr, 0, 0, width-1, height-1);
+ else
+ clearlooks_rounded_rectangle (cr, 0, 0, width-1, height-1, widget->roundness, corners);
+
+ /* Draw fill */
+ if (!widget->active)
+ {
+ murrine_set_color_rgba (cr, fill, NOTEBOOK_OPACITY);
+ cairo_fill (cr);
+ }
+
+ /* Draw highlight */
+/* if (!widget->active)
+ {
+ ShadowParameters shadow;
+
+ shadow.shadow = MRN_SHADOW_OUT;
+ shadow.corners = widget->corners;
+
+ murrine_draw_highlight_and_shade (cr, colors, &shadow,
+ width,
+ height, widget->roundness-1);
+ }
+*/
+ if (widget->active)
+ {
+ MurrineRGB shade1, shade2, shade3, shade4;
+
+ MurrineGradients mrn_gradient_custom = widget->mrn_gradient;
+ mrn_gradient_custom.gradient_stop_1 = get_decreased_ratio (widget->mrn_gradient.gradient_stop_1, 3.0);
+ mrn_gradient_custom.gradient_stop_2 = get_decreased_ratio (widget->mrn_gradient.gradient_stop_2, 3.0);
+ mrn_gradient_custom.gradient_stop_3 = get_decreased_ratio (widget->mrn_gradient.gradient_stop_3, 3.0);
+ mrn_gradient_custom.gradient_stop_4 = get_decreased_ratio (widget->mrn_gradient.gradient_stop_4, 3.0);
+
+ double custom_highlight_ratio = widget->highlight_ratio;
+ custom_highlight_ratio = get_decreased_ratio (widget->highlight_ratio, 2.0);
+
+ if (mrn_gradient_custom.gradients)
+ {
+ if (mrn_gradient_custom.has_gradient_stop)
+ {
+ murrine_shade (fill, &shade1, mrn_gradient_custom.gradient_stop_1*custom_highlight_ratio);
+ murrine_shade (fill, &shade2, mrn_gradient_custom.gradient_stop_2*custom_highlight_ratio);
+ murrine_shade (fill, &shade3, mrn_gradient_custom.gradient_stop_3);
+ murrine_shade (fill, &shade4, mrn_gradient_custom.gradient_stop_4);
+ }
+ else
+ {
+ murrine_shade (fill, &shade1, 1.1*custom_highlight_ratio);
+ murrine_shade (fill, &shade2, 1.0*custom_highlight_ratio);
+ murrine_shade (fill, &shade3, 1.0);
+ murrine_shade (fill, &shade4, 1.1);;
+ }
+ }
+ else
+ {
+ murrine_shade (fill, &shade1, 1.0*custom_highlight_ratio);
+ murrine_shade (fill, &shade2, 1.0*custom_highlight_ratio);
+ murrine_shade (fill, &shade3, 1.0);
+ murrine_shade (fill, &shade4, 1.0);
+ }
+
+ switch (tab->gap_side)
+ {
+ case MRN_GAP_TOP:
+ pattern = cairo_pattern_create_linear (0, height-2, 0, 0);
+ break;
+ case MRN_GAP_BOTTOM:
+ pattern = cairo_pattern_create_linear (0, 1, 0, height);
+ break;
+ case MRN_GAP_LEFT:
+ pattern = cairo_pattern_create_linear (width-2, 0, 1, 0);
+ break;
+ case MRN_GAP_RIGHT:
+ pattern = cairo_pattern_create_linear (1, 0, width-2, 0);
+ break;
+ }
+
+ if (widget->roundness < 2)
+ cairo_rectangle (cr, 0, 0, width-1, height-1);
+ else
+ clearlooks_rounded_rectangle (cr, 0, 0, width-1, height-1, widget->roundness, corners);
+
+ cairo_pattern_add_color_stop_rgba (pattern, 0.0, shade1.r, shade1.g, shade1.b, NOTEBOOK_OPACITY);
+ cairo_pattern_add_color_stop_rgba (pattern, 0.4, shade2.r, shade2.g, shade2.b, NOTEBOOK_OPACITY);
+ cairo_pattern_add_color_stop_rgba (pattern, 0.4, shade3.r, shade3.g, shade3.b, NOTEBOOK_OPACITY);
+ cairo_pattern_add_color_stop_rgba (pattern, 1.0, shade4.r, shade4.g, shade4.b, NOTEBOOK_OPACITY);
+ cairo_set_source (cr, pattern);
+ cairo_fill (cr);
+ cairo_pattern_destroy (pattern);
+
+ cairo_set_line_width (cr, 1.0);
+ murrine_set_color_rgba (cr, &colors->shade[0], 0.2);
+
+ if (widget->roundness < 2)
+ cairo_rectangle (cr, 1, 1, width-3, height-3);
+ else
+ clearlooks_rounded_rectangle (cr, 1, 1, width-3, height-3, widget->roundness, corners);
+
+ cairo_stroke (cr);
+ }
+ else
+ {
+ /* Draw shade */
+ switch (tab->gap_side)
+ {
+ case MRN_GAP_TOP:
+ pattern = cairo_pattern_create_linear (0, height-2, 0, 0);
+ break;
+ case MRN_GAP_BOTTOM:
+ pattern = cairo_pattern_create_linear (0, 0, 0, height);
+ break;
+ case MRN_GAP_LEFT:
+ pattern = cairo_pattern_create_linear (width-2, 0, 0, 0);
+ break;
+ case MRN_GAP_RIGHT:
+ pattern = cairo_pattern_create_linear (0, 0, width, 0);
+ break;
+ }
+
+ if (widget->roundness < 2)
+ cairo_rectangle (cr, 0, 0, width-1, height-1);
+ else
+ clearlooks_rounded_rectangle (cr, 0, 0, width-1, height-1, widget->roundness, corners);
+
+ cairo_pattern_add_color_stop_rgba (pattern, 0.0, stripe_fill->r, stripe_fill->g, stripe_fill->b, NOTEBOOK_OPACITY);
+ cairo_pattern_add_color_stop_rgba (pattern, strip_size, stripe_fill->r, stripe_fill->g, stripe_fill->b, NOTEBOOK_OPACITY);
+ cairo_pattern_add_color_stop_rgba (pattern, strip_size, fill->r, fill->g, fill->b, 0.0);
+ cairo_set_source (cr, pattern);
+ cairo_fill (cr);
+ cairo_pattern_destroy (pattern);
+ }
+
+ murrine_rounded_rectangle (cr, 0, 0, width-1, height-1, widget->roundness, corners);
+
+ if (widget->active)
+ {
+ murrine_set_color_rgb (cr, border);
+ cairo_stroke (cr);
+ }
+ else
+ {
+ switch (tab->gap_side)
+ {
+ case MRN_GAP_TOP:
+ pattern = cairo_pattern_create_linear (2, height-2, 2, 2);
+ break;
+ case MRN_GAP_BOTTOM:
+ pattern = cairo_pattern_create_linear (2, 2, 2, height);
+ break;
+ case MRN_GAP_LEFT:
+ pattern = cairo_pattern_create_linear (width-2, 2, 2, 2);
+ break;
+ case MRN_GAP_RIGHT:
+ pattern = cairo_pattern_create_linear (2, 2, width, 2);
+ break;
+ }
+
+ cairo_pattern_add_color_stop_rgb (pattern, 0.0, stripe_border->r, stripe_border->g, stripe_border->b);
+ cairo_pattern_add_color_stop_rgb (pattern, strip_size, stripe_border->r, stripe_border->g, stripe_border->b);
+ cairo_pattern_add_color_stop_rgb (pattern, strip_size, stripe_border->r, stripe_border->g, stripe_border->b);
+ cairo_pattern_add_color_stop_rgb (pattern, 0.8, border->r, border->g, border->b);
+ cairo_set_source (cr, pattern);
+ cairo_stroke (cr);
+ cairo_pattern_destroy (pattern);
+ }
+}
+
+static void
+murrine_rgba_draw_scrollbar_trough (cairo_t *cr,
+ const MurrineColors *colors,
+ const WidgetParameters *widget,
+ const ScrollBarParameters *scrollbar,
+ int x, int y, int width, int height)
+{
+ const MurrineRGB *bg = &colors->shade[scrollbar->stepperstyle < 1 ? 1 : 0];
+ const MurrineRGB *border = &colors->shade[scrollbar->stepperstyle < 1 ? 4 : 5];
+
+ cairo_set_line_width (cr, 1.0);
+
+ if (scrollbar->horizontal)
+ {
+ int tmp = height;
+ rotate_mirror_translate (cr, M_PI/2, x, y, FALSE, FALSE);
+ height = width;
+ width = tmp;
+ }
+ else
+ {
+ cairo_translate (cr, x, y);
+ }
+
+ /* Draw fill */
+ clearlooks_rounded_rectangle (cr, 1, 0, width-2, height, widget->roundness, widget->corners);
+ murrine_set_color_rgba (cr, bg, 0.4);
+ cairo_fill (cr);
+
+ /* Draw border */
+ murrine_rounded_rectangle (cr, 0.5, 0.5, width-1, height-1, widget->roundness, widget->corners);
+ murrine_set_color_rgba (cr, border, 0.82);
+ cairo_stroke (cr);
+}
+
+void
+murrine_rgba_draw_scrollbar_stepper (cairo_t *cr,
+ const MurrineColors *colors,
+ const WidgetParameters *widget,
+ const ScrollBarParameters *scrollbar,
+ int x, int y, int width, int height)
+{
+ const MurrineRGB *fill = &colors->bg[widget->state_type];
+ MurrineRGB border_normal;
+ MurrineRGB highlight;
+
+ murrine_shade (&colors->shade[7], &border_normal, 0.95);
+ murrine_shade (fill, &highlight, widget->highlight_ratio);
+
+ if (!scrollbar->horizontal)
+ murrine_exchange_axis (cr, &x, &y, &width, &height);
+
+ /* Border color */
+ murrine_mix_color (&border_normal, fill, 0.45, &border_normal);
+
+ cairo_translate (cr, x, y);
+ cairo_set_line_width (cr, 1.0);
+ cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
+
+ /* Draw the bg */
+ if (widget->roundness < 2)
+ cairo_rectangle (cr, 1, 1, width-2, height-2);
+ else
+ clearlooks_rounded_rectangle (cr, 0.5, 0.5, width-1, height-1, widget->roundness+1, widget->corners);
+ murrine_set_gradient (cr, fill, widget->mrn_gradient, 1, 1, 0, height-2, widget->mrn_gradient.gradients, FALSE);
+
+ cairo_save (cr);
+
+ int curve_pos = 1;
+ if (widget->glazestyle != 4)
+ curve_pos = 2;
+
+ /* Draw the glass effect */
+ if (widget->glazestyle > 0)
+ {
+ cairo_set_fill_rule (cr, CAIRO_FILL_RULE_EVEN_ODD);
+ widget->glazestyle == 2 ? cairo_fill_preserve (cr) : cairo_fill (cr);
+ if (widget->glazestyle < 3)
+ murrine_draw_curved_highlight (cr, curve_pos, width, height);
+ else
+ murrine_draw_curved_highlight_top (cr, curve_pos, width, height);
+ }
+ else
+ {
+ cairo_fill (cr);
+ murrine_draw_flat_highlight (cr, 1, 1, width-2, height-2);
+ }
+
+ murrine_set_gradient (cr, &highlight, widget->mrn_gradient, 1, 1, 0, height-2, widget->mrn_gradient.gradients, TRUE);
+ cairo_fill (cr);
+
+ if (widget->glazestyle == 4)
+ {
+ murrine_draw_curved_highlight_bottom (cr, curve_pos, width, height);
+ MurrineRGB shadow;
+ murrine_shade (fill, &shadow, 1.0/widget->highlight_ratio);
+ murrine_set_gradient (cr, &shadow, widget->mrn_gradient, 1, 1, 0, height-2, widget->mrn_gradient.gradients, TRUE);
+ cairo_fill (cr);
+ }
+
+ cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
+
+ /* Draw the white inner border */
+ if (widget->glazestyle != 4)
+ {
+ murrine_shade (fill, &highlight, widget->innerborder_ratio*widget->highlight_ratio);
+ murrine_draw_innerborder (cr, &highlight, fill, widget->mrn_gradient,
+ 1.5, 1.5,
+ width-3, height-3,
+ widget->mrn_gradient.gradients, TRUE,
+ widget->glazestyle, widget->roundness, widget->corners);
+ }
+
+ cairo_reset_clip (cr);
+ cairo_restore (cr);
+
+ murrine_set_color_rgb (cr, &border_normal);
+ /* Draw the border */
+ murrine_rounded_rectangle (cr, 0.5, 0.5, width-1, height-1, widget->roundness, widget->corners);
+ cairo_stroke (cr);
+}
+
+void
+murrine_rgba_draw_scrollbar_slider (cairo_t *cr,
+ const MurrineColors *colors,
+ const WidgetParameters *widget,
+ const ScrollBarParameters *scrollbar,
+ int x, int y, int width, int height)
+{
+ if (scrollbar->stepperstyle < 1)
+ {
+ if (scrollbar->junction & MRN_JUNCTION_BEGIN)
+ {
+ if (scrollbar->horizontal)
+ {
+ x -= 1;
+ width += 1;
+ }
+ else
+ {
+ y -= 1;
+ height += 1;
+ }
+ }
+ if (scrollbar->junction & MRN_JUNCTION_END)
+ {
+ if (scrollbar->horizontal)
+ width += 1;
+ else
+ height += 1;
+ }
+ }
+
+ /* Set colors */
+ MurrineRGB fill;
+ if (scrollbar->has_color)
+ fill = scrollbar->color;
+ else
+ fill = colors->bg[0];
+
+ MurrineRGB border;
+ murrine_shade (&colors->shade[7], &border, 0.95);
+ MurrineRGB highlight;
+
+ if (widget->prelight)
+ murrine_shade (&fill, &fill, 1.06);
+
+ murrine_shade (&fill, &highlight, widget->highlight_ratio);
+ /* Draw the border */
+ murrine_mix_color (&border, &fill, 0.5, &border);
+
+ if (scrollbar->horizontal)
+ cairo_translate (cr, x, y);
+
+ else
+ {
+ int tmp = height;
+ rotate_mirror_translate (cr, M_PI/2, x, y, FALSE, FALSE);
+ height = width;
+ width = tmp;
+ }
+
+ cairo_set_line_width (cr, 1.0);
+ cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
+
+ murrine_rounded_rectangle_fast (cr, 0.5, 0.5, width-1, height-1, widget->corners);
+ murrine_set_color_rgb (cr, &border);
+ cairo_stroke (cr);
+
+ cairo_rectangle (cr, 1, 1, width-2, height-2);
+ murrine_set_gradient (cr, &fill, widget->mrn_gradient, 1, 1, 0, height-2, widget->mrn_gradient.gradients, FALSE);
+
+ /* Draw the glass effect */
+ if (widget->glazestyle > 0)
+ {
+ widget->glazestyle == 2 ? cairo_fill_preserve (cr) : cairo_fill (cr);
+ if (widget->glazestyle < 3)
+ murrine_draw_curved_highlight (cr, 1, width, height);
+ else
+ murrine_draw_curved_highlight_top (cr, 1, width, height);
+ }
+ else
+ {
+ cairo_fill (cr);
+ murrine_draw_flat_highlight (cr, 1, 1, width-2, height-2);
+ }
+
+ murrine_set_gradient (cr, &highlight, widget->mrn_gradient, 1, 1, 0, height-2, widget->mrn_gradient.gradients, TRUE);
+ cairo_fill (cr);
+
+ if (widget->glazestyle == 4)
+ {
+ murrine_draw_curved_highlight_bottom (cr, 1, width, height);
+ MurrineRGB shadow;
+ murrine_shade (&fill, &shadow, 1.0/widget->highlight_ratio);
+ murrine_set_color_rgb (cr, &shadow);
+ cairo_fill (cr);
+ }
+
+ cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
+
+ if (widget->glazestyle != 4)
+ {
+ murrine_shade (&fill, &highlight, widget->innerborder_ratio*widget->highlight_ratio);
+ murrine_draw_innerborder (cr, &highlight, &fill, widget->mrn_gradient,
+ 1.5, 1.5,
+ width-3, height-3,
+ widget->mrn_gradient.gradients, TRUE,
+ widget->glazestyle, 0, MRN_CORNER_NONE);
+ }
+
+ /* Draw the options */
+ MurrineRGB style;
+ if (scrollbar->style > 0)
+ murrine_shade (&fill, &style, 0.55);
+
+ /* Draw the circles */
+ if (scrollbar->style == 1)
+ {
+ int circ_radius = 2;
+ int circ_space = 5;
+ int i;
+ int x1 = circ_space+circ_radius;
+ int y1 = height/2;
+ for (i = circ_space; i < width-circ_space; i += 2*circ_radius+circ_space)
+ {
+ cairo_move_to (cr, i, 1);
+ cairo_arc (cr, x1, y1, circ_radius, 0, M_PI*2);
+
+ x1 += 2*circ_radius+circ_space;
+
+ cairo_close_path (cr);
+ murrine_set_color_rgba (cr, &style, 0.15);
+ cairo_fill (cr);
+ }
+ }
+ if (scrollbar->style > 2)
+ {
+ /* Draw the diagonal strokes */
+ if (scrollbar->style < 5)
+ {
+ cairo_save (cr);
+ cairo_rectangle (cr, 1, 1, width-2, height-2);
+ cairo_clip (cr);
+ cairo_new_path (cr);
+ int counter = -width;
+ cairo_set_line_width (cr, 5); /* stroke width */
+ murrine_set_color_rgba (cr, &style, 0.08);
+ while (counter < height)
+ {
+ cairo_move_to (cr, width, counter);
+ cairo_line_to (cr, 0, counter+width);
+ cairo_stroke (cr);
+ counter += 12;
+ }
+ cairo_restore (cr);
+ }
+ /* Draw the horizontal strokes */
+ if (scrollbar->style > 4)
+ {
+ int stroke_width = 7;
+ int stroke_space = 5;
+ int i;
+ murrine_set_color_rgba (cr, &style, 0.08);
+ for (i = stroke_space; i < width-stroke_space; i += stroke_width+stroke_space)
+ {
+ cairo_move_to (cr, i, 1);
+ cairo_rel_line_to (cr, 0, height-2);
+ cairo_rel_line_to (cr, stroke_width, 0);
+ cairo_rel_line_to (cr, 0, -(height-2));
+ cairo_fill (cr);
+ }
+ }
+ }
+ /* Draw the handle */
+ if (scrollbar->style > 0 && scrollbar->style % 2 == 0 )
+ {
+ int bar_x = width/2 - 4;
+ cairo_translate (cr, 0.5, 0.5);
+ int i;
+ for (i=0; i<3; i++)
+ {
+ cairo_move_to (cr, bar_x, 4.5);
+ cairo_line_to (cr, bar_x, height-5.5);
+ murrine_set_color_rgb (cr, &border);
+ cairo_stroke (cr);
+
+ bar_x += 3;
+ }
+ }
+}
+/*
+static void
+murrine_rgba_draw_tooltip (cairo_t *cr,
+ const MurrineColors *colors,
+ const WidgetParameters *widget,
+ int x, int y, int width, int height)
+{
+ MurrineRGB border, highlight;
+
+ MurrineGradients mrn_gradient_custom = widget->mrn_gradient;
+
+ mrn_gradient_custom.gradient_stop_1 = get_decreased_ratio (widget->mrn_gradient.gradient_stop_1, 2.0);
+ mrn_gradient_custom.gradient_stop_2 = get_decreased_ratio (widget->mrn_gradient.gradient_stop_2, 2.0);
+ mrn_gradient_custom.gradient_stop_3 = get_decreased_ratio (widget->mrn_gradient.gradient_stop_3, 2.0);
+ mrn_gradient_custom.gradient_stop_4 = get_decreased_ratio (widget->mrn_gradient.gradient_stop_4, 2.0);
+
+ murrine_shade (&colors->bg[widget->state_type], &border, 0.6);
+ murrine_shade (&colors->bg[widget->state_type], &highlight, 1.0);
+
+ cairo_save (cr);
+
+ cairo_translate (cr, x, y);
+ cairo_set_line_width (cr, 1.0);
+ cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR);
+ cairo_paint (cr);
+ cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
+
+ murrine_set_gradient (cr, &colors->bg[widget->state_type], mrn_gradient_custom, 0, 0, 0, height, widget->mrn_gradient.gradients, FALSE);
+ murrine_rounded_rectangle (cr, 0, 0, width, height, widget->roundness, MRN_CORNER_ALL);
+ cairo_fill (cr);
+
+ murrine_set_gradient (cr, &highlight, mrn_gradient_custom, 0, 0, 0, height, widget->mrn_gradient.gradients, TRUE);
+ murrine_rounded_rectangle (cr, 0, 0, width, height/2, widget->roundness, MRN_CORNER_TOPLEFT | MRN_CORNER_TOPRIGHT);
+ cairo_fill (cr);
+
+ murrine_set_color_rgb (cr, &border);
+ murrine_rounded_rectangle (cr, 0.5, 0.5, width-1, height-1, widget->roundness, MRN_CORNER_ALL);
+ cairo_stroke (cr);
+
+ cairo_restore (cr);
+}
+*/
+static void
+murrine_rgba_draw_handle (cairo_t *cr,
+ const MurrineColors *colors,
+ const WidgetParameters *widget,
+ const HandleParameters *handle,
+ int x, int y, int width, int height)
+{
+ const MurrineRGB *dark = &colors->shade[5];
+
+ int bar_height;
+ int bar_width = 4;
+ int i, bar_y = 1;
+ int num_bars, bar_spacing;
+ num_bars = 3;
+ bar_spacing = 3;
+ bar_height = num_bars * bar_spacing;
+
+ if (handle->horizontal)
+ {
+ int tmp = height;
+ rotate_mirror_translate (cr, M_PI/2, x + 0.5 + width/2 - bar_height/2, y + height/2 - bar_width/2, FALSE, FALSE);
+ height = width;
+ width = tmp;
+ }
+ else
+ {
+ cairo_translate (cr, x + width/2 - bar_width/2, y + height/2 - bar_height/2 + 0.5);
+ }
+
+ cairo_set_line_width (cr, 1.0);
+
+ for (i=0; i<num_bars; i++)
+ {
+ cairo_move_to (cr, 0, bar_y);
+ cairo_line_to (cr, bar_width, bar_y);
+ murrine_set_color_rgb (cr, dark);
+ cairo_stroke (cr);
+
+ bar_y += bar_spacing;
+ }
+}
+
+
+static void
+murrine_rgba_draw_radiobutton (cairo_t * cr,
+ const MurrineColors *colors,
+ const WidgetParameters *widget,
+ const OptionParameters *status,
+ int x, int y, int width, int height,
+ double trans)
+{
+ MurrineRGB border;
+ const MurrineRGB *dot;
+
+ width = height = 15;
+
+ if (widget->state_type == GTK_STATE_INSENSITIVE)
+ {
+ border = colors->shade[4];
+ dot = &colors->shade[4];
+ }
+ else
+ {
+ border = colors->shade[6];
+ if (status->draw_bullet)
+ border = colors->spot[2];
+ dot = &colors->text[widget->state_type];
+ }
+ murrine_mix_color (&border, widget->state_type != GTK_STATE_INSENSITIVE ?
+ status->draw_bullet ? &colors->spot[1] : &colors->bg[0] : &colors->bg[0], 0.2, &border);
+
+ cairo_translate (cr, x, y);
+
+ cairo_set_line_width (cr, 2);
+ cairo_arc (cr, 7, 7, 6, 0, M_PI*2);
+ murrine_set_color_rgba (cr, &colors->shade[8], 0.12);
+ cairo_stroke (cr);
+
+ cairo_set_line_width (cr, 1.0);
+
+ cairo_arc (cr, 7, 7, 5.5, 0, M_PI*2);
+
+ if (widget->state_type != GTK_STATE_INSENSITIVE)
+ {
+ const MurrineRGB *bg = &colors->base[0];
+ if (status->draw_bullet)
+ bg = &colors->spot[1];
+ if (widget->glazestyle != 2)
+ {
+ MurrineRGB highlight;
+ murrine_shade (bg, &highlight, widget->highlight_ratio);
+ murrine_set_gradient (cr, &highlight, widget->mrn_gradient, 0, 0, 0, 14, widget->mrn_gradient.gradients, FALSE);
+ }
+ else
+ murrine_set_gradient (cr, bg, widget->mrn_gradient, 0, 0, 0, 14, widget->mrn_gradient.gradients, FALSE);
+ cairo_fill_preserve (cr);
+ }
+
+ murrine_set_color_rgb (cr, &border);
+ cairo_stroke (cr);
+
+ cairo_arc (cr, 7, 7, 5, 0, M_PI*2);
+ cairo_clip (cr);
+
+ if (widget->state_type != GTK_STATE_INSENSITIVE)
+ {
+ const MurrineRGB *bg = &colors->base[0];
+ if (status->draw_bullet)
+ bg = &colors->spot[1];
+
+ cairo_rectangle (cr, 0, 7, width, height);
+ if (widget->glazestyle == 2)
+ {
+ MurrineRGB highlight;
+ murrine_shade (bg, &highlight, widget->highlight_ratio);
+ murrine_set_gradient (cr, &highlight, widget->mrn_gradient, 0, 0, 0, 14, widget->mrn_gradient.gradients, FALSE);
+ }
+ else
+ murrine_set_gradient (cr, bg, widget->mrn_gradient, 0, 0, 0, 14, widget->mrn_gradient.gradients, FALSE);
+ cairo_fill (cr);
+ }
+
+ /* inconsistent state is missing? */
+ if (status->draw_bullet)
+ {
+ cairo_arc (cr, 7, 7, 2, 0, M_PI*2);
+ /* murrine_set_color_rgb (cr, dot); */
+ murrine_set_color_rgba (cr, dot, trans);
+ cairo_fill (cr);
+ }
+
+ cairo_restore (cr);
+}
+
+static void
+murrine_rgba_draw_checkbox (cairo_t * cr,
+ const MurrineColors *colors,
+ const WidgetParameters *widget,
+ const OptionParameters *status,
+ int x, int y, int width, int height,
+ double trans)
+{
+ MurrineRGB border;
+ const MurrineRGB *dot;
+
+ width = height = 13;
+
+ if (widget->state_type == GTK_STATE_INSENSITIVE)
+ {
+ border = colors->shade[4];
+ dot = &colors->shade[4];
+ }
+ else
+ {
+ border = colors->shade[6];
+ if (status->draw_bullet)
+ border = colors->spot[2];
+ dot = &colors->text[widget->state_type];
+ }
+ murrine_mix_color (&border, widget->state_type != GTK_STATE_INSENSITIVE ?
+ status->draw_bullet ? &colors->spot[1] : &colors->bg[0] : &colors->bg[0], 0.24, &border);
+
+ cairo_translate (cr, x, y);
+ cairo_set_line_width (cr, 1.0);
+
+ if (widget->xthickness > 2 && widget->ythickness > 2)
+ {
+ cairo_rectangle (cr, 0.5, 0.5, width-1, height-1);
+ murrine_set_color_rgba (cr, &colors->shade[8], 0.12);
+ cairo_stroke (cr);
+
+ /* Draw the rectangle for the checkbox itself */
+ cairo_rectangle (cr, 1.5, 1.5, width-3, height-3);
+ }
+ else
+ {
+ cairo_rectangle (cr, 0.5, 0.5, width-1, height-1);
+ }
+
+
+ if (widget->state_type != GTK_STATE_INSENSITIVE)
+ {
+ const MurrineRGB *bg = &colors->base[0];
+ if (status->draw_bullet)
+ bg = &colors->spot[1];
+
+ if (widget->glazestyle == 2)
+ {
+ MurrineRGB highlight;
+ murrine_shade (bg, &highlight, widget->highlight_ratio);
+ murrine_set_gradient (cr, &highlight, widget->mrn_gradient, 0, 0, 0, 14, widget->mrn_gradient.gradients, FALSE);
+ }
+ else
+ murrine_set_gradient (cr, bg, widget->mrn_gradient, 0, 0, 0, 14, widget->mrn_gradient.gradients, FALSE);
+ cairo_fill_preserve (cr);
+ }
+
+ murrine_set_color_rgb (cr, &border);
+ cairo_stroke (cr);
+
+ if (widget->state_type != GTK_STATE_INSENSITIVE)
+ {
+ const MurrineRGB *bg = &colors->base[0];
+ if (status->draw_bullet)
+ bg = &colors->spot[1];
+
+ MurrineRGB highlight;
+ murrine_shade (bg, &highlight, widget->highlight_ratio);
+ if (widget->xthickness > 2 && widget->ythickness > 2)
+ cairo_rectangle (cr, 2, 2, width-4, (height-4)/2);
+ else
+ cairo_rectangle (cr, 1, 1, width-2, (height-2)/2);
+
+ if (widget->glazestyle != 2)
+ {
+ MurrineRGB highlight;
+ murrine_shade (bg, &highlight, widget->highlight_ratio);
+ murrine_set_gradient (cr, &highlight, widget->mrn_gradient, 0, 0, 0, 14, widget->mrn_gradient.gradients, FALSE);
+ }
+ else
+ murrine_set_gradient (cr, bg, widget->mrn_gradient, 0, 0, 0, 14, widget->mrn_gradient.gradients, FALSE);
+ cairo_fill (cr);
+ }
+
+ cairo_scale (cr, width / 13.0, height / 13.0);
+ if (status->draw_bullet)
+ {
+ if (status->inconsistent) /* Inconsistent */
+ {
+ cairo_set_line_width (cr, 2.0);
+ cairo_move_to (cr, 3, height*0.5);
+ cairo_line_to (cr, width-3, height*0.5);
+ }
+ else
+ {
+ cairo_translate (cr, -2, 0);
+ /*
+ if (widget && widget->parent && GTK_IS_MENU(widget->parent))
+ cairo_translate (cr, 0, 0);
+ */
+ cairo_move_to (cr, 4, 8);
+ cairo_rel_line_to (cr, 5, 4);
+ cairo_rel_curve_to (cr, 1.4, -5, -1, -1, 5.7, -12.5);
+ cairo_rel_curve_to (cr, -4, 4, -4, 4, -6.7, 9.3);
+ cairo_rel_line_to (cr, -2.3, -2.5);
+ }
+
+ murrine_set_color_rgba (cr, dot, trans);
+ cairo_fill (cr);
+ }
+}
+
+static void
+murrine_rgba_draw_menu_frame (cairo_t *cr,
+ const MurrineColors *colors,
+ const WidgetParameters *widget,
+ int x, int y, int width, int height,
+ int menustyle)
+{
+ const MurrineRGB *border = &colors->shade[5];
+ uint8 corners = (menustyle == 1 ? MRN_CORNER_TOPRIGHT | MRN_CORNER_BOTTOMRIGHT :
+ MRN_CORNER_TOPRIGHT |
+ MRN_CORNER_BOTTOMLEFT | MRN_CORNER_BOTTOMRIGHT);
+
+ cairo_translate (cr, x, y);
+ cairo_set_line_width (cr, 1.0);
+ cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR);
+ cairo_paint (cr);
+ cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
+
+ clearlooks_rounded_rectangle (cr, 0.5, 0.5, width-1, height-1, widget->roundness, corners);
+ murrine_set_color_rgba (cr, &colors->bg[0], MENU_OPACITY);
+ cairo_fill (cr);
+
+ murrine_rounded_rectangle (cr, 0.5, 0.5, width-1, height-1, widget->roundness, corners);
+ murrine_set_color_rgb (cr, border);
+ cairo_stroke (cr);
+
+ if (menustyle == 1)
+ {
+ MurrineRGB *fill = (MurrineRGB*)&colors->spot[1];
+ MurrineRGB border2;
+ murrine_shade (fill, &border2, 0.5);
+
+ cairo_rectangle (cr, 0.5, 0.5, 3, height-1);
+ murrine_set_color_rgb (cr, &border2);
+ cairo_stroke_preserve (cr);
+
+ murrine_set_color_rgb (cr, fill);
+ cairo_fill (cr);
+ }
+}
+
+static void
+murrine_rgba_draw_statusbar (cairo_t *cr,
+ const MurrineColors *colors,
+ const WidgetParameters *widget,
+ int x, int y, int width, int height)
+{
+ const MurrineRGB *dark = &colors->shade[4];
+ const MurrineRGB *highlight = &colors->shade[0];
+
+ cairo_set_line_width (cr, 1);
+ cairo_translate (cr, x, y+0.5);
+ cairo_move_to (cr, 0, 0);
+ cairo_line_to (cr, width, 0);
+ murrine_set_color_rgb (cr, dark);
+ cairo_stroke (cr);
+
+ cairo_translate (cr, 0, 1);
+ cairo_move_to (cr, 0, 0);
+ cairo_line_to (cr, width, 0);
+ murrine_set_color_rgba (cr, highlight, 0.5);
+ cairo_stroke (cr);
+}
+
+void
+murrine_register_style_rgba (MurrineStyleFunctions *functions)
+{
+ functions->draw_button = murrine_rgba_draw_button;
+ functions->draw_entry = murrine_rgba_draw_entry;
+ functions->draw_scale_trough = murrine_rgba_draw_scale_trough;
+ functions->draw_progressbar_trough = murrine_rgba_draw_progressbar_trough;
+ functions->draw_progressbar_fill = murrine_rgba_draw_progressbar_fill;
+ functions->draw_menubar = murrine_rgba_draw_menubar;
+ functions->draw_toolbar = murrine_rgba_draw_toolbar;
+ functions->draw_frame = murrine_rgba_draw_frame;
+ functions->draw_separator = murrine_rgba_draw_separator;
+ functions->draw_tab = murrine_rgba_draw_tab;
+ functions->draw_scrollbar_trough = murrine_rgba_draw_scrollbar_trough;
+ functions->draw_scrollbar_stepper = murrine_rgba_draw_scrollbar_stepper;
+ functions->draw_scrollbar_slider = murrine_rgba_draw_scrollbar_slider;
+ functions->draw_handle = murrine_rgba_draw_handle;
+ /* functions->draw_tooltip = murrine_rgba_draw_tooltip; */
+ functions->draw_radiobutton = murrine_rgba_draw_radiobutton;
+ functions->draw_checkbox = murrine_rgba_draw_checkbox;
+ functions->draw_menu_frame = murrine_rgba_draw_menu_frame;
+ functions->draw_statusbar = murrine_rgba_draw_statusbar;
+}
Added: trunk/src/murrine_draw_rgba.h
==============================================================================
--- (empty file)
+++ trunk/src/murrine_draw_rgba.h Mon Feb 11 23:01:49 2008
@@ -0,0 +1,37 @@
+/* Murrine theme engine
+ * Copyright (C) 2007 Andrea Cimitan
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * 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; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ */
+
+#ifndef MURRINE_DRAW_RGBA_H
+#define MURRINE_DRAW_RGBA_H
+
+#include "murrine_types.h"
+
+#include <gtk/gtk.h>
+#include <gdk/gdk.h>
+
+#include <cairo.h>
+
+G_GNUC_INTERNAL void murrine_draw_button_rgba (cairo_t *cr,
+ const MurrineColors *colors,
+ const WidgetParameters *widget,
+ int x, int y, int width, int height,
+ boolean vertical);
+
+#endif /* MURRINE_DRAW_RGBA_H */
Added: trunk/src/murrine_rc_style.c
==============================================================================
--- (empty file)
+++ trunk/src/murrine_rc_style.c Mon Feb 11 23:01:49 2008
@@ -0,0 +1,643 @@
+/* Murrine theme engine
+ * Copyright (C) 2007 Andrea Cimitan
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * 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; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ */
+
+#include "murrine_style.h"
+#include "murrine_rc_style.h"
+
+#include "animation.h"
+
+static void murrine_rc_style_init (MurrineRcStyle *style);
+#ifdef HAVE_ANIMATION
+static void murrine_rc_style_finalize (GObject *object);
+#endif
+static void murrine_rc_style_class_init (MurrineRcStyleClass *klass);
+static GtkStyle *murrine_rc_style_create_style (GtkRcStyle *rc_style);
+static guint murrine_rc_style_parse (GtkRcStyle *rc_style,
+ GtkSettings *settings,
+ GScanner *scanner);
+static void murrine_rc_style_merge (GtkRcStyle *dest,
+ GtkRcStyle *src);
+
+static GtkRcStyleClass *parent_class;
+
+GType murrine_type_rc_style = 0;
+
+enum
+{
+ TOKEN_ANIMATION = G_TOKEN_LAST + 1,
+ TOKEN_COLORIZE_SCROLLBAR,
+ TOKEN_CONTRAST,
+ TOKEN_GLAZESTYLE,
+ TOKEN_GRADIENT_STOP_1,
+ TOKEN_GRADIENT_STOP_2,
+ TOKEN_GRADIENT_STOP_3,
+ TOKEN_GRADIENT_STOP_4,
+ TOKEN_GRADIENTS,
+ TOKEN_HIGHLIGHT_RATIO,
+ TOKEN_INNERBORDER_RATIO,
+ TOKEN_LISTVIEWHEADERSTYLE,
+ TOKEN_LISTVIEWSTYLE,
+ TOKEN_MENUBARITEMSTYLE,
+ TOKEN_MENUBARSTYLE,
+ TOKEN_MENUITEMSTYLE,
+ TOKEN_MENUSTYLE,
+ TOKEN_RGBA,
+ TOKEN_ROUNDNESS,
+ TOKEN_SCROLLBAR_COLOR,
+ TOKEN_SCROLLBARSTYLE,
+ TOKEN_SLIDERSTYLE,
+ TOKEN_STEPPERSTYLE,
+ TOKEN_STYLE,
+ TOKEN_TOOLBARSTYLE,
+
+ TOKEN_CANDIDO,
+ TOKEN_CLEARLOOKS,
+ TOKEN_MIST,
+ TOKEN_MURRINE,
+ TOKEN_NODOKA,
+
+ TOKEN_TRUE,
+ TOKEN_FALSE,
+
+ /* stuff to ignore */
+ TOKEN_HILIGHT_RATIO,
+ TOKEN_SQUAREDSTYLE
+};
+
+static struct
+{
+ const gchar *name;
+ guint token;
+}
+theme_symbols[] =
+{
+ { "animation", TOKEN_ANIMATION },
+ { "colorize_scrollbar", TOKEN_COLORIZE_SCROLLBAR },
+ { "contrast", TOKEN_CONTRAST },
+ { "glazestyle", TOKEN_GLAZESTYLE },
+ { "gradient_stop_1", TOKEN_GRADIENT_STOP_1 },
+ { "gradient_stop_2", TOKEN_GRADIENT_STOP_2 },
+ { "gradient_stop_3", TOKEN_GRADIENT_STOP_3 },
+ { "gradient_stop_4", TOKEN_GRADIENT_STOP_4 },
+ { "gradients", TOKEN_GRADIENTS },
+ { "highlight_ratio", TOKEN_HIGHLIGHT_RATIO },
+ { "innerborder_ratio", TOKEN_INNERBORDER_RATIO },
+ { "listviewheaderstyle", TOKEN_LISTVIEWHEADERSTYLE },
+ { "listviewstyle", TOKEN_LISTVIEWSTYLE },
+ { "menubaritemstyle", TOKEN_MENUBARITEMSTYLE },
+ { "menubarstyle", TOKEN_MENUBARSTYLE },
+ { "menuitemstyle", TOKEN_MENUITEMSTYLE },
+ { "menustyle", TOKEN_MENUSTYLE },
+ { "rgba", TOKEN_RGBA },
+ { "roundness", TOKEN_ROUNDNESS },
+ { "scrollbar_color", TOKEN_SCROLLBAR_COLOR },
+ { "scrollbarstyle", TOKEN_SCROLLBARSTYLE },
+ { "sliderstyle", TOKEN_SLIDERSTYLE },
+ { "stepperstyle", TOKEN_STEPPERSTYLE },
+ { "style", TOKEN_STYLE },
+ { "toolbarstyle", TOKEN_TOOLBARSTYLE },
+
+ { "CANDIDO", TOKEN_CANDIDO },
+ { "CLEARLOOKS", TOKEN_CLEARLOOKS },
+ { "MIST", TOKEN_MIST },
+ { "MURRINE", TOKEN_MURRINE },
+ { "NODOKA", TOKEN_NODOKA },
+
+ { "TRUE", TOKEN_TRUE },
+ { "FALSE", TOKEN_FALSE },
+
+ /* stuff to ignore */
+ { "hilight_ratio", TOKEN_HILIGHT_RATIO },
+ { "squaredstyle", TOKEN_SQUAREDSTYLE }
+};
+
+void
+murrine_rc_style_register_type (GTypeModule *module)
+{
+ static const GTypeInfo object_info =
+ {
+ sizeof (MurrineRcStyleClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) murrine_rc_style_class_init,
+ NULL, /* class_finalize */
+ NULL, /* class_data */
+ sizeof (MurrineRcStyle),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) murrine_rc_style_init,
+ NULL
+ };
+
+ murrine_type_rc_style = g_type_module_register_type (module,
+ GTK_TYPE_RC_STYLE,
+ "MurrineRcStyle",
+ &object_info, 0);
+}
+
+static void
+murrine_rc_style_init (MurrineRcStyle *murrine_rc)
+{
+ murrine_rc->flags = 0;
+
+ murrine_rc->animation = FALSE;
+ murrine_rc->colorize_scrollbar = TRUE;
+ murrine_rc->contrast = 1.0;
+ murrine_rc->glazestyle = 1;
+ murrine_rc->gradient_stop_1 = 1.0;
+ murrine_rc->gradient_stop_2 = 1.0;
+ murrine_rc->gradient_stop_3 = 1.0;
+ murrine_rc->gradient_stop_4 = 1.0;
+ murrine_rc->gradients = TRUE;
+ murrine_rc->has_scrollbar_color = FALSE;
+ murrine_rc->has_gradient_stop = FALSE;
+ murrine_rc->highlight_ratio = 1.1;
+ murrine_rc->innerborder_ratio = 1.1;
+ murrine_rc->listviewheaderstyle = 1;
+ murrine_rc->listviewstyle = 0;
+ murrine_rc->menubaritemstyle = 0;
+ murrine_rc->menubarstyle = 0;
+ murrine_rc->menuitemstyle = 1;
+ murrine_rc->menustyle = 1;
+ murrine_rc->rgba = TRUE;
+ murrine_rc->roundness = 1;
+ murrine_rc->scrollbarstyle = 0;
+ murrine_rc->sliderstyle = 0;
+ murrine_rc->stepperstyle = 0;
+ murrine_rc->style = MRN_STYLE_MURRINE;
+ murrine_rc->toolbarstyle = 0;
+}
+
+#ifdef HAVE_ANIMATION
+static void
+murrine_rc_style_finalize (GObject *object)
+{
+ /* cleanup all the animation stuff */
+ murrine_animation_cleanup ();
+
+ if (G_OBJECT_CLASS (parent_class)->finalize != NULL)
+ G_OBJECT_CLASS (parent_class)->finalize(object);
+}
+#endif
+
+
+static void
+murrine_rc_style_class_init (MurrineRcStyleClass *klass)
+{
+ GtkRcStyleClass *rc_style_class = GTK_RC_STYLE_CLASS (klass);
+#ifdef HAVE_ANIMATION
+ GObjectClass *g_object_class = G_OBJECT_CLASS (klass);
+#endif
+
+ parent_class = g_type_class_peek_parent (klass);
+
+ rc_style_class->parse = murrine_rc_style_parse;
+ rc_style_class->create_style = murrine_rc_style_create_style;
+ rc_style_class->merge = murrine_rc_style_merge;
+
+#ifdef HAVE_ANIMATION
+ g_object_class->finalize = murrine_rc_style_finalize;
+#endif
+}
+
+static guint
+theme_parse_boolean (GtkSettings *settings,
+ GScanner *scanner,
+ gboolean *retval)
+{
+ guint token;
+
+ /* Skip 'ANIMATION' */
+ token = g_scanner_get_next_token(scanner);
+
+ token = g_scanner_get_next_token(scanner);
+ if (token != G_TOKEN_EQUAL_SIGN)
+ return G_TOKEN_EQUAL_SIGN;
+
+ token = g_scanner_get_next_token(scanner);
+ if (token == TOKEN_TRUE)
+ *retval = TRUE;
+ else if (token == TOKEN_FALSE)
+ *retval = FALSE;
+ else
+ return TOKEN_TRUE;
+
+ return G_TOKEN_NONE;
+}
+
+static guint
+theme_parse_color (GtkSettings *settings,
+ GScanner *scanner,
+ GdkColor *color)
+{
+ guint token;
+
+ /* Skip 'blah_color' */
+ token = g_scanner_get_next_token(scanner);
+
+ token = g_scanner_get_next_token(scanner);
+ if (token != G_TOKEN_EQUAL_SIGN)
+ return G_TOKEN_EQUAL_SIGN;
+
+ return gtk_rc_parse_color (scanner, color);
+}
+
+static guint
+theme_parse_ratio (GtkSettings *settings,
+ GScanner *scanner,
+ double *ratio)
+{
+ guint token;
+
+ /* Skip 'ratio' */
+ token = g_scanner_get_next_token(scanner);
+
+ token = g_scanner_get_next_token(scanner);
+ if (token != G_TOKEN_EQUAL_SIGN)
+ return G_TOKEN_EQUAL_SIGN;
+
+ token = g_scanner_get_next_token(scanner);
+ if (token != G_TOKEN_FLOAT)
+ return G_TOKEN_FLOAT;
+
+ *ratio = scanner->value.v_float;
+
+ return G_TOKEN_NONE;
+}
+
+static guint
+theme_parse_int (GtkSettings *settings,
+ GScanner *scanner,
+ guint8 *style)
+{
+ guint token;
+
+ /* Skip '*style' */
+ token = g_scanner_get_next_token(scanner);
+
+ token = g_scanner_get_next_token(scanner);
+ if (token != G_TOKEN_EQUAL_SIGN)
+ return G_TOKEN_EQUAL_SIGN;
+
+ token = g_scanner_get_next_token(scanner);
+ if (token != G_TOKEN_INT)
+ return G_TOKEN_INT;
+
+ *style = scanner->value.v_int;
+
+ return G_TOKEN_NONE;
+}
+
+static guint
+theme_parse_style (GtkSettings *settings,
+ GScanner *scanner,
+ MurrineStyles *style)
+{
+ guint token;
+
+ g_assert (MRN_NUM_STYLES == MRN_STYLE_CLEARLOOKS + 1); /* so that people don't forget ;-) */
+
+ /* Skip 'style' */
+ token = g_scanner_get_next_token (scanner);
+
+ token = g_scanner_get_next_token (scanner);
+ if (token != G_TOKEN_EQUAL_SIGN)
+ return G_TOKEN_EQUAL_SIGN;
+
+ token = g_scanner_get_next_token (scanner);
+
+ switch (token)
+ {
+ case TOKEN_MURRINE:
+ *style = MRN_STYLE_MURRINE;
+ break;
+ case TOKEN_NODOKA:
+ *style = MRN_STYLE_NODOKA;
+ break;
+ case TOKEN_MIST:
+ *style = MRN_STYLE_MIST;
+ break;
+ case TOKEN_CANDIDO:
+ *style = MRN_STYLE_CANDIDO;
+ break;
+ case TOKEN_CLEARLOOKS:
+ *style = MRN_STYLE_CLEARLOOKS;
+ break;
+ default:
+ return TOKEN_MURRINE;
+ }
+
+ return G_TOKEN_NONE;
+}
+
+static guint
+murrine_gtk2_rc_parse_dummy (GtkSettings *settings,
+ GScanner *scanner,
+ gchar *name)
+{
+ guint token;
+
+ /* Skip option */
+ token = g_scanner_get_next_token (scanner);
+
+ /* print a warning. Isn't there a way to get the string from the scanner? */
+ g_scanner_warn (scanner, "Murrine configuration option \"%s\" is not supported and will be ignored.", name);
+
+ /* equal sign */
+ token = g_scanner_get_next_token (scanner);
+ if (token != G_TOKEN_EQUAL_SIGN)
+ return G_TOKEN_EQUAL_SIGN;
+
+ /* eat whatever comes next */
+ token = g_scanner_get_next_token (scanner);
+
+ return G_TOKEN_NONE;
+}
+
+static guint
+murrine_rc_style_parse (GtkRcStyle *rc_style,
+ GtkSettings *settings,
+ GScanner *scanner)
+{
+ static GQuark scope_id = 0;
+ MurrineRcStyle *murrine_style = MURRINE_RC_STYLE (rc_style);
+
+ guint old_scope;
+ guint token;
+ guint i;
+
+ /* Set up a new scope in this scanner. */
+
+ if (!scope_id)
+ scope_id = g_quark_from_string("murrine_theme_engine");
+
+ /* If we bail out due to errors, we *don't* reset the scope, so the
+ * error messaging code can make sense of our tokens.
+ */
+ old_scope = g_scanner_set_scope(scanner, scope_id);
+
+ /* Now check if we already added our symbols to this scope
+ * (in some previous call to murrine_rc_style_parse for the
+ * same scanner.
+ */
+
+ if (!g_scanner_lookup_symbol(scanner, theme_symbols[0].name))
+ {
+ g_scanner_freeze_symbol_table(scanner);
+ for (i = 0; i < G_N_ELEMENTS (theme_symbols); i++)
+ g_scanner_scope_add_symbol(scanner, scope_id, theme_symbols[i].name, GINT_TO_POINTER(theme_symbols[i].token));
+ g_scanner_thaw_symbol_table(scanner);
+ }
+
+ /* We're ready to go, now parse the top level */
+ token = g_scanner_peek_next_token(scanner);
+ while (token != G_TOKEN_RIGHT_CURLY)
+ {
+ switch (token)
+ {
+ case TOKEN_ANIMATION:
+ token = theme_parse_boolean (settings, scanner, &murrine_style->animation);
+ murrine_style->flags |= MRN_FLAG_ANIMATION;
+ break;
+ case TOKEN_COLORIZE_SCROLLBAR:
+ token = theme_parse_boolean (settings, scanner, &murrine_style->colorize_scrollbar);
+ murrine_style->flags |= MRN_FLAG_COLORIZE_SCROLLBAR;
+ break;
+ case TOKEN_CONTRAST:
+ token = theme_parse_ratio (settings, scanner, &murrine_style->contrast);
+ murrine_style->flags |= MRN_FLAG_CONTRAST;
+ break;
+ case TOKEN_GLAZESTYLE:
+ token = theme_parse_int (settings, scanner, &murrine_style->glazestyle);
+ murrine_style->flags |= MRN_FLAG_GLAZESTYLE;
+ break;
+ case TOKEN_GRADIENT_STOP_1:
+ token = theme_parse_ratio (settings, scanner, &murrine_style->gradient_stop_1);
+ murrine_style->flags |= MRN_FLAG_GRADIENT_STOP_1;
+ murrine_style->has_gradient_stop = TRUE;
+ break;
+ case TOKEN_GRADIENT_STOP_2:
+ token = theme_parse_ratio (settings, scanner, &murrine_style->gradient_stop_2);
+ murrine_style->flags |= MRN_FLAG_GRADIENT_STOP_2;
+ murrine_style->has_gradient_stop = TRUE;
+ break;
+ case TOKEN_GRADIENT_STOP_3:
+ token = theme_parse_ratio (settings, scanner, &murrine_style->gradient_stop_3);
+ murrine_style->flags |= MRN_FLAG_GRADIENT_STOP_3;
+ murrine_style->has_gradient_stop = TRUE;
+ break;
+ case TOKEN_GRADIENT_STOP_4:
+ token = theme_parse_ratio (settings, scanner, &murrine_style->gradient_stop_4);
+ murrine_style->flags |= MRN_FLAG_GRADIENT_STOP_4;
+ murrine_style->has_gradient_stop = TRUE;
+ break;
+ case TOKEN_GRADIENTS:
+ token = theme_parse_boolean (settings, scanner, &murrine_style->gradients);
+ murrine_style->flags |= MRN_FLAG_GRADIENTS;
+ break;
+ case TOKEN_HIGHLIGHT_RATIO:
+ token = theme_parse_ratio (settings, scanner, &murrine_style->highlight_ratio);
+ murrine_style->flags |= MRN_FLAG_HIGHLIGHT_RATIO;
+ break;
+ case TOKEN_INNERBORDER_RATIO:
+ token = theme_parse_ratio (settings, scanner, &murrine_style->innerborder_ratio);
+ murrine_style->flags |= MRN_FLAG_INNERBORDER_RATIO;
+ break;
+ case TOKEN_LISTVIEWHEADERSTYLE:
+ token = theme_parse_int (settings, scanner, &murrine_style->listviewheaderstyle);
+ murrine_style->flags |= MRN_FLAG_LISTVIEWHEADERSTYLE;
+ break;
+ case TOKEN_LISTVIEWSTYLE:
+ token = theme_parse_int (settings, scanner, &murrine_style->listviewstyle);
+ murrine_style->flags |= MRN_FLAG_LISTVIEWSTYLE;
+ break;
+ case TOKEN_MENUBARITEMSTYLE:
+ token = theme_parse_int (settings, scanner, &murrine_style->menubaritemstyle);
+ murrine_style->flags |= MRN_FLAG_MENUBARITEMSTYLE;
+ break;
+ case TOKEN_MENUBARSTYLE:
+ token = theme_parse_int (settings, scanner, &murrine_style->menubarstyle);
+ murrine_style->flags |= MRN_FLAG_MENUBARSTYLE;
+ break;
+ case TOKEN_MENUITEMSTYLE:
+ token = theme_parse_int (settings, scanner, &murrine_style->menuitemstyle);
+ murrine_style->flags |= MRN_FLAG_MENUITEMSTYLE;
+ break;
+ case TOKEN_MENUSTYLE:
+ token = theme_parse_int (settings, scanner, &murrine_style->menustyle);
+ murrine_style->flags |= MRN_FLAG_MENUSTYLE;
+ break;
+ case TOKEN_RGBA:
+ token = theme_parse_boolean (settings, scanner, &murrine_style->rgba);
+ murrine_style->flags |= MRN_FLAG_RGBA;
+ break;
+ case TOKEN_ROUNDNESS:
+ token = theme_parse_int (settings, scanner, &murrine_style->roundness);
+ murrine_style->flags |= MRN_FLAG_ROUNDNESS;
+ break;
+ case TOKEN_SCROLLBAR_COLOR:
+ token = theme_parse_color (settings, scanner, &murrine_style->scrollbar_color);
+ murrine_style->flags |= MRN_FLAG_SCROLLBAR_COLOR;
+ murrine_style->has_scrollbar_color = TRUE;
+ break;
+ case TOKEN_SCROLLBARSTYLE:
+ token = theme_parse_int (settings, scanner, &murrine_style->scrollbarstyle);
+ murrine_style->flags |= MRN_FLAG_SCROLLBARSTYLE;
+ break;
+ case TOKEN_SLIDERSTYLE:
+ token = theme_parse_int (settings, scanner, &murrine_style->sliderstyle);
+ murrine_style->flags |= MRN_FLAG_SLIDERSTYLE;
+ break;
+ case TOKEN_STEPPERSTYLE:
+ token = theme_parse_int (settings, scanner, &murrine_style->stepperstyle);
+ murrine_style->flags |= MRN_FLAG_STEPPERSTYLE;
+ break;
+ case TOKEN_STYLE:
+ token = theme_parse_style (settings, scanner, &murrine_style->style);
+ murrine_style->flags |= MRN_FLAG_STYLE;
+ break;
+ case TOKEN_TOOLBARSTYLE:
+ token = theme_parse_int (settings, scanner, &murrine_style->toolbarstyle);
+ murrine_style->flags |= MRN_FLAG_TOOLBARSTYLE;
+ break;
+
+ /* stuff to ignore */
+ case TOKEN_HILIGHT_RATIO:
+ g_scanner_warn (scanner, "Murrine configuration option \"hilight_ratio\" will be deprecated in future releases. Please update this theme to get rid of this warning.", "hilight_ratio");
+ double hilight_ratio;
+ token = theme_parse_ratio (settings, scanner, &hilight_ratio);
+ murrine_style->highlight_ratio = hilight_ratio/0.909090;
+ murrine_style->flags |= MRN_FLAG_HIGHLIGHT_RATIO;
+ break;
+ case TOKEN_SQUAREDSTYLE:
+ token = murrine_gtk2_rc_parse_dummy (settings, scanner, "squaredstyle");
+ break;
+
+ default:
+ g_scanner_get_next_token(scanner);
+ token = G_TOKEN_RIGHT_CURLY;
+ break;
+ }
+
+ if (token != G_TOKEN_NONE)
+ return token;
+
+ token = g_scanner_peek_next_token(scanner);
+ }
+
+ g_scanner_get_next_token(scanner);
+
+ g_scanner_set_scope(scanner, old_scope);
+
+ return G_TOKEN_NONE;
+}
+
+static void
+murrine_rc_style_merge (GtkRcStyle *dest,
+ GtkRcStyle *src)
+{
+ MurrineRcStyle *dest_w, *src_w;
+ MurrineRcFlags flags;
+
+ parent_class->merge (dest, src);
+
+ if (!MURRINE_IS_RC_STYLE (src))
+ return;
+
+ src_w = MURRINE_RC_STYLE (src);
+ dest_w = MURRINE_RC_STYLE (dest);
+
+ flags = (~dest_w->flags) & src_w->flags;
+
+ if (flags & MRN_FLAG_ANIMATION)
+ dest_w->animation = src_w->animation;
+ if (flags & MRN_FLAG_COLORIZE_SCROLLBAR)
+ dest_w->colorize_scrollbar = src_w->colorize_scrollbar;
+ if (flags & MRN_FLAG_CONTRAST)
+ dest_w->contrast = src_w->contrast;
+ if (flags & MRN_FLAG_GLAZESTYLE)
+ dest_w->glazestyle = src_w->glazestyle;
+ if (flags & MRN_FLAG_GRADIENT_STOP_1)
+ {
+ dest_w->has_gradient_stop = TRUE;
+ dest_w->gradient_stop_1 = src_w->gradient_stop_1;
+ }
+ if (flags & MRN_FLAG_GRADIENT_STOP_2)
+ {
+ dest_w->has_gradient_stop = TRUE;
+ dest_w->gradient_stop_2 = src_w->gradient_stop_2;
+ }
+ if (flags & MRN_FLAG_GRADIENT_STOP_3)
+ {
+ dest_w->has_gradient_stop = TRUE;
+ dest_w->gradient_stop_3 = src_w->gradient_stop_3;
+ }
+ if (flags & MRN_FLAG_GRADIENT_STOP_4)
+ {
+ dest_w->has_gradient_stop = TRUE;
+ dest_w->gradient_stop_4 = src_w->gradient_stop_4;
+ }
+ if (flags & MRN_FLAG_GRADIENTS)
+ dest_w->gradients = src_w->gradients;
+ if (flags & MRN_FLAG_HIGHLIGHT_RATIO)
+ dest_w->highlight_ratio = src_w->highlight_ratio;
+ if (flags & MRN_FLAG_INNERBORDER_RATIO)
+ dest_w->innerborder_ratio = src_w->innerborder_ratio;
+ if (flags & MRN_FLAG_LISTVIEWHEADERSTYLE)
+ dest_w->listviewheaderstyle = src_w->listviewheaderstyle;
+ if (flags & MRN_FLAG_LISTVIEWSTYLE)
+ dest_w->listviewstyle = src_w->listviewstyle;
+ if (flags & MRN_FLAG_MENUBARITEMSTYLE)
+ dest_w->menubaritemstyle = src_w->menubaritemstyle;
+ if (flags & MRN_FLAG_MENUBARSTYLE)
+ dest_w->menubarstyle = src_w->menubarstyle;
+ if (flags & MRN_FLAG_MENUITEMSTYLE)
+ dest_w->menuitemstyle = src_w->menuitemstyle;
+ if (flags & MRN_FLAG_MENUSTYLE)
+ dest_w->menustyle = src_w->menustyle;
+ if (flags & MRN_FLAG_RGBA)
+ dest_w->rgba = src_w->rgba;
+ if (flags & MRN_FLAG_ROUNDNESS)
+ dest_w->roundness = src_w->roundness;
+ if (flags & MRN_FLAG_SCROLLBAR_COLOR)
+ {
+ dest_w->has_scrollbar_color = TRUE;
+ dest_w->scrollbar_color = src_w->scrollbar_color;
+ }
+ if (flags & MRN_FLAG_SCROLLBARSTYLE)
+ dest_w->scrollbarstyle = src_w->scrollbarstyle;
+ if (flags & MRN_FLAG_SLIDERSTYLE)
+ dest_w->sliderstyle = src_w->sliderstyle;
+ if (flags & MRN_FLAG_STEPPERSTYLE)
+ dest_w->stepperstyle = src_w->stepperstyle;
+ if (flags & MRN_FLAG_STYLE)
+ dest_w->style = src_w->style;
+ if (flags & MRN_FLAG_TOOLBARSTYLE)
+ dest_w->toolbarstyle = src_w->toolbarstyle;
+
+ dest_w->flags |= src_w->flags;
+}
+
+/* Create an empty style suitable to this RC style
+ */
+static GtkStyle *
+murrine_rc_style_create_style (GtkRcStyle *rc_style)
+{
+ return GTK_STYLE (g_object_new (MURRINE_TYPE_STYLE, NULL));
+}
Added: trunk/src/murrine_rc_style.h
==============================================================================
--- (empty file)
+++ trunk/src/murrine_rc_style.h Mon Feb 11 23:01:49 2008
@@ -0,0 +1,108 @@
+/* Murrine theme engine
+ * Copyright (C) 2007 Andrea Cimitan
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * 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; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ */
+
+#include <gtk/gtkrc.h>
+
+typedef struct _MurrineRcStyle MurrineRcStyle;
+typedef struct _MurrineRcStyleClass MurrineRcStyleClass;
+
+G_GNUC_INTERNAL extern GType murrine_type_rc_style;
+
+#define MURRINE_TYPE_RC_STYLE murrine_type_rc_style
+#define MURRINE_RC_STYLE(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), MURRINE_TYPE_RC_STYLE, MurrineRcStyle))
+#define MURRINE_RC_STYLE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), MURRINE_TYPE_RC_STYLE, MurrineRcStyleClass))
+#define MURRINE_IS_RC_STYLE(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), MURRINE_TYPE_RC_STYLE))
+#define MURRINE_IS_RC_STYLE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), MURRINE_TYPE_RC_STYLE))
+#define MURRINE_RC_STYLE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), MURRINE_TYPE_RC_STYLE, MurrineRcStyleClass))
+
+typedef enum
+{
+ MRN_FLAG_ANIMATION = 1 << 0,
+ MRN_FLAG_COLORIZE_SCROLLBAR = 1 << 1,
+ MRN_FLAG_CONTRAST = 1 << 2,
+ MRN_FLAG_GLAZESTYLE = 1 << 3,
+ MRN_FLAG_GRADIENT_STOP_1 = 1 << 4,
+ MRN_FLAG_GRADIENT_STOP_2 = 1 << 5,
+ MRN_FLAG_GRADIENT_STOP_3 = 1 << 6,
+ MRN_FLAG_GRADIENT_STOP_4 = 1 << 7,
+ MRN_FLAG_GRADIENTS = 1 << 8,
+ MRN_FLAG_HIGHLIGHT_RATIO = 1 << 9,
+ MRN_FLAG_INNERBORDER_RATIO = 1 << 10,
+ MRN_FLAG_LISTVIEWHEADERSTYLE = 1 << 11,
+ MRN_FLAG_LISTVIEWSTYLE = 1 << 12,
+ MRN_FLAG_MENUBARITEMSTYLE = 1 << 13,
+ MRN_FLAG_MENUBARSTYLE = 1 << 14,
+ MRN_FLAG_MENUITEMSTYLE = 1 << 15,
+ MRN_FLAG_MENUSTYLE = 1 << 16,
+ MRN_FLAG_RGBA = 1 << 17,
+ MRN_FLAG_ROUNDNESS = 1 << 18,
+ MRN_FLAG_SCROLLBAR_COLOR = 1 << 19,
+ MRN_FLAG_SCROLLBARSTYLE = 1 << 20,
+ MRN_FLAG_SLIDERSTYLE = 1 << 21,
+ MRN_FLAG_STEPPERSTYLE = 1 << 22,
+ MRN_FLAG_STYLE = 1 << 23,
+ MRN_FLAG_TOOLBARSTYLE = 1 << 24
+} MurrineRcFlags;
+
+struct _MurrineRcStyle
+{
+ GtkRcStyle parent_instance;
+
+ MurrineRcFlags flags;
+
+ double contrast;
+ double gradient_stop_1;
+ double gradient_stop_2;
+ double gradient_stop_3;
+ double gradient_stop_4;
+ double highlight_ratio;
+ double innerborder_ratio;
+
+ guint8 glazestyle;
+ guint8 listviewheaderstyle;
+ guint8 listviewstyle;
+ guint8 menubaritemstyle;
+ guint8 menubarstyle;
+ guint8 menuitemstyle;
+ guint8 menustyle;
+ guint8 roundness;
+ guint8 scrollbarstyle;
+ guint8 sliderstyle;
+ guint8 stepperstyle;
+ guint8 toolbarstyle;
+
+ gboolean animation;
+ gboolean gradients;
+ gboolean colorize_scrollbar;
+ gboolean has_gradient_stop;
+ gboolean has_scrollbar_color;
+ gboolean rgba;
+
+ GdkColor scrollbar_color;
+
+ MurrineStyles style;
+};
+
+struct _MurrineRcStyleClass
+{
+ GtkRcStyleClass parent_class;
+};
+
+G_GNUC_INTERNAL void murrine_rc_style_register_type (GTypeModule *module);
Added: trunk/src/murrine_style.c
==============================================================================
--- (empty file)
+++ trunk/src/murrine_style.c Mon Feb 11 23:01:49 2008
@@ -0,0 +1,2088 @@
+/* Murrine theme engine
+ * Copyright (C) 2007 Andrea Cimitan
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * 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; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ */
+
+#include <gtk/gtk.h>
+#include <cairo.h>
+#include <math.h>
+#include <string.h>
+#include <sys/time.h>
+
+#include "murrine_style.h"
+#include "murrine_rc_style.h"
+#include "murrine_draw.h"
+#include "support.h"
+#include "cairo-support.h"
+
+/* #define DEBUG 1 */
+
+#define SCALE_SIZE 5
+
+#define DETAIL(xx) ((detail) && (!strcmp(xx, detail)))
+#define COMPARE_COLORS(a,b) (a.red == b.red && a.green == b.green && a.blue == b.blue)
+
+#define DRAW_ARGS GtkStyle *style, \
+ GdkWindow *window, \
+ GtkStateType state_type, \
+ GtkShadowType shadow_type, \
+ GdkRectangle *area, \
+ GtkWidget *widget, \
+ const gchar *detail, \
+ gint x, \
+ gint y, \
+ gint width, \
+ gint height
+
+#define CHECK_ARGS \
+ g_return_if_fail (window != NULL); \
+ g_return_if_fail (style != NULL);
+
+#define SANITIZE_SIZE \
+ g_return_if_fail (width >= -1); \
+ g_return_if_fail (height >= -1); \
+ \
+ if ((width == -1) && (height == -1)) \
+ gdk_drawable_get_size (window, &width, &height); \
+ else if (width == -1) \
+ gdk_drawable_get_size (window, &width, NULL); \
+ else if (height == -1) \
+ gdk_drawable_get_size (window, NULL, &height);
+
+#ifdef HAVE_ANIMATION
+#include "animation.h"
+#endif
+
+#define STYLE_FUNCTION(function) (murrine_style_class->style_functions[params.drawstyle].function)
+
+static MurrineStyleClass *murrine_style_class;
+static GtkStyleClass *murrine_parent_class;
+
+static cairo_t *
+murrine_begin_paint (GdkDrawable *window, GdkRectangle *area)
+{
+ cairo_t *cr;
+
+ g_return_val_if_fail (window != NULL, NULL);
+
+ cr = (cairo_t*) gdk_cairo_create (window);
+ cairo_set_line_width (cr, 1.0);
+
+ if (area)
+ {
+ cairo_rectangle (cr, area->x, area->y, area->width, area->height);
+ cairo_clip_preserve (cr);
+ cairo_new_path (cr);
+ }
+
+ return cr;
+}
+
+static
+boolean murrine_widget_is_rgba (GtkWidget *widget)
+{
+ GdkScreen *screen = gtk_widget_get_screen (widget);
+ boolean use_rgba = FALSE;
+
+ if (gdk_screen_is_composited(screen) && gdk_screen_get_rgba_colormap (screen))
+ use_rgba = (gtk_widget_get_colormap (widget) ==
+ gdk_screen_get_rgba_colormap (screen));
+
+ return use_rgba;
+}
+
+static void
+murrine_set_widget_parameters (const GtkWidget *widget,
+ const GtkStyle *style,
+ GtkStateType state_type,
+ WidgetParameters *params)
+{
+ if (widget && MRN_IS_ENTRY (widget))
+ state_type = GTK_WIDGET_STATE (widget);
+
+ MurrineStyle *murrine_style = MURRINE_STYLE (style);
+
+ params->active = (state_type == GTK_STATE_ACTIVE);
+ params->prelight = (state_type == GTK_STATE_PRELIGHT);
+ params->disabled = (state_type == GTK_STATE_INSENSITIVE);
+ params->state_type = (MurrineStateType)state_type;
+ params->corners = MRN_CORNER_ALL;
+ params->ltr = murrine_widget_is_ltr ((GtkWidget*)widget);
+ params->focus = widget && GTK_WIDGET_HAS_FOCUS (widget);
+ params->is_default = widget && GTK_WIDGET_HAS_DEFAULT (widget);
+
+ if (!params->active && widget && MRN_IS_TOGGLE_BUTTON (widget))
+ params->active = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget));
+
+ params->xthickness = style->xthickness;
+ params->ythickness = style->ythickness;
+
+ params->innerborder_ratio = murrine_style->innerborder_ratio;
+ params->glazestyle = murrine_style->glazestyle;
+ params->roundness = murrine_style->roundness;
+ params->highlight_ratio = murrine_style->highlight_ratio;
+
+ MurrineGradients mrn_gradient;
+ mrn_gradient.has_gradient_stop = murrine_style->has_gradient_stop;
+ mrn_gradient.gradient_stop_1 = murrine_style->gradient_stop_1;
+ mrn_gradient.gradient_stop_2 = murrine_style->gradient_stop_2;
+ mrn_gradient.gradient_stop_3 = murrine_style->gradient_stop_3;
+ mrn_gradient.gradient_stop_4 = murrine_style->gradient_stop_4;
+ mrn_gradient.gradients = murrine_style->gradients;
+ mrn_gradient.use_rgba = (murrine_widget_is_rgba ((GtkWidget*) widget) && murrine_style->rgba);
+ mrn_gradient.rgba_opacity = GRADIENT_OPACITY;
+
+ MurrineDrawStyles drawstyle = MRN_DRAW_STYLE_MURRINE;
+ if (mrn_gradient.use_rgba)
+ {
+ //params->highlight_ratio = get_increased_ratio (params->highlight_ratio, 1.4);
+ drawstyle = MRN_DRAW_STYLE_RGBA;
+ }
+ params->mrn_gradient = mrn_gradient;
+ params->drawstyle = drawstyle;
+ params->style_functions = &(murrine_style_class->style_functions[drawstyle]);
+
+ /* I want to avoid to have to do this. I need it for GtkEntry, unless I
+ find out why it doesn't behave the way I expect it to. */
+ params->parentbg = MURRINE_STYLE (style)->colors.bg[state_type];
+ murrine_get_parent_bg (widget, ¶ms->parentbg);
+}
+
+static void
+murrine_style_draw_flat_box (DRAW_ARGS)
+{
+ //printf( "draw_flat_box: %s %s\n", detail, G_OBJECT_TYPE_NAME (widget));
+ if (detail &&
+ state_type == GTK_STATE_SELECTED && (
+ !strncmp ("cell_even", detail, 9) ||
+ !strncmp ("cell_odd", detail, 8)))
+ {
+ MurrineStyle *murrine_style = MURRINE_STYLE (style);
+ MurrineColors *colors = &murrine_style->colors;
+ cairo_t *cr;
+
+ CHECK_ARGS
+ SANITIZE_SIZE
+
+ cr = murrine_begin_paint (window, area);
+
+ WidgetParameters params;
+
+ murrine_set_widget_parameters (widget, style, state_type, ¶ms);
+
+ STYLE_FUNCTION(draw_selected_cell) (cr, colors, ¶ms, x, y, width, height);
+
+ cairo_destroy (cr);
+ }
+ else if (DETAIL ("tooltip"))
+ {
+ MurrineStyle *murrine_style = MURRINE_STYLE (style);
+ MurrineColors *colors = &murrine_style->colors;
+ cairo_t *cr;
+
+ CHECK_ARGS
+ SANITIZE_SIZE
+
+ cr = murrine_begin_paint (window, area);
+
+ WidgetParameters params;
+
+ murrine_set_widget_parameters (widget, style, state_type, ¶ms);
+
+ STYLE_FUNCTION(draw_tooltip) (cr, colors, ¶ms, x, y, width, height);
+
+ cairo_destroy (cr);
+ }
+ else
+ {
+ if (DETAIL ("base") || DETAIL ("eventbox") || DETAIL ("entry_bg") || DETAIL ("trough"))
+ {
+ MurrineStyle *murrine_style = MURRINE_STYLE (style);
+ MurrineColors *colors = &murrine_style->colors;
+ cairo_t *cr;
+ boolean use_rgba = FALSE;
+
+ CHECK_ARGS
+ SANITIZE_SIZE
+
+ use_rgba = (murrine_widget_is_rgba (widget) && murrine_style->rgba);
+
+ if (!use_rgba)
+ {
+ murrine_parent_class->draw_flat_box (style, window, state_type,
+ shadow_type,
+ area, widget, detail,
+ x, y, width, height);
+ }
+ else
+ {
+ cr = (cairo_t*) gdk_cairo_create (window);
+
+ if (DETAIL ("entry_bg"))
+ {
+ /* Draw (erase) the background */
+ cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR);
+ cairo_paint (cr);
+ cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
+
+ murrine_set_color_rgba (cr, &colors->base[state_type], ENTRY_OPACITY);
+ cairo_rectangle (cr, 0, 0, width, height);
+ cairo_fill (cr);
+ }
+ else if (DETAIL ("eventbox") || DETAIL ("trough"))
+ {
+ /* Draw (erase) the background */
+ cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR);
+ cairo_paint (cr);
+ cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
+
+ murrine_set_color_rgba (cr, &colors->bg[0], WINDOW_OPACITY);
+ cairo_rectangle (cr, 0, 0, width, height);
+ cairo_fill (cr);
+ }
+ else
+ {
+ /* Draw (erase) the background */
+ cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR);
+ cairo_paint (cr);
+ cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
+
+ cairo_pattern_t *pattern;
+
+ pattern = cairo_pattern_create_linear (0, 0, width, 0);
+ cairo_pattern_add_color_stop_rgba (pattern, 0.0, colors->bg[0].r,
+ colors->bg[0].g,
+ colors->bg[0].b, WINDOW_OPACITY);
+ cairo_pattern_add_color_stop_rgba (pattern, 0.5, colors->bg[0].r,
+ colors->bg[0].g,
+ colors->bg[0].b, 0.8);
+ cairo_pattern_add_color_stop_rgba (pattern, 1.0, colors->bg[0].r,
+ colors->bg[0].g,
+ colors->bg[0].b, WINDOW_OPACITY);
+ cairo_set_source (cr, pattern);
+ cairo_rectangle (cr, 0, 0, width, height);
+ cairo_fill (cr);
+ cairo_pattern_destroy (pattern);
+ }
+
+ cairo_destroy (cr);
+ }
+ }
+ else
+ {
+ // printf( "draw_flat_box: %s %s\n", detail, G_OBJECT_TYPE_NAME (widget));
+ murrine_parent_class->draw_flat_box (style, window, state_type,
+ shadow_type,
+ area, widget, detail,
+ x, y, width, height);
+ }
+ }
+
+ /* Dotted listview */
+ if (detail && (!strncmp ("cell_even", detail, 9) || !strncmp ("cell_odd", detail, 8)))
+ {
+ MurrineStyle *murrine_style = MURRINE_STYLE (style);
+ if (murrine_style->listviewstyle > 0)
+ {
+ MurrineColors *colors = &murrine_style->colors;
+ cairo_t *cr;
+
+ CHECK_ARGS
+ SANITIZE_SIZE
+
+ cr = murrine_begin_paint (window, area);
+
+ cairo_translate (cr, x, y);
+ int i;
+ int pos = 1;
+ if (murrine_style->listviewheaderstyle != 1)
+ pos = 2;
+
+ murrine_set_color_rgba (cr, &colors->text[GTK_STATE_NORMAL], 0.42);
+ for (i = 2; i < height; i+=4)
+ {
+ cairo_rectangle (cr, -pos, i, 1, 1);
+ cairo_fill (cr);
+ }
+
+ cairo_destroy (cr);
+ }
+ }
+}
+
+static void
+murrine_style_draw_shadow (DRAW_ARGS)
+{
+ MurrineStyle *murrine_style = MURRINE_STYLE (style);
+ MurrineColors *colors = &murrine_style->colors;
+ cairo_t *cr;
+
+ CHECK_ARGS
+ SANITIZE_SIZE
+
+ cr = murrine_begin_paint (window, area);
+
+ if (DETAIL ("entry") && !(widget && widget->parent && MRN_IS_TREE_VIEW (widget->parent)))
+ {
+ WidgetParameters params;
+
+ murrine_set_widget_parameters (widget, style, state_type, ¶ms);
+ params.roundness = murrine_style->roundness;
+
+ if (widget && (MRN_IS_COMBO (widget->parent) ||
+ MRN_IS_COMBO_BOX_ENTRY(widget->parent) ||
+ MRN_IS_SPIN_BUTTON (widget)))
+ {
+ width += style->xthickness;
+ if (!params.ltr)
+ x -= style->xthickness;
+
+ if (params.ltr)
+ params.corners = MRN_CORNER_TOPLEFT | MRN_CORNER_BOTTOMLEFT;
+ else
+ params.corners = MRN_CORNER_TOPRIGHT | MRN_CORNER_BOTTOMRIGHT;
+ }
+
+ STYLE_FUNCTION(draw_entry) (cr, &murrine_style->colors, ¶ms,
+ x, y, width, height);
+ }
+ else if (DETAIL ("frame") && widget && MRN_IS_STATUSBAR (widget->parent))
+ {
+ WidgetParameters params;
+
+ murrine_set_widget_parameters (widget, style, state_type, ¶ms);
+
+ if (!params.mrn_gradient.use_rgba)
+ {
+ gtk_style_apply_default_background (style, window, TRUE, state_type,
+ area, x, y, width, height);
+ }
+
+ STYLE_FUNCTION(draw_statusbar) (cr, colors, ¶ms,
+ x, y, width, height);
+ }
+ else if (DETAIL ("frame"))
+ {
+ WidgetParameters params;
+ FrameParameters frame;
+
+ frame.shadow = shadow_type;
+ frame.gap_x = -1; /* No gap will be drawn */
+ frame.border = &colors->shade[4];
+
+ murrine_set_widget_parameters (widget, style, state_type, ¶ms);
+ params.corners = MRN_CORNER_NONE;
+
+ if (widget && !g_str_equal ("XfcePanelWindow", gtk_widget_get_name (gtk_widget_get_toplevel (widget))))
+ STYLE_FUNCTION(draw_frame) (cr, colors, ¶ms, &frame, x, y, width, height);
+ }
+ else if (DETAIL ("scrolled_window") || DETAIL ("viewport") || detail == NULL)
+ {
+ MurrineRGB *border = (MurrineRGB*)&colors->shade[5];
+ cairo_rectangle (cr, x+0.5, y+0.5, width-1, height-1);
+ murrine_set_color_rgb (cr, border);
+ cairo_set_line_width (cr, 1);
+ cairo_stroke (cr);
+ }
+ else
+ {
+ WidgetParameters params;
+ FrameParameters frame;
+
+ frame.shadow = shadow_type;
+ frame.gap_x = -1;
+ frame.border = &colors->shade[4];
+
+ murrine_set_widget_parameters (widget, style, state_type, ¶ms);
+
+ params.corners = MRN_CORNER_ALL;
+ if (params.roundness < 2)
+ params.corners = MRN_CORNER_NONE;
+
+ STYLE_FUNCTION(draw_frame) (cr, colors, ¶ms, &frame, x, y, width, height);
+ }
+
+ cairo_destroy (cr);
+}
+
+static void
+murrine_style_draw_box_gap (DRAW_ARGS,
+ GtkPositionType gap_side,
+ gint gap_x,
+ gint gap_width)
+{
+ MurrineStyle *murrine_style = MURRINE_STYLE (style);
+ MurrineColors *colors = &murrine_style->colors;
+ cairo_t *cr;
+
+ CHECK_ARGS
+ SANITIZE_SIZE
+
+ cr = murrine_begin_paint (window, area);
+
+ if (DETAIL ("notebook"))
+ {
+ WidgetParameters params;
+ FrameParameters frame;
+ gboolean start, end;
+
+ frame.shadow = shadow_type;
+ frame.gap_side = gap_side;
+ frame.gap_x = gap_x;
+ frame.gap_width = gap_width;
+ frame.border = &colors->shade[5];
+
+ murrine_set_widget_parameters (widget, style, state_type, ¶ms);
+
+ murrine_get_notebook_tab_position (widget, &start, &end);
+
+ params.corners = MRN_CORNER_ALL;
+ switch (gap_side)
+ {
+ case GTK_POS_TOP:
+ if (murrine_widget_is_ltr (widget))
+ {
+ if (start)
+ params.corners ^= MRN_CORNER_TOPLEFT;
+ if (end)
+ params.corners ^= MRN_CORNER_TOPRIGHT;
+ }
+ else
+ {
+ if (start)
+ params.corners ^= MRN_CORNER_TOPRIGHT;
+ if (end)
+ params.corners ^= MRN_CORNER_TOPLEFT;
+ }
+ break;
+ case GTK_POS_BOTTOM:
+ if (murrine_widget_is_ltr (widget))
+ {
+ if (start)
+ params.corners ^= MRN_CORNER_BOTTOMLEFT;
+ if (end)
+ params.corners ^= MRN_CORNER_BOTTOMRIGHT;
+ }
+ else
+ {
+ if (start)
+ params.corners ^= MRN_CORNER_BOTTOMRIGHT;
+ if (end)
+ params.corners ^= MRN_CORNER_BOTTOMLEFT;
+ }
+ break;
+ case GTK_POS_LEFT:
+ if (start)
+ params.corners ^= MRN_CORNER_TOPLEFT;
+ if (end)
+ params.corners ^= MRN_CORNER_BOTTOMLEFT;
+ break;
+ case GTK_POS_RIGHT:
+ if (start)
+ params.corners ^= MRN_CORNER_TOPRIGHT;
+ if (end)
+ params.corners ^= MRN_CORNER_BOTTOMRIGHT;
+ break;
+ }
+ if (params.roundness < 2)
+ params.corners = MRN_CORNER_NONE;
+
+ /* Fill the background with bg[NORMAL] */
+ murrine_rounded_rectangle (cr, x, y, width, height, params.roundness, params.corners);
+ if (!params.mrn_gradient.use_rgba)
+ murrine_set_color_rgb (cr, &colors->bg[0]);
+ else
+ murrine_set_color_rgba (cr, &colors->bg[0], NOTEBOOK_OPACITY);
+ cairo_fill(cr);
+
+ STYLE_FUNCTION(draw_frame) (cr, colors, ¶ms, &frame,
+ x, y, width, height);
+ }
+ else
+ {
+ murrine_parent_class->draw_box_gap (style, window, state_type, shadow_type,
+ area, widget, detail,
+ x, y, width, height,
+ gap_side, gap_x, gap_width);
+ }
+
+ cairo_destroy (cr);
+}
+
+static void
+murrine_style_draw_extension (DRAW_ARGS, GtkPositionType gap_side)
+{
+ MurrineStyle *murrine_style = MURRINE_STYLE (style);
+ MurrineColors *colors = &murrine_style->colors;
+ cairo_t *cr;
+
+ CHECK_ARGS
+ SANITIZE_SIZE
+
+ cr = murrine_begin_paint (window, area);
+
+ if (DETAIL ("tab"))
+ {
+ WidgetParameters params;
+ TabParameters tab;
+
+ murrine_set_widget_parameters (widget, style, state_type, ¶ms);
+
+ tab.gap_side = (MurrineGapSide)gap_side;
+ switch (gap_side)
+ {
+ case MRN_GAP_TOP:
+ params.corners = MRN_CORNER_BOTTOMLEFT | MRN_CORNER_BOTTOMRIGHT;
+ break;
+ case MRN_GAP_BOTTOM:
+ params.corners = MRN_CORNER_TOPLEFT | MRN_CORNER_TOPRIGHT;
+ break;
+ case MRN_GAP_LEFT:
+ params.corners = MRN_CORNER_TOPRIGHT | MRN_CORNER_BOTTOMRIGHT;
+ break;
+ case MRN_GAP_RIGHT:
+ params.corners = MRN_CORNER_TOPLEFT | MRN_CORNER_BOTTOMLEFT;
+ break;
+ }
+
+ STYLE_FUNCTION(draw_tab) (cr, colors, ¶ms, &tab, x, y, width, height);
+ }
+ else
+ {
+ murrine_parent_class->draw_extension (style, window, state_type, shadow_type, area,
+ widget, detail, x, y, width, height, gap_side);
+ }
+
+ cairo_destroy (cr);
+}
+
+static void
+murrine_style_draw_handle (DRAW_ARGS, GtkOrientation orientation)
+{
+ MurrineStyle *murrine_style = MURRINE_STYLE (style);
+ MurrineColors *colors = &murrine_style->colors;
+ cairo_t *cr;
+ gboolean is_horizontal;
+
+ CHECK_ARGS
+ SANITIZE_SIZE
+
+ cr = murrine_begin_paint (window, area);
+
+ /* Evil hack to work around broken orientation for toolbars */
+ is_horizontal = (width > height);
+
+ if (DETAIL ("handlebox"))
+ {
+ WidgetParameters params;
+ HandleParameters handle;
+
+ handle.type = MRN_HANDLE_TOOLBAR;
+ handle.horizontal = is_horizontal;
+
+ murrine_set_widget_parameters (widget, style, state_type, ¶ms);
+
+ /* Is this ever true? -Daniel */
+ if (MRN_IS_TOOLBAR (widget) && shadow_type != GTK_SHADOW_NONE)
+ {
+ ToolbarParameters toolbar;
+
+ murrine_set_toolbar_parameters (&toolbar, widget, window, x, y);
+ toolbar.style = murrine_style->toolbarstyle;
+
+ if (params.mrn_gradient.use_rgba)
+ {
+ params.mrn_gradient.rgba_opacity = TOOLBAR_GLOSSY_OPACITY;
+ }
+
+ cairo_save (cr);
+ STYLE_FUNCTION(draw_toolbar) (cr, colors, ¶ms, &toolbar, x, y, width, height);
+ cairo_restore (cr);
+ }
+
+ STYLE_FUNCTION(draw_handle) (cr, colors, ¶ms, &handle, x, y, width, height);
+ }
+ else if (DETAIL ("paned"))
+ {
+ WidgetParameters params;
+ HandleParameters handle;
+
+ handle.type = MRN_HANDLE_SPLITTER;
+ handle.horizontal = orientation == GTK_ORIENTATION_HORIZONTAL;
+
+ murrine_set_widget_parameters (widget, style, state_type, ¶ms);
+
+ STYLE_FUNCTION(draw_handle) (cr, colors, ¶ms, &handle, x, y, width, height);
+ }
+ else
+ {
+ WidgetParameters params;
+ HandleParameters handle;
+
+ handle.type = MRN_HANDLE_TOOLBAR;
+ handle.horizontal = is_horizontal;
+
+ murrine_set_widget_parameters (widget, style, state_type, ¶ms);
+
+ if (MRN_IS_TOOLBAR (widget) && shadow_type != GTK_SHADOW_NONE)
+ {
+ ToolbarParameters toolbar;
+
+ murrine_set_toolbar_parameters (&toolbar, widget, window, x, y);
+ toolbar.style = murrine_style->toolbarstyle;
+
+ cairo_save (cr);
+ STYLE_FUNCTION(draw_toolbar) (cr, colors, ¶ms, &toolbar, x, y, width, height);
+ cairo_restore (cr);
+ }
+
+ STYLE_FUNCTION(draw_handle) (cr, colors, ¶ms, &handle, x, y, width, height);
+ }
+
+ cairo_destroy (cr);
+}
+
+static void
+murrine_style_draw_box (DRAW_ARGS)
+{
+ MurrineStyle *murrine_style = MURRINE_STYLE (style);
+ const MurrineColors *colors = &murrine_style->colors;
+ cairo_t *cr;
+
+ CHECK_ARGS
+ SANITIZE_SIZE
+
+ cr = murrine_begin_paint (window, area);
+
+ if ((width == -1) && (height == -1))
+ gdk_window_get_size (window, &width, &height);
+ else if (width == -1)
+ gdk_window_get_size (window, &width, NULL);
+ else if (height == -1)
+ gdk_window_get_size (window, NULL, &height);
+
+ if (DETAIL ("menubar") &&
+ !(widget && (murrine_is_panel_widget (widget->parent))))
+ {
+ WidgetParameters params;
+
+ murrine_set_widget_parameters (widget, style, state_type, ¶ms);
+
+ if (params.mrn_gradient.use_rgba)
+ {
+ params.mrn_gradient.rgba_opacity = MENUBAR_GLOSSY_OPACITY;
+ }
+
+ STYLE_FUNCTION(draw_menubar) (cr, colors, ¶ms, x, y, width, height,
+ murrine_style->menubarstyle);
+ }
+ else if (DETAIL ("button") && widget && widget->parent &&
+ (MRN_IS_TREE_VIEW(widget->parent) ||
+ MRN_IS_CLIST (widget->parent)))
+ {
+ WidgetParameters params;
+ ListViewHeaderParameters header;
+ header.style = murrine_style->listviewheaderstyle;
+
+ gint columns, column_index;
+ gboolean resizable = TRUE;
+
+ murrine_set_widget_parameters (widget, style, state_type, ¶ms);
+ params.corners = MRN_CORNER_NONE;
+
+ if (MRN_IS_TREE_VIEW (widget->parent))
+ {
+ murrine_gtk_treeview_get_header_index (GTK_TREE_VIEW(widget->parent),
+ widget, &column_index, &columns,
+ &resizable);
+ }
+ else if (MRN_IS_CLIST (widget->parent))
+ {
+ murrine_gtk_clist_get_header_index (GTK_CLIST(widget->parent),
+ widget, &column_index, &columns);
+ }
+
+ header.resizable = resizable;
+
+ if (column_index == 0)
+ header.order = params.ltr ? MRN_ORDER_FIRST : MRN_ORDER_LAST;
+ else if (column_index == columns-1)
+ header.order = params.ltr ? MRN_ORDER_LAST : MRN_ORDER_FIRST;
+ else
+ header.order = MRN_ORDER_MIDDLE;
+
+ gtk_style_apply_default_background (style, window, FALSE, state_type, area, x, y, width, height);
+
+ STYLE_FUNCTION(draw_list_view_header) (cr, colors, ¶ms, &header, x, y, width, height);
+ }
+ else if (DETAIL ("button") || DETAIL ("buttondefault"))
+ {
+ WidgetParameters params;
+
+ murrine_set_widget_parameters (widget, style, state_type, ¶ms);
+ params.roundness = murrine_style->roundness;
+
+ boolean horizontal = TRUE;
+ if (((float)width/height<0.5)|| (murrine_style->glazestyle > 0 && width<height))
+ horizontal = FALSE;
+
+ if ((widget && (MRN_IS_COMBO_BOX_ENTRY (widget->parent) || MRN_IS_COMBO (widget->parent))))
+ {
+ if (murrine_style->roundness > 0)
+ {
+ if (params.ltr)
+ {
+ params.corners = MRN_CORNER_TOPRIGHT | MRN_CORNER_BOTTOMRIGHT;
+ if (!horizontal)
+ params.corners = MRN_CORNER_BOTTOMLEFT | MRN_CORNER_BOTTOMRIGHT;
+ }
+ else
+ {
+ params.corners = MRN_CORNER_TOPLEFT | MRN_CORNER_BOTTOMLEFT;
+ if (!horizontal)
+ params.corners = MRN_CORNER_BOTTOMRIGHT | MRN_CORNER_BOTTOMLEFT;
+ }
+ }
+ else
+ params.corners = MRN_CORNER_NONE;
+
+ /* Seriously, why can't non-gtk-apps at least try to be decent citizens?
+ Take this fucking OpenOffice.org 1.9 for example. The morons responsible
+ for this utter piece of crap gave the clip size wrong values! :'( */
+/* cairo_reset_clip (cr);
+ cairo_rectangle (cr, x+ 0.5, y+ 0.5, 10, 10);
+ cairo_clip (cr);
+ cairo_new_path (cr);
+*/
+ if (params.xthickness > 1)
+ {
+ if (params.ltr)
+ x--;
+ width++;
+ }
+ }
+ else
+ if (murrine_style->roundness > 0)
+ params.corners = MRN_CORNER_ALL;
+ else
+ params.corners = MRN_CORNER_NONE;
+
+ if (MRN_IS_TOGGLE_BUTTON (widget) &&
+ gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget)))
+ params.active = TRUE;
+
+ /* Fix some firefox crap. */
+ if (MRN_IS_BUTTON (widget) && MRN_IS_FIXED (widget->parent) && widget->allocation.x == -1 && widget->allocation.y == -1)
+ {
+ gtk_style_apply_default_background (widget->parent->style, window, TRUE, GTK_STATE_NORMAL,
+ area, x, y, width, height);
+ }
+
+ STYLE_FUNCTION(draw_button) (cr, &murrine_style->colors, ¶ms, x, y, width, height, horizontal);
+ }
+ else if (DETAIL ("spinbutton_up") || DETAIL ("spinbutton_down"))
+ {
+ if (state_type == GTK_STATE_ACTIVE)
+ {
+ WidgetParameters params;
+ murrine_set_widget_parameters (widget, style, state_type, ¶ms);
+
+ if (style->xthickness > 1)
+ {
+ width++;
+ if (params.ltr)
+ x--;
+ }
+
+ if (DETAIL ("spinbutton_up"))
+ {
+ height+=2;
+ if (params.ltr)
+ params.corners = MRN_CORNER_TOPRIGHT;
+ else
+ params.corners = MRN_CORNER_TOPLEFT;
+ }
+ else
+ {
+ if (params.ltr)
+ params.corners = MRN_CORNER_BOTTOMRIGHT;
+ else
+ params.corners = MRN_CORNER_BOTTOMLEFT;
+ }
+
+ STYLE_FUNCTION(draw_spinbutton_down) (cr, &murrine_style->colors, ¶ms, x, y, width, height);
+ }
+ }
+ else if (DETAIL ("spinbutton"))
+ {
+ WidgetParameters params;
+
+ murrine_set_widget_parameters (widget, style, state_type, ¶ms);
+ params.roundness = murrine_style->roundness;
+
+ boolean horizontal = TRUE;
+ if (((float)width/height<0.5)|| (murrine_style->glazestyle > 0 && width<height))
+ horizontal = FALSE;
+
+ if (murrine_style->roundness > 0)
+ {
+ if (params.ltr)
+ {
+ params.corners = MRN_CORNER_TOPRIGHT | MRN_CORNER_BOTTOMRIGHT;
+ if (!horizontal)
+ params.corners = MRN_CORNER_BOTTOMLEFT | MRN_CORNER_BOTTOMRIGHT;
+ }
+ else
+ {
+ params.corners = MRN_CORNER_TOPLEFT | MRN_CORNER_BOTTOMLEFT;
+ if (!horizontal)
+ params.corners = MRN_CORNER_BOTTOMRIGHT | MRN_CORNER_BOTTOMLEFT;
+ }
+ }
+ else
+ params.corners = MRN_CORNER_NONE;
+
+ if (style->xthickness > 1)
+ {
+ if (params.ltr)
+ x--;
+ width++;
+ }
+
+ /* draw_spinbutton (cr, &murrine_style->colors, ¶ms, x, y, width, height); */
+ STYLE_FUNCTION(draw_button) (cr, &murrine_style->colors, ¶ms, x, y, width, height, horizontal);
+ }
+ else if (DETAIL ("trough") && widget && MRN_IS_SCALE (widget))
+ {
+ GtkAdjustment *adjustment = gtk_range_get_adjustment (GTK_RANGE (widget));
+ WidgetParameters params;
+ SliderParameters slider;
+ gint slider_length;
+
+ gtk_widget_style_get (widget, "slider-length", &slider_length, NULL);
+
+ slider.inverted = gtk_range_get_inverted (GTK_RANGE (widget));
+ slider.horizontal = (GTK_RANGE (widget)->orientation == GTK_ORIENTATION_HORIZONTAL);
+ slider.fill_size = ((slider.horizontal ? width : height) - slider_length) *
+ (1 / ((adjustment->upper - adjustment->lower) / (adjustment->value - adjustment->lower)))
+ + slider_length / 2;
+ if (slider.horizontal)
+ slider.inverted = slider.inverted != (murrine_get_direction (widget) == GTK_TEXT_DIR_RTL);
+
+ murrine_set_widget_parameters (widget, style, state_type, ¶ms);
+ params.corners = MRN_CORNER_NONE;
+
+ STYLE_FUNCTION(draw_scale_trough) (cr, &murrine_style->colors,
+ ¶ms, &slider,
+ x, y, width, height);
+ }
+ else if (DETAIL ("trough") && widget && MRN_IS_PROGRESS_BAR (widget))
+ {
+ WidgetParameters params;
+
+ murrine_set_widget_parameters (widget, style, state_type, ¶ms);
+
+ STYLE_FUNCTION(draw_progressbar_trough) (cr, colors, ¶ms, x, y, width, height);
+ }
+ else if (DETAIL ("trough") && widget && (MRN_IS_VSCROLLBAR (widget) || MRN_IS_HSCROLLBAR (widget)))
+ {
+ WidgetParameters params;
+ ScrollBarParameters scrollbar;
+
+ scrollbar.horizontal = TRUE;
+ scrollbar.junction = murrine_scrollbar_get_junction (widget);
+ scrollbar.steppers = murrine_scrollbar_visible_steppers (widget);
+ scrollbar.stepperstyle = murrine_style->stepperstyle;
+
+ murrine_set_widget_parameters (widget, style, state_type, ¶ms);
+
+ if (murrine_style->roundness > 0)
+ params.corners = MRN_CORNER_ALL;
+ else
+ params.corners = MRN_CORNER_NONE;
+
+ if (MRN_IS_RANGE (widget))
+ scrollbar.horizontal = GTK_RANGE (widget)->orientation == GTK_ORIENTATION_HORIZONTAL;
+
+ if (murrine_style->stepperstyle != 1 && !params.mrn_gradient.use_rgba)
+ {
+ if (scrollbar.horizontal)
+ {
+ x += 2;
+ width -= 4;
+ }
+ else
+ {
+ y += 2;
+ height -= 4;
+ }
+ }
+
+ STYLE_FUNCTION(draw_scrollbar_trough) (cr, colors, ¶ms, &scrollbar, x, y, width, height);
+ }
+ else if (DETAIL ("bar"))
+ {
+ WidgetParameters params;
+
+ ProgressBarParameters progressbar;
+ gdouble elapsed = 0.0;
+
+ if (widget && MRN_IS_PROGRESS_BAR (widget))
+ progressbar.orientation = gtk_progress_bar_get_orientation (GTK_PROGRESS_BAR (widget));
+ else
+ progressbar.orientation = MRN_ORIENTATION_LEFT_TO_RIGHT;
+
+ if (!params.ltr)
+ {
+ if (progressbar.orientation == GTK_PROGRESS_LEFT_TO_RIGHT)
+ progressbar.orientation = GTK_PROGRESS_RIGHT_TO_LEFT;
+ else if (progressbar.orientation == GTK_PROGRESS_RIGHT_TO_LEFT)
+ progressbar.orientation = GTK_PROGRESS_LEFT_TO_RIGHT;
+ }
+
+#ifdef HAVE_ANIMATION
+ if(murrine_style->animation && MRN_IS_PROGRESS_BAR (widget))
+ {
+ gboolean activity_mode = GTK_PROGRESS (widget)->activity_mode;
+
+ if (!activity_mode)
+ murrine_animation_progressbar_add ((gpointer)widget);
+ }
+
+ elapsed = murrine_animation_elapsed (widget);
+#endif
+
+ murrine_set_widget_parameters (widget, style, state_type, ¶ms);
+ params.roundness = murrine_style->roundness;
+
+ /* cairo_reset_clip (cr); */
+
+ /* The x-1 and width+2 are to make the fill cover the left and
+ * right-hand sides of the trough box */
+
+#ifndef HAVE_ANIMATIONTOLEFT
+ STYLE_FUNCTION(draw_progressbar_fill) (cr, colors, ¶ms, &progressbar,
+ x-1, y, width+2, height,
+ 10 - (int)(elapsed * 10.0) % 10);
+#else
+ STYLE_FUNCTION(draw_progressbar_fill) (cr, colors, ¶ms, &progressbar,
+ x-1, y, width+2, height,
+ 10 + (int)(elapsed * 10.0) % 10);
+#endif
+ }
+ else if (DETAIL ("hscale") || DETAIL ("vscale"))
+ {
+ WidgetParameters params;
+ /* SliderParameters slider; */
+
+ murrine_set_widget_parameters (widget, style, state_type, ¶ms);
+
+ boolean horizontal = TRUE;
+ if (DETAIL ("vscale"))
+ horizontal = FALSE;
+
+ if (murrine_style->roundness > 0)
+ params.corners = MRN_CORNER_ALL;
+ else
+ params.corners = MRN_CORNER_NONE;
+
+ STYLE_FUNCTION(draw_button) (cr, &murrine_style->colors, ¶ms, x, y, width, height, horizontal);
+
+ if (murrine_style->sliderstyle == 1)
+ STYLE_FUNCTION(draw_slider_handle) (cr, &murrine_style->colors, ¶ms, x, y, width, height, horizontal);
+ }
+ else if (DETAIL ("optionmenu"))
+ {
+ WidgetParameters params;
+ OptionMenuParameters optionmenu;
+
+ GtkRequisition indicator_size;
+ GtkBorder indicator_spacing;
+
+ murrine_option_menu_get_props (widget, &indicator_size, &indicator_spacing);
+
+ if (widget && murrine_get_direction (widget) == GTK_TEXT_DIR_RTL)
+ optionmenu.linepos = (indicator_size.width + indicator_spacing.left + indicator_spacing.right) + style->xthickness;
+ else
+ optionmenu.linepos = width - (indicator_size.width + indicator_spacing.left + indicator_spacing.right) - style->xthickness;
+
+ murrine_set_widget_parameters (widget, style, state_type, ¶ms);
+
+ if (murrine_style->roundness > 0)
+ params.corners = MRN_CORNER_ALL;
+ else
+ params.corners = MRN_CORNER_NONE;
+
+ STYLE_FUNCTION(draw_optionmenu) (cr, colors, ¶ms, &optionmenu, x, y, width, height);
+ }
+ else if (DETAIL ("menuitem"))
+ {
+ WidgetParameters params;
+
+ murrine_set_widget_parameters (widget, style, state_type, ¶ms);
+
+ if (murrine_style->roundness > 0)
+ params.corners = MRN_CORNER_ALL;
+ else
+ params.corners = MRN_CORNER_NONE;
+
+ if (widget && !(MRN_IS_MENU_BAR (widget->parent) && murrine_style->menubaritemstyle))
+ {
+ if (murrine_style->menustyle != 1 || (MRN_IS_MENU_BAR (widget->parent) && !murrine_style->menubaritemstyle))
+ STYLE_FUNCTION(draw_menuitem) (cr, colors, ¶ms, x, y, width, height, murrine_style->menuitemstyle);
+ else
+ /* little translation */
+ STYLE_FUNCTION(draw_menuitem) (cr, colors, ¶ms, x+3, y, width-3, height, murrine_style->menuitemstyle);
+ }
+
+ if (widget && MRN_IS_MENU_BAR (widget->parent) && murrine_style->menubaritemstyle)
+ {
+ params.active = FALSE;
+ params.prelight = TRUE;
+ params.focus = TRUE;
+ params.state_type = MRN_STATE_SELECTED;
+ params.xthickness = 2;
+ params.ythickness = 2;
+
+ if (murrine_style->roundness > 0)
+ params.corners = MRN_CORNER_TOPRIGHT | MRN_CORNER_TOPLEFT;
+ else
+ params.corners = MRN_CORNER_NONE;
+
+ STYLE_FUNCTION(draw_button) (cr, colors, ¶ms, x, y, width, height+1, TRUE);
+ }
+ }
+ else if (DETAIL ("hscrollbar") || DETAIL ("vscrollbar") || DETAIL ("slider") || DETAIL ("stepper"))
+ {
+ WidgetParameters params;
+ ScrollBarParameters scrollbar;
+
+ scrollbar.has_color = FALSE;
+ scrollbar.horizontal = TRUE;
+ scrollbar.junction = murrine_scrollbar_get_junction (widget);
+ scrollbar.steppers = murrine_scrollbar_visible_steppers (widget);
+ scrollbar.style = murrine_style->scrollbarstyle;
+ scrollbar.stepperstyle = murrine_style->stepperstyle;
+
+ if (MRN_IS_RANGE (widget))
+ scrollbar.horizontal = GTK_RANGE (widget)->orientation == GTK_ORIENTATION_HORIZONTAL;
+
+ if (murrine_style->colorize_scrollbar)
+ {
+ scrollbar.color = colors->spot[1];
+ scrollbar.has_color = TRUE;
+ }
+
+ if (!scrollbar.has_color)
+ scrollbar.color = colors->bg[0];
+
+ if (murrine_style->has_scrollbar_color)
+ {
+ murrine_gdk_color_to_rgb (&murrine_style->scrollbar_color, &scrollbar.color.r, &scrollbar.color.g, &scrollbar.color.b);
+ scrollbar.has_color = TRUE;
+ }
+
+ murrine_set_widget_parameters (widget, style, state_type, ¶ms);
+
+ params.corners = MRN_CORNER_NONE;
+
+ if (DETAIL ("slider"))
+ {
+ if (murrine_style->roundness == 1)
+ params.corners = MRN_CORNER_ALL;
+ else
+ params.corners = MRN_CORNER_NONE;
+
+ STYLE_FUNCTION(draw_scrollbar_slider) (cr, colors, ¶ms, &scrollbar, x, y, width, height);
+ }
+ else
+ {
+ if (murrine_style->roundness > 1)
+ {
+ ScrollBarStepperParameters stepper;
+ GdkRectangle this_rectangle = { x, y, width, height };
+
+ stepper.stepper = murrine_scrollbar_get_stepper (widget, &this_rectangle);
+
+ if (scrollbar.horizontal)
+ {
+ if (stepper.stepper == MRN_STEPPER_A)
+ params.corners = MRN_CORNER_TOPLEFT | MRN_CORNER_BOTTOMLEFT;
+ else if (stepper.stepper == MRN_STEPPER_D)
+ params.corners = MRN_CORNER_TOPRIGHT | MRN_CORNER_BOTTOMRIGHT;
+ }
+ else
+ {
+ if (stepper.stepper == MRN_STEPPER_A)
+ params.corners = MRN_CORNER_BOTTOMLEFT | MRN_CORNER_TOPLEFT;
+ else if (stepper.stepper == MRN_STEPPER_D)
+ params.corners = MRN_CORNER_TOPRIGHT | MRN_CORNER_BOTTOMRIGHT;
+ }
+ }
+ else if (murrine_style->roundness == 1)
+ params.corners = MRN_CORNER_ALL;
+ else
+ params.corners = MRN_CORNER_NONE;
+
+ if (murrine_style->stepperstyle != 1)
+ STYLE_FUNCTION(draw_scrollbar_stepper) (cr, colors, ¶ms, &scrollbar, x, y, width, height);
+ }
+ }
+ else if (DETAIL ("toolbar") || DETAIL ("handlebox_bin") || DETAIL ("dockitem_bin"))
+ {
+ /* Only draw the shadows on horizontal toolbars */
+ if (shadow_type != GTK_SHADOW_NONE && height < 2*width )
+ {
+ WidgetParameters params;
+ ToolbarParameters toolbar;
+
+ murrine_set_widget_parameters (widget, style, state_type, ¶ms);
+
+ murrine_set_toolbar_parameters (&toolbar, widget, window, x, y);
+ toolbar.style = murrine_style->toolbarstyle;
+
+ STYLE_FUNCTION(draw_toolbar) (cr, colors, ¶ms, &toolbar, x, y, width, height);
+ }
+ }
+ else if (DETAIL ("trough"))
+ {
+ /* Do nothing? */
+ }
+ else if (DETAIL ("menu"))
+ {
+ WidgetParameters params;
+
+ murrine_set_widget_parameters (widget, style, state_type, ¶ms);
+
+ STYLE_FUNCTION(draw_menu_frame) (cr, colors, ¶ms, x, y, width, height, murrine_style->menustyle);
+ }
+ else
+ {
+ murrine_parent_class->draw_box (style, window, state_type, shadow_type, area,
+ widget, detail, x, y, width, height);
+ }
+
+ cairo_destroy (cr);
+}
+
+static void
+murrine_style_draw_slider (DRAW_ARGS, GtkOrientation orientation)
+{
+ if (DETAIL ("hscale") || DETAIL ("vscale"))
+ {
+ murrine_style_draw_box (style, window, state_type, shadow_type, area,
+ widget, detail, x, y, width, height);
+ }
+ else
+ murrine_parent_class->draw_slider (style, window, state_type, shadow_type, area,
+ widget, detail, x, y, width, height, orientation);
+}
+
+static void
+murrine_style_draw_option (DRAW_ARGS)
+{
+ MurrineStyle *murrine_style = MURRINE_STYLE (style);
+ MurrineColors *colors = &murrine_style->colors;
+ cairo_t *cr;
+
+ CHECK_ARGS
+ SANITIZE_SIZE
+
+ cr = murrine_begin_paint (window, area);
+
+ WidgetParameters params;
+ OptionParameters option;
+
+ option.draw_bullet = ((shadow_type == GTK_SHADOW_IN) || (shadow_type == GTK_SHADOW_ETCHED_IN));
+ option.inconsistent = (shadow_type == GTK_SHADOW_ETCHED_IN);
+ double trans = 1.0;
+
+ murrine_set_widget_parameters (widget, style, state_type, ¶ms);
+
+ #ifdef HAVE_ANIMATION
+ if (murrine_style->animation)
+ murrine_animation_connect_checkbox (widget);
+
+ if (murrine_style->animation &&
+ MRN_IS_CHECK_BUTTON (widget) &&
+ murrine_animation_is_animated (widget) &&
+ !gtk_toggle_button_get_inconsistent (GTK_TOGGLE_BUTTON (widget)))
+ {
+ gfloat elapsed = murrine_animation_elapsed (widget);
+ trans = sqrt (sqrt (MIN(elapsed / CHECK_ANIMATION_TIME, 1.0)));
+ }
+ #endif
+
+ STYLE_FUNCTION(draw_radiobutton) (cr, colors, ¶ms, &option, x, y, width, height, trans);
+
+ cairo_destroy (cr);
+}
+
+static void
+murrine_style_draw_check (DRAW_ARGS)
+{
+ MurrineStyle *murrine_style = MURRINE_STYLE (style);
+ MurrineColors *colors = &murrine_style->colors;
+ cairo_t *cr;
+
+ CHECK_ARGS
+ SANITIZE_SIZE
+
+ cr = murrine_begin_paint (window, area);
+
+ WidgetParameters params;
+ OptionParameters option;
+
+ option.draw_bullet = ((shadow_type == GTK_SHADOW_IN) || (shadow_type == GTK_SHADOW_ETCHED_IN));
+ option.inconsistent = (shadow_type == GTK_SHADOW_ETCHED_IN);
+ double trans = 1.0;
+
+ murrine_set_widget_parameters (widget, style, state_type, ¶ms);
+
+ #ifdef HAVE_ANIMATION
+ if (murrine_style->animation)
+ murrine_animation_connect_checkbox (widget);
+
+ if (murrine_style->animation && MRN_IS_CHECK_BUTTON (widget) &&
+ murrine_animation_is_animated (widget) &&
+ !gtk_toggle_button_get_inconsistent (GTK_TOGGLE_BUTTON (widget)))
+ {
+ gfloat elapsed = murrine_animation_elapsed (widget);
+ trans = sqrt (sqrt (MIN(elapsed / CHECK_ANIMATION_TIME, 1.0)));
+ }
+ #endif
+
+ STYLE_FUNCTION(draw_checkbox) (cr, colors, ¶ms, &option, x, y, width, height, trans);
+
+ cairo_destroy (cr);
+}
+
+static void
+murrine_style_draw_tab (DRAW_ARGS)
+{
+ MurrineStyle *murrine_style = MURRINE_STYLE (style);
+ MurrineColors *colors = &murrine_style->colors;
+
+ cairo_t *cr;
+
+ CHECK_ARGS
+ SANITIZE_SIZE
+
+ cr = murrine_begin_paint (window, area);
+
+ WidgetParameters params;
+ ArrowParameters arrow;
+
+ arrow.type = MRN_ARROW_COMBO;
+ arrow.direction = MRN_DIRECTION_DOWN;
+
+ murrine_set_widget_parameters (widget, style, state_type, ¶ms);
+
+ STYLE_FUNCTION(draw_arrow) (cr, colors, ¶ms, &arrow, x, y, width, height);
+
+ cairo_destroy (cr);
+}
+
+static void
+murrine_style_draw_vline (GtkStyle *style,
+ GdkWindow *window,
+ GtkStateType state_type,
+ GdkRectangle *area,
+ GtkWidget *widget,
+ const gchar *detail,
+ gint y1,
+ gint y2,
+ gint x)
+{
+ /* Get toplevel window for this widget */
+ GtkWidget* toplevel = gtk_widget_get_toplevel (widget);
+
+ MurrineStyle *murrine_style = MURRINE_STYLE (style);
+ MurrineColors *colors = &murrine_style->colors;
+ cairo_t *cr;
+
+ CHECK_ARGS
+
+ cr = murrine_begin_paint (window, area);
+
+ SeparatorParameters separator;
+ separator.horizontal = FALSE;
+
+ WidgetParameters params;
+
+ params.drawstyle = MRN_DRAW_STYLE_MURRINE;
+ if (murrine_widget_is_rgba (toplevel))
+ {
+ params.drawstyle = MRN_DRAW_STYLE_RGBA;
+ }
+
+ if (!(widget &&
+ MRN_IS_HBOX (widget->parent) &&
+ MRN_IS_TOGGLE_BUTTON (widget->parent->parent) &&
+ MRN_IS_COMBO_BOX (widget->parent->parent->parent)))
+ {
+ STYLE_FUNCTION(draw_separator) (cr, colors, NULL, &separator, x, y1, 2, y2-y1);
+ }
+ else
+ STYLE_FUNCTION(draw_combo_separator) (cr, colors, NULL, x, y1, 2, y2-y1);
+
+ cairo_destroy (cr);
+}
+
+static void
+murrine_style_draw_hline (GtkStyle *style,
+ GdkWindow *window,
+ GtkStateType state_type,
+ GdkRectangle *area,
+ GtkWidget *widget,
+ const gchar *detail,
+ gint x1,
+ gint x2,
+ gint y)
+{
+ /* Get toplevel window for this widget */
+ GtkWidget* toplevel = gtk_widget_get_toplevel (widget);
+
+ MurrineStyle *murrine_style = MURRINE_STYLE (style);
+ MurrineColors *colors = &murrine_style->colors;
+ cairo_t *cr;
+
+ CHECK_ARGS
+
+ cr = murrine_begin_paint (window, area);
+
+ SeparatorParameters separator;
+ separator.horizontal = TRUE;
+
+ WidgetParameters params;
+
+ params.drawstyle = MRN_DRAW_STYLE_MURRINE;
+ if (murrine_widget_is_rgba (toplevel))
+ {
+ params.drawstyle = MRN_DRAW_STYLE_RGBA;
+ }
+
+ STYLE_FUNCTION(draw_separator) (cr, colors, NULL, &separator, x1, y, x2-x1, 2);
+
+ cairo_destroy (cr);
+}
+
+static void
+murrine_style_draw_shadow_gap (DRAW_ARGS,
+ GtkPositionType gap_side,
+ gint gap_x,
+ gint gap_width)
+{
+ MurrineStyle *murrine_style = MURRINE_STYLE (style);
+ const MurrineColors *colors = &murrine_style->colors;
+ cairo_t *cr;
+
+ CHECK_ARGS
+ SANITIZE_SIZE
+
+ cr = murrine_begin_paint (window, area);
+
+ if (DETAIL ("frame"))
+ {
+ WidgetParameters params;
+ FrameParameters frame;
+
+ frame.shadow = shadow_type;
+ frame.gap_side = gap_side;
+ frame.gap_x = gap_x;
+ frame.gap_width = gap_width;
+ frame.border = (MurrineRGB*)&colors->shade[4];
+
+ murrine_set_widget_parameters (widget, style, state_type, ¶ms);
+
+ params.corners = MRN_CORNER_ALL;
+
+ if (params.roundness < 2)
+ params.corners = MRN_CORNER_NONE;
+
+ STYLE_FUNCTION(draw_frame) (cr, colors, ¶ms, &frame, x, y, width, height);
+ }
+ else
+ {
+ murrine_parent_class->draw_shadow_gap (style, window, state_type, shadow_type, area,
+ widget, detail, x, y, width, height,
+ gap_side, gap_x, gap_width);
+ }
+
+ cairo_destroy (cr);
+}
+
+static void
+murrine_style_draw_resize_grip (GtkStyle *style,
+ GdkWindow *window,
+ GtkStateType state_type,
+ GdkRectangle *area,
+ GtkWidget *widget,
+ const gchar *detail,
+ GdkWindowEdge edge,
+ gint x,
+ gint y,
+ gint width,
+ gint height)
+{
+ MurrineStyle *murrine_style = MURRINE_STYLE (style);
+ MurrineColors *colors = &murrine_style->colors;
+
+ cairo_t *cr;
+
+ CHECK_ARGS
+ SANITIZE_SIZE
+
+ cr = murrine_begin_paint (window, area);
+
+ WidgetParameters params;
+ ResizeGripParameters grip;
+ grip.edge = (MurrineWindowEdge)edge;
+
+ int lx, ly;
+
+ g_return_if_fail (window != NULL);
+
+ if (edge != GDK_WINDOW_EDGE_SOUTH_EAST)
+ return; /* sorry... need to work on this :P */
+
+ murrine_set_widget_parameters (widget, style, state_type, ¶ms);
+
+ STYLE_FUNCTION(draw_resize_grip) (cr, colors, ¶ms, &grip, x, y, width, height);
+
+ cairo_destroy (cr);
+
+ return;
+}
+
+static void
+murrine_style_draw_arrow (GtkStyle *style,
+ GdkWindow *window,
+ GtkStateType state_type,
+ GtkShadowType shadow,
+ GdkRectangle *area,
+ GtkWidget *widget,
+ const gchar *detail,
+ GtkArrowType arrow_type,
+ gboolean fill,
+ gint x,
+ gint y,
+ gint width,
+ gint height)
+{
+ MurrineStyle *murrine_style = MURRINE_STYLE (style);
+ MurrineColors *colors = &murrine_style->colors;
+ cairo_t *cr;
+
+ CHECK_ARGS
+ SANITIZE_SIZE;
+
+ cr = murrine_begin_paint (window, area);
+
+ WidgetParameters params;
+ ArrowParameters arrow;
+
+ if (arrow_type == GTK_ARROW_NONE)
+ {
+ cairo_destroy (cr);
+ return;
+ }
+
+ arrow.type = MRN_ARROW_NORMAL;
+ arrow.direction = (MurrineDirection)arrow_type;
+
+ if (MRN_IS_COMBO_BOX (widget) && !MRN_IS_COMBO_BOX_ENTRY (widget))
+ {
+ arrow.type = MRN_ARROW_COMBO;
+ }
+
+ murrine_set_widget_parameters (widget, style, state_type, ¶ms);
+
+ /* I have no idea why, but the arrow of GtkCombo is larger than in other places.
+ * Subtracting 3 seems to fix this. */
+ if (widget && widget->parent && MRN_IS_COMBO (widget->parent->parent))
+ {
+ if (params.ltr)
+ x += 1;
+ else
+ x += 2;
+ width -= 3;
+ }
+
+ STYLE_FUNCTION(draw_arrow) (cr, colors, ¶ms, &arrow, x, y, width, height);
+
+ cairo_destroy (cr);
+}
+
+static void
+murrine_style_draw_layout (GtkStyle *style,
+ GdkWindow *window,
+ GtkStateType state_type,
+ gboolean use_text,
+ GdkRectangle *area,
+ GtkWidget *widget,
+ const gchar *detail, gint x, gint y,
+ PangoLayout *layout)
+{
+ GdkGC *gc;
+
+ g_return_if_fail (GTK_IS_STYLE (style));
+ g_return_if_fail (window != NULL);
+
+ gc = use_text ? style->text_gc[state_type] : style->fg_gc[state_type];
+
+ if (area)
+ gdk_gc_set_clip_rectangle (gc, area);
+
+ if (state_type == GTK_STATE_INSENSITIVE)
+ {
+ MurrineStyle *murrine_style = MURRINE_STYLE (style);
+ MurrineColors *colors = &murrine_style->colors;
+
+ WidgetParameters params;
+
+ murrine_set_widget_parameters (widget, style, state_type, ¶ms);
+
+ GdkColor etched;
+ MurrineRGB temp;
+
+ if (GTK_WIDGET_NO_WINDOW (widget))
+ murrine_shade (¶ms.parentbg, &temp, 1.2);
+ else
+ murrine_shade (&colors->bg[widget->state], &temp, 1.2);
+
+ etched.red = (int) (temp.r * 65535);
+ etched.green = (int) (temp.g * 65535);
+ etched.blue = (int) (temp.b * 65535);
+
+ gdk_draw_layout_with_colors (window, gc, x + 1, y + 1, layout, &etched, NULL);
+ gdk_draw_layout (window, gc, x, y, layout);
+ }
+ else
+ {
+ gdk_draw_layout (window, gc, x, y, layout);
+ }
+
+ if (area)
+ gdk_gc_set_clip_rectangle (gc, NULL);
+}
+
+static void
+murrine_style_init_from_rc (GtkStyle *style,
+ GtkRcStyle *rc_style)
+{
+ MurrineStyle *murrine_style = MURRINE_STYLE (style);
+
+ murrine_parent_class->init_from_rc (style, rc_style);
+
+ murrine_style->gradient_stop_1 = MURRINE_RC_STYLE (rc_style)->gradient_stop_1;
+ murrine_style->gradient_stop_2 = MURRINE_RC_STYLE (rc_style)->gradient_stop_2;
+ murrine_style->gradient_stop_3 = MURRINE_RC_STYLE (rc_style)->gradient_stop_3;
+ murrine_style->gradient_stop_4 = MURRINE_RC_STYLE (rc_style)->gradient_stop_4;
+ murrine_style->has_gradient_stop = MURRINE_RC_STYLE (rc_style)->has_gradient_stop;
+ murrine_style->highlight_ratio = MURRINE_RC_STYLE (rc_style)->highlight_ratio;
+ murrine_style->innerborder_ratio = MURRINE_RC_STYLE (rc_style)->innerborder_ratio;
+ murrine_style->glazestyle = MURRINE_RC_STYLE (rc_style)->glazestyle;
+
+ if (murrine_style->has_gradient_stop &&
+ murrine_style->glazestyle != 0)
+ {
+ double gradient_stop_mid = ((murrine_style->gradient_stop_2)+(murrine_style->gradient_stop_2))/2.0;
+ murrine_style->gradient_stop_2 = gradient_stop_mid;
+ murrine_style->gradient_stop_3 = gradient_stop_mid;
+ }
+
+ /* Ignore roundness > 1 with glazestyle = 2 */
+ if (murrine_style->glazestyle == 2)
+ {
+ if (MURRINE_RC_STYLE (rc_style)->roundness > 0)
+ murrine_style->roundness = 1;
+ else
+ murrine_style->roundness = 0;
+ }
+ else
+ murrine_style->roundness = MURRINE_RC_STYLE (rc_style)->roundness;
+ murrine_style->menubarstyle = MURRINE_RC_STYLE (rc_style)->menubarstyle;
+ murrine_style->menubaritemstyle = MURRINE_RC_STYLE (rc_style)->menubaritemstyle;
+ murrine_style->menustyle = MURRINE_RC_STYLE (rc_style)->menustyle;
+ murrine_style->menuitemstyle = MURRINE_RC_STYLE (rc_style)->menuitemstyle;
+ murrine_style->listviewheaderstyle = MURRINE_RC_STYLE (rc_style)->listviewheaderstyle;
+ murrine_style->listviewstyle = MURRINE_RC_STYLE (rc_style)->listviewstyle;
+ murrine_style->sliderstyle = MURRINE_RC_STYLE (rc_style)->sliderstyle;
+ murrine_style->scrollbarstyle = MURRINE_RC_STYLE (rc_style)->scrollbarstyle;
+ murrine_style->has_scrollbar_color = MURRINE_RC_STYLE (rc_style)->has_scrollbar_color;
+ murrine_style->stepperstyle = MURRINE_RC_STYLE (rc_style)->stepperstyle;
+ murrine_style->toolbarstyle = MURRINE_RC_STYLE (rc_style)->toolbarstyle;
+ murrine_style->animation = MURRINE_RC_STYLE (rc_style)->animation;
+ murrine_style->gradients = MURRINE_RC_STYLE (rc_style)->gradients;
+ murrine_style->colorize_scrollbar = MURRINE_RC_STYLE (rc_style)->colorize_scrollbar;
+ murrine_style->rgba = MURRINE_RC_STYLE (rc_style)->rgba;
+
+ if (murrine_style->has_scrollbar_color)
+ murrine_style->scrollbar_color = MURRINE_RC_STYLE (rc_style)->scrollbar_color;
+
+ g_assert ((MURRINE_RC_STYLE (rc_style)->style >= 0) && (MURRINE_RC_STYLE (rc_style)->style < MRN_NUM_STYLES));
+ murrine_style->style = MURRINE_RC_STYLE (rc_style)->style;
+
+ switch (murrine_style->style)
+ {
+ case (MRN_STYLE_NODOKA):
+ murrine_style->highlight_ratio = 1.0;
+ murrine_style->gradients = TRUE;
+ murrine_style->sliderstyle = 1;
+ murrine_style->scrollbarstyle = 2;
+ murrine_style->stepperstyle = 0;
+ murrine_style->colorize_scrollbar = FALSE;
+ murrine_style->has_scrollbar_color = FALSE;
+ murrine_style->has_gradient_stop = FALSE;
+ break;
+ case (MRN_STYLE_MIST):
+ murrine_style->highlight_ratio = 1.0;
+ murrine_style->gradients = FALSE;
+ break;
+ case (MRN_STYLE_CANDIDO):
+ murrine_style->highlight_ratio = 1.0;
+ murrine_style->innerborder_ratio = 1.06;
+ murrine_style->gradients = TRUE;
+ murrine_style->gradient_stop_1 = 1.01;
+ murrine_style->gradient_stop_2 = 0.99;
+ murrine_style->gradient_stop_3 = 0.99;
+ murrine_style->gradient_stop_4 = 0.97;
+ break;
+ case (MRN_STYLE_CLEARLOOKS):
+ murrine_style->gradient_stop_1 = 1.08;
+ murrine_style->gradient_stop_2 = 1.02;
+ murrine_style->gradient_stop_3 = 1.00;
+ murrine_style->gradient_stop_4 = 0.94;
+ murrine_style->has_gradient_stop = TRUE;
+ murrine_style->gradients = TRUE;
+ murrine_style->highlight_ratio = 1.0;
+ murrine_style->toolbarstyle = 1;
+ murrine_style->innerborder_ratio = 1.02;
+ murrine_style->menustyle = 0;
+ murrine_style->sliderstyle = 1;
+ murrine_style->scrollbarstyle = 2;
+ break;
+ };
+}
+
+static void
+murrine_style_realize (GtkStyle * style)
+{
+ MurrineStyle *murrine_style = MURRINE_STYLE (style);
+ double shades[] = {1.15, 0.95, 0.896, 0.82, 0.75, 0.665, 0.5, 0.45, 0.4};
+ MurrineRGB spot_color;
+ MurrineRGB bg_normal;
+ double contrast;
+ int i;
+
+ murrine_parent_class->realize (style);
+
+ contrast = MURRINE_RC_STYLE (style->rc_style)->contrast;
+
+ bg_normal.r = style->bg[0].red / 65535.0;
+ bg_normal.g = style->bg[0].green / 65535.0;
+ bg_normal.b = style->bg[0].blue / 65535.0;
+
+ /* Lighter to darker */
+ for (i = 0; i < 9; i++)
+ {
+ murrine_shade (&bg_normal, &murrine_style->colors.shade[i],
+ (shades[i]-0.9) * contrast + 0.9);
+ }
+
+ spot_color.r = style->bg[GTK_STATE_SELECTED].red / 65535.0;
+ spot_color.g = style->bg[GTK_STATE_SELECTED].green / 65535.0;
+ spot_color.b = style->bg[GTK_STATE_SELECTED].blue / 65535.0;
+
+ murrine_shade (&spot_color, &murrine_style->colors.spot[0], 1.42);
+ murrine_shade (&spot_color, &murrine_style->colors.spot[1], 1.00);
+ murrine_shade (&spot_color, &murrine_style->colors.spot[2], 0.65);
+
+ for (i=0; i<5; i++)
+ {
+ murrine_gdk_color_to_rgb (&style->bg[i],
+ &murrine_style->colors.bg[i].r,
+ &murrine_style->colors.bg[i].g,
+ &murrine_style->colors.bg[i].b);
+
+ murrine_gdk_color_to_rgb (&style->base[i],
+ &murrine_style->colors.base[i].r,
+ &murrine_style->colors.base[i].g,
+ &murrine_style->colors.base[i].b);
+
+ murrine_gdk_color_to_rgb (&style->text[i],
+ &murrine_style->colors.text[i].r,
+ &murrine_style->colors.text[i].g,
+ &murrine_style->colors.text[i].b);
+
+ murrine_gdk_color_to_rgb (&style->fg[i],
+ &murrine_style->colors.fg[i].r,
+ &murrine_style->colors.fg[i].g,
+ &murrine_style->colors.fg[i].b);
+ }
+}
+
+static void
+gdk_cairo_set_source_color_alpha (cairo_t *cr,
+ GdkColor *color,
+ float alpha)
+{
+ g_return_if_fail (cr != NULL);
+ g_return_if_fail (color != NULL);
+
+ cairo_set_source_rgba (cr,
+ color->red / 65535.,
+ color->green / 65535.,
+ color->blue / 65535.,
+ alpha);
+}
+
+static void
+murrine_style_draw_focus (GtkStyle *style, GdkWindow *window, GtkStateType state_type,
+ GdkRectangle *area, GtkWidget *widget, const gchar *detail,
+ gint x, gint y, gint width, gint height)
+{
+ cairo_t *cr;
+
+ CHECK_ARGS
+ SANITIZE_SIZE
+
+ cr = gdk_cairo_create (window);
+
+ gboolean free_dash_list = FALSE;
+ gint line_width = 1;
+ gint8 *dash_list = "\1\1";
+
+ if (widget)
+ {
+ gtk_widget_style_get (widget,
+ "focus-line-width", &line_width,
+ "focus-line-pattern",
+ (gchar *) & dash_list, NULL);
+
+ free_dash_list = TRUE;
+ }
+
+ if (detail && !strcmp (detail, "add-mode"))
+ {
+ if (free_dash_list)
+ g_free (dash_list);
+
+ dash_list = "\4\4";
+ free_dash_list = FALSE;
+ }
+
+ if (detail && !strcmp (detail, "colorwheel_light"))
+ cairo_set_source_rgb (cr, 0., 0., 0.);
+ else if (detail && !strcmp (detail, "colorwheel_dark"))
+ cairo_set_source_rgb (cr, 1., 1., 1.);
+ else
+ gdk_cairo_set_source_color_alpha (cr, &style->fg[state_type], 0.7);
+
+ cairo_set_line_width (cr, line_width);
+
+ if (dash_list[0])
+ {
+ gint n_dashes = strlen (dash_list);
+ gdouble *dashes = g_new (gdouble, n_dashes);
+ gdouble total_length = 0;
+ gdouble dash_offset;
+ gint i;
+
+ for (i = 0; i < n_dashes; i++)
+ {
+ dashes[i] = dash_list[i];
+ total_length += dash_list[i];
+ }
+
+ dash_offset = -line_width / 2.;
+ while (dash_offset < 0)
+ dash_offset += total_length;
+
+ cairo_set_dash (cr, dashes, n_dashes, dash_offset);
+ g_free (dashes);
+ }
+
+ if (area)
+ {
+ gdk_cairo_rectangle (cr, area);
+ cairo_clip (cr);
+ }
+
+ cairo_rectangle (cr, x + line_width / 2., y + line_width / 2., width - line_width, height - line_width);
+ cairo_stroke (cr);
+ cairo_destroy (cr);
+
+ if (free_dash_list)
+ g_free (dash_list);
+}
+
+static void
+murrine_style_copy (GtkStyle * style, GtkStyle * src)
+{
+ MurrineStyle * mrn_style = MURRINE_STYLE (style);
+ MurrineStyle * mrn_src = MURRINE_STYLE (src);
+
+ mrn_style->animation = mrn_src->animation;
+ mrn_style->colorize_scrollbar = mrn_src->colorize_scrollbar;
+ mrn_style->colors = mrn_src->colors;
+ mrn_style->glazestyle = mrn_src->glazestyle;
+ mrn_style->gradient_stop_1 = mrn_src->gradient_stop_1;
+ mrn_style->gradient_stop_2 = mrn_src->gradient_stop_2;
+ mrn_style->gradient_stop_3 = mrn_src->gradient_stop_3;
+ mrn_style->gradient_stop_4 = mrn_src->gradient_stop_4;
+ mrn_style->gradients = mrn_src->gradients;
+ mrn_style->has_gradient_stop = mrn_src->has_gradient_stop;
+ mrn_style->has_scrollbar_color = mrn_src->has_scrollbar_color;
+ mrn_style->highlight_ratio = mrn_src->highlight_ratio;
+ mrn_style->innerborder_ratio = mrn_src->innerborder_ratio;
+ mrn_style->listviewheaderstyle = mrn_src->listviewheaderstyle;
+ mrn_style->listviewstyle = mrn_src->listviewstyle;
+ mrn_style->menubaritemstyle = mrn_src->menubaritemstyle;
+ mrn_style->menubarstyle = mrn_src->menubarstyle;
+ mrn_style->menuitemstyle = mrn_src->menuitemstyle;
+ mrn_style->menustyle = mrn_src->menustyle;
+ mrn_style->rgba = mrn_src->rgba;
+ mrn_style->roundness = mrn_src->roundness;
+ mrn_style->scrollbar_color = mrn_src->scrollbar_color;
+ mrn_style->scrollbarstyle = mrn_src->scrollbarstyle;
+ mrn_style->sliderstyle = mrn_src->sliderstyle;
+ mrn_style->stepperstyle = mrn_src->stepperstyle;
+ mrn_style->style = mrn_src->style;
+ mrn_style->toolbarstyle = mrn_src->toolbarstyle;
+
+ murrine_parent_class->copy (style, src);
+}
+
+static void
+murrine_style_unrealize (GtkStyle * style)
+{
+ murrine_parent_class->unrealize (style);
+}
+
+static GdkPixbuf *
+set_transparency (const GdkPixbuf *pixbuf, gdouble alpha_percent)
+{
+ GdkPixbuf *target;
+ guchar *data, *current;
+ guint x, y, rowstride, height, width;
+
+ g_return_val_if_fail (pixbuf != NULL, NULL);
+ g_return_val_if_fail (GDK_IS_PIXBUF (pixbuf), NULL);
+
+ /* Returns a copy of pixbuf with it's non-completely-transparent pixels to
+ have an alpha level "alpha_percent" of their original value. */
+
+ target = gdk_pixbuf_add_alpha (pixbuf, FALSE, 0, 0, 0);
+
+ if (alpha_percent == 1.0)
+ return target;
+ width = gdk_pixbuf_get_width (target);
+ height = gdk_pixbuf_get_height (target);
+ rowstride = gdk_pixbuf_get_rowstride (target);
+ data = gdk_pixbuf_get_pixels (target);
+
+ for (y = 0; y < height; y++)
+ {
+ for (x = 0; x < width; x++)
+ {
+ /* The "4" is the number of chars per pixel, in this case, RGBA,
+ the 3 means "skip to the alpha" */
+ current = data + (y * rowstride) + (x * 4) + 3;
+ *(current) = (guchar) (*(current) * alpha_percent);
+ }
+ }
+
+ return target;
+}
+
+static GdkPixbuf*
+scale_or_ref (GdkPixbuf *src,
+ int width,
+ int height)
+{
+ if (width == gdk_pixbuf_get_width (src) &&
+ height == gdk_pixbuf_get_height (src))
+ {
+ return g_object_ref (src);
+ }
+ else
+ {
+ return gdk_pixbuf_scale_simple (src, width, height, GDK_INTERP_BILINEAR);
+ }
+}
+
+static GdkPixbuf *
+murrine_style_draw_render_icon (GtkStyle *style,
+ const GtkIconSource *source,
+ GtkTextDirection direction,
+ GtkStateType state,
+ GtkIconSize size,
+ GtkWidget *widget,
+ const char *detail)
+{
+ int width = 1;
+ int height = 1;
+ GdkPixbuf *scaled;
+ GdkPixbuf *stated;
+ GdkPixbuf *base_pixbuf;
+ GdkScreen *screen;
+ GtkSettings *settings;
+
+ /* Oddly, style can be NULL in this function, because
+ * GtkIconSet can be used without a style and if so
+ * it uses this function.
+ */
+
+ base_pixbuf = gtk_icon_source_get_pixbuf (source);
+
+ g_return_val_if_fail (base_pixbuf != NULL, NULL);
+
+ if (widget && gtk_widget_has_screen (widget))
+ {
+ screen = gtk_widget_get_screen (widget);
+ settings = gtk_settings_get_for_screen (screen);
+ }
+ else if (style->colormap)
+ {
+ screen = gdk_colormap_get_screen (style->colormap);
+ settings = gtk_settings_get_for_screen (screen);
+ }
+ else
+ {
+ settings = gtk_settings_get_default ();
+ GTK_NOTE (MULTIHEAD,
+ g_warning ("Using the default screen for gtk_default_murrine_style_draw_render_icon()"));
+ }
+
+ if (size != (GtkIconSize) -1 && !gtk_icon_size_lookup_for_settings (settings, size, &width, &height))
+ {
+ g_warning (G_STRLOC ": invalid icon size '%d'", size);
+ return NULL;
+ }
+
+ /* If the size was wildcarded, and we're allowed to scale, then scale; otherwise,
+ * leave it alone.
+ */
+ if (size != (GtkIconSize)-1 && gtk_icon_source_get_size_wildcarded (source))
+ scaled = scale_or_ref (base_pixbuf, width, height);
+ else
+ scaled = g_object_ref (base_pixbuf);
+
+ /* If the state was wildcarded, then generate a state. */
+ if (gtk_icon_source_get_state_wildcarded (source))
+ {
+ if (state == GTK_STATE_INSENSITIVE)
+ {
+ stated = set_transparency (scaled, 0.3);
+#if 0
+ stated =
+ gdk_pixbuf_composite_color_simple (scaled,
+ gdk_pixbuf_get_width (scaled),
+ gdk_pixbuf_get_height (scaled),
+ GDK_INTERP_BILINEAR, 128,
+ gdk_pixbuf_get_width (scaled),
+ style->bg[state].pixel,
+ style->bg[state].pixel);
+#endif
+ gdk_pixbuf_saturate_and_pixelate (stated, stated, 0.1, FALSE);
+
+ g_object_unref (scaled);
+ }
+ else if (state == GTK_STATE_PRELIGHT)
+ {
+ stated = gdk_pixbuf_copy (scaled);
+
+ gdk_pixbuf_saturate_and_pixelate (scaled, stated, 1.2, FALSE);
+
+ g_object_unref (scaled);
+ }
+ else
+ {
+ stated = scaled;
+ }
+ }
+ else
+ stated = scaled;
+
+ return stated;
+}
+
+static void
+murrine_style_init (MurrineStyle * style)
+{
+}
+
+static void
+murrine_style_class_init (MurrineStyleClass * klass)
+{
+ GtkStyleClass *style_class = GTK_STYLE_CLASS (klass);
+
+ murrine_style_class = MURRINE_STYLE_CLASS (klass);
+ murrine_parent_class = g_type_class_peek_parent (klass);
+
+ style_class->copy = murrine_style_copy;
+ style_class->realize = murrine_style_realize;
+ style_class->unrealize = murrine_style_unrealize;
+ style_class->init_from_rc = murrine_style_init_from_rc;
+ style_class->draw_handle = murrine_style_draw_handle;
+ style_class->draw_slider = murrine_style_draw_slider;
+ style_class->draw_shadow_gap = murrine_style_draw_shadow_gap;
+ style_class->draw_focus = murrine_style_draw_focus;
+ style_class->draw_box = murrine_style_draw_box;
+ style_class->draw_shadow = murrine_style_draw_shadow;
+ style_class->draw_box_gap = murrine_style_draw_box_gap;
+ style_class->draw_extension = murrine_style_draw_extension;
+ style_class->draw_option = murrine_style_draw_option;
+ style_class->draw_check = murrine_style_draw_check;
+ style_class->draw_flat_box = murrine_style_draw_flat_box;
+ style_class->draw_tab = murrine_style_draw_tab;
+ style_class->draw_vline = murrine_style_draw_vline;
+ style_class->draw_hline = murrine_style_draw_hline;
+ style_class->draw_resize_grip = murrine_style_draw_resize_grip;
+ style_class->draw_arrow = murrine_style_draw_arrow;
+ style_class->draw_layout = murrine_style_draw_layout;
+ style_class->render_icon = murrine_style_draw_render_icon;
+
+ murrine_register_style_murrine (&murrine_style_class->style_functions[MRN_DRAW_STYLE_MURRINE]);
+ murrine_style_class->style_functions[MRN_DRAW_STYLE_RGBA] = murrine_style_class->style_functions[MRN_DRAW_STYLE_MURRINE];
+ murrine_register_style_rgba (&murrine_style_class->style_functions[MRN_DRAW_STYLE_RGBA]);
+}
+
+GType murrine_type_style = 0;
+
+void
+murrine_style_register_type (GTypeModule * module)
+{
+ static const GTypeInfo object_info =
+ {
+ sizeof (MurrineStyleClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) murrine_style_class_init,
+ NULL, /* class_finalize */
+ NULL, /* class_data */
+ sizeof (MurrineStyle),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) murrine_style_init,
+ NULL
+ };
+
+ murrine_type_style = g_type_module_register_type (module, GTK_TYPE_STYLE, "MurrineStyle", &object_info, 0);
+}
Added: trunk/src/murrine_style.h
==============================================================================
--- (empty file)
+++ trunk/src/murrine_style.h Mon Feb 11 23:01:49 2008
@@ -0,0 +1,89 @@
+/* Murrine theme engine
+ * Copyright (C) 2007 Andrea Cimitan
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * 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; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ */
+
+#include <gtk/gtkstyle.h>
+
+#ifndef MURRINE_STYLE_H
+#define MURRINE_STYLE_H
+
+#include "animation.h"
+#include "murrine_types.h"
+
+typedef struct _MurrineStyle MurrineStyle;
+typedef struct _MurrineStyleClass MurrineStyleClass;
+
+G_GNUC_INTERNAL extern GType murrine_type_style;
+
+#define MURRINE_TYPE_STYLE murrine_type_style
+#define MURRINE_STYLE(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), MURRINE_TYPE_STYLE, MurrineStyle))
+#define MURRINE_STYLE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), MURRINE_TYPE_STYLE, MurrineStyleClass))
+#define MURRINE_IS_STYLE(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), MURRINE_TYPE_STYLE))
+#define MURRINE_IS_STYLE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), MURRINE_TYPE_STYLE))
+#define MURRINE_STYLE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), MURRINE_TYPE_STYLE, MurrineStyleClass))
+
+struct _MurrineStyle
+{
+ GtkStyle parent_instance;
+
+ MurrineColors colors;
+
+ MurrineStyles style;
+
+ double contrast;
+ double gradient_stop_1;
+ double gradient_stop_2;
+ double gradient_stop_3;
+ double gradient_stop_4;
+ double highlight_ratio;
+ double innerborder_ratio;
+
+ guint8 glazestyle;
+ guint8 listviewheaderstyle;
+ guint8 listviewstyle;
+ guint8 menubaritemstyle;
+ guint8 menubarstyle;
+ guint8 menuitemstyle;
+ guint8 menustyle;
+ guint8 roundness;
+ guint8 scrollbarstyle;
+ guint8 sliderstyle;
+ guint8 stepperstyle;
+ guint8 toolbarstyle;
+
+ gboolean animation;
+ gboolean gradients;
+ gboolean colorize_scrollbar;
+ gboolean has_gradient_stop;
+ gboolean has_scrollbar_color;
+ gboolean rgba;
+
+ GdkColor scrollbar_color;
+};
+
+struct _MurrineStyleClass
+{
+ GtkStyleClass parent_class;
+
+ MurrineStyleFunctions style_functions[MRN_NUM_DRAW_STYLES];
+};
+
+G_GNUC_INTERNAL void murrine_style_register_type (GTypeModule *module);
+
+#endif /* MURRINE_STYLE_H */
Added: trunk/src/murrine_theme_main.c
==============================================================================
--- (empty file)
+++ trunk/src/murrine_theme_main.c Mon Feb 11 23:01:49 2008
@@ -0,0 +1,56 @@
+/* Murrine theme engine
+ * Copyright (C) 2007 Andrea Cimitan
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * 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; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ */
+
+#include <gmodule.h>
+#include <gtk/gtk.h>
+
+#include "murrine_style.h"
+#include "murrine_rc_style.h"
+
+G_MODULE_EXPORT void
+theme_init (GTypeModule *module)
+{
+ murrine_rc_style_register_type (module);
+ murrine_style_register_type (module);
+}
+
+G_MODULE_EXPORT void
+theme_exit (void)
+{
+}
+
+G_MODULE_EXPORT GtkRcStyle *
+theme_create_rc_style (void)
+{
+ return GTK_RC_STYLE (g_object_new (MURRINE_TYPE_RC_STYLE, NULL));
+}
+
+/* The following function will be called by GTK+ when the module
+ * is loaded and checks to see if we are compatible with the
+ * version of GTK+ that loads us.
+ */
+G_MODULE_EXPORT const gchar* g_module_check_init (GModule *module);
+const gchar*
+g_module_check_init (GModule *module)
+{
+ return gtk_check_version (GTK_MAJOR_VERSION,
+ GTK_MINOR_VERSION,
+ GTK_MICRO_VERSION - GTK_INTERFACE_AGE);
+}
Added: trunk/src/murrine_types.h
==============================================================================
--- (empty file)
+++ trunk/src/murrine_types.h Mon Feb 11 23:01:49 2008
@@ -0,0 +1,488 @@
+/* Murrine theme engine
+ * Copyright (C) 2007 Andrea Cimitan
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * 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; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ */
+
+#ifndef MURRINE_TYPES_H
+#define MURRINE_TYPES_H
+
+typedef unsigned char boolean;
+typedef unsigned char uint8;
+typedef struct _MurrineStyleFunctions MurrineStyleFunctions;
+
+typedef enum
+{
+ MRN_STYLE_MURRINE = 0,
+ MRN_STYLE_NODOKA = 1,
+ MRN_STYLE_MIST = 2,
+ MRN_STYLE_CANDIDO = 3,
+ MRN_STYLE_CLEARLOOKS = 4,
+ MRN_NUM_STYLES = 5
+} MurrineStyles;
+
+typedef enum
+{
+ MRN_DRAW_STYLE_MURRINE = 0,
+ MRN_DRAW_STYLE_RGBA = 1,
+ MRN_NUM_DRAW_STYLES = 2
+} MurrineDrawStyles;
+
+typedef enum
+{
+ MRN_STATE_NORMAL,
+ MRN_STATE_ACTIVE,
+ MRN_STATE_SELECTED,
+ MRN_STATE_INSENSITIVE
+} MurrineStateType;
+
+typedef enum
+{
+ MRN_CORNER_NONE = 0,
+ MRN_CORNER_TOPLEFT = 1,
+ MRN_CORNER_TOPRIGHT = 2,
+ MRN_CORNER_BOTTOMLEFT = 4,
+ MRN_CORNER_BOTTOMRIGHT = 8,
+ MRN_CORNER_ALL = 15
+} MurrineCorners;
+
+typedef enum
+{
+ MRN_JUNCTION_NONE = 0,
+ MRN_JUNCTION_BEGIN = 1,
+ MRN_JUNCTION_END = 2
+} MurrineJunction;
+
+typedef enum
+{
+ MRN_STEPPER_UNKNOWN = 0,
+ MRN_STEPPER_A = 1,
+ MRN_STEPPER_B = 2,
+ MRN_STEPPER_C = 4,
+ MRN_STEPPER_D = 8
+} MurrineStepper;
+
+typedef enum
+{
+ MRN_ORDER_FIRST,
+ MRN_ORDER_MIDDLE,
+ MRN_ORDER_LAST
+} MurrineOrder;
+
+typedef enum
+{
+ MRN_ORIENTATION_LEFT_TO_RIGHT,
+ MRN_ORIENTATION_RIGHT_TO_LEFT,
+ MRN_ORIENTATION_BOTTOM_TO_TOP,
+ MRN_ORIENTATION_TOP_TO_BOTTOM
+} MurrineOrientation;
+
+typedef enum
+{
+ MRN_GAP_LEFT,
+ MRN_GAP_RIGHT,
+ MRN_GAP_TOP,
+ MRN_GAP_BOTTOM
+} MurrineGapSide;
+
+typedef enum
+{
+ MRN_SHADOW_NONE,
+ MRN_SHADOW_IN,
+ MRN_SHADOW_OUT,
+ MRN_SHADOW_ETCHED_IN,
+ MRN_SHADOW_ETCHED_OUT,
+ MRN_SHADOW_FLAT
+} MurrineShadowType;
+
+typedef enum
+{
+ MRN_HANDLE_TOOLBAR,
+ MRN_HANDLE_SPLITTER
+} MurrineHandleType;
+
+typedef enum
+{
+ MRN_ARROW_NORMAL,
+ MRN_ARROW_COMBO
+} MurrineArrowType;
+
+typedef enum
+{
+ MRN_DIRECTION_UP,
+ MRN_DIRECTION_DOWN,
+ MRN_DIRECTION_LEFT,
+ MRN_DIRECTION_RIGHT
+} MurrineDirection;
+
+typedef enum
+{
+ MRN_PROGRESSBAR_CONTINUOUS,
+ MRN_PROGRESSBAR_DISCRETE
+} MurrineProgressBarStyle;
+
+typedef enum
+{
+ MRN_WINDOW_EDGE_NORTH_WEST,
+ MRN_WINDOW_EDGE_NORTH,
+ MRN_WINDOW_EDGE_NORTH_EAST,
+ MRN_WINDOW_EDGE_WEST,
+ MRN_WINDOW_EDGE_EAST,
+ MRN_WINDOW_EDGE_SOUTH_WEST,
+ MRN_WINDOW_EDGE_SOUTH,
+ MRN_WINDOW_EDGE_SOUTH_EAST
+} MurrineWindowEdge;
+
+typedef struct
+{
+ double r;
+ double g;
+ double b;
+} MurrineRGB;
+
+typedef struct
+{
+ double x;
+ double y;
+ double width;
+ double height;
+} MurrineRectangle;
+
+typedef struct
+{
+ MurrineRGB bg[5];
+ MurrineRGB base[5];
+ MurrineRGB text[5];
+ MurrineRGB fg[5];
+
+ MurrineRGB shade[9];
+ MurrineRGB spot[3];
+} MurrineColors;
+
+typedef struct
+{
+ double gradient_stop_1;
+ double gradient_stop_2;
+ double gradient_stop_3;
+ double gradient_stop_4;
+ double rgba_opacity;
+
+ boolean gradients;
+ boolean has_gradient_stop;
+ boolean use_rgba;
+} MurrineGradients;
+
+typedef struct
+{
+ boolean active;
+ boolean prelight;
+ boolean disabled;
+ boolean ltr;
+ boolean focus;
+ boolean is_default;
+ MurrineStateType state_type;
+ uint8 corners;
+ uint8 xthickness;
+ uint8 ythickness;
+ MurrineRGB parentbg;
+
+ /* Style */
+ int glazestyle;
+ int roundness;
+ double highlight_ratio;
+ double innerborder_ratio;
+ MurrineGradients mrn_gradient;
+
+ MurrineDrawStyles drawstyle;
+ MurrineStyleFunctions *style_functions;
+} WidgetParameters;
+
+typedef struct
+{
+ boolean inverted;
+ int fill_size;
+ boolean horizontal;
+} SliderParameters;
+
+typedef struct
+{
+ MurrineOrientation orientation;
+ MurrineProgressBarStyle style;
+} ProgressBarParameters;
+
+typedef struct
+{
+ int linepos;
+} OptionMenuParameters;
+
+typedef struct
+{
+ boolean inconsistent;
+ boolean draw_bullet;
+} OptionParameters;
+
+typedef struct
+{
+ MurrineShadowType shadow;
+ MurrineGapSide gap_side;
+ int gap_x;
+ int gap_width;
+ MurrineRGB *border;
+} FrameParameters;
+
+typedef struct
+{
+ MurrineGapSide gap_side;
+} TabParameters;
+
+typedef struct
+{
+ MurrineCorners corners;
+ MurrineShadowType shadow;
+} ShadowParameters;
+
+typedef struct
+{
+ boolean horizontal;
+ boolean use_rgba;
+} SeparatorParameters;
+
+typedef struct
+{
+ MurrineOrder order;
+ boolean resizable;
+ int style;
+} ListViewHeaderParameters;
+
+typedef struct
+{
+ MurrineRGB color;
+ MurrineJunction junction; /* On which sides the slider junctions */
+ MurrineStepper steppers; /* The visible steppers */
+ boolean horizontal;
+ boolean has_color;
+ int style;
+ int stepperstyle;
+} ScrollBarParameters;
+
+typedef struct
+{
+ MurrineHandleType type;
+ boolean horizontal;
+} HandleParameters;
+
+typedef struct
+{
+ MurrineStepper stepper; /* Which stepper to draw */
+} ScrollBarStepperParameters;
+
+typedef struct
+{
+ MurrineArrowType type;
+ MurrineDirection direction;
+} ArrowParameters;
+
+typedef struct
+{
+ MurrineWindowEdge edge;
+} ResizeGripParameters;
+
+typedef struct
+{
+ boolean topmost;
+ int style;
+} ToolbarParameters;
+
+struct _MurrineStyleFunctions
+{
+ void (*draw_button) (cairo_t *cr,
+ const MurrineColors *colors,
+ const WidgetParameters *widget,
+ int x, int y, int width, int height,
+ boolean vertical);
+
+ void (*draw_scale_trough) (cairo_t *cr,
+ const MurrineColors *colors,
+ const WidgetParameters *widget,
+ const SliderParameters *slider,
+ int x, int y, int width, int height);
+
+ void (*draw_slider_handle) (cairo_t *cr,
+ const MurrineColors *colors,
+ const WidgetParameters *widget,
+ int x, int y, int width, int height,
+ boolean horizontal);
+
+ void (*draw_progressbar_trough) (cairo_t *cr,
+ const MurrineColors *colors,
+ const WidgetParameters *widget,
+ int x, int y, int width, int height);
+
+ void (*draw_progressbar_fill) (cairo_t *cr,
+ const MurrineColors *colors,
+ const WidgetParameters *widget,
+ const ProgressBarParameters *progressbar,
+ int x, int y, int width, int height,
+ gint offset);
+
+ void (*draw_entry) (cairo_t *cr,
+ const MurrineColors *colors,
+ const WidgetParameters *widget,
+ int x, int y, int width, int height);
+
+ void (*draw_spinbutton) (cairo_t *cr,
+ const MurrineColors *colors,
+ const WidgetParameters *widget,
+ int x, int y, int width, int height);
+
+ void (*draw_spinbutton_down) (cairo_t *cr,
+ const MurrineColors *colors,
+ const WidgetParameters *widget,
+ int x, int y, int width, int height);
+
+ void (*draw_optionmenu) (cairo_t *cr,
+ const MurrineColors *colors,
+ const WidgetParameters *widget,
+ const OptionMenuParameters *optionmenu,
+ int x, int y, int width, int height);
+
+ void (*draw_menubar) (cairo_t *cr,
+ const MurrineColors *colors,
+ const WidgetParameters *widget,
+ int x, int y, int width, int height,
+ int menubarstyle);
+
+ void (*draw_tab) (cairo_t *cr,
+ const MurrineColors *colors,
+ const WidgetParameters *widget,
+ const TabParameters *tab,
+ int x, int y, int width, int height);
+
+ void (*draw_frame) (cairo_t *cr,
+ const MurrineColors *colors,
+ const WidgetParameters *widget,
+ const FrameParameters *frame,
+ int x, int y, int width, int height);
+
+ void (*draw_separator) (cairo_t *cr,
+ const MurrineColors *colors,
+ const WidgetParameters *widget,
+ const SeparatorParameters *separator,
+ int x, int y, int width, int height);
+
+ void (*draw_combo_separator) (cairo_t *cr,
+ const MurrineColors *colors,
+ const WidgetParameters *widget,
+ int x, int y, int width, int height);
+
+ void (*draw_list_view_header) (cairo_t *cr,
+ const MurrineColors *colors,
+ const WidgetParameters *widget,
+ const ListViewHeaderParameters *header,
+ int x, int y, int width, int height);
+
+ void (*draw_toolbar) (cairo_t *cr,
+ const MurrineColors *colors,
+ const WidgetParameters *widget,
+ const ToolbarParameters *toolbar,
+ int x, int y, int width, int height);
+
+ void (*draw_menuitem) (cairo_t *cr,
+ const MurrineColors *colors,
+ const WidgetParameters *widget,
+ int x, int y, int width, int height,
+ int menuitemstyle);
+
+ void (*draw_scrollbar_stepper) (cairo_t *cr,
+ const MurrineColors *colors,
+ const WidgetParameters *widget,
+ const ScrollBarParameters *scrollbar,
+ //const ScrollBarStepperParameters *stepper,
+ int x, int y, int width, int height);
+
+ void (*draw_scrollbar_slider) (cairo_t *cr,
+ const MurrineColors *colors,
+ const WidgetParameters *widget,
+ const ScrollBarParameters *scrollbar,
+ int x, int y, int width, int height);
+
+ void (*draw_scrollbar_trough) (cairo_t *cr,
+ const MurrineColors *colors,
+ const WidgetParameters *widget,
+ const ScrollBarParameters *scrollbar,
+ int x, int y, int width, int height);
+
+ void (*draw_selected_cell) (cairo_t *cr,
+ const MurrineColors *colors,
+ const WidgetParameters *widget,
+ int x, int y, int width, int height);
+
+ void (*draw_statusbar) (cairo_t *cr,
+ const MurrineColors *colors,
+ const WidgetParameters *widget,
+ int x, int y, int width, int height);
+
+ void (*draw_menu_frame) (cairo_t *cr,
+ const MurrineColors *colors,
+ const WidgetParameters *widget,
+ int x, int y, int width, int height,
+ int menustyle);
+
+ void (*draw_tooltip) (cairo_t *cr,
+ const MurrineColors *colors,
+ const WidgetParameters *widget,
+ int x, int y, int width, int height);
+
+ void (*draw_handle) (cairo_t *cr,
+ const MurrineColors *colors,
+ const WidgetParameters *widget,
+ const HandleParameters *handle,
+ int x, int y, int width, int height);
+
+ void (*draw_arrow) (cairo_t *cr,
+ const MurrineColors *colors,
+ const WidgetParameters *widget,
+ const ArrowParameters *arrow,
+ int x, int y, int width, int height);
+
+ void (*draw_checkbox) (cairo_t *cr,
+ const MurrineColors *colors,
+ const WidgetParameters *widget,
+ const OptionParameters *status,
+ int x, int y, int width, int height,
+ double trans);
+
+ void (*draw_radiobutton) (cairo_t *cr,
+ const MurrineColors *colors,
+ const WidgetParameters *widget,
+ const OptionParameters *status,
+ int x, int y, int width, int height,
+ double trans);
+
+ void (*draw_resize_grip) (cairo_t *cr,
+ const MurrineColors *colors,
+ const WidgetParameters *widget,
+ const ResizeGripParameters *grip,
+ int x, int y, int width, int height);
+};
+
+#define MURRINE_RECTANGLE_SET(rect, _x, _y, _w, _h) rect.x = _x; \
+ rect.y = _y; \
+ rect.width = _w; \
+ rect.height = _h;
+
+#endif /* MURRINE_TYPES_H */
Added: trunk/src/support.c
==============================================================================
--- (empty file)
+++ trunk/src/support.c Mon Feb 11 23:01:49 2008
@@ -0,0 +1,411 @@
+/* Murrine theme engine
+ * Copyright (C) 2007 Andrea Cimitan
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * 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; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ */
+
+#include "support.h"
+#include "cairo-support.h"
+
+GtkTextDirection
+murrine_get_direction (GtkWidget *widget)
+{
+ GtkTextDirection dir;
+
+ if (widget)
+ dir = gtk_widget_get_direction (widget);
+ else
+ dir = GTK_TEXT_DIR_LTR;
+
+ return dir;
+}
+
+void murrine_gtk_treeview_get_header_index (GtkTreeView *tv, GtkWidget *header,
+ gint *column_index, gint *columns,
+ gboolean *resizable)
+{
+ GList *list, *list_start;
+ *column_index = *columns = 0;
+ list_start = list = gtk_tree_view_get_columns (tv);
+
+ do
+ {
+ GtkTreeViewColumn *column = GTK_TREE_VIEW_COLUMN(list->data);
+ if ( column->button == header )
+ {
+ *column_index = *columns;
+ *resizable = column->resizable;
+ }
+ if ( column->visible )
+ (*columns)++;
+ } while ((list = g_list_next(list)));
+
+ g_list_free (list_start);
+}
+
+void murrine_gtk_clist_get_header_index (GtkCList *clist, GtkWidget *button,
+ gint *column_index, gint *columns)
+{
+ int i;
+ *columns = clist->columns;
+
+ for (i=0; i<*columns; i++)
+ {
+ if (clist->column[i].button == button)
+ {
+ *column_index = i;
+ break;
+ }
+ }
+}
+
+static GtkRequisition default_option_indicator_size = { 7, 13 };
+static GtkBorder default_option_indicator_spacing = { 7, 5, 2, 2 };
+
+void
+murrine_option_menu_get_props (GtkWidget *widget,
+ GtkRequisition *indicator_size,
+ GtkBorder *indicator_spacing)
+{
+ GtkRequisition *tmp_size = NULL;
+ GtkBorder *tmp_spacing = NULL;
+
+ if (widget)
+ gtk_widget_style_get (widget, "indicator_size", &tmp_size,
+ "indicator_spacing", &tmp_spacing, NULL);
+
+ if (tmp_size)
+ {
+ *indicator_size = *tmp_size;
+ gtk_requisition_free (tmp_size);
+ }
+ else
+ *indicator_size = default_option_indicator_size;
+
+ if (tmp_spacing)
+ {
+ *indicator_spacing = *tmp_spacing;
+ gtk_border_free (tmp_spacing);
+ }
+ else
+ *indicator_spacing = default_option_indicator_spacing;
+}
+
+GtkWidget *murrine_special_get_ancestor(GtkWidget * widget, GType widget_type)
+{
+ g_return_val_if_fail(GTK_IS_WIDGET(widget), NULL);
+
+ while (widget && widget->parent
+ && !g_type_is_a(GTK_WIDGET_TYPE(widget->parent),
+ widget_type))
+ widget = widget->parent;
+
+ if (!
+ (widget && widget->parent
+ && g_type_is_a(GTK_WIDGET_TYPE(widget->parent), widget_type)))
+ return NULL;
+
+ return widget;
+}
+
+GtkWidget *murrine_get_parent_window (GtkWidget *widget)
+{
+ GtkWidget *parent = widget->parent;
+
+ while (parent && GTK_WIDGET_NO_WINDOW (parent))
+ parent = parent->parent;
+
+ return parent;
+}
+
+GdkColor *murrine_get_parent_bgcolor (GtkWidget *widget)
+{
+ GtkWidget *parent = murrine_get_parent_window (widget);
+
+ if (parent && parent->style)
+ return &parent->style->bg[GTK_STATE_NORMAL];
+
+ return NULL;
+}
+
+gboolean
+murrine_object_is_a (const GObject * object, const gchar * type_name)
+{
+ gboolean result = FALSE;
+
+ if ((object))
+ {
+ GType tmp = g_type_from_name (type_name);
+
+ if (tmp)
+ result = g_type_check_instance_is_a ((GTypeInstance *) object, tmp);
+ }
+
+ return result;
+}
+
+gboolean
+murrine_widget_is_ltr (GtkWidget *widget)
+{
+ GtkTextDirection dir = GTK_TEXT_DIR_NONE;
+
+ if (MRN_IS_WIDGET (widget))
+ dir = gtk_widget_get_direction (widget);
+
+ if (dir == GTK_TEXT_DIR_NONE)
+ dir = gtk_widget_get_default_direction ();
+
+ if (dir == GTK_TEXT_DIR_RTL)
+ return FALSE;
+ else
+ return TRUE;
+}
+
+GtkWidget *
+murrine_find_combo_box_widget (GtkWidget * widget)
+{
+ GtkWidget *result = NULL;
+
+ if (widget && !GTK_IS_COMBO_BOX_ENTRY (widget))
+ {
+ if (GTK_IS_COMBO_BOX (widget))
+ result = widget;
+ else
+ result = murrine_find_combo_box_widget(widget->parent);
+ }
+
+ return result;
+}
+
+gboolean
+murrine_is_combo_box (GtkWidget * widget)
+{
+ return (murrine_find_combo_box_widget(widget) != NULL);
+}
+
+MurrineStepper
+murrine_scrollbar_get_stepper (GtkWidget *widget,
+ GdkRectangle *stepper)
+{
+ MurrineStepper value = MRN_STEPPER_UNKNOWN;
+ GdkRectangle tmp;
+ GdkRectangle check_rectangle;
+ GtkOrientation orientation;
+
+ g_return_val_if_fail (GTK_IS_RANGE (widget), MRN_STEPPER_UNKNOWN);
+
+ check_rectangle.x = widget->allocation.x;
+ check_rectangle.y = widget->allocation.y;
+ check_rectangle.width = stepper->width;
+ check_rectangle.height = stepper->height;
+
+ orientation = GTK_RANGE (widget)->orientation;
+
+ if (widget->allocation.x == -1 && widget->allocation.y == -1)
+ return MRN_STEPPER_UNKNOWN;
+
+ if (gdk_rectangle_intersect (stepper, &check_rectangle, &tmp))
+ value = MRN_STEPPER_A;
+
+ if (value == MRN_STEPPER_UNKNOWN) /* Haven't found a match */
+ {
+ if (orientation == GTK_ORIENTATION_HORIZONTAL)
+ check_rectangle.x = widget->allocation.x + stepper->width;
+ else
+ check_rectangle.y = widget->allocation.y + stepper->height;
+
+ if (gdk_rectangle_intersect (stepper, &check_rectangle, &tmp))
+ value = MRN_STEPPER_B;
+ }
+
+ if (value == MRN_STEPPER_UNKNOWN) /* Still haven't found a match */
+ {
+ if (orientation == GTK_ORIENTATION_HORIZONTAL)
+ check_rectangle.x = widget->allocation.x + widget->allocation.width - (stepper->width * 2);
+ else
+ check_rectangle.y = widget->allocation.y + widget->allocation.height - (stepper->height * 2);
+
+ if (gdk_rectangle_intersect (stepper, &check_rectangle, &tmp))
+ value = MRN_STEPPER_C;
+ }
+
+ if (value == MRN_STEPPER_UNKNOWN) /* STILL haven't found a match */
+ {
+ if (orientation == GTK_ORIENTATION_HORIZONTAL)
+ check_rectangle.x = widget->allocation.x + widget->allocation.width - stepper->width;
+ else
+ check_rectangle.y = widget->allocation.y + widget->allocation.height - stepper->height;
+
+ if (gdk_rectangle_intersect (stepper, &check_rectangle, &tmp))
+ value = MRN_STEPPER_D;
+ }
+
+ return value;
+}
+
+MurrineStepper
+murrine_scrollbar_visible_steppers (GtkWidget *widget)
+{
+ MurrineStepper steppers = 0;
+
+ g_return_val_if_fail (GTK_IS_RANGE (widget), MRN_STEPPER_UNKNOWN);
+
+ if (GTK_RANGE (widget)->has_stepper_a)
+ steppers |= MRN_STEPPER_A;
+
+ if (GTK_RANGE (widget)->has_stepper_b)
+ steppers |= MRN_STEPPER_B;
+
+ if (GTK_RANGE (widget)->has_stepper_c)
+ steppers |= MRN_STEPPER_C;
+
+ if (GTK_RANGE (widget)->has_stepper_d)
+ steppers |= MRN_STEPPER_D;
+}
+
+MurrineJunction
+murrine_scrollbar_get_junction (GtkWidget *widget)
+{
+ GtkAdjustment *adj;
+ MurrineJunction junction = MRN_JUNCTION_NONE;
+
+ g_return_val_if_fail (GTK_IS_RANGE (widget), MRN_JUNCTION_NONE);
+
+ adj = GTK_RANGE (widget)->adjustment;
+
+ if (adj->value <= adj->lower &&
+ (GTK_RANGE (widget)->has_stepper_a || GTK_RANGE (widget)->has_stepper_b))
+ {
+ junction |= MRN_JUNCTION_BEGIN;
+ }
+
+ if (adj->value >= adj->upper - adj->page_size &&
+ (GTK_RANGE (widget)->has_stepper_c || GTK_RANGE (widget)->has_stepper_d))
+ {
+ junction |= MRN_JUNCTION_END;
+ }
+
+ return junction;
+}
+
+gboolean murrine_is_panel_widget (GtkWidget *widget)
+{
+ return widget && (strcmp(G_OBJECT_TYPE_NAME (widget), "PanelApplet") == 0 ||
+ strcmp(G_OBJECT_TYPE_NAME (widget), "PanelWidget") == 0);
+}
+
+void
+murrine_set_toolbar_parameters (ToolbarParameters *toolbar,
+ GtkWidget *widget,
+ GdkWindow *window,
+ gint x, gint y)
+{
+ toolbar->topmost = FALSE;
+
+ if (x == 0 && y == 0)
+ {
+ if (widget && widget->allocation.x == 0 && widget->allocation.y == 0)
+ {
+ if (widget->window == window && MRN_IS_TOOLBAR (widget))
+ {
+ toolbar->topmost = TRUE;
+ }
+ }
+ }
+}
+
+void
+murrine_get_notebook_tab_position (GtkWidget *widget,
+ gboolean *start,
+ gboolean *end)
+{
+ /* default value */
+ *start = TRUE;
+ *end = FALSE;
+
+ if (MRN_IS_NOTEBOOK (widget))
+ {
+ gboolean found_tabs = FALSE;
+ gint i, n_pages;
+ GtkNotebook *notebook = GTK_NOTEBOOK (widget);
+
+ /* got a notebook, so walk over all the tabs and decide based
+ * on that ...
+ * It works like this:
+ * - If there is any visible tab that is expanded, set both.
+ * - Set start/end if there is any visible tab that is at
+ * the start/end.
+ * - If one has the child_visibility set to false, arrows
+ * are present; so none
+ * The heuristic falls over if there is a notebook that just
+ * happens to fill up all the available space. ie. All tabs
+ * are left aligned, but it does not require scrolling.
+ * (a more complex heuristic could calculate the tabs width
+ * and add them all up) */
+
+ n_pages = gtk_notebook_get_n_pages (notebook);
+ for (i = 0; i < n_pages; i++)
+ {
+ GtkWidget *tab_child;
+ GtkWidget *tab_label;
+ gboolean expand;
+ GtkPackType pack_type;
+
+ tab_child = gtk_notebook_get_nth_page (notebook, i);
+
+ /* Skip invisible tabs */
+ tab_label = gtk_notebook_get_tab_label (notebook, tab_child);
+ if (!tab_label || !GTK_WIDGET_VISIBLE (tab_label))
+ continue;
+ /* This is the same what the notebook does internally. */
+ if (tab_label && !gtk_widget_get_child_visible (tab_label))
+ {
+ /* One child is hidden because scroll arrows are present.
+ * So both corners are rounded. */
+ *start = FALSE;
+ *end = FALSE;
+ return;
+ }
+
+ gtk_notebook_query_tab_label_packing (notebook, tab_child,
+ &expand,
+ NULL, /* don't need fill */
+ &pack_type);
+
+ if (!found_tabs)
+ {
+ found_tabs = TRUE;
+ *start = FALSE;
+ *end = FALSE;
+ }
+
+ if (expand)
+ {
+ *start = TRUE;
+ *end = TRUE;
+ }
+ else if (pack_type == GTK_PACK_START)
+ {
+ *start = TRUE;
+ }
+ else
+ {
+ *end = TRUE;
+ }
+ }
+ }
+}
Added: trunk/src/support.h
==============================================================================
--- (empty file)
+++ trunk/src/support.h Mon Feb 11 23:01:49 2008
@@ -0,0 +1,154 @@
+/* Murrine theme engine
+ * Copyright (C) 2007 Andrea Cimitan
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * 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; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ */
+
+#ifndef SUPPORT_H
+#define SUPPORT_H
+
+#include <gtk/gtk.h>
+#include <math.h>
+#include <string.h>
+
+#include "murrine_types.h"
+#include "cairo-support.h"
+
+/* GTK 2.2 compatibility */
+#ifndef GTK_IS_COMBO_BOX_ENTRY
+ #define GTK_IS_COMBO_BOX_ENTRY(x) 0
+#endif
+#ifndef GTK_IS_COMBO_BOX
+ #define GTK_IS_COMBO_BOX(x) 0
+#endif
+
+#define RADIO_SIZE 13
+#define CHECK_SIZE 13
+
+/* Opacity settings */
+#define GRADIENT_OPACITY 0.90
+#define WINDOW_OPACITY 0.84
+#define ENTRY_OPACITY 0.88
+#define NOTEBOOK_OPACITY 0.74
+#define MENUBAR_OPACITY 0.90
+#define MENUBAR_GLOSSY_OPACITY 0.86
+#define MENUBAR_STRIPED_OPACITY 0.94
+#define TOOLBAR_OPACITY 0.87
+#define TOOLBAR_GLOSSY_OPACITY 0.86
+#define MENU_OPACITY 0.90
+
+/* From gtk-engines 20071109 */
+#define MRN_IS_WIDGET(object) ((object) && murrine_object_is_a ((GObject*)(object), "GtkWidget"))
+#define MRN_IS_CONTAINER(object) ((object) && murrine_object_is_a ((GObject*)(object), "GtkContainer"))
+#define MRN_IS_BIN(object) ((object) && murrine_object_is_a ((GObject*)(object), "GtkBin"))
+
+#define MRN_IS_ARROW(object) ((object) && murrine_object_is_a ((GObject*)(object), "GtkArrow"))
+
+#define MRN_IS_SEPARATOR(object) ((object) && murrine_object_is_a ((GObject*)(object), "GtkSeparator"))
+#define MRN_IS_VSEPARATOR(object) ((object) && murrine_object_is_a ((GObject*)(object), "GtkVSeparator"))
+#define MRN_IS_HSEPARATOR(object) ((object) && murrine_object_is_a ((GObject*)(object), "GtkHSeparator"))
+
+#define MRN_IS_HANDLE_BOX(object) ((object) && murrine_object_is_a ((GObject*)(object), "GtkHandleBox"))
+#define MRN_IS_HANDLE_BOX_ITEM(object) ((object) && MRN_IS_HANDLE_BOX(object->parent))
+#define MRN_IS_BONOBO_DOCK_ITEM(object) ((object) && murrine_object_is_a ((GObject*)(object), "BonoboDockItem"))
+#define MRN_IS_BONOBO_DOCK_ITEM_GRIP(object) ((object) && murrine_object_is_a ((GObject*)(object), "BonoboDockItemGrip"))
+#define MRN_IS_BONOBO_TOOLBAR(object) ((object) && murrine_object_is_a ((GObject*)(object), "BonoboUIToolbar"))
+#define MRN_IS_EGG_TOOLBAR(object) ((object) && murrine_object_is_a ((GObject*)(object), "Toolbar"))
+#define MRN_IS_TOOLBAR(object) ((object) && murrine_object_is_a ((GObject*)(object), "GtkToolbar"))
+#define MRN_IS_PANEL_WIDGET(object) ((object) && (murrine_object_is_a ((GObject*)(object), "PanelWidget") || murrine_object_is_a ((GObject*)(object), "PanelApplet")))
+
+#define MRN_IS_COMBO_BOX_ENTRY(object) ((object) && murrine_object_is_a ((GObject*)(object), "GtkComboBoxEntry"))
+#define MRN_IS_COMBO_BOX(object) ((object) && murrine_object_is_a ((GObject*)(object), "GtkComboBox"))
+#define MRN_IS_COMBO(object) ((object) && murrine_object_is_a ((GObject*)(object), "GtkCombo"))
+#define MRN_IS_OPTION_MENU(object) ((object) && murrine_object_is_a ((GObject*)(object), "GtkOptionMenu"))
+
+#define MRN_IS_TOGGLE_BUTTON(object) ((object) && murrine_object_is_a ((GObject*)(object), "GtkToggleButton"))
+#define MRN_IS_CHECK_BUTTON(object) ((object) && murrine_object_is_a ((GObject*)(object), "GtkCheckButton"))
+#define MRN_IS_SPIN_BUTTON(object) ((object) && murrine_object_is_a ((GObject*)(object), "GtkSpinButton"))
+
+#define MRN_IS_STATUSBAR(object) ((object) && murrine_object_is_a ((GObject*)(object), "GtkStatusbar"))
+#define MRN_IS_PROGRESS_BAR(object) ((object) && murrine_object_is_a ((GObject*)(object), "GtkProgressBar"))
+
+#define MRN_IS_MENU_SHELL(object) ((object) && murrine_object_is_a ((GObject*)(object), "GtkMenuShell"))
+#define MRN_IS_MENU(object) ((object) && murrine_object_is_a ((GObject*)(object), "GtkMenu"))
+#define MRN_IS_MENU_BAR(object) ((object) && murrine_object_is_a ((GObject*)(object), "GtkMenuBar"))
+#define MRN_IS_MENU_ITEM(object) ((object) && murrine_object_is_a ((GObject*)(object), "GtkMenuItem"))
+
+#define MRN_IS_CHECK_MENU_ITEM(object) ((object) && murrine_object_is_a ((GObject*)(object), "GtkCheckMenuItem"))
+
+#define MRN_IS_RANGE(object) ((object) && murrine_object_is_a ((GObject*)(object), "GtkRange"))
+
+#define MRN_IS_SCROLLBAR(object) ((object) && murrine_object_is_a ((GObject*)(object), "GtkScrollbar"))
+#define MRN_IS_VSCROLLBAR(object) ((object) && murrine_object_is_a ((GObject*)(object), "GtkVScrollbar"))
+#define MRN_IS_HSCROLLBAR(object) ((object) && murrine_object_is_a ((GObject*)(object), "GtkHScrollbar"))
+
+#define MRN_IS_SCALE(object) ((object) && murrine_object_is_a ((GObject*)(object), "GtkScale"))
+#define MRN_IS_VSCALE(object) ((object) && murrine_object_is_a ((GObject*)(object), "GtkVScale"))
+#define MRN_IS_HSCALE(object) ((object) && murrine_object_is_a ((GObject*)(object), "GtkHScale"))
+
+#define MRN_IS_PANED(object) ((object) && murrine_object_is_a ((GObject*)(object), "GtkPaned"))
+#define MRN_IS_VPANED(object) ((object) && murrine_object_is_a ((GObject*)(object), "GtkVPaned"))
+#define MRN_IS_HPANED(object) ((object) && murrine_object_is_a ((GObject*)(object), "GtkHPaned"))
+
+#define MRN_IS_BOX(object) ((object) && murrine_object_is_a ((GObject*)(object), "GtkBox"))
+#define MRN_IS_VBOX(object) ((object) && murrine_object_is_a ((GObject*)(object), "GtkVBox"))
+#define MRN_IS_HBOX(object) ((object) && murrine_object_is_a ((GObject*)(object), "GtkHBox"))
+
+#define MRN_IS_CLIST(object) ((object) && murrine_object_is_a ((GObject*)(object), "GtkCList"))
+#define MRN_IS_TREE_VIEW(object) ((object) && murrine_object_is_a ((GObject*)(object), "GtkTreeView"))
+#define MRN_IS_ENTRY(object) ((object) && murrine_object_is_a ((GObject*)(object), "GtkEntry"))
+#define MRN_IS_BUTTON(object) ((object) && murrine_object_is_a ((GObject*)(object), "GtkButton"))
+#define MRN_IS_FIXED(object) ((object) && murrine_object_is_a ((GObject*)(object), "GtkFixed"))
+
+#define TOGGLE_BUTTON(object) (MRN_IS_TOGGLE_BUTTON(object)?(GtkToggleButton *)object:NULL)
+
+#define MRN_IS_NOTEBOOK(object) ((object) && murrine_object_is_a ((GObject*)(object), "GtkNotebook"))
+#define MRN_IS_CELL_RENDERER_TOGGLE(object) ((object) && murrine_object_is_a ((GObject*)(object), "GtkCellRendererToggle"))
+
+#define MRN_WIDGET_HAS_DEFAULT(object) ((object) && MRN_IS_WIDGET(object) && GTK_WIDGET_HAS_DEFAULT(object))
+
+G_GNUC_INTERNAL GtkTextDirection murrine_get_direction (GtkWidget *widget);
+G_GNUC_INTERNAL GtkWidget *murrine_special_get_ancestor (GtkWidget *widget, GType widget_type);
+G_GNUC_INTERNAL GdkColor* murrine_get_parent_bgcolor (GtkWidget *widget);
+G_GNUC_INTERNAL GtkWidget* murrine_get_parent_window (GtkWidget *widget);
+G_GNUC_INTERNAL gboolean murrine_is_combo_box (GtkWidget *widget);
+G_GNUC_INTERNAL GtkWidget* murrine_find_combo_box_widget(GtkWidget *widget);
+G_GNUC_INTERNAL void murrine_gtk_treeview_get_header_index (GtkTreeView *tv,
+ GtkWidget *header,
+ gint *column_index,
+ gint *columns,
+ gboolean *resizable);
+G_GNUC_INTERNAL void murrine_gtk_clist_get_header_index (GtkCList *clist,
+ GtkWidget *button,
+ gint *column_index,
+ gint *columns);
+G_GNUC_INTERNAL void murrine_option_menu_get_props (GtkWidget *widget,
+ GtkRequisition *indicator_size,
+ GtkBorder *indicator_spacing);
+G_GNUC_INTERNAL MurrineStepper murrine_scrollbar_get_stepper (GtkWidget *widget, GdkRectangle *stepper);
+G_GNUC_INTERNAL MurrineStepper murrine_scrollbar_visible_steppers (GtkWidget *widget);
+G_GNUC_INTERNAL MurrineJunction murrine_scrollbar_get_junction (GtkWidget *widget);
+G_GNUC_INTERNAL gboolean murrine_is_panel_widget (GtkWidget *widget);
+G_GNUC_INTERNAL void murrine_set_toolbar_parameters (ToolbarParameters *toolbar,
+ GtkWidget *widget,
+ GdkWindow *window,
+ gint x, gint y);
+G_GNUC_INTERNAL void murrine_get_notebook_tab_position (GtkWidget *widget,
+ gboolean *start,
+ gboolean *end);
+
+#endif /* SUPPORT_H */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]