summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlessandro Ghedini <al3xbio@gmail.com>2011-10-19 10:56:04 +0200
committerAlessandro Ghedini <al3xbio@gmail.com>2011-10-19 10:56:04 +0200
commit6451a495637c6e3047a5a56573cffc6e3de9a515 (patch)
tree7c3eb29532e7c4b36a9da13c5890664fb816959b
Imported Upstream version 0.2+gitdfdad95upstream/0.2+gitdfdad95
-rw-r--r--CMakeLists.txt171
-rw-r--r--CMake_Uninstall.cmake.in26
-rw-r--r--README80
-rw-r--r--cmake/vala/FindVala.cmake65
-rw-r--r--cmake/vala/ParseArguments.cmake36
-rw-r--r--cmake/vala/ValaPrecompile.cmake175
-rw-r--r--cmake/vala/ValaVersion.cmake96
-rwxr-xr-xmake.sh5
-rw-r--r--resources/gnome-pie-indicator.svg770
-rwxr-xr-xresources/gnome-pie.desktop7
-rw-r--r--resources/gnome-pie.svg2896
-rwxr-xr-xresources/locale/compile-po.sh6
-rw-r--r--resources/locale/de/LC_MESSAGES/de.po221
-rw-r--r--resources/locale/de/LC_MESSAGES/gnomepie.mobin0 -> 3132 bytes
-rwxr-xr-xresources/locale/gen-po.sh13
-rwxr-xr-xresources/locale/gen-pot.sh22
-rw-r--r--resources/locale/gnomepie.pot357
-rw-r--r--resources/locale/pt-br/LC_MESSAGES/gnomepie.mobin0 -> 5633 bytes
-rw-r--r--resources/locale/pt-br/LC_MESSAGES/pt-br.po301
-rw-r--r--resources/themes/adwaita/arrow.svg121
-rw-r--r--resources/themes/adwaita/icon_active.svg152
-rw-r--r--resources/themes/adwaita/icon_inactive.svg152
-rw-r--r--resources/themes/adwaita/ring.svg258
-rw-r--r--resources/themes/adwaita/theme.xml27
-rw-r--r--resources/themes/bright/arrow.svg121
-rw-r--r--resources/themes/bright/gloss.svg156
-rw-r--r--resources/themes/bright/icon_active.svg142
-rw-r--r--resources/themes/bright/icon_inactive.svg142
-rw-r--r--resources/themes/bright/ring.svg214
-rw-r--r--resources/themes/bright/theme.xml29
-rw-r--r--resources/themes/funky/bg.svg151
-rw-r--r--resources/themes/funky/blue.svg148
-rw-r--r--resources/themes/funky/caption.svg130
-rw-r--r--resources/themes/funky/icon_bg.svg118
-rw-r--r--resources/themes/funky/icon_fg.svg118
-rw-r--r--resources/themes/funky/red.svg148
-rw-r--r--resources/themes/funky/star.svg126
-rw-r--r--resources/themes/funky/theme.xml38
-rw-r--r--resources/themes/gloss/arrow.svg225
-rw-r--r--resources/themes/gloss/glow_bg.svg140
-rw-r--r--resources/themes/gloss/icon_bg.svg118
-rw-r--r--resources/themes/gloss/icon_fg.svg214
-rw-r--r--resources/themes/gloss/icon_fg_active.svg214
-rw-r--r--resources/themes/gloss/icon_mask.svg118
-rw-r--r--resources/themes/gloss/theme.xml34
-rw-r--r--resources/themes/o-pie/arrow.svg115
-rw-r--r--resources/themes/o-pie/ring.svg179
-rw-r--r--resources/themes/o-pie/theme.xml24
-rw-r--r--resources/themes/slim/bg.svg198
-rw-r--r--resources/themes/slim/dot.svg125
-rw-r--r--resources/themes/slim/theme.xml36
-rw-r--r--resources/themes/unity/arrow.svg121
-rw-r--r--resources/themes/unity/gloss.svg156
-rw-r--r--resources/themes/unity/icon_active.svg142
-rw-r--r--resources/themes/unity/icon_inactive.svg142
-rw-r--r--resources/themes/unity/ring.svg214
-rw-r--r--resources/themes/unity/theme.xml29
-rw-r--r--src/CMakeLists.txt82
-rw-r--r--src/actionGroups/actionGroup.vala75
-rw-r--r--src/actionGroups/bookmarkGroup.vala148
-rw-r--r--src/actionGroups/clipboardGroup.vala116
-rw-r--r--src/actionGroups/devicesGroup.vala129
-rw-r--r--src/actionGroups/groupRegistry.vala89
-rw-r--r--src/actionGroups/menuGroup.vala254
-rw-r--r--src/actionGroups/sessionGroup.vala68
-rw-r--r--src/actions/action.vala77
-rw-r--r--src/actions/actionRegistry.vala200
-rw-r--r--src/actions/appAction.vala72
-rw-r--r--src/actions/keyAction.vala77
-rw-r--r--src/actions/pieAction.vala95
-rw-r--r--src/actions/sigAction.vala63
-rw-r--r--src/actions/uriAction.vala71
-rw-r--r--src/deamon.vala175
-rw-r--r--src/gui/about.vala43
-rw-r--r--src/gui/cellRendererIcon.vala132
-rw-r--r--src/gui/iconSelectWindow.vala349
-rw-r--r--src/gui/indicator.vala160
-rw-r--r--src/gui/pieList.vala1018
-rw-r--r--src/gui/preferences.vala338
-rw-r--r--src/gui/themeList.vala95
-rw-r--r--src/gui/tipViewer.vala172
-rw-r--r--src/pies/defaultConfig.vala70
-rw-r--r--src/pies/load.vala230
-rw-r--r--src/pies/pie.vala96
-rw-r--r--src/pies/pieManager.vala231
-rw-r--r--src/pies/save.vala81
-rw-r--r--src/renderers/centerRenderer.vala146
-rw-r--r--src/renderers/pieRenderer.vala208
-rw-r--r--src/renderers/pieWindow.vala263
-rw-r--r--src/renderers/sliceRenderer.vala182
-rw-r--r--src/themes/centerLayer.vala111
-rw-r--r--src/themes/sliceLayer.vala65
-rw-r--r--src/themes/theme.vala489
-rw-r--r--src/utilities/animatedValue.vala190
-rw-r--r--src/utilities/bindingManager.vala196
-rw-r--r--src/utilities/color.vala305
-rw-r--r--src/utilities/config.vala202
-rw-r--r--src/utilities/icon.vala102
-rw-r--r--src/utilities/image.vala163
-rw-r--r--src/utilities/key.vala139
-rw-r--r--src/utilities/logger.vala194
-rw-r--r--src/utilities/paths.vala211
-rw-r--r--src/utilities/renderedText.vala110
-rw-r--r--src/utilities/themedIcon.vala161
-rw-r--r--vapi/appindicator-0.1.vapi94
-rw-r--r--vapi/gee-1.0.vapi416
-rw-r--r--vapi/libgnome-menu-3.0.vapi93
-rw-r--r--vapi/x11.vapi996
-rw-r--r--vapi/xtst.vapi60
109 files changed, 20184 insertions, 0 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
new file mode 100644
index 0000000..fadea59
--- /dev/null
+++ b/CMakeLists.txt
@@ -0,0 +1,171 @@
+################################################################
+# Project Gnome-Pie
+################################################################
+
+project("gnomepie" C)
+
+cmake_minimum_required(VERSION 2.6)
+
+# Location where cmake first looks for modules.
+list(APPEND CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake/vala)
+
+################################################################
+# Find Vala
+################################################################
+
+include(ValaPrecompile)
+include(ValaVersion)
+
+find_package(Vala)
+ensure_vala_version("0.11.0" MINIMUM)
+
+################################################################
+# Configure and find libraries
+################################################################
+
+find_package(PkgConfig)
+pkg_check_modules(GIO REQUIRED gio-unix-2.0)
+pkg_check_modules(GTK REQUIRED gtk+-2.0)
+pkg_check_modules(CAIRO REQUIRED cairo)
+pkg_check_modules(GEE REQUIRED gee-1.0)
+pkg_check_modules(X11 REQUIRED x11)
+pkg_check_modules(INDICATOR appindicator-0.1)
+pkg_check_modules(XML REQUIRED libxml-2.0)
+pkg_check_modules(XTST REQUIRED xtst)
+pkg_check_modules(UNIQUE REQUIRED unique-1.0)
+pkg_check_modules(GMENU3 libgnome-menu-3.0)
+
+find_library(M_LIB m)
+
+set(CFLAGS
+ ${GIO_CFLAGS}
+ ${GTK_CFLAGS} ${GTK_CFLAGS_OTHER}
+ ${CAIRO_CFLAGS} ${CAIRO_CFLAGS_OTHER}
+ ${GEE_CFLAGS} ${CAIRO_CFLAGS_OTHER}
+ ${X11_CFLAGS} ${X11_CFLAGS_OTHER}
+ -DGMENU_I_KNOW_THIS_IS_UNSTABLE
+ -DGETTEXT_PACKAGE="gnomepie"
+ -s -O3
+)
+
+if (${GMENU3_FOUND})
+ LIST(APPEND CFLAGS -DHAVE_GMENU_3)
+else (${GMENU3_FOUND})
+ pkg_check_modules(GMENU REQUIRED libgnome-menu)
+endif (${GMENU3_FOUND})
+
+if (${INDICATOR_FOUND})
+ LIST(APPEND CFLAGS -DHAVE_APPINDICATOR)
+endif (${INDICATOR_FOUND})
+
+add_definitions(${CFLAGS})
+
+set(LIBS
+ ${GIO_LIBRARIES}
+ ${GTK_LIBRARIES}
+ ${CAIRO_LIBRARIES}
+ ${GEE_LIBRARIES}
+ ${INDICATOR_LIBRARIES}
+ ${XML_LIBRARIES}
+ ${XTST_LIBRARIES}
+ ${GMENU_LIBRARIES}
+ ${GMENU3_LIBRARIES}
+ ${UNIQUE_LIBRARIES}
+ ${X11_LIBRARIES}
+ ${M_LIB}
+)
+link_libraries(${LIBS})
+
+set(LIB_PATHS
+ ${GIO_LIBRARY_DIRS}
+ ${GTK_LIBRARY_DIRS}
+ ${CAIRO_LIBRARY_DIRS}
+ ${GEE_LIBRARY_DIRS}
+ ${INDICATOR_LIBRARY_DIRS}
+ ${XML_LIBRARY_DIRS}
+ ${XTST_LIBRARY_DIRS}
+ ${GMENU_LIBRARY_DIRS}
+ ${GMENU3_LIBRARY_DIRS}
+ ${UNIQUE_LIBRARY_DIRS}
+ ${X11_LIBRARY_DIRS}
+)
+link_directories(${LIB_PATHS})
+
+set(INCLUDE_PATHS
+ ${GIO_INCLUDE_DIRS}
+ ${GTK_INCLUDE_DIRS}
+ ${CAIRO_INCLUDE_DIRS}
+ ${GEE_INCLUDE_DIRS}
+ ${INDICATOR_INCLUDE_DIRS}
+ ${XML_INCLUDE_DIRS}
+ ${XTST_INCLUDE_DIRS}
+ ${GMENU_INCLUDE_DIRS}
+ ${GMENU3_INCLUDE_DIRS}
+ ${UNIQUE_INCLUDE_DIRS}
+ ${X11_INCLUDE_DIRS}
+)
+include_directories(${INCLUDE_PATHS})
+
+################################################################
+# Add executable
+################################################################
+
+set(EXECUTABLE_OUTPUT_PATH ${gnomepie_SOURCE_DIR})
+
+set(VALA_PKGS
+ gtk+-2.0
+ gdk-x11-2.0
+ cairo
+ gee-1.0
+ x11
+ gio-unix-2.0
+ posix
+ libxml-2.0
+ xtst
+ unique-1.0
+)
+
+if (${INDICATOR_FOUND})
+ LIST(APPEND VALA_PKGS appindicator-0.1)
+endif (${INDICATOR_FOUND})
+
+if (${GMENU3_FOUND})
+ LIST(APPEND VALA_PKGS libgnome-menu-3.0)
+else (${GMENU3_FOUND})
+ LIST(APPEND VALA_PKGS libgnome-menu)
+endif (${GMENU3_FOUND})
+
+add_subdirectory(src)
+
+################################################################
+# Add uninstall option
+################################################################
+
+configure_file(
+ "${CMAKE_CURRENT_SOURCE_DIR}/CMake_Uninstall.cmake.in"
+ "${CMAKE_CURRENT_BINARY_DIR}/CMake_Uninstall.cmake"
+ IMMEDIATE @ONLY)
+
+add_custom_target(uninstall
+ COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_BINARY_DIR}/CMake_Uninstall.cmake)
+
+################################################################
+# Summary
+################################################################
+
+message( "" )
+message( "Summary:" )
+message( " EXECUTABLE_OUTPUT_PATH = ${EXECUTABLE_OUTPUT_PATH}" )
+message( " VALA_EXECUTABLE = ${VALA_EXECUTABLE}" )
+message( "Libs:" )
+message( " GTK_LIBRARIES = ${GTK_LIBRARIES}" )
+message( " CAIRO_LIBRARIES = ${CAIRO_LIBRARIES}" )
+message( " GEE_LIBRARIES = ${GEE_LIBRARIES}" )
+message( " INDICATOR_LIBRARIES = ${INDICATOR_LIBRARIES}" )
+message( " XML_LIBRARIES = ${XML_LIBRARIES}" )
+message( " XTST_LIBRARIES = ${XTST_LIBRARIES}" )
+message( " GMENU_LIBRARIES = ${GMENU_LIBRARIES}" )
+message( " GMENU3_LIBRARIES = ${GMENU3_LIBRARIES}" )
+message( " UNIQUE_LIBRARIES = ${UNIQUE_LIBRARIES}" )
+message( " X11_LIBRARIES = ${X11_LIBRARIES}" )
+message( "" )
diff --git a/CMake_Uninstall.cmake.in b/CMake_Uninstall.cmake.in
new file mode 100644
index 0000000..6ccb93f
--- /dev/null
+++ b/CMake_Uninstall.cmake.in
@@ -0,0 +1,26 @@
+################################################################
+# Project Gnome-Pie --- uninstall script
+################################################################
+
+if (NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt")
+ message(FATAL_ERROR "Cannot find install manifest: \"@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt\"")
+endif(NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt")
+
+file(READ "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt" files)
+string(REGEX REPLACE "\n" ";" files "${files}")
+
+foreach (file ${files})
+ message(STATUS "Uninstalling \"$ENV{DESTDIR}${file}\"")
+ if (EXISTS "$ENV{DESTDIR}${file}")
+ execute_process(
+ COMMAND @CMAKE_COMMAND@ -E remove "$ENV{DESTDIR}${file}"
+ OUTPUT_VARIABLE rm_out
+ RESULT_VARIABLE rm_retval
+ )
+ if(NOT ${rm_retval} EQUAL 0)
+ message(FATAL_ERROR "Problem when removing \"$ENV{DESTDIR}${file}\"")
+ endif (NOT ${rm_retval} EQUAL 0)
+ else (EXISTS "$ENV{DESTDIR}${file}")
+ message(STATUS "File \"$ENV{DESTDIR}${file}\" does not exist.")
+ endif (EXISTS "$ENV{DESTDIR}${file}")
+endforeach(file)
diff --git a/README b/README
new file mode 100644
index 0000000..81ac7a4
--- /dev/null
+++ b/README
@@ -0,0 +1,80 @@
+####################################################################
+# Gnome-Pie #
+####################################################################
+
+This is an experimantal attempt to create a visual application
+launcher for the Gnome Desktop.
+
+Homepage: http://gnome-pie.simonschneegans.de
+
+It is inspired by the an addon written for the game World of Warcraft.
+(http://go-hero.net/opie/)
+
+####################################################################
+# About this Branch #
+####################################################################
+
+This is the master Branch of Gnome-Pie. A recent "stable" version
+will be in here.
+
+####################################################################
+# PPA #
+####################################################################
+
+There is a PPA with a recent version of Gnome-Pie. If you simply
+want to test it, it's very easy to install:
+
+sudo add-apt-repository ppa:simonschneegans/testing
+sudo apt-get update
+sudo apt-get install gnome-pie
+
+####################################################################
+# Compiling #
+####################################################################
+
+First of all, install all dependancies:
+
+sudo apt-get install libgtk2.0-dev libcairo2-dev libappindicator-dev
+ libgee-dev libxml2-dev libxtst-dev
+ libgnome-menu-dev valac cmake libunique-dev
+
+Then build and launch Gnome-Pie by typing:
+
+./make.sh
+
+####################################################################
+# Usage #
+####################################################################
+
+Now you may launch it by Pressing <ctrl><Alt>A to open up a default
+Pie with your default applications. There are some other Pies
+defined --- just open up the configuration dialog by activating the
+appropriate entry in the appindicator menu or by launching gnome-pie
+for a second time. There you may configure the Pies to suit your
+needs.
+
+You can open Pies not only by presing their key stroke.
+Alternatively you may open any Pie by invoking gnome-pie --open 123
+where 123 is the ID of the desired Pie (which is displayed in the
+configuration dialog).
+
+####################################################################
+# License #
+####################################################################
+
+Copyright (C) 2011 Simon Schneegans <code@simonschneegans.de>
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 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, see <http://www.gnu.org/licenses/>.
+
+
diff --git a/cmake/vala/FindVala.cmake b/cmake/vala/FindVala.cmake
new file mode 100644
index 0000000..aa3a6e7
--- /dev/null
+++ b/cmake/vala/FindVala.cmake
@@ -0,0 +1,65 @@
+##
+# Copyright 2009-2010 Jakob Westhoff. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# 1. Redistributions of source code must retain the above copyright notice,
+# this list of conditions and the following disclaimer.
+#
+# 2. Redistributions in binary form must reproduce the above copyright notice,
+# this list of conditions and the following disclaimer in the documentation
+# and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY JAKOB WESTHOFF ``AS IS'' AND ANY EXPRESS OR
+# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+# EVENT SHALL JAKOB WESTHOFF OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+# OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+# The views and conclusions contained in the software and documentation are those
+# of the authors and should not be interpreted as representing official policies,
+# either expressed or implied, of Jakob Westhoff
+##
+
+##
+# Find module for the Vala compiler (valac)
+#
+# This module determines wheter a Vala compiler is installed on the current
+# system and where its executable is.
+#
+# Call the module using "find_package(Vala) from within your CMakeLists.txt.
+#
+# The following variables will be set after an invocation:
+#
+# VALA_FOUND Whether the vala compiler has been found or not
+# VALA_EXECUTABLE Full path to the valac executable if it has been found
+# VALA_VERSION Version number of the available valac
+##
+
+
+# Search for the valac executable in the usual system paths.
+find_program(VALA_EXECUTABLE
+ NAMES valac)
+
+# Handle the QUIETLY and REQUIRED arguments, which may be given to the find call.
+# Furthermore set VALA_FOUND to TRUE if Vala has been found (aka.
+# VALA_EXECUTABLE is set)
+
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(Vala DEFAULT_MSG VALA_EXECUTABLE)
+
+mark_as_advanced(VALA_EXECUTABLE)
+
+# Determine the valac version
+if(VALA_FOUND)
+ execute_process(COMMAND ${VALA_EXECUTABLE} "--version"
+ OUTPUT_VARIABLE "VALA_VERSION")
+ string(REPLACE "Vala" "" "VALA_VERSION" ${VALA_VERSION})
+ string(STRIP ${VALA_VERSION} "VALA_VERSION")
+endif(VALA_FOUND)
diff --git a/cmake/vala/ParseArguments.cmake b/cmake/vala/ParseArguments.cmake
new file mode 100644
index 0000000..717c0f5
--- /dev/null
+++ b/cmake/vala/ParseArguments.cmake
@@ -0,0 +1,36 @@
+##
+# This is a helper Macro to parse optional arguments in Macros/Functions
+# It has been taken from the public CMake wiki.
+# See http://www.cmake.org/Wiki/CMakeMacroParseArguments for documentation and
+# licensing.
+##
+macro(parse_arguments prefix arg_names option_names)
+ set(DEFAULT_ARGS)
+ foreach(arg_name ${arg_names})
+ set(${prefix}_${arg_name})
+ endforeach(arg_name)
+ foreach(option ${option_names})
+ set(${prefix}_${option} FALSE)
+ endforeach(option)
+
+ set(current_arg_name DEFAULT_ARGS)
+ set(current_arg_list)
+ foreach(arg ${ARGN})
+ set(larg_names ${arg_names})
+ list(FIND larg_names "${arg}" is_arg_name)
+ if(is_arg_name GREATER -1)
+ set(${prefix}_${current_arg_name} ${current_arg_list})
+ set(current_arg_name ${arg})
+ set(current_arg_list)
+ else(is_arg_name GREATER -1)
+ set(loption_names ${option_names})
+ list(FIND loption_names "${arg}" is_option)
+ if(is_option GREATER -1)
+ set(${prefix}_${arg} TRUE)
+ else(is_option GREATER -1)
+ set(current_arg_list ${current_arg_list} ${arg})
+ endif(is_option GREATER -1)
+ endif(is_arg_name GREATER -1)
+ endforeach(arg)
+ set(${prefix}_${current_arg_name} ${current_arg_list})
+endmacro(parse_arguments)
diff --git a/cmake/vala/ValaPrecompile.cmake b/cmake/vala/ValaPrecompile.cmake
new file mode 100644
index 0000000..19c4739
--- /dev/null
+++ b/cmake/vala/ValaPrecompile.cmake
@@ -0,0 +1,175 @@
+##
+# Copyright 2009-2010 Jakob Westhoff. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# 1. Redistributions of source code must retain the above copyright notice,
+# this list of conditions and the following disclaimer.
+#
+# 2. Redistributions in binary form must reproduce the above copyright notice,
+# this list of conditions and the following disclaimer in the documentation
+# and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY JAKOB WESTHOFF ``AS IS'' AND ANY EXPRESS OR
+# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+# EVENT SHALL JAKOB WESTHOFF OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+# OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+# The views and conclusions contained in the software and documentation are those
+# of the authors and should not be interpreted as representing official policies,
+# either expressed or implied, of Jakob Westhoff
+##
+
+include(ParseArguments)
+find_package(Vala REQUIRED)
+
+##
+# Compile vala files to their c equivalents for further processing.
+#
+# The "vala_precompile" macro takes care of calling the valac executable on the
+# given source to produce c files which can then be processed further using
+# default cmake functions.
+#
+# The first parameter provided is a variable, which will be filled with a list
+# of c files outputted by the vala compiler. This list can than be used in
+# conjuction with functions like "add_executable" or others to create the
+# neccessary compile rules with CMake.
+#
+# The initial variable is followed by a list of .vala files to be compiled.
+# Please take care to add every vala file belonging to the currently compiled
+# project or library as Vala will otherwise not be able to resolve all
+# dependencies.
+#
+# The following sections may be specified afterwards to provide certain options
+# to the vala compiler:
+#
+# PACKAGES
+# A list of vala packages/libraries to be used during the compile cycle. The
+# package names are exactly the same, as they would be passed to the valac
+# "--pkg=" option.
+#
+# OPTIONS
+# A list of optional options to be passed to the valac executable. This can be
+# used to pass "--thread" for example to enable multi-threading support.
+#
+# CUSTOM_VAPIS
+# A list of custom vapi files to be included for compilation. This can be
+# useful to include freshly created vala libraries without having to install
+# them in the system.
+#
+# GENERATE_VAPI
+# Pass all the needed flags to the compiler to create an internal vapi for
+# the compiled library. The provided name will be used for this and a
+# <provided_name>.vapi file will be created.
+#
+# GENERATE_HEADER
+# Let the compiler generate a header file for the compiled code. There will
+# be a header file as well as an internal header file being generated called
+# <provided_name>.h and <provided_name>_internal.h
+#
+# The following call is a simple example to the vala_precompile macro showing
+# an example to every of the optional sections:
+#
+# vala_precompile(VALA_C
+# source1.vala
+# source2.vala
+# source3.vala
+# PACKAGES
+# gtk+-2.0
+# gio-1.0
+# posix
+# DIRECTORY
+# gen
+# OPTIONS
+# --thread
+# CUSTOM_VAPIS
+# some_vapi.vapi
+# GENERATE_VAPI
+# myvapi
+# GENERATE_HEADER
+# myheader
+# )
+#
+# Most important is the variable VALA_C which will contain all the generated c
+# file names after the call.
+##
+
+macro(vala_precompile output)
+ parse_arguments(ARGS "PACKAGES;OPTIONS;DIRECTORY;GENERATE_HEADER;GENERATE_VAPI;CUSTOM_VAPIS" "" ${ARGN})
+ if(ARGS_DIRECTORY)
+ set(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/${ARGS_DIRECTORY})
+ else(ARGS_DIRECTORY)
+ set(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
+ endif(ARGS_DIRECTORY)
+ include_directories(${DIRECTORY})
+ set(vala_pkg_opts "")
+ foreach(pkg ${ARGS_PACKAGES})
+ list(APPEND vala_pkg_opts "--pkg=${pkg}")
+ endforeach(pkg ${ARGS_PACKAGES})
+ set(in_files "")
+ set(out_files "")
+ set(${output} "")
+ foreach(src ${ARGS_DEFAULT_ARGS})
+ list(APPEND in_files "${CMAKE_CURRENT_SOURCE_DIR}/${src}")
+ string(REPLACE ".vala" ".c" src ${src})
+ string(REPLACE ".gs" ".c" src ${src})
+ set(out_file "${DIRECTORY}/${src}")
+ list(APPEND out_files "${DIRECTORY}/${src}")
+ list(APPEND ${output} ${out_file})
+ endforeach(src ${ARGS_DEFAULT_ARGS})
+
+ set(custom_vapi_arguments "")
+ if(ARGS_CUSTOM_VAPIS)
+ foreach(vapi ${ARGS_CUSTOM_VAPIS})
+ if(${vapi} MATCHES ${CMAKE_SOURCE_DIR} OR ${vapi} MATCHES ${CMAKE_BINARY_DIR})
+ list(APPEND custom_vapi_arguments ${vapi})
+ else (${vapi} MATCHES ${CMAKE_SOURCE_DIR} OR ${vapi} MATCHES ${CMAKE_BINARY_DIR})
+ list(APPEND custom_vapi_arguments ${CMAKE_CURRENT_SOURCE_DIR}/${vapi})
+ endif(${vapi} MATCHES ${CMAKE_SOURCE_DIR} OR ${vapi} MATCHES ${CMAKE_BINARY_DIR})
+ endforeach(vapi ${ARGS_CUSTOM_VAPIS})
+ endif(ARGS_CUSTOM_VAPIS)
+
+ set(vapi_arguments "")
+ if(ARGS_GENERATE_VAPI)
+ list(APPEND out_files "${DIRECTORY}/${ARGS_GENERATE_VAPI}.vapi")
+ set(vapi_arguments "--internal-vapi=${ARGS_GENERATE_VAPI}.vapi")
+
+ # Header and internal header is needed to generate internal vapi
+ if (NOT ARGS_GENERATE_HEADER)
+ set(ARGS_GENERATE_HEADER ${ARGS_GENERATE_VAPI})
+ endif(NOT ARGS_GENERATE_HEADER)
+ endif(ARGS_GENERATE_VAPI)
+
+ set(header_arguments "")
+ if(ARGS_GENERATE_HEADER)
+ list(APPEND out_files "${DIRECTORY}/${ARGS_GENERATE_HEADER}.h")
+ list(APPEND out_files "${DIRECTORY}/${ARGS_GENERATE_HEADER}_internal.h")
+ list(APPEND header_arguments "--header=${DIRECTORY}/${ARGS_GENERATE_HEADER}.h")
+ list(APPEND header_arguments "--internal-header=${DIRECTORY}/${ARGS_GENERATE_HEADER}_internal.h")
+ endif(ARGS_GENERATE_HEADER)
+
+ add_custom_command(OUTPUT ${out_files}
+ COMMAND
+ ${VALA_EXECUTABLE}
+ ARGS
+ "-C"
+ ${header_arguments}
+ ${vapi_arguments}
+ "-b" ${CMAKE_CURRENT_SOURCE_DIR}
+ "-d" ${DIRECTORY}
+ ${vala_pkg_opts}
+ ${ARGS_OPTIONS}
+ ${in_files}
+ ${custom_vapi_arguments}
+ DEPENDS
+ ${in_files}
+ ${ARGS_CUSTOM_VAPIS}
+ )
+endmacro(vala_precompile)
diff --git a/cmake/vala/ValaVersion.cmake b/cmake/vala/ValaVersion.cmake
new file mode 100644
index 0000000..3fff193
--- /dev/null
+++ b/cmake/vala/ValaVersion.cmake
@@ -0,0 +1,96 @@
+##
+# Copyright 2009-2010 Jakob Westhoff. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# 1. Redistributions of source code must retain the above copyright notice,
+# this list of conditions and the following disclaimer.
+#
+# 2. Redistributions in binary form must reproduce the above copyright notice,
+# this list of conditions and the following disclaimer in the documentation
+# and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY JAKOB WESTHOFF ``AS IS'' AND ANY EXPRESS OR
+# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+# EVENT SHALL JAKOB WESTHOFF OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+# OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+# The views and conclusions contained in the software and documentation are those
+# of the authors and should not be interpreted as representing official policies,
+# either expressed or implied, of Jakob Westhoff
+##
+
+include(ParseArguments)
+find_package(Vala REQUIRED)
+
+##
+# Ensure a certain valac version is available
+#
+# The initial argument is the version to check for
+#
+# It may be followed by a optional parameter to specifiy a version range. The
+# following options are valid:
+#
+# EXACT
+# Vala needs to be available in the exact version given
+#
+# MINIMUM
+# The provided version is the minimum version. Therefore Vala needs to be
+# available in the given version or any higher version
+#
+# MAXIMUM
+# The provided version is the maximum. Therefore Vala needs to be available
+# in the given version or any version older than this
+#
+# If no option is specified the version will be treated as a minimal version.
+##
+macro(ensure_vala_version version)
+ parse_arguments(ARGS "" "MINIMUM;MAXIMUM;EXACT" ${ARGN})
+ set(compare_message "")
+ set(error_message "")
+ if(ARGS_MINIMUM)
+ set(compare_message "a minimum ")
+ set(error_message "or greater ")
+ elseif(ARGS_MAXIMUM)
+ set(compare_message "a maximum ")
+ set(error_message "or less ")
+ endif(ARGS_MINIMUM)
+
+ message(STATUS
+ "checking for ${compare_message}Vala version of ${version}"
+ )
+
+ unset(version_accepted)
+
+ # MINIMUM is the default if no option is specified
+ if(ARGS_EXACT)
+ if(${VALA_VERSION} VERSION_EQUAL ${version} )
+ set(version_accepted TRUE)
+ endif(${VALA_VERSION} VERSION_EQUAL ${version})
+ elseif(ARGS_MAXIMUM)
+ if(${VALA_VERSION} VERSION_LESS ${version} OR ${VALA_VERSION} VERSION_EQUAL ${version})
+ set(version_accepted TRUE)
+ endif(${VALA_VERSION} VERSION_LESS ${version} OR ${VALA_VERSION} VERSION_EQUAL ${version})
+ else(ARGS_MAXIMUM)
+ if(${VALA_VERSION} VERSION_GREATER ${version} OR ${VALA_VERSION} VERSION_EQUAL ${version})
+ set(version_accepted TRUE)
+ endif(${VALA_VERSION} VERSION_GREATER ${version} OR ${VALA_VERSION} VERSION_EQUAL ${version})
+ endif(ARGS_EXACT)
+
+ if (NOT version_accepted)
+ message(FATAL_ERROR
+ "Vala version ${version} ${error_message}is required."
+ )
+ endif(NOT version_accepted)
+
+ message(STATUS
+ " found Vala, version ${VALA_VERSION}"
+ )
+endmacro(ensure_vala_version)
diff --git a/make.sh b/make.sh
new file mode 100755
index 0000000..0bd7ca8
--- /dev/null
+++ b/make.sh
@@ -0,0 +1,5 @@
+#!/bin/sh
+
+mkdir build
+
+cd build; cmake ..; make && ( cd .. )
diff --git a/resources/gnome-pie-indicator.svg b/resources/gnome-pie-indicator.svg
new file mode 100644
index 0000000..bfeb5bd
--- /dev/null
+++ b/resources/gnome-pie-indicator.svg
@@ -0,0 +1,770 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ version="1.0"
+ width="32"
+ height="32"
+ id="svg2408"
+ inkscape:version="0.48.1 r9760"
+ sodipodi:docname="gnome-pie-indicator.svg">
+ <sodipodi:namedview
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1"
+ objecttolerance="10"
+ gridtolerance="10"
+ guidetolerance="10"
+ inkscape:pageopacity="0"
+ inkscape:pageshadow="2"
+ inkscape:window-width="1117"
+ inkscape:window-height="801"
+ id="namedview93"
+ showgrid="false"
+ inkscape:zoom="13.666667"
+ inkscape:cx="14.888492"
+ inkscape:cy="21.146173"
+ inkscape:window-x="575"
+ inkscape:window-y="84"
+ inkscape:window-maximized="0"
+ inkscape:current-layer="svg2408" />
+ <defs
+ id="defs2410">
+ <linearGradient
+ id="linearGradient3858">
+ <stop
+ offset="0"
+ style="stop-color:#ffffff;stop-opacity:1"
+ id="stop3860" />
+ <stop
+ offset="1"
+ style="stop-color:#aaaaaa;stop-opacity:1"
+ id="stop3862" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3637">
+ <stop
+ id="stop3639"
+ style="stop-color:#f0f0f0;stop-opacity:1"
+ offset="0" />
+ <stop
+ id="stop3641"
+ style="stop-color:#aaaaaa;stop-opacity:1"
+ offset="1" />
+ </linearGradient>
+ <linearGradient
+ x1="45.447727"
+ y1="92.539597"
+ x2="45.447727"
+ y2="7.0165396"
+ id="ButtonShadow"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="scale(1.0058652,0.994169)">
+ <stop
+ id="stop3750"
+ style="stop-color:#000000;stop-opacity:1"
+ offset="0" />
+ <stop
+ id="stop3752"
+ style="stop-color:#000000;stop-opacity:0.58823532"
+ offset="1" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3737">
+ <stop
+ id="stop3739"
+ style="stop-color:#ffffff;stop-opacity:1"
+ offset="0" />
+ <stop
+ id="stop3741"
+ style="stop-color:#ffffff;stop-opacity:0"
+ offset="1" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3700">
+ <stop
+ id="stop3702"
+ style="stop-color:#2276c5;stop-opacity:1"
+ offset="0" />
+ <stop
+ id="stop3704"
+ style="stop-color:#68baf4;stop-opacity:1"
+ offset="1" />
+ </linearGradient>
+ <filter
+ color-interpolation-filters="sRGB"
+ id="filter3174">
+ <feGaussianBlur
+ id="feGaussianBlur3176"
+ stdDeviation="1.71" />
+ </filter>
+ <linearGradient
+ x1="36.357143"
+ y1="6"
+ x2="36.357143"
+ y2="63.893143"
+ id="linearGradient3188"
+ xlink:href="#linearGradient3737"
+ gradientUnits="userSpaceOnUse" />
+ <filter
+ x="-0.192"
+ y="-0.192"
+ width="1.3839999"
+ height="1.3839999"
+ color-interpolation-filters="sRGB"
+ id="filter3794">
+ <feGaussianBlur
+ id="feGaussianBlur3796"
+ stdDeviation="5.28" />
+ </filter>
+ <linearGradient
+ x1="48"
+ y1="20.220806"
+ x2="48"
+ y2="138.66119"
+ id="linearGradient3613"
+ xlink:href="#linearGradient3737"
+ gradientUnits="userSpaceOnUse" />
+ <radialGradient
+ cx="48"
+ cy="90.171875"
+ r="42"
+ fx="48"
+ fy="90.171875"
+ id="radialGradient3619"
+ xlink:href="#linearGradient3737"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.1573129,0,0,0.99590774,-7.5510206,0.19713193)" />
+ <clipPath
+ id="clipPath3613">
+ <rect
+ width="84"
+ height="84"
+ rx="6"
+ ry="6"
+ x="6"
+ y="6"
+ id="rect3615"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none" />
+ </clipPath>
+ <linearGradient
+ x1="48"
+ y1="90"
+ x2="48"
+ y2="5.9877172"
+ id="linearGradient2843"
+ xlink:href="#linearGradient3700"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,100)" />
+ <clipPath
+ id="clipPath3625">
+ <path
+ d="M 0,0 0,96 96,96 96,0 0,0 z m 12,6 72,0 c 3.324,0 6,2.676 6,6 l 0,72 c 0,3.324 -2.676,6 -6,6 L 12,90 C 8.676,90 6,87.324 6,84 L 6,12 C 6,8.676 8.676,6 12,6 z"
+ inkscape:connector-curvature="0"
+ id="path3627"
+ style="fill:#ffffff;fill-opacity:1;stroke:none" />
+ </clipPath>
+ <linearGradient
+ x1="44.512066"
+ y1="6"
+ x2="44.512066"
+ y2="90.015434"
+ id="linearGradient3643"
+ xlink:href="#linearGradient3637"
+ gradientUnits="userSpaceOnUse" />
+ <clipPath
+ id="clipPath3649">
+ <rect
+ width="76"
+ height="76"
+ rx="4"
+ ry="4"
+ x="10"
+ y="10"
+ id="rect3651"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none" />
+ </clipPath>
+ <filter
+ color-interpolation-filters="sRGB"
+ id="filter3657">
+ <feGaussianBlur
+ id="feGaussianBlur3659"
+ stdDeviation="1.14" />
+ </filter>
+ <linearGradient
+ x1="45.447727"
+ y1="92.539597"
+ x2="45.447727"
+ y2="7.0165396"
+ id="ButtonShadow-0"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.0058652,0,0,0.994169,100,0)">
+ <stop
+ id="stop3750-8"
+ style="stop-color:#000000;stop-opacity:1"
+ offset="0" />
+ <stop
+ id="stop3752-5"
+ style="stop-color:#000000;stop-opacity:0.58823532"
+ offset="1" />
+ </linearGradient>
+ <linearGradient
+ x1="32.251034"
+ y1="6.1317081"
+ x2="32.251034"
+ y2="90.238609"
+ id="linearGradient3780"
+ xlink:href="#ButtonShadow-0"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.0238095,0,0,-1.0119048,-1.1428571,98.071429)" />
+ <linearGradient
+ x1="32.251034"
+ y1="6.1317081"
+ x2="32.251034"
+ y2="90.238609"
+ id="linearGradient3772"
+ xlink:href="#ButtonShadow-0"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.0238095,0,0,-1.0119048,-1.1428571,98.071429)" />
+ <linearGradient
+ x1="32.251034"
+ y1="6.1317081"
+ x2="32.251034"
+ y2="90.238609"
+ id="linearGradient3725"
+ xlink:href="#ButtonShadow-0"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.0238095,0,0,-1.0119048,-1.1428571,98.071429)" />
+ <linearGradient
+ x1="32.251034"
+ y1="6.1317081"
+ x2="32.251034"
+ y2="90.238609"
+ id="linearGradient3721"
+ xlink:href="#ButtonShadow-0"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,-1,0,97)" />
+ <linearGradient
+ x1="32.251034"
+ y1="6.1317081"
+ x2="32.251034"
+ y2="90.238609"
+ id="linearGradient3199"
+ xlink:href="#ButtonShadow-0"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.0238095,0,0,-1.0119048,-1.1428571,98.071429)" />
+ <linearGradient
+ x1="36.357143"
+ y1="6"
+ x2="36.357143"
+ y2="63.893143"
+ id="linearGradient3188-8"
+ xlink:href="#linearGradient3737-3"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-7.3170732,-6.2926829)" />
+ <linearGradient
+ id="linearGradient3737-3">
+ <stop
+ id="stop3739-6"
+ style="stop-color:#ffffff;stop-opacity:1"
+ offset="0" />
+ <stop
+ id="stop3741-1"
+ style="stop-color:#ffffff;stop-opacity:0"
+ offset="1" />
+ </linearGradient>
+ <radialGradient
+ cx="48"
+ cy="90.171875"
+ r="42"
+ fx="48"
+ fy="90.171875"
+ id="radialGradient3619-3"
+ xlink:href="#linearGradient3737-3"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.1573129,0,0,0.99590774,-14.868094,-6.095551)" />
+ <linearGradient
+ x1="104"
+ y1="8"
+ x2="120"
+ y2="8"
+ id="linearGradient3905"
+ xlink:href="#linearGradient3637"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-104,104)" />
+ <linearGradient
+ x1="104"
+ y1="8"
+ x2="120"
+ y2="8"
+ id="linearGradient3913"
+ xlink:href="#linearGradient3183-0"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-144,104)" />
+ <linearGradient
+ id="linearGradient3183-0">
+ <stop
+ id="stop3185-9"
+ style="stop-color:#c80000;stop-opacity:1"
+ offset="0" />
+ <stop
+ id="stop3187-6"
+ style="stop-color:#f3604d;stop-opacity:1"
+ offset="1" />
+ </linearGradient>
+ <linearGradient
+ x1="13"
+ y1="3"
+ x2="13"
+ y2="19"
+ id="linearGradient3022"
+ xlink:href="#linearGradient3637"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(3.25,0,0,3.25,12.25,12.25)" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3183-0"
+ id="linearGradient3077"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-144,104)"
+ x1="104"
+ y1="8"
+ x2="120"
+ y2="8" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3637"
+ id="linearGradient3082"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-104,104)"
+ x1="104"
+ y1="8"
+ x2="120"
+ y2="8" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3637"
+ id="linearGradient3102"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(5.2543554,0,0,5.2543554,-105.50523,-10.414634)"
+ x1="13"
+ y1="3"
+ x2="13"
+ y2="19" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3858"
+ id="linearGradient3983"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.4967108,0,0,1.4967108,-2.4094778,0.11280244)"
+ x1="13"
+ y1="3"
+ x2="13"
+ y2="19" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3637"
+ id="linearGradient4019"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.4967108,0,0,1.4967108,1.4542413,-1.2816271)"
+ x1="13"
+ y1="3"
+ x2="13"
+ y2="19" />
+ </defs>
+ <metadata
+ id="metadata2413">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title />
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <path
+ inkscape:transform-center-y="0.36649443"
+ inkscape:transform-center-x="0.19686872"
+ sodipodi:nodetypes="ssssssssss"
+ inkscape:connector-curvature="0"
+ style="opacity:0.1;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ d="m 7.7360918,10.076705 c -1.0465409,-0.02783 -4.5578473,1.895837 -4.370619,3.201562 1.1292459,7.87531 3.0176472,3.848231 4.0641876,3.876067 1.04654,0.02783 3.0913186,-2.092967 3.1191546,-3.139507 0.02784,-1.04654 -1.7661835,-3.910286 -2.8127232,-3.938122 z m -0.2484806,2.596547 c 0.7365921,0.0196 1.3199737,0.62932 1.3003816,1.365911 -0.019591,0.736592 -0.6347054,1.319831 -1.3712973,1.300239 C 6.6801043,15.319822 6.0968659,14.704697 6.116458,13.968104 6.136051,13.231514 6.7510197,12.65366 7.4876112,12.673252 z"
+ id="path3885" />
+ <path
+ inkscape:transform-center-y="0.44737781"
+ inkscape:transform-center-x="-0.49775681"
+ id="path3887"
+ d="m 7.50964,10.456728 c -1.4846825,-0.0395 -4.0165802,1.677249 -4.0560705,3.161931 -0.03949,1.484683 2.3723168,4.282886 3.8569993,4.322377 1.4846825,0.0395 4.4930972,-2.511286 4.5325872,-3.995968 0.03949,-1.484683 -2.8488334,-3.448851 -4.333516,-3.48834 z m -0.00929,1.585106 c 1.044973,0.02779 1.8725925,0.892788 1.8447974,1.93776 -0.027792,1.044971 -0.900429,1.872388 -1.9454014,1.844592 -1.0449709,-0.02779 -1.872387,-0.900428 -1.8445924,-1.945401 0.027794,-1.044971 0.9002269,-1.864747 1.9451973,-1.836951 z"
+ style="opacity:0.15;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ssssssssss" />
+ <path
+ inkscape:transform-center-y="0.15406876"
+ inkscape:transform-center-x="-0.20260573"
+ style="opacity:0.3;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ d="m 7.4418655,10.570955 c -1.8406283,-0.04896 -3.3742444,1.405189 -3.4232025,3.245817 -0.048958,1.840628 1.4051888,3.374244 3.2458166,3.423202 1.8406287,0.04896 3.3742444,-1.405187 3.4232024,-3.245816 0.04896,-1.840628 -1.405188,-3.374245 -3.2458165,-3.423203 z m 0.04061,0.968013 c 1.2954991,0.03446 2.3215364,1.106832 2.287078,2.40233 C 9.7350962,15.236796 8.6532501,16.262582 7.357752,16.228123 6.0622533,16.193665 5.0364682,15.11182 5.0709264,13.816321 5.1053841,12.520824 6.1869779,11.50451 7.4824762,11.538968 z"
+ id="path3889"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path3873"
+ d="m 9.5886993,18.492316 c -1.0468884,-0.0069 -4.5189639,1.98674 -4.3056216,3.288454 1.2867453,7.851113 3.0941135,3.787021 4.1410019,3.793891 1.0468874,0.0069 3.0487804,-2.154459 3.0556514,-3.201346 0.0069,-1.046889 -1.844144,-3.874128 -2.8910317,-3.880999 z m -0.1964272,2.601002 c 0.7368369,0.0049 1.3323129,0.602758 1.3274829,1.339588 -0.0049,0.736835 -0.608144,1.332278 -1.344978,1.327444 -0.7368361,-0.0049 -1.3322773,-0.608144 -1.3274445,-1.344978 0.00484,-0.736836 0.6081094,-1.32689 1.3449449,-1.322054 z"
+ style="opacity:0.1;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ssssssssss"
+ inkscape:transform-center-x="0.56656789"
+ inkscape:transform-center-y="0.28133852" />
+ <path
+ sodipodi:nodetypes="ssssssssss"
+ inkscape:connector-curvature="0"
+ style="opacity:0.15;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ d="m 9.3699042,18.876798 c -1.4851755,-0.0098 -3.9821831,1.757355 -3.9919301,3.242531 -0.00975,1.485176 2.4576172,4.234514 3.9427934,4.244261 1.4851765,0.0098 4.4418985,-2.600768 4.4516465,-4.085943 0.0098,-1.485176 -2.917335,-3.391102 -4.4025098,-3.400849 z m 0.022461,1.584973 c 1.0453178,0.0069 1.8900968,0.855105 1.8832348,1.900424 -0.0069,1.045319 -0.862748,1.890046 -1.908069,1.883182 -1.0453184,-0.0069 -1.8900451,-0.862749 -1.8831824,-1.908071 0.00686,-1.045318 0.8626989,-1.882401 1.908017,-1.87554 z"
+ id="path3875"
+ inkscape:transform-center-x="-0.13191825"
+ inkscape:transform-center-y="0.34529215" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path3877"
+ d="m 9.3044317,18.99236 c -1.8412404,-0.01209 -3.3454255,1.472486 -3.3575151,3.31372 -0.012088,1.841239 1.4724861,3.345424 3.3137198,3.357514 1.8412396,0.01209 3.3454256,-1.472486 3.3575146,-3.313719 0.01209,-1.841239 -1.472485,-3.345425 -3.3137193,-3.357514 z m 0.059989,0.967006 c 1.2959293,0.0086 2.3432373,1.060112 2.3347343,2.35604 -0.0086,1.295928 -1.06959,2.343175 -2.365522,2.334666 -1.2959294,-0.0086 -2.3431761,-1.069589 -2.3346664,-2.365521 0.0085,-1.29593 1.0695264,-2.3337 2.365455,-2.325195 z"
+ style="opacity:0.3;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ inkscape:transform-center-x="0.16073992"
+ inkscape:transform-center-y="0.053082034" />
+ <path
+ id="path3849"
+ d="m 18.889042,18.664314 c -1.037856,0.1374 -4.202218,2.590276 -3.811601,3.850193 2.355951,7.599026 3.586271,3.324715 4.624127,3.187315 1.037854,-0.137402 2.722945,-2.553885 2.585545,-3.591739 -0.137401,-1.037856 -2.360217,-3.583171 -3.398071,-3.445769 z m 0.163726,2.603265 c 0.730481,-0.0967 1.402641,0.413487 1.499349,1.143965 0.0967,0.730479 -0.418829,1.403349 -1.149308,1.500057 -0.730478,0.0967 -1.403347,-0.41883 -1.500054,-1.149309 -0.0967,-0.730479 0.419537,-1.398006 1.150013,-1.494713 z"
+ style="opacity:0.1;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ssssssssss"
+ inkscape:transform-center-x="0.4446968"
+ inkscape:transform-center-y="0.58573564" />
+ <path
+ sodipodi:nodetypes="ssssssssss"
+ inkscape:connector-curvature="0"
+ style="opacity:0.15;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ d="m 18.725294,19.075267 c -1.472361,0.194925 -3.702151,2.28914 -3.507226,3.761501 0.194925,1.47236 3.017484,3.855618 4.489845,3.660693 1.47236,-0.194926 4.041308,-3.187838 3.846382,-4.6602 -0.194924,-1.47236 -3.356641,-2.956918 -4.829001,-2.761994 z m 0.240572,1.566772 c 1.036299,-0.137195 1.989868,0.586597 2.127062,1.622895 0.137195,1.036301 -0.594175,1.990871 -1.630474,2.128066 -1.036299,0.137195 -1.990871,-0.594175 -2.128066,-1.630474 -0.137193,-1.036299 0.59518,-1.983292 1.631478,-2.120487 z"
+ id="path3851"
+ inkscape:transform-center-x="-0.27111393"
+ inkscape:transform-center-y="0.5280789" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path3853"
+ d="m 18.676364,19.198747 c -1.825353,0.241657 -3.110704,1.919272 -2.869046,3.744625 0.241656,1.825352 1.919272,3.110703 3.744624,2.869046 1.825354,-0.241658 3.110704,-1.919274 2.869047,-3.744626 -0.241657,-1.825352 -1.919273,-3.110702 -3.744625,-2.869045 z m 0.19262,0.949525 c 1.284746,-0.170088 2.466929,0.727231 2.637015,2.011979 0.170087,1.284746 -0.736626,2.468171 -2.021373,2.638257 -1.284746,0.170087 -2.468172,-0.736626 -2.638258,-2.021372 -0.170087,-1.284747 0.737869,-2.458778 2.022616,-2.628864 z"
+ style="opacity:0.3;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ inkscape:transform-center-x="0.00017342173"
+ inkscape:transform-center-y="0.25032941" />
+ <path
+ inkscape:transform-center-y="0.54608804"
+ inkscape:transform-center-x="0.62401103"
+ sodipodi:nodetypes="ssssssssss"
+ inkscape:connector-curvature="0"
+ style="opacity:0.1;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ d="m 24.868484,8.2343126 c -1.044562,0.070097 -4.360716,2.3135084 -4.052276,3.5960204 1.860318,7.735304 3.364089,3.549363 4.408651,3.479269 1.044562,-0.0701 2.882184,-2.372716 2.812089,-3.417277 -0.0701,-1.044561 -2.123903,-3.7281053 -3.168464,-3.6580124 z m -0.0048,2.6084054 c 0.735198,-0.04933 1.373011,0.503203 1.422345,1.238402 0.04933,0.735197 -0.508577,1.373371 -1.243777,1.422705 -0.735166,0.04933 -1.373339,-0.508578 -1.422674,-1.243777 -0.04933,-0.735199 0.508939,-1.367995 1.244138,-1.41733 z"
+ id="path3861" />
+ <path
+ inkscape:transform-center-y="0.54641798"
+ inkscape:transform-center-x="-0.085724368"
+ id="path3863"
+ d="m 24.678541,8.6338352 c -1.481876,0.099434 -3.842248,2.0452918 -3.74281,3.5271678 0.09943,1.481875 2.762206,4.042426 4.244081,3.942988 1.481876,-0.09943 4.238731,-2.920212 4.139292,-4.402086 -0.09943,-1.481877 -3.158689,-3.167508 -4.640563,-3.0680698 z m 0.138894,1.5790368 c 1.042995,-0.06999 1.947833,0.713872 2.017822,1.756867 0.06999,1.042995 -0.721498,1.948344 -1.764494,2.018334 -1.042995,0.06999 -1.948344,-0.721499 -2.018333,-1.764494 -0.06999,-1.042996 0.72201,-1.940719 1.765005,-2.010707 z"
+ style="opacity:0.15;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ssssssssss" />
+ <path
+ inkscape:transform-center-y="0.26029952"
+ inkscape:transform-center-x="0.196409"
+ style="opacity:0.3;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ d="m 24.621738,8.7538978 c -1.837147,0.1232842 -3.228149,1.7143892 -3.10487,3.5515372 0.123284,1.837149 1.714389,3.22815 3.551537,3.104871 1.837148,-0.123284 3.228149,-1.71439 3.104871,-3.551538 -0.123285,-1.837148 -1.71439,-3.228149 -3.551538,-3.1048702 z m 0.130904,0.9599816 c 1.293048,-0.086762 2.414817,0.8850186 2.501585,2.1780666 0.08676,1.293049 -0.894474,2.415452 -2.187522,2.50222 -1.293049,0.08676 -2.415453,-0.894474 -2.50222,-2.187522 -0.08676,-1.293049 0.895108,-2.405997 2.188157,-2.4927646 z"
+ id="path3865"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ssssssssss"
+ inkscape:connector-curvature="0"
+ style="opacity:0.1;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ d="m 14.029843,5.4909841 c -1.046911,0 -4.5058277,2.016355 -4.2839472,3.3166402 1.3382432,7.8424997 3.1189012,3.7666337 4.1658122,3.7666337 1.04691,0 3.034575,-2.174423 3.034575,-3.2213323 0,-1.0469108 -1.869531,-3.8619416 -2.91644,-3.8619416 z M 13.850489,8.093221 c 0.736853,0 1.336241,0.5939985 1.336241,1.3308516 0,0.7368514 -0.599388,1.3362394 -1.336241,1.3362394 -0.736851,0 -1.336239,-0.599388 -1.336239,-1.3362394 0,-0.7368531 0.599388,-1.3308516 1.336239,-1.3308516 z"
+ id="path3077" />
+ <path
+ id="path3075"
+ d="m 13.813576,5.8768934 c -1.485209,0 -3.9705641,1.7834529 -3.9705641,3.2686617 0,1.4852079 2.4853551,4.2182919 3.9705641,4.2182919 1.485207,0 4.158787,-2.851487 4.158787,-4.3366948 0,-1.4852088 -2.67358,-3.1502588 -4.158787,-3.1502588 z m 0.03286,1.5847924 c 1.045341,0 1.895668,0.8426816 1.895668,1.8880223 0,1.0453419 -0.850327,1.8956679 -1.895668,1.8956679 -1.045341,0 -1.895666,-0.850326 -1.895666,-1.8956679 0,-1.0453407 0.850325,-1.8880223 1.895666,-1.8880223 z"
+ style="opacity:0.15;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ssssssssss" />
+ <path
+ style="opacity:0.3;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ d="m 13.748863,5.9928827 c -1.84128,0 -3.335689,1.4944093 -3.335689,3.3356891 0,1.8412782 1.494409,3.3356892 3.335689,3.3356892 1.841278,0 3.335689,-1.494411 3.335689,-3.3356892 0,-1.8412798 -1.494411,-3.3356891 -3.335689,-3.3356891 z m 0.06634,0.966592 c 1.295956,0 2.350144,1.0447105 2.350144,2.3406671 0,1.2959582 -1.054188,2.3501442 -2.350144,2.3501442 -1.295958,0 -2.350145,-1.054186 -2.350145,-2.3501442 0,-1.2959566 1.054187,-2.3406671 2.350145,-2.3406671 z"
+ id="path3065"
+ inkscape:connector-curvature="0" />
+ <g
+ id="layer2"
+ style="display:none"
+ transform="translate(0,-64)">
+ <rect
+ width="86"
+ height="85"
+ rx="6"
+ ry="6"
+ x="5"
+ y="7"
+ clip-path="url(#clipPath3625)"
+ id="rect3745"
+ style="opacity:0.9;fill:url(#ButtonShadow);fill-opacity:1;fill-rule:nonzero;stroke:none;filter:url(#filter3174)" />
+ </g>
+ <g
+ id="layer1"
+ style="display:none"
+ transform="translate(0,-64)">
+ <rect
+ width="84"
+ height="84"
+ rx="6"
+ ry="6"
+ x="6"
+ y="6"
+ id="rect2419"
+ style="opacity:0.8;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none" />
+ <path
+ d="m 14,10 c -2.216,0 -4,1.784 -4,4 l 0,68 c 0,2.216 1.784,4 4,4 l 68,0 c 2.216,0 4,-1.784 4,-4 l 0,-68 c 0,-2.216 -1.784,-4 -4,-4 l -68,0 z m 0,3.0625 68,0 c 0.578769,0 0.9375,0.358731 0.9375,0.9375 l 0,68 c 0,0.578769 -0.358731,0.9375 -0.9375,0.9375 l -68,0 c -0.578769,0 -0.9375,-0.358731 -0.9375,-0.9375 l 0,-68 c 0,-0.578769 0.358731,-0.9375 0.9375,-0.9375 z"
+ inkscape:connector-curvature="0"
+ id="rect3726"
+ style="opacity:0.07999998;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none" />
+ <path
+ d="M 12,6 C 8.676,6 6,8.676 6,12 l 0,72 c 0,3.324 2.676,6 6,6 l 72,0 c 3.324,0 6,-2.676 6,-6 L 90,12 C 90,8.676 87.324,6 84,6 L 12,6 z m 2,4 68,0 c 2.216,0 4,1.784 4,4 l 0,68 c 0,2.216 -1.784,4 -4,4 l -68,0 c -2.216,0 -4,-1.784 -4,-4 l 0,-68 c 0,-2.216 1.784,-4 4,-4 z"
+ inkscape:connector-curvature="0"
+ id="rect3629"
+ style="fill:url(#linearGradient3643);fill-opacity:1;fill-rule:nonzero;stroke:none" />
+ <path
+ d="M 12,6 C 8.676,6 6,8.676 6,12 l 0,2 0,68 0,2 c 0,0.334721 0.04135,0.6507 0.09375,0.96875 0.0487,0.295596 0.09704,0.596915 0.1875,0.875 0.00988,0.03038 0.020892,0.0636 0.03125,0.09375 0.098865,0.287771 0.2348802,0.547452 0.375,0.8125 0.1445918,0.273507 0.3156161,0.535615 0.5,0.78125 0.1843839,0.245635 0.3737765,0.473472 0.59375,0.6875 0.439947,0.428056 0.94291,0.814526 1.5,1.09375 0.278545,0.139612 0.5734731,0.246947 0.875,0.34375 -0.2562018,-0.100222 -0.4867109,-0.236272 -0.71875,-0.375 -0.00741,-0.0044 -0.023866,0.0045 -0.03125,0 -0.031933,-0.0193 -0.062293,-0.04251 -0.09375,-0.0625 -0.120395,-0.0767 -0.2310226,-0.163513 -0.34375,-0.25 -0.1061728,-0.0808 -0.2132809,-0.161112 -0.3125,-0.25 C 8.4783201,88.557317 8.3087904,88.373362 8.15625,88.1875 8.0486711,88.057245 7.9378561,87.922215 7.84375,87.78125 7.818661,87.74287 7.805304,87.69538 7.78125,87.65625 7.716487,87.553218 7.6510225,87.451733 7.59375,87.34375 7.4927417,87.149044 7.3880752,86.928049 7.3125,86.71875 7.30454,86.69694 7.288911,86.6782 7.28125,86.65625 7.2494249,86.5643 7.2454455,86.469419 7.21875,86.375 7.1884177,86.268382 7.1483606,86.171969 7.125,86.0625 7.0521214,85.720988 7,85.364295 7,85 L 7,83 7,15 7,13 C 7,10.218152 9.2181517,8 12,8 l 2,0 68,0 2,0 c 2.781848,0 5,2.218152 5,5 l 0,2 0,68 0,2 c 0,0.364295 -0.05212,0.720988 -0.125,1.0625 -0.04415,0.206893 -0.08838,0.397658 -0.15625,0.59375 -0.0077,0.02195 -0.0233,0.04069 -0.03125,0.0625 -0.06274,0.173739 -0.138383,0.367449 -0.21875,0.53125 -0.04158,0.0828 -0.07904,0.169954 -0.125,0.25 -0.0546,0.09721 -0.126774,0.18835 -0.1875,0.28125 -0.09411,0.140965 -0.204921,0.275995 -0.3125,0.40625 -0.143174,0.17445 -0.303141,0.346998 -0.46875,0.5 -0.01117,0.0102 -0.01998,0.02115 -0.03125,0.03125 -0.138386,0.125556 -0.285091,0.234436 -0.4375,0.34375 -0.102571,0.07315 -0.204318,0.153364 -0.3125,0.21875 -0.0074,0.0045 -0.02384,-0.0044 -0.03125,0 -0.232039,0.138728 -0.462548,0.274778 -0.71875,0.375 0.301527,-0.0968 0.596455,-0.204138 0.875,-0.34375 0.55709,-0.279224 1.060053,-0.665694 1.5,-1.09375 0.219973,-0.214028 0.409366,-0.441865 0.59375,-0.6875 0.184384,-0.245635 0.355408,-0.507743 0.5,-0.78125 0.14012,-0.265048 0.276135,-0.524729 0.375,-0.8125 0.01041,-0.03078 0.02133,-0.06274 0.03125,-0.09375 0.09046,-0.278085 0.1388,-0.579404 0.1875,-0.875 C 89.95865,84.6507 90,84.334721 90,84 l 0,-2 0,-68 0,-2 C 90,8.676 87.324,6 84,6 L 12,6 z"
+ inkscape:connector-curvature="0"
+ id="rect3728"
+ style="fill:url(#linearGradient3188);fill-opacity:1;fill-rule:nonzero;stroke:none" />
+ <path
+ d="M 12,90 C 8.676,90 6,87.324 6,84 L 6,82 6,14 6,12 c 0,-0.334721 0.04135,-0.6507 0.09375,-0.96875 0.0487,-0.295596 0.09704,-0.596915 0.1875,-0.875 C 6.29113,10.12587 6.302142,10.09265 6.3125,10.0625 6.411365,9.774729 6.5473802,9.515048 6.6875,9.25 6.8320918,8.976493 7.0031161,8.714385 7.1875,8.46875 7.3718839,8.223115 7.5612765,7.995278 7.78125,7.78125 8.221197,7.353194 8.72416,6.966724 9.28125,6.6875 9.559795,6.547888 9.8547231,6.440553 10.15625,6.34375 9.9000482,6.443972 9.6695391,6.580022 9.4375,6.71875 c -0.00741,0.0044 -0.023866,-0.0045 -0.03125,0 -0.031933,0.0193 -0.062293,0.04251 -0.09375,0.0625 -0.120395,0.0767 -0.2310226,0.163513 -0.34375,0.25 -0.1061728,0.0808 -0.2132809,0.161112 -0.3125,0.25 C 8.4783201,7.442683 8.3087904,7.626638 8.15625,7.8125 8.0486711,7.942755 7.9378561,8.077785 7.84375,8.21875 7.818661,8.25713 7.805304,8.30462 7.78125,8.34375 7.716487,8.446782 7.6510225,8.548267 7.59375,8.65625 7.4927417,8.850956 7.3880752,9.071951 7.3125,9.28125 7.30454,9.30306 7.288911,9.3218 7.28125,9.34375 7.2494249,9.4357 7.2454455,9.530581 7.21875,9.625 7.1884177,9.731618 7.1483606,9.828031 7.125,9.9375 7.0521214,10.279012 7,10.635705 7,11 l 0,2 0,68 0,2 c 0,2.781848 2.2181517,5 5,5 l 2,0 68,0 2,0 c 2.781848,0 5,-2.218152 5,-5 l 0,-2 0,-68 0,-2 C 89,10.635705 88.94788,10.279012 88.875,9.9375 88.83085,9.730607 88.78662,9.539842 88.71875,9.34375 88.71105,9.3218 88.69545,9.30306 88.6875,9.28125 88.62476,9.107511 88.549117,8.913801 88.46875,8.75 88.42717,8.6672 88.38971,8.580046 88.34375,8.5 88.28915,8.40279 88.216976,8.31165 88.15625,8.21875 88.06214,8.077785 87.951329,7.942755 87.84375,7.8125 87.700576,7.63805 87.540609,7.465502 87.375,7.3125 87.36383,7.3023 87.35502,7.29135 87.34375,7.28125 87.205364,7.155694 87.058659,7.046814 86.90625,6.9375 86.803679,6.86435 86.701932,6.784136 86.59375,6.71875 c -0.0074,-0.0045 -0.02384,0.0044 -0.03125,0 -0.232039,-0.138728 -0.462548,-0.274778 -0.71875,-0.375 0.301527,0.0968 0.596455,0.204138 0.875,0.34375 0.55709,0.279224 1.060053,0.665694 1.5,1.09375 0.219973,0.214028 0.409366,0.441865 0.59375,0.6875 0.184384,0.245635 0.355408,0.507743 0.5,0.78125 0.14012,0.265048 0.276135,0.524729 0.375,0.8125 0.01041,0.03078 0.02133,0.06274 0.03125,0.09375 0.09046,0.278085 0.1388,0.579404 0.1875,0.875 C 89.95865,11.3493 90,11.665279 90,12 l 0,2 0,68 0,2 c 0,3.324 -2.676,6 -6,6 l -72,0 z"
+ inkscape:connector-curvature="0"
+ id="path3615"
+ style="opacity:0.6;fill:url(#radialGradient3619);fill-opacity:1;fill-rule:nonzero;stroke:none" />
+ <rect
+ width="84"
+ height="84"
+ rx="6"
+ ry="6"
+ x="6"
+ y="106"
+ id="rect2841"
+ style="fill:url(#linearGradient2843);fill-opacity:1;fill-rule:nonzero;stroke:none" />
+ <rect
+ width="76"
+ height="76"
+ rx="4"
+ ry="4"
+ x="10"
+ y="110"
+ id="rect3634"
+ style="fill:#ff0000;fill-opacity:1;fill-rule:nonzero;stroke:none" />
+ <path
+ d="m 14,9 c -2.752703,0 -5,2.247297 -5,5 l 0,68 c 0,2.752703 2.247297,5 5,5 l 68,0 c 2.752703,0 5,-2.247297 5,-5 L 87,14 C 87,11.247297 84.752703,9 82,9 L 14,9 z m 0,2 68,0 c 1.679297,0 3,1.320703 3,3 l 0,68 c 0,1.679297 -1.320703,3 -3,3 l -68,0 c -1.679297,0 -3,-1.320703 -3,-3 l 0,-68 c 0,-1.679297 1.320703,-3 3,-3 z"
+ inkscape:connector-curvature="0"
+ transform="translate(-110,0)"
+ clip-path="url(#clipPath3649)"
+ id="rect3647"
+ style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;color:#000000;fill:#000000;fill-opacity:1;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;filter:url(#filter3657);enable-background:accumulate;font-family:Abandoned Bitplane;-inkscape-font-specification:Abandoned Bitplane" />
+ <path
+ d="m 14.089286,10 c -2.216,0 -4,1.784 -4,4 l 0,68 c 0,2.216 1.784,4 4,4 l 68,0 c 2.216,0 4,-1.784 4,-4 l 0,-68 c 0,-2.216 -1.784,-4 -4,-4 l -68,0 z m 0,2 68,0 c 1.140301,0 2,0.859699 2,2 l 0,68 c 0,1.140301 -0.859699,2 -2,2 l -68,0 c -1.140301,0 -2,-0.859699 -2,-2 l 0,-68 c 0,-1.140301 0.859699,-2 2,-2 z"
+ inkscape:connector-curvature="0"
+ id="path3709"
+ style="opacity:0.16000001;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none" />
+ <path
+ d="m 14,10 c -2.216,0 -4,1.784 -4,4 l 0,68 c 0,2.216 1.784,4 4,4 l 68,0 c 2.216,0 4,-1.784 4,-4 l 0,-68 c 0,-2.216 -1.784,-4 -4,-4 l -68,0 z m 0,1 68,0 c 1.673848,0 3,1.326152 3,3 l 0,68 c 0,1.673848 -1.326152,3 -3,3 l -68,0 c -1.673848,0 -3,-1.326152 -3,-3 l 0,-68 c 0,-1.673848 1.326152,-3 3,-3 z"
+ inkscape:connector-curvature="0"
+ id="path3707"
+ style="opacity:0.36000001;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none" />
+ </g>
+ <g
+ id="layer5"
+ style="display:none"
+ transform="translate(0,-64)">
+ <rect
+ width="66"
+ height="66"
+ rx="12"
+ ry="12"
+ x="15"
+ y="15"
+ clip-path="url(#clipPath3613)"
+ id="rect3171"
+ style="opacity:0.1;fill:url(#linearGradient3613);fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:0.5;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;filter:url(#filter3794)" />
+ </g>
+ <path
+ style="opacity:0.1;fill:#000000;fill-opacity:1;stroke:none;display:inline"
+ d="m 23.397052,4.7958958 -1.187267,1.8882981 c 1.316951,0.6107865 4.230976,1.9166511 5.402368,4.2338811 0.657198,1.300058 0.04794,3.317313 0.04794,4.737899 0,0.932918 -0.647251,3.122641 -0.647251,3.122641 0,0 1.828583,0.135671 2.392219,0.208367 0.794448,0.03519 1.167317,-0.156493 1.270971,-0.741323 0.08399,-0.939569 0.137141,-1.748123 0.144748,-2.603153 0.03993,-4.488938 -2.773058,-8.6996204 -6.325173,-11.0411282 -0.385787,-0.2726949 -0.862833,-0.1544034 -1.098552,0.194518 z"
+ id="path3999"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccsscccscc" />
+ <path
+ style="opacity:0.1;fill:#000000;fill-opacity:1;stroke:none;display:inline"
+ d="M 22.958481,7.1064202 C 21.018009,5.9359454 16.47899,4.1359021 14.056025,4.1359021 c -7.1032893,0 -12.9010336,5.797743 -12.9010336,12.9010339 0,7.10329 5.7977443,12.901033 12.9010336,12.901033 6.234948,0 12.101435,-6.559764 13.286228,-12.455126 -1.205926,-0.366255 -8.045057,-1.714877 -8.469378,-2.443175 -0.371038,-0.62055 4.383423,-7.7589277 4.085606,-7.9332464 z m 0.935323,12.0758788 c -1.207028,4.813644 -4.706496,8.408307 -9.89457,8.408307 -0.02985,0 -0.05539,2.35e-4 -0.08519,0 -0.0298,2.35e-4 -0.06479,0 -0.09465,0 -6.1209915,0 -11.0837208,-4.953264 -11.0837208,-11.074255 0,-6.12099 4.9627293,-11.0837195 11.0837208,-11.0837195 0.02985,0 0.06485,-2.363e-4 0.09465,0 0.02981,-2.363e-4 0.05533,0 0.08519,0 2.168345,0 3.381177,1.2891357 4.446785,1.5675255 l -5.85294,10.279757 z"
+ id="path3923"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="csssccccscssscsccc" />
+ <path
+ style="opacity:0.35;fill:#000000;fill-opacity:1;stroke:none;display:inline"
+ d="M 20.416623,6.3791493 C 18.54855,5.2606951 16.387684,4.5713004 14.056025,4.5713004 c -6.8729409,0 -12.4656355,5.5926936 -12.4656355,12.4656356 0,6.872941 5.5926946,12.465635 12.4656355,12.465635 6.030193,0 10.563977,-4.32965 11.709806,-10.026852 l -1.052019,-0.271258 c -1.207028,4.813643 -5.526504,8.386145 -10.714578,8.386145 -6.120991,0 -11.08372,-4.953264 -11.08372,-11.074255 0,-6.12099 4.962729,-11.0837195 11.08372,-11.0837195 1.891369,0 4.189184,0.5241053 5.928132,1.3982729 0.07121,0.035789 -7.59274,10.1167446 -7.59274,10.1167446 l 1.514486,0.358997 c 0,0 6.829048,-9.7863279 6.981648,-9.9750518 0.144113,-0.4278928 -0.0811,-0.7112672 -0.414137,-0.9524449 z"
+ id="path3989"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="csssccsssscccc" />
+ <path
+ style="opacity:0.35;fill:#000000;fill-opacity:1;stroke:none;display:inline"
+ d="m 24.280341,4.9847188 -0.459529,0.7291303 c 3.114065,1.9618503 5.12586,5.4554279 5.12586,9.4080719 0,0.932918 -4.351964,0.271079 -3.785454,1.011296 L 20.429503,12.338806 24.83496,5.598668 C 24.483575,5.4553815 24.233831,4.3191687 23.567031,5.3210632 L 16.100252,16.30836 28.946227,18.608589 c 0.627721,0.06835 1.111696,-0.156879 1.193058,-0.505138 0.160133,-0.796209 0.236629,-1.618197 0.236629,-2.460945 0,-4.54128 -2.457204,-8.4794201 -6.095573,-10.6577872 z"
+ id="path3919"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccscccccccsc" />
+ <path
+ style="opacity:0.45;fill:#000000;fill-opacity:1;stroke:none;display:inline"
+ d="M 20.225241,6.6919614 C 18.435255,5.6259801 16.289494,5.0634892 14.056025,5.0634892 c -6.6094748,0 -11.9734464,5.3639718 -11.9734464,11.9734468 0,6.609475 5.3639716,11.973446 11.9734464,11.973446 5.799323,0 10.628006,-4.130176 11.727351,-9.607152 l -1.13582,-0.208235 c -1.247018,4.755417 -5.529967,8.282028 -10.676718,8.282028 -6.1209903,0 -11.0837195,-4.962729 -11.0837195,-11.083719 0,-6.120991 4.9627292,-11.0837204 11.0837195,-11.0837204 2.203136,0 4.202774,0.6284983 5.928202,1.7367442 0.04152,0.030478 -7.853058,10.1011992 -7.853058,10.1011992 l 1.298577,0.204818 c 0,0 6.940561,-10.0934568 6.955136,-10.1137253 0.121193,-0.1685314 0.08888,-0.4540396 -0.07446,-0.5466583 z"
+ id="path4002"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="csssccssscccsc" />
+ <path
+ style="opacity:0.45;fill:#000000;fill-opacity:1;stroke:none;display:inline"
+ d="m 24.005851,5.3917211 -0.19877,0.293421 c 3.068343,1.9708036 5.111195,5.3958779 5.111195,9.3137319 0,0.97424 -10.835321,-0.451046 -11.071373,0.449118 l -0.792479,0.640281 12.156547,2.210083 c 0.252619,0.01637 0.381726,-0.09727 0.436123,-0.289557 0.153577,-0.76512 0.246096,-1.556142 0.246095,-2.366293 0,-4.376005 -2.380247,-8.1622223 -5.887338,-10.2507849 z"
+ id="path3913"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccsccccsc" />
+ <path
+ style="fill:url(#linearGradient3983);fill-opacity:1;stroke:none;display:inline"
+ d="m 14.056025,4.5996963 c -6.6094748,0 -11.9734464,5.3639705 -11.9734464,11.9734457 0,6.609477 5.3639716,11.973446 11.9734464,11.973446 5.63699,0 10.334306,-3.914092 11.604305,-9.162289 L 13.175763,17.065332 20.378761,6.4454052 C 18.539507,5.2938977 16.384779,4.5996963 14.056025,4.5996963 z m -0.331281,1.8835702 c 1.493619,0 2.70704,1.2039546 2.70704,2.6975747 0,1.4936188 -1.071444,2.6313178 -2.565063,2.6313178 -1.49362,0 -2.849017,-1.137699 -2.849017,-2.6313178 0,-1.4936201 1.21342,-2.697576 2.70704,-2.697576 z M 7.2600291,10.969759 c 0.4359735,-0.01019 0.8814994,0.08971 1.2967288,0.302886 1.3287348,0.682175 1.8558581,2.305892 1.1736818,3.634627 C 9.0482644,16.236006 7.4150818,16.753664 6.0863474,16.071488 4.757613,15.389313 4.2304904,13.765596 4.9126656,12.436861 5.3816612,11.523357 6.300888,10.99213 7.2600291,10.969759 z m 2.0255476,8.651169 c 0.6921258,3.66e-4 1.3841703,0.257257 1.9119663,0.78561 1.055588,1.056708 1.056707,2.768342 0,3.823931 -1.056708,1.055589 -2.7683428,1.056706 -3.8239318,0 -1.0555888,-1.056709 -1.0567075,-2.768342 0,-3.823931 0.528354,-0.527794 1.2198398,-0.785976 1.9119655,-0.78561 z m 9.6828743,0.10412 c 0.867672,-0.02936 1.742128,0.361474 2.290572,1.116891 0.877509,1.208668 0.602896,2.899096 -0.605771,3.776606 -1.208668,0.877509 -2.899096,0.602896 -3.776606,-0.605771 -0.877509,-1.208667 -0.61236,-2.889631 0.596308,-3.767141 0.453249,-0.329066 0.974893,-0.50297 1.495497,-0.520585 z"
+ id="path3971"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:url(#linearGradient4019);fill-opacity:1;stroke:none;display:inline"
+ d="M 24.24248,5.0509761 17.039481,15.670902 29.524048,17.98987 c 0.219097,-0.90541 0.369142,-1.838673 0.369141,-2.811157 0,-4.280721 -2.269787,-8.011035 -5.650709,-10.1277369 z m 0.643631,4.1836066 c 1.053846,0.01236 2.055676,0.6480115 2.479876,1.6848013 0.565601,1.382387 -0.09418,2.955444 -1.476566,3.521046 -1.382388,0.565599 -2.96491,-0.09418 -3.530511,-1.476568 -0.565602,-1.382388 0.09418,-2.9649104 1.476567,-3.5305102 0.345597,-0.1414013 0.699353,-0.2029062 1.050634,-0.1987691 z"
+ id="path2505"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.15;fill:#000000;fill-opacity:1;stroke:none;display:inline"
+ d="m 25.537282,19.355905 c -1.419799,5.028896 -6.00014,8.736355 -11.481257,8.736355 -6.5326617,0 -11.8507636,-5.242776 -11.9734464,-11.746282 -0.00143,0.07647 0,0.150351 0,0.227164 0,6.609475 5.3639716,11.973446 11.9734464,11.973446 5.637551,0 10.334648,-3.913084 11.604305,-9.162289 l -0.123054,-0.0284 z"
+ id="path4013"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.15;fill:#000000;fill-opacity:1;stroke:none;display:inline"
+ d="m 29.475439,17.636297 0.123053,0.0284 c 0.218891,-0.904972 0.28687,-1.874492 0.28687,-2.846416 0,-0.07682 -0.03383,-0.166365 -0.03526,-0.242835 -0.01975,1.046851 -0.102273,2.096069 -0.374656,3.060856 z"
+ id="path3904"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccscc" />
+ <path
+ style="opacity:0.75;fill:#ffffff;fill-opacity:1;stroke:none;display:inline"
+ d="M 20.378761,6.4454052 C 18.539342,5.2937334 16.384779,4.5996963 14.056025,4.5996963 c -6.6094748,0 -11.9734464,5.3639705 -11.9734464,11.9734457 0,0.07681 -0.00143,0.160159 0,0.23663 C 2.2052612,10.306266 7.5233633,5.0634892 14.056025,5.0634892 c 2.235014,0 4.304278,0.6457475 6.095573,1.713197 l 0.227163,-0.331281 z"
+ id="path4010"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.75;fill:#ffffff;fill-opacity:1;stroke:none;display:inline"
+ d="m 24.24248,5.0509761 -0.227164,0.331281 c 3.444431,2.0525688 5.797164,5.7546189 5.877873,10.0330849 0.0015,-0.07647 0,-0.159816 0,-0.236629 0,-4.280722 -2.269484,-8.0107322 -5.650709,-10.1277369 z"
+ id="path3888"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.75;fill:#ffffff;fill-opacity:1;stroke:none;display:inline"
+ id="path3890"
+ inkscape:connector-curvature="0"
+ d="m 13.736282,12.139839 c -1.50143,0 -2.734087,-1.102416 -2.730402,-3.034897 3.3e-5,-0.017983 -3.32e-4,-0.03602 0,-0.053934 0.02787,1.5234153 1.230788,2.7850673 2.714769,2.7850673 1.48398,0 2.730483,-1.103647 2.725191,-2.7850673 3.31e-4,0.017915 -3.5e-5,0.035938 0,0.053934 0.0037,1.892978 -1.20813,3.034897 -2.709558,3.034897 z"
+ sodipodi:nodetypes="sscscss" />
+ <path
+ sodipodi:nodetypes="sscscss"
+ d="m 13.725859,6.2796975 c 1.50143,0 2.723665,1.175367 2.719981,3.1078475 -3.5e-5,0.017983 3.31e-4,0.03602 0,0.053934 -0.02787,-1.5234151 -1.23079,-2.7538044 -2.714771,-2.7538044 -1.483978,0 -2.730481,1.0723826 -2.725189,2.7538044 -3.33e-4,-0.017915 3.5e-5,-0.035938 0,-0.053934 -0.0037,-1.8929785 1.218551,-3.1078475 2.719979,-3.1078475 z"
+ inkscape:connector-curvature="0"
+ id="path3892"
+ style="opacity:0.15;fill:#000000;fill-opacity:1;stroke:none;display:inline" />
+ <path
+ sodipodi:nodetypes="sscscss"
+ d="m 19.470644,25.294184 c -1.488442,0.197053 -2.855123,-0.734049 -3.105097,-2.650297 -0.0023,-0.01783 -0.005,-0.03567 -0.0071,-0.05347 0.227566,1.50658 1.585669,2.599443 3.056812,2.40468 1.471143,-0.194764 2.562016,-1.452462 2.336094,-3.118643 0.0027,0.01771 0.0046,0.03564 0.0071,0.05347 0.252095,1.876121 -0.799366,3.167206 -2.287807,3.36426 z"
+ inkscape:connector-curvature="0"
+ id="path3855"
+ style="opacity:0.75;fill:#ffffff;fill-opacity:1;stroke:none;display:inline"
+ inkscape:transform-center-x="0.03718261"
+ inkscape:transform-center-y="1.3430212" />
+ <path
+ style="opacity:0.15;fill:#000000;fill-opacity:1;stroke:none;display:inline"
+ id="path3857"
+ inkscape:connector-curvature="0"
+ d="m 18.691202,19.486101 c 1.488441,-0.197054 2.854364,0.807735 3.104339,2.723982 0.0023,0.01783 0.005,0.03567 0.0071,0.05347 -0.227566,-1.506581 -1.581564,-2.568449 -3.052709,-2.373685 -1.471143,0.194762 -2.566119,1.421465 -2.340197,3.087648 -0.0027,-0.01771 -0.0046,-0.03564 -0.0071,-0.05347 -0.252094,-1.876121 0.800123,-3.240891 2.288565,-3.437945 z"
+ sodipodi:nodetypes="sscscss"
+ inkscape:transform-center-x="0.030372304"
+ inkscape:transform-center-y="-1.0356419" />
+ <path
+ inkscape:transform-center-y="1.4378439"
+ inkscape:transform-center-x="0.23106924"
+ style="opacity:0.75;fill:#ffffff;fill-opacity:1;stroke:none;display:inline"
+ id="path3867"
+ inkscape:connector-curvature="0"
+ d="m 25.02074,14.887904 c -1.498058,0.10052 -2.801761,-0.916889 -2.927469,-2.84528 -0.0012,-0.01796 -0.0027,-0.03592 -0.0037,-0.05381 0.129804,1.518132 1.414496,2.696414 2.895146,2.597058 1.480651,-0.09935 2.650464,-1.283984 2.532609,-2.961278 0.0015,0.01785 0.0023,0.03587 0.0037,0.05381 0.130415,1.888486 -1.002225,3.108975 -2.500285,3.2095 z"
+ sodipodi:nodetypes="sscscss" />
+ <path
+ inkscape:transform-center-y="-1.1149883"
+ inkscape:transform-center-x="0.21865458"
+ sodipodi:nodetypes="sscscss"
+ d="m 24.617989,9.041609 c 1.49806,-0.1005207 2.796249,0.990373 2.921956,2.918764 0.0012,0.01795 0.0027,0.03592 0.0037,0.05381 -0.129804,-1.518131 -1.412402,-2.6652198 -2.893053,-2.5658631 -1.480649,0.099353 -2.652557,1.2527891 -2.534702,2.9300831 -0.0015,-0.01785 -0.0023,-0.03587 -0.0037,-0.05381 -0.130414,-1.888484 1.007738,-3.1824592 2.505798,-3.2829827 z"
+ inkscape:connector-curvature="0"
+ id="path3869"
+ style="opacity:0.15;fill:#000000;fill-opacity:1;stroke:none;display:inline" />
+ <path
+ sodipodi:nodetypes="sscscss"
+ d="m 9.2515079,25.139101 c -1.5013962,-0.0099 -2.726792,-1.120336 -2.7104247,-3.052752 1.55e-4,-0.01798 -1.058e-4,-0.03602 3.318e-4,-0.05393 0.017869,1.523564 1.2124844,2.793085 2.6964323,2.802825 1.4839477,0.0098 2.7376667,-1.085703 2.7434107,-2.767122 2.27e-4,0.01792 -2.72e-4,0.03594 -3.33e-4,0.05393 -0.0087,1.892963 -1.228021,3.026903 -2.7294174,3.017049 z"
+ inkscape:connector-curvature="0"
+ id="path3879"
+ style="opacity:0.75;fill:#ffffff;fill-opacity:1;stroke:none;display:inline"
+ inkscape:transform-center-x="0.18215477"
+ inkscape:transform-center-y="1.3108968" />
+ <path
+ style="opacity:0.15;fill:#000000;fill-opacity:1;stroke:none;display:inline"
+ id="path3881"
+ inkscape:connector-curvature="0"
+ d="m 9.279546,19.279018 c 1.501397,0.0098 2.715891,1.193217 2.699525,3.125631 -1.55e-4,0.01798 1.06e-4,0.03602 -3.31e-4,0.05393 -0.01787,-1.523562 -1.212689,-2.761819 -2.6966388,-2.771559 -1.4839477,-0.0098 -2.7374615,1.054439 -2.7432059,2.735858 -2.253e-4,-0.01791 2.711e-4,-0.03594 3.318e-4,-0.05393 0.00873,-1.892961 1.2389212,-3.099782 2.7403179,-3.089929 z"
+ sodipodi:nodetypes="sscscss"
+ inkscape:transform-center-x="0.18423798"
+ inkscape:transform-center-y="-1.4061262" />
+ <path
+ inkscape:transform-center-y="1.3843595"
+ inkscape:transform-center-x="-0.18536286"
+ style="opacity:0.75;fill:#ffffff;fill-opacity:1;stroke:none;display:inline"
+ id="path3891"
+ inkscape:connector-curvature="0"
+ d="M 7.2658469,16.715404 C 5.7649488,16.675487 4.5620394,15.54068 4.6171056,13.608982 c 5.308e-4,-0.01798 6.304e-4,-0.03602 0.00143,-0.05392 -0.012645,1.523617 1.1563015,2.816807 2.6397578,2.856266 1.4834547,0.03946 2.7588626,-1.030656 2.7982786,-2.711623 -1.32e-4,0.01791 -9.95e-4,0.03592 -0.0014,0.05392 -0.04665,1.892408 -1.288397,3.001702 -2.7892953,2.961779 z"
+ sodipodi:nodetypes="sscscss" />
+ <path
+ inkscape:transform-center-y="-1.2783355"
+ inkscape:transform-center-x="-0.17825997"
+ sodipodi:nodetypes="sscscss"
+ d="m 7.4112441,10.857057 c 1.5008986,0.03992 2.6914499,1.247371 2.6363839,3.17907 -5.31e-4,0.01798 -6.3e-4,0.03602 -0.0014,0.05392 0.01265,-1.523619 -1.157134,-2.785558 -2.64059,-2.825015 -1.483455,-0.03946 -2.7580303,0.999402 -2.7974484,2.680369 1.338e-4,-0.01792 9.953e-4,-0.03592 0.00143,-0.05392 0.046652,-1.892406 1.3007552,-3.074348 2.8016531,-3.034427 z"
+ inkscape:connector-curvature="0"
+ id="path3893"
+ style="opacity:0.15;fill:#000000;fill-opacity:1;stroke:none;display:inline" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path4021"
+ d="M 25.559837,19.375241 C 20.943325,18.463676 12.732572,16.97967 12.732572,16.97967 l 0.577198,0.271705 11.631124,2.455147 z"
+ style="opacity:0.75;fill:#ffffff;fill-opacity:1;stroke:none;display:inline"
+ sodipodi:nodetypes="ccccc" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path4023"
+ d="M 12.732978,16.998382 13.18315,17.05794 20.372067,6.4504795 19.892575,6.6437071 z"
+ style="opacity:0.15;fill:#000000;fill-opacity:1;stroke:none;display:inline"
+ sodipodi:nodetypes="ccccc" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ style="opacity:0.15;fill:#000000;fill-opacity:1;stroke:none;display:inline"
+ d="m 17.616917,15.427399 -0.536605,0.241627 12.450679,2.340457 0.07314,-0.349773 z"
+ id="path4025"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ style="opacity:0.75;fill:#ffffff;fill-opacity:1;stroke:none;display:inline"
+ d="m 24.020288,5.3820561 -6.978623,10.2909549 0.572778,-0.25839 6.676265,-9.8824969 z"
+ id="path4027"
+ inkscape:connector-curvature="0" />
+</svg>
diff --git a/resources/gnome-pie.desktop b/resources/gnome-pie.desktop
new file mode 100755
index 0000000..ae5811d
--- /dev/null
+++ b/resources/gnome-pie.desktop
@@ -0,0 +1,7 @@
+[Desktop Entry]
+Type=Application
+Name=Gnome-Pie
+Comment=Cakes don't lie.
+Exec=gnome-pie
+Icon=gnome-pie
+Categories=GNOME;Utility;
diff --git a/resources/gnome-pie.svg b/resources/gnome-pie.svg
new file mode 100644
index 0000000..c001a21
--- /dev/null
+++ b/resources/gnome-pie.svg
@@ -0,0 +1,2896 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="256"
+ height="256"
+ id="svg2"
+ version="1.1"
+ inkscape:version="0.48.1 r9760"
+ sodipodi:docname="gnome-pie.svg">
+ <defs
+ id="defs4">
+ <linearGradient
+ gradientTransform="matrix(1.0238095,0,0,1.0119048,-1.1428571,-98.071429)"
+ gradientUnits="userSpaceOnUse"
+ xlink:href="#ButtonShadow-0"
+ id="linearGradient2918"
+ y2="90.238609"
+ x2="32.251034"
+ y1="6.1317081"
+ x1="32.251034" />
+ <linearGradient
+ gradientTransform="translate(0,-97)"
+ gradientUnits="userSpaceOnUse"
+ xlink:href="#ButtonShadow-0"
+ id="linearGradient3721"
+ y2="90.238609"
+ x2="32.251034"
+ y1="6.1317081"
+ x1="32.251034" />
+ <linearGradient
+ gradientTransform="matrix(1.0238095,0,0,1.0119048,-1.1428571,-98.071429)"
+ gradientUnits="userSpaceOnUse"
+ xlink:href="#ButtonShadow-0"
+ id="linearGradient3725"
+ y2="90.238609"
+ x2="32.251034"
+ y1="6.1317081"
+ x1="32.251034" />
+ <linearGradient
+ gradientTransform="matrix(1.0238095,0,0,1.0119048,-1.1428571,-98.071429)"
+ gradientUnits="userSpaceOnUse"
+ xlink:href="#ButtonShadow-0"
+ id="linearGradient3772"
+ y2="90.238609"
+ x2="32.251034"
+ y1="6.1317081"
+ x1="32.251034" />
+ <linearGradient
+ gradientTransform="matrix(1.0238095,0,0,1.0119048,-1.1428571,-98.071429)"
+ gradientUnits="userSpaceOnUse"
+ xlink:href="#ButtonShadow-0"
+ id="linearGradient3780"
+ y2="90.238609"
+ x2="32.251034"
+ y1="6.1317081"
+ x1="32.251034" />
+ <linearGradient
+ gradientTransform="matrix(1.0058652,0,0,0.994169,100,0)"
+ gradientUnits="userSpaceOnUse"
+ id="ButtonShadow-0"
+ y2="7.0165396"
+ x2="45.447727"
+ y1="92.539597"
+ x1="45.447727">
+ <stop
+ offset="0"
+ style="stop-color:#000000;stop-opacity:1"
+ id="stop3750-8" />
+ <stop
+ offset="1"
+ style="stop-color:#000000;stop-opacity:0.58823532"
+ id="stop3752-5" />
+ </linearGradient>
+ <linearGradient
+ gradientUnits="userSpaceOnUse"
+ xlink:href="#linearGradient3761"
+ id="linearGradient3817"
+ y2="46.568573"
+ x2="46.604744"
+ y1="64.036171"
+ x1="64.072342" />
+ <filter
+ id="filter3987"
+ color-interpolation-filters="sRGB">
+ <feGaussianBlur
+ stdDeviation="0.42020394"
+ id="feGaussianBlur3989" />
+ </filter>
+ <linearGradient
+ gradientTransform="matrix(0.72592593,-0.72592593,0.72592593,0.72592593,-20.03897,99.25749)"
+ gradientUnits="userSpaceOnUse"
+ xlink:href="#linearGradient3871"
+ id="linearGradient3981"
+ y2="40.483921"
+ x2="61.802849"
+ y1="61.183025"
+ x1="53.034939" />
+ <linearGradient
+ gradientTransform="matrix(0,-1.0266143,1.0266143,0,0.77836254,147)"
+ gradientUnits="userSpaceOnUse"
+ xlink:href="#linearGradient3861"
+ id="linearGradient3979"
+ y2="60.715324"
+ x2="52.881298"
+ y1="39.683075"
+ x1="61.628212" />
+ <linearGradient
+ gradientTransform="matrix(-0.72592593,-0.72592593,0.72592593,-0.72592593,49.25749,166.03897)"
+ gradientUnits="userSpaceOnUse"
+ xlink:href="#linearGradient3851"
+ id="linearGradient3977"
+ y2="39.70118"
+ x2="60.324341"
+ y1="59.878456"
+ x1="53.469795" />
+ <linearGradient
+ gradientTransform="matrix(-1.0266143,0,0,-1.0266143,96.999997,145.22164)"
+ gradientUnits="userSpaceOnUse"
+ xlink:href="#linearGradient3921"
+ id="linearGradient3975"
+ y2="39.683075"
+ x2="60.999012"
+ y1="61.330303"
+ x1="53.87949" />
+ <linearGradient
+ gradientTransform="matrix(-0.72592593,0.72592593,-0.72592593,-0.72592593,116.03897,96.742509)"
+ gradientUnits="userSpaceOnUse"
+ xlink:href="#linearGradient3911"
+ id="linearGradient3973"
+ y2="40.223007"
+ x2="61.88982"
+ y1="59.182693"
+ x1="53.295853" />
+ <linearGradient
+ gradientTransform="matrix(0,1.0266143,-1.0266143,0,95.221638,49.000001)"
+ gradientUnits="userSpaceOnUse"
+ xlink:href="#linearGradient3901"
+ id="linearGradient3971"
+ y2="39.437084"
+ x2="61.982975"
+ y1="60.34634"
+ x1="53.387505" />
+ <linearGradient
+ gradientTransform="matrix(0.72592593,0.72592593,-0.72592593,0.72592593,46.742509,29.961028)"
+ gradientUnits="userSpaceOnUse"
+ xlink:href="#linearGradient3891"
+ id="linearGradient3969"
+ y2="38.831467"
+ x2="62.58559"
+ y1="60.139374"
+ x1="53.730709" />
+ <linearGradient
+ gradientTransform="matrix(1.0266143,0,0,1.0266143,-0.9999987,50.778362)"
+ gradientUnits="userSpaceOnUse"
+ xlink:href="#linearGradient3881"
+ id="linearGradient3967"
+ y2="39.92907"
+ x2="61.49099"
+ y1="59.608364"
+ x1="53.510502" />
+ <filter
+ id="filter3774"
+ color-interpolation-filters="sRGB">
+ <feGaussianBlur
+ stdDeviation="0.27274118"
+ id="feGaussianBlur3776" />
+ </filter>
+ <radialGradient
+ gradientTransform="matrix(1,0,0,0.61803397,0,19.862234)"
+ gradientUnits="userSpaceOnUse"
+ xlink:href="#linearGradient3797"
+ id="radialGradient3803"
+ fy="52"
+ fx="41"
+ r="9.7082043"
+ cy="52"
+ cx="41" />
+ <linearGradient
+ gradientUnits="userSpaceOnUse"
+ xlink:href="#linearGradient3761"
+ id="linearGradient3791"
+ y2="41.697067"
+ x2="40.068184"
+ y1="58.17598"
+ x1="40.068184" />
+ <linearGradient
+ gradientUnits="userSpaceOnUse"
+ xlink:href="#linearGradient3761"
+ id="linearGradient3779"
+ y2="41.697067"
+ x2="40.068184"
+ y1="58.17598"
+ x1="40.068184" />
+ <linearGradient
+ gradientUnits="userSpaceOnUse"
+ xlink:href="#linearGradient3761"
+ id="linearGradient3775"
+ y2="41.697067"
+ x2="40.068184"
+ y1="58.17598"
+ x1="40.068184" />
+ <linearGradient
+ gradientUnits="userSpaceOnUse"
+ xlink:href="#linearGradient3761"
+ id="linearGradient3771"
+ y2="41.697067"
+ x2="40.068184"
+ y1="58.17598"
+ x1="40.068184" />
+ <linearGradient
+ gradientUnits="userSpaceOnUse"
+ xlink:href="#linearGradient3761"
+ id="linearGradient3767"
+ y2="49.665066"
+ x2="31.793724"
+ y1="58.17598"
+ x1="40.068184" />
+ <linearGradient
+ gradientUnits="userSpaceOnUse"
+ xlink:href="#linearGradient3727"
+ id="linearGradient3733"
+ y2="45.997448"
+ x2="67.957489"
+ y1="45.997448"
+ x1="33.199345" />
+ <radialGradient
+ gradientUnits="userSpaceOnUse"
+ xlink:href="#linearGradient3681"
+ id="radialGradient3687"
+ fy="45.997448"
+ fx="47.729706"
+ r="13.637059"
+ cy="45.997448"
+ cx="47.729706" />
+ <filter
+ id="filter3833"
+ color-interpolation-filters="sRGB"
+ height="1.48"
+ width="1.48"
+ y="-0.24000001"
+ x="-0.23999999">
+ <feGaussianBlur
+ stdDeviation="2.8000002"
+ id="feGaussianBlur3835" />
+ </filter>
+ <clipPath
+ id="clipPath3798">
+ <path
+ style="fill:#ff00ff;fill-opacity:1;stroke:none"
+ id="path3800"
+ transform="matrix(1.0266143,0,0,1.0266143,-0.999999,0.778362)"
+ d="m 61.366765,45.997448 a 13.637059,13.637059 0 1 1 -27.274118,0 13.637059,13.637059 0 1 1 27.274118,0 z" />
+ </clipPath>
+ <linearGradient
+ gradientUnits="userSpaceOnUse"
+ xlink:href="#linearGradient3746"
+ id="linearGradient3744"
+ y2="44.48222"
+ x2="76.771591"
+ y1="44.48222"
+ x1="16.162441" />
+ <radialGradient
+ gradientTransform="matrix(1,0,0,0.99996543,0,0.00165947)"
+ gradientUnits="userSpaceOnUse"
+ xlink:href="#linearGradient3732"
+ id="radialGradient3738"
+ fy="48.000935"
+ fx="48"
+ r="27.001867"
+ cy="48.000935"
+ cx="48" />
+ <linearGradient
+ gradientUnits="userSpaceOnUse"
+ xlink:href="#linearGradient3650"
+ id="linearGradient3707"
+ y2="44.48222"
+ x2="76.771591"
+ y1="44.48222"
+ x1="16.162441" />
+ <linearGradient
+ gradientUnits="userSpaceOnUse"
+ xlink:href="#linearGradient3719"
+ id="linearGradient3674"
+ y2="44.48222"
+ x2="76.771591"
+ y1="44.48222"
+ x1="16.162441" />
+ <linearGradient
+ gradientUnits="userSpaceOnUse"
+ xlink:href="#linearGradient3664"
+ id="linearGradient3670"
+ y2="52.098946"
+ x2="76.838295"
+ y1="52.098946"
+ x1="16.162441" />
+ <linearGradient
+ gradientUnits="userSpaceOnUse"
+ xlink:href="#linearGradient3641"
+ id="linearGradient3617"
+ y2="5.9877172"
+ x2="48"
+ y1="90"
+ x1="48" />
+ <clipPath
+ id="clipPath3613">
+ <rect
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ id="rect3615"
+ y="6"
+ x="6"
+ ry="6"
+ rx="6"
+ height="84"
+ width="84" />
+ </clipPath>
+ <radialGradient
+ gradientTransform="matrix(1.1573129,0,0,0.99590774,-7.5510206,0.19713193)"
+ gradientUnits="userSpaceOnUse"
+ xlink:href="#linearGradient3737"
+ id="radialGradient3619"
+ fy="90.171875"
+ fx="48"
+ r="42"
+ cy="90.171875"
+ cx="48" />
+ <linearGradient
+ gradientUnits="userSpaceOnUse"
+ xlink:href="#linearGradient3737"
+ id="linearGradient3613"
+ y2="138.66119"
+ x2="48"
+ y1="20.220806"
+ x1="48" />
+ <filter
+ id="filter3794"
+ color-interpolation-filters="sRGB"
+ height="1.3839999"
+ width="1.3839999"
+ y="-0.192"
+ x="-0.192">
+ <feGaussianBlur
+ stdDeviation="5.28"
+ id="feGaussianBlur3796" />
+ </filter>
+ <linearGradient
+ gradientUnits="userSpaceOnUse"
+ xlink:href="#linearGradient3737"
+ id="linearGradient3188"
+ y2="63.893143"
+ x2="36.357143"
+ y1="6"
+ x1="36.357143" />
+ <filter
+ id="filter3174"
+ color-interpolation-filters="sRGB">
+ <feGaussianBlur
+ stdDeviation="1.71"
+ id="feGaussianBlur3176" />
+ </filter>
+ <linearGradient
+ id="linearGradient3737">
+ <stop
+ offset="0"
+ style="stop-color:#ffffff;stop-opacity:1"
+ id="stop3739" />
+ <stop
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:0"
+ id="stop3741" />
+ </linearGradient>
+ <linearGradient
+ gradientTransform="scale(1.0058652,0.994169)"
+ gradientUnits="userSpaceOnUse"
+ id="ButtonShadow"
+ y2="7.0165396"
+ x2="45.447727"
+ y1="92.539597"
+ x1="45.447727">
+ <stop
+ offset="0"
+ style="stop-color:#000000;stop-opacity:1"
+ id="stop3750" />
+ <stop
+ offset="1"
+ style="stop-color:#000000;stop-opacity:0.58823532"
+ id="stop3752" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3641">
+ <stop
+ offset="0"
+ style="stop-color:#bdb8c4;stop-opacity:1"
+ id="stop3643" />
+ <stop
+ offset="1"
+ style="stop-color:#dbd9df;stop-opacity:1"
+ id="stop3645" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3650">
+ <stop
+ offset="0"
+ style="stop-color:#141414;stop-opacity:1"
+ id="stop3709" />
+ <stop
+ offset="1"
+ style="stop-color:#616161;stop-opacity:1"
+ id="stop3654" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3664">
+ <stop
+ offset="0"
+ style="stop-color:#000000;stop-opacity:0.29838711"
+ id="stop3666" />
+ <stop
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:0.64516127"
+ id="stop3668" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3719">
+ <stop
+ offset="0"
+ style="stop-color:#4b4b4b;stop-opacity:1"
+ id="stop3721" />
+ <stop
+ offset="0.37373093"
+ style="stop-color:#232323;stop-opacity:1"
+ id="stop3723" />
+ <stop
+ offset="1"
+ style="stop-color:#5c5c5c;stop-opacity:1"
+ id="stop3725" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3732">
+ <stop
+ offset="0"
+ style="stop-color:#000000;stop-opacity:0"
+ id="stop3734" />
+ <stop
+ offset="0.94999999"
+ style="stop-color:#000000;stop-opacity:0"
+ id="stop3740" />
+ <stop
+ offset="1"
+ style="stop-color:#000000;stop-opacity:1"
+ id="stop3736" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3746">
+ <stop
+ offset="0"
+ style="stop-color:#5d5d5d;stop-opacity:1"
+ id="stop3748" />
+ <stop
+ offset="0.60000002"
+ style="stop-color:#0a0a0a;stop-opacity:1"
+ id="stop3753" />
+ <stop
+ offset="1"
+ style="stop-color:#4e4e4e;stop-opacity:1"
+ id="stop3751" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3681">
+ <stop
+ offset="0"
+ style="stop-color:#ffffff;stop-opacity:0.18548387"
+ id="stop3683" />
+ <stop
+ offset="0.3086735"
+ style="stop-color:#ffffff;stop-opacity:0.10887097"
+ id="stop3689" />
+ <stop
+ offset="0.43622452"
+ style="stop-color:#000000;stop-opacity:0"
+ id="stop3691" />
+ <stop
+ offset="0.54464293"
+ style="stop-color:#000000;stop-opacity:0"
+ id="stop3693" />
+ <stop
+ offset="0.58290821"
+ style="stop-color:#ffffff;stop-opacity:0"
+ id="stop3695" />
+ <stop
+ offset="0.61479598"
+ style="stop-color:#000000;stop-opacity:0.1814516"
+ id="stop3697" />
+ <stop
+ offset="0.69132656"
+ style="stop-color:#000000;stop-opacity:0.43145162"
+ id="stop3699" />
+ <stop
+ offset="0.78061229"
+ style="stop-color:#ffffff;stop-opacity:0.08064516"
+ id="stop3701" />
+ <stop
+ offset="0.87627554"
+ style="stop-color:#000000;stop-opacity:0"
+ id="stop3703" />
+ <stop
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:0"
+ id="stop3685" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3727">
+ <stop
+ offset="0"
+ style="stop-color:#ffffff;stop-opacity:1"
+ id="stop3729" />
+ <stop
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:0"
+ id="stop3731" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3761">
+ <stop
+ offset="0"
+ style="stop-color:#ffffff;stop-opacity:1"
+ id="stop3763" />
+ <stop
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:0"
+ id="stop3765" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3797">
+ <stop
+ offset="0"
+ style="stop-color:#ffffff;stop-opacity:1"
+ id="stop3799" />
+ <stop
+ offset="0.5"
+ style="stop-color:#ffffff;stop-opacity:1"
+ id="stop3805" />
+ <stop
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:0"
+ id="stop3801" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3851">
+ <stop
+ offset="0"
+ style="stop-color:#55d400;stop-opacity:0"
+ id="stop3853" />
+ <stop
+ offset="0.5"
+ style="stop-color:#55d400;stop-opacity:1"
+ id="stop3859" />
+ <stop
+ offset="1"
+ style="stop-color:#55d400;stop-opacity:0"
+ id="stop3855" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3861">
+ <stop
+ offset="0"
+ style="stop-color:#ffcc00;stop-opacity:0"
+ id="stop3863" />
+ <stop
+ offset="0.5"
+ style="stop-color:#ffcc00;stop-opacity:1"
+ id="stop3869" />
+ <stop
+ offset="1"
+ style="stop-color:#ffcc00;stop-opacity:0"
+ id="stop3865" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3871">
+ <stop
+ offset="0"
+ style="stop-color:#ff6600;stop-opacity:0"
+ id="stop3873" />
+ <stop
+ offset="0.5"
+ style="stop-color:#ff6600;stop-opacity:1"
+ id="stop3879" />
+ <stop
+ offset="1"
+ style="stop-color:#ff6600;stop-opacity:0"
+ id="stop3875" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3881">
+ <stop
+ offset="0"
+ style="stop-color:#d40000;stop-opacity:0"
+ id="stop3883" />
+ <stop
+ offset="0.5"
+ style="stop-color:#d40000;stop-opacity:1"
+ id="stop3889" />
+ <stop
+ offset="1"
+ style="stop-color:#d40000;stop-opacity:0"
+ id="stop3885" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3891">
+ <stop
+ offset="0"
+ style="stop-color:#d42aff;stop-opacity:0"
+ id="stop3893" />
+ <stop
+ offset="0.5"
+ style="stop-color:#d42aff;stop-opacity:1"
+ id="stop3899" />
+ <stop
+ offset="1"
+ style="stop-color:#d42aff;stop-opacity:0"
+ id="stop3895" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3901">
+ <stop
+ offset="0"
+ style="stop-color:#6600ff;stop-opacity:0"
+ id="stop3903" />
+ <stop
+ offset="0.5"
+ style="stop-color:#6600ff;stop-opacity:1"
+ id="stop3909" />
+ <stop
+ offset="1"
+ style="stop-color:#6600ff;stop-opacity:0"
+ id="stop3905" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3911">
+ <stop
+ offset="0"
+ style="stop-color:#2a7fff;stop-opacity:0"
+ id="stop3913" />
+ <stop
+ offset="0.5"
+ style="stop-color:#2a7fff;stop-opacity:1"
+ id="stop3919" />
+ <stop
+ offset="1"
+ style="stop-color:#2a7fff;stop-opacity:0"
+ id="stop3915" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3921">
+ <stop
+ offset="0"
+ style="stop-color:#5fd3bc;stop-opacity:0"
+ id="stop3923" />
+ <stop
+ offset="0.5"
+ style="stop-color:#5fd3bc;stop-opacity:1"
+ id="stop3929" />
+ <stop
+ offset="1"
+ style="stop-color:#5fd3bc;stop-opacity:0"
+ id="stop3925" />
+ </linearGradient>
+ <linearGradient
+ gradientTransform="matrix(1.0238095,0,0,1.0119048,-1.1428571,-98.071429)"
+ gradientUnits="userSpaceOnUse"
+ xlink:href="#ButtonShadow-0-1"
+ id="linearGradient2969"
+ y2="90.238609"
+ x2="32.251034"
+ y1="6.1317081"
+ x1="32.251034" />
+ <linearGradient
+ gradientTransform="matrix(1.0238095,0,0,1.0119048,-1.1428571,-98.071429)"
+ gradientUnits="userSpaceOnUse"
+ xlink:href="#ButtonShadow-0-1"
+ id="linearGradient3780-1"
+ y2="90.238609"
+ x2="32.251034"
+ y1="6.1317081"
+ x1="32.251034" />
+ <linearGradient
+ gradientTransform="matrix(1.0238095,0,0,1.0119048,-1.1428571,-98.071429)"
+ gradientUnits="userSpaceOnUse"
+ xlink:href="#ButtonShadow-0-1"
+ id="linearGradient3772-2"
+ y2="90.238609"
+ x2="32.251034"
+ y1="6.1317081"
+ x1="32.251034" />
+ <linearGradient
+ gradientTransform="matrix(1.0238095,0,0,1.0119048,-1.1428571,-98.071429)"
+ gradientUnits="userSpaceOnUse"
+ xlink:href="#ButtonShadow-0-1"
+ id="linearGradient3725-0"
+ y2="90.238609"
+ x2="32.251034"
+ y1="6.1317081"
+ x1="32.251034" />
+ <linearGradient
+ gradientTransform="matrix(1.0058652,0,0,0.994169,100,0)"
+ gradientUnits="userSpaceOnUse"
+ id="ButtonShadow-0-1"
+ y2="7.0165396"
+ x2="45.447727"
+ y1="92.539597"
+ x1="45.447727">
+ <stop
+ offset="0"
+ style="stop-color:#000000;stop-opacity:1"
+ id="stop3750-8-6" />
+ <stop
+ offset="1"
+ style="stop-color:#000000;stop-opacity:0.58823532"
+ id="stop3752-5-3" />
+ </linearGradient>
+ <linearGradient
+ gradientTransform="translate(0,-97)"
+ gradientUnits="userSpaceOnUse"
+ xlink:href="#ButtonShadow-0-1"
+ id="linearGradient3721-2"
+ y2="90.238609"
+ x2="32.251034"
+ y1="6.1317081"
+ x1="32.251034" />
+ <linearGradient
+ gradientTransform="translate(0,-96)"
+ gradientUnits="userSpaceOnUse"
+ xlink:href="#linearGradient3224"
+ id="linearGradient3757"
+ y2="5.9877172"
+ x2="48"
+ y1="90"
+ x1="48" />
+ <linearGradient
+ id="linearGradient3224">
+ <stop
+ offset="0"
+ style="stop-color:#80a2c8;stop-opacity:1"
+ id="stop3226" />
+ <stop
+ offset="1"
+ style="stop-color:#2e4c6d;stop-opacity:1"
+ id="stop3228" />
+ </linearGradient>
+ <linearGradient
+ gradientTransform="matrix(-1,0,0,-1,91.080609,91.12006)"
+ gradientUnits="userSpaceOnUse"
+ xlink:href="#linearGradient3932"
+ id="linearGradient3938"
+ y2="45.617771"
+ x2="42.662289"
+ y1="48.267761"
+ x1="45.312279" />
+ <linearGradient
+ gradientTransform="matrix(0.44988627,0,0,0.44988627,-7.7869415e-6,-94.532869)"
+ gradientUnits="userSpaceOnUse"
+ xlink:href="#linearGradient5128"
+ id="linearGradient3916"
+ y2="66.807335"
+ x2="-6.5244856"
+ y1="62.878765"
+ x1="5.2744913" />
+ <linearGradient
+ gradientUnits="userSpaceOnUse"
+ xlink:href="#linearGradient5128"
+ id="linearGradient3887"
+ y2="66.807335"
+ x2="-6.5244856"
+ y1="62.878765"
+ x1="5.2744913" />
+ <linearGradient
+ gradientUnits="userSpaceOnUse"
+ xlink:href="#linearGradient3309"
+ id="linearGradient3879"
+ y2="47.535378"
+ x2="36.821369"
+ y1="21.650217"
+ x1="32.237946" />
+ <linearGradient
+ gradientTransform="matrix(0.5,0.8660254,-0.8660254,0.5,91.523702,-24.523702)"
+ gradientUnits="userSpaceOnUse"
+ xlink:href="#linearGradient3865"
+ id="linearGradient3871-2"
+ y2="69.230995"
+ x2="69.693596"
+ y1="66.836105"
+ x1="60.755741" />
+ <radialGradient
+ gradientTransform="matrix(2.3125312,2.3348434,1.2717514,-1.2595982,-125.14605,4.532606)"
+ gradientUnits="userSpaceOnUse"
+ xlink:href="#linearGradient3751"
+ id="radialGradient3811"
+ fy="54.10635"
+ fx="47.644325"
+ r="4.8616066"
+ cy="54.10635"
+ cx="47.644325" />
+ <linearGradient
+ gradientUnits="userSpaceOnUse"
+ xlink:href="#linearGradient3724"
+ id="linearGradient3800"
+ y2="52.871964"
+ x2="59.574085"
+ y1="71.888321"
+ x1="64.669502" />
+ <radialGradient
+ gradientTransform="matrix(-0.01155242,1.9830883,-2.0305783,-0.02269268,158.07483,-40.252061)"
+ gradientUnits="userSpaceOnUse"
+ xlink:href="#linearGradient3777"
+ id="radialGradient3791"
+ fy="53.8909"
+ fx="48.089584"
+ r="5.4927044"
+ cy="53.8909"
+ cx="48.089584" />
+ <linearGradient
+ gradientUnits="userSpaceOnUse"
+ xlink:href="#linearGradient3741"
+ id="linearGradient3747"
+ y2="64.307716"
+ x2="54.767216"
+ y1="44.039856"
+ x1="52.51516" />
+ <linearGradient
+ gradientUnits="userSpaceOnUse"
+ xlink:href="#linearGradient3700-4"
+ id="linearGradient2977"
+ y2="5.9877172"
+ x2="48"
+ y1="90"
+ x1="48" />
+ <clipPath
+ id="clipPath2973">
+ <rect
+ style="fill:url(#linearGradient2977);fill-opacity:1;fill-rule:nonzero;stroke:none"
+ id="rect2975"
+ y="6"
+ x="6"
+ ry="6"
+ rx="6"
+ height="84"
+ width="84" />
+ </clipPath>
+ <linearGradient
+ id="linearGradient3700-4">
+ <stop
+ offset="0"
+ style="stop-color:#70a83e;stop-opacity:1"
+ id="stop3702-4" />
+ <stop
+ offset="1"
+ style="stop-color:#9fd058;stop-opacity:1"
+ id="stop3704-4" />
+ </linearGradient>
+ <linearGradient
+ gradientUnits="userSpaceOnUse"
+ xlink:href="#linearGradient3700"
+ id="linearGradient3878"
+ y2="5.9877172"
+ x2="48"
+ y1="90"
+ x1="48" />
+ <filter
+ id="filter3814"
+ color-interpolation-filters="sRGB">
+ <feGaussianBlur
+ stdDeviation="2.1999956"
+ id="feGaussianBlur3816" />
+ </filter>
+ <linearGradient
+ gradientTransform="matrix(1.2790652,0,0,1.2790652,17.302433,18.5815)"
+ gradientUnits="userSpaceOnUse"
+ xlink:href="#linearGradient3397"
+ id="linearGradient3806"
+ y2="45"
+ x2="37.201294"
+ y1="1"
+ x1="37.201294" />
+ <linearGradient
+ gradientTransform="matrix(1.2790652,0,0,1.2790652,17.302433,18.5815)"
+ gradientUnits="userSpaceOnUse"
+ xlink:href="#linearGradient3309"
+ id="linearGradient3804"
+ y2="45.017357"
+ x2="20.758585"
+ y1="1"
+ x1="20.758585" />
+ <linearGradient
+ gradientTransform="matrix(0.41503146,0,0,0.41503146,21.437996,21.853023)"
+ gradientUnits="userSpaceOnUse"
+ xlink:href="#linearGradient5128"
+ id="linearGradient3801"
+ y2="20.895"
+ x2="84.63858"
+ y1="105.105"
+ x1="86.132919" />
+ <linearGradient
+ id="linearGradient3397">
+ <stop
+ offset="0"
+ style="stop-color:#aaaaaa;stop-opacity:1"
+ id="stop3399" />
+ <stop
+ offset="1"
+ style="stop-color:#8c8c8c;stop-opacity:1"
+ id="stop3401" />
+ </linearGradient>
+ <linearGradient
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient3309"
+ y2="122.8994"
+ x2="63.9995"
+ y1="3.1001"
+ x1="63.9995">
+ <stop
+ offset="0"
+ style="stop-color:#f6f6f6;stop-opacity:1"
+ id="stop3311" />
+ <stop
+ offset="1"
+ style="stop-color:#d2d2d2;stop-opacity:1"
+ id="stop3313" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient5128">
+ <stop
+ offset="0"
+ style="stop-color:#e5e5e5;stop-opacity:1"
+ id="stop5130" />
+ <stop
+ offset="1"
+ style="stop-color:#ababab;stop-opacity:1"
+ id="stop5132" />
+ </linearGradient>
+ <linearGradient
+ gradientUnits="userSpaceOnUse"
+ xlink:href="#linearGradient3700"
+ id="linearGradient3617-7"
+ y2="5.9877172"
+ x2="48"
+ y1="90"
+ x1="48" />
+ <clipPath
+ id="clipPath3613-7">
+ <rect
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ id="rect3615-9"
+ y="6"
+ x="6"
+ ry="6"
+ rx="6"
+ height="84"
+ width="84" />
+ </clipPath>
+ <radialGradient
+ gradientTransform="matrix(1.1573129,0,0,0.99590774,-7.5510206,0.19713193)"
+ gradientUnits="userSpaceOnUse"
+ xlink:href="#linearGradient3737-5"
+ id="radialGradient3619-4"
+ fy="90.171875"
+ fx="48"
+ r="42"
+ cy="90.171875"
+ cx="48" />
+ <linearGradient
+ gradientUnits="userSpaceOnUse"
+ xlink:href="#linearGradient3737-5"
+ id="linearGradient3613-6"
+ y2="138.66119"
+ x2="48"
+ y1="20.220806"
+ x1="48" />
+ <filter
+ id="filter3794-7"
+ color-interpolation-filters="sRGB"
+ height="1.3839999"
+ width="1.3839999"
+ y="-0.192"
+ x="-0.192">
+ <feGaussianBlur
+ stdDeviation="5.28"
+ id="feGaussianBlur3796-3" />
+ </filter>
+ <linearGradient
+ gradientUnits="userSpaceOnUse"
+ xlink:href="#linearGradient3737-5"
+ id="linearGradient3188-2"
+ y2="63.893143"
+ x2="36.357143"
+ y1="6"
+ x1="36.357143" />
+ <filter
+ id="filter3174-5"
+ color-interpolation-filters="sRGB">
+ <feGaussianBlur
+ stdDeviation="1.71"
+ id="feGaussianBlur3176-9" />
+ </filter>
+ <linearGradient
+ id="linearGradient3700">
+ <stop
+ offset="0"
+ style="stop-color:#70a83e;stop-opacity:1"
+ id="stop3702" />
+ <stop
+ offset="1"
+ style="stop-color:#9fd058;stop-opacity:1"
+ id="stop3704" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3737-5">
+ <stop
+ offset="0"
+ style="stop-color:#ffffff;stop-opacity:1"
+ id="stop3739-7" />
+ <stop
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:0"
+ id="stop3741-8" />
+ </linearGradient>
+ <linearGradient
+ gradientTransform="scale(1.0058652,0.994169)"
+ gradientUnits="userSpaceOnUse"
+ id="ButtonShadow-4"
+ y2="7.0165396"
+ x2="45.447727"
+ y1="92.539597"
+ x1="45.447727">
+ <stop
+ offset="0"
+ style="stop-color:#000000;stop-opacity:1"
+ id="stop3750-1" />
+ <stop
+ offset="1"
+ style="stop-color:#000000;stop-opacity:0.58823532"
+ id="stop3752-6" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3724">
+ <stop
+ offset="0"
+ style="stop-color:#ffa92a;stop-opacity:1"
+ id="stop3726" />
+ <stop
+ offset="1"
+ style="stop-color:#ffcf2a;stop-opacity:1"
+ id="stop3728" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3741">
+ <stop
+ offset="0"
+ style="stop-color:#ffffff;stop-opacity:1"
+ id="stop3743" />
+ <stop
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:0"
+ id="stop3745" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3751">
+ <stop
+ offset="0"
+ style="stop-color:#f89400;stop-opacity:1"
+ id="stop3753-2" />
+ <stop
+ offset="1"
+ style="stop-color:#f89400;stop-opacity:0"
+ id="stop3755" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3777">
+ <stop
+ offset="0"
+ style="stop-color:#ff6600;stop-opacity:1"
+ id="stop3779" />
+ <stop
+ offset="1"
+ style="stop-color:#ff6600;stop-opacity:0"
+ id="stop3781" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3865">
+ <stop
+ offset="0"
+ style="stop-color:#ffe99d;stop-opacity:1"
+ id="stop3867" />
+ <stop
+ offset="1"
+ style="stop-color:#ffe99d;stop-opacity:0"
+ id="stop3869-7" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3932">
+ <stop
+ offset="0"
+ style="stop-color:#000000;stop-opacity:1"
+ id="stop3934" />
+ <stop
+ offset="1"
+ style="stop-color:#000000;stop-opacity:0"
+ id="stop3936" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#ButtonShadow-4"
+ id="linearGradient4585"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="scale(1.0058652,0.994169)"
+ x1="45.447727"
+ y1="92.539597"
+ x2="45.447727"
+ y2="7.0165396" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#ButtonShadow-0-1"
+ id="linearGradient4587"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.0238095,0,0,1.0119048,-1.1428571,-98.071429)"
+ x1="32.251034"
+ y1="6.1317081"
+ x2="32.251034"
+ y2="90.238609" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#ButtonShadow-0-1"
+ id="linearGradient4589"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.0238095,0,0,1.0119048,-1.1428571,-98.071429)"
+ x1="32.251034"
+ y1="6.1317081"
+ x2="32.251034"
+ y2="90.238609" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#ButtonShadow-0-1"
+ id="linearGradient4591"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.0238095,0,0,1.0119048,-1.1428571,-98.071429)"
+ x1="32.251034"
+ y1="6.1317081"
+ x2="32.251034"
+ y2="90.238609" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#ButtonShadow-0-1"
+ id="linearGradient4593"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.0238095,0,0,1.0119048,-1.1428571,-98.071429)"
+ x1="32.251034"
+ y1="6.1317081"
+ x2="32.251034"
+ y2="90.238609" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#ButtonShadow-0-1"
+ id="linearGradient4595"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,-97)"
+ x1="32.251034"
+ y1="6.1317081"
+ x2="32.251034"
+ y2="90.238609" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3224"
+ id="linearGradient4597"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,-96)"
+ x1="48"
+ y1="90"
+ x2="48"
+ y2="5.9877172" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3737-5"
+ id="linearGradient4599"
+ gradientUnits="userSpaceOnUse"
+ x1="36.357143"
+ y1="6"
+ x2="36.357143"
+ y2="63.893143" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3737-5"
+ id="radialGradient4601"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.1573129,0,0,0.99590774,-7.5510206,0.19713193)"
+ cx="48"
+ cy="90.171875"
+ fx="48"
+ fy="90.171875"
+ r="42" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3700"
+ id="linearGradient4603"
+ gradientUnits="userSpaceOnUse"
+ x1="48"
+ y1="90"
+ x2="48"
+ y2="5.9877172" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3700"
+ id="linearGradient4605"
+ gradientUnits="userSpaceOnUse"
+ x1="48"
+ y1="90"
+ x2="48"
+ y2="5.9877172" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3737-5"
+ id="linearGradient4607"
+ gradientUnits="userSpaceOnUse"
+ x1="48"
+ y1="20.220806"
+ x2="48"
+ y2="138.66119" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3309"
+ id="linearGradient4609"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.2790652,0,0,1.2790652,17.302433,18.5815)"
+ x1="20.758585"
+ y1="1"
+ x2="20.758585"
+ y2="45.017357" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3397"
+ id="linearGradient4611"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.2790652,0,0,1.2790652,17.302433,18.5815)"
+ x1="37.201294"
+ y1="1"
+ x2="37.201294"
+ y2="45" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5128"
+ id="linearGradient4613"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.41503146,0,0,0.41503146,21.437996,21.853023)"
+ x1="86.132919"
+ y1="105.105"
+ x2="84.63858"
+ y2="20.895" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5128"
+ id="linearGradient4615"
+ gradientUnits="userSpaceOnUse"
+ x1="5.2744913"
+ y1="62.878765"
+ x2="-6.5244856"
+ y2="66.807335" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5128"
+ id="linearGradient4617"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.44988627,0,0,0.44988627,-7.7869415e-6,-94.532869)"
+ x1="5.2744913"
+ y1="62.878765"
+ x2="-6.5244856"
+ y2="66.807335" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3932"
+ id="linearGradient4619"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1,0,0,-1,91.080609,91.12006)"
+ x1="45.312279"
+ y1="48.267761"
+ x2="42.662289"
+ y2="45.617771" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3309"
+ id="linearGradient4621"
+ gradientUnits="userSpaceOnUse"
+ x1="32.237946"
+ y1="21.650217"
+ x2="36.821369"
+ y2="47.535378" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3724"
+ id="linearGradient4623"
+ gradientUnits="userSpaceOnUse"
+ x1="64.669502"
+ y1="71.888321"
+ x2="59.574085"
+ y2="52.871964" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3741"
+ id="linearGradient4625"
+ gradientUnits="userSpaceOnUse"
+ x1="52.51516"
+ y1="44.039856"
+ x2="54.767216"
+ y2="64.307716" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3777"
+ id="radialGradient4627"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-0.01155242,1.9830883,-2.0305783,-0.02269268,158.07483,-40.252061)"
+ cx="48.089584"
+ cy="53.8909"
+ fx="48.089584"
+ fy="53.8909"
+ r="5.4927044" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3751"
+ id="radialGradient4629"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.3125312,2.3348434,1.2717514,-1.2595982,-125.14605,4.532606)"
+ cx="47.644325"
+ cy="54.10635"
+ fx="47.644325"
+ fy="54.10635"
+ r="4.8616066" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3865"
+ id="linearGradient4631"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.5,0.8660254,-0.8660254,0.5,91.523702,-24.523702)"
+ x1="60.755741"
+ y1="66.836105"
+ x2="69.693596"
+ y2="69.230995" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5128"
+ id="linearGradient4695"
+ gradientUnits="userSpaceOnUse"
+ x1="5.2744913"
+ y1="62.878765"
+ x2="-6.5244856"
+ y2="66.807335" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5128"
+ id="linearGradient4697"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.44988627,0,0,0.44988627,-7.7869415e-6,-94.532869)"
+ x1="5.2744913"
+ y1="62.878765"
+ x2="-6.5244856"
+ y2="66.807335" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3932"
+ id="linearGradient4699"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1,0,0,-1,91.080609,91.12006)"
+ x1="45.312279"
+ y1="48.267761"
+ x2="42.662289"
+ y2="45.617771" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3309"
+ id="linearGradient4701"
+ gradientUnits="userSpaceOnUse"
+ x1="32.237946"
+ y1="21.650217"
+ x2="36.821369"
+ y2="47.535378" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3724"
+ id="linearGradient4703"
+ gradientUnits="userSpaceOnUse"
+ x1="64.669502"
+ y1="71.888321"
+ x2="59.574085"
+ y2="52.871964" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3741"
+ id="linearGradient4705"
+ gradientUnits="userSpaceOnUse"
+ x1="52.51516"
+ y1="44.039856"
+ x2="54.767216"
+ y2="64.307716" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3777"
+ id="radialGradient4707"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-0.01155242,1.9830883,-2.0305783,-0.02269268,158.07483,-40.252061)"
+ cx="48.089584"
+ cy="53.8909"
+ fx="48.089584"
+ fy="53.8909"
+ r="5.4927044" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3751"
+ id="radialGradient4709"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.3125312,2.3348434,1.2717514,-1.2595982,-125.14605,4.532606)"
+ cx="47.644325"
+ cy="54.10635"
+ fx="47.644325"
+ fy="54.10635"
+ r="4.8616066" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3865"
+ id="linearGradient4711"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.5,0.8660254,-0.8660254,0.5,91.523702,-24.523702)"
+ x1="60.755741"
+ y1="66.836105"
+ x2="69.693596"
+ y2="69.230995" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3865"
+ id="linearGradient4716"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.5,0.8660254,-0.8660254,0.5,253.36599,768.22675)"
+ x1="60.755741"
+ y1="66.836105"
+ x2="69.693596"
+ y2="69.230995" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3751"
+ id="radialGradient4719"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.3125312,2.3348434,1.2717514,-1.2595982,36.69624,797.28306)"
+ cx="47.644325"
+ cy="54.10635"
+ fx="47.644325"
+ fy="54.10635"
+ r="4.8616066" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3777"
+ id="radialGradient4722"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1.4135694,1.3909409,-1.9726688,-2.0047611,389.83126,880.07421)"
+ cx="48.089584"
+ cy="53.8909"
+ fx="48.089584"
+ fy="53.8909"
+ r="5.4927044" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3741"
+ id="linearGradient4725"
+ gradientUnits="userSpaceOnUse"
+ x1="52.51516"
+ y1="44.039856"
+ x2="54.767216"
+ y2="64.307716"
+ gradientTransform="translate(161.84229,792.75045)" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3724"
+ id="linearGradient4731"
+ gradientUnits="userSpaceOnUse"
+ x1="64.669502"
+ y1="71.888321"
+ x2="59.574085"
+ y2="52.871964"
+ gradientTransform="translate(161.84229,792.75045)" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3309"
+ id="linearGradient4734"
+ gradientUnits="userSpaceOnUse"
+ x1="32.237946"
+ y1="21.650217"
+ x2="36.821369"
+ y2="47.535378"
+ gradientTransform="translate(161.84229,792.75045)" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3932"
+ id="linearGradient4738"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1,0,0,-1,252.9229,883.87051)"
+ x1="45.312279"
+ y1="48.267761"
+ x2="42.662289"
+ y2="45.617771" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5128"
+ id="linearGradient4741"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.44988627,0,0,0.44988627,446.11943,-769.53187)"
+ x1="5.2744913"
+ y1="62.878765"
+ x2="-6.5244856"
+ y2="66.807335" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5128"
+ id="linearGradient4744"
+ gradientUnits="userSpaceOnUse"
+ x1="5.2744913"
+ y1="62.878765"
+ x2="-6.5244856"
+ y2="66.807335"
+ gradientTransform="translate(-446.11944,674.999)" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3309"
+ id="linearGradient4753"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.2790652,0,0,1.2790652,17.302433,18.5815)"
+ x1="20.758585"
+ y1="1"
+ x2="20.758585"
+ y2="45.017357" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3397"
+ id="linearGradient4755"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.2790652,0,0,1.2790652,17.302433,18.5815)"
+ x1="37.201294"
+ y1="1"
+ x2="37.201294"
+ y2="45" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5128"
+ id="linearGradient4757"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.41503146,0,0,0.41503146,21.437996,21.853023)"
+ x1="86.132919"
+ y1="105.105"
+ x2="84.63858"
+ y2="20.895" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5128"
+ id="linearGradient4761"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.41503146,0,0,0.41503146,183.28029,814.60347)"
+ x1="86.132919"
+ y1="105.105"
+ x2="84.63858"
+ y2="20.895" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3309"
+ id="linearGradient4764"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.2790652,0,0,1.2790652,179.14472,811.33195)"
+ x1="20.758585"
+ y1="1"
+ x2="20.758585"
+ y2="45.017357" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3397"
+ id="linearGradient4766"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.2790652,0,0,1.2790652,179.14472,811.33195)"
+ x1="37.201294"
+ y1="1"
+ x2="37.201294"
+ y2="45" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3737-5"
+ id="linearGradient4769"
+ gradientUnits="userSpaceOnUse"
+ x1="48"
+ y1="20.220806"
+ x2="48"
+ y2="138.66119" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3700"
+ id="linearGradient4772"
+ gradientUnits="userSpaceOnUse"
+ x1="48"
+ y1="90"
+ x2="48"
+ y2="5.9877172" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3700"
+ id="linearGradient4774"
+ gradientUnits="userSpaceOnUse"
+ x1="48"
+ y1="90"
+ x2="48"
+ y2="5.9877172" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3700"
+ id="linearGradient4777"
+ gradientUnits="userSpaceOnUse"
+ x1="48"
+ y1="90"
+ x2="48"
+ y2="5.9877172"
+ gradientTransform="translate(161.84229,792.75045)" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3700"
+ id="linearGradient4780"
+ gradientUnits="userSpaceOnUse"
+ x1="48"
+ y1="90"
+ x2="48"
+ y2="5.9877172"
+ gradientTransform="translate(161.84229,792.75045)" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3224"
+ id="linearGradient4799"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,-96)"
+ x1="48"
+ y1="90"
+ x2="48"
+ y2="5.9877172" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3737-5"
+ id="linearGradient4801"
+ gradientUnits="userSpaceOnUse"
+ x1="36.357143"
+ y1="6"
+ x2="36.357143"
+ y2="63.893143" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3737-5"
+ id="radialGradient4803"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.1573129,0,0,0.99590774,-7.5510206,0.19713193)"
+ cx="48"
+ cy="90.171875"
+ fx="48"
+ fy="90.171875"
+ r="42" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3737-5"
+ id="radialGradient4806"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.1573129,0,0,0.99590774,154.29127,792.94758)"
+ cx="48"
+ cy="90.171875"
+ fx="48"
+ fy="90.171875"
+ r="42" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3737-5"
+ id="linearGradient4809"
+ gradientUnits="userSpaceOnUse"
+ x1="36.357143"
+ y1="6"
+ x2="36.357143"
+ y2="63.893143"
+ gradientTransform="translate(161.84229,792.75045)" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3224"
+ id="linearGradient4812"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(161.84229,-888.75045)"
+ x1="48"
+ y1="90"
+ x2="48"
+ y2="5.9877172" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#ButtonShadow-0-1"
+ id="linearGradient4814"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.0238095,0,0,1.0119048,-1.1428571,-98.071429)"
+ x1="32.251034"
+ y1="6.1317081"
+ x2="32.251034"
+ y2="90.238609" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#ButtonShadow-0-1"
+ id="linearGradient4816"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.0238095,0,0,1.0119048,-1.1428571,-98.071429)"
+ x1="32.251034"
+ y1="6.1317081"
+ x2="32.251034"
+ y2="90.238609" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#ButtonShadow-0-1"
+ id="linearGradient4818"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.0238095,0,0,1.0119048,-1.1428571,-98.071429)"
+ x1="32.251034"
+ y1="6.1317081"
+ x2="32.251034"
+ y2="90.238609" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#ButtonShadow-0-1"
+ id="linearGradient4820"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.0238095,0,0,1.0119048,-1.1428571,-98.071429)"
+ x1="32.251034"
+ y1="6.1317081"
+ x2="32.251034"
+ y2="90.238609" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#ButtonShadow-0-1"
+ id="linearGradient4822"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,-97)"
+ x1="32.251034"
+ y1="6.1317081"
+ x2="32.251034"
+ y2="90.238609" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#ButtonShadow-0-1"
+ id="linearGradient4825"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(161.84229,-889.75045)"
+ x1="32.251034"
+ y1="6.1317081"
+ x2="32.251034"
+ y2="90.238609" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#ButtonShadow-0-1"
+ id="linearGradient4828"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.0238095,0,0,1.0119048,160.69943,-890.82188)"
+ x1="32.251034"
+ y1="6.1317081"
+ x2="32.251034"
+ y2="90.238609" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#ButtonShadow-0-1"
+ id="linearGradient4831"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.0238095,0,0,-1.0119048,160.69943,890.82188)"
+ x1="32.251034"
+ y1="6.1317081"
+ x2="32.251034"
+ y2="90.238609" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#ButtonShadow-0-1"
+ id="linearGradient4834"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.0238095,0,0,-1.0119048,160.69943,890.82188)"
+ x1="32.251034"
+ y1="6.1317081"
+ x2="32.251034"
+ y2="90.238609" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#ButtonShadow-0-1"
+ id="linearGradient4837"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.0238095,0,0,-1.0119048,160.69943,890.82188)"
+ x1="32.251034"
+ y1="6.1317081"
+ x2="32.251034"
+ y2="90.238609" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#ButtonShadow-4"
+ id="linearGradient4839"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="scale(1.0058652,0.994169)"
+ x1="45.447727"
+ y1="92.539597"
+ x2="45.447727"
+ y2="7.0165396" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#ButtonShadow-4"
+ id="linearGradient4842"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.0058652,0,0,0.994169,161.84229,792.75045)"
+ x1="45.447727"
+ y1="92.539597"
+ x2="45.447727"
+ y2="7.0165396" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#ButtonShadow-0-1"
+ id="linearGradient4890"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.0238095,0,0,-1.0119048,160.69943,890.82188)"
+ x1="32.251034"
+ y1="6.1317081"
+ x2="32.251034"
+ y2="90.238609" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#ButtonShadow-0-1"
+ id="linearGradient4892"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.0238095,0,0,-1.0119048,160.69943,890.82188)"
+ x1="32.251034"
+ y1="6.1317081"
+ x2="32.251034"
+ y2="90.238609" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#ButtonShadow-0-1"
+ id="linearGradient4894"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.0238095,0,0,-1.0119048,160.69943,890.82188)"
+ x1="32.251034"
+ y1="6.1317081"
+ x2="32.251034"
+ y2="90.238609" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#ButtonShadow-0-1"
+ id="linearGradient4896"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.0238095,0,0,1.0119048,160.69943,-890.82188)"
+ x1="32.251034"
+ y1="6.1317081"
+ x2="32.251034"
+ y2="90.238609" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#ButtonShadow-0-1"
+ id="linearGradient4898"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(161.84229,-889.75045)"
+ x1="32.251034"
+ y1="6.1317081"
+ x2="32.251034"
+ y2="90.238609" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3224"
+ id="linearGradient4900"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(161.84229,-888.75045)"
+ x1="48"
+ y1="90"
+ x2="48"
+ y2="5.9877172" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3737-5"
+ id="linearGradient4902"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(161.84229,792.75045)"
+ x1="36.357143"
+ y1="6"
+ x2="36.357143"
+ y2="63.893143" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3737-5"
+ id="radialGradient4904"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.1573129,0,0,0.99590774,154.29127,792.94758)"
+ cx="48"
+ cy="90.171875"
+ fx="48"
+ fy="90.171875"
+ r="42" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3737-5"
+ id="linearGradient4906"
+ gradientUnits="userSpaceOnUse"
+ x1="48"
+ y1="20.220806"
+ x2="48"
+ y2="138.66119" />
+ <linearGradient
+ y2="19"
+ x2="13"
+ y1="3"
+ x1="13"
+ gradientTransform="matrix(4.941505,0,0,4.941505,-1.552318,-8.2232516)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient4019"
+ xlink:href="#linearGradient3637"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="19"
+ x2="13"
+ y1="3"
+ x1="13"
+ gradientTransform="matrix(4.941505,0,0,4.941505,-10.141081,-5.2223592)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient3983"
+ xlink:href="#linearGradient3637"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="19"
+ x2="13"
+ y1="3"
+ x1="13"
+ gradientTransform="matrix(5.2543554,0,0,5.2543554,-105.50523,-10.414634)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient3102"
+ xlink:href="#linearGradient3637"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="8"
+ x2="120"
+ y1="8"
+ x1="104"
+ gradientTransform="translate(-104,104)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient3082"
+ xlink:href="#linearGradient3637"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="8"
+ x2="120"
+ y1="8"
+ x1="104"
+ gradientTransform="translate(-144,104)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient3077"
+ xlink:href="#linearGradient3183-0"
+ inkscape:collect="always" />
+ <linearGradient
+ gradientTransform="matrix(3.25,0,0,3.25,12.25,12.25)"
+ gradientUnits="userSpaceOnUse"
+ xlink:href="#linearGradient3637"
+ id="linearGradient3022"
+ y2="19"
+ x2="13"
+ y1="3"
+ x1="13" />
+ <linearGradient
+ id="linearGradient3183-0">
+ <stop
+ offset="0"
+ style="stop-color:#c80000;stop-opacity:1"
+ id="stop3185-9" />
+ <stop
+ offset="1"
+ style="stop-color:#f3604d;stop-opacity:1"
+ id="stop3187-6" />
+ </linearGradient>
+ <linearGradient
+ gradientTransform="translate(-144,104)"
+ gradientUnits="userSpaceOnUse"
+ xlink:href="#linearGradient3183-0"
+ id="linearGradient3913"
+ y2="8"
+ x2="120"
+ y1="8"
+ x1="104" />
+ <linearGradient
+ gradientTransform="translate(-104,104)"
+ gradientUnits="userSpaceOnUse"
+ xlink:href="#linearGradient3637"
+ id="linearGradient3905"
+ y2="8"
+ x2="120"
+ y1="8"
+ x1="104" />
+ <radialGradient
+ gradientTransform="matrix(1.1573129,0,0,0.99590774,-14.868094,-6.095551)"
+ gradientUnits="userSpaceOnUse"
+ xlink:href="#linearGradient3737-3"
+ id="radialGradient3619-3"
+ fy="90.171875"
+ fx="48"
+ r="42"
+ cy="90.171875"
+ cx="48" />
+ <linearGradient
+ id="linearGradient3737-3">
+ <stop
+ offset="0"
+ style="stop-color:#ffffff;stop-opacity:1"
+ id="stop3739-6" />
+ <stop
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:0"
+ id="stop3741-1" />
+ </linearGradient>
+ <linearGradient
+ gradientTransform="translate(-7.3170732,-6.2926829)"
+ gradientUnits="userSpaceOnUse"
+ xlink:href="#linearGradient3737-3"
+ id="linearGradient3188-8"
+ y2="63.893143"
+ x2="36.357143"
+ y1="6"
+ x1="36.357143" />
+ <linearGradient
+ gradientTransform="matrix(1.0238095,0,0,-1.0119048,-1.1428571,98.071429)"
+ gradientUnits="userSpaceOnUse"
+ xlink:href="#ButtonShadow-0-9"
+ id="linearGradient3199"
+ y2="90.238609"
+ x2="32.251034"
+ y1="6.1317081"
+ x1="32.251034" />
+ <linearGradient
+ gradientTransform="matrix(1,0,0,-1,0,97)"
+ gradientUnits="userSpaceOnUse"
+ xlink:href="#ButtonShadow-0-9"
+ id="linearGradient3721-1"
+ y2="90.238609"
+ x2="32.251034"
+ y1="6.1317081"
+ x1="32.251034" />
+ <linearGradient
+ gradientTransform="matrix(1.0238095,0,0,-1.0119048,-1.1428571,98.071429)"
+ gradientUnits="userSpaceOnUse"
+ xlink:href="#ButtonShadow-0-9"
+ id="linearGradient3725-6"
+ y2="90.238609"
+ x2="32.251034"
+ y1="6.1317081"
+ x1="32.251034" />
+ <linearGradient
+ gradientTransform="matrix(1.0238095,0,0,-1.0119048,-1.1428571,98.071429)"
+ gradientUnits="userSpaceOnUse"
+ xlink:href="#ButtonShadow-0-9"
+ id="linearGradient3772-27"
+ y2="90.238609"
+ x2="32.251034"
+ y1="6.1317081"
+ x1="32.251034" />
+ <linearGradient
+ gradientTransform="matrix(1.0238095,0,0,-1.0119048,-1.1428571,98.071429)"
+ gradientUnits="userSpaceOnUse"
+ xlink:href="#ButtonShadow-0-9"
+ id="linearGradient3780-0"
+ y2="90.238609"
+ x2="32.251034"
+ y1="6.1317081"
+ x1="32.251034" />
+ <linearGradient
+ gradientTransform="matrix(1.0058652,0,0,0.994169,100,0)"
+ gradientUnits="userSpaceOnUse"
+ id="ButtonShadow-0-9"
+ y2="7.0165396"
+ x2="45.447727"
+ y1="92.539597"
+ x1="45.447727">
+ <stop
+ offset="0"
+ style="stop-color:#000000;stop-opacity:1"
+ id="stop3750-8-9" />
+ <stop
+ offset="1"
+ style="stop-color:#000000;stop-opacity:0.58823532"
+ id="stop3752-5-6" />
+ </linearGradient>
+ <filter
+ id="filter3657"
+ color-interpolation-filters="sRGB">
+ <feGaussianBlur
+ stdDeviation="1.14"
+ id="feGaussianBlur3659" />
+ </filter>
+ <clipPath
+ id="clipPath3649">
+ <rect
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ id="rect3651"
+ y="10"
+ x="10"
+ ry="4"
+ rx="4"
+ height="76"
+ width="76" />
+ </clipPath>
+ <linearGradient
+ gradientUnits="userSpaceOnUse"
+ xlink:href="#linearGradient3637"
+ id="linearGradient3643"
+ y2="90.015434"
+ x2="44.512066"
+ y1="6"
+ x1="44.512066" />
+ <clipPath
+ id="clipPath3625">
+ <path
+ style="fill:#ffffff;fill-opacity:1;stroke:none"
+ id="path3627"
+ inkscape:connector-curvature="0"
+ d="M 0,0 0,96 96,96 96,0 0,0 z m 12,6 72,0 c 3.324,0 6,2.676 6,6 l 0,72 c 0,3.324 -2.676,6 -6,6 L 12,90 C 8.676,90 6,87.324 6,84 L 6,12 C 6,8.676 8.676,6 12,6 z" />
+ </clipPath>
+ <linearGradient
+ gradientTransform="translate(0,100)"
+ gradientUnits="userSpaceOnUse"
+ xlink:href="#linearGradient3700-6"
+ id="linearGradient2843"
+ y2="5.9877172"
+ x2="48"
+ y1="90"
+ x1="48" />
+ <clipPath
+ id="clipPath3613-8">
+ <rect
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ id="rect3615-2"
+ y="6"
+ x="6"
+ ry="6"
+ rx="6"
+ height="84"
+ width="84" />
+ </clipPath>
+ <radialGradient
+ gradientTransform="matrix(1.1573129,0,0,0.99590774,-7.5510206,0.19713193)"
+ gradientUnits="userSpaceOnUse"
+ xlink:href="#linearGradient3737-0"
+ id="radialGradient3619-2"
+ fy="90.171875"
+ fx="48"
+ r="42"
+ cy="90.171875"
+ cx="48" />
+ <linearGradient
+ gradientUnits="userSpaceOnUse"
+ xlink:href="#linearGradient3737-0"
+ id="linearGradient3613-7"
+ y2="138.66119"
+ x2="48"
+ y1="20.220806"
+ x1="48" />
+ <filter
+ id="filter3794-9"
+ color-interpolation-filters="sRGB"
+ height="1.3839999"
+ width="1.3839999"
+ y="-0.192"
+ x="-0.192">
+ <feGaussianBlur
+ stdDeviation="5.28"
+ id="feGaussianBlur3796-8" />
+ </filter>
+ <linearGradient
+ gradientUnits="userSpaceOnUse"
+ xlink:href="#linearGradient3737-0"
+ id="linearGradient3188-6"
+ y2="63.893143"
+ x2="36.357143"
+ y1="6"
+ x1="36.357143" />
+ <filter
+ id="filter3174-7"
+ color-interpolation-filters="sRGB">
+ <feGaussianBlur
+ stdDeviation="1.71"
+ id="feGaussianBlur3176-5" />
+ </filter>
+ <linearGradient
+ id="linearGradient3700-6">
+ <stop
+ offset="0"
+ style="stop-color:#2276c5;stop-opacity:1"
+ id="stop3702-2" />
+ <stop
+ offset="1"
+ style="stop-color:#68baf4;stop-opacity:1"
+ id="stop3704-6" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3737-0">
+ <stop
+ offset="0"
+ style="stop-color:#ffffff;stop-opacity:1"
+ id="stop3739-0" />
+ <stop
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:0"
+ id="stop3741-4" />
+ </linearGradient>
+ <linearGradient
+ gradientTransform="scale(1.0058652,0.994169)"
+ gradientUnits="userSpaceOnUse"
+ id="ButtonShadow-6"
+ y2="7.0165396"
+ x2="45.447727"
+ y1="92.539597"
+ x1="45.447727">
+ <stop
+ offset="0"
+ style="stop-color:#000000;stop-opacity:1"
+ id="stop3750-6" />
+ <stop
+ offset="1"
+ style="stop-color:#000000;stop-opacity:0.58823532"
+ id="stop3752-4" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3637">
+ <stop
+ offset="0"
+ style="stop-color:#f0f0f0;stop-opacity:1"
+ id="stop3639" />
+ <stop
+ offset="1"
+ style="stop-color:#aaaaaa;stop-opacity:1"
+ id="stop3641" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3637"
+ id="linearGradient3570"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(9.826824,0,0,9.826824,28.191015,807.27776)"
+ x1="13"
+ y1="3"
+ x2="13"
+ y2="19" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3637"
+ id="linearGradient3573"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(9.826824,0,0,9.826824,11.111145,813.24543)"
+ x1="13"
+ y1="3"
+ x2="13"
+ y2="19" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3183-0"
+ id="linearGradient3580"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.3378535,0,0,2.3378535,-1144.3993,258.54666)"
+ x1="104"
+ y1="8"
+ x2="120"
+ y2="8" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3637"
+ id="linearGradient3585"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.3378535,0,0,2.3378535,564.61167,258.54666)"
+ x1="104"
+ y1="8"
+ x2="120"
+ y2="8" />
+ </defs>
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="1.4"
+ inkscape:cx="134.93952"
+ inkscape:cy="67.598387"
+ inkscape:document-units="px"
+ inkscape:current-layer="layer1"
+ showgrid="false"
+ showguides="true"
+ inkscape:guide-bbox="true"
+ inkscape:window-width="725"
+ inkscape:window-height="698"
+ inkscape:window-x="1073"
+ inkscape:window-y="355"
+ inkscape:window-maximized="0" />
+ <metadata
+ id="metadata7">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title />
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="Ebene 1"
+ inkscape:groupmode="layer"
+ id="layer1"
+ transform="translate(0,-796.36218)">
+ <rect
+ style="opacity:0.9;fill:url(#linearGradient4842);fill-opacity:1;fill-rule:nonzero;stroke:none;display:none;filter:url(#filter3174-5)"
+ id="rect3745"
+ y="799.75043"
+ x="166.84229"
+ ry="6"
+ rx="6"
+ height="85"
+ width="86" />
+ <rect
+ style="opacity:0.9;fill:url(#linearGradient4780);fill-opacity:1;fill-rule:nonzero;stroke:none;display:none"
+ id="rect3873"
+ y="798.75043"
+ x="167.84229"
+ ry="6"
+ rx="6"
+ height="84"
+ width="84" />
+ <rect
+ style="opacity:0.9;fill:url(#linearGradient4777);fill-opacity:1;fill-rule:nonzero;stroke:none;display:none"
+ id="rect3880"
+ y="798.75043"
+ x="167.84229"
+ ry="6"
+ rx="6"
+ height="84"
+ width="84" />
+ <g
+ id="g4844"
+ transform="matrix(2.7693269,0,0,2.7693269,-452.8745,-1409.2435)">
+ <path
+ inkscape:connector-curvature="0"
+ d="m 173.84229,887.7817 c -5.51109,0 -10.03125,-4.52016 -10.03125,-10.03125 l 0,-71 c 0,-5.51109 4.52016,-10.03125 10.03125,-10.03125 l 72,0 c 5.51109,0 10.03125,4.52016 10.03125,10.03125 l 0,71 c 0,5.51109 -4.52016,10.03125 -10.03125,10.03125 l -72,0 z"
+ id="path3786"
+ style="opacity:0.07999998;fill:url(#linearGradient4890);fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline" />
+ <path
+ inkscape:connector-curvature="0"
+ d="m 173.84229,886.7817 c -4.97163,0 -9.03125,-4.05962 -9.03125,-9.03125 l 0,-71 c 0,-4.97163 4.05962,-9.03125 9.03125,-9.03125 l 72,0 c 4.97163,0 9.03125,4.05962 9.03125,9.03125 l 0,71 c 0,4.97163 -4.05962,9.03125 -9.03125,9.03125 l -72,0 z"
+ id="path3778"
+ style="opacity:0.1;fill:url(#linearGradient4892);fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline" />
+ <path
+ inkscape:connector-curvature="0"
+ d="m 173.84229,885.75045 c -4.40913,0 -8,-3.59087 -8,-8 l 0,-71 c 0,-4.40913 3.59087,-8 8,-8 l 72,0 c 4.40913,0 8,3.59087 8,8 l 0,71 c 0,4.40913 -3.59087,8 -8,8 l -72,0 z"
+ id="path3770"
+ style="opacity:0.2;fill:url(#linearGradient4894);fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline" />
+ <rect
+ width="86"
+ height="85"
+ rx="7"
+ ry="7"
+ x="166.84229"
+ y="-884.75043"
+ transform="scale(1,-1)"
+ id="rect3723"
+ style="opacity:0.3;fill:url(#linearGradient4896);fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline" />
+ <rect
+ width="84"
+ height="84"
+ rx="6"
+ ry="6"
+ x="167.84229"
+ y="-883.75043"
+ transform="scale(1,-1)"
+ id="rect3716"
+ style="opacity:0.45;fill:url(#linearGradient4898);fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline" />
+ <rect
+ width="84"
+ height="84"
+ rx="6"
+ ry="6"
+ x="167.84229"
+ y="-882.75043"
+ transform="scale(1,-1)"
+ id="rect2419"
+ style="fill:url(#linearGradient4900);fill-opacity:1;fill-rule:nonzero;stroke:none" />
+ <path
+ d="m 173.84229,798.75045 c -3.324,0 -6,2.676 -6,6 l 0,2 0,68 0,2 c 0,0.33472 0.0414,0.6507 0.0937,0.96875 0.0487,0.2956 0.097,0.59691 0.1875,0.875 0.01,0.0304 0.0209,0.0636 0.0312,0.0937 0.0989,0.28777 0.23488,0.54745 0.375,0.8125 0.14459,0.27351 0.31562,0.53561 0.5,0.78125 0.18438,0.24563 0.37378,0.47347 0.59375,0.6875 0.43995,0.42806 0.94291,0.81453 1.5,1.09375 0.27854,0.13961 0.57347,0.24695 0.875,0.34375 -0.2562,-0.10022 -0.48671,-0.23627 -0.71875,-0.375 -0.007,-0.004 -0.0239,0.005 -0.0312,0 -0.0319,-0.0193 -0.0623,-0.0425 -0.0937,-0.0625 -0.1204,-0.0767 -0.23102,-0.16351 -0.34375,-0.25 -0.10617,-0.0808 -0.21328,-0.16111 -0.3125,-0.25 -0.17793,-0.16143 -0.34746,-0.34539 -0.5,-0.53125 -0.10758,-0.13026 -0.21839,-0.26528 -0.3125,-0.40625 -0.0251,-0.0384 -0.0384,-0.0859 -0.0625,-0.125 -0.0648,-0.10303 -0.13023,-0.20452 -0.1875,-0.3125 -0.10101,-0.19471 -0.20567,-0.4157 -0.28125,-0.625 -0.008,-0.0218 -0.0236,-0.0406 -0.0312,-0.0625 -0.0318,-0.0919 -0.0358,-0.18683 -0.0625,-0.28125 -0.0303,-0.10662 -0.0704,-0.20303 -0.0937,-0.3125 -0.0729,-0.34151 -0.125,-0.69821 -0.125,-1.0625 l 0,-2 0,-68 0,-2 c 0,-2.78185 2.21815,-5 5,-5 l 2,0 68,0 2,0 c 2.78185,0 5,2.21815 5,5 l 0,2 0,68 0,2 c 0,0.36429 -0.0521,0.72099 -0.125,1.0625 -0.0442,0.20689 -0.0884,0.39766 -0.15625,0.59375 -0.008,0.0219 -0.0233,0.0407 -0.0312,0.0625 -0.0627,0.17374 -0.13838,0.36745 -0.21875,0.53125 -0.0416,0.0828 -0.079,0.16995 -0.125,0.25 -0.0546,0.0972 -0.12677,0.18835 -0.1875,0.28125 -0.0941,0.14097 -0.20492,0.27599 -0.3125,0.40625 -0.14317,0.17445 -0.30314,0.347 -0.46875,0.5 -0.0112,0.0102 -0.02,0.0212 -0.0312,0.0312 -0.13839,0.12556 -0.28509,0.23444 -0.4375,0.34375 -0.10257,0.0732 -0.20432,0.15336 -0.3125,0.21875 -0.007,0.005 -0.0238,-0.004 -0.0312,0 -0.23204,0.13873 -0.46255,0.27478 -0.71875,0.375 0.30153,-0.0968 0.59645,-0.20414 0.875,-0.34375 0.55709,-0.27922 1.06005,-0.66569 1.5,-1.09375 0.21997,-0.21403 0.40937,-0.44187 0.59375,-0.6875 0.18438,-0.24564 0.35541,-0.50774 0.5,-0.78125 0.14012,-0.26505 0.27613,-0.52473 0.375,-0.8125 0.0104,-0.0308 0.0213,-0.0627 0.0312,-0.0937 0.0905,-0.27809 0.1388,-0.5794 0.1875,-0.875 0.0524,-0.31805 0.0937,-0.63403 0.0937,-0.96875 l 0,-2 0,-68 0,-2 c 0,-3.324 -2.676,-6 -6,-6 l -72,0 z"
+ inkscape:connector-curvature="0"
+ id="rect3728"
+ style="opacity:0.4;fill:url(#linearGradient4902);fill-opacity:1;fill-rule:nonzero;stroke:none" />
+ <path
+ d="m 173.84229,882.75045 c -3.324,0 -6,-2.676 -6,-6 l 0,-2 0,-68 0,-2 c 0,-0.33472 0.0414,-0.6507 0.0937,-0.96875 0.0487,-0.2956 0.097,-0.59691 0.1875,-0.875 0.01,-0.0304 0.0209,-0.0636 0.0312,-0.0937 0.0989,-0.28777 0.23488,-0.54745 0.375,-0.8125 0.14459,-0.27351 0.31562,-0.53562 0.5,-0.78125 0.18438,-0.24564 0.37378,-0.47347 0.59375,-0.6875 0.43995,-0.42806 0.94291,-0.81453 1.5,-1.09375 0.27854,-0.13961 0.57347,-0.24695 0.875,-0.34375 -0.2562,0.10022 -0.48671,0.23627 -0.71875,0.375 -0.007,0.004 -0.0239,-0.005 -0.0312,0 -0.0319,0.0193 -0.0623,0.0425 -0.0937,0.0625 -0.1204,0.0767 -0.23102,0.16351 -0.34375,0.25 -0.10617,0.0808 -0.21328,0.16111 -0.3125,0.25 -0.17793,0.16143 -0.34746,0.34539 -0.5,0.53125 -0.10758,0.13026 -0.21839,0.26528 -0.3125,0.40625 -0.0251,0.0384 -0.0384,0.0859 -0.0625,0.125 -0.0648,0.10303 -0.13023,0.20452 -0.1875,0.3125 -0.10101,0.19471 -0.20567,0.4157 -0.28125,0.625 -0.008,0.0218 -0.0236,0.0406 -0.0312,0.0625 -0.0318,0.0919 -0.0358,0.18683 -0.0625,0.28125 -0.0303,0.10662 -0.0704,0.20303 -0.0937,0.3125 -0.0729,0.34151 -0.125,0.69821 -0.125,1.0625 l 0,2 0,68 0,2 c 0,2.78185 2.21815,5 5,5 l 2,0 68,0 2,0 c 2.78185,0 5,-2.21815 5,-5 l 0,-2 0,-68 0,-2 c 0,-0.36429 -0.0521,-0.72099 -0.125,-1.0625 -0.0442,-0.20689 -0.0884,-0.39766 -0.15625,-0.59375 -0.008,-0.0219 -0.0233,-0.0407 -0.0312,-0.0625 -0.0627,-0.17374 -0.13838,-0.36745 -0.21875,-0.53125 -0.0416,-0.0828 -0.079,-0.16995 -0.125,-0.25 -0.0546,-0.0972 -0.12677,-0.18835 -0.1875,-0.28125 -0.0941,-0.14097 -0.20492,-0.27599 -0.3125,-0.40625 -0.14317,-0.17445 -0.30314,-0.347 -0.46875,-0.5 -0.0112,-0.0102 -0.02,-0.0212 -0.0312,-0.0312 -0.13839,-0.12556 -0.28509,-0.23444 -0.4375,-0.34375 -0.10257,-0.0732 -0.20432,-0.15336 -0.3125,-0.21875 -0.007,-0.005 -0.0238,0.004 -0.0312,0 -0.23204,-0.13873 -0.46255,-0.27478 -0.71875,-0.375 0.30153,0.0968 0.59645,0.20414 0.875,0.34375 0.55709,0.27922 1.06005,0.66569 1.5,1.09375 0.21997,0.21403 0.40937,0.44186 0.59375,0.6875 0.18438,0.24563 0.35541,0.50774 0.5,0.78125 0.14012,0.26505 0.27613,0.52473 0.375,0.8125 0.0104,0.0308 0.0213,0.0627 0.0312,0.0937 0.0905,0.27809 0.1388,0.5794 0.1875,0.875 0.0524,0.31805 0.0937,0.63403 0.0937,0.96875 l 0,2 0,68 0,2 c 0,3.324 -2.676,6 -6,6 l -72,0 z"
+ inkscape:connector-curvature="0"
+ id="path3615"
+ style="opacity:0.2;fill:url(#radialGradient4904);fill-opacity:1;fill-rule:nonzero;stroke:none" />
+ <g
+ transform="translate(161.84229,792.75045)"
+ clip-path="url(#clipPath2973)"
+ id="g3855"
+ style="opacity:0.9;fill:#aaccff">
+ <path
+ d="M 48,48 72,-8 88,-8 48,48 z"
+ inkscape:connector-curvature="0"
+ id="path3819"
+ style="opacity:0.15;fill:#aaccff;stroke:none" />
+ <path
+ d="M 48,48 103.25122,73.67688 102.769,89.669611 48,48 z"
+ inkscape:connector-curvature="0"
+ id="path3821"
+ style="opacity:0.15;fill:#aaccff;stroke:none" />
+ <path
+ d="M 48,47.999999 -11.82794,59.515947 -20.796753,46.266027 48,47.999999 z"
+ inkscape:connector-curvature="0"
+ id="path3823"
+ style="opacity:0.15;fill:#aaccff;stroke:none" />
+ <path
+ d="M 48,48 -1.3111997,12.217252 2.2248524,-3.3871168 48,48 z"
+ inkscape:connector-curvature="0"
+ id="path3825"
+ style="opacity:0.15;fill:#aaccff;stroke:none" />
+ <path
+ d="M 48,48 65.519239,-14.073153 95.955194,-1.3588835 48,48 z"
+ inkscape:connector-curvature="0"
+ id="path3827"
+ style="opacity:0.15;fill:#aaccff;stroke:none" />
+ <path
+ d="M 48,48 109.6356,28.998609 115.4895,61.459846 48,48 z"
+ inkscape:connector-curvature="0"
+ id="path3829"
+ style="opacity:0.15;fill:#aaccff;stroke:none" />
+ <path
+ d="M 48,48 16.754067,104.42421 -9.9692451,85.088633 48,48 z"
+ inkscape:connector-curvature="0"
+ id="path3831"
+ style="opacity:0.15;fill:#aaccff;stroke:none" />
+ <path
+ d="M 48,48 -14.811967,33.348835 -3.5083336,2.3612922 48,48 z"
+ inkscape:connector-curvature="0"
+ id="path3833"
+ style="opacity:0.15;fill:#aaccff;stroke:none" />
+ <path
+ d="M 48,48 93.809637,93.403493 90.117903,102.42501 48,48 z"
+ inkscape:connector-curvature="0"
+ id="path3835"
+ style="opacity:0.15;fill:#aaccff;stroke:none" />
+ <path
+ d="m 48,48 -2.970052,64.42964 -9.168463,3.30998 L 48,48 z"
+ inkscape:connector-curvature="0"
+ id="path3837"
+ style="opacity:0.15;fill:#aaccff;stroke:none" />
+ <path
+ d="M 48,48 3.1405789,94.342551 -5.923902,90.757601 48,48 z"
+ inkscape:connector-curvature="0"
+ id="path3839"
+ style="opacity:0.15;fill:#aaccff;stroke:none" />
+ <path
+ d="M 48,47.999999 -14.116138,65.366204 -20.132068,57.696441 48,47.999999 z"
+ inkscape:connector-curvature="0"
+ id="path3841"
+ style="opacity:0.15;fill:#aaccff;stroke:none" />
+ <path
+ d="M 48.000001,47.999998 18.853372,-9.5367177 25.202646,-16.932892 48.000001,47.999998 z"
+ inkscape:connector-curvature="0"
+ id="path3843"
+ style="opacity:0.15;fill:#aaccff;stroke:none" />
+ <path
+ d="m 48.000003,48.000001 59.481677,-24.938521 6.921,6.864135 -66.402677,18.074386 z"
+ inkscape:connector-curvature="0"
+ id="path3845"
+ style="opacity:0.15;fill:#aaccff;stroke:none" />
+ <path
+ d="M 47.999999,47.999999 88.186743,93.793286 81.290444,108.23077 47.999999,47.999999 z"
+ inkscape:connector-curvature="0"
+ id="path3849"
+ style="opacity:0.15;fill:#aaccff;stroke:none" />
+ <path
+ d="M 48.000001,48 12.042033,-1.1835747 20.194136,-14.95104 48.000001,48 z"
+ inkscape:connector-curvature="0"
+ id="path3851"
+ style="opacity:0.15;fill:#aaccff;stroke:none" />
+ </g>
+ <rect
+ transform="translate(161.84229,792.75045)"
+ width="66"
+ height="66"
+ rx="12"
+ ry="12"
+ x="15"
+ y="15"
+ clip-path="url(#clipPath3613-7)"
+ id="rect3171"
+ style="opacity:0.1;fill:url(#linearGradient4906);fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:0.5;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;filter:url(#filter3794-7)" />
+ </g>
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:none;overflow:visible;filter:url(#filter3814);enable-background:accumulate"
+ id="path3808"
+ inkscape:connector-curvature="0"
+ d="m 206.04507,814.25055 c -1.08226,0 -1.95858,0.89778 -1.95858,1.99854 l 0,3.87716 c -1.93515,0.5156 -3.78419,1.2944 -5.47599,2.27834 l -2.75799,-2.75798 c -0.38918,-0.38918 -0.85537,-0.5953 -1.35901,-0.59957 -0.50363,-0.004 -1.01634,0.17696 -1.39897,0.55959 l -5.39606,5.39606 c -0.76526,0.76527 -0.73838,1.97963 0.0399,2.75798 l 2.75799,2.75799 c -0.98394,1.6918 -1.76273,3.54084 -2.27834,5.476 l -3.87716,0 c -1.10076,0 -1.99855,0.87631 -1.99855,1.95856 l 0,7.59446 c 0,1.08225 0.89779,1.95856 1.99855,1.95856 l 3.87716,0 c 0.51561,1.93516 1.2944,3.7842 2.27834,5.476 l -2.75799,2.75799 c -0.77835,0.77835 -0.80524,1.99271 -0.0399,2.75798 l 5.39606,5.39606 c 0.76526,0.76527 1.97963,0.73837 2.75798,-0.04 l 2.75799,-2.75799 c 1.6918,0.98394 3.54084,1.76274 5.47599,2.27834 l 0,3.87716 c 0,1.10076 0.87632,1.99854 1.95858,1.99854 l 7.59445,0 c 1.08225,0 1.95856,-0.89778 1.95856,-1.99854 l 0,-3.87716 c 1.93515,-0.5156 3.78419,-1.2944 5.476,-2.27834 l 2.75798,2.75799 c 0.77835,0.77835 1.99272,0.80524 2.75799,0.04 l 5.39605,-5.39606 c 0.76527,-0.76527 0.73838,-1.97963 -0.0399,-2.75798 l -2.75797,-2.75799 c 0.98393,-1.6918 1.76273,-3.54084 2.27832,-5.476 l 3.87718,0 c 1.10074,0 1.99854,-0.87631 1.99854,-1.95856 l 0,-7.59446 c 0,-1.08225 -0.8978,-1.95856 -1.99854,-1.95856 l -3.87718,0 c -0.51559,-1.93516 -1.29439,-3.7842 -2.27832,-5.476 l 2.75798,-2.75799 c 0.77835,-0.77835 0.80524,-1.99271 0.0399,-2.75798 l -5.39605,-5.39606 c -0.76528,-0.76527 -1.97964,-0.73838 -2.75799,0.04 l -2.75799,2.75799 c -1.69181,-0.98394 -3.54085,-1.76274 -5.47599,-2.27834 l 0,-3.87716 c 0,-1.10076 -0.87632,-1.99854 -1.95857,-1.99854 l -7.59445,0 z m 3.79722,19.18598 c 4.58929,0 8.31392,3.72463 8.31392,8.31392 0,4.58929 -3.72463,8.31392 -8.31392,8.31392 -4.58929,0 -8.31393,-3.72463 -8.31393,-8.31392 0,-4.58929 3.72464,-8.31392 8.31393,-8.31392 z" />
+ <path
+ style="fill:url(#linearGradient4764);fill-opacity:1;fill-rule:nonzero;stroke:url(#linearGradient4766);stroke-width:1;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:none;overflow:visible;enable-background:accumulate"
+ id="rect3267"
+ inkscape:connector-curvature="0"
+ d="m 206.04507,813.25055 c -1.08226,0 -1.95858,0.89778 -1.95858,1.99854 l 0,3.87716 c -1.93515,0.5156 -3.78419,1.2944 -5.47599,2.27834 l -2.75799,-2.75798 c -0.38918,-0.38918 -0.85537,-0.5953 -1.35901,-0.59957 -0.50363,-0.004 -1.01634,0.17696 -1.39897,0.55959 l -5.39606,5.39606 c -0.76526,0.76527 -0.73838,1.97963 0.0399,2.75798 l 2.75799,2.75799 c -0.98394,1.6918 -1.76273,3.54084 -2.27834,5.476 l -3.87716,0 c -1.10076,0 -1.99855,0.87631 -1.99855,1.95856 l 0,7.59446 c 0,1.08225 0.89779,1.95856 1.99855,1.95856 l 3.87716,0 c 0.51561,1.93516 1.2944,3.7842 2.27834,5.476 l -2.75799,2.75799 c -0.77835,0.77835 -0.80524,1.99271 -0.0399,2.75798 l 5.39606,5.39606 c 0.76526,0.76527 1.97963,0.73837 2.75798,-0.04 l 2.75799,-2.75799 c 1.6918,0.98394 3.54084,1.76274 5.47599,2.27834 l 0,3.87716 c 0,1.10076 0.87632,1.99854 1.95858,1.99854 l 7.59445,0 c 1.08225,0 1.95856,-0.89778 1.95856,-1.99854 l 0,-3.87716 c 1.93515,-0.5156 3.78419,-1.2944 5.476,-2.27834 l 2.75798,2.75799 c 0.77835,0.77835 1.99272,0.80524 2.75799,0.04 l 5.39605,-5.39606 c 0.76527,-0.76527 0.73838,-1.97963 -0.0399,-2.75798 l -2.75797,-2.75799 c 0.98393,-1.6918 1.76273,-3.54084 2.27832,-5.476 l 3.87718,0 c 1.10074,0 1.99854,-0.87631 1.99854,-1.95856 l 0,-7.59446 c 0,-1.08225 -0.8978,-1.95856 -1.99854,-1.95856 l -3.87718,0 c -0.51559,-1.93516 -1.29439,-3.7842 -2.27832,-5.476 l 2.75798,-2.75799 c 0.77835,-0.77835 0.80524,-1.99271 0.0399,-2.75798 l -5.39605,-5.39606 c -0.76528,-0.76527 -1.97964,-0.73838 -2.75799,0.04 l -2.75799,2.75799 c -1.69181,-0.98394 -3.54085,-1.76274 -5.47599,-2.27834 l 0,-3.87716 c 0,-1.10076 -0.87632,-1.99854 -1.95857,-1.99854 l -7.59445,0 z m 3.79722,19.18598 c 4.58929,0 8.31392,3.72463 8.31392,8.31392 0,4.58929 -3.72463,8.31392 -8.31392,8.31392 -4.58929,0 -8.31393,-3.72463 -8.31393,-8.31392 0,-4.58929 3.72464,-8.31392 8.31393,-8.31392 z" />
+ <path
+ style="fill:none;stroke:url(#linearGradient4761);stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none;display:none"
+ id="path28"
+ inkscape:connector-curvature="0"
+ d="m 209.84229,823.48307 c -9.52124,0 -17.26738,7.74614 -17.26738,17.26738 0,9.52123 7.74614,17.26738 17.26738,17.26738 9.52123,0 17.26738,-7.74615 17.26738,-17.26738 0,-9.52124 -7.74615,-17.26738 -17.26738,-17.26738 z" />
+ <path
+ style="opacity:0.05;fill:#000000;fill-opacity:1;stroke:none;display:none"
+ id="path3315"
+ inkscape:connector-curvature="0"
+ d="m 209.84229,824.1226 c -9.16875,0 -16.62786,7.4591 -16.62786,16.62785 0,9.16875 7.45911,16.62785 16.62786,16.62785 9.16875,0 16.62785,-7.4591 16.62785,-16.62785 0,-9.16875 -7.4591,-16.62785 -16.62785,-16.62785 z m 0,7.67439 c 4.9423,0 8.95346,4.01115 8.95346,8.95346 0,4.94231 -4.01116,8.95346 -8.95346,8.95346 -4.94231,0 -8.95346,-4.01115 -8.95346,-8.95346 0,-4.94231 4.01115,-8.95346 8.95346,-8.95346 z" />
+ <path
+ inkscape:transform-center-y="1.0292608"
+ inkscape:transform-center-x="0.55288406"
+ sodipodi:nodetypes="ssssssssss"
+ inkscape:connector-curvature="0"
+ style="opacity:0.1;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ d="m 77.723031,878.66456 c -6.871183,-0.18276 -29.925063,12.44733 -28.695793,21.02021 7.414192,51.70624 19.812703,25.26599 26.683883,25.44876 6.871176,0.18275 20.296404,-13.74161 20.479167,-20.61279 0.182755,-6.87118 -11.596082,-25.67342 -18.467257,-25.85618 z m -1.631426,17.04792 c 4.836178,0.12865 8.666437,4.13188 8.537802,8.96804 -0.128625,4.83618 -4.167231,8.6655 -9.003408,8.53686 -4.836173,-0.12862 -8.665492,-4.16723 -8.536858,-9.0034 0.128645,-4.83617 4.166288,-8.63013 9.002464,-8.5015 z"
+ id="path3885" />
+ <path
+ inkscape:transform-center-y="1.2564107"
+ inkscape:transform-center-x="-1.3978974"
+ id="path3887"
+ d="m 76.236238,881.15963 c -9.747853,-0.25927 -26.371314,11.01217 -26.630593,20.76003 -0.259276,9.74785 15.575715,28.11977 25.323566,28.37905 9.747851,0.25928 29.499939,-16.48813 29.759219,-26.23598 0.25928,-9.74786 -18.704341,-22.64382 -28.452192,-22.9031 z m -0.06099,10.40719 c 6.860884,0.18251 12.294713,5.86171 12.112221,12.72259 -0.182476,6.86089 -5.911868,12.29338 -12.772752,12.11088 -6.860874,-0.1825 -12.293369,-5.91186 -12.110882,-12.77275 0.182496,-6.86088 5.910541,-12.2432 12.771413,-12.06072 z"
+ style="opacity:0.15;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ssssssssss" />
+ <path
+ inkscape:transform-center-y="0.4326845"
+ inkscape:transform-center-x="-0.56899649"
+ style="opacity:0.3;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ d="m 75.791256,881.90961 c -12.084853,-0.32143 -22.153983,9.22592 -22.475426,21.31078 -0.321436,12.08486 9.225928,22.15398 21.310779,22.47542 12.084855,0.32145 22.153988,-9.22592 22.475424,-21.31077 0.32144,-12.08485 -9.225924,-22.15399 -21.310777,-22.47543 z m 0.266633,6.3556 c 8.505744,0.22625 15.242309,7.26703 15.016068,15.77277 -0.226238,8.50574 -7.329218,15.24065 -15.834957,15.01441 -8.505745,-0.22624 -15.240653,-7.32922 -15.014413,-15.83496 0.22624,-8.50574 7.327562,-15.17846 15.833302,-14.95222 z"
+ id="path3889"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path3873"
+ d="m 89.886535,933.91821 c -6.873465,-0.0451 -29.669767,13.04416 -28.269045,21.59071 8.448271,51.54748 20.314752,24.86411 27.188216,24.90922 6.873457,0.0451 20.017114,-14.14534 20.062234,-21.0188 0.0451,-6.87346 -12.107945,-25.43602 -18.981405,-25.48113 z m -1.289665,17.07717 c 4.837788,0.0317 8.747453,3.95747 8.715743,8.79521 -0.03176,4.83779 -3.992843,8.74722 -8.830608,8.71549 -4.837779,-0.0317 -8.747217,-3.99284 -8.715488,-8.8306 0.03176,-4.83779 3.992612,-8.71184 8.830389,-8.6801 z"
+ style="opacity:0.1;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ssssssssss"
+ inkscape:transform-center-x="1.5911461"
+ inkscape:transform-center-y="0.79011717" />
+ <path
+ sodipodi:nodetypes="ssssssssss"
+ inkscape:connector-curvature="0"
+ style="opacity:0.15;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ d="m 88.450012,936.44256 c -9.751089,-0.064 -26.145474,11.53811 -26.20947,21.28921 -0.06399,9.75109 16.135765,27.80218 25.886857,27.86618 9.751092,0.064 29.163801,-17.07565 29.227791,-26.82673 0.064,-9.75109 -19.154087,-22.26466 -28.905178,-22.32866 z m 0.147457,10.40633 c 6.86316,0.0451 12.409641,5.61429 12.364601,12.47744 -0.045,6.86317 -5.664476,12.40931 -12.527653,12.36425 -6.863157,-0.0451 -12.409306,-5.66448 -12.364247,-12.52765 0.04504,-6.86316 5.664147,-12.35912 12.527303,-12.31408 z"
+ id="path3875"
+ inkscape:transform-center-x="-0.37047638"
+ inkscape:transform-center-y="0.96971637" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path3877"
+ d="m 88.020144,937.20129 c -12.088871,-0.0794 -21.964769,9.66777 -22.044146,21.75661 -0.07933,12.08886 9.667775,21.96476 21.756604,22.04414 12.088866,0.0794 21.964768,-9.66777 22.044148,-21.75659 0.0794,-12.08887 -9.66778,-21.96477 -21.756606,-22.04415 z m 0.393866,6.34899 c 8.508569,0.0559 15.38479,6.9603 15.32896,15.46886 -0.0558,8.50857 -7.022512,15.38438 -15.5311,15.32851 -8.508569,-0.0559 -15.384386,-7.02251 -15.328516,-15.53111 0.05584,-8.50855 7.022096,-15.32216 15.530664,-15.26632 z"
+ style="opacity:0.3;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ inkscape:transform-center-x="0.45141933"
+ inkscape:transform-center-y="0.14907012" />
+ <path
+ id="path3849-3"
+ d="m 150.94899,935.04747 c -6.81416,0.90212 -27.59013,17.00676 -25.0255,25.27889 15.46827,49.89224 23.54608,21.82879 30.36023,20.92667 6.81415,-0.90212 17.87781,-16.76782 16.97569,-23.58197 -0.90212,-6.81415 -15.49627,-23.52571 -22.31042,-22.62359 z m 1.07497,17.09204 c 4.79605,-0.63495 9.20919,2.71479 9.84415,7.51084 0.63494,4.79604 -2.74987,9.21384 -7.54592,9.84878 -4.79604,0.63495 -9.21384,-2.74987 -9.84877,-7.54591 -0.63495,-4.79604 2.75451,-9.17877 7.55054,-9.81371 z"
+ style="opacity:0.1;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ssssssssss"
+ inkscape:transform-center-x="1.2488847"
+ inkscape:transform-center-y="1.6449717" />
+ <path
+ sodipodi:nodetypes="ssssssssss"
+ inkscape:connector-curvature="0"
+ style="opacity:0.15;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ d="m 149.87389,937.74564 c -9.66696,1.2798 -24.30689,15.02961 -23.02709,24.69656 1.2798,9.66695 19.81163,25.31453 29.47859,24.03469 9.66694,-1.2798 26.53366,-20.93011 25.25385,-30.59707 -1.2798,-9.66694 -22.0384,-19.41398 -31.70535,-18.13418 z m 1.5795,10.28681 c 6.80394,-0.90077 13.0647,3.85137 13.96547,10.65531 0.90077,6.80395 -3.90112,13.07129 -10.70507,13.97205 -6.80393,0.90077 -13.07128,-3.90112 -13.97204,-10.70506 -0.90078,-6.80394 3.90771,-13.02153 10.71164,-13.9223 z"
+ id="path3851-2"
+ inkscape:transform-center-x="-0.76139378"
+ inkscape:transform-center-y="1.4830543" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path3853"
+ d="m 149.55262,938.55636 c -11.98455,1.58662 -20.42367,12.6012 -18.83704,24.58576 1.58663,11.98455 12.60121,20.42367 24.58576,18.83704 11.98457,-1.58662 20.42368,-12.6012 18.83705,-24.58576 -1.58663,-11.98456 -12.60121,-20.42367 -24.58577,-18.83704 z m 1.26468,6.23421 c 8.43515,-1.11673 16.1969,4.77472 17.31362,13.20987 1.11673,8.43515 -4.8364,16.20507 -13.27155,17.32179 -8.43515,1.11672 -16.20507,-4.83641 -17.32179,-13.27155 -1.11672,-8.43515 4.84457,-16.14339 13.27972,-17.26011 z"
+ style="opacity:0.3;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ inkscape:transform-center-x="0.00048976323"
+ inkscape:transform-center-y="0.70302153" />
+ <path
+ inkscape:transform-center-y="1.533628"
+ inkscape:transform-center-x="1.7524685"
+ sodipodi:nodetypes="ssssssssss"
+ inkscape:connector-curvature="0"
+ style="opacity:0.1;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ d="m 181.91988,869.75574 c -6.85819,0.46021 -28.63077,15.1896 -26.60568,23.61008 12.21414,50.78701 22.08731,23.30375 28.9455,22.84353 6.85819,-0.4602 18.9233,-15.57833 18.46309,-22.43651 -0.4602,-6.85819 -13.94472,-24.4773 -20.80291,-24.0171 z m -0.031,17.12579 c 4.82704,-0.32392 9.01467,3.30383 9.33858,8.13086 0.3239,4.82702 -3.33913,9.01703 -8.16616,9.34093 -4.82703,0.32392 -9.01703,-3.33912 -9.34094,-8.16615 -0.32391,-4.82703 3.3415,-8.98174 8.16852,-9.30564 z"
+ id="path3861" />
+ <path
+ inkscape:transform-center-y="1.5345569"
+ inkscape:transform-center-x="-0.24074801"
+ id="path3863"
+ d="m 180.67279,872.37886 c -9.72943,0.65287 -25.22672,13.42859 -24.57384,23.15801 0.65287,9.72942 18.13557,26.54101 27.86499,25.88814 9.72942,-0.65288 27.82987,-19.17299 27.17699,-28.9024 -0.65287,-9.72942 -20.73873,-20.79663 -30.46814,-20.14375 z m 0.91192,10.36734 c 6.84791,-0.45953 12.78873,4.687 13.24824,11.5349 0.45952,6.84792 -4.73708,12.79209 -11.58498,13.2516 -6.8479,0.45952 -12.79208,-4.73707 -13.2516,-11.58498 -0.45951,-6.8479 4.74044,-12.74201 11.58834,-13.20152 z"
+ style="opacity:0.15;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ssssssssss" />
+ <path
+ inkscape:transform-center-y="0.73102307"
+ inkscape:transform-center-x="0.5515962"
+ style="opacity:0.3;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ d="m 180.29985,873.16714 c -12.06201,0.8094 -21.19479,11.25602 -20.38539,23.31802 0.8094,12.062 11.25603,21.19478 23.31803,20.38538 12.062,-0.8094 21.19478,-11.25602 20.38537,-23.31802 -0.8094,-12.062 -11.25601,-21.19478 -23.31801,-20.38538 z m 0.85945,6.30286 c 8.48965,-0.56968 15.85475,5.81069 16.42444,14.30035 0.56969,8.48966 -5.87277,15.85892 -14.36243,16.42861 -8.48966,0.56968 -15.85892,-5.87277 -16.42861,-14.36243 -0.56968,-8.48966 5.87694,-15.79684 14.3666,-16.36653 z"
+ id="path3865"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ssssssssss"
+ inkscape:connector-curvature="0"
+ style="opacity:0.1;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ d="m 119.04536,848.55648 c -6.8736,0 -29.583513,13.23862 -28.126733,21.77578 8.786393,51.49083 20.477503,24.73026 27.351113,24.73026 6.8736,0 19.92385,-14.27641 19.92385,-21.15002 0,-6.87361 -12.27461,-25.35602 -19.14823,-25.35602 z m -1.17755,17.08528 c 4.83789,0 8.77323,3.89998 8.77323,8.73786 0,4.83788 -3.93534,8.77323 -8.77323,8.77323 -4.83788,0 -8.77324,-3.93535 -8.77324,-8.77323 0,-4.83788 3.93536,-8.73786 8.77324,-8.73786 z"
+ id="path3077" />
+ <path
+ id="path3075"
+ d="m 117.62544,851.09021 c -9.7513,0 -26.069186,11.70947 -26.069186,21.46077 0,9.7513 16.317886,27.69569 26.069186,27.69569 9.75131,0 27.30499,-18.72177 27.30499,-28.47307 0,-9.7513 -17.55368,-20.68339 -27.30499,-20.68339 z m 0.21576,10.40513 c 6.86331,0 12.44622,5.53273 12.44622,12.39604 0,6.86331 -5.58291,12.44622 -12.44622,12.44622 -6.8633,0 -12.44621,-5.58291 -12.44621,-12.44622 0,-6.86331 5.58291,-12.39604 12.44621,-12.39604 z"
+ style="opacity:0.15;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ssssssssss" />
+ <path
+ style="opacity:0.3;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ d="m 117.20056,851.85176 c -12.08913,0 -21.900844,9.81171 -21.900844,21.90084 0,12.08912 9.811714,21.90084 21.900844,21.90084 12.08913,0 21.90085,-9.81172 21.90085,-21.90084 0,-12.08913 -9.81172,-21.90084 -21.90085,-21.90084 z m 0.43553,6.34626 c 8.50875,0 15.43014,6.85918 15.43014,15.36792 0,8.50876 -6.92139,15.43014 -15.43014,15.43014 -8.50875,0 -15.43014,-6.92138 -15.43014,-15.43014 0,-8.50874 6.92139,-15.36792 15.43014,-15.36792 z"
+ id="path3065"
+ inkscape:connector-curvature="0" />
+ <g
+ id="layer2"
+ style="display:none"
+ transform="matrix(2.3378535,0,0,2.3378535,15.409894,807.74843)">
+ <rect
+ width="86"
+ height="85"
+ rx="6"
+ ry="6"
+ x="5"
+ y="7"
+ clip-path="url(#clipPath3625)"
+ id="rect3745-1"
+ style="opacity:0.9;fill:url(#ButtonShadow-6);fill-opacity:1;fill-rule:nonzero;stroke:none;filter:url(#filter3174-7)" />
+ </g>
+ <g
+ id="layer1-5"
+ style="display:none"
+ transform="matrix(2.3378535,0,0,2.3378535,15.409894,807.74843)">
+ <rect
+ width="84"
+ height="84"
+ rx="6"
+ ry="6"
+ x="6"
+ y="6"
+ id="rect2419-9"
+ style="opacity:0.8;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none" />
+ <path
+ d="m 14,10 c -2.216,0 -4,1.784 -4,4 l 0,68 c 0,2.216 1.784,4 4,4 l 68,0 c 2.216,0 4,-1.784 4,-4 l 0,-68 c 0,-2.216 -1.784,-4 -4,-4 l -68,0 z m 0,3.0625 68,0 c 0.578769,0 0.9375,0.358731 0.9375,0.9375 l 0,68 c 0,0.578769 -0.358731,0.9375 -0.9375,0.9375 l -68,0 c -0.578769,0 -0.9375,-0.358731 -0.9375,-0.9375 l 0,-68 c 0,-0.578769 0.358731,-0.9375 0.9375,-0.9375 z"
+ inkscape:connector-curvature="0"
+ id="rect3726"
+ style="opacity:0.07999998;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none" />
+ <path
+ d="M 12,6 C 8.676,6 6,8.676 6,12 l 0,72 c 0,3.324 2.676,6 6,6 l 72,0 c 3.324,0 6,-2.676 6,-6 L 90,12 C 90,8.676 87.324,6 84,6 L 12,6 z m 2,4 68,0 c 2.216,0 4,1.784 4,4 l 0,68 c 0,2.216 -1.784,4 -4,4 l -68,0 c -2.216,0 -4,-1.784 -4,-4 l 0,-68 c 0,-2.216 1.784,-4 4,-4 z"
+ inkscape:connector-curvature="0"
+ id="rect3629"
+ style="fill:url(#linearGradient3643);fill-opacity:1;fill-rule:nonzero;stroke:none" />
+ <path
+ d="M 12,6 C 8.676,6 6,8.676 6,12 l 0,2 0,68 0,2 c 0,0.334721 0.04135,0.6507 0.09375,0.96875 0.0487,0.295596 0.09704,0.596915 0.1875,0.875 0.00988,0.03038 0.020892,0.0636 0.03125,0.09375 0.098865,0.287771 0.2348802,0.547452 0.375,0.8125 0.1445918,0.273507 0.3156161,0.535615 0.5,0.78125 0.1843839,0.245635 0.3737765,0.473472 0.59375,0.6875 0.439947,0.428056 0.94291,0.814526 1.5,1.09375 0.278545,0.139612 0.5734731,0.246947 0.875,0.34375 -0.2562018,-0.100222 -0.4867109,-0.236272 -0.71875,-0.375 -0.00741,-0.0044 -0.023866,0.0045 -0.03125,0 -0.031933,-0.0193 -0.062293,-0.04251 -0.09375,-0.0625 -0.120395,-0.0767 -0.2310226,-0.163513 -0.34375,-0.25 -0.1061728,-0.0808 -0.2132809,-0.161112 -0.3125,-0.25 C 8.4783201,88.557317 8.3087904,88.373362 8.15625,88.1875 8.0486711,88.057245 7.9378561,87.922215 7.84375,87.78125 7.818661,87.74287 7.805304,87.69538 7.78125,87.65625 7.716487,87.553218 7.6510225,87.451733 7.59375,87.34375 7.4927417,87.149044 7.3880752,86.928049 7.3125,86.71875 7.30454,86.69694 7.288911,86.6782 7.28125,86.65625 7.2494249,86.5643 7.2454455,86.469419 7.21875,86.375 7.1884177,86.268382 7.1483606,86.171969 7.125,86.0625 7.0521214,85.720988 7,85.364295 7,85 L 7,83 7,15 7,13 C 7,10.218152 9.2181517,8 12,8 l 2,0 68,0 2,0 c 2.781848,0 5,2.218152 5,5 l 0,2 0,68 0,2 c 0,0.364295 -0.05212,0.720988 -0.125,1.0625 -0.04415,0.206893 -0.08838,0.397658 -0.15625,0.59375 -0.0077,0.02195 -0.0233,0.04069 -0.03125,0.0625 -0.06274,0.173739 -0.138383,0.367449 -0.21875,0.53125 -0.04158,0.0828 -0.07904,0.169954 -0.125,0.25 -0.0546,0.09721 -0.126774,0.18835 -0.1875,0.28125 -0.09411,0.140965 -0.204921,0.275995 -0.3125,0.40625 -0.143174,0.17445 -0.303141,0.346998 -0.46875,0.5 -0.01117,0.0102 -0.01998,0.02115 -0.03125,0.03125 -0.138386,0.125556 -0.285091,0.234436 -0.4375,0.34375 -0.102571,0.07315 -0.204318,0.153364 -0.3125,0.21875 -0.0074,0.0045 -0.02384,-0.0044 -0.03125,0 -0.232039,0.138728 -0.462548,0.274778 -0.71875,0.375 0.301527,-0.0968 0.596455,-0.204138 0.875,-0.34375 0.55709,-0.279224 1.060053,-0.665694 1.5,-1.09375 0.219973,-0.214028 0.409366,-0.441865 0.59375,-0.6875 0.184384,-0.245635 0.355408,-0.507743 0.5,-0.78125 0.14012,-0.265048 0.276135,-0.524729 0.375,-0.8125 0.01041,-0.03078 0.02133,-0.06274 0.03125,-0.09375 0.09046,-0.278085 0.1388,-0.579404 0.1875,-0.875 C 89.95865,84.6507 90,84.334721 90,84 l 0,-2 0,-68 0,-2 C 90,8.676 87.324,6 84,6 L 12,6 z"
+ inkscape:connector-curvature="0"
+ id="rect3728-9"
+ style="fill:url(#linearGradient3188-6);fill-opacity:1;fill-rule:nonzero;stroke:none" />
+ <path
+ d="M 12,90 C 8.676,90 6,87.324 6,84 L 6,82 6,14 6,12 c 0,-0.334721 0.04135,-0.6507 0.09375,-0.96875 0.0487,-0.295596 0.09704,-0.596915 0.1875,-0.875 C 6.29113,10.12587 6.302142,10.09265 6.3125,10.0625 6.411365,9.774729 6.5473802,9.515048 6.6875,9.25 6.8320918,8.976493 7.0031161,8.714385 7.1875,8.46875 7.3718839,8.223115 7.5612765,7.995278 7.78125,7.78125 8.221197,7.353194 8.72416,6.966724 9.28125,6.6875 9.559795,6.547888 9.8547231,6.440553 10.15625,6.34375 9.9000482,6.443972 9.6695391,6.580022 9.4375,6.71875 c -0.00741,0.0044 -0.023866,-0.0045 -0.03125,0 -0.031933,0.0193 -0.062293,0.04251 -0.09375,0.0625 -0.120395,0.0767 -0.2310226,0.163513 -0.34375,0.25 -0.1061728,0.0808 -0.2132809,0.161112 -0.3125,0.25 C 8.4783201,7.442683 8.3087904,7.626638 8.15625,7.8125 8.0486711,7.942755 7.9378561,8.077785 7.84375,8.21875 7.818661,8.25713 7.805304,8.30462 7.78125,8.34375 7.716487,8.446782 7.6510225,8.548267 7.59375,8.65625 7.4927417,8.850956 7.3880752,9.071951 7.3125,9.28125 7.30454,9.30306 7.288911,9.3218 7.28125,9.34375 7.2494249,9.4357 7.2454455,9.530581 7.21875,9.625 7.1884177,9.731618 7.1483606,9.828031 7.125,9.9375 7.0521214,10.279012 7,10.635705 7,11 l 0,2 0,68 0,2 c 0,2.781848 2.2181517,5 5,5 l 2,0 68,0 2,0 c 2.781848,0 5,-2.218152 5,-5 l 0,-2 0,-68 0,-2 C 89,10.635705 88.94788,10.279012 88.875,9.9375 88.83085,9.730607 88.78662,9.539842 88.71875,9.34375 88.71105,9.3218 88.69545,9.30306 88.6875,9.28125 88.62476,9.107511 88.549117,8.913801 88.46875,8.75 88.42717,8.6672 88.38971,8.580046 88.34375,8.5 88.28915,8.40279 88.216976,8.31165 88.15625,8.21875 88.06214,8.077785 87.951329,7.942755 87.84375,7.8125 87.700576,7.63805 87.540609,7.465502 87.375,7.3125 87.36383,7.3023 87.35502,7.29135 87.34375,7.28125 87.205364,7.155694 87.058659,7.046814 86.90625,6.9375 86.803679,6.86435 86.701932,6.784136 86.59375,6.71875 c -0.0074,-0.0045 -0.02384,0.0044 -0.03125,0 -0.232039,-0.138728 -0.462548,-0.274778 -0.71875,-0.375 0.301527,0.0968 0.596455,0.204138 0.875,0.34375 0.55709,0.279224 1.060053,0.665694 1.5,1.09375 0.219973,0.214028 0.409366,0.441865 0.59375,0.6875 0.184384,0.245635 0.355408,0.507743 0.5,0.78125 0.14012,0.265048 0.276135,0.524729 0.375,0.8125 0.01041,0.03078 0.02133,0.06274 0.03125,0.09375 0.09046,0.278085 0.1388,0.579404 0.1875,0.875 C 89.95865,11.3493 90,11.665279 90,12 l 0,2 0,68 0,2 c 0,3.324 -2.676,6 -6,6 l -72,0 z"
+ inkscape:connector-curvature="0"
+ id="path3615-1"
+ style="opacity:0.6;fill:url(#radialGradient3619-2);fill-opacity:1;fill-rule:nonzero;stroke:none" />
+ <rect
+ width="84"
+ height="84"
+ rx="6"
+ ry="6"
+ x="6"
+ y="106"
+ id="rect2841"
+ style="fill:url(#linearGradient2843);fill-opacity:1;fill-rule:nonzero;stroke:none" />
+ <rect
+ width="76"
+ height="76"
+ rx="4"
+ ry="4"
+ x="10"
+ y="110"
+ id="rect3634"
+ style="fill:#ff0000;fill-opacity:1;fill-rule:nonzero;stroke:none" />
+ <path
+ d="m 14,9 c -2.752703,0 -5,2.247297 -5,5 l 0,68 c 0,2.752703 2.247297,5 5,5 l 68,0 c 2.752703,0 5,-2.247297 5,-5 L 87,14 C 87,11.247297 84.752703,9 82,9 L 14,9 z m 0,2 68,0 c 1.679297,0 3,1.320703 3,3 l 0,68 c 0,1.679297 -1.320703,3 -3,3 l -68,0 c -1.679297,0 -3,-1.320703 -3,-3 l 0,-68 c 0,-1.679297 1.320703,-3 3,-3 z"
+ inkscape:connector-curvature="0"
+ transform="translate(-110,0)"
+ clip-path="url(#clipPath3649)"
+ id="rect3647"
+ style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;color:#000000;fill:#000000;fill-opacity:1;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;filter:url(#filter3657);enable-background:accumulate;font-family:Abandoned Bitplane;-inkscape-font-specification:Abandoned Bitplane" />
+ <path
+ d="m 14.089286,10 c -2.216,0 -4,1.784 -4,4 l 0,68 c 0,2.216 1.784,4 4,4 l 68,0 c 2.216,0 4,-1.784 4,-4 l 0,-68 c 0,-2.216 -1.784,-4 -4,-4 l -68,0 z m 0,2 68,0 c 1.140301,0 2,0.859699 2,2 l 0,68 c 0,1.140301 -0.859699,2 -2,2 l -68,0 c -1.140301,0 -2,-0.859699 -2,-2 l 0,-68 c 0,-1.140301 0.859699,-2 2,-2 z"
+ inkscape:connector-curvature="0"
+ id="path3709"
+ style="opacity:0.16000001;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none" />
+ <path
+ d="m 14,10 c -2.216,0 -4,1.784 -4,4 l 0,68 c 0,2.216 1.784,4 4,4 l 68,0 c 2.216,0 4,-1.784 4,-4 l 0,-68 c 0,-2.216 -1.784,-4 -4,-4 l -68,0 z m 0,1 68,0 c 1.673848,0 3,1.326152 3,3 l 0,68 c 0,1.673848 -1.326152,3 -3,3 l -68,0 c -1.673848,0 -3,-1.326152 -3,-3 l 0,-68 c 0,-1.673848 1.326152,-3 3,-3 z"
+ inkscape:connector-curvature="0"
+ id="path3707"
+ style="opacity:0.36000001;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none" />
+ </g>
+ <g
+ id="layer5"
+ style="display:none"
+ transform="matrix(2.3378535,0,0,2.3378535,15.409894,807.74843)">
+ <rect
+ width="66"
+ height="66"
+ rx="12"
+ ry="12"
+ x="15"
+ y="15"
+ clip-path="url(#clipPath3613-8)"
+ id="rect3171-4"
+ style="opacity:0.1;fill:url(#linearGradient3613-7);fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:0.5;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;filter:url(#filter3794-9)" />
+ </g>
+ <path
+ style="opacity:0.1;fill:#000000;fill-opacity:1;stroke:none;display:inline"
+ d="m 172.25903,847.18043 -4.30145,6.48111 c 13.49767,6.26007 40.73811,35.36404 40.73811,61.31558 0,6.12517 -5.37494,24.04545 -5.37494,24.04545 0,0 4.68391,0.85374 8.38452,1.33104 5.21603,0.23106 7.66416,-1.02748 8.34471,-4.86723 0.55146,-6.16885 0.90041,-11.4775 0.95035,-17.0913 0.26219,-29.47263 -18.20682,-57.11834 -41.52864,-72.49179 -2.53292,-1.79041 -5.66502,-1.01375 -7.21266,1.27714 z"
+ id="path3999"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccscccscc" />
+ <path
+ style="opacity:0.1;fill:#000000;fill-opacity:1;stroke:none;display:inline"
+ d="m 174.96257,857.47233 c -12.74039,-7.6849 -39.83705,-17.81278 -55.7453,-17.81278 -46.637452,0 -84.703198,38.06573 -84.703198,84.70319 0,46.63746 38.065746,84.70326 84.703198,84.70326 40.93626,0 79.05889,-41.6602 86.83779,-80.36686 -7.91764,-2.4047 -52.42628,-12.66797 -55.21221,-17.44969 -2.4361,-4.0743 26.07507,-52.63261 24.11972,-53.77712 z m 8.84576,80.97604 c -7.92488,31.60452 -30.90104,55.20576 -64.96393,55.20576 -0.19604,0 -0.36362,0 -0.5593,0 -0.19568,0 -0.4254,0 -0.62145,0 -40.188056,0 -72.771417,-32.52129 -72.771417,-72.70935 0,-40.18805 32.583361,-72.77142 72.771417,-72.77142 0.19605,0 0.42577,-0.002 0.62145,0 0.19568,-0.002 0.36326,0 0.5593,0 14.23652,0 22.1995,8.46397 29.19588,10.29177 l -38.42815,67.49291 z"
+ id="path3923"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="csssccccscssscsccc" />
+ <path
+ style="opacity:0.15;fill:#000000;fill-opacity:1;stroke:none;display:inline"
+ d="m 160.97849,854.38783 c -12.26504,-7.34334 -26.45244,-11.86963 -41.76122,-11.86963 -45.125073,0 -81.844544,36.71946 -81.844544,81.84454 0,45.12508 36.719471,81.84466 81.844544,81.84466 39.59192,0 69.35899,-28.42693 76.88207,-65.83255 l -6.90716,-1.78098 c -7.92488,31.60453 -36.28489,55.06026 -70.34778,55.06026 -40.188058,0 -72.771418,-32.52129 -72.771418,-72.70935 0,-40.18805 32.58336,-72.77142 72.771418,-72.77142 12.418,0 27.50457,3.44108 38.92183,9.18053 0.46752,0.23502 -49.851,66.42262 -49.851,66.42262 l 9.94354,2.35704 c 0,0 44.83688,-64.25324 45.83879,-65.49233 0.9462,-2.80938 -0.53242,-4.66991 -2.71907,-6.25339 z"
+ id="path3989"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="csssccsssscccc" />
+ <path
+ style="opacity:0.15;fill:#000000;fill-opacity:1;stroke:none;display:inline"
+ d="m 178.05836,848.42017 -3.01709,4.78719 c 20.44574,12.88075 33.65442,35.81822 33.65442,61.76976 0,6.12517 -28.57332,1.77979 -24.85383,6.63977 l -31.06661,-24.91262 28.92453,-44.25316 c -2.30707,-0.94076 -3.94679,-8.40069 -8.32474,-1.82263 l -49.02398,72.13834 84.3417,15.10241 c 4.12138,0.44874 7.29897,-1.03001 7.83316,-3.31653 1.05138,-5.22761 1.55362,-10.62447 1.55362,-16.15762 0,-29.8163 -16.13305,-55.67259 -40.02118,-69.97491 z"
+ id="path3919"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccscccccccsc" />
+ <path
+ style="opacity:0.3;fill:#000000;fill-opacity:1;stroke:none;display:inline"
+ d="m 159.72196,856.44164 c -11.75236,-6.99883 -25.84058,-10.69192 -40.50469,-10.69192 -43.395256,0 -78.61302,35.21776 -78.61302,78.61302 0,43.39526 35.217764,78.61306 78.61302,78.61306 38.07612,0 69.77938,-27.11718 76.99726,-63.07689 l -7.45736,-1.36718 c -8.18744,31.22222 -36.30762,54.37666 -70.0992,54.37666 -40.188062,0 -72.771422,-32.58343 -72.771422,-72.77148 0,-40.18807 32.58336,-72.77143 72.771422,-72.77143 14.46493,0 27.59378,4.12647 38.92227,11.4028 0.2726,0.20007 -51.56013,66.32056 -51.56013,66.32056 l 8.52596,1.34475 c 0,0 45.56903,-66.26973 45.66472,-66.4028 0.79572,-1.10652 0.58358,-2.98105 -0.48883,-3.58915 z"
+ id="path4002"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="csssccssscccsc" />
+ <path
+ style="opacity:0.3;fill:#000000;fill-opacity:1;stroke:none;display:inline"
+ d="m 176.25616,851.09239 -1.30503,1.92648 c 20.14554,12.93954 33.55813,35.42724 33.55813,61.15037 0,6.39648 -71.14055,-2.9614 -72.69036,2.94873 l -5.20311,4.20384 79.81517,14.51055 c 1.65861,0.10749 2.50628,-0.63865 2.86344,-1.90111 1.00832,-5.02349 1.61575,-10.21703 1.61575,-15.53617 0,-28.73116 -15.62778,-53.59 -38.65399,-67.30269 z"
+ id="path3913"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccsccccsc" />
+ <path
+ style="fill:url(#linearGradient3573);fill-opacity:1;stroke:none;display:inline"
+ d="m 119.21727,842.70464 c -43.395256,0 -78.61302,35.21775 -78.61302,78.61301 0,43.39527 35.217764,78.61305 78.61302,78.61305 37.0103,0 67.85105,-25.69845 76.18938,-60.15608 l -81.96883,-15.22544 47.2921,-69.72634 c -12.07584,-7.56035 -26.22295,-12.1182 -41.51265,-12.1182 z m -2.17506,12.36678 c 9.80653,0 17.77338,7.9047 17.77338,17.71124 0,9.80652 -7.03469,17.27622 -16.84121,17.27622 -9.80653,0 -18.705554,-7.4697 -18.705554,-17.27622 0,-9.80654 7.966854,-17.71124 17.773384,-17.71124 z M 74.597388,884.528 c 2.862434,-0.0668 5.787585,0.58897 8.513821,1.98863 8.723958,4.4789 12.184839,15.1396 7.70594,23.86356 -4.478898,8.72396 -15.201746,12.1227 -23.925701,7.6438 -8.723957,-4.4789 -12.18484,-15.1396 -7.70594,-23.86357 3.079244,-5.99772 9.114531,-9.48553 15.41188,-9.63242 z m 13.298961,56.80024 c 4.54423,0.003 9.087931,1.68904 12.553221,5.158 6.93059,6.93794 6.93794,18.17586 0,25.10646 -6.937928,6.93058 -18.175856,6.93793 -25.106446,0 -6.930587,-6.93794 -6.937933,-18.17587 0,-25.10646 3.468968,-3.46529 8.008996,-5.16041 12.553225,-5.158 z m 63.574011,0.68359 c 5.6968,-0.19274 11.43815,2.3733 15.03902,7.33307 5.76138,7.93564 3.95837,19.03434 -3.97727,24.79573 -7.93564,5.76139 -19.03434,3.95838 -24.79572,-3.97726 -5.76139,-7.93564 -4.02053,-18.97219 3.91511,-24.73358 2.97587,-2.16052 6.40078,-3.30231 9.81886,-3.41796 z"
+ id="path3971"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:url(#linearGradient3570);fill-opacity:1;stroke:none;display:inline"
+ d="m 177.80978,848.85518 -47.2921,69.72633 81.96883,15.22545 c 1.43851,-5.94458 2.42364,-12.07202 2.42364,-18.45697 0,-28.10556 -14.90254,-52.59736 -37.10037,-66.49481 z m 4.22584,27.46794 c 6.91914,0.0815 13.49677,4.2546 16.28191,11.06176 3.71352,9.07622 -0.61835,19.4043 -9.69458,23.11782 -9.07622,3.71352 -19.46645,-0.61835 -23.17996,-9.69457 -3.71352,-9.07622 0.61835,-19.46645 9.69457,-23.17996 2.26906,-0.92838 4.59168,-1.33221 6.89806,-1.30505 z"
+ id="path2505"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.15;fill:#000000;fill-opacity:1;stroke:none;display:inline"
+ d="m 194.59877,939.58819 c -9.32186,33.0178 -39.3946,57.35955 -75.3815,57.35955 -42.890931,0 -77.807532,-34.42206 -78.61302,-77.12156 -0.0094,0.50207 0,0.98715 0,1.49147 0,43.39526 35.217764,78.61305 78.61302,78.61305 37.01398,0 67.85331,-25.69183 76.18938,-60.15608 l -0.80788,-0.18643 z"
+ id="path4013"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.15;fill:#000000;fill-opacity:1;stroke:none;display:inline"
+ d="m 212.16736,931.48554 0.80788,0.18643 c 1.43715,-5.9417 1.88348,-12.30719 1.88347,-18.68847 0,-0.50433 -0.22216,-1.09229 -0.23151,-1.59437 -0.12965,6.87323 -0.67145,13.76199 -2.45984,20.09641 z"
+ id="path3904"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccscc" />
+ <path
+ style="opacity:0.75;fill:#ffffff;fill-opacity:1;stroke:none;display:inline"
+ d="m 160.72992,854.82284 c -12.07692,-7.56143 -26.22295,-12.1182 -41.51265,-12.1182 -43.395256,0 -78.61302,35.21775 -78.61302,78.61301 0,0.50433 -0.0094,1.05154 0,1.55361 0.805488,-42.6995 35.722089,-77.12154 78.61302,-77.12154 14.67425,0 28.26022,4.23973 40.02118,11.24819 l 1.49147,-2.17507 z"
+ id="path4010"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.75;fill:#ffffff;fill-opacity:1;stroke:none;display:inline"
+ d="m 177.80978,848.85518 -1.49147,2.17506 c 22.6148,13.47638 38.06194,37.78261 38.59184,65.87337 0.01,-0.50208 0,-1.0493 0,-1.55362 0,-28.10557 -14.90056,-52.59537 -37.10037,-66.49481 z"
+ id="path3888"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.75;fill:#ffffff;fill-opacity:1;stroke:none;display:inline"
+ id="path3890"
+ inkscape:connector-curvature="0"
+ d="m 117.11796,892.2103 c -9.8578,0 -17.950958,-7.23805 -17.926766,-19.92596 2.25e-4,-0.11811 -0.0022,-0.23653 0,-0.35413 0.182974,10.00215 8.080886,18.28567 17.824136,18.28567 9.74324,0 17.92728,-7.24612 17.89254,-18.28567 0.003,0.1176 -2.3e-4,0.23599 0,0.35413 0.0242,12.42856 -7.93211,19.92596 -17.78991,19.92596 z"
+ sodipodi:nodetypes="sscscss" />
+ <path
+ sodipodi:nodetypes="sscscss"
+ d="m 117.04953,853.73487 c 9.8578,0 17.88253,7.71701 17.85834,20.40493 -2.3e-4,0.1181 0.003,0.23652 0,0.35413 -0.18297,-10.00215 -8.08089,-18.08041 -17.82413,-18.08041 -9.74323,0 -17.927291,7.04085 -17.892549,18.08041 -0.0022,-0.11761 2.32e-4,-0.236 0,-0.35413 -0.02418,-12.42857 8.000539,-20.40493 17.858339,-20.40493 z"
+ inkscape:connector-curvature="0"
+ id="path3892"
+ style="opacity:0.15;fill:#000000;fill-opacity:1;stroke:none;display:inline" />
+ <path
+ sodipodi:nodetypes="sscscss"
+ d="m 154.76757,978.57664 c -9.77254,1.29378 -18.74564,-4.81947 -20.38687,-17.40082 -0.0153,-0.11711 -0.0333,-0.23419 -0.0464,-0.35107 1.49411,9.89162 10.41088,17.06693 20.06984,15.78819 9.65896,-1.27874 16.82121,-9.53629 15.33789,-20.4758 0.0175,0.1163 0.0308,0.23398 0.0464,0.35107 1.65515,12.31789 -5.24833,20.79465 -15.02086,22.08843 z"
+ inkscape:connector-curvature="0"
+ id="path3855"
+ style="opacity:0.75;fill:#ffffff;fill-opacity:1;stroke:none;display:inline"
+ inkscape:transform-center-x="0.10437309"
+ inkscape:transform-center-y="3.7717298" />
+ <path
+ style="opacity:0.15;fill:#000000;fill-opacity:1;stroke:none;display:inline"
+ id="path3857"
+ inkscape:connector-curvature="0"
+ d="m 149.65005,940.44301 c 9.77254,-1.29378 18.74066,5.30328 20.3819,17.88461 0.0153,0.11712 0.0333,0.2342 0.0464,0.35107 -1.49411,-9.89162 -10.38394,-16.86344 -20.04291,-15.58469 -9.65896,1.27874 -16.84814,9.33279 -15.36482,20.2723 -0.0175,-0.1163 -0.0307,-0.23398 -0.0464,-0.35107 -1.65515,-12.31788 5.25329,-21.27844 15.02583,-22.57222 z"
+ sodipodi:nodetypes="sscscss"
+ inkscape:transform-center-x="0.085342765"
+ inkscape:transform-center-y="-2.9084878" />
+ <path
+ inkscape:transform-center-y="4.0380281"
+ inkscape:transform-center-x="0.64879679"
+ style="opacity:0.75;fill:#ffffff;fill-opacity:1;stroke:none;display:inline"
+ id="path3867"
+ inkscape:connector-curvature="0"
+ d="m 182.91954,913.44065 c -9.83568,0.66001 -18.39528,-6.01994 -19.22064,-18.68101 -0.008,-0.11784 -0.0181,-0.23584 -0.0237,-0.35333 0.85223,9.96745 9.28703,17.70361 19.00842,17.05127 9.72137,-0.65233 17.40191,-8.43014 16.62812,-19.4426 0.0101,0.11717 0.0155,0.23548 0.0237,0.35334 0.85625,12.39905 -6.58021,20.41232 -16.41589,21.07233 z"
+ sodipodi:nodetypes="sscscss" />
+ <path
+ inkscape:transform-center-y="-3.1313222"
+ inkscape:transform-center-x="0.61420118"
+ sodipodi:nodetypes="sscscss"
+ d="m 180.27523,875.05614 c 9.83568,-0.66001 18.35908,6.5024 19.18444,19.16347 0.008,0.11787 0.0181,0.23585 0.0237,0.35334 -0.85222,-9.96745 -9.27328,-17.4988 -18.99466,-16.84647 -9.72138,0.65233 -17.41567,8.22534 -16.64187,19.2378 -0.0101,-0.11717 -0.0155,-0.23548 -0.0237,-0.35333 -0.85626,-12.39907 6.61642,-20.8948 16.4521,-21.55481 z"
+ inkscape:connector-curvature="0"
+ id="path3869"
+ style="opacity:0.15;fill:#000000;fill-opacity:1;stroke:none;display:inline" />
+ <path
+ sodipodi:nodetypes="sscscss"
+ d="m 87.672668,977.55843 c -9.857587,-0.0647 -17.903062,-7.35571 -17.795601,-20.04319 0.001,-0.1181 -6.94e-4,-0.23653 0.0022,-0.35412 0.117329,10.00313 7.960704,18.33832 17.703732,18.40227 9.743027,0.064 17.974461,-7.12831 18.012161,-18.16786 0.002,0.11761 -0.002,0.23598 -0.003,0.35412 -0.0573,12.42846 -8.062707,19.87348 -17.920297,19.80878 z"
+ inkscape:connector-curvature="0"
+ id="path3879"
+ style="opacity:0.75;fill:#ffffff;fill-opacity:1;stroke:none;display:inline"
+ inkscape:transform-center-x="0.51152745"
+ inkscape:transform-center-y="3.6815103" />
+ <path
+ style="opacity:0.15;fill:#000000;fill-opacity:1;stroke:none;display:inline"
+ id="path3881"
+ inkscape:connector-curvature="0"
+ d="m 87.856754,939.08338 c 9.857592,0.0646 17.831506,7.8342 17.724046,20.52169 -8.5e-4,0.1181 6.9e-4,0.23653 -0.003,0.35412 -0.11731,-10.00313 -7.962058,-18.13305 -17.705094,-18.197 -9.743026,-0.064 -17.973112,6.92305 -18.010828,17.96259 -0.0014,-0.11762 0.0018,-0.23598 0.0022,-0.35412 0.05738,-12.42846 8.134277,-20.35199 17.991867,-20.28729 z"
+ sodipodi:nodetypes="sscscss"
+ inkscape:transform-center-x="0.51762959"
+ inkscape:transform-center-y="-3.9489544" />
+ <path
+ inkscape:transform-center-y="3.8878274"
+ inkscape:transform-center-x="-0.52053966"
+ style="opacity:0.75;fill:#ffffff;fill-opacity:1;stroke:none;display:inline"
+ id="path3891"
+ inkscape:connector-curvature="0"
+ d="m 74.635586,922.25169 c -9.854317,-0.2621 -17.752153,-7.71279 -17.390611,-20.39557 0.0034,-0.11805 0.0042,-0.23651 0.0093,-0.35401 -0.08305,10.00348 7.591829,18.49408 17.331629,18.75314 9.739791,0.25907 18.11362,-6.76688 18.372416,-17.80347 -8.5e-4,0.11761 -0.0065,0.23591 -0.0093,0.35401 -0.306291,12.42481 -8.459118,19.70801 -18.313435,19.4459 z"
+ sodipodi:nodetypes="sscscss" />
+ <path
+ inkscape:transform-center-y="-3.5900653"
+ inkscape:transform-center-x="-0.50061725"
+ sodipodi:nodetypes="sscscss"
+ d="m 75.590208,883.78805 c 9.854318,0.26211 17.671017,8.18975 17.309477,20.87254 -0.0034,0.11807 -0.0042,0.23651 -0.0093,0.35401 0.08305,-10.00348 -7.597287,-18.28889 -17.337087,-18.54794 -9.739791,-0.25907 -18.10816,6.56169 -18.366964,17.59827 8.5e-4,-0.11763 0.0065,-0.2359 0.0093,-0.35401 0.306293,-12.42482 8.540256,-20.18498 18.394571,-19.92287 z"
+ inkscape:connector-curvature="0"
+ id="path3893"
+ style="opacity:0.15;fill:#000000;fill-opacity:1;stroke:none;display:inline" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path4021"
+ d="m 194.74686,939.71515 c -30.31024,-5.98499 -84.21887,-15.7284 -84.21887,-15.7284 l 3.78966,1.78392 76.36547,16.11954 z"
+ style="opacity:0.75;fill:#ffffff;fill-opacity:1;stroke:none;display:inline"
+ sodipodi:nodetypes="ccccc" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path4023"
+ d="m 110.53066,924.10962 2.95566,0.39105 47.19964,-69.64448 -3.14815,1.26866 z"
+ style="opacity:0.15;fill:#000000;fill-opacity:1;stroke:none;display:inline"
+ sodipodi:nodetypes="ccccc" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ style="opacity:0.15;fill:#000000;fill-opacity:1;stroke:none;display:inline"
+ d="m 134.30889,916.98277 -3.52314,1.58642 81.74635,15.36654 0.48023,-2.29648 z"
+ id="path4025"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ style="opacity:0.75;fill:#ffffff;fill-opacity:1;stroke:none;display:inline"
+ d="m 176.35096,851.02893 -45.81894,67.56644 3.76063,-1.6965 43.83377,-64.88465 z"
+ id="path4027"
+ inkscape:connector-curvature="0" />
+ </g>
+</svg>
diff --git a/resources/locale/compile-po.sh b/resources/locale/compile-po.sh
new file mode 100755
index 0000000..6b201de
--- /dev/null
+++ b/resources/locale/compile-po.sh
@@ -0,0 +1,6 @@
+#!/bin/bash
+
+for d in `ls -d */`
+do
+ msgfmt -c -v $d/LC_MESSAGES/*.po -o $d/LC_MESSAGES/gnomepie.mo
+done
diff --git a/resources/locale/de/LC_MESSAGES/de.po b/resources/locale/de/LC_MESSAGES/de.po
new file mode 100644
index 0000000..3426769
--- /dev/null
+++ b/resources/locale/de/LC_MESSAGES/de.po
@@ -0,0 +1,221 @@
+# German translations for gnomepie package.
+# Copyright (C) 2011 Simon Schneegans <simon.schneegans@uni-weimar.de>
+# This file is distributed under the same license as the gnomepie package.
+# Simon Schneegans <simon.schneegans@uni-weimar.de>, 2011.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: gnomepie 0.1\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2011-08-25 21:04+0200\n"
+"PO-Revision-Date: 2011-08-25 21:04+0200\n"
+"Last-Translator: Simon Schneegans <simon.schneegans@uni-weimar.de>\n"
+"Language-Team: German\n"
+"Language: de\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+#: ../../src/actions/keyAction.vala:24 ../../src/settings/pieList.vala:73
+msgid "Press key stroke"
+msgstr "Tastenkombination"
+
+#: ../../src/actions/appAction.vala:24 ../../src/settings/pieList.vala:72
+msgid "Launch application"
+msgstr "Programm ausführen"
+
+#: ../../src/actions/action.vala:88
+msgid "Trash"
+msgstr "Müll"
+
+#: ../../src/actions/uriAction.vala:24 ../../src/settings/pieList.vala:75
+msgid "Open URI"
+msgstr "URI öffnen"
+
+#: ../../src/actions/pieAction.vala:24 ../../src/settings/pieList.vala:74
+msgid "Open Pie"
+msgstr "Pie öffnen"
+
+#: ../../src/settings/preferences.vala:26
+msgid "Gnome-Pie - Settings"
+msgstr "Gnome-Pie - Einstellungen"
+
+#: ../../src/settings/preferences.vala:49
+msgid "Behavior"
+msgstr "Verhalten"
+
+#: ../../src/settings/preferences.vala:59
+msgid "Startup on Login"
+msgstr "Beim Anmelden automatisch ausführen"
+
+#: ../../src/settings/preferences.vala:65
+msgid "Show Indicator"
+msgstr "Benachrichtigungssymbol anzeigen"
+
+#: ../../src/settings/preferences.vala:71
+msgid "Open Pies at Mouse"
+msgstr "Pies an der Maus öffnen"
+
+#: ../../src/settings/preferences.vala:77
+msgid "Click to activate a Slice"
+msgstr "Klicken um Slices zu aktivieren"
+
+#: ../../src/settings/preferences.vala:86
+msgid "Global Scale"
+msgstr "Skalierungsfaktor"
+
+#: ../../src/settings/preferences.vala:123
+msgid "Themes"
+msgstr "Themen"
+
+#: ../../src/settings/preferences.vala:141
+msgid "General"
+msgstr "Allgemein"
+
+#: ../../src/settings/preferences.vala:146
+msgid "Pies"
+msgstr "Pies"
+
+#: ../../src/settings/preferences.vala:170
+msgid ""
+"You can right-click in the list\n"
+"for adding or removing entries."
+msgstr ""
+"Zum Löschen und Hinzufügen von Einträgen kannst \n"
+"du mit der rechten Maustaste in die Liste klicken."
+
+#: ../../src/settings/themeList.vala:75
+msgid "by"
+msgstr "von"
+
+#: ../../src/settings/iconChooserWindow.vala:79
+msgid "Choose an Icon"
+msgstr "Wähle ein Symbol"
+
+#: ../../src/settings/iconChooserWindow.vala:101
+msgid "All icons"
+msgstr "Alle Symbole"
+
+#: ../../src/settings/iconChooserWindow.vala:102
+msgid "Applications"
+msgstr "Anwendungen"
+
+#: ../../src/settings/iconChooserWindow.vala:103
+msgid "Actions"
+msgstr "Aktionen"
+
+#: ../../src/settings/iconChooserWindow.vala:104
+msgid "Places"
+msgstr "Orte"
+
+#: ../../src/settings/iconChooserWindow.vala:105
+msgid "File types"
+msgstr "Dateitypen"
+
+#: ../../src/settings/iconChooserWindow.vala:106
+msgid "Emotes"
+msgstr "Smilies"
+
+#: ../../src/settings/iconChooserWindow.vala:107
+msgid "Miscellaneous"
+msgstr "Sonstige"
+
+#: ../../src/settings/pieList.vala:56
+#: ../../src/actionGroups/bookmarkGroup.vala:23
+msgid "Bookmarks"
+msgstr "Lesezeichen"
+
+#: ../../src/settings/pieList.vala:57
+#: ../../src/actionGroups/devicesGroup.vala:23
+msgid "Devices"
+msgstr "Laufwerke"
+
+#: ../../src/settings/pieList.vala:58 ../../src/actionGroups/menuGroup.vala:25
+msgid "Main menu"
+msgstr "Hauptmenü"
+
+#: ../../src/settings/pieList.vala:59
+#: ../../src/actionGroups/sessionGroup.vala:23
+msgid "Session Control"
+msgstr "Sitzung"
+
+#: ../../src/settings/pieList.vala:76 ../../src/settings/pieList.vala:738
+msgid "Slice group"
+msgstr "Slice-Gruppe"
+
+#: ../../src/settings/pieList.vala:119
+msgid "Icon"
+msgstr "Symbol"
+
+#: ../../src/settings/pieList.vala:181
+msgid "Command"
+msgstr "Kommando"
+
+#: ../../src/settings/pieList.vala:261 ../../src/settings/pieList.vala:601
+#: ../../src/settings/pieList.vala:753
+#: ../../src/system/bindingManager.vala:118
+msgid "Not bound"
+msgstr "Nicht zugewiesen"
+
+#: ../../src/settings/pieList.vala:326
+msgid "Action type"
+msgstr "Slice-Typ"
+
+#: ../../src/settings/pieList.vala:388
+msgid "Name"
+msgstr "Name"
+
+#: ../../src/settings/pieList.vala:423
+msgid "Add new Pie"
+msgstr "Pie hinzufügen"
+
+#: ../../src/settings/pieList.vala:428
+msgid "Add new Slice"
+msgstr "Slice hinzufügen"
+
+#: ../../src/settings/pieList.vala:436
+msgid "Delete"
+msgstr "Eintrag löschen"
+
+#: ../../src/settings/pieList.vala:517
+msgid "New Pie"
+msgstr "Neuer Pie"
+
+#: ../../src/settings/pieList.vala:562
+msgid "New Action"
+msgstr "Neue Slice"
+
+#: ../../src/settings/pieList.vala:576
+msgid "You have to select a Pie to add a Slice to!"
+msgstr "Es muss ein Pie ausgewählt sein, zu dem eine Slice hinzugefügt werden soll!"
+
+#: ../../src/settings/pieList.vala:623
+msgid "You have to select a Pie or a Slice to delete!"
+msgstr "Es muss etwas ausgewählt sein, das gelöscht werden soll!"
+
+#: ../../src/settings/pieList.vala:633
+msgid ""
+"Do you really want to delete the selected Pie with all contained Slices?"
+msgstr ""
+"Soll dieser Pie wirklich mit allen Slices gelöscht werden?"
+
+#: ../../src/settings/pieList.vala:666
+msgid "Do you really want to delete the selected Slice?"
+msgstr "Soll die ausgewählte Slice wirklich gelöscht werden?"
+
+#: ../../src/actionGroups/sessionGroup.vala:29
+msgid "Shutdown"
+msgstr "Herunterfahren"
+
+#: ../../src/actionGroups/sessionGroup.vala:32
+msgid "Logout"
+msgstr "Ausloggen"
+
+#: ../../src/actionGroups/sessionGroup.vala:35
+msgid "Reboot"
+msgstr "Neustarten"
+
+#: ../../src/actionGroups/devicesGroup.vala:44
+msgid "Root"
+msgstr "Dateisystem"
diff --git a/resources/locale/de/LC_MESSAGES/gnomepie.mo b/resources/locale/de/LC_MESSAGES/gnomepie.mo
new file mode 100644
index 0000000..622b2ee
--- /dev/null
+++ b/resources/locale/de/LC_MESSAGES/gnomepie.mo
Binary files differ
diff --git a/resources/locale/gen-po.sh b/resources/locale/gen-po.sh
new file mode 100755
index 0000000..cecc4c9
--- /dev/null
+++ b/resources/locale/gen-po.sh
@@ -0,0 +1,13 @@
+#!/bin/bash
+
+echo "Insert your locale:";
+read locale;
+
+if [ "$locale" == "" ]
+then
+ echo "No locale inserted! Aborting...";
+ exit 1
+fi
+
+mkdir -p $locale/LC_MESSAGES
+msginit --locale=$locale --input=gnomepie.pot --output=$locale/LC_MESSAGES/$locale.po
diff --git a/resources/locale/gen-pot.sh b/resources/locale/gen-pot.sh
new file mode 100755
index 0000000..65acff3
--- /dev/null
+++ b/resources/locale/gen-pot.sh
@@ -0,0 +1,22 @@
+#!/bin/bash
+
+# Searches trough all vala files of Gnome-Pie and generates
+# a gnomepie.pot for strings which need to be translated.
+
+filelist=$( find ../../src/ -name '*.vala' -printf "%h/%f " )
+
+domain="gnomepie"
+version="0.1"
+copyright="Simon Schneegans <simon.schneegans@uni-weimar.de>"
+
+xgettext --package-name $domain \
+ --package-version $version \
+ --default-domain $domain \
+ --output $domain.pot \
+ --copyright-holder="$copyright" \
+ -k_ \
+ -L C# \
+ $filelist
+
+sed --in-place $domain.pot --expression='s/CHARSET/UTF-8/'
+
diff --git a/resources/locale/gnomepie.pot b/resources/locale/gnomepie.pot
new file mode 100644
index 0000000..871ef0e
--- /dev/null
+++ b/resources/locale/gnomepie.pot
@@ -0,0 +1,357 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR Simon Schneegans <simon.schneegans@uni-weimar.de>
+# This file is distributed under the same license as the PACKAGE package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: gnomepie 0.1\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2011-10-11 15:55-0300\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
+"Language-Team: LANGUAGE <LL@li.org>\n"
+"Language: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#: ../../src/actions/keyAction.vala:33
+msgid "Press key stroke"
+msgstr ""
+
+#: ../../src/actions/pieAction.vala:33
+msgid "Open Pie"
+msgstr ""
+
+#: ../../src/actions/appAction.vala:33
+msgid "Launch application"
+msgstr ""
+
+#: ../../src/actions/uriAction.vala:33
+msgid "Open URI"
+msgstr ""
+
+#: ../../src/actions/actionRegistry.vala:107
+msgid "Trash"
+msgstr ""
+
+#: ../../src/utilities/bindingManager.vala:150 ../../src/gui/pieList.vala:278
+#: ../../src/gui/pieList.vala:660 ../../src/gui/pieList.vala:818
+msgid "Not bound"
+msgstr ""
+
+#: ../../src/pies/defaultConfig.vala:29
+msgid "Multimedia"
+msgstr ""
+
+#: ../../src/pies/defaultConfig.vala:30
+msgid "Next Track"
+msgstr ""
+
+#: ../../src/pies/defaultConfig.vala:31
+msgid "Stop"
+msgstr ""
+
+#: ../../src/pies/defaultConfig.vala:32
+msgid "Previous Track"
+msgstr ""
+
+#: ../../src/pies/defaultConfig.vala:33
+msgid "Play/Pause"
+msgstr ""
+
+#: ../../src/pies/defaultConfig.vala:36
+#: ../../src/gui/iconSelectWindow.vala:119
+msgid "Applications"
+msgstr ""
+
+#: ../../src/pies/defaultConfig.vala:45
+#: ../../src/actionGroups/bookmarkGroup.vala:35
+msgid "Bookmarks"
+msgstr ""
+
+#: ../../src/pies/defaultConfig.vala:50
+msgid "Session"
+msgstr ""
+
+#: ../../src/pies/defaultConfig.vala:54
+msgid "Main Menu"
+msgstr ""
+
+#: ../../src/pies/defaultConfig.vala:58
+msgid "Window"
+msgstr ""
+
+#: ../../src/pies/defaultConfig.vala:59
+msgid "Scale"
+msgstr ""
+
+#: ../../src/pies/defaultConfig.vala:60
+msgid "Minimize"
+msgstr ""
+
+#: ../../src/pies/defaultConfig.vala:61
+msgid "Close"
+msgstr ""
+
+#: ../../src/pies/defaultConfig.vala:62
+msgid "Maximize"
+msgstr ""
+
+#: ../../src/pies/defaultConfig.vala:63
+msgid "Restore"
+msgstr ""
+
+#: ../../src/gui/preferences.vala:32
+msgid "Gnome-Pie - Settings"
+msgstr ""
+
+#: ../../src/gui/preferences.vala:55
+msgid "Behavior"
+msgstr ""
+
+#: ../../src/gui/preferences.vala:65
+msgid "Startup on Login"
+msgstr ""
+
+#: ../../src/gui/preferences.vala:66
+msgid "If checked, Gnome-Pie will start when you log in."
+msgstr ""
+
+#: ../../src/gui/preferences.vala:72
+msgid "Show Indicator"
+msgstr ""
+
+#: ../../src/gui/preferences.vala:73
+msgid ""
+"If checked, an indicator for easy access of the settings menu is shown in "
+"your panel."
+msgstr ""
+
+#: ../../src/gui/preferences.vala:79
+msgid "Open Pies at Mouse"
+msgstr ""
+
+#: ../../src/gui/preferences.vala:80
+msgid ""
+"If checked, pies will open at your pointer. Otherwise they'll pop up in the "
+"middle of the screen."
+msgstr ""
+
+#: ../../src/gui/preferences.vala:86
+msgid "Turbo mode"
+msgstr ""
+
+#: ../../src/gui/preferences.vala:87
+msgid ""
+"If checked, the pie closes when its keystroke is released. The currently "
+"hovered slice gets executed. This allows very fast selection but disables "
+"keyboard navigating."
+msgstr ""
+
+#: ../../src/gui/preferences.vala:96
+msgid "Global Scale"
+msgstr ""
+
+#: ../../src/gui/preferences.vala:133
+msgid "Themes"
+msgstr ""
+
+#: ../../src/gui/preferences.vala:151
+msgid "General"
+msgstr ""
+
+#: ../../src/gui/preferences.vala:156
+msgid "Pies"
+msgstr ""
+
+#: ../../src/gui/preferences.vala:180
+msgid "You can right-click in the list for adding or removing entries."
+msgstr ""
+
+#: ../../src/gui/preferences.vala:181
+msgid ""
+"You can reset Gnome-Pie to its default options with the terminal command "
+"\"gnome-pie --reset\"."
+msgstr ""
+
+#: ../../src/gui/preferences.vala:182
+msgid ""
+"The radiobutton at the beginning of each slice-line indicates the "
+"QuickAction of the pie."
+msgstr ""
+
+#: ../../src/gui/preferences.vala:183
+msgid "Pies can be opened with the terminal command \"gnome-pie --open=ID\"."
+msgstr ""
+
+#: ../../src/gui/preferences.vala:184
+msgid "Feel free to visit Gnome-Pie's homepage at %s!"
+msgstr ""
+
+#: ../../src/gui/preferences.vala:185
+msgid "You can drag'n'drop applications from your main menu to the list above."
+msgstr ""
+
+#: ../../src/gui/preferences.vala:186
+msgid "If you want to give some feedback, please write an e-mail to %s!"
+msgstr ""
+
+#: ../../src/gui/preferences.vala:187
+msgid ""
+"You may drag'n'drop URLs and bookmarks from your internet browser to the "
+"list above."
+msgstr ""
+
+#: ../../src/gui/preferences.vala:188
+msgid "Bugs can be reported at %s!"
+msgstr ""
+
+#: ../../src/gui/preferences.vala:189
+msgid ""
+"It's possible to drag'n'drop files and folders from your file browser to the "
+"list above."
+msgstr ""
+
+#: ../../src/gui/preferences.vala:198
+msgid "Moves the selected Slice down"
+msgstr ""
+
+#: ../../src/gui/preferences.vala:210
+msgid "Moves the selected Slice up"
+msgstr ""
+
+#: ../../src/gui/pieList.vala:88 ../../src/gui/pieList.vala:803
+msgid "Slice group"
+msgstr ""
+
+#: ../../src/gui/pieList.vala:134
+msgid "Icon"
+msgstr ""
+
+#: ../../src/gui/pieList.vala:199
+msgid "Command"
+msgstr ""
+
+#: ../../src/gui/pieList.vala:343
+msgid "Pie-ID / Action type"
+msgstr ""
+
+#: ../../src/gui/pieList.vala:403
+msgid "Name"
+msgstr ""
+
+#: ../../src/gui/pieList.vala:446
+msgid "Add new Pie"
+msgstr ""
+
+#: ../../src/gui/pieList.vala:451
+msgid "Add new Slice"
+msgstr ""
+
+#: ../../src/gui/pieList.vala:459
+msgid "Delete"
+msgstr ""
+
+#: ../../src/gui/pieList.vala:574
+msgid "New Pie"
+msgstr ""
+
+#: ../../src/gui/pieList.vala:620
+msgid "New Action"
+msgstr ""
+
+#: ../../src/gui/pieList.vala:634
+msgid "You have to select a Pie to add a Slice to!"
+msgstr ""
+
+#: ../../src/gui/pieList.vala:683
+msgid "You have to select a Pie or a Slice to delete!"
+msgstr ""
+
+#: ../../src/gui/pieList.vala:694
+msgid ""
+"Do you really want to delete the selected Pie with all contained Slices?"
+msgstr ""
+
+#: ../../src/gui/pieList.vala:728
+msgid "Do you really want to delete the selected Slice?"
+msgstr ""
+
+#: ../../src/gui/themeList.vala:88
+msgid "by"
+msgstr ""
+
+#: ../../src/gui/iconSelectWindow.vala:91
+msgid "Choose an Icon"
+msgstr ""
+
+#: ../../src/gui/iconSelectWindow.vala:118
+msgid "All icons"
+msgstr ""
+
+#: ../../src/gui/iconSelectWindow.vala:120
+msgid "Actions"
+msgstr ""
+
+#: ../../src/gui/iconSelectWindow.vala:121
+msgid "Places"
+msgstr ""
+
+#: ../../src/gui/iconSelectWindow.vala:122
+msgid "File types"
+msgstr ""
+
+#: ../../src/gui/iconSelectWindow.vala:123
+msgid "Emotes"
+msgstr ""
+
+#: ../../src/gui/iconSelectWindow.vala:124
+msgid "Miscellaneous"
+msgstr ""
+
+#: ../../src/gui/iconSelectWindow.vala:192
+msgid "Icon Theme"
+msgstr ""
+
+#: ../../src/gui/iconSelectWindow.vala:200
+msgid "All supported image formats"
+msgstr ""
+
+#: ../../src/gui/iconSelectWindow.vala:217
+msgid "Custom Icon"
+msgstr ""
+
+#: ../../src/actionGroups/devicesGroup.vala:34
+msgid "Devices"
+msgstr ""
+
+#: ../../src/actionGroups/devicesGroup.vala:82
+msgid "Root"
+msgstr ""
+
+#: ../../src/actionGroups/sessionGroup.vala:34
+msgid "Session Control"
+msgstr ""
+
+#: ../../src/actionGroups/sessionGroup.vala:52
+msgid "Shutdown"
+msgstr ""
+
+#: ../../src/actionGroups/sessionGroup.vala:55
+msgid "Logout"
+msgstr ""
+
+#: ../../src/actionGroups/sessionGroup.vala:58
+msgid "Reboot"
+msgstr ""
+
+#: ../../src/actionGroups/menuGroup.vala:33
+msgid "Main menu"
+msgstr ""
+
+#: ../../src/actionGroups/clipboardGroup.vala:62
+msgid "Clipboard"
+msgstr ""
diff --git a/resources/locale/pt-br/LC_MESSAGES/gnomepie.mo b/resources/locale/pt-br/LC_MESSAGES/gnomepie.mo
new file mode 100644
index 0000000..7c0c5d9
--- /dev/null
+++ b/resources/locale/pt-br/LC_MESSAGES/gnomepie.mo
Binary files differ
diff --git a/resources/locale/pt-br/LC_MESSAGES/pt-br.po b/resources/locale/pt-br/LC_MESSAGES/pt-br.po
new file mode 100644
index 0000000..b192fc0
--- /dev/null
+++ b/resources/locale/pt-br/LC_MESSAGES/pt-br.po
@@ -0,0 +1,301 @@
+# Language pt-br translations for gnomepie package.
+# Copyright (C) 2011 Simon Schneegans <simon.schneegans@uni-weimar.de>
+# This file is distributed under the same license as the gnomepie package.
+# Magnun Leno <magnun@codecommunity.org>, 2011.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: gnomepie 0.1\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2011-10-11 15:55-0300\n"
+"PO-Revision-Date: 2011-10-11 15:55-0300\n"
+"Last-Translator: Magnun Leno <magnun@codecommunity.org>\n"
+"Language-Team: Language pt-br\n"
+"Language: pt-br\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#: ../../src/actions/keyAction.vala:33
+msgid "Press key stroke"
+msgstr "Pressione qualquer tecla"
+
+#: ../../src/actions/pieAction.vala:33
+msgid "Open Pie"
+msgstr "Abrir menu"
+
+#: ../../src/actions/appAction.vala:33
+msgid "Launch application"
+msgstr "Lançar aplicação"
+
+#: ../../src/actions/uriAction.vala:33
+msgid "Open URI"
+msgstr "Abrir URL"
+
+#: ../../src/actions/actionRegistry.vala:107
+msgid "Trash"
+msgstr "Remover"
+
+#: ../../src/pies/defaultConfig.vala:62
+msgid "Maximize"
+msgstr "Maximizar"
+
+#: ../../src/pies/defaultConfig.vala:63
+msgid "Restore"
+msgstr ""
+
+#: ../../src/gui/preferences.vala:32
+msgid "Gnome-Pie - Settings"
+msgstr "Gnome-Pie - Configurações"
+
+#: ../../src/gui/preferences.vala:55
+msgid "Behavior"
+msgstr "Comportamento"
+
+#: ../../src/gui/preferences.vala:65
+msgid "Startup on Login"
+msgstr "Iniciar durante o Login"
+
+#: ../../src/gui/preferences.vala:66
+msgid "If checked, Gnome-Pie will start when you log in."
+msgstr "Se marcado, o Gnome-Pie irá iniciar durante o login."
+
+#: ../../src/gui/preferences.vala:72
+msgid "Show Indicator"
+msgstr "Mostrar Indicador"
+
+#: ../../src/gui/preferences.vala:73
+msgid ""
+"If checked, an indicator for easy access of the settings menu is shown in "
+"your panel."
+msgstr ""
+"Se marcado, um indicador para facilitar o acesso às configurações estará "
+"disponível em seu painel."
+
+#: ../../src/gui/preferences.vala:79
+msgid "Open Pies at Mouse"
+msgstr "Abrir Menus sobre o Mouse"
+
+#: ../../src/gui/preferences.vala:86
+msgid "Turbo mode"
+msgstr "Modo Turbo"
+
+#: ../../src/gui/preferences.vala:87
+msgid ""
+"If checked, the pie closes when its keystroke is released. The currently "
+"hovered slice gets executed. This allows very fast selection but disables "
+"keyboard navigating."
+msgstr ""
+"Se marcado, o menu se fechará quando a combinação de teclas for liberada. A opção que estiver "
+"sobre o cursor será executada. Essa opção possibilita uma uma seleção rápida mas desativa "
+"a navegação pelo teclado."
+
+#: ../../src/gui/preferences.vala:96
+msgid "Global Scale"
+msgstr "Escalonamento Global"
+
+#: ../../src/gui/preferences.vala:133
+msgid "Themes"
+msgstr "Temas"
+
+#: ../../src/gui/preferences.vala:151
+msgid "General"
+msgstr "Geral"
+
+#: ../../src/gui/preferences.vala:156
+msgid "Pies"
+msgstr "Menus"
+
+#: ../../src/gui/preferences.vala:180
+msgid "You can right-click in the list for adding or removing entries."
+msgstr "Você pode clicar com o botão direito sobre a lista para adicioná-las ou removê-las."
+
+#: ../../src/gui/preferences.vala:181
+msgid ""
+"You can reset Gnome-Pie to its default options with the terminal command "
+"\"gnome-pie --reset\"."
+msgstr ""
+"Você pode voltar o Gnome-Pie para suas configurações padrão usando o comando de terminal "
+"\"gnome-pie --reset\"."
+
+#: ../../src/gui/preferences.vala:182
+msgid ""
+"The radiobutton at the beginning of each slice-line indicates the "
+"QuickAction of the pie."
+msgstr ""
+"O botão de seleção no início de cada Opção indica a "
+"Ação Rápida vinculada ao Menu."
+
+#: ../../src/gui/preferences.vala:183
+msgid "Pies can be opened with the terminal command \"gnome-pie --open=ID\"."
+msgstr "Menus podem ser abertos através do terminal com o comando \"gnome-pie --open=ID\"."
+
+#: ../../src/gui/preferences.vala:184
+msgid "Feel free to visit Gnome-Pie's homepage at %s!"
+msgstr "Sinta-se a vontade para visitar o site do Gnome-Pie em %s"
+
+#: ../../src/gui/preferences.vala:185
+msgid "You can drag'n'drop applications from your main menu to the list above."
+msgstr "Você pode arrastar aplicações do seu menu principal para a lista acima."
+
+#: ../../src/gui/preferences.vala:186
+msgid "If you want to give some feedback, please write an e-mail to %s!"
+msgstr "Se você quiser enviar algum feedback, por favor escreva um e-mail para %s!"
+
+#: ../../src/gui/preferences.vala:187
+msgid ""
+"You may drag'n'drop URLs and bookmarks from your internet browser to the "
+"list above."
+msgstr ""
+"Você pode arrastar URLs e Favoritos do seu navegador predileto para "
+"a lista acima."
+
+#: ../../src/gui/preferences.vala:188
+msgid "Bugs can be reported at %s!"
+msgstr "Defeitos podem ser informados em %s!"
+
+#: ../../src/gui/preferences.vala:189
+msgid ""
+"It's possible to drag'n'drop files and folders from your file browser to the "
+"list above."
+msgstr ""
+"É possível arrastar arquivos e pastas do seu navegador para dentro da "
+"lista acima."
+
+#: ../../src/gui/preferences.vala:198
+msgid "Moves the selected Slice down"
+msgstr "Move a Opção selecionada para baixo"
+
+#: ../../src/gui/preferences.vala:210
+msgid "Moves the selected Slice up"
+msgstr "Move a Opção selecionada para cima"
+
+#: ../../src/gui/pieList.vala:88 ../../src/gui/pieList.vala:803
+msgid "Slice group"
+msgstr "Grupo de Opções"
+
+#: ../../src/gui/pieList.vala:134
+msgid "Icon"
+msgstr "Ícone"
+
+#: ../../src/gui/pieList.vala:199
+msgid "Command"
+msgstr "Comando"
+
+#: ../../src/gui/pieList.vala:343
+msgid "Pie-ID / Action type"
+msgstr "ID-Opção / Tipo de Ação"
+
+#: ../../src/gui/pieList.vala:403
+msgid "Name"
+msgstr "Nome"
+
+#: ../../src/gui/pieList.vala:446
+msgid "Add new Pie"
+msgstr "Adicionar novo Menu"
+
+#: ../../src/gui/pieList.vala:451
+msgid "Add new Slice"
+msgstr "Adicionar nova Opção"
+
+#: ../../src/gui/pieList.vala:459
+msgid "Delete"
+msgstr "Deletar"
+
+#: ../../src/gui/pieList.vala:574
+msgid "New Pie"
+msgstr "Novo Menu"
+
+#: ../../src/gui/pieList.vala:620
+msgid "New Action"
+msgstr "Nova Ação"
+
+#: ../../src/gui/pieList.vala:634
+msgid "You have to select a Pie to add a Slice to!"
+msgstr "Você tem que selecionar um Menu para poder adicionar uma Opção"
+
+#: ../../src/gui/pieList.vala:683
+msgid "You have to select a Pie or a Slice to delete!"
+msgstr "Para remover você precisa selecionar um Menu ou uma Opção"
+
+#: ../../src/gui/pieList.vala:694
+msgid ""
+"Do you really want to delete the selected Pie with all contained Slices?"
+msgstr ""
+"Você realmente deseja excluir o Menu selecionado e todas as suas Opções?"
+
+#: ../../src/gui/pieList.vala:728
+msgid "Do you really want to delete the selected Slice?"
+msgstr "Você realmente deseja excluir a Opção selecionada?"
+
+#: ../../src/gui/iconSelectWindow.vala:91
+msgid "Choose an Icon"
+msgstr "Escolha um Ícone"
+
+#: ../../src/gui/iconSelectWindow.vala:118
+msgid "All icons"
+msgstr "Todos os ícones"
+
+#: ../../src/gui/iconSelectWindow.vala:120
+msgid "Actions"
+msgstr "Ações"
+
+#: ../../src/gui/iconSelectWindow.vala:121
+msgid "Places"
+msgstr "Lugares"
+
+#: ../../src/gui/iconSelectWindow.vala:122
+msgid "File types"
+msgstr "Tipos de arquivos"
+
+#: ../../src/gui/iconSelectWindow.vala:123
+msgid "Emotes"
+msgstr "Emotes"
+
+#: ../../src/gui/iconSelectWindow.vala:124
+msgid "Miscellaneous"
+msgstr "Diversos"
+
+#: ../../src/gui/iconSelectWindow.vala:192
+msgid "Icon Theme"
+msgstr "Tema de Ícones"
+
+#: ../../src/gui/iconSelectWindow.vala:200
+msgid "All supported image formats"
+msgstr "Todos os tipos de imagem suportados"
+
+#: ../../src/gui/iconSelectWindow.vala:217
+msgid "Custom Icon"
+msgstr "Outros Ícones"
+
+#: ../../src/actionGroups/devicesGroup.vala:34
+msgid "Devices"
+msgstr "Dispositivos"
+
+#: ../../src/actionGroups/devicesGroup.vala:82
+msgid "Root"
+msgstr "Raiz"
+
+#: ../../src/actionGroups/sessionGroup.vala:34
+msgid "Session Control"
+msgstr "Controle de Sessão"
+
+#: ../../src/actionGroups/sessionGroup.vala:52
+msgid "Shutdown"
+msgstr "Desligar"
+
+#: ../../src/actionGroups/sessionGroup.vala:55
+msgid "Logout"
+msgstr "Logout"
+
+#: ../../src/actionGroups/sessionGroup.vala:58
+msgid "Reboot"
+msgstr "Reboot"
+
+#: ../../src/actionGroups/menuGroup.vala:33
+msgid "Main menu"
+msgstr "Menu Principal"
+
+#: ../../src/actionGroups/clipboardGroup.vala:62
+msgid "Clipboard"
+msgstr "Clipboard"
diff --git a/resources/themes/adwaita/arrow.svg b/resources/themes/adwaita/arrow.svg
new file mode 100644
index 0000000..4b81a6d
--- /dev/null
+++ b/resources/themes/adwaita/arrow.svg
@@ -0,0 +1,121 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="100"
+ height="100"
+ id="svg2"
+ version="1.1"
+ inkscape:version="0.48.1 r9760"
+ sodipodi:docname="arrow.svg">
+ <defs
+ id="defs4">
+ <linearGradient
+ id="linearGradient3007">
+ <stop
+ id="stop3009"
+ offset="0"
+ style="stop-color:#ffffff;stop-opacity:0" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="0.3680203"
+ id="stop3011" />
+ <stop
+ id="stop3013"
+ offset="0.57677984"
+ style="stop-color:#ffffff;stop-opacity:0.66666667;" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0.45490196;"
+ offset="0.66058904"
+ id="stop3015" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0.34901961;"
+ offset="0.70194155"
+ id="stop3017" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0.25490196;"
+ offset="0.74285865"
+ id="stop3019" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0.1254902;"
+ offset="0.8251282"
+ id="stop3021" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0.05490196;"
+ offset="0.90009141"
+ id="stop3023" />
+ <stop
+ id="stop3025"
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:0" />
+ </linearGradient>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3007"
+ id="radialGradient3005"
+ gradientUnits="userSpaceOnUse"
+ cx="50.002552"
+ cy="49.744911"
+ fx="50.002552"
+ fy="49.744911"
+ r="49.750011" />
+ </defs>
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#1d1d1d"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="1"
+ inkscape:pageshadow="2"
+ inkscape:zoom="11.2"
+ inkscape:cx="77.449971"
+ inkscape:cy="47.388963"
+ inkscape:document-units="px"
+ inkscape:current-layer="layer1"
+ showgrid="false"
+ inkscape:showpageshadow="false"
+ showguides="true"
+ inkscape:guide-bbox="true"
+ inkscape:window-width="1174"
+ inkscape:window-height="737"
+ inkscape:window-x="552"
+ inkscape:window-y="163"
+ inkscape:window-maximized="0">
+ <sodipodi:guide
+ orientation="0,1"
+ position="111.25,50"
+ id="guide2994" />
+ </sodipodi:namedview>
+ <metadata
+ id="metadata7">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title />
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="Ebene 1"
+ inkscape:groupmode="layer"
+ id="layer1"
+ transform="translate(0,-952.36218)">
+ <path
+ style="fill:#ffffff;fill-opacity:1;stroke:none"
+ d="m 81.857481,996.8239 5.535712,5.5357 -5.535712,5.5357 c 0.621411,-3.8458 0.51189,-7.5089 0,-11.0714 z"
+ id="rect2998"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cccc" />
+ </g>
+</svg>
diff --git a/resources/themes/adwaita/icon_active.svg b/resources/themes/adwaita/icon_active.svg
new file mode 100644
index 0000000..8393747
--- /dev/null
+++ b/resources/themes/adwaita/icon_active.svg
@@ -0,0 +1,152 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="100"
+ height="100"
+ id="svg2"
+ version="1.1"
+ inkscape:version="0.48.1 r9760"
+ sodipodi:docname="icon_active.svg">
+ <defs
+ id="defs4">
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient3785">
+ <stop
+ style="stop-color:#f8fafa;stop-opacity:1"
+ offset="0"
+ id="stop3787" />
+ <stop
+ id="stop3797"
+ offset="0.61673242"
+ style="stop-color:#e4e6e6;stop-opacity:1" />
+ <stop
+ style="stop-color:#d2d6d6;stop-opacity:1"
+ offset="1"
+ id="stop3789" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient3009">
+ <stop
+ style="stop-color:#fafcfc;stop-opacity:1"
+ offset="0"
+ id="stop3011" />
+ <stop
+ id="stop3795"
+ offset="0.95082122"
+ style="stop-color:#e5e8e8;stop-opacity:1;" />
+ <stop
+ style="stop-color:#d2d6d6;stop-opacity:1"
+ offset="1"
+ id="stop3013" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3785"
+ id="linearGradient3791"
+ x1="44.385059"
+ y1="958.93121"
+ x2="44.385059"
+ y2="1045.9142"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.59160385,0,0,0.59160385,20.456735,409.35291)" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3009"
+ id="linearGradient3793"
+ x1="51.33149"
+ y1="958.94989"
+ x2="51.33149"
+ y2="1045.7374"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.59160385,0,0,0.59160385,20.456735,409.35291)" />
+ <filter
+ inkscape:collect="always"
+ id="filter3921"
+ x="-0.28370607"
+ width="1.5674121"
+ y="-0.28370607"
+ height="1.5674121">
+ <feGaussianBlur
+ inkscape:collect="always"
+ stdDeviation="9.4292716"
+ id="feGaussianBlur3923" />
+ </filter>
+ </defs>
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#000000"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="5.6"
+ inkscape:cx="56.854505"
+ inkscape:cy="49.374216"
+ inkscape:document-units="px"
+ inkscape:current-layer="layer1"
+ showgrid="false"
+ inkscape:showpageshadow="false"
+ inkscape:window-width="1517"
+ inkscape:window-height="834"
+ inkscape:window-x="328"
+ inkscape:window-y="111"
+ inkscape:window-maximized="0" />
+ <metadata
+ id="metadata7">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title />
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="Ebene 1"
+ inkscape:groupmode="layer"
+ id="layer1"
+ transform="translate(0,-952.36218)"
+ style="display:inline">
+ <rect
+ style="fill:#000000;fill-opacity:0.29136694;stroke:none;filter:url(#filter3921)"
+ id="rect3883"
+ width="79.766541"
+ height="79.766541"
+ x="10.207148"
+ y="962.45947"
+ ry="9.8949661"
+ rx="10.6689"
+ transform="matrix(0.69218766,0,0,0.69218766,16.668448,309.78347)" />
+ <rect
+ rx="7.384881"
+ ry="6.8491735"
+ y="973.88806"
+ x="21.635719"
+ height="56.909401"
+ width="56.909401"
+ id="rect3799"
+ style="fill:#000000;fill-opacity:0.34892087;stroke:none" />
+ <rect
+ style="fill:url(#linearGradient3791);fill-opacity:1;stroke:url(#linearGradient3793);stroke-width:1.14377474999999995;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="rect3000"
+ width="54.012722"
+ height="54.012722"
+ x="23.084059"
+ y="975.33636"
+ ry="6.3134527"
+ rx="6.3134527" />
+ </g>
+</svg>
diff --git a/resources/themes/adwaita/icon_inactive.svg b/resources/themes/adwaita/icon_inactive.svg
new file mode 100644
index 0000000..1120dc9
--- /dev/null
+++ b/resources/themes/adwaita/icon_inactive.svg
@@ -0,0 +1,152 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="100"
+ height="100"
+ id="svg2"
+ version="1.1"
+ inkscape:version="0.48.1 r9760"
+ sodipodi:docname="icon_inactive.svg">
+ <defs
+ id="defs4">
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient3785">
+ <stop
+ style="stop-color:#abab9f;stop-opacity:1"
+ offset="0"
+ id="stop3787" />
+ <stop
+ id="stop3797"
+ offset="0.29400957"
+ style="stop-color:#c2c2bb;stop-opacity:1" />
+ <stop
+ style="stop-color:#d3d3d2;stop-opacity:1"
+ offset="1"
+ id="stop3789" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient3009">
+ <stop
+ style="stop-color:#fafcfc;stop-opacity:1"
+ offset="0"
+ id="stop3011" />
+ <stop
+ id="stop3795"
+ offset="0.95082122"
+ style="stop-color:#e5e8e8;stop-opacity:1;" />
+ <stop
+ style="stop-color:#d2d6d6;stop-opacity:1"
+ offset="1"
+ id="stop3013" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3785"
+ id="linearGradient3791"
+ x1="44.385059"
+ y1="958.93121"
+ x2="44.385059"
+ y2="1045.9142"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.59160385,0,0,0.59160385,20.456735,409.35291)" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3009"
+ id="linearGradient3793"
+ x1="51.33149"
+ y1="958.94989"
+ x2="51.33149"
+ y2="1045.7374"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.59160385,0,0,0.59160385,20.456735,409.35291)" />
+ <filter
+ inkscape:collect="always"
+ id="filter3921"
+ x="-0.28370607"
+ width="1.5674121"
+ y="-0.28370607"
+ height="1.5674121">
+ <feGaussianBlur
+ inkscape:collect="always"
+ stdDeviation="9.4292716"
+ id="feGaussianBlur3923" />
+ </filter>
+ </defs>
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#000000"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="5.6"
+ inkscape:cx="56.854505"
+ inkscape:cy="49.374216"
+ inkscape:document-units="px"
+ inkscape:current-layer="layer1"
+ showgrid="false"
+ inkscape:showpageshadow="false"
+ inkscape:window-width="1517"
+ inkscape:window-height="834"
+ inkscape:window-x="335"
+ inkscape:window-y="111"
+ inkscape:window-maximized="0" />
+ <metadata
+ id="metadata7">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title />
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="Ebene 1"
+ inkscape:groupmode="layer"
+ id="layer1"
+ transform="translate(0,-952.36218)"
+ style="display:inline">
+ <rect
+ style="fill:#000000;fill-opacity:0.29136694;stroke:none;filter:url(#filter3921)"
+ id="rect3883"
+ width="79.766541"
+ height="79.766541"
+ x="10.207148"
+ y="962.45947"
+ ry="9.2462864"
+ rx="9.9694843"
+ transform="matrix(0.74074858,0,0,0.74074858,13.878869,260.75164)" />
+ <rect
+ rx="7.384881"
+ ry="6.8491735"
+ y="973.88806"
+ x="21.635719"
+ height="56.909401"
+ width="56.909401"
+ id="rect3799"
+ style="fill:#000000;fill-opacity:0.34892087;stroke:none" />
+ <rect
+ style="fill:url(#linearGradient3791);fill-opacity:1;stroke:url(#linearGradient3793);stroke-width:1.14377475;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="rect3000"
+ width="54.012722"
+ height="54.012722"
+ x="23.084059"
+ y="975.33636"
+ ry="6.3134527"
+ rx="6.3134527" />
+ </g>
+</svg>
diff --git a/resources/themes/adwaita/ring.svg b/resources/themes/adwaita/ring.svg
new file mode 100644
index 0000000..acc7c61
--- /dev/null
+++ b/resources/themes/adwaita/ring.svg
@@ -0,0 +1,258 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="100"
+ height="100"
+ id="svg2"
+ version="1.1"
+ inkscape:version="0.48.1 r9760"
+ sodipodi:docname="ring.svg">
+ <defs
+ id="defs4">
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient3794">
+ <stop
+ style="stop-color:#878786;stop-opacity:1"
+ offset="0"
+ id="stop3796" />
+ <stop
+ style="stop-color:#e3e3e0;stop-opacity:1"
+ offset="1"
+ id="stop3798" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3784">
+ <stop
+ style="stop-color:#e3e3e0;stop-opacity:1;"
+ offset="0"
+ id="stop3786" />
+ <stop
+ style="stop-color:#aeaea2;stop-opacity:1"
+ offset="1"
+ id="stop3788" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3800">
+ <stop
+ id="stop3810"
+ offset="0"
+ style="stop-color:#000000;stop-opacity:1;" />
+ <stop
+ style="stop-color:#000000;stop-opacity:0.63106796"
+ offset="0.5776158"
+ id="stop3780" />
+ <stop
+ id="stop3813"
+ offset="0.75491738"
+ style="stop-color:#000000;stop-opacity:0.27843137;" />
+ <stop
+ id="stop3811"
+ offset="0.79946876"
+ style="stop-color:#000000;stop-opacity:0.19215686;" />
+ <stop
+ id="stop3782"
+ offset="0.86143982"
+ style="stop-color:#000000;stop-opacity:0.10980392;" />
+ <stop
+ style="stop-color:#000000;stop-opacity:0"
+ offset="1"
+ id="stop3804" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3007">
+ <stop
+ id="stop3009"
+ offset="0"
+ style="stop-color:#ffffff;stop-opacity:0" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="0.3680203"
+ id="stop3011" />
+ <stop
+ id="stop3013"
+ offset="0.57677984"
+ style="stop-color:#ffffff;stop-opacity:0.66666667;" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0.45490196;"
+ offset="0.66058904"
+ id="stop3015" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0.34901961;"
+ offset="0.70194155"
+ id="stop3017" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0.25490196;"
+ offset="0.74285865"
+ id="stop3019" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0.1254902;"
+ offset="0.8251282"
+ id="stop3021" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0.05490196;"
+ offset="0.90009141"
+ id="stop3023" />
+ <stop
+ id="stop3025"
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:0" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3767">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0"
+ offset="0"
+ id="stop3769" />
+ <stop
+ id="stop4739"
+ offset="0.3680203"
+ style="stop-color:#ffffff;stop-opacity:0;" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0.66666667;"
+ offset="0.59831607"
+ id="stop4703" />
+ <stop
+ id="stop4713"
+ offset="0.66058904"
+ style="stop-color:#ffffff;stop-opacity:0.45490196;" />
+ <stop
+ id="stop4711"
+ offset="0.70194155"
+ style="stop-color:#ffffff;stop-opacity:0.34901961;" />
+ <stop
+ id="stop4709"
+ offset="0.74285865"
+ style="stop-color:#ffffff;stop-opacity:0.25490196;" />
+ <stop
+ id="stop4707"
+ offset="0.8251282"
+ style="stop-color:#ffffff;stop-opacity:0.1254902;" />
+ <stop
+ id="stop4705"
+ offset="0.90009141"
+ style="stop-color:#ffffff;stop-opacity:0.05490196;" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0"
+ offset="1"
+ id="stop3771" />
+ </linearGradient>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3767"
+ id="radialGradient3775"
+ cx="50.002552"
+ cy="49.744911"
+ fx="50.002552"
+ fy="49.744911"
+ r="49.750011"
+ gradientUnits="userSpaceOnUse" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3007"
+ id="radialGradient3005"
+ gradientUnits="userSpaceOnUse"
+ cx="50.002552"
+ cy="49.744911"
+ fx="50.002552"
+ fy="49.744911"
+ r="49.750011" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3800"
+ id="radialGradient3808"
+ cx="50"
+ cy="50"
+ fx="50"
+ fy="50"
+ r="49.47143"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.194041,0,0,1.1819698,-9.7020495,-9.098491)" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3794"
+ id="linearGradient3807"
+ x1="35.535618"
+ y1="3.2004027"
+ x2="35.887642"
+ y2="97.42083"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3784"
+ id="linearGradient3809"
+ x1="52.98814"
+ y1="97.627907"
+ x2="53.845432"
+ y2="2.1650128"
+ gradientUnits="userSpaceOnUse" />
+ </defs>
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#1d1d1d"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="5.6"
+ inkscape:cx="73.450679"
+ inkscape:cy="52.126988"
+ inkscape:document-units="px"
+ inkscape:current-layer="layer1"
+ showgrid="false"
+ inkscape:showpageshadow="false"
+ showguides="true"
+ inkscape:guide-bbox="true"
+ inkscape:window-width="1920"
+ inkscape:window-height="1056"
+ inkscape:window-x="0"
+ inkscape:window-y="24"
+ inkscape:window-maximized="1" />
+ <metadata
+ id="metadata7">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title />
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="Ebene 1"
+ inkscape:groupmode="layer"
+ id="layer1"
+ transform="translate(0,-952.36218)">
+ <path
+ sodipodi:type="arc"
+ style="opacity:0.5964912;fill:none;stroke:url(#radialGradient3808);stroke-width:26.50491905;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="path3012"
+ sodipodi:cx="50"
+ sodipodi:cy="50"
+ sodipodi:rx="48.57143"
+ sodipodi:ry="48.57143"
+ d="M 98.57143,50 A 48.57143,48.57143 0 1 1 1.4285698,50 48.57143,48.57143 0 1 1 98.57143,50 z"
+ transform="matrix(0.7492844,0,0,0.7492844,14.429816,967.14914)" />
+ <path
+ transform="matrix(0.70847877,0,0,0.70847877,14.576061,966.93823)"
+ d="M 98.57143,50 A 48.57143,48.57143 0 1 1 1.4285698,50 48.57143,48.57143 0 1 1 98.57143,50 z"
+ sodipodi:ry="48.57143"
+ sodipodi:rx="48.57143"
+ sodipodi:cy="50"
+ sodipodi:cx="50"
+ id="path3782"
+ style="fill:url(#linearGradient3809);fill-opacity:1;stroke:url(#linearGradient3807);stroke-width:0.34789082;stroke-miterlimit:4;stroke-dasharray:none"
+ sodipodi:type="arc" />
+ </g>
+</svg>
diff --git a/resources/themes/adwaita/theme.xml b/resources/themes/adwaita/theme.xml
new file mode 100644
index 0000000..25b18ff
--- /dev/null
+++ b/resources/themes/adwaita/theme.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<theme name="Adwaita" description="Made for the default theme of Gnome3" author="Simon Schneegans" email="josi.schneegans@vr-web.de">
+ <pie radius="150" maxZoom="1.1" zoomRange="0.1" transitionTime="0.2" springiness="1.5"
+ fadeInTime="0.3" fadeOutTime="0.3" fadeInZoom="1.5" fadeOutZoom="0.7" fadeInRotation="0.5" fadeOutRotation="-0.7">
+ <center radius="100" activeRadius="55">
+ <center_layer file="ring.svg"
+ active_scale="0.8" active_rotationMode="auto" active_rotationSpeed="0" active_colorize="false" active_alpha="1.0"
+ inactive_scale="0.8" inactive_rotationMode="auto" inactive_rotationSpeed="0" inactive_colorize="false" inactive_alpha="1.0" />
+ <center_layer file="arrow.svg"
+ active_scale="1.0" active_rotationMode="turn_to_mouse" active_rotationSpeed="10.0" active_colorize="true" active_alpha="1.0"
+ inactive_scale="1.0" inactive_rotationMode="turn_to_mouse" inactive_rotationSpeed="5.0" inactive_colorize="false" inactive_alpha="0.0" />
+ </center>
+ <slices radius="30">
+ <activeSlice>
+ <slice_layer type="file" file="icon_active.svg" scale="1.8" />
+ <slice_layer type="icon" scale="0.9" />
+ </activeSlice>
+ <inactiveSlice>
+ <slice_layer type="file" file="icon_inactive.svg" scale="1.8" />
+ <slice_layer type="icon" scale="0.9" />
+ </inactiveSlice>
+ </slices>
+ <caption position="0" font="sans 10" width="100" height="100" color="#000"/>
+ </pie>
+</theme>
+
diff --git a/resources/themes/bright/arrow.svg b/resources/themes/bright/arrow.svg
new file mode 100644
index 0000000..4b81a6d
--- /dev/null
+++ b/resources/themes/bright/arrow.svg
@@ -0,0 +1,121 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="100"
+ height="100"
+ id="svg2"
+ version="1.1"
+ inkscape:version="0.48.1 r9760"
+ sodipodi:docname="arrow.svg">
+ <defs
+ id="defs4">
+ <linearGradient
+ id="linearGradient3007">
+ <stop
+ id="stop3009"
+ offset="0"
+ style="stop-color:#ffffff;stop-opacity:0" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="0.3680203"
+ id="stop3011" />
+ <stop
+ id="stop3013"
+ offset="0.57677984"
+ style="stop-color:#ffffff;stop-opacity:0.66666667;" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0.45490196;"
+ offset="0.66058904"
+ id="stop3015" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0.34901961;"
+ offset="0.70194155"
+ id="stop3017" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0.25490196;"
+ offset="0.74285865"
+ id="stop3019" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0.1254902;"
+ offset="0.8251282"
+ id="stop3021" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0.05490196;"
+ offset="0.90009141"
+ id="stop3023" />
+ <stop
+ id="stop3025"
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:0" />
+ </linearGradient>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3007"
+ id="radialGradient3005"
+ gradientUnits="userSpaceOnUse"
+ cx="50.002552"
+ cy="49.744911"
+ fx="50.002552"
+ fy="49.744911"
+ r="49.750011" />
+ </defs>
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#1d1d1d"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="1"
+ inkscape:pageshadow="2"
+ inkscape:zoom="11.2"
+ inkscape:cx="77.449971"
+ inkscape:cy="47.388963"
+ inkscape:document-units="px"
+ inkscape:current-layer="layer1"
+ showgrid="false"
+ inkscape:showpageshadow="false"
+ showguides="true"
+ inkscape:guide-bbox="true"
+ inkscape:window-width="1174"
+ inkscape:window-height="737"
+ inkscape:window-x="552"
+ inkscape:window-y="163"
+ inkscape:window-maximized="0">
+ <sodipodi:guide
+ orientation="0,1"
+ position="111.25,50"
+ id="guide2994" />
+ </sodipodi:namedview>
+ <metadata
+ id="metadata7">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title />
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="Ebene 1"
+ inkscape:groupmode="layer"
+ id="layer1"
+ transform="translate(0,-952.36218)">
+ <path
+ style="fill:#ffffff;fill-opacity:1;stroke:none"
+ d="m 81.857481,996.8239 5.535712,5.5357 -5.535712,5.5357 c 0.621411,-3.8458 0.51189,-7.5089 0,-11.0714 z"
+ id="rect2998"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cccc" />
+ </g>
+</svg>
diff --git a/resources/themes/bright/gloss.svg b/resources/themes/bright/gloss.svg
new file mode 100644
index 0000000..60a795f
--- /dev/null
+++ b/resources/themes/bright/gloss.svg
@@ -0,0 +1,156 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="100"
+ height="100"
+ id="svg2"
+ version="1.1"
+ inkscape:version="0.48.1 r9760"
+ sodipodi:docname="gloss.svg">
+ <defs
+ id="defs4">
+ <linearGradient
+ id="linearGradient3786"
+ inkscape:collect="always">
+ <stop
+ id="stop3788"
+ offset="0"
+ style="stop-color:#ffffff;stop-opacity:0.59649123" />
+ <stop
+ id="stop3790"
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:0" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient3772">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0.64912281"
+ offset="0"
+ id="stop3774" />
+ <stop
+ id="stop3804"
+ offset="0.33709621"
+ style="stop-color:#ffffff;stop-opacity:0.30980392;" />
+ <stop
+ id="stop3802"
+ offset="0.41556084"
+ style="stop-color:#ffffff;stop-opacity:0.25882353;" />
+ <stop
+ id="stop3800"
+ offset="0.50963062"
+ style="stop-color:#ffffff;stop-opacity:0.21568627;" />
+ <stop
+ id="stop3798"
+ offset="0.61938298"
+ style="stop-color:#ffffff;stop-opacity:0.15294118;" />
+ <stop
+ id="stop3796"
+ offset="0.75001973"
+ style="stop-color:#ffffff;stop-opacity:0.09019608;" />
+ <stop
+ id="stop3794"
+ offset="0.83893943"
+ style="stop-color:#ffffff;stop-opacity:0.05490196;" />
+ <stop
+ id="stop3792"
+ offset="0.91730076"
+ style="stop-color:#ffffff;stop-opacity:0.02745098;" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0"
+ offset="1"
+ id="stop3776" />
+ </linearGradient>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3772"
+ id="radialGradient3778"
+ cx="49.10873"
+ cy="-14.628683"
+ fx="49.10873"
+ fy="-14.628683"
+ r="48.035713"
+ gradientTransform="matrix(-1.156153,0.00571083,-0.00496751,-1.0056696,106.16882,941.03082)"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3786"
+ id="linearGradient3784"
+ x1="48.214287"
+ y1="1050.13"
+ x2="48.214287"
+ y2="994.57111"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,-952.36218)" />
+ </defs>
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#000000"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="1"
+ inkscape:pageshadow="2"
+ inkscape:zoom="4"
+ inkscape:cx="-99.870026"
+ inkscape:cy="62.091167"
+ inkscape:document-units="px"
+ inkscape:current-layer="layer1"
+ showgrid="false"
+ inkscape:showpageshadow="false"
+ inkscape:window-width="1920"
+ inkscape:window-height="1056"
+ inkscape:window-x="0"
+ inkscape:window-y="24"
+ inkscape:window-maximized="1" />
+ <metadata
+ id="metadata7">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title />
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="Ebene 1"
+ inkscape:groupmode="layer"
+ id="layer1"
+ transform="translate(0,-952.36218)"
+ style="display:inline">
+ <path
+ style="fill:url(#linearGradient3784);fill-opacity:1;stroke:none;opacity:0.72491909"
+ d="M 8.09375 31.78125 C 6.4638438 31.78125 4.9928252 32.769882 3.875 34.375 L 3.875 90.875 C 3.875 93.836 6.22655 96.1875 9.1875 96.1875 L 91 96.1875 C 93.96095 96.1875 96.3125 93.836 96.3125 90.875 L 96.3125 35.28125 C 95.156434 33.140485 93.450449 31.78125 91.53125 31.78125 L 8.09375 31.78125 z M 1.875 40.15625 C 1.8170155 40.70633 1.78125 41.266602 1.78125 41.84375 L 1.78125 87.78125 C 1.78125 88.358398 1.8170155 88.91867 1.875 89.46875 L 1.875 40.15625 z "
+ transform="translate(0,952.36218)"
+ id="rect3780" />
+ <rect
+ style="fill:none;stroke:#ffffff;stroke-width:2;stroke-miterlimit:4;stroke-opacity:0.31007752;stroke-dasharray:none"
+ id="rect3000"
+ width="94.446426"
+ height="94.446426"
+ x="2.8672049"
+ y="955.11957"
+ ry="6.3134527"
+ rx="6.3134527" />
+ <rect
+ style="fill:url(#radialGradient3778);fill-opacity:1;stroke:none;opacity:0.73139159"
+ id="rect3770"
+ width="96.071426"
+ height="56.071426"
+ x="1.7857143"
+ y="954.32648"
+ rx="6.3134527"
+ ry="6.3134527" />
+ </g>
+</svg>
diff --git a/resources/themes/bright/icon_active.svg b/resources/themes/bright/icon_active.svg
new file mode 100644
index 0000000..79593ab
--- /dev/null
+++ b/resources/themes/bright/icon_active.svg
@@ -0,0 +1,142 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="100"
+ height="100"
+ id="svg2"
+ version="1.1"
+ inkscape:version="0.48.1 r9760"
+ sodipodi:docname="unity_fg.svg">
+ <defs
+ id="defs4">
+ <linearGradient
+ id="linearGradient3786"
+ inkscape:collect="always">
+ <stop
+ id="stop3788"
+ offset="0"
+ style="stop-color:#ffffff;stop-opacity:0.59649123" />
+ <stop
+ id="stop3790"
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:0" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient3772">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0.64912281"
+ offset="0"
+ id="stop3774" />
+ <stop
+ id="stop3804"
+ offset="0.33709621"
+ style="stop-color:#ffffff;stop-opacity:0.30980392;" />
+ <stop
+ id="stop3802"
+ offset="0.41556084"
+ style="stop-color:#ffffff;stop-opacity:0.25882353;" />
+ <stop
+ id="stop3800"
+ offset="0.50963062"
+ style="stop-color:#ffffff;stop-opacity:0.21568627;" />
+ <stop
+ id="stop3798"
+ offset="0.61938298"
+ style="stop-color:#ffffff;stop-opacity:0.15294118;" />
+ <stop
+ id="stop3796"
+ offset="0.75001973"
+ style="stop-color:#ffffff;stop-opacity:0.09019608;" />
+ <stop
+ id="stop3794"
+ offset="0.83893943"
+ style="stop-color:#ffffff;stop-opacity:0.05490196;" />
+ <stop
+ id="stop3792"
+ offset="0.91730076"
+ style="stop-color:#ffffff;stop-opacity:0.02745098;" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0"
+ offset="1"
+ id="stop3776" />
+ </linearGradient>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3772"
+ id="radialGradient3778"
+ cx="49.10873"
+ cy="-14.628683"
+ fx="49.10873"
+ fy="-14.628683"
+ r="48.035713"
+ gradientTransform="matrix(-1.156153,0.00571083,-0.00496751,-1.0056696,106.16882,941.03082)"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3786"
+ id="linearGradient3784"
+ x1="48.214287"
+ y1="1050.13"
+ x2="48.214287"
+ y2="994.57111"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,2.9263432e-6)" />
+ </defs>
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#000000"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="1"
+ inkscape:pageshadow="2"
+ inkscape:zoom="2.8"
+ inkscape:cx="-16.038516"
+ inkscape:cy="39.866578"
+ inkscape:document-units="px"
+ inkscape:current-layer="layer1"
+ showgrid="false"
+ inkscape:showpageshadow="false"
+ inkscape:window-width="1920"
+ inkscape:window-height="1056"
+ inkscape:window-x="0"
+ inkscape:window-y="24"
+ inkscape:window-maximized="1" />
+ <metadata
+ id="metadata7">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title></dc:title>
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="Ebene 1"
+ inkscape:groupmode="layer"
+ id="layer1"
+ transform="translate(0,-952.36218)"
+ style="display:inline">
+ <rect
+ style="fill:#d8d8d8;stroke:#ffffff;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;fill-opacity:1"
+ id="rect3000"
+ width="94.446426"
+ height="94.446426"
+ x="2.8672049"
+ y="955.11957"
+ ry="6.3134527"
+ rx="6.3134527" />
+ </g>
+</svg>
diff --git a/resources/themes/bright/icon_inactive.svg b/resources/themes/bright/icon_inactive.svg
new file mode 100644
index 0000000..a16fdcf
--- /dev/null
+++ b/resources/themes/bright/icon_inactive.svg
@@ -0,0 +1,142 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="100"
+ height="100"
+ id="svg2"
+ version="1.1"
+ inkscape:version="0.48.2 r9819"
+ sodipodi:docname="icon_inactive.svg">
+ <defs
+ id="defs4">
+ <linearGradient
+ id="linearGradient3786"
+ inkscape:collect="always">
+ <stop
+ id="stop3788"
+ offset="0"
+ style="stop-color:#ffffff;stop-opacity:0.59649123" />
+ <stop
+ id="stop3790"
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:0" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient3772">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0.64912281"
+ offset="0"
+ id="stop3774" />
+ <stop
+ id="stop3804"
+ offset="0.33709621"
+ style="stop-color:#ffffff;stop-opacity:0.30980392;" />
+ <stop
+ id="stop3802"
+ offset="0.41556084"
+ style="stop-color:#ffffff;stop-opacity:0.25882353;" />
+ <stop
+ id="stop3800"
+ offset="0.50963062"
+ style="stop-color:#ffffff;stop-opacity:0.21568627;" />
+ <stop
+ id="stop3798"
+ offset="0.61938298"
+ style="stop-color:#ffffff;stop-opacity:0.15294118;" />
+ <stop
+ id="stop3796"
+ offset="0.75001973"
+ style="stop-color:#ffffff;stop-opacity:0.09019608;" />
+ <stop
+ id="stop3794"
+ offset="0.83893943"
+ style="stop-color:#ffffff;stop-opacity:0.05490196;" />
+ <stop
+ id="stop3792"
+ offset="0.91730076"
+ style="stop-color:#ffffff;stop-opacity:0.02745098;" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0"
+ offset="1"
+ id="stop3776" />
+ </linearGradient>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3772"
+ id="radialGradient3778"
+ cx="49.10873"
+ cy="-14.628683"
+ fx="49.10873"
+ fy="-14.628683"
+ r="48.035713"
+ gradientTransform="matrix(-1.156153,0.00571083,-0.00496751,-1.0056696,106.16882,941.03082)"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3786"
+ id="linearGradient3784"
+ x1="48.214287"
+ y1="1050.13"
+ x2="48.214287"
+ y2="994.57111"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,2.9263432e-6)" />
+ </defs>
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#000000"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="2.8"
+ inkscape:cx="89.140056"
+ inkscape:cy="36.295149"
+ inkscape:document-units="px"
+ inkscape:current-layer="layer1"
+ showgrid="false"
+ inkscape:showpageshadow="false"
+ inkscape:window-width="973"
+ inkscape:window-height="573"
+ inkscape:window-x="308"
+ inkscape:window-y="197"
+ inkscape:window-maximized="0" />
+ <metadata
+ id="metadata7">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title />
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="Ebene 1"
+ inkscape:groupmode="layer"
+ id="layer1"
+ transform="translate(0,-952.36218)"
+ style="display:inline">
+ <rect
+ style="fill:#ffffff;stroke:none;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;fill-opacity:0.64028775999999998"
+ id="rect3000"
+ width="94.446426"
+ height="94.446426"
+ x="2.8672049"
+ y="955.11957"
+ ry="6.3134527"
+ rx="6.3134527" />
+ </g>
+</svg>
diff --git a/resources/themes/bright/ring.svg b/resources/themes/bright/ring.svg
new file mode 100644
index 0000000..f11ccbd
--- /dev/null
+++ b/resources/themes/bright/ring.svg
@@ -0,0 +1,214 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="100"
+ height="100"
+ id="svg2"
+ version="1.1"
+ inkscape:version="0.48.1 r9760"
+ sodipodi:docname="ring.svg">
+ <defs
+ id="defs4">
+ <linearGradient
+ id="linearGradient3800">
+ <stop
+ style="stop-color:#5a5a5a;stop-opacity:1;"
+ offset="0"
+ id="stop3802" />
+ <stop
+ id="stop3810"
+ offset="0.79372883"
+ style="stop-color:#000000;stop-opacity:1" />
+ <stop
+ style="stop-color:#000000;stop-opacity:0"
+ offset="1"
+ id="stop3804" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3007">
+ <stop
+ id="stop3009"
+ offset="0"
+ style="stop-color:#ffffff;stop-opacity:0" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="0.3680203"
+ id="stop3011" />
+ <stop
+ id="stop3013"
+ offset="0.57677984"
+ style="stop-color:#ffffff;stop-opacity:0.66666667;" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0.45490196;"
+ offset="0.66058904"
+ id="stop3015" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0.34901961;"
+ offset="0.70194155"
+ id="stop3017" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0.25490196;"
+ offset="0.74285865"
+ id="stop3019" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0.1254902;"
+ offset="0.8251282"
+ id="stop3021" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0.05490196;"
+ offset="0.90009141"
+ id="stop3023" />
+ <stop
+ id="stop3025"
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:0" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3767">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0"
+ offset="0"
+ id="stop3769" />
+ <stop
+ id="stop4739"
+ offset="0.3680203"
+ style="stop-color:#ffffff;stop-opacity:0;" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0.66666667;"
+ offset="0.59831607"
+ id="stop4703" />
+ <stop
+ id="stop4713"
+ offset="0.66058904"
+ style="stop-color:#ffffff;stop-opacity:0.45490196;" />
+ <stop
+ id="stop4711"
+ offset="0.70194155"
+ style="stop-color:#ffffff;stop-opacity:0.34901961;" />
+ <stop
+ id="stop4709"
+ offset="0.74285865"
+ style="stop-color:#ffffff;stop-opacity:0.25490196;" />
+ <stop
+ id="stop4707"
+ offset="0.8251282"
+ style="stop-color:#ffffff;stop-opacity:0.1254902;" />
+ <stop
+ id="stop4705"
+ offset="0.90009141"
+ style="stop-color:#ffffff;stop-opacity:0.05490196;" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0"
+ offset="1"
+ id="stop3771" />
+ </linearGradient>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3767"
+ id="radialGradient3775"
+ cx="50.002552"
+ cy="49.744911"
+ fx="50.002552"
+ fy="49.744911"
+ r="49.750011"
+ gradientUnits="userSpaceOnUse" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3007"
+ id="radialGradient3005"
+ gradientUnits="userSpaceOnUse"
+ cx="50.002552"
+ cy="49.744911"
+ fx="50.002552"
+ fy="49.744911"
+ r="49.750011" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3800"
+ id="radialGradient3808"
+ cx="50"
+ cy="50"
+ fx="50"
+ fy="50"
+ r="49.47143"
+ gradientUnits="userSpaceOnUse" />
+ </defs>
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#1d1d1d"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="7.919596"
+ inkscape:cx="28.191241"
+ inkscape:cy="49.007698"
+ inkscape:document-units="px"
+ inkscape:current-layer="layer1"
+ showgrid="false"
+ inkscape:showpageshadow="false"
+ showguides="true"
+ inkscape:guide-bbox="true"
+ inkscape:window-width="1920"
+ inkscape:window-height="1056"
+ inkscape:window-x="0"
+ inkscape:window-y="24"
+ inkscape:window-maximized="1" />
+ <metadata
+ id="metadata7">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title />
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="Ebene 1"
+ inkscape:groupmode="layer"
+ id="layer1"
+ transform="translate(0,-952.36218)">
+ <path
+ transform="matrix(0.90278069,0,0,0.90278069,4.8609651,957.22314)"
+ d="M 98.57143,50 A 48.57143,48.57143 0 1 1 1.4285698,50 48.57143,48.57143 0 1 1 98.57143,50 z"
+ sodipodi:ry="48.57143"
+ sodipodi:rx="48.57143"
+ sodipodi:cy="50"
+ sodipodi:cx="50"
+ id="path3780"
+ style="opacity:0.57281553;fill:#ffffff;fill-opacity:0.42805755000000001;stroke:none"
+ sodipodi:type="arc" />
+ <path
+ sodipodi:type="arc"
+ style="opacity:0.59649120000000000;fill:none;fill-opacity:1;stroke:url(#radialGradient3808);stroke-width:9.40000000000000036;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="path3012"
+ sodipodi:cx="50"
+ sodipodi:cy="50"
+ sodipodi:rx="48.57143"
+ sodipodi:ry="48.57143"
+ d="M 98.57143,50 C 98.57143,76.82526 76.82526,98.57143 50,98.57143 23.17474,98.57143 1.4285698,76.82526 1.4285698,50 1.4285698,23.17474 23.17474,1.4285698 50,1.4285698 76.82526,1.4285698 98.57143,23.17474 98.57143,50 z"
+ transform="translate(0,952.36218)" />
+ <path
+ sodipodi:type="arc"
+ style="opacity:0.69579287999999995;fill:#ffffff;fill-opacity:1;stroke:none"
+ id="path3812"
+ sodipodi:cx="50"
+ sodipodi:cy="50"
+ sodipodi:rx="48.57143"
+ sodipodi:ry="48.57143"
+ d="M 98.57143,50 A 48.57143,48.57143 0 1 1 1.4285698,50 48.57143,48.57143 0 1 1 98.57143,50 z"
+ transform="matrix(0.79619474,0,0,0.79619474,10.190263,962.55243)" />
+ </g>
+</svg>
diff --git a/resources/themes/bright/theme.xml b/resources/themes/bright/theme.xml
new file mode 100644
index 0000000..511e3e1
--- /dev/null
+++ b/resources/themes/bright/theme.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<theme name="Bright" description="An elegant theme." author="Simon Schneegans" email="josi.schneegans@vr-web.de">
+ <pie radius="120" maxZoom="1.1" zoomRange="0.1" transitionTime="0.2" springiness="1.5"
+ fadeInTime="0.3" fadeOutTime="0.3" fadeInZoom="1.5" fadeOutZoom="0.7" fadeInRotation="0.5" fadeOutRotation="-0.7">
+ <center radius="80" activeRadius="55">
+ <center_layer file="ring.svg"
+ active_scale="0.8" active_rotationMode="auto" active_rotationSpeed="0" active_colorize="false" active_alpha="1.0"
+ inactive_scale="0.8" inactive_rotationMode="auto" inactive_rotationSpeed="0" inactive_colorize="false" inactive_alpha="1.0" />
+ <center_layer file="arrow.svg"
+ active_scale="1.0" active_rotationMode="turn_to_mouse" active_rotationSpeed="15.0" active_colorize="true" active_alpha="1.0"
+ inactive_scale="1.0" inactive_rotationMode="auto" inactive_rotationSpeed="0.0" inactive_colorize="true" inactive_alpha="0.0" />
+ </center>
+ <slices radius="26">
+ <activeSlice>
+ <slice_layer type="file" file="icon_active.svg" scale="1" colorize="true" />
+ <slice_layer type="file" file="gloss.svg" scale="1" colorize="false" />
+ <slice_layer type="icon" scale="0.9" colorize="false" />
+ </activeSlice>
+ <inactiveSlice>
+ <slice_layer type="file" file="icon_inactive.svg" scale="1" colorize="false" />
+ <slice_layer type="file" file="gloss.svg" scale="1" colorize="false" />
+ <slice_layer type="icon" scale="0.9" colorize="false" />
+ </inactiveSlice>
+ </slices>
+ <caption position="0" font="sans 10" width="90" height="90" color="#000"/>
+ </pie>
+</theme>
+
diff --git a/resources/themes/funky/bg.svg b/resources/themes/funky/bg.svg
new file mode 100644
index 0000000..1f5b6e3
--- /dev/null
+++ b/resources/themes/funky/bg.svg
@@ -0,0 +1,151 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="100"
+ height="100"
+ id="svg2"
+ version="1.1"
+ inkscape:version="0.48.1 r9760"
+ sodipodi:docname="glow_bg.svg">
+ <defs
+ id="defs4">
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient3771">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1"
+ offset="0"
+ id="stop3773" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0"
+ offset="1"
+ id="stop3775" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3767">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0"
+ offset="0"
+ id="stop3769" />
+ <stop
+ id="stop4739"
+ offset="0.39852998"
+ style="stop-color:#ffffff;stop-opacity:0;" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0.7605178"
+ offset="0.58575326"
+ id="stop4703" />
+ <stop
+ id="stop4713"
+ offset="0.66058904"
+ style="stop-color:#ffffff;stop-opacity:0.45490196;" />
+ <stop
+ id="stop4711"
+ offset="0.70194155"
+ style="stop-color:#ffffff;stop-opacity:0.34901961;" />
+ <stop
+ id="stop4709"
+ offset="0.74285865"
+ style="stop-color:#ffffff;stop-opacity:0.25490196;" />
+ <stop
+ id="stop4707"
+ offset="0.8251282"
+ style="stop-color:#ffffff;stop-opacity:0.1254902;" />
+ <stop
+ id="stop4705"
+ offset="0.90009141"
+ style="stop-color:#ffffff;stop-opacity:0.05490196;" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0"
+ offset="1"
+ id="stop3771" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3771"
+ id="linearGradient3777"
+ x1="50"
+ y1="92.75"
+ x2="50"
+ y2="50.25"
+ gradientUnits="userSpaceOnUse" />
+ <filter
+ inkscape:collect="always"
+ id="filter3773">
+ <feGaussianBlur
+ inkscape:collect="always"
+ stdDeviation="0.53661761"
+ id="feGaussianBlur3775" />
+ </filter>
+ </defs>
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#6e6e6e"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0.61176471"
+ inkscape:pageshadow="2"
+ inkscape:zoom="4"
+ inkscape:cx="10.117591"
+ inkscape:cy="36.683022"
+ inkscape:document-units="px"
+ inkscape:current-layer="layer1"
+ showgrid="false"
+ inkscape:showpageshadow="false"
+ showguides="true"
+ inkscape:guide-bbox="true"
+ inkscape:window-width="1920"
+ inkscape:window-height="1056"
+ inkscape:window-x="0"
+ inkscape:window-y="24"
+ inkscape:window-maximized="1">
+ <sodipodi:guide
+ orientation="0,1"
+ position="50,49.75"
+ id="guide3916" />
+ <sodipodi:guide
+ orientation="1,0"
+ position="50,43.125"
+ id="guide3918" />
+ </sodipodi:namedview>
+ <metadata
+ id="metadata7">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title></dc:title>
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="Ebene 1"
+ inkscape:groupmode="layer"
+ id="layer1"
+ transform="translate(0,-952.36218)">
+ <path
+ sodipodi:type="spiral"
+ style="fill:none;stroke:#000000;stroke-width:2.50000000000000000;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:3.99999990000000016;stroke-dasharray:none;filter:url(#filter3773)"
+ id="path2999"
+ sodipodi:cx="50"
+ sodipodi:cy="50.25"
+ sodipodi:expansion="1.71"
+ sodipodi:revolution="3"
+ sodipodi:radius="41.75"
+ sodipodi:argument="-17.278759"
+ sodipodi:t0="0"
+ d="m 50,50.25 c 0,0.286456 -0.509907,0.0791 -0.596014,0 -0.660289,-0.606539 -0.01383,-1.617979 0.596015,-1.949925 1.581367,-0.860752 3.360347,0.461046 3.900621,1.949927 1.028026,2.833021 -1.225693,5.651393 -3.900626,6.379387 C 45.65224,57.81265 41.557734,54.387932 40.656809,50.249994 39.32605,44.137839 44.142155,38.551518 50.000008,37.488692 58.114147,36.016495 65.394074,42.430257 66.610174,50.25001 68.218744,60.593412 60.011902,69.758474 49.999988,71.120864 37.208799,72.861449 25.975193,62.674766 24.472327,50.249985 22.60354,34.8 34.949675,21.321139 50.000018,19.682738 68.313284,17.68913 84.20842,32.368275 85.978085,50.250021 88.093487,71.625315 70.912998,90.102818 49.999975,92"
+ transform="translate(0,952.36218)" />
+ </g>
+</svg>
diff --git a/resources/themes/funky/blue.svg b/resources/themes/funky/blue.svg
new file mode 100644
index 0000000..159516c
--- /dev/null
+++ b/resources/themes/funky/blue.svg
@@ -0,0 +1,148 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="100"
+ height="100"
+ id="svg2"
+ version="1.1"
+ inkscape:version="0.48.1 r9760"
+ sodipodi:docname="star.svg">
+ <defs
+ id="defs4">
+ <linearGradient
+ id="linearGradient3767">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0"
+ offset="0"
+ id="stop3769" />
+ <stop
+ id="stop4739"
+ offset="0.39852998"
+ style="stop-color:#ffffff;stop-opacity:0;" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0.7605178"
+ offset="0.58575326"
+ id="stop4703" />
+ <stop
+ id="stop4713"
+ offset="0.66058904"
+ style="stop-color:#ffffff;stop-opacity:0.45490196;" />
+ <stop
+ id="stop4711"
+ offset="0.70194155"
+ style="stop-color:#ffffff;stop-opacity:0.34901961;" />
+ <stop
+ id="stop4709"
+ offset="0.74285865"
+ style="stop-color:#ffffff;stop-opacity:0.25490196;" />
+ <stop
+ id="stop4707"
+ offset="0.8251282"
+ style="stop-color:#ffffff;stop-opacity:0.1254902;" />
+ <stop
+ id="stop4705"
+ offset="0.90009141"
+ style="stop-color:#ffffff;stop-opacity:0.05490196;" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0"
+ offset="1"
+ id="stop3771" />
+ </linearGradient>
+ </defs>
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#6e6e6e"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0.61176471"
+ inkscape:pageshadow="2"
+ inkscape:zoom="4"
+ inkscape:cx="10.117591"
+ inkscape:cy="36.683022"
+ inkscape:document-units="px"
+ inkscape:current-layer="layer1"
+ showgrid="false"
+ inkscape:showpageshadow="false"
+ showguides="true"
+ inkscape:guide-bbox="true"
+ inkscape:window-width="1920"
+ inkscape:window-height="1056"
+ inkscape:window-x="0"
+ inkscape:window-y="24"
+ inkscape:window-maximized="1">
+ <sodipodi:guide
+ orientation="0,1"
+ position="50,49.75"
+ id="guide3916" />
+ <sodipodi:guide
+ orientation="1,0"
+ position="50,43.125"
+ id="guide3918" />
+ </sodipodi:namedview>
+ <metadata
+ id="metadata7">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title></dc:title>
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="Ebene 1"
+ inkscape:groupmode="layer"
+ id="layer1"
+ transform="translate(0,-952.36218)">
+ <path
+ sodipodi:type="arc"
+ style="fill:#a5ecff;fill-opacity:1;stroke:#000000;stroke-width:1.19999999999999996;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="path3817"
+ sodipodi:cx="50"
+ sodipodi:cy="8.75"
+ sodipodi:rx="7"
+ sodipodi:ry="7"
+ d="m 57,8.75 a 7,7 0 1 1 -14,0 7,7 0 1 1 14,0 z"
+ transform="translate(0,955.11218)" />
+ <path
+ transform="translate(37.5,993.86218)"
+ d="m 57,8.75 a 7,7 0 1 1 -14,0 7,7 0 1 1 14,0 z"
+ sodipodi:ry="7"
+ sodipodi:rx="7"
+ sodipodi:cy="8.75"
+ sodipodi:cx="50"
+ id="path3819"
+ style="fill:#a5ecff;fill-opacity:1;stroke:#000000;stroke-width:1.20000005;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ sodipodi:type="arc" />
+ <path
+ sodipodi:type="arc"
+ style="fill:#a5ecff;fill-opacity:1;stroke:#000000;stroke-width:1.20000005;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="path3821"
+ sodipodi:cx="50"
+ sodipodi:cy="8.75"
+ sodipodi:rx="7"
+ sodipodi:ry="7"
+ d="m 57,8.75 a 7,7 0 1 1 -14,0 7,7 0 1 1 14,0 z"
+ transform="translate(0,1031.6122)" />
+ <path
+ transform="translate(-37.25,993.86218)"
+ d="m 57,8.75 a 7,7 0 1 1 -14,0 7,7 0 1 1 14,0 z"
+ sodipodi:ry="7"
+ sodipodi:rx="7"
+ sodipodi:cy="8.75"
+ sodipodi:cx="50"
+ id="path3823"
+ style="fill:#a5ecff;fill-opacity:1;stroke:#000000;stroke-width:1.20000005;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ sodipodi:type="arc" />
+ </g>
+</svg>
diff --git a/resources/themes/funky/caption.svg b/resources/themes/funky/caption.svg
new file mode 100644
index 0000000..ebdc75d
--- /dev/null
+++ b/resources/themes/funky/caption.svg
@@ -0,0 +1,130 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="100"
+ height="100"
+ id="svg2"
+ version="1.1"
+ inkscape:version="0.48.1 r9760"
+ sodipodi:docname="caption.svg">
+ <defs
+ id="defs4">
+ <linearGradient
+ id="linearGradient3767">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0"
+ offset="0"
+ id="stop3769" />
+ <stop
+ id="stop4739"
+ offset="0.39852998"
+ style="stop-color:#ffffff;stop-opacity:0;" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0.7605178"
+ offset="0.58575326"
+ id="stop4703" />
+ <stop
+ id="stop4713"
+ offset="0.66058904"
+ style="stop-color:#ffffff;stop-opacity:0.45490196;" />
+ <stop
+ id="stop4711"
+ offset="0.70194155"
+ style="stop-color:#ffffff;stop-opacity:0.34901961;" />
+ <stop
+ id="stop4709"
+ offset="0.74285865"
+ style="stop-color:#ffffff;stop-opacity:0.25490196;" />
+ <stop
+ id="stop4707"
+ offset="0.8251282"
+ style="stop-color:#ffffff;stop-opacity:0.1254902;" />
+ <stop
+ id="stop4705"
+ offset="0.90009141"
+ style="stop-color:#ffffff;stop-opacity:0.05490196;" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0"
+ offset="1"
+ id="stop3771" />
+ </linearGradient>
+ <filter
+ inkscape:collect="always"
+ id="filter3780"
+ x="-0.19497946"
+ width="1.3899589"
+ y="-1.3648562"
+ height="3.7297125">
+ <feGaussianBlur
+ inkscape:collect="always"
+ stdDeviation="5.1182109"
+ id="feGaussianBlur3782" />
+ </filter>
+ </defs>
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#6e6e6e"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0.61176471"
+ inkscape:pageshadow="2"
+ inkscape:zoom="4"
+ inkscape:cx="-40.757409"
+ inkscape:cy="36.683022"
+ inkscape:document-units="px"
+ inkscape:current-layer="layer1"
+ showgrid="false"
+ inkscape:showpageshadow="false"
+ showguides="true"
+ inkscape:guide-bbox="true"
+ inkscape:window-width="1920"
+ inkscape:window-height="1056"
+ inkscape:window-x="0"
+ inkscape:window-y="24"
+ inkscape:window-maximized="1">
+ <sodipodi:guide
+ orientation="0,1"
+ position="50,49.75"
+ id="guide3916" />
+ <sodipodi:guide
+ orientation="1,0"
+ position="50,43.125"
+ id="guide3918" />
+ </sodipodi:namedview>
+ <metadata
+ id="metadata7">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title />
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="Ebene 1"
+ inkscape:groupmode="layer"
+ id="layer1"
+ transform="translate(0,-952.36218)">
+ <rect
+ style="fill:#000000;fill-opacity:1;stroke:none;filter:url(#filter3780)"
+ id="rect2998"
+ width="63"
+ height="9"
+ x="18.5"
+ y="960.36218"
+ rx="7.3848815"
+ ry="6.159205"
+ transform="matrix(1,0,0,-1.1120224,0,2056.9934)" />
+ </g>
+</svg>
diff --git a/resources/themes/funky/icon_bg.svg b/resources/themes/funky/icon_bg.svg
new file mode 100644
index 0000000..4c37253
--- /dev/null
+++ b/resources/themes/funky/icon_bg.svg
@@ -0,0 +1,118 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="100"
+ height="100"
+ id="svg2"
+ version="1.1"
+ inkscape:version="0.48.1 r9760"
+ sodipodi:docname="icon_bg.svg">
+ <defs
+ id="defs4">
+ <linearGradient
+ id="linearGradient3767">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0"
+ offset="0"
+ id="stop3769" />
+ <stop
+ id="stop4739"
+ offset="0.39852998"
+ style="stop-color:#ffffff;stop-opacity:0;" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0.7605178"
+ offset="0.58575326"
+ id="stop4703" />
+ <stop
+ id="stop4713"
+ offset="0.66058904"
+ style="stop-color:#ffffff;stop-opacity:0.45490196;" />
+ <stop
+ id="stop4711"
+ offset="0.70194155"
+ style="stop-color:#ffffff;stop-opacity:0.34901961;" />
+ <stop
+ id="stop4709"
+ offset="0.74285865"
+ style="stop-color:#ffffff;stop-opacity:0.25490196;" />
+ <stop
+ id="stop4707"
+ offset="0.8251282"
+ style="stop-color:#ffffff;stop-opacity:0.1254902;" />
+ <stop
+ id="stop4705"
+ offset="0.90009141"
+ style="stop-color:#ffffff;stop-opacity:0.05490196;" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0"
+ offset="1"
+ id="stop3771" />
+ </linearGradient>
+ </defs>
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#6e6e6e"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0.61176471"
+ inkscape:pageshadow="2"
+ inkscape:zoom="4"
+ inkscape:cx="11.117591"
+ inkscape:cy="36.183022"
+ inkscape:document-units="px"
+ inkscape:current-layer="layer1"
+ showgrid="false"
+ inkscape:showpageshadow="false"
+ showguides="true"
+ inkscape:guide-bbox="true"
+ inkscape:window-width="1920"
+ inkscape:window-height="1056"
+ inkscape:window-x="0"
+ inkscape:window-y="24"
+ inkscape:window-maximized="1">
+ <sodipodi:guide
+ orientation="0,1"
+ position="50,49.75"
+ id="guide3916" />
+ <sodipodi:guide
+ orientation="1,0"
+ position="50,43.125"
+ id="guide3918" />
+ </sodipodi:namedview>
+ <metadata
+ id="metadata7">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title />
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="Ebene 1"
+ inkscape:groupmode="layer"
+ id="layer1"
+ transform="translate(0,-952.36218)">
+ <path
+ sodipodi:type="arc"
+ style="fill:#000000;fill-opacity:1;stroke:none"
+ id="path2997"
+ sodipodi:cx="50"
+ sodipodi:cy="50.25"
+ sodipodi:rx="42.75"
+ sodipodi:ry="42.75"
+ d="m 92.75,50.25 a 42.75,42.75 0 1 1 -85.5,0 42.75,42.75 0 1 1 85.5,0 z"
+ transform="matrix(1.1461988,0,0,1.1461988,-7.3099415,945.01569)" />
+ </g>
+</svg>
diff --git a/resources/themes/funky/icon_fg.svg b/resources/themes/funky/icon_fg.svg
new file mode 100644
index 0000000..f2f8207
--- /dev/null
+++ b/resources/themes/funky/icon_fg.svg
@@ -0,0 +1,118 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="100"
+ height="100"
+ id="svg2"
+ version="1.1"
+ inkscape:version="0.48.1 r9760"
+ sodipodi:docname="icon_fg.svg">
+ <defs
+ id="defs4">
+ <linearGradient
+ id="linearGradient3767">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0"
+ offset="0"
+ id="stop3769" />
+ <stop
+ id="stop4739"
+ offset="0.39852998"
+ style="stop-color:#ffffff;stop-opacity:0;" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0.7605178"
+ offset="0.58575326"
+ id="stop4703" />
+ <stop
+ id="stop4713"
+ offset="0.66058904"
+ style="stop-color:#ffffff;stop-opacity:0.45490196;" />
+ <stop
+ id="stop4711"
+ offset="0.70194155"
+ style="stop-color:#ffffff;stop-opacity:0.34901961;" />
+ <stop
+ id="stop4709"
+ offset="0.74285865"
+ style="stop-color:#ffffff;stop-opacity:0.25490196;" />
+ <stop
+ id="stop4707"
+ offset="0.8251282"
+ style="stop-color:#ffffff;stop-opacity:0.1254902;" />
+ <stop
+ id="stop4705"
+ offset="0.90009141"
+ style="stop-color:#ffffff;stop-opacity:0.05490196;" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0"
+ offset="1"
+ id="stop3771" />
+ </linearGradient>
+ </defs>
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#6e6e6e"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0.61176471"
+ inkscape:pageshadow="2"
+ inkscape:zoom="4"
+ inkscape:cx="11.117591"
+ inkscape:cy="36.183022"
+ inkscape:document-units="px"
+ inkscape:current-layer="layer1"
+ showgrid="false"
+ inkscape:showpageshadow="false"
+ showguides="true"
+ inkscape:guide-bbox="true"
+ inkscape:window-width="1920"
+ inkscape:window-height="1056"
+ inkscape:window-x="0"
+ inkscape:window-y="24"
+ inkscape:window-maximized="1">
+ <sodipodi:guide
+ orientation="0,1"
+ position="50,49.75"
+ id="guide3916" />
+ <sodipodi:guide
+ orientation="1,0"
+ position="50,43.125"
+ id="guide3918" />
+ </sodipodi:namedview>
+ <metadata
+ id="metadata7">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title />
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="Ebene 1"
+ inkscape:groupmode="layer"
+ id="layer1"
+ transform="translate(0,-952.36218)">
+ <path
+ sodipodi:type="arc"
+ style="fill:#c3c3c3;fill-opacity:1;stroke:none"
+ id="path2997"
+ sodipodi:cx="50"
+ sodipodi:cy="50.25"
+ sodipodi:rx="42.75"
+ sodipodi:ry="42.75"
+ d="m 92.75,50.25 a 42.75,42.75 0 1 1 -85.5,0 42.75,42.75 0 1 1 85.5,0 z"
+ transform="matrix(1.0818714,0,0,1.0818714,-4.0935673,948.24815)" />
+ </g>
+</svg>
diff --git a/resources/themes/funky/red.svg b/resources/themes/funky/red.svg
new file mode 100644
index 0000000..9932ebb
--- /dev/null
+++ b/resources/themes/funky/red.svg
@@ -0,0 +1,148 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="100"
+ height="100"
+ id="svg2"
+ version="1.1"
+ inkscape:version="0.48.1 r9760"
+ sodipodi:docname="blue.svg">
+ <defs
+ id="defs4">
+ <linearGradient
+ id="linearGradient3767">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0"
+ offset="0"
+ id="stop3769" />
+ <stop
+ id="stop4739"
+ offset="0.39852998"
+ style="stop-color:#ffffff;stop-opacity:0;" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0.7605178"
+ offset="0.58575326"
+ id="stop4703" />
+ <stop
+ id="stop4713"
+ offset="0.66058904"
+ style="stop-color:#ffffff;stop-opacity:0.45490196;" />
+ <stop
+ id="stop4711"
+ offset="0.70194155"
+ style="stop-color:#ffffff;stop-opacity:0.34901961;" />
+ <stop
+ id="stop4709"
+ offset="0.74285865"
+ style="stop-color:#ffffff;stop-opacity:0.25490196;" />
+ <stop
+ id="stop4707"
+ offset="0.8251282"
+ style="stop-color:#ffffff;stop-opacity:0.1254902;" />
+ <stop
+ id="stop4705"
+ offset="0.90009141"
+ style="stop-color:#ffffff;stop-opacity:0.05490196;" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0"
+ offset="1"
+ id="stop3771" />
+ </linearGradient>
+ </defs>
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#6e6e6e"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0.61176471"
+ inkscape:pageshadow="2"
+ inkscape:zoom="4"
+ inkscape:cx="10.117591"
+ inkscape:cy="36.683022"
+ inkscape:document-units="px"
+ inkscape:current-layer="layer1"
+ showgrid="false"
+ inkscape:showpageshadow="false"
+ showguides="true"
+ inkscape:guide-bbox="true"
+ inkscape:window-width="1920"
+ inkscape:window-height="1056"
+ inkscape:window-x="0"
+ inkscape:window-y="24"
+ inkscape:window-maximized="1">
+ <sodipodi:guide
+ orientation="0,1"
+ position="50,49.75"
+ id="guide3916" />
+ <sodipodi:guide
+ orientation="1,0"
+ position="50,43.125"
+ id="guide3918" />
+ </sodipodi:namedview>
+ <metadata
+ id="metadata7">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title></dc:title>
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="Ebene 1"
+ inkscape:groupmode="layer"
+ id="layer1"
+ transform="translate(0,-952.36218)">
+ <path
+ sodipodi:type="arc"
+ style="fill:#ffa5d9;fill-opacity:1;stroke:#000000;stroke-width:1.20000005000000010;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="path3817"
+ sodipodi:cx="50"
+ sodipodi:cy="8.75"
+ sodipodi:rx="7"
+ sodipodi:ry="7"
+ d="m 57,8.75 a 7,7 0 1 1 -14,0 7,7 0 1 1 14,0 z"
+ transform="matrix(0.71942091,0.69457437,-0.69457437,0.71942091,46.709029,933.48386)" />
+ <path
+ transform="matrix(0.71942091,0.69457437,-0.69457437,0.71942091,46.772556,987.40796)"
+ d="m 57,8.75 a 7,7 0 1 1 -14,0 7,7 0 1 1 14,0 z"
+ sodipodi:ry="7"
+ sodipodi:rx="7"
+ sodipodi:cy="8.75"
+ sodipodi:cx="50"
+ id="path3819"
+ style="fill:#ffa5d9;fill-opacity:1;stroke:#000000;stroke-width:1.20000005000000010;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ sodipodi:type="arc" />
+ <path
+ sodipodi:type="arc"
+ style="fill:#ffa5d9;fill-opacity:1;stroke:#000000;stroke-width:1.20000005000000010;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="path3821"
+ sodipodi:cx="50"
+ sodipodi:cy="8.75"
+ sodipodi:rx="7"
+ sodipodi:ry="7"
+ d="m 57,8.75 a 7,7 0 1 1 -14,0 7,7 0 1 1 14,0 z"
+ transform="matrix(0.71942091,0.69457437,-0.69457437,0.71942091,-6.425924,988.51957)" />
+ <path
+ transform="matrix(0.71942091,0.69457437,-0.69457437,0.71942091,-7.0041566,935.48852)"
+ d="m 57,8.75 a 7,7 0 1 1 -14,0 7,7 0 1 1 14,0 z"
+ sodipodi:ry="7"
+ sodipodi:rx="7"
+ sodipodi:cy="8.75"
+ sodipodi:cx="50"
+ id="path3823"
+ style="fill:#ffa5d9;fill-opacity:1;stroke:#000000;stroke-width:1.20000005000000010;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ sodipodi:type="arc" />
+ </g>
+</svg>
diff --git a/resources/themes/funky/star.svg b/resources/themes/funky/star.svg
new file mode 100644
index 0000000..4faac80
--- /dev/null
+++ b/resources/themes/funky/star.svg
@@ -0,0 +1,126 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="100"
+ height="100"
+ id="svg2"
+ version="1.1"
+ inkscape:version="0.48.1 r9760"
+ sodipodi:docname="star.svg">
+ <defs
+ id="defs4">
+ <linearGradient
+ id="linearGradient3767">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0"
+ offset="0"
+ id="stop3769" />
+ <stop
+ id="stop4739"
+ offset="0.39852998"
+ style="stop-color:#ffffff;stop-opacity:0;" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0.7605178"
+ offset="0.58575326"
+ id="stop4703" />
+ <stop
+ id="stop4713"
+ offset="0.66058904"
+ style="stop-color:#ffffff;stop-opacity:0.45490196;" />
+ <stop
+ id="stop4711"
+ offset="0.70194155"
+ style="stop-color:#ffffff;stop-opacity:0.34901961;" />
+ <stop
+ id="stop4709"
+ offset="0.74285865"
+ style="stop-color:#ffffff;stop-opacity:0.25490196;" />
+ <stop
+ id="stop4707"
+ offset="0.8251282"
+ style="stop-color:#ffffff;stop-opacity:0.1254902;" />
+ <stop
+ id="stop4705"
+ offset="0.90009141"
+ style="stop-color:#ffffff;stop-opacity:0.05490196;" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0"
+ offset="1"
+ id="stop3771" />
+ </linearGradient>
+ </defs>
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#6e6e6e"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0.61176471"
+ inkscape:pageshadow="2"
+ inkscape:zoom="4"
+ inkscape:cx="10.117591"
+ inkscape:cy="36.683022"
+ inkscape:document-units="px"
+ inkscape:current-layer="layer1"
+ showgrid="false"
+ inkscape:showpageshadow="false"
+ showguides="true"
+ inkscape:guide-bbox="true"
+ inkscape:window-width="1920"
+ inkscape:window-height="1056"
+ inkscape:window-x="0"
+ inkscape:window-y="24"
+ inkscape:window-maximized="1">
+ <sodipodi:guide
+ orientation="0,1"
+ position="50,49.75"
+ id="guide3916" />
+ <sodipodi:guide
+ orientation="1,0"
+ position="50,43.125"
+ id="guide3918" />
+ </sodipodi:namedview>
+ <metadata
+ id="metadata7">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title />
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="Ebene 1"
+ inkscape:groupmode="layer"
+ id="layer1"
+ transform="translate(0,-952.36218)">
+ <path
+ sodipodi:type="star"
+ style="fill:#fdffa5;fill-opacity:1;stroke:#000000;stroke-opacity:1"
+ id="path3796"
+ sodipodi:sides="5"
+ sodipodi:cx="16.5"
+ sodipodi:cy="13.25"
+ sodipodi:r1="31.705679"
+ sodipodi:r2="15.852839"
+ sodipodi:arg1="0.66242629"
+ sodipodi:arg2="1.2907448"
+ inkscape:flatsided="false"
+ inkscape:rounded="0"
+ inkscape:randomized="0"
+ d="M 41.500001,32.750001 20.881807,28.485232 5.6798225,43.052245 3.3644863,22.125291 -15.187238,12.1688 3.9999993,3.4999999 7.7363871,-17.220464 21.910088,-1.6511229 42.771028,-4.5005823 32.343619,13.7906 z"
+ transform="matrix(0.4330051,0,0,0.4330051,79.011797,996.64078)"
+ inkscape:transform-center-x="1.1726231"
+ inkscape:transform-center-y="-0.14467343" />
+ </g>
+</svg>
diff --git a/resources/themes/funky/theme.xml b/resources/themes/funky/theme.xml
new file mode 100644
index 0000000..a953089
--- /dev/null
+++ b/resources/themes/funky/theme.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<theme name="Funky" description="Just testing what these themes can do..." author="Simon Schneegans" email="josi.schneegans@vr-web.de">
+ <pie radius="80" maxZoom="1.3" zoomRange="0.3" transitionTime="0.2" springiness="2.5"
+ fadeInTime="0.3" fadeOutTime="0.3" fadeInZoom="1.5" fadeOutZoom="0.4" fadeInRotation="0.5" fadeOutRotation="-0.7">
+ <center radius="100" activeRadius="40">
+ <center_layer file="bg.svg"
+ active_scale="0.5" active_rotationMode="auto" active_rotationSpeed="6" active_colorize="false" active_alpha="1.0"
+ inactive_scale="0.5" inactive_rotationMode="auto" inactive_rotationSpeed="-6" inactive_colorize="false" inactive_alpha="1.0" />
+ <center_layer file="star.svg"
+ active_scale="1.0" active_rotationMode="turn_to_mouse" active_rotationSpeed="5" active_colorize="false" active_alpha="1.0"
+ inactive_scale="0.3" inactive_rotationMode="auto" inactive_rotationSpeed="1" inactive_colorize="false" inactive_alpha="1.0" />
+ <center_layer file="red.svg"
+ active_scale="1.0" active_rotationMode="auto" active_rotationSpeed="-2" active_colorize="false" active_alpha="1.0"
+ inactive_scale="0.5" inactive_rotationMode="auto" inactive_rotationSpeed="-2" inactive_colorize="false" inactive_alpha="1.0" />
+ <center_layer file="blue.svg"
+ active_scale="0.5" active_rotationMode="auto" active_rotationSpeed="2" active_colorize="false" active_alpha="1.0"
+ inactive_scale="1.0" inactive_rotationMode="auto" inactive_rotationSpeed="2" inactive_colorize="false" inactive_alpha="1.0" />
+ <center_layer file="caption.svg"
+ active_scale="1.0" active_rotationMode="auto" active_rotationSpeed="0" active_colorize="false" active_alpha="0.8"
+ inactive_scale="1.0" inactive_rotationMode="auto" inactive_rotationSpeed="0" inactive_colorize="false" inactive_alpha="0.0" />
+ </center>
+ <slices radius="30" minGap="0">
+ <activeSlice>
+ <slice_layer type="file" file="icon_bg.svg" scale="1" colorize="false" />
+ <slice_layer type="file" file="icon_fg.svg" scale="1" colorize="true" />
+ <slice_layer type="icon" scale="0.7"/>
+ </activeSlice>
+ <inactiveSlice>
+ <slice_layer type="file" file="icon_bg.svg" scale="0.7" colorize="false" />
+ <slice_layer type="file" file="icon_fg.svg" scale="0.65" colorize="false" />
+ <slice_layer type="icon" scale="0.5"/>
+ </inactiveSlice>
+ </slices>
+ <caption position="-35" font="sans bold 10" width="100" height="30" />
+ </pie>
+</theme>
+
diff --git a/resources/themes/gloss/arrow.svg b/resources/themes/gloss/arrow.svg
new file mode 100644
index 0000000..10cd599
--- /dev/null
+++ b/resources/themes/gloss/arrow.svg
@@ -0,0 +1,225 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="100"
+ height="100"
+ id="svg2"
+ version="1.1"
+ inkscape:version="0.48.1 r9760"
+ sodipodi:docname="icon_fg.svg">
+ <defs
+ id="defs4">
+ <linearGradient
+ id="linearGradient3791"
+ inkscape:collect="always">
+ <stop
+ id="stop3793"
+ offset="0"
+ style="stop-color:#ffffff;stop-opacity:0" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1"
+ offset="0.49609163"
+ id="stop3797" />
+ <stop
+ id="stop3795"
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:0" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient4240">
+ <stop
+ style="stop-color:#000000;stop-opacity:0"
+ offset="0"
+ id="stop4242" />
+ <stop
+ id="stop4250"
+ offset="0.78713447"
+ style="stop-color:#000000;stop-opacity:0" />
+ <stop
+ id="stop4248"
+ offset="0.8975364"
+ style="stop-color:#000000;stop-opacity:1" />
+ <stop
+ style="stop-color:#000000;stop-opacity:0"
+ offset="1"
+ id="stop4244" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient4228">
+ <stop
+ style="stop-color:#d4d4d4;stop-opacity:1"
+ offset="0"
+ id="stop4230" />
+ <stop
+ style="stop-color:#0b0b0b;stop-opacity:1"
+ offset="1"
+ id="stop4232" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient4216">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1"
+ offset="0"
+ id="stop4218" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0"
+ offset="1"
+ id="stop4220" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3767">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0"
+ offset="0"
+ id="stop3769" />
+ <stop
+ id="stop4739"
+ offset="0.39852998"
+ style="stop-color:#ffffff;stop-opacity:0;" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0.7605178"
+ offset="0.58575326"
+ id="stop4703" />
+ <stop
+ id="stop4713"
+ offset="0.66058904"
+ style="stop-color:#ffffff;stop-opacity:0.45490196;" />
+ <stop
+ id="stop4711"
+ offset="0.70194155"
+ style="stop-color:#ffffff;stop-opacity:0.34901961;" />
+ <stop
+ id="stop4709"
+ offset="0.74285865"
+ style="stop-color:#ffffff;stop-opacity:0.25490196;" />
+ <stop
+ id="stop4707"
+ offset="0.8251282"
+ style="stop-color:#ffffff;stop-opacity:0.1254902;" />
+ <stop
+ id="stop4705"
+ offset="0.90009141"
+ style="stop-color:#ffffff;stop-opacity:0.05490196;" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0"
+ offset="1"
+ id="stop3771" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4216"
+ id="linearGradient4222"
+ x1="50"
+ y1="7.0154586"
+ x2="50"
+ y2="56.874996"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.75590848,0,-12.45593)" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4228"
+ id="linearGradient4234"
+ x1="19.54899"
+ y1="18.430195"
+ x2="85.931084"
+ y2="85.605339"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.88419848,0,0,0.88419848,5.7900758,5.8190262)" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4240"
+ id="radialGradient4246"
+ cx="50.993256"
+ cy="51.135944"
+ fx="50.993256"
+ fy="51.135944"
+ r="39.143398"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.73416584,0.61180559,-0.62443446,0.74862707,45.385927,-18.201904)" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4228"
+ id="linearGradient3018"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.88419847,0,0,0.88419847,5.7900759,-946.54315)"
+ x1="19.54899"
+ y1="18.430195"
+ x2="85.931084"
+ y2="85.605339" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3791"
+ id="linearGradient3789"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.88419847,0,0,0.88419847,5.7900759,-946.54315)"
+ x1="99.33847"
+ y1="1102.5673"
+ x2="99.33847"
+ y2="1152.505" />
+ </defs>
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#1d1d1d"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="8"
+ inkscape:cx="69.793143"
+ inkscape:cy="37.175187"
+ inkscape:document-units="px"
+ inkscape:current-layer="layer1"
+ showgrid="false"
+ inkscape:showpageshadow="false"
+ showguides="true"
+ inkscape:guide-bbox="true"
+ inkscape:window-width="1920"
+ inkscape:window-height="1056"
+ inkscape:window-x="0"
+ inkscape:window-y="24"
+ inkscape:window-maximized="1">
+ <sodipodi:guide
+ orientation="0,1"
+ position="50,49.75"
+ id="guide3916" />
+ <sodipodi:guide
+ orientation="1,0"
+ position="50,43.125"
+ id="guide3918" />
+ </sodipodi:namedview>
+ <metadata
+ id="metadata7">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title></dc:title>
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="Ebene 1"
+ inkscape:groupmode="layer"
+ id="layer1"
+ transform="translate(0,-952.36218)">
+ <path
+ style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;color:#000000;fill:url(#linearGradient3789);fill-opacity:1;stroke:none;stroke-width:5.30519104000000041;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Sans;-inkscape-font-specification:Sans"
+ d="M 83.09375 16.5625 L 83.09375 25.53125 C 88.240624 32.416999 91.28125 40.976003 91.28125 50.25 C 91.28125 59.523997 88.240624 68.083009 83.09375 74.96875 L 83.09375 83.9375 C 91.822678 75.360707 97.25 63.43584 97.25 50.25 C 97.25 37.06414 91.822678 25.139306 83.09375 16.5625 z "
+ transform="translate(0,952.36218)"
+ id="path4226" />
+ </g>
+</svg>
diff --git a/resources/themes/gloss/glow_bg.svg b/resources/themes/gloss/glow_bg.svg
new file mode 100644
index 0000000..a4bb460
--- /dev/null
+++ b/resources/themes/gloss/glow_bg.svg
@@ -0,0 +1,140 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="100"
+ height="100"
+ id="svg2"
+ version="1.1"
+ inkscape:version="0.48.1 r9760"
+ sodipodi:docname="glow_bg.svg">
+ <defs
+ id="defs4">
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient3771">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1"
+ offset="0"
+ id="stop3773" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0"
+ offset="1"
+ id="stop3775" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3767">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0"
+ offset="0"
+ id="stop3769" />
+ <stop
+ id="stop4739"
+ offset="0.39852998"
+ style="stop-color:#ffffff;stop-opacity:0;" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0.7605178"
+ offset="0.58575326"
+ id="stop4703" />
+ <stop
+ id="stop4713"
+ offset="0.66058904"
+ style="stop-color:#ffffff;stop-opacity:0.45490196;" />
+ <stop
+ id="stop4711"
+ offset="0.70194155"
+ style="stop-color:#ffffff;stop-opacity:0.34901961;" />
+ <stop
+ id="stop4709"
+ offset="0.74285865"
+ style="stop-color:#ffffff;stop-opacity:0.25490196;" />
+ <stop
+ id="stop4707"
+ offset="0.8251282"
+ style="stop-color:#ffffff;stop-opacity:0.1254902;" />
+ <stop
+ id="stop4705"
+ offset="0.90009141"
+ style="stop-color:#ffffff;stop-opacity:0.05490196;" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0"
+ offset="1"
+ id="stop3771" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3771"
+ id="linearGradient3777"
+ x1="50"
+ y1="92.75"
+ x2="50"
+ y2="50.25"
+ gradientUnits="userSpaceOnUse" />
+ </defs>
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="4"
+ inkscape:cx="-29.007409"
+ inkscape:cy="39.183022"
+ inkscape:document-units="px"
+ inkscape:current-layer="layer1"
+ showgrid="false"
+ inkscape:showpageshadow="false"
+ showguides="true"
+ inkscape:guide-bbox="true"
+ inkscape:window-width="1920"
+ inkscape:window-height="1056"
+ inkscape:window-x="0"
+ inkscape:window-y="24"
+ inkscape:window-maximized="1">
+ <sodipodi:guide
+ orientation="0,1"
+ position="50,49.75"
+ id="guide3916" />
+ <sodipodi:guide
+ orientation="1,0"
+ position="50,43.125"
+ id="guide3918" />
+ </sodipodi:namedview>
+ <metadata
+ id="metadata7">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title />
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="Ebene 1"
+ inkscape:groupmode="layer"
+ id="layer1"
+ transform="translate(0,-952.36218)">
+ <path
+ sodipodi:type="arc"
+ style="opacity:1;fill:url(#linearGradient3777);fill-opacity:1;stroke:none"
+ id="path4364"
+ sodipodi:cx="50"
+ sodipodi:cy="50.25"
+ sodipodi:rx="44"
+ sodipodi:ry="44"
+ d="m 94,50.25 c 0,24.300529 -19.699471,44 -44,44 -24.300529,0 -44,-19.699471 -44,-44 0,-24.300529 19.699471,-44 44,-44 24.300529,0 44,19.699471 44,44 z"
+ transform="translate(0,952.36218)" />
+ </g>
+</svg>
diff --git a/resources/themes/gloss/icon_bg.svg b/resources/themes/gloss/icon_bg.svg
new file mode 100644
index 0000000..cbbda42
--- /dev/null
+++ b/resources/themes/gloss/icon_bg.svg
@@ -0,0 +1,118 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="100"
+ height="100"
+ id="svg2"
+ version="1.1"
+ inkscape:version="0.48.1 r9760"
+ sodipodi:docname="icon_mask.svg">
+ <defs
+ id="defs4">
+ <linearGradient
+ id="linearGradient3767">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0"
+ offset="0"
+ id="stop3769" />
+ <stop
+ id="stop4739"
+ offset="0.39852998"
+ style="stop-color:#ffffff;stop-opacity:0;" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0.7605178"
+ offset="0.58575326"
+ id="stop4703" />
+ <stop
+ id="stop4713"
+ offset="0.66058904"
+ style="stop-color:#ffffff;stop-opacity:0.45490196;" />
+ <stop
+ id="stop4711"
+ offset="0.70194155"
+ style="stop-color:#ffffff;stop-opacity:0.34901961;" />
+ <stop
+ id="stop4709"
+ offset="0.74285865"
+ style="stop-color:#ffffff;stop-opacity:0.25490196;" />
+ <stop
+ id="stop4707"
+ offset="0.8251282"
+ style="stop-color:#ffffff;stop-opacity:0.1254902;" />
+ <stop
+ id="stop4705"
+ offset="0.90009141"
+ style="stop-color:#ffffff;stop-opacity:0.05490196;" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0"
+ offset="1"
+ id="stop3771" />
+ </linearGradient>
+ </defs>
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="4"
+ inkscape:cx="19.367591"
+ inkscape:cy="39.183022"
+ inkscape:document-units="px"
+ inkscape:current-layer="layer1"
+ showgrid="false"
+ inkscape:showpageshadow="false"
+ showguides="true"
+ inkscape:guide-bbox="true"
+ inkscape:window-width="1920"
+ inkscape:window-height="1056"
+ inkscape:window-x="0"
+ inkscape:window-y="24"
+ inkscape:window-maximized="1">
+ <sodipodi:guide
+ orientation="0,1"
+ position="50,49.75"
+ id="guide3916" />
+ <sodipodi:guide
+ orientation="1,0"
+ position="50,43.125"
+ id="guide3918" />
+ </sodipodi:namedview>
+ <metadata
+ id="metadata7">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title></dc:title>
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="Ebene 1"
+ inkscape:groupmode="layer"
+ id="layer1"
+ transform="translate(0,-952.36218)">
+ <path
+ sodipodi:type="arc"
+ style="opacity:1;fill:#000000;fill-opacity:1;stroke:none"
+ id="path4364"
+ sodipodi:cx="50"
+ sodipodi:cy="50.25"
+ sodipodi:rx="44"
+ sodipodi:ry="44"
+ d="m 94,50.25 a 44,44 0 1 1 -88,0 44,44 0 1 1 88,0 z"
+ transform="translate(0,952.36218)" />
+ </g>
+</svg>
diff --git a/resources/themes/gloss/icon_fg.svg b/resources/themes/gloss/icon_fg.svg
new file mode 100644
index 0000000..53b57a0
--- /dev/null
+++ b/resources/themes/gloss/icon_fg.svg
@@ -0,0 +1,214 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="100"
+ height="100"
+ id="svg2"
+ version="1.1"
+ inkscape:version="0.48.1 r9760"
+ sodipodi:docname="icon_fg.svg">
+ <defs
+ id="defs4">
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient4240">
+ <stop
+ style="stop-color:#000000;stop-opacity:0"
+ offset="0"
+ id="stop4242" />
+ <stop
+ id="stop4250"
+ offset="0.78713447"
+ style="stop-color:#000000;stop-opacity:0" />
+ <stop
+ id="stop4248"
+ offset="0.8975364"
+ style="stop-color:#000000;stop-opacity:1" />
+ <stop
+ style="stop-color:#000000;stop-opacity:0"
+ offset="1"
+ id="stop4244" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient4228">
+ <stop
+ style="stop-color:#d4d4d4;stop-opacity:1"
+ offset="0"
+ id="stop4230" />
+ <stop
+ style="stop-color:#0b0b0b;stop-opacity:1"
+ offset="1"
+ id="stop4232" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient4216">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1"
+ offset="0"
+ id="stop4218" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0"
+ offset="1"
+ id="stop4220" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3767">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0"
+ offset="0"
+ id="stop3769" />
+ <stop
+ id="stop4739"
+ offset="0.39852998"
+ style="stop-color:#ffffff;stop-opacity:0;" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0.7605178"
+ offset="0.58575326"
+ id="stop4703" />
+ <stop
+ id="stop4713"
+ offset="0.66058904"
+ style="stop-color:#ffffff;stop-opacity:0.45490196;" />
+ <stop
+ id="stop4711"
+ offset="0.70194155"
+ style="stop-color:#ffffff;stop-opacity:0.34901961;" />
+ <stop
+ id="stop4709"
+ offset="0.74285865"
+ style="stop-color:#ffffff;stop-opacity:0.25490196;" />
+ <stop
+ id="stop4707"
+ offset="0.8251282"
+ style="stop-color:#ffffff;stop-opacity:0.1254902;" />
+ <stop
+ id="stop4705"
+ offset="0.90009141"
+ style="stop-color:#ffffff;stop-opacity:0.05490196;" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0"
+ offset="1"
+ id="stop3771" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4216"
+ id="linearGradient4222"
+ x1="50"
+ y1="7.0154586"
+ x2="50"
+ y2="56.874996"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.75590848,0,-12.45593)" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4228"
+ id="linearGradient4234"
+ x1="19.54899"
+ y1="18.430195"
+ x2="85.931084"
+ y2="85.605339"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.88419848,0,0,0.88419848,5.7900758,5.8190262)" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4240"
+ id="radialGradient4246"
+ cx="50.993256"
+ cy="51.135944"
+ fx="50.993256"
+ fy="51.135944"
+ r="39.143398"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.73416584,0.61180559,-0.62443446,0.74862707,45.385927,-18.201904)" />
+ </defs>
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#1d1d1d"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="4"
+ inkscape:cx="19.367591"
+ inkscape:cy="39.183022"
+ inkscape:document-units="px"
+ inkscape:current-layer="layer1"
+ showgrid="false"
+ inkscape:showpageshadow="false"
+ showguides="true"
+ inkscape:guide-bbox="true"
+ inkscape:window-width="1920"
+ inkscape:window-height="1056"
+ inkscape:window-x="0"
+ inkscape:window-y="24"
+ inkscape:window-maximized="1">
+ <sodipodi:guide
+ orientation="0,1"
+ position="50,49.75"
+ id="guide3916" />
+ <sodipodi:guide
+ orientation="1,0"
+ position="50,43.125"
+ id="guide3918" />
+ </sodipodi:namedview>
+ <metadata
+ id="metadata7">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title></dc:title>
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="Ebene 1"
+ inkscape:groupmode="layer"
+ id="layer1"
+ transform="translate(0,-952.36218)">
+ <path
+ transform="matrix(1.2934966,0,0,1.2940955,-14.567411,937.39052)"
+ d="m 89.143398,50.25 a 39.143398,39.143398 0 1 1 -78.286796,0 39.143398,39.143398 0 1 1 78.286796,0 z"
+ sodipodi:ry="39.143398"
+ sodipodi:rx="39.143398"
+ sodipodi:cy="50.25"
+ sodipodi:cx="50"
+ id="path4236"
+ style="fill:url(#radialGradient4246);fill-opacity:1;stroke:none"
+ sodipodi:type="arc" />
+ <path
+ sodipodi:type="arc"
+ style="fill:url(#linearGradient4222);fill-opacity:1;stroke:none;opacity:0.55339806"
+ id="path4214"
+ sodipodi:cx="50"
+ sodipodi:cy="7.8993421"
+ sodipodi:rx="25.809397"
+ sodipodi:ry="12.904698"
+ d="m 75.809397,7.8993421 a 25.809397,12.904698 0 1 1 -51.618794,0 25.809397,12.904698 0 1 1 51.618794,0 z"
+ transform="matrix(1,0,0,1.3229115,0,968.84027)" />
+ <path
+ sodipodi:type="arc"
+ style="fill:none;stroke:url(#linearGradient4234);stroke-width:5.30519104;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path4226"
+ sodipodi:cx="50"
+ sodipodi:cy="50.25"
+ sodipodi:rx="39.143398"
+ sodipodi:ry="39.143398"
+ d="m 89.143398,50.25 a 39.143398,39.143398 0 1 1 -78.286796,0 39.143398,39.143398 0 1 1 78.286796,0 z"
+ transform="matrix(1.1309678,0,0,1.1309678,-6.5483892,945.78105)" />
+ </g>
+</svg>
diff --git a/resources/themes/gloss/icon_fg_active.svg b/resources/themes/gloss/icon_fg_active.svg
new file mode 100644
index 0000000..9483a68
--- /dev/null
+++ b/resources/themes/gloss/icon_fg_active.svg
@@ -0,0 +1,214 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="100"
+ height="100"
+ id="svg2"
+ version="1.1"
+ inkscape:version="0.48.1 r9760"
+ sodipodi:docname="icon_fg_active.svg">
+ <defs
+ id="defs4">
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient4240">
+ <stop
+ style="stop-color:#000000;stop-opacity:0"
+ offset="0"
+ id="stop4242" />
+ <stop
+ id="stop4250"
+ offset="0.78713447"
+ style="stop-color:#000000;stop-opacity:0" />
+ <stop
+ id="stop4248"
+ offset="0.8975364"
+ style="stop-color:#000000;stop-opacity:1" />
+ <stop
+ style="stop-color:#000000;stop-opacity:0"
+ offset="1"
+ id="stop4244" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient4228">
+ <stop
+ style="stop-color:#f9f9f9;stop-opacity:1"
+ offset="0"
+ id="stop4230" />
+ <stop
+ style="stop-color:#8e8e8e;stop-opacity:1"
+ offset="1"
+ id="stop4232" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient4216">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1"
+ offset="0"
+ id="stop4218" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0"
+ offset="1"
+ id="stop4220" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3767">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0"
+ offset="0"
+ id="stop3769" />
+ <stop
+ id="stop4739"
+ offset="0.39852998"
+ style="stop-color:#ffffff;stop-opacity:0;" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0.7605178"
+ offset="0.58575326"
+ id="stop4703" />
+ <stop
+ id="stop4713"
+ offset="0.66058904"
+ style="stop-color:#ffffff;stop-opacity:0.45490196;" />
+ <stop
+ id="stop4711"
+ offset="0.70194155"
+ style="stop-color:#ffffff;stop-opacity:0.34901961;" />
+ <stop
+ id="stop4709"
+ offset="0.74285865"
+ style="stop-color:#ffffff;stop-opacity:0.25490196;" />
+ <stop
+ id="stop4707"
+ offset="0.8251282"
+ style="stop-color:#ffffff;stop-opacity:0.1254902;" />
+ <stop
+ id="stop4705"
+ offset="0.90009141"
+ style="stop-color:#ffffff;stop-opacity:0.05490196;" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0"
+ offset="1"
+ id="stop3771" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4216"
+ id="linearGradient4222"
+ x1="50"
+ y1="7.0154586"
+ x2="50"
+ y2="56.874996"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.75590848,0,-12.45593)" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4228"
+ id="linearGradient4234"
+ x1="19.54899"
+ y1="18.430195"
+ x2="85.931084"
+ y2="85.605339"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.88419848,0,0,0.88419848,5.7900758,5.8190262)" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4240"
+ id="radialGradient4246"
+ cx="50.993256"
+ cy="51.135944"
+ fx="50.993256"
+ fy="51.135944"
+ r="39.143398"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.73416584,0.61180559,-0.62443446,0.74862707,45.385927,-18.201904)" />
+ </defs>
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#1d1d1d"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="4"
+ inkscape:cx="-29.007409"
+ inkscape:cy="39.183022"
+ inkscape:document-units="px"
+ inkscape:current-layer="layer1"
+ showgrid="false"
+ inkscape:showpageshadow="false"
+ showguides="true"
+ inkscape:guide-bbox="true"
+ inkscape:window-width="1920"
+ inkscape:window-height="1056"
+ inkscape:window-x="0"
+ inkscape:window-y="24"
+ inkscape:window-maximized="1">
+ <sodipodi:guide
+ orientation="0,1"
+ position="50,49.75"
+ id="guide3916" />
+ <sodipodi:guide
+ orientation="1,0"
+ position="50,43.125"
+ id="guide3918" />
+ </sodipodi:namedview>
+ <metadata
+ id="metadata7">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title />
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="Ebene 1"
+ inkscape:groupmode="layer"
+ id="layer1"
+ transform="translate(0,-952.36218)">
+ <path
+ transform="matrix(1.2934966,0,0,1.2940955,-14.567411,937.39052)"
+ d="M 89.143398,50.25 C 89.143398,71.868302 71.618302,89.393398 50,89.393398 28.381698,89.393398 10.856602,71.868302 10.856602,50.25 10.856602,28.631698 28.381698,11.106602 50,11.106602 c 21.618302,0 39.143398,17.525096 39.143398,39.143398 z"
+ sodipodi:ry="39.143398"
+ sodipodi:rx="39.143398"
+ sodipodi:cy="50.25"
+ sodipodi:cx="50"
+ id="path4236"
+ style="fill:url(#radialGradient4246);fill-opacity:1;stroke:none"
+ sodipodi:type="arc" />
+ <path
+ sodipodi:type="arc"
+ style="fill:url(#linearGradient4222);fill-opacity:1;stroke:none;opacity:0.55339806"
+ id="path4214"
+ sodipodi:cx="50"
+ sodipodi:cy="7.8993421"
+ sodipodi:rx="25.809397"
+ sodipodi:ry="12.904698"
+ d="M 75.809397,7.8993421 C 75.809397,15.02641 64.254136,20.80404 50,20.80404 c -14.254136,0 -25.809397,-5.77763 -25.809397,-12.9046979 0,-7.12706815 11.555261,-12.9046984 25.809397,-12.9046984 14.254136,0 25.809397,5.77763025 25.809397,12.9046984 z"
+ transform="matrix(1,0,0,1.3229115,0,968.84027)" />
+ <path
+ sodipodi:type="arc"
+ style="fill:none;stroke:url(#linearGradient4234);stroke-width:5.30519104;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path4226"
+ sodipodi:cx="50"
+ sodipodi:cy="50.25"
+ sodipodi:rx="39.143398"
+ sodipodi:ry="39.143398"
+ d="M 89.143398,50.25 C 89.143398,71.868302 71.618302,89.393398 50,89.393398 28.381698,89.393398 10.856602,71.868302 10.856602,50.25 10.856602,28.631698 28.381698,11.106602 50,11.106602 c 21.618302,0 39.143398,17.525096 39.143398,39.143398 z"
+ transform="matrix(1.1309678,0,0,1.1309678,-6.5483892,945.78105)" />
+ </g>
+</svg>
diff --git a/resources/themes/gloss/icon_mask.svg b/resources/themes/gloss/icon_mask.svg
new file mode 100644
index 0000000..cbbda42
--- /dev/null
+++ b/resources/themes/gloss/icon_mask.svg
@@ -0,0 +1,118 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="100"
+ height="100"
+ id="svg2"
+ version="1.1"
+ inkscape:version="0.48.1 r9760"
+ sodipodi:docname="icon_mask.svg">
+ <defs
+ id="defs4">
+ <linearGradient
+ id="linearGradient3767">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0"
+ offset="0"
+ id="stop3769" />
+ <stop
+ id="stop4739"
+ offset="0.39852998"
+ style="stop-color:#ffffff;stop-opacity:0;" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0.7605178"
+ offset="0.58575326"
+ id="stop4703" />
+ <stop
+ id="stop4713"
+ offset="0.66058904"
+ style="stop-color:#ffffff;stop-opacity:0.45490196;" />
+ <stop
+ id="stop4711"
+ offset="0.70194155"
+ style="stop-color:#ffffff;stop-opacity:0.34901961;" />
+ <stop
+ id="stop4709"
+ offset="0.74285865"
+ style="stop-color:#ffffff;stop-opacity:0.25490196;" />
+ <stop
+ id="stop4707"
+ offset="0.8251282"
+ style="stop-color:#ffffff;stop-opacity:0.1254902;" />
+ <stop
+ id="stop4705"
+ offset="0.90009141"
+ style="stop-color:#ffffff;stop-opacity:0.05490196;" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0"
+ offset="1"
+ id="stop3771" />
+ </linearGradient>
+ </defs>
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="4"
+ inkscape:cx="19.367591"
+ inkscape:cy="39.183022"
+ inkscape:document-units="px"
+ inkscape:current-layer="layer1"
+ showgrid="false"
+ inkscape:showpageshadow="false"
+ showguides="true"
+ inkscape:guide-bbox="true"
+ inkscape:window-width="1920"
+ inkscape:window-height="1056"
+ inkscape:window-x="0"
+ inkscape:window-y="24"
+ inkscape:window-maximized="1">
+ <sodipodi:guide
+ orientation="0,1"
+ position="50,49.75"
+ id="guide3916" />
+ <sodipodi:guide
+ orientation="1,0"
+ position="50,43.125"
+ id="guide3918" />
+ </sodipodi:namedview>
+ <metadata
+ id="metadata7">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title></dc:title>
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="Ebene 1"
+ inkscape:groupmode="layer"
+ id="layer1"
+ transform="translate(0,-952.36218)">
+ <path
+ sodipodi:type="arc"
+ style="opacity:1;fill:#000000;fill-opacity:1;stroke:none"
+ id="path4364"
+ sodipodi:cx="50"
+ sodipodi:cy="50.25"
+ sodipodi:rx="44"
+ sodipodi:ry="44"
+ d="m 94,50.25 a 44,44 0 1 1 -88,0 44,44 0 1 1 88,0 z"
+ transform="translate(0,952.36218)" />
+ </g>
+</svg>
diff --git a/resources/themes/gloss/theme.xml b/resources/themes/gloss/theme.xml
new file mode 100644
index 0000000..efc20e0
--- /dev/null
+++ b/resources/themes/gloss/theme.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<theme name="Glossy" description="A shiny theme for Gnome-Pie" author="Simon Schneegans" email="josi.schneegans@vr-web.de">
+ <pie radius="100" maxZoom="1.3" zoomRange="0.2" transitionTime="0.1" fadeInTime="0.2" fadeOutTime="0.2" fadeInZoom="0.7" fadeOutZoom="0.7">
+ <center radius="65" activeRadius="40">
+ <center_layer file="icon_bg.svg"
+ active_scale="1" active_rotationMode="auto" active_rotationSpeed="0" active_colorize="false" active_alpha="1.0"
+ inactive_scale="0.6" inactive_rotationMode="auto" inactive_rotationSpeed="0" inactive_colorize="false" inactive_alpha="1.0" />
+ <center_layer file="glow_bg.svg"
+ active_scale="1" active_rotationMode="auto" active_rotationSpeed="0" active_colorize="true" active_alpha="0.8"
+ inactive_scale="0.6" inactive_rotationMode="auto" inactive_rotationSpeed="0" inactive_colorize="false" inactive_alpha="0.3" />
+ <center_layer file="icon_fg.svg"
+ active_scale="1" active_rotationMode="auto" active_rotationSpeed="0" active_colorize="false" active_alpha="1.0"
+ inactive_scale="0.6" inactive_rotationMode="auto" inactive_rotationSpeed="0" inactive_colorize="false" inactive_alpha="1.0" />
+ <center_layer file="arrow.svg"
+ active_scale="1" active_rotationMode="turn_to_mouse" active_rotationSpeed="10.0" active_colorize="false" active_alpha="1.0"
+ inactive_scale="0.6" inactive_rotationMode="auto" inactive_rotationSpeed="0.0" inactive_colorize="false" inactive_alpha="0.0" />
+ </center>
+ <slices radius="26" minGap="0">
+ <activeSlice>
+ <slice_layer type="file" file="icon_bg.svg" scale="1" colorize="false" />
+ <slice_layer type="icon" file="icon_mask.svg" scale="0.9" colorize="false" />
+ <slice_layer type="file" file="icon_fg_active.svg" scale="1" colorize="false" />
+ </activeSlice>
+ <inactiveSlice>
+ <slice_layer type="file" file="icon_bg.svg" scale="1" colorize="false" />
+ <slice_layer type="icon" file="icon_mask.svg" scale="0.9" colorize="false" />
+ <slice_layer type="file" file="icon_fg.svg" scale="1" colorize="false" />
+ </inactiveSlice>
+ </slices>
+ <caption position="0" font="sans 10" width="100" height="100" />
+ </pie>
+</theme>
+
diff --git a/resources/themes/o-pie/arrow.svg b/resources/themes/o-pie/arrow.svg
new file mode 100644
index 0000000..94b457c
--- /dev/null
+++ b/resources/themes/o-pie/arrow.svg
@@ -0,0 +1,115 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="100"
+ height="100"
+ id="svg2"
+ version="1.1"
+ inkscape:version="0.48.1 r9760"
+ sodipodi:docname="ring.svg">
+ <defs
+ id="defs4">
+ <linearGradient
+ id="linearGradient3007">
+ <stop
+ id="stop3009"
+ offset="0"
+ style="stop-color:#ffffff;stop-opacity:0" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="0.3680203"
+ id="stop3011" />
+ <stop
+ id="stop3013"
+ offset="0.57677984"
+ style="stop-color:#ffffff;stop-opacity:0.66666667;" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0.45490196;"
+ offset="0.66058904"
+ id="stop3015" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0.34901961;"
+ offset="0.70194155"
+ id="stop3017" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0.25490196;"
+ offset="0.74285865"
+ id="stop3019" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0.1254902;"
+ offset="0.8251282"
+ id="stop3021" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0.05490196;"
+ offset="0.90009141"
+ id="stop3023" />
+ <stop
+ id="stop3025"
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:0" />
+ </linearGradient>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3007"
+ id="radialGradient3005"
+ gradientUnits="userSpaceOnUse"
+ cx="50.002552"
+ cy="49.744911"
+ fx="50.002552"
+ fy="49.744911"
+ r="49.750011" />
+ </defs>
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#1d1d1d"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="5.6"
+ inkscape:cx="61.209662"
+ inkscape:cy="38.347822"
+ inkscape:document-units="px"
+ inkscape:current-layer="layer1"
+ showgrid="false"
+ inkscape:showpageshadow="false"
+ showguides="true"
+ inkscape:guide-bbox="true"
+ inkscape:window-width="1174"
+ inkscape:window-height="737"
+ inkscape:window-x="531"
+ inkscape:window-y="163"
+ inkscape:window-maximized="0" />
+ <metadata
+ id="metadata7">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title></dc:title>
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="Ebene 1"
+ inkscape:groupmode="layer"
+ id="layer1"
+ transform="translate(0,-952.36218)">
+ <path
+ style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;color:#000000;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:3;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Sans;-inkscape-font-specification:Sans"
+ d="m 82.464286,989.51841 -1,0.6875 0,3.125 6.21875,9.03129 -6.21875,8.9062 0,3.125 0.96875,0.6875 8.3125,-11.875 0.59375,-0.8437 -0.59375,-0.875 -8.28125,-11.96879 z"
+ id="path3054"
+ inkscape:connector-curvature="0" />
+ </g>
+</svg>
diff --git a/resources/themes/o-pie/ring.svg b/resources/themes/o-pie/ring.svg
new file mode 100644
index 0000000..6a6975f
--- /dev/null
+++ b/resources/themes/o-pie/ring.svg
@@ -0,0 +1,179 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="100"
+ height="100"
+ id="svg2"
+ version="1.1"
+ inkscape:version="0.48.1 r9760"
+ sodipodi:docname="ring.svg">
+ <defs
+ id="defs4">
+ <linearGradient
+ id="linearGradient3007">
+ <stop
+ id="stop3009"
+ offset="0"
+ style="stop-color:#b4b4b4;stop-opacity:0;" />
+ <stop
+ style="stop-color:#b4b4b4;stop-opacity:0;"
+ offset="0.3680203"
+ id="stop3011" />
+ <stop
+ id="stop3013"
+ offset="0.57677984"
+ style="stop-color:#b4b4b4;stop-opacity:0.66666669;" />
+ <stop
+ style="stop-color:#b4b4b4;stop-opacity:0.45490196;"
+ offset="0.66058904"
+ id="stop3015" />
+ <stop
+ style="stop-color:#b4b4b4;stop-opacity:0.34901962;"
+ offset="0.70194155"
+ id="stop3017" />
+ <stop
+ style="stop-color:#b4b4b4;stop-opacity:0.25490195;"
+ offset="0.74285865"
+ id="stop3019" />
+ <stop
+ style="stop-color:#b4b4b4;stop-opacity:0.1254902;"
+ offset="0.8251282"
+ id="stop3021" />
+ <stop
+ style="stop-color:#b4b4b4;stop-opacity:0.05490196;"
+ offset="0.90009141"
+ id="stop3023" />
+ <stop
+ id="stop3025"
+ offset="1"
+ style="stop-color:#b4b4b4;stop-opacity:0;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3767">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0"
+ offset="0"
+ id="stop3769" />
+ <stop
+ id="stop4739"
+ offset="0.3680203"
+ style="stop-color:#ffffff;stop-opacity:0;" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0.66666667;"
+ offset="0.59831607"
+ id="stop4703" />
+ <stop
+ id="stop4713"
+ offset="0.66058904"
+ style="stop-color:#ffffff;stop-opacity:0.45490196;" />
+ <stop
+ id="stop4711"
+ offset="0.70194155"
+ style="stop-color:#ffffff;stop-opacity:0.34901961;" />
+ <stop
+ id="stop4709"
+ offset="0.74285865"
+ style="stop-color:#ffffff;stop-opacity:0.25490196;" />
+ <stop
+ id="stop4707"
+ offset="0.8251282"
+ style="stop-color:#ffffff;stop-opacity:0.1254902;" />
+ <stop
+ id="stop4705"
+ offset="0.90009141"
+ style="stop-color:#ffffff;stop-opacity:0.05490196;" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0"
+ offset="1"
+ id="stop3771" />
+ </linearGradient>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3767"
+ id="radialGradient3775"
+ cx="50.002552"
+ cy="49.744911"
+ fx="50.002552"
+ fy="49.744911"
+ r="49.750011"
+ gradientUnits="userSpaceOnUse" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3007"
+ id="radialGradient3005"
+ gradientUnits="userSpaceOnUse"
+ cx="50.002552"
+ cy="49.744911"
+ fx="50.002552"
+ fy="49.744911"
+ r="49.750011"
+ gradientTransform="translate(0,952.36218)" />
+ </defs>
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#1d1d1d"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="4"
+ inkscape:cx="58.115744"
+ inkscape:cy="74.271276"
+ inkscape:document-units="px"
+ inkscape:current-layer="layer1"
+ showgrid="false"
+ inkscape:showpageshadow="false"
+ showguides="true"
+ inkscape:guide-bbox="true"
+ inkscape:window-width="1920"
+ inkscape:window-height="1056"
+ inkscape:window-x="0"
+ inkscape:window-y="24"
+ inkscape:window-maximized="1">
+ <sodipodi:guide
+ orientation="0,1"
+ position="14.9375,50"
+ id="guide3006" />
+ <sodipodi:guide
+ orientation="1,0"
+ position="50,78.171875"
+ id="guide3008" />
+ </sodipodi:namedview>
+ <metadata
+ id="metadata7">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title />
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="Ebene 1"
+ inkscape:groupmode="layer"
+ id="layer1"
+ transform="translate(0,-952.36218)">
+ <path
+ style="fill:url(#radialGradient3005);fill-opacity:1;stroke:none"
+ d="M 45.728643,952.3622 C 20.113026,954.53668 0,976.08716 0,1002.3622 c 0,26.275 20.113026,47.8255 45.728643,50 l 4.271357,-50 -4.271357,-50 z m 4.271357,50 4.271357,50 c 25.615617,-2.1745 45.728643,-23.725 45.728643,-50 0,-26.27504 -20.113026,-47.82552 -45.728643,-50 l -4.271357,50 z"
+ id="path3765"
+ inkscape:connector-curvature="0" />
+ <path
+ style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;color:#000000;fill:#a7a7a7;fill-opacity:1;stroke:none;stroke-width:6;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Sans;-inkscape-font-specification:Sans"
+ d="M 47.536559,973.36218 C 32.694324,974.6225 21,987.13624 21,1002.3622 c 0,15.2259 11.694324,27.7397 26.536559,29 l 0.374194,-4.6976 c -12.455306,-1.0591 -22.202151,-11.5135 -22.202151,-24.3024 0,-12.7889 9.746845,-23.24337 22.202151,-24.3024 l -0.374194,-4.69762 z m 4.926882,0 -0.374194,4.69762 c 12.455305,1.05903 22.202151,11.5135 22.202151,24.3024 0,12.7889 -9.746846,23.2433 -22.202151,24.3024 l 0.374194,4.6976 C 67.305675,1030.1019 79,1017.5881 79,1002.3622 79,987.13624 67.305675,974.6225 52.463441,973.36218 z"
+ id="path19"
+ inkscape:connector-curvature="0" />
+ </g>
+</svg>
diff --git a/resources/themes/o-pie/theme.xml b/resources/themes/o-pie/theme.xml
new file mode 100644
index 0000000..19d4101
--- /dev/null
+++ b/resources/themes/o-pie/theme.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<theme name="O-Pie" description="Inspired by the original O-Pie theme" author="Simon Schneegans" email="josi.schneegans@vr-web.de">
+ <pie radius="120" maxZoom="1.3" zoomRange="0.2" transitionTime="0.1" springiness="1.5"
+ fadeInTime="0.2" fadeOutTime="0.2" fadeInZoom="0.7" fadeOutZoom="0.8" fadeInRotation="0.2" fadeOutRotation="-0.2">
+ <center radius="70" activeRadius="35">
+ <center_layer file="ring.svg"
+ active_scale="1.0" active_rotationMode="auto" active_rotationSpeed="4" active_colorize="true" active_alpha="1.0"
+ inactive_scale="0.8" inactive_rotationMode="auto" inactive_rotationSpeed="-0.5" inactive_colorize="false" inactive_alpha="1.0" />
+ <center_layer file="arrow.svg"
+ active_scale="1.0" active_rotationMode="turn_to_mouse" active_rotationSpeed="15.0" active_colorize="true" active_alpha="1.0"
+ inactive_scale="0.8" inactive_rotationMode="turn_to_mouse" inactive_rotationSpeed="5.0" inactive_colorize="false" inactive_alpha="0.0" />
+ </center>
+ <slices radius="24">
+ <activeSlice>
+ <slice_layer type="icon" />
+ </activeSlice>
+ <inactiveSlice>
+ <slice_layer type="icon" />
+ </inactiveSlice>
+ </slices>
+ </pie>
+</theme>
+
diff --git a/resources/themes/slim/bg.svg b/resources/themes/slim/bg.svg
new file mode 100644
index 0000000..3496355
--- /dev/null
+++ b/resources/themes/slim/bg.svg
@@ -0,0 +1,198 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="100"
+ height="100"
+ id="svg2"
+ version="1.1"
+ inkscape:version="0.48.1 r9760"
+ sodipodi:docname="bg.svg">
+ <defs
+ id="defs4">
+ <linearGradient
+ id="linearGradient3011"
+ inkscape:collect="always">
+ <stop
+ id="stop3013"
+ offset="0"
+ style="stop-color:#000000;stop-opacity:0.53074434" />
+ <stop
+ style="stop-color:#000000;stop-opacity:0.51764706;"
+ offset="0.14756918"
+ id="stop3035" />
+ <stop
+ style="stop-color:#000000;stop-opacity:0.45882353;"
+ offset="0.28023249"
+ id="stop3033" />
+ <stop
+ style="stop-color:#000000;stop-opacity:0.39607843;"
+ offset="0.37345532"
+ id="stop3031" />
+ <stop
+ style="stop-color:#000000;stop-opacity:0.35686275;"
+ offset="0.43799418"
+ id="stop3029" />
+ <stop
+ style="stop-color:#000000;stop-opacity:0.30196078;"
+ offset="0.50253308"
+ id="stop3027" />
+ <stop
+ style="stop-color:#000000;stop-opacity:0.23529412;"
+ offset="0.57782847"
+ id="stop3025" />
+ <stop
+ style="stop-color:#000000;stop-opacity:0.19215686;"
+ offset="0.6244399"
+ id="stop3023" />
+ <stop
+ style="stop-color:#000000;stop-opacity:0.14901961;"
+ offset="0.6782223"
+ id="stop3021" />
+ <stop
+ style="stop-color:#000000;stop-opacity:0.10196078;"
+ offset="0.75351769"
+ id="stop3019" />
+ <stop
+ style="stop-color:#000000;stop-opacity:0.06666667;"
+ offset="0.84674048"
+ id="stop3015" />
+ <stop
+ id="stop3017"
+ offset="1"
+ style="stop-color:#000000;stop-opacity:0;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient4010">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop4012" />
+ <stop
+ id="stop3007"
+ offset="0.93279237"
+ style="stop-color:#000000;stop-opacity:0.06666667;" />
+ <stop
+ style="stop-color:#000000;stop-opacity:0;"
+ offset="1"
+ id="stop4014" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3767">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0"
+ offset="0"
+ id="stop3769" />
+ <stop
+ id="stop4739"
+ offset="0.39852998"
+ style="stop-color:#ffffff;stop-opacity:0;" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0.7605178"
+ offset="0.58575326"
+ id="stop4703" />
+ <stop
+ id="stop4713"
+ offset="0.66058904"
+ style="stop-color:#ffffff;stop-opacity:0.45490196;" />
+ <stop
+ id="stop4711"
+ offset="0.70194155"
+ style="stop-color:#ffffff;stop-opacity:0.34901961;" />
+ <stop
+ id="stop4709"
+ offset="0.74285865"
+ style="stop-color:#ffffff;stop-opacity:0.25490196;" />
+ <stop
+ id="stop4707"
+ offset="0.8251282"
+ style="stop-color:#ffffff;stop-opacity:0.1254902;" />
+ <stop
+ id="stop4705"
+ offset="0.90009141"
+ style="stop-color:#ffffff;stop-opacity:0.05490196;" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0"
+ offset="1"
+ id="stop3771" />
+ </linearGradient>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4010"
+ id="radialGradient4016"
+ cx="50"
+ cy="50.25"
+ fx="50"
+ fy="50.25"
+ r="44"
+ gradientUnits="userSpaceOnUse" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3011"
+ id="radialGradient3009"
+ gradientUnits="userSpaceOnUse"
+ cx="50"
+ cy="50.25"
+ fx="50"
+ fy="50.25"
+ r="44" />
+ </defs>
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="5.6568542"
+ inkscape:cx="16.453353"
+ inkscape:cy="34.273681"
+ inkscape:document-units="px"
+ inkscape:current-layer="layer1"
+ showgrid="false"
+ inkscape:showpageshadow="false"
+ showguides="true"
+ inkscape:guide-bbox="true"
+ inkscape:window-width="1920"
+ inkscape:window-height="1056"
+ inkscape:window-x="0"
+ inkscape:window-y="24"
+ inkscape:window-maximized="1" />
+ <metadata
+ id="metadata7">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title />
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="Ebene 1"
+ inkscape:groupmode="layer"
+ id="layer1"
+ transform="translate(0,-952.36218)">
+ <path
+ sodipodi:type="arc"
+ style="opacity:0.33980583;fill:url(#radialGradient3009);fill-opacity:1;stroke:none"
+ id="path4364"
+ sodipodi:cx="50"
+ sodipodi:cy="50.25"
+ sodipodi:rx="44"
+ sodipodi:ry="44"
+ d="m 94,50.25 a 44,44 0 1 1 -88,0 44,44 0 1 1 88,0 z"
+ transform="matrix(1.1205296,0,0,1.1205296,-6.0264783,946.30557)" />
+ </g>
+</svg>
diff --git a/resources/themes/slim/dot.svg b/resources/themes/slim/dot.svg
new file mode 100644
index 0000000..b5945c6
--- /dev/null
+++ b/resources/themes/slim/dot.svg
@@ -0,0 +1,125 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="100"
+ height="100"
+ id="svg2"
+ version="1.1"
+ inkscape:version="0.48.1 r9760"
+ sodipodi:docname="arrow.svg">
+ <defs
+ id="defs4">
+ <linearGradient
+ id="linearGradient3007">
+ <stop
+ id="stop3009"
+ offset="0"
+ style="stop-color:#ffffff;stop-opacity:0" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="0.3680203"
+ id="stop3011" />
+ <stop
+ id="stop3013"
+ offset="0.57677984"
+ style="stop-color:#ffffff;stop-opacity:0.66666667;" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0.45490196;"
+ offset="0.66058904"
+ id="stop3015" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0.34901961;"
+ offset="0.70194155"
+ id="stop3017" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0.25490196;"
+ offset="0.74285865"
+ id="stop3019" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0.1254902;"
+ offset="0.8251282"
+ id="stop3021" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0.05490196;"
+ offset="0.90009141"
+ id="stop3023" />
+ <stop
+ id="stop3025"
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:0" />
+ </linearGradient>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3007"
+ id="radialGradient3005"
+ gradientUnits="userSpaceOnUse"
+ cx="50.002552"
+ cy="49.744911"
+ fx="50.002552"
+ fy="49.744911"
+ r="49.750011" />
+ </defs>
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#1d1d1d"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0.74901961"
+ inkscape:pageshadow="2"
+ inkscape:zoom="3.959798"
+ inkscape:cx="45.4458"
+ inkscape:cy="51.896193"
+ inkscape:document-units="px"
+ inkscape:current-layer="layer1"
+ showgrid="false"
+ inkscape:showpageshadow="false"
+ showguides="true"
+ inkscape:guide-bbox="true"
+ inkscape:window-width="1174"
+ inkscape:window-height="737"
+ inkscape:window-x="538"
+ inkscape:window-y="163"
+ inkscape:window-maximized="0">
+ <sodipodi:guide
+ orientation="0,1"
+ position="68.214286,50"
+ id="guide2994" />
+ </sodipodi:namedview>
+ <metadata
+ id="metadata7">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title />
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="Ebene 1"
+ inkscape:groupmode="layer"
+ id="layer1"
+ transform="translate(0,-952.36218)">
+ <path
+ sodipodi:type="arc"
+ style="fill:#ffffff;fill-opacity:1;stroke:none"
+ id="path2996"
+ sodipodi:cx="81.428574"
+ sodipodi:cy="50"
+ sodipodi:rx="4.4642859"
+ sodipodi:ry="4.4642859"
+ d="m 85.892859,50 a 4.4642859,4.4642859 0 1 1 -8.928571,0 4.4642859,4.4642859 0 1 1 8.928571,0 z"
+ transform="translate(12.014119,952.36218)" />
+ </g>
+</svg>
diff --git a/resources/themes/slim/theme.xml b/resources/themes/slim/theme.xml
new file mode 100644
index 0000000..91b5a96
--- /dev/null
+++ b/resources/themes/slim/theme.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<theme name="Slim" description="Well... quite simplistic" author="Simon Schneegans" email="josi.schneegans@vr-web.de">
+ <pie radius="120" maxZoom="1.3" zoomRange="0.2" transitionTime="0.2" springiness="1.5"
+ fadeInTime="0.3" fadeOutTime="0.3" fadeInZoom="0.8" fadeOutZoom="0.8" fadeInRotation="0.3" fadeOutRotation="-0.3">
+ <center radius="120" activeRadius="35">
+ <center_layer file="bg.svg"
+ active_scale="1.0" active_rotationMode="auto" active_rotationSpeed="0" active_colorize="false" active_alpha="1"
+ inactive_scale="1.0" inactive_rotationMode="auto" inactive_rotationSpeed="0" inactive_colorize="false" inactive_alpha="1" />
+ <center_layer file="dot.svg"
+ active_scale="0.22" active_rotationMode="turn_to_mouse" active_rotationSpeed="5.5" active_colorize="false" active_alpha="0.8"
+ inactive_scale="0.22" inactive_rotationMode="auto" inactive_rotationSpeed="0.55" inactive_colorize="false" inactive_alpha="0.8" />
+ <center_layer file="dot.svg"
+ active_scale="0.3" active_rotationMode="turn_to_mouse" active_rotationSpeed="4.0" active_colorize="false" active_alpha="0.8"
+ inactive_scale="0.25" inactive_rotationMode="auto" inactive_rotationSpeed="-0.35" inactive_colorize="false" inactive_alpha="0.8" />
+ <center_layer file="dot.svg"
+ active_scale="0.4" active_rotationMode="turn_to_mouse" active_rotationSpeed="4.0" active_colorize="false" active_alpha="0.85"
+ inactive_scale="0.35" inactive_rotationMode="auto" inactive_rotationSpeed="0.5" inactive_colorize="false" inactive_alpha="0.85" />
+ <center_layer file="dot.svg"
+ active_scale="0.5" active_rotationMode="turn_to_mouse" active_rotationSpeed="5" active_colorize="false" active_alpha="0.9"
+ inactive_scale="0.4" inactive_rotationMode="auto" inactive_rotationSpeed="-0.7" inactive_colorize="false" inactive_alpha="0.9" />
+ <center_layer file="dot.svg"
+ active_scale="0.7" active_rotationMode="turn_to_mouse" active_rotationSpeed="9.0" active_colorize="true" active_alpha="1.0"
+ inactive_scale="0.5" inactive_rotationMode="auto" inactive_rotationSpeed="1.0" inactive_colorize="false" inactive_alpha="1.0" />
+ </center>
+ <slices radius="24">
+ <activeSlice>
+ <slice_layer type="icon" />
+ </activeSlice>
+ <inactiveSlice>
+ <slice_layer type="icon" />
+ </inactiveSlice>
+ </slices>
+ </pie>
+</theme>
+
diff --git a/resources/themes/unity/arrow.svg b/resources/themes/unity/arrow.svg
new file mode 100644
index 0000000..4b81a6d
--- /dev/null
+++ b/resources/themes/unity/arrow.svg
@@ -0,0 +1,121 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="100"
+ height="100"
+ id="svg2"
+ version="1.1"
+ inkscape:version="0.48.1 r9760"
+ sodipodi:docname="arrow.svg">
+ <defs
+ id="defs4">
+ <linearGradient
+ id="linearGradient3007">
+ <stop
+ id="stop3009"
+ offset="0"
+ style="stop-color:#ffffff;stop-opacity:0" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="0.3680203"
+ id="stop3011" />
+ <stop
+ id="stop3013"
+ offset="0.57677984"
+ style="stop-color:#ffffff;stop-opacity:0.66666667;" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0.45490196;"
+ offset="0.66058904"
+ id="stop3015" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0.34901961;"
+ offset="0.70194155"
+ id="stop3017" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0.25490196;"
+ offset="0.74285865"
+ id="stop3019" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0.1254902;"
+ offset="0.8251282"
+ id="stop3021" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0.05490196;"
+ offset="0.90009141"
+ id="stop3023" />
+ <stop
+ id="stop3025"
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:0" />
+ </linearGradient>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3007"
+ id="radialGradient3005"
+ gradientUnits="userSpaceOnUse"
+ cx="50.002552"
+ cy="49.744911"
+ fx="50.002552"
+ fy="49.744911"
+ r="49.750011" />
+ </defs>
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#1d1d1d"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="1"
+ inkscape:pageshadow="2"
+ inkscape:zoom="11.2"
+ inkscape:cx="77.449971"
+ inkscape:cy="47.388963"
+ inkscape:document-units="px"
+ inkscape:current-layer="layer1"
+ showgrid="false"
+ inkscape:showpageshadow="false"
+ showguides="true"
+ inkscape:guide-bbox="true"
+ inkscape:window-width="1174"
+ inkscape:window-height="737"
+ inkscape:window-x="552"
+ inkscape:window-y="163"
+ inkscape:window-maximized="0">
+ <sodipodi:guide
+ orientation="0,1"
+ position="111.25,50"
+ id="guide2994" />
+ </sodipodi:namedview>
+ <metadata
+ id="metadata7">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title />
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="Ebene 1"
+ inkscape:groupmode="layer"
+ id="layer1"
+ transform="translate(0,-952.36218)">
+ <path
+ style="fill:#ffffff;fill-opacity:1;stroke:none"
+ d="m 81.857481,996.8239 5.535712,5.5357 -5.535712,5.5357 c 0.621411,-3.8458 0.51189,-7.5089 0,-11.0714 z"
+ id="rect2998"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cccc" />
+ </g>
+</svg>
diff --git a/resources/themes/unity/gloss.svg b/resources/themes/unity/gloss.svg
new file mode 100644
index 0000000..60a795f
--- /dev/null
+++ b/resources/themes/unity/gloss.svg
@@ -0,0 +1,156 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="100"
+ height="100"
+ id="svg2"
+ version="1.1"
+ inkscape:version="0.48.1 r9760"
+ sodipodi:docname="gloss.svg">
+ <defs
+ id="defs4">
+ <linearGradient
+ id="linearGradient3786"
+ inkscape:collect="always">
+ <stop
+ id="stop3788"
+ offset="0"
+ style="stop-color:#ffffff;stop-opacity:0.59649123" />
+ <stop
+ id="stop3790"
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:0" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient3772">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0.64912281"
+ offset="0"
+ id="stop3774" />
+ <stop
+ id="stop3804"
+ offset="0.33709621"
+ style="stop-color:#ffffff;stop-opacity:0.30980392;" />
+ <stop
+ id="stop3802"
+ offset="0.41556084"
+ style="stop-color:#ffffff;stop-opacity:0.25882353;" />
+ <stop
+ id="stop3800"
+ offset="0.50963062"
+ style="stop-color:#ffffff;stop-opacity:0.21568627;" />
+ <stop
+ id="stop3798"
+ offset="0.61938298"
+ style="stop-color:#ffffff;stop-opacity:0.15294118;" />
+ <stop
+ id="stop3796"
+ offset="0.75001973"
+ style="stop-color:#ffffff;stop-opacity:0.09019608;" />
+ <stop
+ id="stop3794"
+ offset="0.83893943"
+ style="stop-color:#ffffff;stop-opacity:0.05490196;" />
+ <stop
+ id="stop3792"
+ offset="0.91730076"
+ style="stop-color:#ffffff;stop-opacity:0.02745098;" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0"
+ offset="1"
+ id="stop3776" />
+ </linearGradient>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3772"
+ id="radialGradient3778"
+ cx="49.10873"
+ cy="-14.628683"
+ fx="49.10873"
+ fy="-14.628683"
+ r="48.035713"
+ gradientTransform="matrix(-1.156153,0.00571083,-0.00496751,-1.0056696,106.16882,941.03082)"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3786"
+ id="linearGradient3784"
+ x1="48.214287"
+ y1="1050.13"
+ x2="48.214287"
+ y2="994.57111"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,-952.36218)" />
+ </defs>
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#000000"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="1"
+ inkscape:pageshadow="2"
+ inkscape:zoom="4"
+ inkscape:cx="-99.870026"
+ inkscape:cy="62.091167"
+ inkscape:document-units="px"
+ inkscape:current-layer="layer1"
+ showgrid="false"
+ inkscape:showpageshadow="false"
+ inkscape:window-width="1920"
+ inkscape:window-height="1056"
+ inkscape:window-x="0"
+ inkscape:window-y="24"
+ inkscape:window-maximized="1" />
+ <metadata
+ id="metadata7">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title />
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="Ebene 1"
+ inkscape:groupmode="layer"
+ id="layer1"
+ transform="translate(0,-952.36218)"
+ style="display:inline">
+ <path
+ style="fill:url(#linearGradient3784);fill-opacity:1;stroke:none;opacity:0.72491909"
+ d="M 8.09375 31.78125 C 6.4638438 31.78125 4.9928252 32.769882 3.875 34.375 L 3.875 90.875 C 3.875 93.836 6.22655 96.1875 9.1875 96.1875 L 91 96.1875 C 93.96095 96.1875 96.3125 93.836 96.3125 90.875 L 96.3125 35.28125 C 95.156434 33.140485 93.450449 31.78125 91.53125 31.78125 L 8.09375 31.78125 z M 1.875 40.15625 C 1.8170155 40.70633 1.78125 41.266602 1.78125 41.84375 L 1.78125 87.78125 C 1.78125 88.358398 1.8170155 88.91867 1.875 89.46875 L 1.875 40.15625 z "
+ transform="translate(0,952.36218)"
+ id="rect3780" />
+ <rect
+ style="fill:none;stroke:#ffffff;stroke-width:2;stroke-miterlimit:4;stroke-opacity:0.31007752;stroke-dasharray:none"
+ id="rect3000"
+ width="94.446426"
+ height="94.446426"
+ x="2.8672049"
+ y="955.11957"
+ ry="6.3134527"
+ rx="6.3134527" />
+ <rect
+ style="fill:url(#radialGradient3778);fill-opacity:1;stroke:none;opacity:0.73139159"
+ id="rect3770"
+ width="96.071426"
+ height="56.071426"
+ x="1.7857143"
+ y="954.32648"
+ rx="6.3134527"
+ ry="6.3134527" />
+ </g>
+</svg>
diff --git a/resources/themes/unity/icon_active.svg b/resources/themes/unity/icon_active.svg
new file mode 100644
index 0000000..79593ab
--- /dev/null
+++ b/resources/themes/unity/icon_active.svg
@@ -0,0 +1,142 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="100"
+ height="100"
+ id="svg2"
+ version="1.1"
+ inkscape:version="0.48.1 r9760"
+ sodipodi:docname="unity_fg.svg">
+ <defs
+ id="defs4">
+ <linearGradient
+ id="linearGradient3786"
+ inkscape:collect="always">
+ <stop
+ id="stop3788"
+ offset="0"
+ style="stop-color:#ffffff;stop-opacity:0.59649123" />
+ <stop
+ id="stop3790"
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:0" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient3772">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0.64912281"
+ offset="0"
+ id="stop3774" />
+ <stop
+ id="stop3804"
+ offset="0.33709621"
+ style="stop-color:#ffffff;stop-opacity:0.30980392;" />
+ <stop
+ id="stop3802"
+ offset="0.41556084"
+ style="stop-color:#ffffff;stop-opacity:0.25882353;" />
+ <stop
+ id="stop3800"
+ offset="0.50963062"
+ style="stop-color:#ffffff;stop-opacity:0.21568627;" />
+ <stop
+ id="stop3798"
+ offset="0.61938298"
+ style="stop-color:#ffffff;stop-opacity:0.15294118;" />
+ <stop
+ id="stop3796"
+ offset="0.75001973"
+ style="stop-color:#ffffff;stop-opacity:0.09019608;" />
+ <stop
+ id="stop3794"
+ offset="0.83893943"
+ style="stop-color:#ffffff;stop-opacity:0.05490196;" />
+ <stop
+ id="stop3792"
+ offset="0.91730076"
+ style="stop-color:#ffffff;stop-opacity:0.02745098;" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0"
+ offset="1"
+ id="stop3776" />
+ </linearGradient>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3772"
+ id="radialGradient3778"
+ cx="49.10873"
+ cy="-14.628683"
+ fx="49.10873"
+ fy="-14.628683"
+ r="48.035713"
+ gradientTransform="matrix(-1.156153,0.00571083,-0.00496751,-1.0056696,106.16882,941.03082)"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3786"
+ id="linearGradient3784"
+ x1="48.214287"
+ y1="1050.13"
+ x2="48.214287"
+ y2="994.57111"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,2.9263432e-6)" />
+ </defs>
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#000000"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="1"
+ inkscape:pageshadow="2"
+ inkscape:zoom="2.8"
+ inkscape:cx="-16.038516"
+ inkscape:cy="39.866578"
+ inkscape:document-units="px"
+ inkscape:current-layer="layer1"
+ showgrid="false"
+ inkscape:showpageshadow="false"
+ inkscape:window-width="1920"
+ inkscape:window-height="1056"
+ inkscape:window-x="0"
+ inkscape:window-y="24"
+ inkscape:window-maximized="1" />
+ <metadata
+ id="metadata7">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title></dc:title>
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="Ebene 1"
+ inkscape:groupmode="layer"
+ id="layer1"
+ transform="translate(0,-952.36218)"
+ style="display:inline">
+ <rect
+ style="fill:#d8d8d8;stroke:#ffffff;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;fill-opacity:1"
+ id="rect3000"
+ width="94.446426"
+ height="94.446426"
+ x="2.8672049"
+ y="955.11957"
+ ry="6.3134527"
+ rx="6.3134527" />
+ </g>
+</svg>
diff --git a/resources/themes/unity/icon_inactive.svg b/resources/themes/unity/icon_inactive.svg
new file mode 100644
index 0000000..e5ad950
--- /dev/null
+++ b/resources/themes/unity/icon_inactive.svg
@@ -0,0 +1,142 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="100"
+ height="100"
+ id="svg2"
+ version="1.1"
+ inkscape:version="0.48.1 r9760"
+ sodipodi:docname="icon_inactive.svg">
+ <defs
+ id="defs4">
+ <linearGradient
+ id="linearGradient3786"
+ inkscape:collect="always">
+ <stop
+ id="stop3788"
+ offset="0"
+ style="stop-color:#ffffff;stop-opacity:0.59649123" />
+ <stop
+ id="stop3790"
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:0" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient3772">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0.64912281"
+ offset="0"
+ id="stop3774" />
+ <stop
+ id="stop3804"
+ offset="0.33709621"
+ style="stop-color:#ffffff;stop-opacity:0.30980392;" />
+ <stop
+ id="stop3802"
+ offset="0.41556084"
+ style="stop-color:#ffffff;stop-opacity:0.25882353;" />
+ <stop
+ id="stop3800"
+ offset="0.50963062"
+ style="stop-color:#ffffff;stop-opacity:0.21568627;" />
+ <stop
+ id="stop3798"
+ offset="0.61938298"
+ style="stop-color:#ffffff;stop-opacity:0.15294118;" />
+ <stop
+ id="stop3796"
+ offset="0.75001973"
+ style="stop-color:#ffffff;stop-opacity:0.09019608;" />
+ <stop
+ id="stop3794"
+ offset="0.83893943"
+ style="stop-color:#ffffff;stop-opacity:0.05490196;" />
+ <stop
+ id="stop3792"
+ offset="0.91730076"
+ style="stop-color:#ffffff;stop-opacity:0.02745098;" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0"
+ offset="1"
+ id="stop3776" />
+ </linearGradient>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3772"
+ id="radialGradient3778"
+ cx="49.10873"
+ cy="-14.628683"
+ fx="49.10873"
+ fy="-14.628683"
+ r="48.035713"
+ gradientTransform="matrix(-1.156153,0.00571083,-0.00496751,-1.0056696,106.16882,941.03082)"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3786"
+ id="linearGradient3784"
+ x1="48.214287"
+ y1="1050.13"
+ x2="48.214287"
+ y2="994.57111"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,2.9263432e-6)" />
+ </defs>
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#000000"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="2.8"
+ inkscape:cx="-88.717087"
+ inkscape:cy="39.866578"
+ inkscape:document-units="px"
+ inkscape:current-layer="layer1"
+ showgrid="false"
+ inkscape:showpageshadow="false"
+ inkscape:window-width="1920"
+ inkscape:window-height="1056"
+ inkscape:window-x="0"
+ inkscape:window-y="24"
+ inkscape:window-maximized="1" />
+ <metadata
+ id="metadata7">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title />
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="Ebene 1"
+ inkscape:groupmode="layer"
+ id="layer1"
+ transform="translate(0,-952.36218)"
+ style="display:inline">
+ <rect
+ style="fill:#000000;stroke:none;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;fill-opacity:0.64028776"
+ id="rect3000"
+ width="94.446426"
+ height="94.446426"
+ x="2.8672049"
+ y="955.11957"
+ ry="6.3134527"
+ rx="6.3134527" />
+ </g>
+</svg>
diff --git a/resources/themes/unity/ring.svg b/resources/themes/unity/ring.svg
new file mode 100644
index 0000000..1fb2dcd
--- /dev/null
+++ b/resources/themes/unity/ring.svg
@@ -0,0 +1,214 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="100"
+ height="100"
+ id="svg2"
+ version="1.1"
+ inkscape:version="0.48.1 r9760"
+ sodipodi:docname="ring.svg">
+ <defs
+ id="defs4">
+ <linearGradient
+ id="linearGradient3800">
+ <stop
+ style="stop-color:#5a5a5a;stop-opacity:1;"
+ offset="0"
+ id="stop3802" />
+ <stop
+ id="stop3810"
+ offset="0.92134696"
+ style="stop-color:#101010;stop-opacity:1" />
+ <stop
+ style="stop-color:#000000;stop-opacity:0"
+ offset="1"
+ id="stop3804" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3007">
+ <stop
+ id="stop3009"
+ offset="0"
+ style="stop-color:#ffffff;stop-opacity:0" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="0.3680203"
+ id="stop3011" />
+ <stop
+ id="stop3013"
+ offset="0.57677984"
+ style="stop-color:#ffffff;stop-opacity:0.66666667;" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0.45490196;"
+ offset="0.66058904"
+ id="stop3015" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0.34901961;"
+ offset="0.70194155"
+ id="stop3017" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0.25490196;"
+ offset="0.74285865"
+ id="stop3019" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0.1254902;"
+ offset="0.8251282"
+ id="stop3021" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0.05490196;"
+ offset="0.90009141"
+ id="stop3023" />
+ <stop
+ id="stop3025"
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:0" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3767">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0"
+ offset="0"
+ id="stop3769" />
+ <stop
+ id="stop4739"
+ offset="0.3680203"
+ style="stop-color:#ffffff;stop-opacity:0;" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0.66666667;"
+ offset="0.59831607"
+ id="stop4703" />
+ <stop
+ id="stop4713"
+ offset="0.66058904"
+ style="stop-color:#ffffff;stop-opacity:0.45490196;" />
+ <stop
+ id="stop4711"
+ offset="0.70194155"
+ style="stop-color:#ffffff;stop-opacity:0.34901961;" />
+ <stop
+ id="stop4709"
+ offset="0.74285865"
+ style="stop-color:#ffffff;stop-opacity:0.25490196;" />
+ <stop
+ id="stop4707"
+ offset="0.8251282"
+ style="stop-color:#ffffff;stop-opacity:0.1254902;" />
+ <stop
+ id="stop4705"
+ offset="0.90009141"
+ style="stop-color:#ffffff;stop-opacity:0.05490196;" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0"
+ offset="1"
+ id="stop3771" />
+ </linearGradient>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3767"
+ id="radialGradient3775"
+ cx="50.002552"
+ cy="49.744911"
+ fx="50.002552"
+ fy="49.744911"
+ r="49.750011"
+ gradientUnits="userSpaceOnUse" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3007"
+ id="radialGradient3005"
+ gradientUnits="userSpaceOnUse"
+ cx="50.002552"
+ cy="49.744911"
+ fx="50.002552"
+ fy="49.744911"
+ r="49.750011" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3800"
+ id="radialGradient3808"
+ cx="50"
+ cy="50"
+ fx="50"
+ fy="50"
+ r="49.47143"
+ gradientUnits="userSpaceOnUse" />
+ </defs>
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#1d1d1d"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="3.959798"
+ inkscape:cx="-48.85178"
+ inkscape:cy="58.882718"
+ inkscape:document-units="px"
+ inkscape:current-layer="layer1"
+ showgrid="false"
+ inkscape:showpageshadow="false"
+ showguides="true"
+ inkscape:guide-bbox="true"
+ inkscape:window-width="1920"
+ inkscape:window-height="1056"
+ inkscape:window-x="0"
+ inkscape:window-y="24"
+ inkscape:window-maximized="1" />
+ <metadata
+ id="metadata7">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title />
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="Ebene 1"
+ inkscape:groupmode="layer"
+ id="layer1"
+ transform="translate(0,-952.36218)">
+ <path
+ transform="matrix(0.90538035,0,0,0.90538035,4.7309822,957.09316)"
+ d="M 98.57143,50 A 48.57143,48.57143 0 1 1 1.4285698,50 48.57143,48.57143 0 1 1 98.57143,50 z"
+ sodipodi:ry="48.57143"
+ sodipodi:rx="48.57143"
+ sodipodi:cy="50"
+ sodipodi:cx="50"
+ id="path3782"
+ style="opacity:0.36140351;fill:none;stroke:#000000;stroke-width:7.62110661999999994;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ sodipodi:type="arc" />
+ <path
+ sodipodi:type="arc"
+ style="opacity:0.59649120000000000;fill:none;fill-opacity:1;stroke:url(#radialGradient3808);stroke-width:1.80000000000000004;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="path3012"
+ sodipodi:cx="50"
+ sodipodi:cy="50"
+ sodipodi:rx="48.57143"
+ sodipodi:ry="48.57143"
+ d="M 98.57143,50 A 48.57143,48.57143 0 1 1 1.4285698,50 48.57143,48.57143 0 1 1 98.57143,50 z"
+ transform="translate(0,952.36218)" />
+ <path
+ sodipodi:type="arc"
+ style="opacity:0.81403509;fill:#000000;fill-opacity:1;stroke:none"
+ id="path3812"
+ sodipodi:cx="50"
+ sodipodi:cy="50"
+ sodipodi:rx="48.57143"
+ sodipodi:ry="48.57143"
+ d="M 98.57143,50 A 48.57143,48.57143 0 1 1 1.4285698,50 48.57143,48.57143 0 1 1 98.57143,50 z"
+ transform="matrix(0.82999029,0,0,0.82999029,8.5004852,960.86266)" />
+ </g>
+</svg>
diff --git a/resources/themes/unity/theme.xml b/resources/themes/unity/theme.xml
new file mode 100644
index 0000000..9718753
--- /dev/null
+++ b/resources/themes/unity/theme.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<theme name="Unity" description="A theme made for the Unity interface of Ubuntu" author="Simon Schneegans" email="josi.schneegans@vr-web.de">
+ <pie radius="130" maxZoom="1.1" zoomRange="0.1" transitionTime="0.2" springiness="1.5"
+ fadeInTime="0.3" fadeOutTime="0.3" fadeInZoom="1.5" fadeOutZoom="0.7" fadeInRotation="0.5" fadeOutRotation="-0.7">
+ <center radius="80" activeRadius="55">
+ <center_layer file="ring.svg"
+ active_scale="0.8" active_rotationMode="auto" active_rotationSpeed="0" active_colorize="false" active_alpha="1.0"
+ inactive_scale="0.8" inactive_rotationMode="auto" inactive_rotationSpeed="0" inactive_colorize="false" inactive_alpha="1.0" />
+ <center_layer file="arrow.svg"
+ active_scale="1.0" active_rotationMode="turn_to_mouse" active_rotationSpeed="15.0" active_colorize="false" active_alpha="1.0"
+ inactive_scale="1.0" inactive_rotationMode="auto" inactive_rotationSpeed="0.0" inactive_colorize="false" inactive_alpha="0.0" />
+ </center>
+ <slices radius="28" minGap="14">
+ <activeSlice>
+ <slice_layer type="file" file="icon_active.svg" scale="1" colorize="true" />
+ <slice_layer type="file" file="gloss.svg" scale="1" colorize="false" />
+ <slice_layer type="icon" scale="0.9" colorize="false" />
+ </activeSlice>
+ <inactiveSlice>
+ <slice_layer type="file" file="icon_inactive.svg" scale="1" colorize="false" />
+ <slice_layer type="file" file="gloss.svg" scale="1" colorize="false" />
+ <slice_layer type="icon" scale="0.9" colorize="false" />
+ </inactiveSlice>
+ </slices>
+ <caption position="0" font="sans 10" width="90" height="90" />
+ </pie>
+</theme>
+
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
new file mode 100644
index 0000000..b3b8ed3
--- /dev/null
+++ b/src/CMakeLists.txt
@@ -0,0 +1,82 @@
+################################################################
+# Actually compile the executable
+################################################################
+
+# determine source and header files
+file(GLOB VALA_SRC RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.vala */*.vala)
+
+if (${INDICATOR_FOUND})
+ SET(DEFINES --define HAVE_APPINDICATOR)
+endif(${INDICATOR_FOUND})
+
+if (${GMENU3_FOUND})
+ LIST(APPEND DEFINES --define HAVE_GMENU_3)
+endif (${GMENU3_FOUND})
+
+# use valac to compile sources to c files
+vala_precompile(
+ VALA_C
+ ${VALA_SRC}
+ PACKAGES
+ ${VALA_PKGS}
+ OPTIONS
+ --vapidir=${CMAKE_SOURCE_DIR}/vapi/
+ --thread
+ ${DEFINES}
+)
+
+# compile c-sources
+add_executable(gnome-pie ${VALA_C})
+
+# install executable
+install(
+ TARGETS
+ gnome-pie
+ RUNTIME DESTINATION
+ ${CMAKE_INSTALL_PREFIX}/bin
+)
+
+# install credits
+install(
+ FILES
+ ${CMAKE_SOURCE_DIR}/README
+ DESTINATION
+ ${CMAKE_INSTALL_PREFIX}/share/doc/gnome-pie
+)
+
+# install locales
+install(
+ DIRECTORY
+ ${CMAKE_SOURCE_DIR}/resources/locale
+ DESTINATION
+ ${CMAKE_INSTALL_PREFIX}/share
+ PATTERN *.po EXCLUDE
+ PATTERN *.pot EXCLUDE
+ PATTERN *.sh EXCLUDE
+)
+
+# install themes
+install(
+ DIRECTORY
+ ${CMAKE_SOURCE_DIR}/resources/themes
+ DESTINATION
+ ${CMAKE_INSTALL_PREFIX}/share/gnome-pie
+)
+
+# install icons
+install(
+ FILES
+ ${CMAKE_SOURCE_DIR}/resources/gnome-pie.svg
+ ${CMAKE_SOURCE_DIR}/resources/gnome-pie-indicator.svg
+ DESTINATION
+ ${CMAKE_INSTALL_PREFIX}/share/icons/hicolor/scalable/apps
+)
+
+# desktop file
+install(
+ FILES
+ ${CMAKE_SOURCE_DIR}/resources/gnome-pie.desktop
+ DESTINATION
+ ${CMAKE_INSTALL_PREFIX}/share/applications
+)
+
diff --git a/src/actionGroups/actionGroup.vala b/src/actionGroups/actionGroup.vala
new file mode 100644
index 0000000..a6b52ff
--- /dev/null
+++ b/src/actionGroups/actionGroup.vala
@@ -0,0 +1,75 @@
+/*
+Copyright (c) 2011 by Simon Schneegans
+
+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 3 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, see <http://www.gnu.org/licenses/>.
+*/
+
+namespace GnomePie {
+
+/////////////////////////////////////////////////////////////////////////
+// A base class storing a set of Actions. Derived classes may define
+// how these Actions are created. This base class serves for custom
+// actions, defined by the user.
+/////////////////////////////////////////////////////////////////////////
+
+public class ActionGroup : GLib.Object {
+
+ /////////////////////////////////////////////////////////////////////
+ /// A list of all stored actions.
+ /////////////////////////////////////////////////////////////////////
+
+ public Gee.ArrayList<Action?> actions { get; private set; }
+
+ /////////////////////////////////////////////////////////////////////
+ /// The ID of the pie to which this group is attached.
+ /////////////////////////////////////////////////////////////////////
+
+ public string parent_id { get; construct set; }
+
+ /////////////////////////////////////////////////////////////////////
+ /// C'tor, initializes all members.
+ /////////////////////////////////////////////////////////////////////
+
+ public ActionGroup(string parent_id) {
+ GLib.Object(parent_id : parent_id);
+ }
+
+ construct {
+ this.actions = new Gee.ArrayList<Action?>();
+ }
+
+ /////////////////////////////////////////////////////////////////////
+ /// This one is called, when the ActionGroup is deleted.
+ /////////////////////////////////////////////////////////////////////
+
+ public virtual void on_remove() {}
+
+ /////////////////////////////////////////////////////////////////////
+ /// Adds a new Action to the group.
+ /////////////////////////////////////////////////////////////////////
+
+ public void add_action(Action new_action) {
+ this.actions.add(new_action);
+ }
+
+ /////////////////////////////////////////////////////////////////////
+ /// Removes all Actions from the group.
+ /////////////////////////////////////////////////////////////////////
+
+ public void delete_all() {
+ actions.clear();
+ }
+}
+
+}
diff --git a/src/actionGroups/bookmarkGroup.vala b/src/actionGroups/bookmarkGroup.vala
new file mode 100644
index 0000000..f4ba66e
--- /dev/null
+++ b/src/actionGroups/bookmarkGroup.vala
@@ -0,0 +1,148 @@
+/*
+Copyright (c) 2011 by Simon Schneegans
+
+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 3 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, see <http://www.gnu.org/licenses/>.
+*/
+
+namespace GnomePie {
+
+/////////////////////////////////////////////////////////////////////////
+/// A group of Actions, which represent the users gtk-bookmarks, his home
+/// directory, desktop and trash. It stay up-to-date, even if the
+/// bookmarks change.
+/////////////////////////////////////////////////////////////////////////
+
+public class BookmarkGroup : ActionGroup {
+
+ /////////////////////////////////////////////////////////////////////
+ /// Used to register this type of ActionGroup. It sets the display
+ /// name for this ActionGroup, it's icon name and the string used in
+ /// the pies.conf file for this kind of ActionGroups.
+ /////////////////////////////////////////////////////////////////////
+
+ public static void register(out string name, out string icon, out string settings_name) {
+ name = _("Bookmarks");
+ icon = "user-bookmarks";
+ settings_name = "bookmarks";
+ }
+
+ /////////////////////////////////////////////////////////////////////
+ /// Two members needed to avoid useless, frequent changes of the
+ /// stored Actions.
+ /////////////////////////////////////////////////////////////////////
+
+ private bool changing = false;
+ private bool changed_again = false;
+
+ /////////////////////////////////////////////////////////////////////
+ /// C'tor, initializes all members.
+ /////////////////////////////////////////////////////////////////////
+
+ public BookmarkGroup(string parent_id) {
+ GLib.Object(parent_id : parent_id);
+ }
+
+ /////////////////////////////////////////////////////////////////////
+ /// Construct block loads the bookmarks of the user and adds a file
+ /// monitor in order to update the BookmarkGroup when the bookmarks
+ /// of the user change.
+ /////////////////////////////////////////////////////////////////////
+
+ construct {
+ this.load();
+
+ // add monitor
+ var bookmark_file = GLib.File.new_for_path(
+ GLib.Environment.get_home_dir()).get_child(".gtk-bookmarks");
+
+ if (bookmark_file.query_exists()) {
+ try {
+ var monitor = bookmark_file.monitor(GLib.FileMonitorFlags.NONE);
+ monitor.changed.connect(this.reload);
+ } catch (GLib.Error e) {
+ warning(e.message);
+ }
+ }
+ }
+
+ /////////////////////////////////////////////////////////////////////
+ /// Adds Actions for each gtk-bookmark of the user and for his home
+ /// folder, desktop and trash.
+ /////////////////////////////////////////////////////////////////////
+
+ private void load() {
+ // add home folder
+ this.add_action(ActionRegistry.new_for_uri("file://" + GLib.Environment.get_home_dir()));
+
+ // add .gtk-bookmarks
+ var bookmark_file = GLib.File.new_for_path(
+ GLib.Environment.get_home_dir()).get_child(".gtk-bookmarks");
+
+ if (!bookmark_file.query_exists()) {
+ warning("Failed to find file \".gtk-bookmarks\"!");
+ return;
+ }
+
+ try {
+ var dis = new DataInputStream(bookmark_file.read());
+ string line;
+ while ((line = dis.read_line(null)) != null) {
+ var parts = line.split(" ");
+
+ string uri = parts[0];
+ string name = parts[1];
+
+ this.add_action(ActionRegistry.new_for_uri(uri, name));
+ }
+ } catch (Error e) {
+ error ("%s", e.message);
+ }
+
+ // add trash
+ this.add_action(ActionRegistry.new_for_uri("trash:///"));
+
+ // add desktop
+ this.add_action(ActionRegistry.new_for_uri("file://" + GLib.Environment.get_user_special_dir(GLib.UserDirectory.DESKTOP)));
+ }
+
+ /////////////////////////////////////////////////////////////////////
+ /// Reloads all Bookmarks. Is called when the user's gtk-bookmarks
+ /// file changes.
+ /////////////////////////////////////////////////////////////////////
+
+ private void reload() {
+ // avoid too frequent changes...
+ if (!this.changing) {
+ this.changing = true;
+ Timeout.add(200, () => {
+ if (this.changed_again) {
+ this.changed_again = false;
+ return true;
+ }
+
+ // reload
+ message("Bookmarks changed...");
+ this.delete_all();
+ this.load();
+
+ this.changing = false;
+ return false;
+ });
+ } else {
+ this.changed_again = true;
+ }
+ }
+}
+
+}
diff --git a/src/actionGroups/clipboardGroup.vala b/src/actionGroups/clipboardGroup.vala
new file mode 100644
index 0000000..0e95b65
--- /dev/null
+++ b/src/actionGroups/clipboardGroup.vala
@@ -0,0 +1,116 @@
+/*
+Copyright (c) 2011 by Simon Schneegans
+
+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 3 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, see <http://www.gnu.org/licenses/>.
+*/
+
+namespace GnomePie {
+
+/////////////////////////////////////////////////////////////////////////
+/// This Group keeps a history of the last used Clipboard entries.
+/////////////////////////////////////////////////////////////////////////
+
+public class ClipboardGroup : ActionGroup {
+
+ /////////////////////////////////////////////////////////////////////
+ ///
+ /////////////////////////////////////////////////////////////////////
+
+ private class ClipboardItem : GLib.Object {
+
+ public string name { get; private set; }
+ public string icon { get; private set; }
+
+ private Gtk.SelectionData contents;
+
+ public ClipboardItem(Gtk.SelectionData contents) {
+ this.contents = contents.copy();
+ this.name = this.contents.get_text() ?? "";
+ this.icon = "edit-paste";
+ }
+
+ public void paste() {
+ debug(name);
+ }
+ }
+
+ public ClipboardGroup(string parent_id) {
+ GLib.Object(parent_id : parent_id);
+ }
+
+ /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+
+ /////////////////////////////////////////////////////////////////////
+ /// Used to register this type of ActionGroup. It sets the display
+ /// name for this ActionGroup, it's icon name and the string used in
+ /// the pies.conf file for this kind of ActionGroups.
+ /////////////////////////////////////////////////////////////////////
+
+ public static void register(out string name, out string icon, out string settings_name) {
+ name = _("Clipboard");
+ icon = "edit-paste";
+ settings_name = "clipboard";
+ }
+
+ /////////////////////////////////////////////////////////////////////
+ /// The clipboard to be monitored.
+ /////////////////////////////////////////////////////////////////////
+
+ private Gtk.Clipboard clipboard;
+
+
+ /////////////////////////////////////////////////////////////////////
+ /// The maximum remembered items of the clipboard.
+ /////////////////////////////////////////////////////////////////////
+
+ private const int max_items = 6;
+
+ private Gee.ArrayList<ClipboardItem?> items;
+
+ construct {
+ this.items = new Gee.ArrayList<ClipboardItem?>();
+ this.clipboard = Gtk.Clipboard.get(Gdk.SELECTION_CLIPBOARD);
+ this.clipboard.owner_change.connect(this.on_change);
+ }
+
+ private void on_change() {
+ if (this.clipboard.wait_is_text_available()) {
+ this.clipboard.request_contents(Gdk.Atom.intern("text/plain", false), this.add_item);
+ }
+ }
+
+ private void add_item(Gtk.Clipboard c, Gtk.SelectionData contents) {
+ var new_item = new ClipboardItem(contents);
+
+ if (this.items.size == this.max_items)
+ this.items.remove_at(0);
+
+ this.items.add(new_item);
+
+ // update slices
+ this.delete_all();
+
+ for (int i=0; i<this.items.size; ++i) {
+ var action = new SigAction(items[i].name, items[i].icon, i.to_string());
+ action.activated.connect(() => {
+ this.items[int.parse(action.real_command)].paste();
+ });
+ this.add_action(action);
+ }
+
+ }
+}
+
+}
diff --git a/src/actionGroups/devicesGroup.vala b/src/actionGroups/devicesGroup.vala
new file mode 100644
index 0000000..3d2ced0
--- /dev/null
+++ b/src/actionGroups/devicesGroup.vala
@@ -0,0 +1,129 @@
+/*
+Copyright (c) 2011 by Simon Schneegans
+
+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 3 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, see <http://www.gnu.org/licenses/>.
+*/
+
+namespace GnomePie {
+
+/////////////////////////////////////////////////////////////////////
+/// An ActionGroup which contains all currently plugged-in devices,
+/// such as CD-ROM's or USB-sticks.
+/////////////////////////////////////////////////////////////////////
+
+public class DevicesGroup : ActionGroup {
+
+ /////////////////////////////////////////////////////////////////////
+ /// Used to register this type of ActionGroup. It sets the display
+ /// name for this ActionGroup, it's icon name and the string used in
+ /// the pies.conf file for this kind of ActionGroups.
+ /////////////////////////////////////////////////////////////////////
+
+ public static void register(out string name, out string icon, out string settings_name) {
+ name = _("Devices");
+ icon = "harddrive";
+ settings_name = "devices";
+ }
+
+ /////////////////////////////////////////////////////////////////////
+ /// Two members needed to avoid useless, frequent changes of the
+ /// stored Actions.
+ /////////////////////////////////////////////////////////////////////
+
+ private bool changing = false;
+ private bool changed_again = false;
+
+ /////////////////////////////////////////////////////////////////////
+ /// The VolumeMonitor used to check for added or removed devices.
+ /////////////////////////////////////////////////////////////////////
+
+ private GLib.VolumeMonitor monitor;
+
+ /////////////////////////////////////////////////////////////////////
+ /// C'tor, initializes all members.
+ /////////////////////////////////////////////////////////////////////
+
+ public DevicesGroup(string parent_id) {
+ GLib.Object(parent_id : parent_id);
+ }
+
+ /////////////////////////////////////////////////////////////////////
+ /// Construct block loads all currently plugged-in devices and
+ /// connects signal handlers to the VolumeMonitor.
+ /////////////////////////////////////////////////////////////////////
+
+ construct {
+ this.monitor = GLib.VolumeMonitor.get();
+
+ this.load();
+
+ // add monitor
+ this.monitor.mount_added.connect(this.reload);
+ this.monitor.mount_removed.connect(this.reload);
+ }
+
+ /////////////////////////////////////////////////////////////////////
+ /// Loads all currently plugged-in devices.
+ /////////////////////////////////////////////////////////////////////
+
+ private void load() {
+ // add root device
+ this.add_action(new UriAction(_("Root"), "harddrive", "file:///"));
+
+ // add all other devices
+ foreach(var mount in this.monitor.get_mounts()) {
+ // get icon
+ var icon_names = mount.get_icon().to_string().split(" ");
+
+ string icon = "";
+ foreach (var icon_name in icon_names) {
+ if (Gtk.IconTheme.get_default().has_icon(icon_name)) {
+ icon = icon_name;
+ break;
+ }
+ }
+
+ this.add_action(new UriAction(mount.get_name(), icon, mount.get_root().get_uri()));
+ }
+ }
+
+ /////////////////////////////////////////////////////////////////////
+ /// Reloads all devices. Is called when the VolumeMonitor changes.
+ /////////////////////////////////////////////////////////////////////
+
+ private void reload() {
+ // avoid too frequent changes...
+ if (!this.changing) {
+ this.changing = true;
+ Timeout.add(200, () => {
+ if (this.changed_again) {
+ this.changed_again = false;
+ return true;
+ }
+
+ // reload
+ message("Devices changed...");
+ this.delete_all();
+ this.load();
+
+ this.changing = false;
+ return false;
+ });
+ } else {
+ this.changed_again = true;
+ }
+ }
+}
+
+}
diff --git a/src/actionGroups/groupRegistry.vala b/src/actionGroups/groupRegistry.vala
new file mode 100644
index 0000000..94169d5
--- /dev/null
+++ b/src/actionGroups/groupRegistry.vala
@@ -0,0 +1,89 @@
+/*
+Copyright (c) 2011 by Simon Schneegans
+
+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 3 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, see <http://www.gnu.org/licenses/>.
+*/
+
+namespace GnomePie {
+
+/////////////////////////////////////////////////////////////////////////
+/// A which has knowledge on all possible acion group types.
+/////////////////////////////////////////////////////////////////////////
+
+public class GroupRegistry : GLib.Object {
+
+ /////////////////////////////////////////////////////////////////////
+ /// A list containing all available ActionGroup types.
+ /////////////////////////////////////////////////////////////////////
+
+ public static Gee.ArrayList<Type> types { get; private set; }
+
+ /////////////////////////////////////////////////////////////////////
+ /// Three maps associating a displayable name for each ActionGroup,
+ /// an icon name and a name for the pies.conf file with it's type.
+ /////////////////////////////////////////////////////////////////////
+
+ public static Gee.HashMap<Type, string> names { get; private set; }
+ public static Gee.HashMap<Type, string> icons { get; private set; }
+ public static Gee.HashMap<Type, string> settings_names { get; private set; }
+
+
+ /////////////////////////////////////////////////////////////////////
+ /// Registers all ActionGroup types.
+ /////////////////////////////////////////////////////////////////////
+
+ public static void init() {
+ types = new Gee.ArrayList<Type>();
+
+ names = new Gee.HashMap<Type, string>();
+ icons = new Gee.HashMap<Type, string>();
+ settings_names = new Gee.HashMap<Type, string>();
+
+ string name = "";
+ string icon = "";
+ string settings_name = "";
+
+ BookmarkGroup.register(out name, out icon, out settings_name);
+ types.add(typeof(BookmarkGroup));
+ names.set(typeof(BookmarkGroup), name);
+ icons.set(typeof(BookmarkGroup), icon);
+ settings_names.set(typeof(BookmarkGroup), settings_name);
+
+ DevicesGroup.register(out name, out icon, out settings_name);
+ types.add(typeof(DevicesGroup));
+ names.set(typeof(DevicesGroup), name);
+ icons.set(typeof(DevicesGroup), icon);
+ settings_names.set(typeof(DevicesGroup), settings_name);
+
+ MenuGroup.register(out name, out icon, out settings_name);
+ types.add(typeof(MenuGroup));
+ names.set(typeof(MenuGroup), name);
+ icons.set(typeof(MenuGroup), icon);
+ settings_names.set(typeof(MenuGroup), settings_name);
+
+ SessionGroup.register(out name, out icon, out settings_name);
+ types.add(typeof(SessionGroup));
+ names.set(typeof(SessionGroup), name);
+ icons.set(typeof(SessionGroup), icon);
+ settings_names.set(typeof(SessionGroup), settings_name);
+
+// ClipboardGroup.register(out name, out icon, out settings_name);
+// types.add(typeof(ClipboardGroup));
+// names.set(typeof(ClipboardGroup), name);
+// icons.set(typeof(ClipboardGroup), icon);
+// settings_names.set(typeof(ClipboardGroup), settings_name);
+ }
+}
+
+}
diff --git a/src/actionGroups/menuGroup.vala b/src/actionGroups/menuGroup.vala
new file mode 100644
index 0000000..07a4bd1
--- /dev/null
+++ b/src/actionGroups/menuGroup.vala
@@ -0,0 +1,254 @@
+/*
+Copyright (c) 2011 by Simon Schneegans
+
+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 3 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, see <http://www.gnu.org/licenses/>.
+*/
+
+namespace GnomePie {
+
+/////////////////////////////////////////////////////////////////////////
+/// An ActionGroup which displays the user's main menu. It's a bit ugly,
+/// but it supports both, an older version and libgnome-menus-3 at the
+/// same time.
+/////////////////////////////////////////////////////////////////////////
+
+public class MenuGroup : ActionGroup {
+ /////////////////////////////////////////////////////////////////////
+ /// Used to register this type of ActionGroup. It sets the display
+ /// name for this ActionGroup, it's icon name and the string used in
+ /// the pies.conf file for this kind of ActionGroups.
+ /////////////////////////////////////////////////////////////////////
+
+ public static void register(out string name, out string icon, out string settings_name) {
+ name = _("Main menu");
+ icon = "gnome-main-menu";
+ settings_name = "menu";
+ }
+
+ /////////////////////////////////////////////////////////////////////
+ /// True, if this MenuGroup is the top most menu.
+ /////////////////////////////////////////////////////////////////////
+
+ public bool is_toplevel {get; construct set; default = true;}
+
+ /////////////////////////////////////////////////////////////////////
+ /// The menu tree displayed by the MenuGroup. Only set for the
+ /// toplevel MenuGroup.
+ /////////////////////////////////////////////////////////////////////
+
+ private GMenu.Tree menu = null;
+
+ /////////////////////////////////////////////////////////////////////
+ /// A list of all sub menus of this MenuGroup.
+ /////////////////////////////////////////////////////////////////////
+
+ private Gee.ArrayList<MenuGroup?> childs;
+
+ /////////////////////////////////////////////////////////////////////
+ /// Two members needed to avoid useless, frequent changes of the
+ /// stored Actions.
+ /////////////////////////////////////////////////////////////////////
+
+ private bool changing = false;
+ private bool changed_again = false;
+
+ /////////////////////////////////////////////////////////////////////
+ /// C'tor, initializes all members. Used for the toplevel menu.
+ /////////////////////////////////////////////////////////////////////
+
+ public MenuGroup(string parent_id) {
+ GLib.Object(parent_id : parent_id, is_toplevel : true);
+ }
+
+ /////////////////////////////////////////////////////////////////////
+ /// C'tor, initializes all members. Used for sub menus.
+ /////////////////////////////////////////////////////////////////////
+
+ public MenuGroup.sub_menu(string parent_id) {
+ GLib.Object(parent_id : parent_id, is_toplevel : false);
+ }
+
+ construct {
+ this.childs = new Gee.ArrayList<MenuGroup?>();
+
+ if (this.is_toplevel) {
+ #if HAVE_GMENU_3
+ this.menu = new GMenu.Tree("applications.menu", GMenu.TreeFlags.INCLUDE_EXCLUDED);
+ this.menu.changed.connect(this.reload);
+ #endif
+
+ this.load_toplevel();
+ }
+ }
+
+ /////////////////////////////////////////////////////////////////////
+ /// Starts to load the menu.
+ /////////////////////////////////////////////////////////////////////
+
+ private void load_toplevel() {
+ #if HAVE_GMENU_3
+ try {
+ if (this.menu.load_sync()) {
+ this.load_contents(this.menu.get_root_directory(), this.parent_id);
+ }
+ } catch (GLib.Error e) {
+ warning(e.message);
+ }
+ #else
+ this.menu = GMenu.Tree.lookup ("applications.menu", GMenu.TreeFlags.INCLUDE_EXCLUDED);
+ this.menu.add_monitor(this.reload);
+ var dir = this.menu.get_root_directory();
+ this.load_contents(dir, this.parent_id);
+ #endif
+ }
+
+ /////////////////////////////////////////////////////////////////////
+ /// Parses the main menu recursively.
+ /////////////////////////////////////////////////////////////////////
+
+ private void load_contents(GMenu.TreeDirectory dir, string parent_id) {
+ #if HAVE_GMENU_3
+ var item = dir.iter();
+
+ while (true) {
+ var type = item.next();
+ if (type == GMenu.TreeItemType.INVALID)
+ break;
+
+ if (type == GMenu.TreeItemType.DIRECTORY && !item.get_directory().get_is_nodisplay()) {
+ // create a MenuGroup for sub menus
+ string[] icons = item.get_directory().get_icon().to_string().split(" ");
+ string final_icon = "application-default-icon";
+
+ // search for available icons
+ foreach (var icon in icons) {
+ if (Gtk.IconTheme.get_default().has_icon(icon)) {
+ final_icon = icon;
+ break;
+ }
+ }
+
+ var sub_menu = PieManager.create_dynamic_pie(item.get_directory().get_name(), final_icon);
+ var group = new MenuGroup.sub_menu(sub_menu.id);
+ group.add_action(new PieAction(parent_id, true));
+ group.load_contents(item.get_directory(), sub_menu.id);
+ childs.add(group);
+
+ sub_menu.add_group(group);
+
+ this.add_action(new PieAction(sub_menu.id));
+
+ } else if (type == GMenu.TreeItemType.ENTRY ) {
+ // create an AppAction for entries
+ if (!item.get_entry().get_is_excluded()) {
+ this.add_action(ActionRegistry.new_for_app_info(item.get_entry().get_app_info()));
+ }
+ }
+ }
+ #else
+ foreach (var item in dir.get_contents()) {
+ switch(item.get_type()) {
+ case GMenu.TreeItemType.DIRECTORY:
+ // create a MenuGroup for sub menus
+ if (!((GMenu.TreeDirectory)item).get_is_nodisplay()) {
+ var sub_menu = PieManager.create_dynamic_pie(
+ ((GMenu.TreeDirectory)item).get_name(),
+ ((GMenu.TreeDirectory)item).get_icon());
+ var group = new MenuGroup.sub_menu(sub_menu.id);
+ group.add_action(new PieAction(parent_id, true));
+ group.load_contents((GMenu.TreeDirectory)item, sub_menu.id);
+ childs.add(group);
+
+ sub_menu.add_group(group);
+
+ this.add_action(new PieAction(sub_menu.id));
+ }
+ break;
+
+ case GMenu.TreeItemType.ENTRY:
+ // create an AppAction for entries
+ if (!((GMenu.TreeEntry)item).get_is_nodisplay() && !((GMenu.TreeEntry)item).get_is_excluded()) {
+ this.add_action(new AppAction(((GMenu.TreeEntry)item).get_name(),
+ ((GMenu.TreeEntry)item).get_icon(),
+ ((GMenu.TreeEntry)item).get_exec()));
+ }
+ break;
+ }
+ }
+ #endif
+ }
+
+ /////////////////////////////////////////////////////////////////////
+ /// Reloads the menu.
+ /////////////////////////////////////////////////////////////////////
+
+ private void reload() {
+ // avoid too frequent changes...
+ if (!this.changing) {
+ this.changing = true;
+ Timeout.add(500, () => {
+ if (this.changed_again) {
+ this.changed_again = false;
+ return true;
+ }
+
+ // reload
+ message("Main menu changed...");
+ #if !HAVE_GMENU_3
+ this.menu.remove_monitor(this.reload);
+ #endif
+
+ this.clear();
+ this.load_toplevel();
+
+ this.changing = false;
+ return false;
+ });
+ } else {
+ this.changed_again = true;
+ }
+ }
+
+ /////////////////////////////////////////////////////////////////////
+ /// Deletes all generated Pies, when the toplevel menu is deleted.
+ /////////////////////////////////////////////////////////////////////
+
+ public override void on_remove() {
+ if (this.is_toplevel)
+ this.clear();
+ }
+
+ /////////////////////////////////////////////////////////////////////
+ /// Clears this ActionGroup recursively.
+ /////////////////////////////////////////////////////////////////////
+
+ private void clear() {
+ foreach (var child in childs)
+ child.clear();
+
+ if (!this.is_toplevel)
+ PieManager.remove_pie(this.parent_id);
+
+ this.delete_all();
+
+ this.childs.clear();
+
+ #if !HAVE_GMENU_3
+ this.menu = null;
+ #endif
+
+ }
+}
+
+}
diff --git a/src/actionGroups/sessionGroup.vala b/src/actionGroups/sessionGroup.vala
new file mode 100644
index 0000000..9fcab1d
--- /dev/null
+++ b/src/actionGroups/sessionGroup.vala
@@ -0,0 +1,68 @@
+/*
+Copyright (c) 2011 by Simon Schneegans
+
+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 3 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, see <http://www.gnu.org/licenses/>.
+*/
+
+namespace GnomePie {
+
+/////////////////////////////////////////////////////////////////////
+/// An ActionGroup which has three Actions: Logout, Shutdown and
+/// Reboot.
+/////////////////////////////////////////////////////////////////////
+
+public class SessionGroup : ActionGroup {
+
+ /////////////////////////////////////////////////////////////////////
+ /// Used to register this type of ActionGroup. It sets the display
+ /// name for this ActionGroup, it's icon name and the string used in
+ /// the pies.conf file for this kind of ActionGroups.
+ /////////////////////////////////////////////////////////////////////
+
+ public static void register(out string name, out string icon, out string settings_name) {
+ name = _("Session Control");
+ icon = "gnome-logout";
+ settings_name = "session";
+ }
+
+ /////////////////////////////////////////////////////////////////////
+ /// C'tor, initializes all members.
+ /////////////////////////////////////////////////////////////////////
+
+ public SessionGroup(string parent_id) {
+ GLib.Object(parent_id : parent_id);
+ }
+
+ /////////////////////////////////////////////////////////////////////
+ /// Construct block adds the three Actions.
+ /////////////////////////////////////////////////////////////////////
+
+ construct {
+ this.add_action(new AppAction(_("Shutdown"), "gnome-shutdown",
+ "dbus-send --print-reply --dest=org.gnome.SessionManager /org/gnome/SessionManager org.gnome.SessionManager.RequestShutdown"));
+
+ this.add_action(new AppAction(_("Logout"), "gnome-session-logout",
+ "dbus-send --print-reply --dest=org.gnome.SessionManager /org/gnome/SessionManager org.gnome.SessionManager.Logout uint32:1"));
+
+ this.add_action(new AppAction(_("Reboot"), "gnome-session-reboot",
+ "dbus-send --print-reply --dest=org.gnome.SessionManager /org/gnome/SessionManager org.gnome.SessionManager.RequestReboot"));
+ }
+
+ // TODO: check for available interfaces --- these may work too:
+ // dbus-send --print-reply --system --dest=org.freedesktop.Hal /org/freedesktop/Hal/devices/computer org.freedesktop.Hal.Device.SystemPowerManagement.Shutdown
+ // dbus-send --print-reply --dest=org.kde.ksmserver /KSMServer org.kde.KSMServerInterface.logout 0 2 2
+ // dbus-send --system --print-reply --dest="org.freedesktop.ConsoleKit" /org/freedesktop/ConsoleKit/Manager org.freedesktop.ConsoleKit.Manager.Stop
+}
+
+}
diff --git a/src/actions/action.vala b/src/actions/action.vala
new file mode 100644
index 0000000..ceed357
--- /dev/null
+++ b/src/actions/action.vala
@@ -0,0 +1,77 @@
+/*
+Copyright (c) 2011 by Simon Schneegans
+
+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 3 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, see <http://www.gnu.org/licenses/>.
+*/
+
+namespace GnomePie {
+
+/////////////////////////////////////////////////////////////////////////
+/// A base class for actions, which are executed when the user
+/// activates a pie's slice.
+/////////////////////////////////////////////////////////////////////////
+
+public abstract class Action : GLib.Object {
+
+ /////////////////////////////////////////////////////////////////////
+ /// The command which gets executed when user activates the Slice.
+ /// It may be anything but has to be representable with a string.
+ /////////////////////////////////////////////////////////////////////
+
+ public abstract string real_command { get; construct set; }
+
+ /////////////////////////////////////////////////////////////////////
+ /// The command displayed to the user. It should be a bit more
+ /// beautiful than the real_command.
+ /////////////////////////////////////////////////////////////////////
+
+ public abstract string display_command { get; }
+
+ /////////////////////////////////////////////////////////////////////
+ /// The name of the Action.
+ /////////////////////////////////////////////////////////////////////
+
+ public virtual string name { get; protected set; }
+
+ /////////////////////////////////////////////////////////////////////
+ /// The name of the icon of this Action. It should be in the users
+ /// current icon theme.
+ /////////////////////////////////////////////////////////////////////
+
+ public virtual string icon { get; protected set; }
+
+ /////////////////////////////////////////////////////////////////////
+ /// True, if this Action is the quickAction of the associated Pie.
+ /// The quickAction of a Pie gets executed when the users clicks on
+ /// the center of a Pie.
+ /////////////////////////////////////////////////////////////////////
+
+ public virtual bool is_quick_action { get; protected set; }
+
+ /////////////////////////////////////////////////////////////////////
+ /// C'tor, initializes all members.
+ /////////////////////////////////////////////////////////////////////
+
+ public Action(string name, string icon, bool is_quick_action) {
+ GLib.Object(name : name, icon : icon, is_quick_action : is_quick_action);
+ }
+
+ /////////////////////////////////////////////////////////////////////
+ /// This one is called, when the user activates the Slice.
+ /////////////////////////////////////////////////////////////////////
+
+ public abstract void activate();
+}
+
+}
diff --git a/src/actions/actionRegistry.vala b/src/actions/actionRegistry.vala
new file mode 100644
index 0000000..091865f
--- /dev/null
+++ b/src/actions/actionRegistry.vala
@@ -0,0 +1,200 @@
+/*
+Copyright (c) 2011 by Simon Schneegans
+
+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 3 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, see <http://www.gnu.org/licenses/>.
+*/
+
+namespace GnomePie {
+
+/////////////////////////////////////////////////////////////////////////
+/// A which has knowledge on all possible acion types.
+/////////////////////////////////////////////////////////////////////////
+
+public class ActionRegistry : GLib.Object {
+
+ /////////////////////////////////////////////////////////////////////
+ /// A list containing all available Action types.
+ /////////////////////////////////////////////////////////////////////
+
+ public static Gee.ArrayList<Type> types { get; private set; }
+
+ /////////////////////////////////////////////////////////////////////
+ /// Three maps associating a displayable name for each Action,
+ /// whether it has a custom icon and a name for the pies.conf
+ /// file with it's type.
+ /////////////////////////////////////////////////////////////////////
+
+ public static Gee.HashMap<Type, string> names { get; private set; }
+ public static Gee.HashMap<Type, bool> icon_name_editables { get; private set; }
+ public static Gee.HashMap<Type, string> settings_names { get; private set; }
+
+ /////////////////////////////////////////////////////////////////////
+ /// Registers all Action types.
+ /////////////////////////////////////////////////////////////////////
+
+ public static void init() {
+ types = new Gee.ArrayList<Type>();
+
+ names = new Gee.HashMap<Type, string>();
+ icon_name_editables = new Gee.HashMap<Type, bool>();
+ settings_names = new Gee.HashMap<Type, string>();
+
+ string name = "";
+ bool icon_name_editable = true;
+ string settings_name = "";
+
+ AppAction.register(out name, out icon_name_editable, out settings_name);
+ types.add(typeof(AppAction));
+ names.set(typeof(AppAction), name);
+ icon_name_editables.set(typeof(AppAction), icon_name_editable);
+ settings_names.set(typeof(AppAction), settings_name);
+
+ KeyAction.register(out name, out icon_name_editable, out settings_name);
+ types.add(typeof(KeyAction));
+ names.set(typeof(KeyAction), name);
+ icon_name_editables.set(typeof(KeyAction), icon_name_editable);
+ settings_names.set(typeof(KeyAction), settings_name);
+
+ PieAction.register(out name, out icon_name_editable, out settings_name);
+ types.add(typeof(PieAction));
+ names.set(typeof(PieAction), name);
+ icon_name_editables.set(typeof(PieAction), icon_name_editable);
+ settings_names.set(typeof(PieAction), settings_name);
+
+ UriAction.register(out name, out icon_name_editable, out settings_name);
+ types.add(typeof(UriAction));
+ names.set(typeof(UriAction), name);
+ icon_name_editables.set(typeof(UriAction), icon_name_editable);
+ settings_names.set(typeof(UriAction), settings_name);
+ }
+
+ /////////////////////////////////////////////////////////////////////
+ /// A helper method which creates an Action, appropriate for the
+ /// given URI. This can result in an UriAction or in an AppAction,
+ /// depending on the Type of the URI.
+ /////////////////////////////////////////////////////////////////////
+
+ public static Action? new_for_uri(string uri, string? name = null) {
+ var file = GLib.File.new_for_uri(uri);
+ var scheme = file.get_uri_scheme();
+
+ string final_icon = "";
+ string final_name = file.get_basename();
+
+ switch (scheme) {
+ case "application":
+ var file_name = uri.split("//")[1];
+
+ var desktop_file = GLib.File.new_for_path("/usr/share/applications/" + file_name);
+ if (desktop_file.query_exists())
+ return new_for_desktop_file(desktop_file.get_path());
+
+ break;
+
+ case "trash":
+ final_icon = "user-trash";
+ final_name = _("Trash");
+ break;
+
+ case "http": case "https":
+ final_icon = "www";
+ break;
+
+ case "ftp": case "sftp":
+ final_icon = "folder-remote";
+ break;
+
+ default:
+ try {
+ var info = file.query_info("*", GLib.FileQueryInfoFlags.NONE);
+
+ if (info.get_content_type() == "application/x-desktop")
+ return new_for_desktop_file(file.get_parse_name());
+
+ // search for an appropriate icon
+ var gicon = info.get_icon();
+ string[] icons = gicon.to_string().split(" ");
+
+ foreach (var icon in icons) {
+ if (Gtk.IconTheme.get_default().has_icon(icon)) {
+ final_icon = icon;
+ break;
+ }
+ }
+
+ } catch (GLib.Error e) {
+ warning(e.message);
+ }
+
+ break;
+ }
+
+ if (!Gtk.IconTheme.get_default().has_icon(final_icon))
+ final_icon = "application-default-icon";
+
+ if (name != null)
+ final_name = name;
+
+ return new UriAction(final_name, final_icon, uri);
+ }
+
+ /////////////////////////////////////////////////////////////////////
+ /// A helper method which creates an AppAction for given AppInfo.
+ /////////////////////////////////////////////////////////////////////
+
+ public static Action? new_for_app_info(GLib.AppInfo info) {
+ string[] icons = info.get_icon().to_string().split(" ");
+ string final_icon = "application-default-icon";
+
+ // search for available icons
+ foreach (var icon in icons) {
+ if (Gtk.IconTheme.get_default().has_icon(icon)) {
+ final_icon = icon;
+ break;
+ }
+ }
+
+ return new AppAction(info.get_display_name() , final_icon, info.get_commandline());
+ }
+
+ /////////////////////////////////////////////////////////////////////
+ /// A helper method which creates an AppAction for given *.desktop
+ /// file.
+ /////////////////////////////////////////////////////////////////////
+
+ public static Action? new_for_desktop_file(string file_name) {
+ var info = new DesktopAppInfo.from_filename(file_name);
+ return new_for_app_info(info);
+ }
+
+ /////////////////////////////////////////////////////////////////////
+ /// A helper method which creates an AppAction for given mime type.
+ /////////////////////////////////////////////////////////////////////
+
+ public static Action? default_for_mime_type(string type) {
+ var info = AppInfo.get_default_for_type(type, false);
+ return new_for_app_info(info);
+ }
+
+ /////////////////////////////////////////////////////////////////////
+ /// A helper method which creates an AppAction for given uri scheme.
+ /////////////////////////////////////////////////////////////////////
+
+ public static Action? default_for_uri(string uri) {
+ var info = AppInfo. get_default_for_uri_scheme(uri);
+ return new_for_app_info(info);
+ }
+}
+
+}
diff --git a/src/actions/appAction.vala b/src/actions/appAction.vala
new file mode 100644
index 0000000..d8363e4
--- /dev/null
+++ b/src/actions/appAction.vala
@@ -0,0 +1,72 @@
+/*
+Copyright (c) 2011 by Simon Schneegans
+
+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 3 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, see <http://www.gnu.org/licenses/>.
+*/
+
+namespace GnomePie {
+
+/////////////////////////////////////////////////////////////////////////
+/// This type of Action launches an application or a custom command.
+/////////////////////////////////////////////////////////////////////////
+
+public class AppAction : Action {
+
+ /////////////////////////////////////////////////////////////////////
+ /// Used to register this type of Action. It sets the display name
+ /// for this Action, whether it has a custom Icon/Name and the string
+ /// used in the pies.conf file for this kind of Actions.
+ /////////////////////////////////////////////////////////////////////
+
+ public static void register(out string name, out bool icon_name_editable, out string settings_name) {
+ name = _("Launch application");
+ icon_name_editable = true;
+ settings_name = "app";
+ }
+
+ /////////////////////////////////////////////////////////////////////
+ /// Stores the command line.
+ /////////////////////////////////////////////////////////////////////
+
+ public override string real_command { get; construct set; }
+
+ /////////////////////////////////////////////////////////////////////
+ /// Simply returns the real_command. No beautification.
+ /////////////////////////////////////////////////////////////////////
+
+ public override string display_command { get {return real_command;} }
+
+ /////////////////////////////////////////////////////////////////////
+ /// C'tor, initializes all members.
+ /////////////////////////////////////////////////////////////////////
+
+ public AppAction(string name, string icon, string command, bool is_quick_action = false) {
+ GLib.Object(name : name, icon : icon, real_command : command, is_quick_action : is_quick_action);
+ }
+
+ /////////////////////////////////////////////////////////////////////
+ /// Launches the desired command.
+ /////////////////////////////////////////////////////////////////////
+
+ public override void activate() {
+ try{
+ var item = GLib.AppInfo.create_from_commandline(this.real_command, null, GLib.AppInfoCreateFlags.NONE);
+ item.launch(null, null);
+ } catch (Error e) {
+ warning(e.message);
+ }
+ }
+}
+
+}
diff --git a/src/actions/keyAction.vala b/src/actions/keyAction.vala
new file mode 100644
index 0000000..0f6d094
--- /dev/null
+++ b/src/actions/keyAction.vala
@@ -0,0 +1,77 @@
+/*
+Copyright (c) 2011 by Simon Schneegans
+
+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 3 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, see <http://www.gnu.org/licenses/>.
+*/
+
+namespace GnomePie {
+
+/////////////////////////////////////////////////////////////////////////
+/// This type of Action "presses" a key stroke.
+/////////////////////////////////////////////////////////////////////////
+
+public class KeyAction : Action {
+
+ /////////////////////////////////////////////////////////////////////
+ /// Used to register this type of Action. It sets the display name
+ /// for this Action, whether it has a custom Icon/Name and the string
+ /// used in the pies.conf file for this kind of Actions.
+ /////////////////////////////////////////////////////////////////////
+
+ public static void register(out string name, out bool icon_name_editable, out string settings_name) {
+ name = _("Press key stroke");
+ icon_name_editable = true;
+ settings_name = "key";
+ }
+
+ /////////////////////////////////////////////////////////////////////
+ /// Stores the accelerator of this action.
+ /////////////////////////////////////////////////////////////////////
+
+ public override string real_command { get; construct set; }
+
+ /////////////////////////////////////////////////////////////////////
+ /// Returns a human readable form of the accelerator.
+ /////////////////////////////////////////////////////////////////////
+
+ public override string display_command { get {return key.label;} }
+
+ /////////////////////////////////////////////////////////////////////
+ /// The simulated key which gets 'pressed' on execution.
+ /////////////////////////////////////////////////////////////////////
+
+ public Key key { get; set; }
+
+ /////////////////////////////////////////////////////////////////////
+ /// C'tor, initializes all members.
+ /////////////////////////////////////////////////////////////////////
+
+ public KeyAction(string name, string icon, string command, bool is_quick_action = false) {
+ GLib.Object(name : name, icon : icon, real_command : command, is_quick_action : is_quick_action);
+ }
+
+ construct {
+ this.key = new Key(real_command);
+ }
+
+ /////////////////////////////////////////////////////////////////////
+ /// Presses the desired key.
+ /////////////////////////////////////////////////////////////////////
+
+ public override void activate() {
+ key.press();
+ }
+}
+
+}
diff --git a/src/actions/pieAction.vala b/src/actions/pieAction.vala
new file mode 100644
index 0000000..53ea919
--- /dev/null
+++ b/src/actions/pieAction.vala
@@ -0,0 +1,95 @@
+/*
+Copyright (c) 2011 by Simon Schneegans
+
+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 3 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, see <http://www.gnu.org/licenses/>.
+*/
+
+namespace GnomePie {
+
+/////////////////////////////////////////////////////////////////////////
+/// This Action opens another pie.
+/////////////////////////////////////////////////////////////////////////
+
+public class PieAction : Action {
+
+ /////////////////////////////////////////////////////////////////////
+ /// Used to register this type of Action. It sets the display name
+ /// for this Action, whether it has a custom Icon/Name and the string
+ /// used in the pies.conf file for this kind of Actions.
+ /////////////////////////////////////////////////////////////////////
+
+ public static void register(out string name, out bool icon_name_editable, out string settings_name) {
+ name = _("Open Pie");
+ icon_name_editable = false;
+ settings_name = "pie";
+ }
+
+ /////////////////////////////////////////////////////////////////////
+ /// Stores the ID of the referenced Pie.
+ /////////////////////////////////////////////////////////////////////
+
+ public override string real_command { get; construct set; }
+
+ /////////////////////////////////////////////////////////////////////
+ /// Returns the name of the referenced Pie.
+ /////////////////////////////////////////////////////////////////////
+
+ public override string display_command { get {return name;} }
+
+ /////////////////////////////////////////////////////////////////////
+ /// Returns the name of the referenced Pie.
+ /////////////////////////////////////////////////////////////////////
+
+ public override string name {
+ get {
+ var referee = PieManager.all_pies[real_command];
+ if (referee != null)
+ return referee.name;
+ return "";
+ }
+ protected set {}
+ }
+
+ /////////////////////////////////////////////////////////////////////
+ /// Returns the icon of the referenced Pie.
+ /////////////////////////////////////////////////////////////////////
+
+ public override string icon {
+ get {
+ var referee = PieManager.all_pies[real_command];
+ if (referee != null)
+ return referee.icon;
+ return "";
+ }
+ protected set {}
+ }
+
+ /////////////////////////////////////////////////////////////////////
+ /// C'tor, initializes all members.
+ /////////////////////////////////////////////////////////////////////
+
+ public PieAction(string id, bool is_quick_action = false) {
+ GLib.Object(name : "", icon : "", real_command : id, is_quick_action : is_quick_action);
+ }
+
+ /////////////////////////////////////////////////////////////////////
+ /// Opens the desired Pie.
+ /////////////////////////////////////////////////////////////////////
+
+ public override void activate() {
+ PieManager.open_pie(real_command);
+ }
+}
+
+}
diff --git a/src/actions/sigAction.vala b/src/actions/sigAction.vala
new file mode 100644
index 0000000..cec9836
--- /dev/null
+++ b/src/actions/sigAction.vala
@@ -0,0 +1,63 @@
+/*
+Copyright (c) 2011 by Simon Schneegans
+
+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 3 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, see <http://www.gnu.org/licenses/>.
+*/
+
+namespace GnomePie {
+
+/////////////////////////////////////////////////////////////////////////
+/// This type of Action can't be selected by the user, therefore there is
+/// no register() method for this class. But it may be useful for
+/// ActionGroups: It emits a signal on activation.
+/////////////////////////////////////////////////////////////////////////
+
+public class SigAction : Action {
+
+ /////////////////////////////////////////////////////////////////////
+ /// This signal is emitted on activation.
+ /////////////////////////////////////////////////////////////////////
+
+ public signal void activated();
+
+ /////////////////////////////////////////////////////////////////////
+ /// This may store something useful.
+ /////////////////////////////////////////////////////////////////////
+
+ public override string real_command { get; construct set; }
+
+ /////////////////////////////////////////////////////////////////////
+ /// Only for inheritance... Greetings to Liskov.
+ /////////////////////////////////////////////////////////////////////
+
+ public override string display_command { get {return real_command;} }
+
+ /////////////////////////////////////////////////////////////////////
+ /// C'tor, initializes all members.
+ /////////////////////////////////////////////////////////////////////
+
+ public SigAction(string name, string icon, string command, bool is_quick_action = false) {
+ GLib.Object(name : name, icon : icon, real_command : command, is_quick_action : is_quick_action);
+ }
+
+ /////////////////////////////////////////////////////////////////////
+ /// Emits the signal on activation.
+ /////////////////////////////////////////////////////////////////////
+
+ public override void activate() {
+ this.activated();
+ }
+}
+
+}
diff --git a/src/actions/uriAction.vala b/src/actions/uriAction.vala
new file mode 100644
index 0000000..25d5c75
--- /dev/null
+++ b/src/actions/uriAction.vala
@@ -0,0 +1,71 @@
+/*
+Copyright (c) 2011 by Simon Schneegans
+
+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 3 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, see <http://www.gnu.org/licenses/>.
+*/
+
+namespace GnomePie {
+
+/////////////////////////////////////////////////////////////////////////
+/// This type of Action opens the default application for an URI.
+/////////////////////////////////////////////////////////////////////////
+
+public class UriAction : Action {
+
+ /////////////////////////////////////////////////////////////////////
+ /// Used to register this type of Action. It sets the display name
+ /// for this Action, whether it has a custom Icon/Name and the string
+ /// used in the pies.conf file for this kind of Actions.
+ /////////////////////////////////////////////////////////////////////
+
+ public static void register(out string name, out bool icon_name_editable, out string settings_name) {
+ name = _("Open URI");
+ icon_name_editable = true;
+ settings_name = "uri";
+ }
+
+ /////////////////////////////////////////////////////////////////////
+ /// The URI of this Action.
+ /////////////////////////////////////////////////////////////////////
+
+ public override string real_command { get; construct set; }
+
+ /////////////////////////////////////////////////////////////////////
+ /// Returns only the real URI. An URI can't be beautified.
+ /////////////////////////////////////////////////////////////////////
+
+ public override string display_command { get {return real_command;} }
+
+ /////////////////////////////////////////////////////////////////////
+ /// C'tor, initializes all members.
+ /////////////////////////////////////////////////////////////////////
+
+ public UriAction(string name, string icon, string command, bool is_quick_action = false) {
+ GLib.Object(name : name, icon : icon, real_command : command, is_quick_action : is_quick_action);
+ }
+
+ /////////////////////////////////////////////////////////////////////
+ /// Opens the default application for the URI.
+ /////////////////////////////////////////////////////////////////////
+
+ public override void activate() {
+ try{
+ GLib.AppInfo.launch_default_for_uri(real_command, null);
+ } catch (Error e) {
+ warning(e.message);
+ }
+ }
+}
+
+}
diff --git a/src/deamon.vala b/src/deamon.vala
new file mode 100644
index 0000000..af232eb
--- /dev/null
+++ b/src/deamon.vala
@@ -0,0 +1,175 @@
+/*
+Copyright (c) 2011 by Simon Schneegans
+
+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 3 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, see <http://www.gnu.org/licenses/>.
+*/
+
+/////////////////////////////////////////////////////////////////////
+/// TODO-List:
+/// IconSelectWindow
+/// PieList
+/// PieWindow
+/// CenterRenderer
+/// SliceRenderer
+/// PieRenderer
+/////////////////////////////////////////////////////////////////////
+
+namespace GnomePie {
+
+/////////////////////////////////////////////////////////////////////////
+/// This class runs in the background. It has an Indicator sitting in the
+/// user's panel. It initializes everything and guarantees that there is
+/// only one instance of Gnome-Pie running.
+/////////////////////////////////////////////////////////////////////////
+
+public class Deamon : GLib.Object {
+
+ /////////////////////////////////////////////////////////////////////
+ /// The beginning of everything.
+ /////////////////////////////////////////////////////////////////////
+
+ public static int main(string[] args) {
+ Logger.init();
+ Gtk.init(ref args);
+ Paths.init();
+
+ // create the Deamon and run it
+ var deamon = new GnomePie.Deamon();
+ deamon.run(args);
+
+ return 0;
+ }
+
+ /////////////////////////////////////////////////////////////////////
+ /// The AppIndicator of Gnome-Pie.
+ /////////////////////////////////////////////////////////////////////
+
+ private Indicator indicator = null;
+
+ /////////////////////////////////////////////////////////////////////
+ /// Varaibles set by the commend line parser.
+ /////////////////////////////////////////////////////////////////////
+
+ private static string open_pie = null;
+ private static bool reset = false;
+
+ /////////////////////////////////////////////////////////////////////
+ /// Available command line options.
+ /////////////////////////////////////////////////////////////////////
+
+ private const GLib.OptionEntry[] options = {
+ { "open", 'o', 0, GLib.OptionArg.STRING, out open_pie,
+ "Open the Pie with the given ID", "ID" },
+ { "reset", 'r', 0, GLib.OptionArg.NONE, out reset,
+ "Reset all options to default values" },
+ { null }
+ };
+
+ /////////////////////////////////////////////////////////////////////
+ /// C'tor of the Deamon. It checks whether it's the firts running
+ /// instance of Gnome-Pie.
+ /////////////////////////////////////////////////////////////////////
+
+ public void run(string[] args) {
+ // create command line options
+ var context = new GLib.OptionContext("");
+ context.set_help_enabled(true);
+ context.add_main_entries(options, null);
+ context.add_group(Gtk.get_option_group (false));
+
+ try {
+ context.parse(ref args);
+ } catch(GLib.OptionError error) {
+ warning(error.message);
+ }
+
+ if (this.reset) {
+ if (GLib.FileUtils.remove(Paths.pie_config) == 0)
+ message("Removed file \"%s\"", Paths.pie_config);
+ if (GLib.FileUtils.remove(Paths.settings) == 0)
+ message("Removed file \"%s\"", Paths.settings);
+ return;
+ }
+
+ // create unique application
+ var app = new Unique.App("org.gnome.gnomepie", null);
+
+ if (app.is_running) {
+ // inform the running instance of the pie to be opened
+ if (open_pie != null) {
+ var data = new Unique.MessageData();
+ data.set_text(open_pie, open_pie.length);
+ app.send_message(Unique.Command.ACTIVATE, data);
+ return;
+ }
+
+ app.send_message(Unique.Command.ACTIVATE, null);
+ return;
+ }
+
+ // wait for incoming messages
+ app.message_received.connect((cmd, data, event_time) => {
+ if (cmd == Unique.Command.ACTIVATE) {
+ var pie = data.get_text();
+
+ if (pie != "") PieManager.open_pie(pie);
+ else this.indicator.show_preferences();
+
+ return Unique.Response.OK;
+ }
+
+ return Unique.Response.PASSTHROUGH;
+ });
+
+ // init toolkits and static stuff
+ Gdk.threads_init();
+ ActionRegistry.init();
+ GroupRegistry.init();
+ PieManager.init();
+ Icon.init();
+ ThemedIcon.init();
+ RenderedText.init();
+
+ // init locale support
+ Intl.bindtextdomain ("gnomepie", Paths.locales);
+ Intl.textdomain ("gnomepie");
+
+ // launch the indicator
+ this.indicator = new Indicator();
+
+ // connect SigHandlers
+ Posix.signal(Posix.SIGINT, sig_handler);
+ Posix.signal(Posix.SIGTERM, sig_handler);
+
+ // finished loading... so run the prog!
+ message("Started happily...");
+
+ // open pie if neccessary
+ if (open_pie != null) PieManager.open_pie(open_pie);
+
+ Gtk.main();
+ }
+
+ /////////////////////////////////////////////////////////////////////
+ /// Print a nifty message when the prog is killed.
+ /////////////////////////////////////////////////////////////////////
+
+ private static void sig_handler(int sig) {
+ stdout.printf("\n");
+ message("Caught signal (%d), bye!".printf(sig));
+ Gtk.main_quit();
+ }
+}
+
+}
diff --git a/src/gui/about.vala b/src/gui/about.vala
new file mode 100644
index 0000000..1ace9cb
--- /dev/null
+++ b/src/gui/about.vala
@@ -0,0 +1,43 @@
+/*
+Copyright (c) 2011 by Simon Schneegans
+
+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 3 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, see <http://www.gnu.org/licenses/>.
+*/
+
+namespace GnomePie {
+
+/////////////////////////////////////////////////////////////////////////
+/// A simple about Dialog.
+/////////////////////////////////////////////////////////////////////////
+
+public class GnomePieAboutDialog: Gtk.AboutDialog {
+
+ public GnomePieAboutDialog () {
+ string[] devs = {"Simon Schneegans <code@simonschneegans.de>",
+ "Francesco Piccinno"};
+ string[] artists = {"Simon Schneegans <code@simonschneegans.de>"};
+ GLib.Object (
+ artists : artists,
+ authors : devs,
+ copyright : "Copyright (C) 2011 Simon Schneegans <code@simonschneegans.de>",
+ program_name: "Gnome-Pie",
+ logo_icon_name: "gnome-pie",
+ website: "http://www.simonschneegans.de/?page_id=12",
+ website_label: "www.gnome-pie.simonschneegans.de",
+ version: "0.2"
+ );
+ }
+}
+
+}
diff --git a/src/gui/cellRendererIcon.vala b/src/gui/cellRendererIcon.vala
new file mode 100644
index 0000000..959a0b7
--- /dev/null
+++ b/src/gui/cellRendererIcon.vala
@@ -0,0 +1,132 @@
+/*
+Copyright (c) 2011 by Simon Schneegans
+
+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 3 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, see <http://www.gnu.org/licenses/>.
+*/
+
+namespace GnomePie {
+
+/////////////////////////////////////////////////////////////////////////
+/// A cellrenderer which displays an Icon. When clicked onto, a window
+/// opens for selecting another icon. This needs to be a subclass of
+/// Gtk.CellRendererText because Gtk.CellRendererPixbuf can't receive
+/// click events. Internally it stores a Gtk.CellRendererPixbuf
+/// which renders and stuff.
+/////////////////////////////////////////////////////////////////////////
+
+public class CellRendererIcon : Gtk.CellRendererText {
+
+ /////////////////////////////////////////////////////////////////////
+ /// This signal is emitted when the user selects another icon.
+ /////////////////////////////////////////////////////////////////////
+
+ public signal void on_select(string path, string icon);
+
+ /////////////////////////////////////////////////////////////////////
+ /// The IconSelectWindow which is shown on click.
+ /////////////////////////////////////////////////////////////////////
+
+ private IconSelectWindow select_window = null;
+
+ /////////////////////////////////////////////////////////////////////
+ /// The internal Renderer used for drawing.
+ /////////////////////////////////////////////////////////////////////
+
+ private Gtk.CellRendererPixbuf renderer = null;
+
+ /////////////////////////////////////////////////////////////////////
+ /// A helper variable, needed to emit the current path.
+ /////////////////////////////////////////////////////////////////////
+
+ private string current_path = "";
+
+ public string icon_name { get; set; }
+
+ /////////////////////////////////////////////////////////////////////
+ /// Forward some parts of the CellRendererPixbuf's interface.
+ /////////////////////////////////////////////////////////////////////
+
+ public bool follow_state {
+ get { return renderer.follow_state; }
+ set { renderer.follow_state = value; }
+ }
+
+ public bool icon_sensitive {
+ get { return renderer.sensitive; }
+ set { renderer.sensitive = value; }
+ }
+
+ public Gdk.Pixbuf pixbuf {
+ owned get { return renderer.pixbuf; }
+ set { renderer.pixbuf = value; }
+ }
+
+ /////////////////////////////////////////////////////////////////////
+ /// C'tor, creates a new CellRendererIcon.
+ /////////////////////////////////////////////////////////////////////
+
+ public CellRendererIcon() {
+ this.select_window = new IconSelectWindow();
+ this.renderer = new Gtk.CellRendererPixbuf();
+
+ this.select_window.on_select.connect((icon) => {
+ this.on_select(current_path, icon);
+ });
+ }
+
+ /////////////////////////////////////////////////////////////////////
+ /// Forward some parts of the CellRendererPixbuf's interface.
+ /////////////////////////////////////////////////////////////////////
+
+ public override void get_size (Gtk.Widget widget, Gdk.Rectangle? cell_area,
+ out int x_offset, out int y_offset,
+ out int width, out int height) {
+
+ this.renderer.get_size(widget, cell_area, out x_offset, out y_offset, out width, out height);
+ }
+
+ /////////////////////////////////////////////////////////////////////
+ /// Forward some parts of the CellRendererPixbuf's interface.
+ /////////////////////////////////////////////////////////////////////
+
+ public override void render (Gdk.Window window, Gtk.Widget widget,
+ Gdk.Rectangle bg_area,
+ Gdk.Rectangle cell_area,
+ Gdk.Rectangle expose_area,
+ Gtk.CellRendererState flags) {
+
+ this.renderer.render(window, widget, bg_area, cell_area, expose_area, flags);
+ }
+
+ /////////////////////////////////////////////////////////////////////
+ /// Open the IconSelectWindow on click.
+ /////////////////////////////////////////////////////////////////////
+
+ public override unowned Gtk.CellEditable start_editing(
+ Gdk.Event event, Gtk.Widget widget, string path, Gdk.Rectangle bg_area,
+ Gdk.Rectangle cell_area, Gtk.CellRendererState flags) {
+
+ this.select_window.set_transient_for((Gtk.Window)widget.get_toplevel());
+ this.select_window.set_modal(true);
+
+ this.current_path = path;
+ this.select_window.show();
+ this.select_window.active_icon = this.icon_name;
+
+ return this.renderer.start_editing(event, widget, path, bg_area, cell_area, flags);
+ }
+}
+
+}
+
diff --git a/src/gui/iconSelectWindow.vala b/src/gui/iconSelectWindow.vala
new file mode 100644
index 0000000..2274ec5
--- /dev/null
+++ b/src/gui/iconSelectWindow.vala
@@ -0,0 +1,349 @@
+/*
+Copyright (c) 2011 by Simon Schneegans
+
+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 3 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, see <http://www.gnu.org/licenses/>.
+*/
+
+namespace GnomePie {
+
+/////////////////////////////////////////////////////////////////////////
+/// A window which allows selection of an Icon of the user's current icon
+/// theme. Loading of Icons happens in an extra thread and a spinner is
+/// displayed while loading.
+/////////////////////////////////////////////////////////////////////////
+
+public class IconSelectWindow : Gtk.Dialog {
+
+ private static Gtk.ListStore icon_list = null;
+
+ private static bool loading {get; set; default = false;}
+ private static bool need_reload {get; set; default = true;}
+
+ private const string disabled_contexts = "Animations, FileSystems, MimeTypes";
+ private Gtk.TreeModelFilter icon_list_filtered = null;
+ private Gtk.IconView icon_view = null;
+ private Gtk.Spinner spinner = null;
+
+ private Gtk.FileChooserWidget file_chooser = null;
+
+ private Gtk.Notebook tabs = null;
+
+ private class ListEntry {
+ public string name;
+ public IconContext context;
+ public Gdk.Pixbuf pixbuf;
+ }
+
+ private GLib.AsyncQueue<ListEntry?> load_queue;
+
+ private enum IconContext {
+ ALL,
+ APPS,
+ ACTIONS,
+ PLACES,
+ FILES,
+ EMOTES,
+ OTHER
+ }
+
+ public string _active_icon = "application-default-icon";
+
+ public string active_icon {
+ get {
+ return _active_icon;
+ }
+ set {
+ if (value.contains("/")) {
+ this.file_chooser.set_filename(value);
+ this.tabs.set_current_page(1);
+ } else {
+ this.icon_list_filtered.foreach((model, path, iter) => {
+ string name = "";
+ model.get(iter, 0, out name);
+
+ if (name == value) {
+ this.icon_view.select_path(path);
+ this.icon_view.scroll_to_path(path, true, 0.5f, 0.0f);
+ this.icon_view.set_cursor(path, null, false);
+ }
+ return (name == value);
+ });
+
+ this.tabs.set_current_page(0);
+ }
+ }
+ }
+
+ public signal void on_select(string icon_name);
+
+ public IconSelectWindow() {
+ this.title = _("Choose an Icon");
+ this.set_size_request(520, 520);
+ this.delete_event.connect(hide_on_delete);
+ this.load_queue = new GLib.AsyncQueue<ListEntry?>();
+
+ if (this.icon_list == null) {
+ this.icon_list = new Gtk.ListStore(3, typeof(string), typeof(IconContext), typeof(Gdk.Pixbuf));
+ this.icon_list.set_default_sort_func(() => {return 0;});
+
+ Gtk.IconTheme.get_default().changed.connect(() => {
+ if (this.visible) load_icons();
+ else need_reload = true;
+ });
+ }
+
+ this.icon_list_filtered = new Gtk.TreeModelFilter(this.icon_list, null);
+
+ var container = new Gtk.VBox(false, 12);
+ container.set_border_width(12);
+
+ // tab container
+ this.tabs = new Gtk.Notebook();
+
+ var theme_tab = new Gtk.VBox(false, 12);
+ theme_tab.set_border_width(12);
+
+ var context_combo = new Gtk.ComboBox.text();
+ context_combo.append_text(_("All icons"));
+ context_combo.append_text(_("Applications"));
+ context_combo.append_text(_("Actions"));
+ context_combo.append_text(_("Places"));
+ context_combo.append_text(_("File types"));
+ context_combo.append_text(_("Emotes"));
+ context_combo.append_text(_("Miscellaneous"));
+
+ context_combo.set_active(0);
+
+ context_combo.changed.connect(() => {
+ this.icon_list_filtered.refilter();
+ });
+
+ theme_tab.pack_start(context_combo, false, false);
+
+ var filter = new Gtk.Entry();
+ filter.primary_icon_stock = Gtk.Stock.FIND;
+ filter.primary_icon_activatable = false;
+ filter.secondary_icon_stock = Gtk.Stock.CLEAR;
+ theme_tab.pack_start(filter, false, false);
+
+ this.icon_list_filtered.set_visible_func((model, iter) => {
+ string name = "";
+ IconContext context = IconContext.ALL;
+ model.get(iter, 0, out name);
+ model.get(iter, 1, out context);
+
+ if (name == null) return false;
+
+ return (context_combo.get_active() == context ||
+ context_combo.get_active() == IconContext.ALL) &&
+ name.down().contains(filter.text.down());
+ });
+
+ filter.icon_release.connect((pos, event) => {
+ if (pos == Gtk.EntryIconPosition.SECONDARY)
+ filter.text = "";
+ });
+
+ filter.notify["text"].connect(() => {
+ this.icon_list_filtered.refilter();
+ });
+
+ var scroll = new Gtk.ScrolledWindow (null, null);
+ scroll.set_policy (Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC);
+ scroll.set_shadow_type (Gtk.ShadowType.IN);
+
+ this.icon_view = new Gtk.IconView.with_model(this.icon_list_filtered);
+ this.icon_view.item_width = 32;
+ this.icon_view.item_padding = 3;
+ this.icon_view.pixbuf_column = 2;
+ this.icon_view.tooltip_column = 0;
+
+ this.icon_view.selection_changed.connect(() => {
+ foreach (var path in this.icon_view.get_selected_items()) {
+ Gtk.TreeIter iter;
+ this.icon_list_filtered.get_iter(out iter, path);
+ icon_list_filtered.get(iter, 0, out this._active_icon);
+ }
+ });
+
+ this.icon_view.item_activated.connect((path) => {
+ Gtk.TreeIter iter;
+ this.icon_list_filtered.get_iter(out iter, path);
+ this.icon_list_filtered.get(iter, 0, out this._active_icon);
+ this.on_select(this._active_icon);
+ this.hide();
+ });
+
+ scroll.add(this.icon_view);
+
+ theme_tab.pack_start(scroll, true, true);
+
+ tabs.append_page(theme_tab, new Gtk.Label(_("Icon Theme")));
+
+ var custom_tab = new Gtk.VBox(false, 6);
+ custom_tab.border_width = 12;
+
+ this.file_chooser = new Gtk.FileChooserWidget(Gtk.FileChooserAction.OPEN);
+ var file_filter = new Gtk.FileFilter();
+ file_filter.add_pixbuf_formats();
+ file_filter.set_name(_("All supported image formats"));
+ file_chooser.add_filter(file_filter);
+
+ file_chooser.selection_changed.connect(() => {
+ if (file_chooser.get_filename() != null && GLib.FileUtils.test(file_chooser.get_filename(), GLib.FileTest.IS_REGULAR))
+ this._active_icon = file_chooser.get_filename();
+ });
+
+ file_chooser.file_activated.connect(() => {
+ this._active_icon = file_chooser.get_filename();
+ this.on_select(this._active_icon);
+ this.hide();
+ });
+
+
+ custom_tab.pack_start(file_chooser, true, true);
+
+ tabs.append_page(custom_tab, new Gtk.Label(_("Custom Icon")));
+
+ container.pack_start(tabs, true, true);
+
+ // button box
+ var bottom_box = new Gtk.HBox(false, 0);
+
+ var bbox = new Gtk.HButtonBox();
+ bbox.set_spacing(6);
+ bbox.set_layout(Gtk.ButtonBoxStyle.END);
+
+ var cancel_button = new Gtk.Button.from_stock(Gtk.Stock.CANCEL);
+ cancel_button.clicked.connect(() => {
+ this.hide();
+ });
+ bbox.pack_start(cancel_button);
+
+ var ok_button = new Gtk.Button.from_stock(Gtk.Stock.OK);
+ ok_button.clicked.connect(() => {
+ this.on_select(this._active_icon);
+ this.hide();
+ });
+ bbox.pack_start(ok_button);
+
+ bottom_box.pack_end(bbox, false);
+
+ this.spinner = new Gtk.Spinner();
+ this.spinner.set_size_request(16, 16);
+ this.spinner.start();
+
+ bottom_box.pack_start(this.spinner, false, false);
+
+ container.pack_start(bottom_box, false, false);
+
+ this.vbox.pack_start(container, true, true);
+
+ this.vbox.show_all();
+
+ this.set_focus(this.icon_view);
+ }
+
+ public override void show() {
+ base.show();
+ this.action_area.hide();
+
+ if (this.need_reload) {
+ this.need_reload = false;
+ this.load_icons();
+ }
+ }
+
+ private void load_icons() {
+ if (!this.loading) {
+ this.loading = true;
+ this.icon_list.clear();
+
+ if (spinner != null)
+ this.spinner.visible = true;
+
+ this.icon_list.set_sort_column_id(-1, Gtk.SortType.ASCENDING);
+
+ try {
+ unowned Thread loader = Thread.create<void*>(load_thread, false);
+ loader.set_priority(ThreadPriority.LOW);
+ } catch (GLib.ThreadError e) {
+ error("Failed to create icon loader thread!");
+ }
+
+ Timeout.add(200, () => {
+ while (this.load_queue.length() > 0) {
+ var new_entry = this.load_queue.pop();
+ Gtk.TreeIter current;
+ this.icon_list.append(out current);
+ this.icon_list.set(current, 0, new_entry.name,
+ 1, new_entry.context,
+ 2, new_entry.pixbuf);
+ }
+
+ if (!this.loading) this.icon_list.set_sort_column_id(0, Gtk.SortType.ASCENDING);
+
+ return loading;
+ });
+ }
+ }
+
+ private void* load_thread() {
+ var icon_theme = Gtk.IconTheme.get_default();
+
+ foreach (var context in icon_theme.list_contexts()) {
+ if (!disabled_contexts.contains(context)) {
+ foreach (var icon in icon_theme.list_icons(context)) {
+ IconContext icon_context = IconContext.OTHER;
+ switch(context) {
+ case "Apps": case "Applications":
+ icon_context = IconContext.APPS; break;
+ case "Emotes":
+ icon_context = IconContext.EMOTES; break;
+ case "Places": case "Devices":
+ icon_context = IconContext.PLACES; break;
+ case "Mimetypes":
+ icon_context = IconContext.FILES; break;
+ case "Actions":
+ icon_context = IconContext.ACTIONS; break;
+ default: break;
+ }
+
+ try {
+ var new_entry = new ListEntry();
+ new_entry.name = icon;
+ new_entry.context = icon_context;
+ new_entry.pixbuf = icon_theme.load_icon(icon, 32, 0);
+
+ // some icons have only weird sizes... do not include them
+ if (new_entry.pixbuf.width == 32)
+ this.load_queue.push(new_entry);
+
+ } catch (GLib.Error e) {
+ warning("Failed to load image " + icon);
+ }
+ }
+ }
+ }
+
+ this.loading = false;
+
+ if (spinner != null)
+ spinner.visible = this.loading;
+
+ return null;
+ }
+}
+
+}
diff --git a/src/gui/indicator.vala b/src/gui/indicator.vala
new file mode 100644
index 0000000..8033cb7
--- /dev/null
+++ b/src/gui/indicator.vala
@@ -0,0 +1,160 @@
+/*
+Copyright (c) 2011 by Simon Schneegans
+
+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 3 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, see <http://www.gnu.org/licenses/>.
+*/
+
+namespace GnomePie {
+
+/////////////////////////////////////////////////////////////////////////
+/// An appindicator sitting in the panel. It owns the settings menu.
+/////////////////////////////////////////////////////////////////////////
+
+public class Indicator : GLib.Object {
+
+ /////////////////////////////////////////////////////////////////////
+ /// The internally used indicator.
+ /////////////////////////////////////////////////////////////////////
+
+ #if HAVE_APPINDICATOR
+ private AppIndicator.Indicator indicator { private get; private set; }
+ #else
+ private Gtk.StatusIcon indicator {private get; private set; }
+ private Gtk.Menu menu {private get; private set; }
+ #endif
+
+ /////////////////////////////////////////////////////////////////////
+ /// The Preferences Menu of Gnome-Pie.
+ /////////////////////////////////////////////////////////////////////
+
+ private Preferences prefs { private get; private set; }
+
+ /////////////////////////////////////////////////////////////////////
+ /// Returns true, when the indicator is currently visible.
+ /////////////////////////////////////////////////////////////////////
+
+ public bool active {
+ get {
+
+ #if HAVE_APPINDICATOR
+ return indicator.get_status() == AppIndicator.IndicatorStatus.ACTIVE;
+ #else
+ return indicator.get_visible();
+ #endif
+ }
+ set {
+ #if HAVE_APPINDICATOR
+ if (value) indicator.set_status(AppIndicator.IndicatorStatus.ACTIVE);
+ else indicator.set_status(AppIndicator.IndicatorStatus.PASSIVE);
+ #else
+ indicator.set_visible(value);
+ #endif
+ }
+ }
+
+ /////////////////////////////////////////////////////////////////////
+ /// C'tor, constructs a new Indicator, residing in the user's panel.
+ /////////////////////////////////////////////////////////////////////
+
+ public Indicator() {
+ #if HAVE_APPINDICATOR
+ string path = "";
+ string icon = "indicator-applet";
+ try {
+ path = GLib.Path.get_dirname(GLib.FileUtils.read_link("/proc/self/exe"))+"/resources";
+ icon = "gnome-pie-indicator";
+ } catch (GLib.FileError e) {
+ warning("Failed to get path of executable!");
+ }
+
+ this.indicator = new AppIndicator.Indicator.with_path("Gnome-Pie", icon,
+ AppIndicator.IndicatorCategory.APPLICATION_STATUS, path);
+ var menu = new Gtk.Menu();
+ #else
+ this.indicator = new Gtk.StatusIcon();
+ try {
+ var file = GLib.File.new_for_path(GLib.Path.build_filename(
+ GLib.Path.get_dirname(GLib.FileUtils.read_link("/proc/self/exe"))+"/resources",
+ "gnome-pie-indicator.svg"
+ ));
+
+ if (!file.query_exists())
+ this.indicator.set_from_icon_name("gnome-pie-indicator");
+ else
+ this.indicator.set_from_file(file.get_path());
+ } catch (GLib.FileError e) {
+ warning("Failed to get path of executable!");
+ this.indicator.set_from_icon_name("gnome-pie-indicator");
+ }
+
+ this.menu = new Gtk.Menu();
+ var menu = this.menu;
+ #endif
+
+ this.prefs = new Preferences();
+
+ // preferences item
+ var item = new Gtk.ImageMenuItem.from_stock (Gtk.Stock.PREFERENCES, null);
+ item.activate.connect(() => {
+ this.prefs.show();
+ });
+
+ item.show();
+ menu.append(item);
+
+ // about item
+ item = new Gtk.ImageMenuItem.from_stock (Gtk.Stock.ABOUT, null);
+ item.show();
+ item.activate.connect(() => {
+ var about = new GnomePieAboutDialog();
+ about.run();
+ about.destroy();
+ });
+ menu.append(item);
+
+ // separator
+ var sepa = new Gtk.SeparatorMenuItem();
+ sepa.show();
+ menu.append(sepa);
+
+ // quit item
+ item = new Gtk.ImageMenuItem.from_stock(Gtk.Stock.QUIT, null);
+ item.activate.connect(Gtk.main_quit);
+ item.show();
+ menu.append(item);
+
+ #if HAVE_APPINDICATOR
+ this.indicator.set_menu(menu);
+ #else
+ this.indicator.popup_menu.connect((btn, time) => {
+ this.menu.popup(null, null, null, btn, time);
+ });
+ #endif
+
+ this.active = Config.global.show_indicator;
+ Config.global.notify["show-indicator"].connect((s, p) => {
+ this.active = Config.global.show_indicator;
+ });
+ }
+
+ /////////////////////////////////////////////////////////////////////
+ /// Shows the preferences menu.
+ /////////////////////////////////////////////////////////////////////
+
+ public void show_preferences() {
+ this.prefs.show();
+ }
+}
+
+}
diff --git a/src/gui/pieList.vala b/src/gui/pieList.vala
new file mode 100644
index 0000000..df6135a
--- /dev/null
+++ b/src/gui/pieList.vala
@@ -0,0 +1,1018 @@
+/*
+Copyright (c) 2011 by Simon Schneegans
+
+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 3 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, see <http://www.gnu.org/licenses/>.
+*/
+
+namespace GnomePie {
+
+// A very complex Widget. This is by far the most ugly file of this project
+// but well, this list *is* complex... sorry ;)
+
+class PieList : Gtk.TreeView {
+
+ private Gtk.ListStore groups;
+ private Gtk.ListStore pies;
+ private Gtk.ListStore actions;
+ private Gtk.TreeStore data;
+
+ private const int small_icon = 24;
+ private const int large_icon = 36;
+
+ // data positions in the data ListStore
+ private enum DataPos {IS_QUICKACTION, ICON, NAME, TYPE_ID, ACTION_TYPE,
+ ICON_PIXBUF, FONT_WEIGHT, ICON_NAME_EDITABLE, QUICKACTION_VISIBLE, QUICKACTION_ACTIVATABLE,
+ TYPE_VISIBLE, GROUP_VISIBLE, APP_VISIBLE, KEY_VISIBLE, PIE_VISIBLE,
+ URI_VISIBLE, DISPLAY_COMMAND_GROUP, DISPLAY_COMMAND_APP,
+ DISPLAY_COMMAND_KEY, DISPLAY_COMMAND_PIE, DISPLAY_COMMAND_URI,
+ REAL_COMMAND_GROUP, REAL_COMMAND_PIE, REAL_COMMAND_KEY}
+
+ // data positions in the actions ListStore
+ private enum ActionPos {NAME, TYPE, CAN_QUICKACTION, ICON_NAME_EDITABLE}
+
+ // data positions in the pies ListStore
+ private enum PiePos {NAME, ID}
+
+ // data positions in the groups ListStore
+ private enum GroupPos {NAME, TYPE, ICON}
+
+ public PieList() {
+ GLib.Object();
+
+ Gtk.TreeIter last;
+
+ // group choices
+ this.groups = new Gtk.ListStore(3, typeof(string), // group name
+ typeof(string), // group type
+ typeof(string)); // group icon
+
+ // add all registered group types
+ foreach (var type in GroupRegistry.types) {
+ this.groups.append(out last);
+ this.groups.set(last, GroupPos.NAME, GroupRegistry.names[type],
+ GroupPos.TYPE, type.name(),
+ GroupPos.ICON, GroupRegistry.icons[type]);
+ }
+
+ // pie choices
+ this.pies = new Gtk.ListStore(2, typeof(string), // pie name
+ typeof(string)); // pie id
+
+ // action type choices
+ this.actions = new Gtk.ListStore(4, typeof(string), // type name
+ typeof(string), // action type
+ typeof(bool), // can be quickaction
+ typeof(bool)); // icon/name editable
+
+ // add all registered action types
+ foreach (var type in ActionRegistry.types) {
+ this.actions.append(out last);
+ this.actions.set(last, ActionPos.NAME, ActionRegistry.names[type],
+ ActionPos.TYPE, type.name(),
+ ActionPos.CAN_QUICKACTION, true,
+ ActionPos.ICON_NAME_EDITABLE, ActionRegistry.icon_name_editables[type]);
+ }
+ // and one type for groups
+ this.actions.append(out last);
+ this.actions.set(last, ActionPos.NAME, _("Slice group"),
+ ActionPos.TYPE, typeof(ActionGroup).name(),
+ ActionPos.CAN_QUICKACTION, false,
+ ActionPos.ICON_NAME_EDITABLE, false);
+
+ // main data model
+ this.data = new Gtk.TreeStore(24, typeof(bool), // is quickaction
+ typeof(string), // icon
+ typeof(string), // name
+ typeof(string), // slice: type label, pie: "ID: %id"
+ typeof(string), // typeof(action), typeof(ActionGroup).name() if group action, pie_id if Pie
+
+ typeof(Gdk.Pixbuf), // icon pixbuf
+ typeof(int), // font weight
+
+ typeof(bool), // icon/name editable
+
+ typeof(bool), // quickaction visible
+ typeof(bool), // quickaction activatable
+ typeof(bool), // type visible
+ typeof(bool), // group renderer visible
+ typeof(bool), // app renderer visible
+ typeof(bool), // key renderer visible
+ typeof(bool), // pie renderer visible
+ typeof(bool), // uri renderer visible
+
+ typeof(string), // display command group
+ typeof(string), // display command app
+ typeof(string), // display command key
+ typeof(string), // display command pie
+ typeof(string), // display command uri
+
+ typeof(string), // real command group
+ typeof(string), // real command pie
+ typeof(string)); // real command key
+
+
+ this.set_model(this.data);
+ this.set_grid_lines(Gtk.TreeViewGridLines.NONE);
+ this.set_enable_tree_lines(false);
+ this.set_reorderable(false);
+ this.set_level_indentation(-10);
+
+ // create the gui
+ // icon column
+ var icon_column = new Gtk.TreeViewColumn();
+ icon_column.title = _("Icon");
+ icon_column.expand = false;
+
+ // quickaction checkbox
+ var check_render = new Gtk.CellRendererToggle();
+ check_render.activatable = true;
+ check_render.radio = true;
+ check_render.width = 15;
+
+ check_render.toggled.connect((path) => {
+ Gtk.TreeIter toggled;
+ this.data.get_iter_from_string(out toggled, path);
+
+ bool current = false;
+ this.data.get(toggled, DataPos.IS_QUICKACTION, out current);
+
+ // set all others off
+ Gtk.TreeIter parent;
+ this.data.iter_parent(out parent, toggled);
+ string parent_pos = this.data.get_string_from_iter(parent);
+ int child_count = this.data.iter_n_children(parent);
+
+ for (int i=0; i<child_count; ++i) {
+ Gtk.TreeIter child;
+ this.data.get_iter_from_string(out child, "%s:%d".printf(parent_pos, i));
+ this.data.set(child, DataPos.IS_QUICKACTION, false);
+ }
+
+ // toggle selected
+ this.data.set(toggled, DataPos.IS_QUICKACTION, !current);
+
+ this.update_pie(toggled);
+ });
+
+ icon_column.pack_start(check_render, false);
+ icon_column.add_attribute(check_render, "activatable", DataPos.QUICKACTION_ACTIVATABLE);
+ icon_column.add_attribute(check_render, "sensitive", DataPos.QUICKACTION_ACTIVATABLE);
+ icon_column.add_attribute(check_render, "visible", DataPos.QUICKACTION_VISIBLE);
+ icon_column.add_attribute(check_render, "active", DataPos.IS_QUICKACTION);
+
+
+ // icon
+ var icon_render = new GnomePie.CellRendererIcon();
+ icon_render.editable = true;
+
+ icon_render.on_select.connect((path, icon_name) => {
+ Gtk.TreeIter iter;
+ this.data.get_iter_from_string(out iter, path);
+ int icon_size = this.data.iter_depth(iter) == 0 ? this.large_icon : this.small_icon;
+
+ this.data.set(iter, DataPos.ICON, icon_name);
+ this.data.set(iter, DataPos.ICON_PIXBUF, this.load_icon(icon_name, icon_size));
+
+ this.update_pie(iter);
+ this.update_linked();
+ });
+
+ icon_column.pack_start(icon_render, false);
+ icon_column.add_attribute(icon_render, "icon_name", DataPos.ICON);
+ icon_column.add_attribute(icon_render, "pixbuf", DataPos.ICON_PIXBUF);
+ icon_column.add_attribute(icon_render, "editable", DataPos.ICON_NAME_EDITABLE);
+ icon_column.add_attribute(icon_render, "icon_sensitive", DataPos.ICON_NAME_EDITABLE);
+
+ // command column
+ var command_column = new Gtk.TreeViewColumn();
+ command_column.title = _("Command");
+ command_column.resizable = true;
+
+ // slice group
+ var command_renderer_group = new Gtk.CellRendererCombo();
+ command_renderer_group.editable = true;
+ command_renderer_group.has_entry = false;
+ command_renderer_group.text_column = 0;
+ command_renderer_group.ellipsize = Pango.EllipsizeMode.END;
+ command_renderer_group.model = this.groups;
+
+ command_renderer_group.changed.connect((path, iter) => {
+ string display_name;
+ string type;
+ string icon;
+
+ this.groups.get(iter, GroupPos.NAME, out display_name);
+ this.groups.get(iter, GroupPos.TYPE, out type);
+ this.groups.get(iter, GroupPos.ICON, out icon);
+
+ Gtk.TreeIter data_iter;
+ this.data.get_iter_from_string(out data_iter, path);
+
+ this.data.set(data_iter, DataPos.DISPLAY_COMMAND_GROUP, display_name);
+ this.data.set(data_iter, DataPos.REAL_COMMAND_GROUP, type);
+ this.data.set(data_iter, DataPos.NAME, display_name);
+ this.data.set(data_iter, DataPos.ICON, icon);
+
+ this.update_pie(data_iter);
+ });
+
+ command_column.pack_end(command_renderer_group, true);
+ command_column.add_attribute(command_renderer_group, "weight", DataPos.FONT_WEIGHT);
+ command_column.add_attribute(command_renderer_group, "text", DataPos.DISPLAY_COMMAND_GROUP);
+ command_column.add_attribute(command_renderer_group, "visible", DataPos.GROUP_VISIBLE);
+
+
+ // app action
+ var command_renderer_app = new Gtk.CellRendererText();
+ command_renderer_app.editable = true;
+ command_renderer_app.ellipsize = Pango.EllipsizeMode.END;
+
+ command_renderer_app.edited.connect((path, command) => {
+ Gtk.TreeIter data_iter;
+ this.data.get_iter_from_string(out data_iter, path);
+
+ this.data.set(data_iter, DataPos.DISPLAY_COMMAND_APP, command);
+
+ this.update_pie(data_iter);
+ });
+
+ command_column.pack_end(command_renderer_app, true);
+ command_column.add_attribute(command_renderer_app, "weight", DataPos.FONT_WEIGHT);
+ command_column.add_attribute(command_renderer_app, "text", DataPos.DISPLAY_COMMAND_APP);
+ command_column.add_attribute(command_renderer_app, "visible", DataPos.APP_VISIBLE);
+
+
+ // key action
+ var command_renderer_key = new Gtk.CellRendererAccel();
+ command_renderer_key.editable = true;
+ command_renderer_key.ellipsize = Pango.EllipsizeMode.END;
+
+ command_renderer_key.accel_edited.connect((path, key, mods) => {
+ Gtk.TreeIter data_iter;
+ this.data.get_iter_from_string(out data_iter, path);
+
+ string label = Gtk.accelerator_get_label(key, mods);
+ string accelerator = Gtk.accelerator_name(key, mods);
+
+ this.data.set(data_iter, DataPos.DISPLAY_COMMAND_KEY, label);
+ this.data.set(data_iter, DataPos.REAL_COMMAND_KEY, accelerator);
+
+ this.update_pie(data_iter);
+ });
+
+ command_renderer_key.accel_cleared.connect((path) => {
+ Gtk.TreeIter data_iter;
+ this.data.get_iter_from_string(out data_iter, path);
+
+ this.data.set(data_iter, DataPos.DISPLAY_COMMAND_KEY, _("Not bound"));
+ this.data.set(data_iter, DataPos.REAL_COMMAND_KEY, "");
+
+ this.update_pie(data_iter);
+ });
+
+ command_column.pack_end(command_renderer_key, true);
+ command_column.add_attribute(command_renderer_key, "weight", DataPos.FONT_WEIGHT);
+ command_column.add_attribute(command_renderer_key, "text", DataPos.DISPLAY_COMMAND_KEY);
+ command_column.add_attribute(command_renderer_key, "visible", DataPos.KEY_VISIBLE);
+
+
+ // pie action
+ var command_renderer_pie = new Gtk.CellRendererCombo();
+ command_renderer_pie.editable = true;
+ command_renderer_pie.has_entry = false;
+ command_renderer_pie.text_column = 0;
+ command_renderer_pie.ellipsize = Pango.EllipsizeMode.END;
+ command_renderer_pie.model = this.pies;
+
+ command_renderer_pie.changed.connect((path, iter) => {
+ string name;
+ string id;
+
+ this.pies.get(iter, PiePos.NAME, out name);
+ this.pies.get(iter, PiePos.ID, out id);
+
+ Gtk.TreeIter data_iter;
+ this.data.get_iter_from_string(out data_iter, path);
+
+ this.data.set(data_iter, DataPos.DISPLAY_COMMAND_PIE, name);
+ this.data.set(data_iter, DataPos.REAL_COMMAND_PIE, id);
+
+ this.update_pie(data_iter);
+ this.update_linked();
+ });
+
+ command_column.pack_end(command_renderer_pie, true);
+ command_column.add_attribute(command_renderer_pie, "weight", DataPos.FONT_WEIGHT);
+ command_column.add_attribute(command_renderer_pie, "text", DataPos.DISPLAY_COMMAND_PIE);
+ command_column.add_attribute(command_renderer_pie, "visible", DataPos.PIE_VISIBLE);
+
+
+ // uri action
+ var command_renderer_uri = new Gtk.CellRendererText();
+ command_renderer_uri.editable = true;
+ command_renderer_uri.ellipsize = Pango.EllipsizeMode.END;
+
+ command_renderer_uri.edited.connect((path, uri) => {
+ Gtk.TreeIter data_iter;
+ this.data.get_iter_from_string(out data_iter, path);
+
+ this.data.set(data_iter, DataPos.DISPLAY_COMMAND_URI, uri);
+
+ this.update_pie(data_iter);
+ });
+
+ command_column.pack_end(command_renderer_uri, true);
+ command_column.add_attribute(command_renderer_uri, "weight", DataPos.FONT_WEIGHT);
+ command_column.add_attribute(command_renderer_uri, "text", DataPos.DISPLAY_COMMAND_URI);
+ command_column.add_attribute(command_renderer_uri, "visible", DataPos.URI_VISIBLE);
+
+
+ // type column
+ var type_column = new Gtk.TreeViewColumn();
+ type_column.title = _("Pie-ID / Action type");
+ type_column.resizable = true;
+
+ var type_render = new Gtk.CellRendererCombo();
+ type_render.editable = true;
+ type_render.has_entry = false;
+ type_render.model = actions;
+ type_render.text_column = 0;
+ type_render.ellipsize = Pango.EllipsizeMode.END;
+
+ // change command_render's visibility accordingly
+ type_render.changed.connect((path, iter) => {
+ string text = "";
+ string type;
+ bool can_quickaction;
+ bool icon_name_editable;
+
+ this.actions.get(iter, ActionPos.NAME, out text);
+ this.actions.get(iter, ActionPos.TYPE, out type);
+ this.actions.get(iter, ActionPos.CAN_QUICKACTION, out can_quickaction);
+ this.actions.get(iter, ActionPos.ICON_NAME_EDITABLE, out icon_name_editable);
+
+ Gtk.TreeIter data_iter;
+ this.data.get_iter_from_string(out data_iter, path);
+
+ this.data.set(data_iter, DataPos.TYPE_ID, text);
+ this.data.set(data_iter, DataPos.ACTION_TYPE, type);
+ this.data.set(data_iter, DataPos.QUICKACTION_ACTIVATABLE, can_quickaction);
+ this.data.set(data_iter, DataPos.ICON_NAME_EDITABLE, icon_name_editable);
+
+ // set all command renderes invisible
+ this.data.set(data_iter, DataPos.GROUP_VISIBLE, false);
+ this.data.set(data_iter, DataPos.APP_VISIBLE, false);
+ this.data.set(data_iter, DataPos.KEY_VISIBLE, false);
+ this.data.set(data_iter, DataPos.PIE_VISIBLE, false);
+ this.data.set(data_iter, DataPos.URI_VISIBLE, false);
+
+ // set one visible
+ int type_id = 0;
+ if(type == typeof(AppAction).name()) type_id = 1;
+ else if(type == typeof(KeyAction).name()) type_id = 2;
+ else if(type == typeof(PieAction).name()) type_id = 3;
+ else if(type == typeof(UriAction).name()) type_id = 4;
+ else type_id = 0;
+
+ this.data.set(data_iter, DataPos.GROUP_VISIBLE + type_id, true);
+
+ this.update_linked();
+ this.update_pie(data_iter);
+
+ //this.set_cursor(new Gtk.TreePath.from_string(path), command_column, true);
+ });
+
+ type_column.pack_start(type_render, true);
+ type_column.add_attribute(type_render, "sensitive", DataPos.TYPE_VISIBLE);
+ type_column.add_attribute(type_render, "editable", DataPos.TYPE_VISIBLE);
+ type_column.add_attribute(type_render, "text", DataPos.TYPE_ID);
+
+ // name column
+ var name_column = new Gtk.TreeViewColumn();
+ name_column.title = _("Name");
+ name_column.expand = true;
+ name_column.resizable = true;
+
+ var name_render = new Gtk.CellRendererText();
+ name_render.editable = true;
+ name_render.ellipsize = Pango.EllipsizeMode.END;
+
+ name_render.edited.connect((path, text) => {
+ Gtk.TreeIter iter;
+ this.data.get_iter_from_string(out iter, path);
+
+ this.data.set(iter, DataPos.NAME, text);
+
+ // try to change icon to a fitting one
+ string icon;
+ this.data.get(iter, DataPos.ICON, out icon);
+ if (icon == "application-default-icon" && Gtk.IconTheme.get_default().has_icon(text.down())) {
+ this.data.set(iter, DataPos.ICON, text.down());
+ }
+
+ this.update_pie(iter);
+ this.update_linked();
+
+ //this.set_cursor(new Gtk.TreePath.from_string(path), type_column, true);
+ });
+
+ name_column.pack_start(name_render, true);
+ name_column.add_attribute(name_render, "weight", DataPos.FONT_WEIGHT);
+ name_column.add_attribute(name_render, "text", DataPos.NAME);
+ name_column.add_attribute(name_render, "sensitive", DataPos.ICON_NAME_EDITABLE);
+ name_column.add_attribute(name_render, "editable", DataPos.ICON_NAME_EDITABLE);
+
+ this.append_column(icon_column);
+ this.append_column(name_column);
+ this.append_column(type_column);
+ this.append_column(command_column);
+
+ this.realize.connect(this.load);
+
+ // context menu
+ var menu = new Gtk.Menu();
+
+ var item = new Gtk.ImageMenuItem.with_label(_("Add new Pie"));
+ item.set_image(new Gtk.Image.from_stock(Gtk.Stock.ADD, Gtk.IconSize.MENU));
+ item.activate.connect(this.add_empty_pie);
+ menu.append(item);
+
+ item = new Gtk.ImageMenuItem.with_label(_("Add new Slice"));
+ item.set_image(new Gtk.Image.from_stock(Gtk.Stock.ADD, Gtk.IconSize.MENU));
+ item.activate.connect(this.add_empty_slice);
+ menu.append(item);
+
+ var sepa = new Gtk.SeparatorMenuItem();
+ menu.append(sepa);
+
+ item = new Gtk.ImageMenuItem.with_label(_("Delete"));
+ item.set_image(new Gtk.Image.from_stock(Gtk.Stock.DELETE, Gtk.IconSize.MENU));
+ item.activate.connect(this.delete_selection);
+ menu.append(item);
+
+ menu.show_all();
+
+ this.button_press_event.connect((event) => {
+ if (event.type == Gdk.EventType.BUTTON_PRESS && event.button == 3) {
+ menu.popup(null, null, null, event.button, event.time);
+ }
+ return false;
+ });
+
+ // setup drag'n'drop
+ Gtk.TargetEntry uri_source = {"text/uri-list", 0, 0};
+ Gtk.TargetEntry[] entries = { uri_source };
+
+ this.drag_data_received.connect(this.on_dnd_received);
+ this.drag_data_get.connect(this.on_dnd_source);
+ this.enable_model_drag_dest(entries, Gdk.DragAction.COPY | Gdk.DragAction.MOVE | Gdk.DragAction.LINK);
+
+ this.get_selection().changed.connect(() => {
+ Gtk.TreeIter selected;
+ if (this.get_selection().get_selected(null, out selected)) {
+ if (this.data.iter_depth(selected) == 0) {
+ this.enable_model_drag_source(Gdk.ModifierType.BUTTON1_MASK, entries, Gdk.DragAction.LINK);
+ } else {
+ this.unset_rows_drag_source();
+ }
+ }
+ });
+
+ this.drag_begin.connect(() => {
+ this.unset_rows_drag_dest();
+ });
+
+ this.drag_end.connect(() => {
+ this.enable_model_drag_dest(entries, Gdk.DragAction.COPY | Gdk.DragAction.MOVE | Gdk.DragAction.LINK);
+ });
+ }
+
+ // moves the selected slice up
+ public void selection_up() {
+ Gtk.TreeIter selected;
+ if (this.get_selection().get_selected(null, out selected)) {
+ Gtk.TreePath path = this.data.get_path(selected);
+ Gtk.TreeIter? before = null;;
+ if (path.prev() && this.data.get_iter(out before, path)) {
+ this.data.swap(selected, before);
+ this.get_selection().changed();
+ this.update_pie(selected);
+ }
+ }
+ }
+
+ // moves the selected slice down
+ public void selection_down() {
+ Gtk.TreeIter selected;
+ if (this.get_selection().get_selected(null, out selected)) {
+ Gtk.TreePath path = this.data.get_path(selected);
+ Gtk.TreeIter? after = null;
+ path.next();
+ if (this.data.get_iter(out after, path)) {
+ this.data.swap(selected, after);
+ this.get_selection().changed();
+ this.update_pie(selected);
+ }
+ }
+ }
+
+ // updates the entire list, checking for changed cross-references via PieActions
+ // updates their names and icons if needed
+ private void update_linked() {
+ this.data.foreach((model, path, iter) => {
+ string action_type;
+ this.data.get(iter, DataPos.ACTION_TYPE, out action_type);
+
+ if (action_type == typeof(PieAction).name()) {
+ string command;
+ this.data.get(iter, DataPos.REAL_COMMAND_PIE, out command);
+
+ var referee = PieManager.all_pies[command];
+
+ if (referee != null) {
+ this.data.set(iter, DataPos.ICON, referee.icon);
+ this.data.set(iter, DataPos.NAME, referee.name);
+ this.data.set(iter, DataPos.ICON_PIXBUF, this.load_icon(referee.icon, this.small_icon));
+ this.data.set(iter, DataPos.DISPLAY_COMMAND_PIE, referee.name);
+ } else {
+ // referenced Pie does not exist anymore or no is selected;
+ // select the first one...
+ Gtk.TreeIter first_pie;
+ this.pies.get_iter_first(out first_pie);
+
+ string name;
+ string id;
+
+ this.pies.get(first_pie, PiePos.NAME, out name);
+ this.pies.get(first_pie, PiePos.ID, out id);
+
+ this.data.set(iter, DataPos.DISPLAY_COMMAND_PIE, name);
+ this.data.set(iter, DataPos.REAL_COMMAND_PIE, id);
+
+ update_linked();
+ }
+ } else if (action_type == typeof(ActionGroup).name()) {
+ string command;
+ this.data.get(iter, DataPos.REAL_COMMAND_GROUP, out command);
+
+ if (command == "") {
+ // no group is selected, select the first one...
+ Gtk.TreeIter first_group;
+ this.groups.get_iter_first(out first_group);
+
+ string name;
+ string type;
+ string icon;
+
+ this.groups.get(first_group, GroupPos.NAME, out name);
+ this.groups.get(first_group, GroupPos.TYPE, out type);
+ this.groups.get(first_group, GroupPos.ICON, out icon);
+
+ this.data.set(iter, DataPos.DISPLAY_COMMAND_GROUP, name);
+ this.data.set(iter, DataPos.NAME, name);
+ this.data.set(iter, DataPos.REAL_COMMAND_GROUP, type);
+ this.data.set(iter, DataPos.ICON, icon);
+ }
+ }
+
+ return false;
+ });
+ }
+
+ // adds a new, empty pie to the list
+ private void add_empty_pie() {
+ var new_one = PieManager.create_persistent_pie(_("New Pie"), "application-default-icon", "");
+
+ Gtk.TreeIter last;
+ this.pies.append(out last); this.pies.set(last, 0, new_one.name, 1, new_one.id);
+
+ Gtk.TreeIter parent;
+ this.data.append(out parent, null);
+ this.data.set(parent, DataPos.IS_QUICKACTION, false,
+ DataPos.ICON, new_one.icon,
+ DataPos.NAME, new_one.name,
+ DataPos.TYPE_ID, "ID: " + new_one.id,
+ DataPos.ACTION_TYPE, new_one.id,
+ DataPos.ICON_PIXBUF, this.load_icon(new_one.icon, this.large_icon),
+ DataPos.FONT_WEIGHT, 800,
+ DataPos.ICON_NAME_EDITABLE, true,
+ DataPos.QUICKACTION_VISIBLE, false,
+ DataPos.QUICKACTION_ACTIVATABLE, false,
+ DataPos.TYPE_VISIBLE, false,
+ DataPos.GROUP_VISIBLE, false,
+ DataPos.APP_VISIBLE, false,
+ DataPos.KEY_VISIBLE, true,
+ DataPos.PIE_VISIBLE, false,
+ DataPos.URI_VISIBLE, false,
+ DataPos.DISPLAY_COMMAND_GROUP, "",
+ DataPos.DISPLAY_COMMAND_APP, "",
+ DataPos.DISPLAY_COMMAND_KEY, PieManager.get_accelerator_label_of(new_one.id),
+ DataPos.DISPLAY_COMMAND_PIE, "",
+ DataPos.DISPLAY_COMMAND_URI, "",
+ DataPos.REAL_COMMAND_GROUP, "",
+ DataPos.REAL_COMMAND_PIE, "",
+ DataPos.REAL_COMMAND_KEY, PieManager.get_accelerator_of(new_one.id));
+
+
+ this.get_selection().select_iter(parent);
+ this.scroll_to_cell(this.data.get_path(parent), null, true, 0.5f, 0.0f);
+ }
+
+ // adds a new empty slice to the list
+ private void add_empty_slice() {
+ Gtk.TreeIter selected;
+ if (this.get_selection().get_selected(null, out selected)) {
+ var path = this.data.get_path(selected);
+ if (path != null) {
+ if (path.get_depth() == 2)
+ this.data.iter_parent(out selected, selected);
+
+ this.load_action(selected, new AppAction(_("New Action"), "application-default-icon", ""));
+
+ Gtk.TreeIter new_one;
+ this.data.iter_nth_child(out new_one, selected, this.data.iter_n_children(selected)-1);
+ this.expand_to_path(this.data.get_path(new_one));
+ this.get_selection().select_iter(new_one);
+ this.scroll_to_cell(this.data.get_path(new_one), null, true, 0.5f, 0.0f);
+
+ this.update_pie(selected);
+ }
+ } else {
+ var dialog = new Gtk.MessageDialog((Gtk.Window)this.get_toplevel(), Gtk.DialogFlags.MODAL,
+ Gtk.MessageType.INFO,
+ Gtk.ButtonsType.CLOSE,
+ _("You have to select a Pie to add a Slice to!"));
+ dialog.run();
+ dialog.destroy();
+ }
+ }
+
+ // writes the contents of action to the position pointed by slice
+ private void write_action(Action action, Gtk.TreeIter slice) {
+ this.data.set(slice, DataPos.IS_QUICKACTION, action.is_quick_action,
+ DataPos.ICON, action.icon,
+ DataPos.NAME, action.name,
+ DataPos.TYPE_ID, ActionRegistry.names[action.get_type()],
+ DataPos.ACTION_TYPE, action.get_type().name(),
+ DataPos.ICON_PIXBUF, this.load_icon(action.icon, this.small_icon),
+ DataPos.FONT_WEIGHT, 400,
+ DataPos.ICON_NAME_EDITABLE, !(action is PieAction),
+ DataPos.QUICKACTION_VISIBLE, true,
+ DataPos.QUICKACTION_ACTIVATABLE, true,
+ DataPos.TYPE_VISIBLE, true,
+ DataPos.GROUP_VISIBLE, false,
+ DataPos.APP_VISIBLE, action is AppAction,
+ DataPos.KEY_VISIBLE, action is KeyAction,
+ DataPos.PIE_VISIBLE, action is PieAction,
+ DataPos.URI_VISIBLE, action is UriAction,
+ DataPos.DISPLAY_COMMAND_GROUP, "",
+ DataPos.DISPLAY_COMMAND_APP, (action is AppAction) ? action.display_command : "",
+ DataPos.DISPLAY_COMMAND_KEY, (action is KeyAction) ? action.display_command : _("Not bound"),
+ DataPos.DISPLAY_COMMAND_PIE, (action is PieAction) ? action.display_command : "",
+ DataPos.DISPLAY_COMMAND_URI, (action is UriAction) ? action.display_command : "",
+ DataPos.REAL_COMMAND_GROUP, "",
+ DataPos.REAL_COMMAND_PIE, (action is PieAction) ? action.real_command : "",
+ DataPos.REAL_COMMAND_KEY, (action is KeyAction) ? action.real_command : "");
+ }
+
+ // deletes the currently selected pie or slice
+ private void delete_selection() {
+ Gtk.TreeIter selected;
+ if (this.get_selection().get_selected(null, out selected)) {
+ var path = this.data.get_path(selected);
+ if (path != null) {
+ if (path.get_depth() == 1)
+ this.delete_pie(selected);
+ else
+ this.delete_slice(selected);
+ }
+ } else {
+ var dialog = new Gtk.MessageDialog((Gtk.Window)this.get_toplevel(), Gtk.DialogFlags.MODAL,
+ Gtk.MessageType.INFO,
+ Gtk.ButtonsType.CLOSE,
+ _("You have to select a Pie or a Slice to delete!"));
+ dialog.run();
+ dialog.destroy();
+ }
+ }
+
+ // deletes the given pie
+ private void delete_pie(Gtk.TreeIter pie) {
+ var dialog = new Gtk.MessageDialog((Gtk.Window)this.get_toplevel(), Gtk.DialogFlags.MODAL,
+ Gtk.MessageType.QUESTION,
+ Gtk.ButtonsType.YES_NO,
+ _("Do you really want to delete the selected Pie with all contained Slices?"));
+
+ dialog.response.connect((response) => {
+ if (response == Gtk.ResponseType.YES) {
+ string id;
+ this.data.get(pie, DataPos.ACTION_TYPE, out id);
+ this.data.remove(pie);
+ PieManager.remove_pie(id);
+
+ this.pies.foreach((model, path, iter) => {
+ string pies_id;
+ this.pies.get(iter, PiePos.ID, out pies_id);
+
+ if (id == pies_id) {
+ this.pies.remove(iter);
+ return true;
+ }
+
+ return false;
+ });
+
+ this.update_linked();
+ }
+ });
+
+ dialog.run();
+ dialog.destroy();
+ }
+
+ // deletes the given slice
+ private void delete_slice(Gtk.TreeIter slice) {
+ var dialog = new Gtk.MessageDialog((Gtk.Window)this.get_toplevel(), Gtk.DialogFlags.MODAL,
+ Gtk.MessageType.QUESTION,
+ Gtk.ButtonsType.YES_NO,
+ _("Do you really want to delete the selected Slice?"));
+
+ dialog.response.connect((response) => {
+ if (response == Gtk.ResponseType.YES) {
+ Gtk.TreeIter parent;
+ this.data.iter_parent(out parent, slice);
+ this.data.remove(slice);
+ this.update_pie(parent);
+ }
+ });
+
+ dialog.run();
+ dialog.destroy();
+ }
+
+ // loads all pies to the list
+ private void load() {
+ foreach (var pie in PieManager.all_pies.entries) {
+ this.load_pie(pie.value);
+ }
+ }
+
+ // loads one given pie to the list
+ private void load_pie(Pie pie) {
+ if (pie.id.length == 3) {
+
+ Gtk.TreeIter last;
+ this.pies.append(out last); this.pies.set(last, PiePos.NAME, pie.name,
+ PiePos.ID, pie.id);
+
+ Gtk.TreeIter parent;
+ this.data.append(out parent, null);
+ this.data.set(parent, DataPos.IS_QUICKACTION, false,
+ DataPos.ICON, pie.icon,
+ DataPos.NAME, pie.name,
+ DataPos.TYPE_ID, "ID: " + pie.id,
+ DataPos.ACTION_TYPE, pie.id,
+ DataPos.ICON_PIXBUF, this.load_icon(pie.icon, this.large_icon),
+ DataPos.FONT_WEIGHT, 800,
+ DataPos.ICON_NAME_EDITABLE, true,
+ DataPos.QUICKACTION_VISIBLE, false,
+ DataPos.QUICKACTION_ACTIVATABLE, false,
+ DataPos.TYPE_VISIBLE, false,
+ DataPos.GROUP_VISIBLE, false,
+ DataPos.APP_VISIBLE, false,
+ DataPos.KEY_VISIBLE, true,
+ DataPos.PIE_VISIBLE, false,
+ DataPos.URI_VISIBLE, false,
+ DataPos.DISPLAY_COMMAND_GROUP, "",
+ DataPos.DISPLAY_COMMAND_APP, "",
+ DataPos.DISPLAY_COMMAND_KEY, PieManager.get_accelerator_label_of(pie.id),
+ DataPos.DISPLAY_COMMAND_PIE, "",
+ DataPos.DISPLAY_COMMAND_URI, "",
+ DataPos.REAL_COMMAND_GROUP, "",
+ DataPos.REAL_COMMAND_PIE, "",
+ DataPos.REAL_COMMAND_KEY, PieManager.get_accelerator_of(pie.id));
+
+ foreach (var group in pie.action_groups) {
+ this.load_group(parent, group);
+ }
+ }
+ }
+
+ // loads a given group
+ private void load_group(Gtk.TreeIter parent, ActionGroup group) {
+ if (group.get_type() == typeof(ActionGroup)) {
+ foreach (var action in group.actions) {
+ this.load_action(parent, action);
+ }
+ } else {
+ Gtk.TreeIter child;
+ this.data.append(out child, parent);
+ this.data.set(child, DataPos.IS_QUICKACTION, false,
+ DataPos.ICON, GroupRegistry.icons[group.get_type()],
+ DataPos.NAME, GroupRegistry.names[group.get_type()],
+ DataPos.TYPE_ID, _("Slice group"),
+ DataPos.ACTION_TYPE, typeof(ActionGroup).name(),
+ DataPos.ICON_PIXBUF, this.load_icon(GroupRegistry.icons[group.get_type()], this.small_icon),
+ DataPos.FONT_WEIGHT, 400,
+ DataPos.ICON_NAME_EDITABLE, false,
+ DataPos.QUICKACTION_VISIBLE, true,
+ DataPos.QUICKACTION_ACTIVATABLE, false,
+ DataPos.TYPE_VISIBLE, true,
+ DataPos.GROUP_VISIBLE, true,
+ DataPos.APP_VISIBLE, false,
+ DataPos.KEY_VISIBLE, false,
+ DataPos.PIE_VISIBLE, false,
+ DataPos.URI_VISIBLE, false,
+ DataPos.DISPLAY_COMMAND_GROUP, GroupRegistry.names[group.get_type()],
+ DataPos.DISPLAY_COMMAND_APP, "",
+ DataPos.DISPLAY_COMMAND_KEY, _("Not bound"),
+ DataPos.DISPLAY_COMMAND_PIE, "",
+ DataPos.DISPLAY_COMMAND_URI, "",
+ DataPos.REAL_COMMAND_GROUP, group.get_type().name(),
+ DataPos.REAL_COMMAND_PIE, "",
+ DataPos.REAL_COMMAND_KEY, "");
+ }
+ }
+
+ // loads a given slice
+ private void load_action(Gtk.TreeIter parent, Action action) {
+ Gtk.TreeIter child;
+ this.data.append(out child, parent);
+ this.write_action(action, child);
+ }
+
+ // applies all changes done to the given pie
+ private void update_pie(Gtk.TreeIter slice_or_pie) {
+ // get pie iter
+ var path = this.data.get_path(slice_or_pie);
+ if (path != null) {
+ var pie = slice_or_pie;
+ if (path.get_depth() == 2)
+ this.data.iter_parent(out pie, slice_or_pie);
+
+ // get information on pie
+ string id;
+ string icon;
+ string name;
+ string hotkey;
+
+ this.data.get(pie, DataPos.ICON, out icon);
+ this.data.get(pie, DataPos.NAME, out name);
+ this.data.get(pie, DataPos.ACTION_TYPE, out id);
+ this.data.get(pie, DataPos.REAL_COMMAND_KEY, out hotkey);
+
+ // remove pie
+ PieManager.remove_pie(id);
+
+ this.pies.foreach((model, path, iter) => {
+ string pies_id;
+ this.pies.get(iter, PiePos.ID, out pies_id);
+
+ if (id == pies_id) {
+ this.pies.set(iter, PiePos.NAME, name);
+ return true;
+ }
+
+ return false;
+ });
+
+ // create new pie
+ var new_pie = PieManager.create_persistent_pie(name, icon, hotkey, id);
+
+ // add actions accordingly
+ if (this.data.iter_has_child(pie)) {
+ Gtk.TreeIter child;
+ this.data.iter_children(out child, pie);
+
+ do {
+ // get slice information
+ string slice_type;
+ string slice_icon;
+ string slice_name;
+ bool is_quick_action;
+
+ this.data.get(child, DataPos.ICON, out slice_icon);
+ this.data.get(child, DataPos.NAME, out slice_name);
+ this.data.get(child, DataPos.ACTION_TYPE, out slice_type);
+ this.data.get(child, DataPos.IS_QUICKACTION, out is_quick_action);
+
+ if (slice_type == typeof(AppAction).name()) {
+ string slice_command;
+ this.data.get(child, DataPos.DISPLAY_COMMAND_APP, out slice_command);
+ var group = new ActionGroup(new_pie.id);
+ group.add_action(new AppAction(slice_name, slice_icon, slice_command, is_quick_action));
+ new_pie.add_group(group);
+ } else if (slice_type == typeof(KeyAction).name()) {
+ string slice_command;
+ this.data.get(child, DataPos.REAL_COMMAND_KEY, out slice_command);
+ var group = new ActionGroup(new_pie.id);
+ group.add_action(new KeyAction(slice_name, slice_icon, slice_command, is_quick_action));
+ new_pie.add_group(group);
+ } else if (slice_type == typeof(PieAction).name()) {
+ string slice_command;
+ this.data.get(child, DataPos.REAL_COMMAND_PIE, out slice_command);
+ var group = new ActionGroup(new_pie.id);
+ group.add_action(new PieAction(slice_command, is_quick_action));
+ new_pie.add_group(group);
+ } else if (slice_type == typeof(UriAction).name()) {
+ string slice_command;
+ this.data.get(child, DataPos.DISPLAY_COMMAND_URI, out slice_command);
+ var group = new ActionGroup(new_pie.id);
+ group.add_action(new UriAction(slice_name, slice_icon, slice_command, is_quick_action));
+ new_pie.add_group(group);
+ } else if (slice_type == typeof(ActionGroup).name()) {
+ string slice_command;
+ this.data.get(child, DataPos.REAL_COMMAND_GROUP, out slice_command);
+
+ var group = GLib.Object.new(GLib.Type.from_name(slice_command), "parent_id", new_pie.id);
+ new_pie.add_group(group as ActionGroup);
+ }
+
+ } while (this.data.iter_next(ref child));
+ }
+ }
+ }
+
+ // creates new action when the list receives a drag'n'drop event
+ private void on_dnd_received(Gdk.DragContext context, int x, int y, Gtk.SelectionData selection_data, uint info, uint time_) {
+ string[] uris = selection_data.get_uris();
+
+ Gtk.TreePath path;
+ Gtk.TreeViewDropPosition pos;
+
+ // check for valid position
+ if (!this.get_dest_row_at_pos(x, y, out path, out pos)
+ || (path.to_string() == "0" && pos == Gtk.TreeViewDropPosition.BEFORE)) {
+
+ warning("Failed to insert Slice: Invalid location!");
+ return;
+ }
+
+ // get position to insert (when child: after, when parent: as first child)
+ Gtk.TreeIter parent;
+ int insert_pos = 0;
+ if (path.get_depth() == 1) {
+ if (pos == Gtk.TreeViewDropPosition.BEFORE) {
+ path.prev();
+ this.data.get_iter(out parent, path);
+ insert_pos = this.data.iter_n_children(parent);
+ } else {
+ this.data.get_iter(out parent, path);
+ }
+ } else {
+ if (pos == Gtk.TreeViewDropPosition.BEFORE) {
+ insert_pos = path.get_indices()[1];
+ } else {
+ insert_pos = path.get_indices()[1]+1;
+ }
+
+ path.up();
+ this.data.get_iter(out parent, path);
+ }
+
+ foreach (var uri in uris) {
+ Gtk.TreeIter new_child;
+ this.data.insert(out new_child, parent, insert_pos);
+ this.write_action(ActionRegistry.new_for_uri(uri), new_child);
+ }
+
+ this.update_pie(parent);
+ }
+
+ private void on_dnd_source(Gdk.DragContext context, Gtk.SelectionData selection_data, uint info, uint time_) {
+ Gtk.TreeIter selected;
+ if (this.get_selection().get_selected(null, out selected)) {
+ string id = "";
+ this.data.get(selected, DataPos.ACTION_TYPE, out id);
+ selection_data.set_uris({"file://" + Paths.launchers + "/" + id + ".desktop"});
+ }
+ }
+
+ private Gdk.Pixbuf load_icon(string name, int size) {
+ Gdk.Pixbuf pixbuf = null;
+
+ try {
+ if (name.contains("/"))
+ pixbuf = new Gdk.Pixbuf.from_file_at_size(name, size, size);
+ else
+ pixbuf = new Gdk.Pixbuf.from_file_at_size(Icon.get_icon_file(name, size), size, size);
+ } catch (GLib.Error e) {
+ warning(e.message);
+ }
+
+ return pixbuf;
+ }
+}
+
+}
diff --git a/src/gui/preferences.vala b/src/gui/preferences.vala
new file mode 100644
index 0000000..f43fd4a
--- /dev/null
+++ b/src/gui/preferences.vala
@@ -0,0 +1,338 @@
+/*
+Copyright (c) 2011 by Simon Schneegans
+
+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 3 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, see <http://www.gnu.org/licenses/>.
+*/
+
+namespace GnomePie {
+
+/////////////////////////////////////////////////////////////////////////
+/// The Gtk settings menu of Gnome-Pie.
+/////////////////////////////////////////////////////////////////////////
+
+public class Preferences : Gtk.Window {
+
+ /////////////////////////////////////////////////////////////////////
+ /// C'tor, constructs the whole dialog. Many thanks to the
+ /// synapse-project, since some of this code is taken from there!
+ /////////////////////////////////////////////////////////////////////
+
+ public Preferences() {
+ this.title = _("Gnome-Pie - Settings");
+ this.set_position(Gtk.WindowPosition.CENTER);
+ this.set_size_request(550, 550);
+ this.resizable = false;
+ this.icon_name = "gnome-pie";
+ this.delete_event.connect(hide_on_delete);
+
+ // main container
+ var main_vbox = new Gtk.VBox(false, 12);
+ main_vbox.border_width = 12;
+ add(main_vbox);
+
+ // tab container
+ var tabs = new Gtk.Notebook();
+
+ // general tab
+ var general_tab = new Gtk.VBox(false, 6);
+ general_tab.border_width = 12;
+
+ // behavior frame
+ var behavior_frame = new Gtk.Frame(null);
+ behavior_frame.set_shadow_type(Gtk.ShadowType.NONE);
+ var behavior_frame_label = new Gtk.Label(null);
+ behavior_frame_label.set_markup(Markup.printf_escaped ("<b>%s</b>", _("Behavior")));
+ behavior_frame.set_label_widget(behavior_frame_label);
+
+ var behavior_vbox = new Gtk.VBox (false, 6);
+ var align = new Gtk.Alignment (0.5f, 0.5f, 1.0f, 1.0f);
+ align.set_padding (6, 12, 12, 12);
+ align.add (behavior_vbox);
+ behavior_frame.add (align);
+
+ // Autostart checkbox
+ var autostart = new Gtk.CheckButton.with_label (_("Startup on Login"));
+ autostart.tooltip_text = _("If checked, Gnome-Pie will start when you log in.");
+ autostart.active = Config.global.auto_start;
+ autostart.toggled.connect(autostart_toggled);
+ behavior_vbox.pack_start(autostart, false);
+
+ // Indicator icon
+ var indicator = new Gtk.CheckButton.with_label (_("Show Indicator"));
+ indicator.tooltip_text = _("If checked, an indicator for easy access of the settings menu is shown in your panel.");
+ indicator.active = Config.global.show_indicator;
+ indicator.toggled.connect(indicator_toggled);
+ behavior_vbox.pack_start(indicator, false);
+
+ // Open Pies at Mouse
+ var open_at_mouse = new Gtk.CheckButton.with_label (_("Open Pies at Mouse"));
+ open_at_mouse.tooltip_text = _("If checked, pies will open at your pointer. Otherwise they'll pop up in the middle of the screen.");
+ open_at_mouse.active = Config.global.open_at_mouse;
+ open_at_mouse.toggled.connect(open_at_mouse_toggled);
+ behavior_vbox.pack_start(open_at_mouse, false);
+
+ // Click to activate
+ var click_to_activate = new Gtk.CheckButton.with_label (_("Turbo mode"));
+ click_to_activate.tooltip_text = _("If checked, the pie closes when its keystroke is released. The currently hovered slice gets executed. This allows very fast selection but disables keyboard navigation.");
+ click_to_activate.active = Config.global.turbo_mode;
+ click_to_activate.toggled.connect(turbo_mode_toggled);
+ behavior_vbox.pack_start(click_to_activate, false);
+
+ // Slider
+ var slider_hbox = new Gtk.HBox (false, 6);
+ behavior_vbox.pack_start(slider_hbox);
+
+ var scale_label = new Gtk.Label(_("Global Scale"));
+ slider_hbox.pack_start(scale_label, false, false);
+
+ var scale_slider = new Gtk.HScale.with_range(0.5, 2.0, 0.05);
+ scale_slider.set_value(Config.global.global_scale);
+ scale_slider.value_pos = Gtk.PositionType.RIGHT;
+
+ bool changing = false;
+ bool changed_again = false;
+
+ scale_slider.value_changed.connect(() => {
+ if (!changing) {
+ changing = true;
+ Timeout.add(300, () => {
+ if (changed_again) {
+ changed_again = false;
+ return true;
+ }
+
+ Config.global.global_scale = scale_slider.get_value();
+ Config.global.load_themes(Config.global.theme.name);
+ changing = false;
+ return false;
+ });
+ } else {
+ changed_again = true;
+ }
+ });
+
+ slider_hbox.pack_end(scale_slider, true, true);
+
+ general_tab.pack_start (behavior_frame, false);
+
+ // theme frame
+ var theme_frame = new Gtk.Frame(null);
+ theme_frame.set_shadow_type(Gtk.ShadowType.NONE);
+ var theme_frame_label = new Gtk.Label(null);
+ theme_frame_label.set_markup(Markup.printf_escaped("<b>%s</b>", _("Themes")));
+ theme_frame.set_label_widget(theme_frame_label);
+
+ // scrollable frame
+ var scroll = new Gtk.ScrolledWindow (null, null);
+ align = new Gtk.Alignment(0.5f, 0.5f, 1.0f, 1.0f);
+ align.set_padding(6, 12, 12, 12);
+ align.add(scroll);
+ theme_frame.add(align);
+
+ scroll.set_policy (Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC);
+ scroll.set_shadow_type (Gtk.ShadowType.IN);
+
+ // themes list
+ var theme_list = new ThemeList();
+ scroll.add(theme_list);
+
+ general_tab.pack_start (theme_frame, true, true);
+ tabs.append_page(general_tab, new Gtk.Label(_("General")));
+
+ // pies tab
+ var pies_tab = new Gtk.VBox(false, 6);
+ pies_tab.border_width = 12;
+ tabs.append_page(pies_tab, new Gtk.Label(_("Pies")));
+
+ // scrollable frame
+ scroll = new Gtk.ScrolledWindow (null, null);
+ align = new Gtk.Alignment(0.5f, 0.5f, 1.0f, 1.0f);
+ align.add(scroll);
+ pies_tab.add(align);
+
+ scroll.set_policy (Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC);
+ scroll.set_shadow_type (Gtk.ShadowType.IN);
+
+ // pies list
+ var pie_list = new PieList();
+ scroll.add(pie_list);
+
+ // bottom box
+ var info_box = new Gtk.HBox (false, 6);
+
+ // info image
+ var info_image = new Gtk.Image.from_stock (Gtk.Stock.INFO, Gtk.IconSize.MENU);
+ info_box.pack_start (info_image, false);
+
+ // info label
+ var info_label = new TipViewer({
+ _("You can right-click in the list for adding or removing entries."),
+ _("You can reset Gnome-Pie to its default options with the terminal command \"gnome-pie --reset\"."),
+ _("The radiobutton at the beginning of each slice-line indicates the QuickAction of the pie."),
+ _("Pies can be opened with the terminal command \"gnome-pie --open=ID\"."),
+ _("Feel free to visit Gnome-Pie's homepage at %s!").printf("<a href='http://gnome-pie.simonschneegans.de'>gnome-pie.simonschneegans.de</a>"),
+ _("You can drag'n'drop applications from your main menu to the list above."),
+ _("If you want to give some feedback, please write an e-mail to %s!").printf("<a href='mailto:code@simonschneegans.de'>code@simonschneegans.de</a>"),
+ _("You may drag'n'drop URLs and bookmarks from your internet browser to the list above."),
+ _("Bugs can be reported at %s!").printf("<a href='https://github.com/Simmesimme/Gnome-Pie'>Github</a>"),
+ _("It's possible to drag'n'drop files and folders from your file browser to the list above."),
+ _("In order to create a launcher for a Pie, drag the Pie from the list to your desktop!")
+ });
+ this.show.connect(info_label.start_slide_show);
+ this.hide.connect(info_label.stop_slide_show);
+
+ info_box.pack_start (info_label);
+
+ // down Button
+ var down_button = new Gtk.Button();
+ down_button.tooltip_text = _("Moves the selected Slice down");
+ down_button.sensitive = false;
+ var down_image = new Gtk.Image.from_stock (Gtk.Stock.GO_DOWN, Gtk.IconSize.LARGE_TOOLBAR);
+ down_button.add(down_image);
+ down_button.clicked.connect (() => {
+ pie_list.selection_down();
+ });
+
+ info_box.pack_end(down_button, false, false);
+
+ // up Button
+ var up_button = new Gtk.Button();
+ up_button.tooltip_text = _("Moves the selected Slice up");
+ up_button.sensitive = false;
+ var up_image = new Gtk.Image.from_stock (Gtk.Stock.GO_UP, Gtk.IconSize.LARGE_TOOLBAR);
+ up_button.add(up_image);
+ up_button.clicked.connect (() => {
+ pie_list.selection_up();
+ });
+
+ info_box.pack_end(up_button, false, false);
+
+ pie_list.get_selection().changed.connect(() => {
+ Gtk.TreeIter selected;
+ if (pie_list.get_selection().get_selected(null, out selected)) {
+ Gtk.TreePath path = pie_list.model.get_path(selected);
+ if (path.get_depth() == 1) {
+ up_button.sensitive = false;
+ down_button.sensitive = false;
+ } else {
+ up_button.sensitive = true;
+ down_button.sensitive = true;
+
+ int child_pos = path.get_indices()[1];
+
+ if (child_pos == 0)
+ up_button.sensitive = false;
+
+ path.up();
+ Gtk.TreeIter parent_iter;
+ pie_list.model.get_iter(out parent_iter, path);
+ if (child_pos == pie_list.model.iter_n_children(parent_iter)-1)
+ down_button.sensitive = false;
+
+ }
+ }
+ });
+
+ pies_tab.pack_start (info_box, false);
+
+ main_vbox.pack_start(tabs);
+
+ // close button
+ var bbox = new Gtk.HButtonBox ();
+ bbox.set_layout (Gtk.ButtonBoxStyle.END);
+ var close_button = new Gtk.Button.from_stock (Gtk.Stock.CLOSE);
+ close_button.clicked.connect (() => {
+ hide();
+ // save settings on close
+ Config.global.save();
+ Pies.save();
+ });
+ bbox.pack_start (close_button);
+
+ main_vbox.pack_start(bbox, false);
+
+ main_vbox.show_all();
+ }
+
+ /////////////////////////////////////////////////////////////////////
+ /// Creates or deletes the autostart file. This code is inspired
+ /// by project synapse as well.
+ /////////////////////////////////////////////////////////////////////
+
+ private void autostart_toggled(Gtk.ToggleButton check_box) {
+ bool active = check_box.active;
+ if (!active && FileUtils.test(Paths.autostart, FileTest.EXISTS)) {
+ // delete the autostart file
+ FileUtils.remove (Paths.autostart);
+ }
+ else if (active && !FileUtils.test(Paths.autostart, FileTest.EXISTS)) {
+ string autostart_entry =
+ "#!/usr/bin/env xdg-open\n" +
+ "[Desktop Entry]\n" +
+ "Name=Gnome-Pie\n" +
+ "Exec=gnome-pie\n" +
+ "Encoding=UTF-8\n" +
+ "Type=Application\n" +
+ "X-GNOME-Autostart-enabled=true\n" +
+ "Icon=gnome-pie\n";
+
+ // create the autostart file
+ string autostart_dir = GLib.Path.get_dirname(Paths.autostart);
+ if (!FileUtils.test(autostart_dir, FileTest.EXISTS | FileTest.IS_DIR)) {
+ DirUtils.create_with_parents(autostart_dir, 0755);
+ }
+
+ try {
+ FileUtils.set_contents(Paths.autostart, autostart_entry);
+ FileUtils.chmod(Paths.autostart, 0755);
+ } catch (Error e) {
+ var d = new Gtk.MessageDialog (this, 0, Gtk.MessageType.ERROR, Gtk.ButtonsType.CLOSE,
+ "%s", e.message);
+ d.run ();
+ d.destroy ();
+ }
+ }
+ }
+
+ /////////////////////////////////////////////////////////////////////
+ /// Shows or hides the indicator.
+ /////////////////////////////////////////////////////////////////////
+
+ private void indicator_toggled(Gtk.ToggleButton check_box) {
+ var check = check_box as Gtk.CheckButton;
+ Config.global.show_indicator = check.active;
+ }
+
+ /////////////////////////////////////////////////////////////////////
+ /// Toggles whether the Pies are shown at the mouse or in the middle
+ /// of the screen.
+ /////////////////////////////////////////////////////////////////////
+
+ private void open_at_mouse_toggled(Gtk.ToggleButton check_box) {
+ var check = check_box as Gtk.CheckButton;
+ Config.global.open_at_mouse = check.active;
+ }
+
+ /////////////////////////////////////////////////////////////////////
+ /// Toggles whether the user has to click with the mouse in order to
+ /// activate a slice.
+ /////////////////////////////////////////////////////////////////////
+
+ private void turbo_mode_toggled(Gtk.ToggleButton check_box) {
+ var check = check_box as Gtk.CheckButton;
+ Config.global.turbo_mode = check.active;
+ }
+}
+
+}
diff --git a/src/gui/themeList.vala b/src/gui/themeList.vala
new file mode 100644
index 0000000..7eadcdb
--- /dev/null
+++ b/src/gui/themeList.vala
@@ -0,0 +1,95 @@
+/*
+Copyright (c) 2011 by Simon Schneegans
+
+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 3 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, see <http://www.gnu.org/licenses/>.
+*/
+
+namespace GnomePie {
+
+/////////////////////////////////////////////////////////////////////////
+/// A widget displaying all available themes of Gnome-Pie.
+/////////////////////////////////////////////////////////////////////////
+
+class ThemeList : Gtk.TreeView {
+
+ /////////////////////////////////////////////////////////////////////
+ /// The currently selected row.
+ /////////////////////////////////////////////////////////////////////
+
+ private Gtk.TreeIter active { private get; private set; }
+
+ /////////////////////////////////////////////////////////////////////
+ /// C'tor, constructs the Widget.
+ /////////////////////////////////////////////////////////////////////
+
+ public ThemeList() {
+ GLib.Object();
+
+ var data = new Gtk.ListStore(2, typeof(bool), // selected
+ typeof(string)); // description
+ base.set_model(data);
+ base.set_headers_visible(false);
+ base.set_rules_hint(true);
+ base.set_grid_lines(Gtk.TreeViewGridLines.NONE);
+
+ var main_column = new Gtk.TreeViewColumn();
+ var check_render = new Gtk.CellRendererToggle();
+ check_render.set_radio(true);
+ check_render.set_activatable(true);
+ main_column.pack_start(check_render, false);
+
+ // switch the theme if the entry has been toggled
+ check_render.toggled.connect((r, path) => {
+ Gtk.TreeIter toggled;
+ data.get_iter(out toggled, new Gtk.TreePath.from_string(path));
+
+ if (toggled != this.active) {
+ Timeout.add(10, () => {
+ int index = int.parse(path);
+ Config.global.theme = Config.global.themes[index];
+ Config.global.theme.load();
+ Config.global.theme.load_images();
+ return false;
+ });
+
+ data.set(this.active, 0, false);
+ data.set(toggled, 0, true);
+
+ this.active = toggled;
+ }
+ });
+
+ var theme_render = new Gtk.CellRendererText();
+ main_column.pack_start(theme_render, true);
+
+ base.append_column(main_column);
+
+ main_column.add_attribute(check_render, "active", 0);
+ main_column.add_attribute(theme_render, "markup", 1);
+
+ // load all themes into the list
+ var themes = Config.global.themes;
+ foreach(var theme in themes) {
+ Gtk.TreeIter current;
+ data.append(out current);
+ data.set(current, 0, theme == Config.global.theme);
+ data.set(current, 1, "<b>" + theme.name + "</b>\n" + theme.description
+ + " <small> - " + _("by") + " " + theme.author + "</small>");
+ if(theme == Config.global.theme)
+ this.active = current;
+ }
+ }
+}
+
+}
diff --git a/src/gui/tipViewer.vala b/src/gui/tipViewer.vala
new file mode 100644
index 0000000..c653dd9
--- /dev/null
+++ b/src/gui/tipViewer.vala
@@ -0,0 +1,172 @@
+/*
+Copyright (c) 2011 by Simon Schneegans
+
+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 3 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, see <http://www.gnu.org/licenses/>.
+*/
+
+namespace GnomePie {
+
+/////////////////////////////////////////////////////////////////////////
+/// A widget showing tips. The tips are beautifully faded in and out.
+/////////////////////////////////////////////////////////////////////////
+
+public class TipViewer : Gtk.Label {
+
+ /////////////////////////////////////////////////////////////////////
+ /// Some settings tweaking the behavior of the TipViewer.
+ /////////////////////////////////////////////////////////////////////
+
+ private const double fade_time = 0.5;
+ private const double frame_rate = 20.0;
+ private const double delay = 7.0;
+
+ /////////////////////////////////////////////////////////////////////
+ /// False, if the playback of tips is stopped.
+ /////////////////////////////////////////////////////////////////////
+
+ private bool playing = false;
+
+ /////////////////////////////////////////////////////////////////////
+ /// An array containing all tips.
+ /////////////////////////////////////////////////////////////////////
+
+ private string[] tips;
+
+ /////////////////////////////////////////////////////////////////////
+ /// The index of the currently displayed tip.
+ /////////////////////////////////////////////////////////////////////
+
+ private int index = -1;
+
+ /////////////////////////////////////////////////////////////////////
+ /// Colors of the font and the background. Used for fading effects.
+ /////////////////////////////////////////////////////////////////////
+
+ private Gdk.Color fg;
+ private Gdk.Color bg;
+
+ /////////////////////////////////////////////////////////////////////
+ /// The fading value.
+ /////////////////////////////////////////////////////////////////////
+
+ private AnimatedValue alpha;
+
+ /////////////////////////////////////////////////////////////////////
+ /// C'tor, initializes all members and sets the basic layout.
+ /////////////////////////////////////////////////////////////////////
+
+ public TipViewer(string[] tips) {
+ this.tips = tips;
+ this.fg = this.get_style().fg[0];
+ this.bg = this.get_style().bg[0];
+
+ this.alpha = new AnimatedValue.linear(1.0, 0.0, this.fade_time);
+
+ this.set_alignment (0.0f, 0.5f);
+ this.wrap = true;
+ this.set_use_markup(true);
+ this.modify_font(Pango.FontDescription.from_string("9"));
+
+ this.set_random_tip();
+ }
+
+ /////////////////////////////////////////////////////////////////////
+ /// Starts the playback of tips.
+ /////////////////////////////////////////////////////////////////////
+
+ public void start_slide_show() {
+ if (!this.playing && tips.length > 1) {
+ this.playing = true;
+ GLib.Timeout.add((uint)(this.delay*1000.0), () => {
+ this.fade_out();
+
+ GLib.Timeout.add((uint)(1000.0*this.fade_time), () => {
+ this.set_random_tip();
+ this.fade_in();
+ return false;
+ });
+
+ return this.playing;
+ });
+ }
+ }
+
+ /////////////////////////////////////////////////////////////////////
+ /// Stops the playback of tips.
+ /////////////////////////////////////////////////////////////////////
+
+ public void stop_slide_show() {
+ this.playing = false;
+ }
+
+ /////////////////////////////////////////////////////////////////////
+ /// Starts the fading in.
+ /////////////////////////////////////////////////////////////////////
+
+ private void fade_in() {
+ this.alpha = new AnimatedValue.linear(this.alpha.val, 1.0, this.fade_time);
+
+ GLib.Timeout.add((uint)(1000.0/this.frame_rate), () => {
+ this.alpha.update(1.0/this.frame_rate);
+ this.update_label();
+
+ return (this.alpha.val != 1.0);
+ });
+ }
+
+ /////////////////////////////////////////////////////////////////////
+ /// Starts the fading out.
+ /////////////////////////////////////////////////////////////////////
+
+ private void fade_out() {
+ this.alpha = new AnimatedValue.linear(this.alpha.val, 0.0, this.fade_time);
+
+ GLib.Timeout.add((uint)(1000.0/this.frame_rate), () => {
+ this.alpha.update(1.0/this.frame_rate);
+ this.update_label();
+
+ return (this.alpha.val != 0.0);
+ });
+ }
+
+ /////////////////////////////////////////////////////////////////////
+ /// Updates the color of the label. Called every frame while fading.
+ /////////////////////////////////////////////////////////////////////
+
+ private void update_label() {
+ Gdk.Color color = {(uint32)(fg.pixel*this.alpha.val + bg.pixel*(1.0 - this.alpha.val)),
+ (uint16)(fg.red*this.alpha.val + bg.red*(1.0 - this.alpha.val)),
+ (uint16)(fg.green*this.alpha.val + bg.green*(1.0 - this.alpha.val)),
+ (uint16)(fg.blue*this.alpha.val + bg.blue*(1.0 - this.alpha.val))};
+
+ this.modify_fg(Gtk.StateType.NORMAL, color);
+ }
+
+ /////////////////////////////////////////////////////////////////////
+ /// Chooses the next random tip.
+ /////////////////////////////////////////////////////////////////////
+
+ private void set_random_tip() {
+ if (tips.length > 1) {
+ int next_index = -1;
+ do {
+ next_index = GLib.Random.int_range(0, tips.length);
+ } while (next_index == this.index);
+ this.index = next_index;
+ this.label = tips[this.index];
+ }
+ }
+}
+
+}
diff --git a/src/pies/defaultConfig.vala b/src/pies/defaultConfig.vala
new file mode 100644
index 0000000..bd981b5
--- /dev/null
+++ b/src/pies/defaultConfig.vala
@@ -0,0 +1,70 @@
+/*
+Copyright (c) 2011 by Simon Schneegans
+
+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 3 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, see <http://www.gnu.org/licenses/>.
+*/
+
+namespace GnomePie {
+
+/////////////////////////////////////////////////////////////////////////
+/// A helper class which creates a user-specific default configuration.
+/////////////////////////////////////////////////////////////////////////
+
+namespace Pies {
+
+ public void create_default_config() {
+
+ // add a pie with playback controls
+ var multimedia = PieManager.create_persistent_pie(_("Multimedia"), "stock_media-play", "<Control><Alt>m");
+ multimedia.add_action(new KeyAction(_("Next Track"), "stock_media-next", "XF86AudioNext", true));
+ multimedia.add_action(new KeyAction(_("Stop"), "stock_media-stop", "XF86AudioStop"));
+ multimedia.add_action(new KeyAction(_("Previous Track"), "stock_media-prev", "XF86AudioPrev"));
+ multimedia.add_action(new KeyAction(_("Play/Pause"), "stock_media-play", "XF86AudioPlay"));
+
+ // add a pie with the users default applications
+ var apps = PieManager.create_persistent_pie(_("Applications"), "applications-accessories", "<Control><Alt>a");
+ apps.add_action(ActionRegistry.default_for_mime_type("text/plain"));
+ apps.add_action(ActionRegistry.default_for_mime_type("audio/ogg"));
+ apps.add_action(ActionRegistry.default_for_mime_type("video/ogg"));
+ apps.add_action(ActionRegistry.default_for_mime_type("image/jpg"));
+ apps.add_action(ActionRegistry.default_for_uri("http"));
+ apps.add_action(ActionRegistry.default_for_uri("mailto"));
+
+ // add a pie with the users bookmarks and devices
+ var bookmarks = PieManager.create_persistent_pie(_("Bookmarks"), "user-bookmarks", "<Control><Alt>b");
+ bookmarks.add_group(new BookmarkGroup(bookmarks.id));
+ bookmarks.add_group(new DevicesGroup(bookmarks.id));
+
+ // add a pie with session controls
+ var session = PieManager.create_persistent_pie(_("Session"), "gnome-session-halt", "<Control><Alt>q");
+ session.add_group(new SessionGroup(session.id));
+
+ // add a pie with a main menu
+ var menu = PieManager.create_persistent_pie(_("Main Menu"), "alacarte", "<Control><Alt>space");
+ menu.add_group(new MenuGroup(menu.id));
+
+ // add a pie with window controls
+ var window = PieManager.create_persistent_pie(_("Window"), "gnome-window-manager", "<Control><Alt>w");
+ window.add_action(new KeyAction(_("Scale"), "top", "<Control><Alt>s"));
+ window.add_action(new KeyAction(_("Minimize"), "bottom", "<Alt>F9", true));
+ window.add_action(new KeyAction(_("Close"), "window-close", "<Alt>F4"));
+ window.add_action(new KeyAction(_("Maximize"), "window_fullscreen", "<Alt>F10"));
+ window.add_action(new KeyAction(_("Restore"), "window_nofullscreen", "<Alt>F5"));
+
+ // save the configuration to file
+ Pies.save();
+ }
+}
+
+}
diff --git a/src/pies/load.vala b/src/pies/load.vala
new file mode 100644
index 0000000..912ddf0
--- /dev/null
+++ b/src/pies/load.vala
@@ -0,0 +1,230 @@
+/*
+Copyright (c) 2011 by Simon Schneegans
+
+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 3 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, see <http://www.gnu.org/licenses/>.
+*/
+
+using GLib.Math;
+
+namespace GnomePie {
+
+/////////////////////////////////////////////////////////////////////////
+/// A helper method which loads pies according to the configuration file.
+/////////////////////////////////////////////////////////////////////////
+
+namespace Pies {
+
+ /////////////////////////////////////////////////////////////////////
+ /// Loads all Pies from the pies.conf file.
+ /////////////////////////////////////////////////////////////////////
+
+ public void load() {
+ // check whether the config file exists
+ if (!GLib.File.new_for_path(Paths.pie_config).query_exists()) {
+ message("Creating new configuration file in \"" + Paths.pie_config + "\".");
+ Pies.create_default_config();
+ return;
+ }
+
+ // load the settings file
+ Xml.Parser.init();
+ Xml.Doc* piesXML = Xml.Parser.parse_file(Paths.pie_config);
+
+ if (piesXML != null) {
+ // begin parsing at the root element
+ Xml.Node* root = piesXML->get_root_element();
+ if (root != null) {
+ for (Xml.Node* node = root->children; node != null; node = node->next) {
+ if (node->type == Xml.ElementType.ELEMENT_NODE) {
+ string node_name = node->name.down();
+ switch (node_name) {
+ case "pie":
+ parse_pie(node);
+ break;
+ default:
+ warning("Invalid child element <" + node_name + "> in <pies> element pies.conf!");
+ break;
+ }
+ }
+ }
+ Xml.Parser.cleanup();
+
+ } else {
+ warning("Error loading pies: pies.conf is empty! The cake is a lie...");
+ }
+
+ delete piesXML;
+
+ } else {
+ warning("Error loading pies: pies.conf not found! The cake is a lie...");
+ }
+ }
+
+ /////////////////////////////////////////////////////////////////////
+ /// Parses a <pie> element from the pies.conf file.
+ /////////////////////////////////////////////////////////////////////
+
+ private static void parse_pie(Xml.Node* node) {
+ string hotkey = "";
+ string name = "";
+ string icon = "";
+ string id = "";
+ int quick_action = -1;
+
+ // parse all attributes of this node
+ for (Xml.Attr* attribute = node->properties; attribute != null; attribute = attribute->next) {
+ string attr_name = attribute->name.down();
+ string attr_content = attribute->children->content;
+
+ switch (attr_name) {
+ case "hotkey":
+ hotkey = attr_content;
+ break;
+ case "quickaction":
+ quick_action = int.parse(attr_content);
+ break;
+ case "name":
+ name = attr_content;
+ break;
+ case "icon":
+ icon = attr_content;
+ break;
+ case "id":
+ id = attr_content;
+ break;
+ default:
+ warning("Invalid setting \"" + attr_name + "\" in pies.conf!");
+ break;
+ }
+ }
+
+ if (name == "") {
+ warning("Invalid <pie> element in pies.conf: No name specified!");
+ return;
+ }
+
+ // add a new Pie with the loaded properties
+ var pie = PieManager.create_persistent_pie(name, icon, hotkey, id);
+
+ // and parse all child elements
+ for (Xml.Node* slice = node->children; slice != null; slice = slice->next) {
+ if (slice->type == Xml.ElementType.ELEMENT_NODE) {
+ string node_name = slice->name.down();
+ switch (node_name) {
+ case "slice":
+ parse_slice(slice, pie);
+ break;
+ case "group":
+ parse_group(slice, pie);
+ break;
+ default:
+ warning("Invalid child element <" + node_name + "> in <pie> element in pies.conf!");
+ break;
+ }
+ }
+ }
+ }
+
+ /////////////////////////////////////////////////////////////////////
+ /// Parses a <slice> element from the pies.conf file.
+ /////////////////////////////////////////////////////////////////////
+
+ private static void parse_slice(Xml.Node* slice, Pie pie) {
+ string name="";
+ string icon="";
+ string command="";
+ string type="";
+ bool quick_action = false;
+
+ // parse all attributes of this node
+ for (Xml.Attr* attribute = slice->properties; attribute != null; attribute = attribute->next) {
+ string attr_name = attribute->name.down();
+ string attr_content = attribute->children->content;
+
+ switch (attr_name) {
+ case "name":
+ name = attr_content;
+ break;
+ case "icon":
+ icon = attr_content;
+ break;
+ case "command":
+ command = attr_content;
+ break;
+ case "type":
+ type = attr_content;
+ break;
+ case "quickaction":
+ quick_action = bool.parse(attr_content);
+ break;
+ default:
+ warning("Invalid attribute \"" + attr_name + "\" in <slice> element in pies.conf!");
+ break;
+ }
+ }
+
+ Action action = null;
+
+ // create a new Action according to the loaded type
+ foreach (var action_type in ActionRegistry.types) {
+ if (ActionRegistry.settings_names[action_type] == type) {
+
+ action = GLib.Object.new(action_type, "name", name,
+ "icon", icon,
+ "real_command", command,
+ "is_quick_action", quick_action) as Action;
+ break;
+ }
+ }
+
+ if (action != null) pie.add_action(action);
+ }
+
+ /////////////////////////////////////////////////////////////////////
+ /// Parses a <group> element from the pies.conf file.
+ /////////////////////////////////////////////////////////////////////
+
+ private static void parse_group(Xml.Node* slice, Pie pie) {
+ string type="";
+
+ // parse all attributes of this node
+ for (Xml.Attr* attribute = slice->properties; attribute != null; attribute = attribute->next) {
+ string attr_name = attribute->name.down();
+ string attr_content = attribute->children->content;
+
+ switch (attr_name) {
+ case "type":
+ type = attr_content;
+ break;
+ default:
+ warning("Invalid attribute \"" + attr_name + "\" in <group> element in pies.conf!");
+ break;
+ }
+ }
+
+ ActionGroup group = null;
+
+ // create a new ActionGroup according to the loaded type
+ foreach (var group_type in GroupRegistry.types) {
+ if (GroupRegistry.settings_names[group_type] == type) {
+ group = GLib.Object.new(group_type, "parent_id", pie.id) as ActionGroup;
+ break;
+ }
+ }
+
+ if (group != null) pie.add_group(group);
+ }
+}
+
+}
diff --git a/src/pies/pie.vala b/src/pies/pie.vala
new file mode 100644
index 0000000..0f87d8f
--- /dev/null
+++ b/src/pies/pie.vala
@@ -0,0 +1,96 @@
+/*
+Copyright (c) 2011 by Simon Schneegans
+
+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 3 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, see <http://www.gnu.org/licenses/>.
+*/
+
+namespace GnomePie {
+
+/////////////////////////////////////////////////////////////////////////
+/// This class stores information on a pie. A pie consists of a name, an
+/// icon name and an unique ID. Furthermore it has an arbitrary amount
+/// of ActionGroups storing Actions.
+/////////////////////////////////////////////////////////////////////////
+
+public class Pie : GLib.Object {
+
+ /////////////////////////////////////////////////////////////////////
+ /// The name of this Pie. It has not to be unique.
+ /////////////////////////////////////////////////////////////////////
+
+ public string name { get; construct; }
+
+ /////////////////////////////////////////////////////////////////////
+ /// The name of the icon to be used for this Pie. It should exist in
+ /// the users current icon theme, else a standard icon will be used.
+ /////////////////////////////////////////////////////////////////////
+
+ public string icon { get; construct; }
+
+ /////////////////////////////////////////////////////////////////////
+ /// The ID of this Pie. It has to be unique among all Pies. This ID
+ /// consists of three digits when the Pie was created by the user,
+ /// of four digits when it was created dynamically by another class,
+ /// for example by an ActionGroup.
+ /////////////////////////////////////////////////////////////////////
+
+ public string id { get; construct; }
+
+ /////////////////////////////////////////////////////////////////////
+ /// Stores all ActionGroups of this Pie.
+ /////////////////////////////////////////////////////////////////////
+
+ public Gee.ArrayList<ActionGroup?> action_groups { get; private set; }
+
+ /////////////////////////////////////////////////////////////////////
+ /// C'tor, initializes all given members.
+ /////////////////////////////////////////////////////////////////////
+
+ public Pie(string id, string name, string icon) {
+ GLib.Object(id: id, name: name, icon:icon);
+
+ this.action_groups = new Gee.ArrayList<ActionGroup?>();
+ }
+
+ /////////////////////////////////////////////////////////////////////
+ /// Should be called when this Pie is deleted, in order to clean up
+ /// stuff created by contained ActionGroups.
+ /////////////////////////////////////////////////////////////////////
+
+ public virtual void on_remove() {
+ foreach (var action_group in action_groups)
+ action_group.on_remove();
+ }
+
+ /////////////////////////////////////////////////////////////////////
+ /// Adds an Action to this Pie.
+ /////////////////////////////////////////////////////////////////////
+
+ public void add_action(Action action) {
+ var group = new ActionGroup(this.id);
+ group.add_action(action);
+ this.add_group(group);
+ }
+
+ /////////////////////////////////////////////////////////////////////
+ /// Adds an ActionGroup to this Pie.
+ /////////////////////////////////////////////////////////////////////
+
+ public void add_group(ActionGroup group) {
+ this.action_groups.add(group);
+ }
+}
+
+}
+
diff --git a/src/pies/pieManager.vala b/src/pies/pieManager.vala
new file mode 100644
index 0000000..eb031d0
--- /dev/null
+++ b/src/pies/pieManager.vala
@@ -0,0 +1,231 @@
+/*
+Copyright (c) 2011 by Simon Schneegans
+
+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 3 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, see <http://www.gnu.org/licenses/>.
+*/
+
+namespace GnomePie {
+
+/////////////////////////////////////////////////////////////////////////
+/// A static class which stores all Pies. It can be used to add, delete
+/// and open Pies.
+/////////////////////////////////////////////////////////////////////////
+
+public class PieManager : GLib.Object {
+
+ /////////////////////////////////////////////////////////////////////
+ /// A map of all Pies. It contains both, dynamic and persistent Pies.
+ /// They are associated to their ID's.
+ /////////////////////////////////////////////////////////////////////
+
+ public static Gee.HashMap<string, Pie?> all_pies { get; private set; }
+
+ /////////////////////////////////////////////////////////////////////
+ /// Stores all global hotkeys.
+ /////////////////////////////////////////////////////////////////////
+
+ private static BindingManager bindings;
+
+ /////////////////////////////////////////////////////////////////////
+ /// True, if any pie has the current focus. If it is closing this
+ /// will be false already.
+ /////////////////////////////////////////////////////////////////////
+
+ private static bool a_pie_is_opened = false;
+
+ /////////////////////////////////////////////////////////////////////
+ /// Initializes all Pies. They are loaded from the pies.conf file.
+ /////////////////////////////////////////////////////////////////////
+
+ public static void init() {
+ all_pies = new Gee.HashMap<string, Pie?>();
+ bindings = new BindingManager();
+
+ // load all Pies from th pies.conf file
+ Pies.load();
+
+ // open the according pie if it's hotkey is pressed
+ bindings.on_press.connect((id) => {
+ open_pie(id);
+ });
+ }
+
+ /////////////////////////////////////////////////////////////////////
+ /// Opens the Pie with the given ID, if it exists.
+ /////////////////////////////////////////////////////////////////////
+
+ public static void open_pie(string id) {
+ if (!a_pie_is_opened) {
+ Pie? pie = all_pies[id];
+
+ if (pie != null) {
+ a_pie_is_opened = true;
+
+ var window = new PieWindow();
+ window.load_pie(pie);
+ window.open();
+
+ window.on_closing.connect(() => {
+ a_pie_is_opened = false;
+ });
+ } else {
+ warning("Failed to open pie with ID \"" + id + "\": ID does not exist!");
+ }
+ }
+ }
+
+ /////////////////////////////////////////////////////////////////////
+ /// Returns the hotkey which the Pie with the given ID is bound to.
+ /////////////////////////////////////////////////////////////////////
+
+ public static string get_accelerator_of(string id) {
+ return bindings.get_accelerator_of(id);
+ }
+
+ /////////////////////////////////////////////////////////////////////
+ /// Returns a human-readable version of the hotkey which the Pie
+ /// with the given ID is bound to.
+ /////////////////////////////////////////////////////////////////////
+
+ public static string get_accelerator_label_of(string id) {
+ return bindings.get_accelerator_label_of(id);
+ }
+
+ /////////////////////////////////////////////////////////////////////
+ /// Returns the name of the Pie with the given ID.
+ /////////////////////////////////////////////////////////////////////
+
+ public static string get_name_of(string id) {
+ Pie? pie = all_pies[id];
+ if (pie == null) return "";
+ else return pie.name;
+ }
+
+ /////////////////////////////////////////////////////////////////////
+ /// Creates a new Pie which is displayed in the configuration dialog
+ /// and gets saved.
+ /////////////////////////////////////////////////////////////////////
+
+ public static Pie create_persistent_pie(string name, string icon_name, string hotkey, string? desired_id = null) {
+ Pie pie = create_pie(name, icon_name, 100, 999, desired_id);
+
+ if (hotkey != "") bindings.bind(hotkey, pie.id);
+
+ create_launcher(pie.id);
+
+ return pie;
+ }
+
+ /////////////////////////////////////////////////////////////////////
+ /// Creates a new Pie which is not displayed in the configuration
+ /// dialog and is not saved.
+ /////////////////////////////////////////////////////////////////////
+
+ public static Pie create_dynamic_pie(string name, string icon_name, string? desired_id = null) {
+ return create_pie(name, icon_name, 1000, 9999, desired_id);
+ }
+
+ /////////////////////////////////////////////////////////////////////
+ /// Adds a new Pie. Can't be accesd from outer scope. Use
+ /// create_persistent_pie or create_dynamic_pie instead.
+ /////////////////////////////////////////////////////////////////////
+
+ private static Pie create_pie(string name, string icon_name, int min_id, int max_id, string? desired_id = null) {
+ var random = new GLib.Rand();
+
+ string final_id;
+
+ if (desired_id == null)
+ final_id = random.int_range(min_id, max_id).to_string();
+ else {
+ final_id = desired_id;
+ final_id.canon("0123456789", '_');
+ final_id = final_id.replace("_", "");
+
+ int id = int.parse(final_id);
+
+ if (id < min_id || id > max_id) {
+ final_id = random.int_range(min_id, max_id).to_string();
+ warning("The ID for pie \"" + name + "\" should be in range %u - %u! Using \"" + final_id + "\" instead of \"" + desired_id + "\"...", min_id, max_id);
+ }
+ }
+
+ if (all_pies.has_key(final_id)) {
+ var tmp = final_id;
+ var id_number = int.parse(final_id) + 1;
+ if (id_number == max_id+1) id_number = min_id;
+ final_id = id_number.to_string();
+ warning("Trying to add pie \"" + name + "\": ID \"" + tmp + "\" already exists! Using \"" + final_id + "\" instead...");
+ return create_pie(name, icon_name, min_id, max_id, final_id);
+ }
+
+ Pie pie = new Pie(final_id, name, icon_name);
+ all_pies.set(final_id, pie);
+
+ return pie;
+ }
+
+ /////////////////////////////////////////////////////////////////////
+ /// Removes the Pie with the given ID if it exists. Additionally it
+ /// unbinds it's global hotkey.
+ /////////////////////////////////////////////////////////////////////
+
+ public static void remove_pie(string id) {
+ if (all_pies.has_key(id)) {
+ all_pies[id].on_remove();
+ all_pies.unset(id);
+ bindings.unbind(id);
+
+ if (id.length == 3)
+ remove_launcher(id);
+ }
+ else {
+ warning("Failed to remove pie with ID \"" + id + "\": ID does not exist!");
+ }
+ }
+
+ private static void create_launcher(string id) {
+ if (all_pies.has_key(id)) {
+ Pie? pie = all_pies[id];
+
+ string launcher_entry =
+ "#!/usr/bin/env xdg-open\n" +
+ "[Desktop Entry]\n" +
+ "Name=%s\n".printf(pie.name) +
+ "Exec=gnome-pie -o %s\n".printf(pie.id) +
+ "Encoding=UTF-8\n" +
+ "Type=Application\n" +
+ "Icon=%s\n".printf(pie.icon);
+
+ // create the launcher file
+ string launcher = Paths.launchers + "/%s.desktop".printf(pie.id);
+
+ try {
+ FileUtils.set_contents(launcher, launcher_entry);
+ FileUtils.chmod(launcher, 0755);
+ } catch (Error e) {
+ warning(e.message);
+ }
+ }
+ }
+
+ private static void remove_launcher(string id) {
+ string launcher = Paths.launchers + "/%s.desktop".printf(id);
+ if (FileUtils.test(launcher, FileTest.EXISTS)) {
+ FileUtils.remove(launcher);
+ }
+ }
+}
+
+}
diff --git a/src/pies/save.vala b/src/pies/save.vala
new file mode 100644
index 0000000..d691a95
--- /dev/null
+++ b/src/pies/save.vala
@@ -0,0 +1,81 @@
+/*
+Copyright (c) 2011 by Simon Schneegans
+
+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 3 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, see <http://www.gnu.org/licenses/>.
+*/
+
+using GLib.Math;
+
+namespace GnomePie {
+
+/////////////////////////////////////////////////////////////////////////
+/// A helper method which saves pies in a configuration file.
+/////////////////////////////////////////////////////////////////////////
+
+namespace Pies {
+
+ /////////////////////////////////////////////////////////////////////
+ /// Saves all Pies of the PieManager to the pies.conf file.
+ /////////////////////////////////////////////////////////////////////
+
+ public void save() {
+ // initializes the XML-Writer
+ var writer = new Xml.TextWriter.filename(Paths.pie_config);
+ writer.set_indent(true);
+ writer.start_document("1.0");
+ writer.start_element("pies");
+
+ // iterate through all Pies
+ foreach (var pie_entry in PieManager.all_pies.entries) {
+ var pie = pie_entry.value;
+
+ // if it's no dynamically created Pie
+ if (pie.id.length == 3) {
+ // write all attributes of the Pie
+ writer.start_element("pie");
+ writer.write_attribute("name", pie.name);
+ writer.write_attribute("id", pie.id);
+ writer.write_attribute("icon", pie.icon);
+ writer.write_attribute("hotkey", PieManager.get_accelerator_of(pie.id));
+
+ // and all of it's Actions
+ foreach (var group in pie.action_groups) {
+ // if it's a custom ActionGroup
+ if (group.get_type().depth() == 2) {
+ foreach (var action in group.actions) {
+ writer.start_element("slice");
+ writer.write_attribute("type", ActionRegistry.settings_names[action.get_type()]);
+ if (ActionRegistry.icon_name_editables[action.get_type()]) {
+ writer.write_attribute("name", action.name);
+ writer.write_attribute("icon", action.icon);
+ }
+ writer.write_attribute("command", action.real_command);
+ writer.write_attribute("quickAction", action.is_quick_action ? "true" : "false");
+ writer.end_element();
+ }
+ } else {
+ writer.start_element("group");
+ writer.write_attribute("type", GroupRegistry.settings_names[group.get_type()]);
+ writer.end_element();
+ }
+ }
+ writer.end_element();
+ }
+ }
+ writer.end_element();
+ writer.end_document();
+ }
+}
+
+}
diff --git a/src/renderers/centerRenderer.vala b/src/renderers/centerRenderer.vala
new file mode 100644
index 0000000..c30e9ce
--- /dev/null
+++ b/src/renderers/centerRenderer.vala
@@ -0,0 +1,146 @@
+/*
+Copyright (c) 2011 by Simon Schneegans
+
+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 3 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, see <http://www.gnu.org/licenses/>.
+*/
+
+using GLib.Math;
+
+namespace GnomePie {
+
+// Renders the center of a Pie.
+
+public class CenterRenderer : GLib.Object {
+
+ private unowned PieRenderer parent;
+ private unowned Image? caption;
+ private Color color;
+
+ private AnimatedValue activity;
+ private AnimatedValue alpha;
+
+ public CenterRenderer(PieRenderer parent) {
+ this.parent = parent;
+ this.activity = new AnimatedValue.linear(0.0, 0.0, Config.global.theme.transition_time);
+ this.alpha = new AnimatedValue.linear(0.0, 1.0, Config.global.theme.fade_in_time);
+ this.color = new Color();
+ this.caption = null;
+ }
+
+ public void fade_out() {
+ this.activity.reset_target(0.0, Config.global.theme.fade_out_time);
+ this.alpha.reset_target(0.0, Config.global.theme.fade_out_time);
+ }
+
+ public void set_active_slice(SliceRenderer? active_slice) {
+ if (active_slice == null) {
+ this.activity.reset_target(0.0, Config.global.theme.transition_time);
+ } else {
+ this.activity.reset_target(1.0, Config.global.theme.transition_time);
+ this.caption = active_slice.caption;
+ this.color = active_slice.color;
+ }
+ }
+
+ public void draw(double frame_time, Cairo.Context ctx, double angle, double distance) {
+
+ var layers = Config.global.theme.center_layers;
+
+ this.activity.update(frame_time);
+ this.alpha.update(frame_time);
+
+ foreach (var layer in layers) {
+
+ ctx.save();
+
+ double active_speed = (layer.active_rotation_mode == CenterLayer.RotationMode.TO_MOUSE) ?
+ 0.0 : layer.active_rotation_speed;
+ double inactive_speed = (layer.inactive_rotation_mode == CenterLayer.RotationMode.TO_MOUSE) ?
+ 0.0 : layer.inactive_rotation_speed;
+ double max_scale = layer.active_scale*this.activity.val
+ + layer.inactive_scale*(1.0-this.activity.val);
+ double max_alpha = layer.active_alpha*this.activity.val
+ + layer.inactive_alpha*(1.0-this.activity.val);
+ double colorize = ((layer.active_colorize == true) ? this.activity.val : 0.0)
+ + ((layer.inactive_colorize == true) ? 1.0 - this.activity.val : 0.0);
+ double max_rotation_speed = active_speed*this.activity.val
+ + inactive_speed*(1.0-this.activity.val);
+ CenterLayer.RotationMode rotation_mode = ((this.activity.val > 0.5) ?
+ layer.active_rotation_mode : layer.inactive_rotation_mode);
+
+ if (rotation_mode == CenterLayer.RotationMode.TO_MOUSE) {
+ double diff = angle-layer.rotation;
+ max_rotation_speed = layer.active_rotation_speed*this.activity.val
+ + layer.inactive_rotation_speed*(1.0-this.activity.val);
+ double smoothy = fabs(diff) < 0.9 ? fabs(diff) + 0.1 : 1.0;
+ double step = max_rotation_speed*frame_time*smoothy;
+
+ if (fabs(diff) <= step || fabs(diff) >= 2.0*PI - step)
+ layer.rotation = angle;
+ else {
+ if ((diff > 0 && diff < PI) || diff < -PI) layer.rotation += step;
+ else layer.rotation -= step;
+ }
+
+ } else if (rotation_mode == CenterLayer.RotationMode.TO_ACTIVE) {
+ max_rotation_speed *= this.activity.val;
+
+ double slice_angle = parent.slice_count() > 0 ? 2*PI/parent.slice_count() : 0;
+ double direction = (int)((angle+0.5*slice_angle) / (slice_angle))*slice_angle;
+ double diff = direction-layer.rotation;
+ double step = max_rotation_speed*frame_time;
+
+ if (fabs(diff) <= step || fabs(diff) >= 2.0*PI - step)
+ layer.rotation = direction;
+ else {
+ if ((diff > 0 && diff < PI) || diff < -PI) layer.rotation += step;
+ else layer.rotation -= step;
+ }
+
+ } else layer.rotation += max_rotation_speed*frame_time;
+
+ layer.rotation = fmod(layer.rotation+2*PI, 2*PI);
+
+ if (colorize > 0.0) ctx.push_group();
+
+ ctx.rotate(layer.rotation);
+ ctx.scale(max_scale, max_scale);
+ layer.image.paint_on(ctx, this.alpha.val*max_alpha);
+
+ if (colorize > 0.0) {
+ ctx.set_operator(Cairo.Operator.ATOP);
+ ctx.set_source_rgb(this.color.r, this.color.g, this.color.b);
+ ctx.paint_with_alpha(colorize);
+
+ ctx.set_operator(Cairo.Operator.OVER);
+ ctx.pop_group_to_source();
+ ctx.paint();
+ }
+
+ ctx.restore();
+ }
+
+ // draw caption
+ if (Config.global.theme.caption && caption != null && this.activity.val > 0) {
+ ctx.save();
+ ctx.identity_matrix();
+ int pos = this.parent.get_size()/2;
+ ctx.translate(pos, (int)(Config.global.theme.caption_position) + pos);
+ caption.paint_on(ctx, this.activity.val*this.alpha.val);
+ ctx.restore();
+ }
+ }
+}
+
+}
diff --git a/src/renderers/pieRenderer.vala b/src/renderers/pieRenderer.vala
new file mode 100644
index 0000000..5b706f4
--- /dev/null
+++ b/src/renderers/pieRenderer.vala
@@ -0,0 +1,208 @@
+/*
+Copyright (c) 2011 by Simon Schneegans
+
+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 3 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, see <http://www.gnu.org/licenses/>.
+*/
+
+using GLib.Math;
+
+namespace GnomePie {
+
+/////////////////////////////////////////////////////////////////////////
+/// This class renders a Pie. In order to accomplish that, it owns a
+/// CenterRenderer and some SliceRenderers.
+/////////////////////////////////////////////////////////////////////////
+
+public class PieRenderer : GLib.Object {
+
+ public int quick_action { get; private set; }
+ public int active_slice { get; private set; }
+ public bool show_hotkeys { get; set; }
+
+ private int size;
+ private Gee.ArrayList<SliceRenderer?> slices;
+ private CenterRenderer center;
+ private bool key_board_control = false;
+
+ public PieRenderer() {
+ this.slices = new Gee.ArrayList<SliceRenderer?>();
+ this.center = new CenterRenderer(this);
+ this.quick_action = -1;
+ this.active_slice = -2;
+ this.size = 0;
+ }
+
+ public void load_pie(Pie pie) {
+ this.slices.clear();
+
+ int count = 0;
+ foreach (var group in pie.action_groups) {
+ foreach (var action in group.actions) {
+ var renderer = new SliceRenderer(this);
+ this.slices.add(renderer);
+ renderer.load(action, slices.size-1);
+
+ if (action.is_quick_action) {
+ this.quick_action = count;
+ }
+
+ ++count;
+ }
+ }
+
+ this.set_highlighted_slice(this.quick_action);
+
+ this.size = (int)fmax(2*Config.global.theme.radius + 2*Config.global.theme.slice_radius*Config.global.theme.max_zoom,
+ 2*Config.global.theme.center_radius);
+
+ // increase size if there are many slices
+ if (slices.size > 0) {
+ this.size = (int)fmax(this.size,
+ (((Config.global.theme.slice_radius + Config.global.theme.slice_gap)/tan(PI/slices.size))
+ + Config.global.theme.slice_radius)*2*Config.global.theme.max_zoom);
+ }
+ }
+
+ public void activate() {
+ if (this.active_slice >= 0 && this.active_slice < this.slices.size)
+ slices[active_slice].activate();
+ this.cancel();
+ }
+
+ public void cancel() {
+ foreach (var slice in this.slices)
+ slice.fade_out();
+
+ center.fade_out();
+ }
+
+ public void select_up() {
+ int bottom = this.slice_count()/4;
+ int top = this.slice_count()*3/4;
+
+ if (this.active_slice == -1 || this.active_slice == bottom)
+ this.set_highlighted_slice(top);
+ else if (this.active_slice > bottom && this.active_slice < top)
+ this.set_highlighted_slice(this.active_slice+1);
+ else if (this.active_slice != top)
+ this.set_highlighted_slice((this.active_slice-1+this.slice_count())%this.slice_count());
+ }
+
+ public void select_down() {
+ int bottom = this.slice_count()/4;
+ int top = this.slice_count()*3/4;
+
+ if (this.active_slice == -1 || this.active_slice == top)
+ this.set_highlighted_slice(bottom);
+ else if (this.active_slice > bottom && this.active_slice < top)
+ this.set_highlighted_slice(this.active_slice-1);
+ else if (this.active_slice != bottom)
+ this.set_highlighted_slice((this.active_slice+1)%this.slice_count());
+ }
+
+ public void select_left() {
+ int left = this.slice_count()/2;
+ int right = 0;
+
+ if (this.active_slice == -1 || this.active_slice == right)
+ this.set_highlighted_slice(left);
+ else if (this.active_slice > left)
+ this.set_highlighted_slice(this.active_slice-1);
+ else if (this.active_slice < left)
+ this.set_highlighted_slice(this.active_slice+1);
+ }
+
+ public void select_right() {
+ int left = this.slice_count()/2;
+ int right = 0;
+
+ if (this.active_slice == -1 || this.active_slice == left)
+ this.set_highlighted_slice(right);
+ else if (this.active_slice > left)
+ this.set_highlighted_slice((this.active_slice+1)%this.slice_count());
+ else if (this.active_slice < left && this.active_slice != right)
+ this.set_highlighted_slice((this.active_slice-1+this.slice_count())%this.slice_count());
+ }
+
+ public int slice_count() {
+ return slices.size;
+ }
+
+ public int get_size() {
+ return size;
+ }
+
+ public void draw(double frame_time, Cairo.Context ctx, int mouse_x, int mouse_y) {
+ double distance = sqrt(mouse_x*mouse_x + mouse_y*mouse_y);
+ double angle = 0.0;
+
+ if (this.key_board_control) {
+ angle = 2.0*PI*this.active_slice/(double)slice_count();
+ } else {
+
+ if (distance > 0) {
+ angle = acos(mouse_x/distance);
+ if (mouse_y < 0)
+ angle = 2*PI - angle;
+ }
+
+ int next_active_slice = this.active_slice;
+
+ if (distance < Config.global.theme.active_radius
+ && this.quick_action >= 0 && this.quick_action < this.slices.size) {
+
+ next_active_slice = this.quick_action;
+ angle = 2.0*PI*quick_action/(double)slice_count();
+ } else if (distance > Config.global.theme.active_radius && this.slice_count() > 0) {
+ next_active_slice = (int)(angle*slices.size/(2*PI) + 0.5) % this.slice_count();
+ } else {
+ next_active_slice = -1;
+ }
+
+ this.set_highlighted_slice(next_active_slice);
+ }
+
+ center.draw(frame_time, ctx, angle, distance);
+
+ foreach (var slice in this.slices)
+ slice.draw(frame_time, ctx, angle, distance);
+ }
+
+ public void on_mouse_move() {
+ this.key_board_control = false;
+ }
+
+ public void set_highlighted_slice(int index) {
+ if (index != this.active_slice) {
+ if (index >= 0 && index < this.slice_count())
+ this.active_slice = index;
+ else if (this.quick_action >= 0)
+ this.active_slice = this.quick_action;
+ else
+ this.active_slice = -1;
+
+ SliceRenderer? active = (this.active_slice >= 0 && this.active_slice < this.slice_count()) ?
+ this.slices[this.active_slice] : null;
+
+ center.set_active_slice(active);
+
+ foreach (var slice in this.slices)
+ slice.set_active_slice(active);
+
+ this.key_board_control = true;
+ }
+ }
+}
+
+}
diff --git a/src/renderers/pieWindow.vala b/src/renderers/pieWindow.vala
new file mode 100644
index 0000000..c4ac2ec
--- /dev/null
+++ b/src/renderers/pieWindow.vala
@@ -0,0 +1,263 @@
+/*
+Copyright (c) 2011 by Simon Schneegans
+
+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 3 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, see <http://www.gnu.org/licenses/>.
+*/
+
+using GLib.Math;
+
+namespace GnomePie {
+
+// An invisible window. Used to draw Pies onto.
+
+public class PieWindow : Gtk.Window {
+
+ public signal void on_closing();
+
+ private PieRenderer renderer;
+ private bool closing = false;
+ private GLib.Timer timer;
+
+ private bool has_compositing = false;
+
+ private Image background = null;
+
+ public PieWindow() {
+ this.renderer = new PieRenderer();
+
+ this.set_title("Gnome-Pie");
+ this.set_skip_taskbar_hint(true);
+ this.set_skip_pager_hint(true);
+ this.set_keep_above(true);
+ this.set_type_hint(Gdk.WindowTypeHint.SPLASHSCREEN);
+ this.set_decorated(false);
+ this.set_resizable(false);
+ this.icon_name = "gnome-pie";
+ this.set_accept_focus(false);
+
+ if (this.screen.is_composited()) {
+ this.set_colormap(this.screen.get_rgba_colormap());
+ this.has_compositing = true;
+ }
+
+ this.add_events(Gdk.EventMask.BUTTON_RELEASE_MASK |
+ Gdk.EventMask.KEY_RELEASE_MASK |
+ Gdk.EventMask.KEY_PRESS_MASK |
+ Gdk.EventMask.POINTER_MOTION_MASK);
+
+ this.button_release_event.connect ((e) => {
+ if (e.button == 1) this.activate_slice();
+ else this.cancel();
+ return true;
+ });
+
+ // remember last pressed key in order to disable key repeat
+ uint last_key = 0;
+ this.key_press_event.connect((e) => {
+ if (e.keyval != last_key) {
+ last_key = e.keyval;
+ this.handle_key_press(e.keyval);
+ }
+ return true;
+ });
+
+ this.key_release_event.connect((e) => {
+ last_key = 0;
+ if (Config.global.turbo_mode)
+ this.activate_slice();
+ else
+ this.handle_key_release(e.keyval);
+ return true;
+ });
+
+ this.motion_notify_event.connect((e) => {
+ this.renderer.on_mouse_move();
+ return true;
+ });
+
+ this.expose_event.connect(this.draw);
+ }
+
+ public void load_pie(Pie pie) {
+ this.renderer.load_pie(pie);
+ this.set_window_position();
+ this.set_size_request(renderer.get_size(), renderer.get_size());
+ }
+
+ public void open() {
+ this.realize();
+
+ if (!this.has_compositing) {
+ int x, y, width, height;
+ this.get_position(out x, out y);
+ this.get_size(out width, out height);
+ this.background = new Image.capture_screen(x, y, width+1, height+1);
+ }
+
+ this.show();
+ this.fix_focus();
+
+ this.timer = new GLib.Timer();
+ this.timer.start();
+ this.queue_draw();
+
+ Timeout.add((uint)(1000.0/Config.global.refresh_rate), () => {
+ this.queue_draw();
+ return this.visible;
+ });
+ }
+
+ private bool draw(Gtk.Widget da, Gdk.EventExpose event) {
+ // clear the window
+ var ctx = Gdk.cairo_create(this.window);
+
+ if (this.has_compositing) {
+ ctx.set_operator (Cairo.Operator.CLEAR);
+ ctx.paint();
+ ctx.set_operator (Cairo.Operator.OVER);
+ } else {
+ ctx.set_operator (Cairo.Operator.OVER);
+ ctx.set_source_surface(background.surface, -1, -1);
+ ctx.paint();
+ }
+
+ ctx.translate(this.width_request*0.5, this.height_request*0.5);
+
+ double mouse_x = 0.0, mouse_y = 0.0;
+ this.get_pointer(out mouse_x, out mouse_y);
+
+ double frame_time = this.timer.elapsed();
+ this.timer.reset();
+
+ this.renderer.draw(frame_time, ctx, (int)(mouse_x - this.width_request*0.5),
+ (int)(mouse_y - this.height_request*0.5));
+
+ return true;
+ }
+
+ private void activate_slice() {
+ if (!this.closing) {
+ this.closing = true;
+ this.on_closing();
+ this.unfix_focus();
+ this.renderer.activate();
+
+ Timeout.add((uint)(Config.global.theme.fade_out_time*1000), () => {
+ this.destroy();
+ //ThemedIcon.clear_cache();
+ return false;
+ });
+ }
+ }
+
+ private void cancel() {
+ if (!this.closing) {
+ this.closing = true;
+ this.on_closing();
+ this.unfix_focus();
+ this.renderer.cancel();
+
+ Timeout.add((uint)(Config.global.theme.fade_out_time*1000), () => {
+ this.destroy();
+ //ThemedIcon.clear_cache();
+ return false;
+ });
+ }
+ }
+
+ private void set_window_position() {
+ if(Config.global.open_at_mouse) this.set_position(Gtk.WindowPosition.MOUSE);
+ else this.set_position(Gtk.WindowPosition.CENTER);
+ }
+
+ private void handle_key_press(uint key) {
+ if (Gdk.keyval_name(key) == "Escape") this.cancel();
+ else if (Gdk.keyval_name(key) == "Return") this.activate_slice();
+ else if (!Config.global.turbo_mode) {
+ if (Gdk.keyval_name(key) == "Up") this.renderer.select_up();
+ else if (Gdk.keyval_name(key) == "Down") this.renderer.select_down();
+ else if (Gdk.keyval_name(key) == "Left") this.renderer.select_left();
+ else if (Gdk.keyval_name(key) == "Right") this.renderer.select_right();
+ else if (Gdk.keyval_name(key) == "Alt_L") this.renderer.show_hotkeys = true;
+ else {
+ int index = -1;
+
+ if (key >= 48 && key <= 57) index = (int)key - 48;
+ else if (key >= 97 && key <= 122) index = (int)key - 87;
+ else if (key >= 65 && key <= 90) index = (int)key - 55;
+
+ if (index >= 0 && index < this.renderer.slice_count()) {
+ this.renderer.set_highlighted_slice(index);
+
+ if (this.renderer.active_slice == index) {
+ GLib.Timeout.add((uint)(Config.global.theme.transition_time*1000.0), ()=> {
+ this.activate_slice();
+ return false;
+ });
+ }
+
+ }
+ }
+ }
+ }
+
+ private void handle_key_release(uint key) {
+ if (!Config.global.turbo_mode) {
+ if (Gdk.keyval_name(key) == "Alt_L") this.renderer.show_hotkeys = false;
+ }
+ }
+
+ // utilities for grabbing focus
+ // Code from Gnome-Do/Synapse
+ private void fix_focus() {
+ uint32 timestamp = Gtk.get_current_event_time();
+ this.present_with_time(timestamp);
+ this.get_window().raise();
+ this.get_window().focus(timestamp);
+
+ int i = 0;
+ Timeout.add(100, () => {
+ if (++i >= 100) return false;
+ return !try_grab_window();
+ });
+ }
+
+ // Code from Gnome-Do/Synapse
+ private void unfix_focus() {
+ uint32 time = Gtk.get_current_event_time();
+ Gdk.pointer_ungrab(time);
+ Gdk.keyboard_ungrab(time);
+ Gtk.grab_remove(this);
+ }
+
+ // Code from Gnome-Do/Synapse
+ private bool try_grab_window() {
+ uint time = Gtk.get_current_event_time();
+ if (Gdk.pointer_grab(this.get_window(), true, Gdk.EventMask.BUTTON_PRESS_MASK |
+ Gdk.EventMask.BUTTON_RELEASE_MASK | Gdk.EventMask.POINTER_MOTION_MASK,
+ null, null, time) == Gdk.GrabStatus.SUCCESS) {
+
+ if (Gdk.keyboard_grab(this.get_window(), true, time) == Gdk.GrabStatus.SUCCESS) {
+ Gtk.grab_add(this);
+ return true;
+ } else {
+ Gdk.pointer_ungrab(time);
+ return false;
+ }
+ }
+ return false;
+ }
+}
+
+}
diff --git a/src/renderers/sliceRenderer.vala b/src/renderers/sliceRenderer.vala
new file mode 100644
index 0000000..08c880f
--- /dev/null
+++ b/src/renderers/sliceRenderer.vala
@@ -0,0 +1,182 @@
+/*
+Copyright (c) 2011 by Simon Schneegans
+
+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 3 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, see <http://www.gnu.org/licenses/>.
+*/
+
+using GLib.Math;
+
+namespace GnomePie {
+
+// Renders a Slice of a Pie. According to the current theme.
+
+public class SliceRenderer : GLib.Object {
+
+ public bool active {get; private set; default = false;}
+ public Image caption {get; private set;}
+ public Color color {get; private set;}
+
+ private Image active_icon;
+ private Image inactive_icon;
+ private Image hotkey;
+
+ private Action action;
+
+ private unowned PieRenderer parent;
+ private int position;
+
+ private AnimatedValue fade;
+ private AnimatedValue scale;
+ private AnimatedValue alpha;
+ private AnimatedValue fade_rotation;
+ private AnimatedValue fade_scale;
+
+ public SliceRenderer(PieRenderer parent) {
+ this.parent = parent;
+
+ this.fade = new AnimatedValue.linear(0.0, 0.0, Config.global.theme.transition_time);
+ this.alpha = new AnimatedValue.linear(0.0, 1.0, Config.global.theme.fade_in_time);
+ this.scale = new AnimatedValue.cubic(AnimatedValue.Direction.OUT,
+ 1.0/Config.global.theme.max_zoom,
+ 1.0/Config.global.theme.max_zoom,
+ Config.global.theme.transition_time,
+ Config.global.theme.springiness);
+ this.fade_scale = new AnimatedValue.cubic(AnimatedValue.Direction.OUT,
+ Config.global.theme.fade_in_zoom, 1.0,
+ Config.global.theme.fade_in_time,
+ Config.global.theme.springiness);
+ this.fade_rotation = new AnimatedValue.cubic(AnimatedValue.Direction.OUT,
+ Config.global.theme.fade_in_rotation, 0.0,
+ Config.global.theme.fade_in_time);
+ }
+
+ public void load(Action action, int position) {
+ this.position = position;
+ this.action = action;
+
+
+ if (Config.global.theme.caption)
+ this.caption = new RenderedText(action.name,
+ Config.global.theme.caption_width,
+ Config.global.theme.caption_height,
+ Config.global.theme.caption_font);
+
+ this.active_icon = new ThemedIcon(action.icon, true);
+ this.inactive_icon = new ThemedIcon(action.icon, false);
+
+ this.color = new Color.from_icon(this.active_icon);
+
+ string hotkey_label = "";
+ if (position < 10) {
+ hotkey_label = "%u".printf(position);
+ } else if (position < 36) {
+ hotkey_label = "%c".printf((char)(55 + position));
+ }
+
+ this.hotkey = new RenderedText(hotkey_label, (int)Config.global.theme.slice_radius*2,
+ (int)Config.global.theme.slice_radius*2, "sans 20");
+ }
+
+ public void activate() {
+ action.activate();
+ }
+
+ public void fade_out() {
+ this.alpha.reset_target(0.0, Config.global.theme.fade_out_time);
+ this.fade_scale = new AnimatedValue.cubic(AnimatedValue.Direction.IN,
+ this.fade_scale.val,
+ Config.global.theme.fade_out_zoom,
+ Config.global.theme.fade_out_time,
+ Config.global.theme.springiness);
+ this.fade_rotation = new AnimatedValue.cubic(AnimatedValue.Direction.IN,
+ this.fade_rotation.val,
+ Config.global.theme.fade_out_rotation,
+ Config.global.theme.fade_out_time);
+ }
+
+ public void set_active_slice(SliceRenderer? active_slice) {
+ if (active_slice == this) {
+ this.fade.reset_target(1.0, Config.global.theme.transition_time);
+ } else {
+ this.fade.reset_target(0.0, Config.global.theme.transition_time);
+ }
+ }
+
+ public void draw(double frame_time, Cairo.Context ctx, double angle, double distance) {
+
+ double direction = 2.0 * PI * position/parent.slice_count() + this.fade_rotation.val;
+ double max_scale = 1.0/Config.global.theme.max_zoom;
+ double diff = fabs(angle-direction);
+
+ if (diff > PI)
+ diff = 2 * PI - diff;
+
+ if (diff < 2 * PI * Config.global.theme.zoom_range)
+ max_scale = (Config.global.theme.max_zoom/(diff * (Config.global.theme.max_zoom - 1)
+ /(2 * PI * Config.global.theme.zoom_range) + 1))
+ /Config.global.theme.max_zoom;
+
+ active = ((parent.active_slice >= 0) && (diff < PI/parent.slice_count()));
+
+ max_scale = (parent.active_slice >= 0 ? max_scale : 1.0/Config.global.theme.max_zoom);
+
+ if (fabs(this.scale.end - max_scale) > Config.global.theme.max_zoom*0.005)
+ this.scale.reset_target(max_scale, Config.global.theme.transition_time);
+
+ this.scale.update(frame_time);
+ this.alpha.update(frame_time);
+ this.fade.update(frame_time);
+ this.fade_scale.update(frame_time);
+ this.fade_rotation.update(frame_time);
+
+ ctx.save();
+
+ double radius = Config.global.theme.radius;
+
+ if (atan((Config.global.theme.slice_radius+Config.global.theme.slice_gap)
+ /(radius/Config.global.theme.max_zoom)) > PI/parent.slice_count()) {
+ radius = (Config.global.theme.slice_radius+Config.global.theme.slice_gap)
+ /tan(PI/parent.slice_count())*Config.global.theme.max_zoom;
+ }
+
+ ctx.scale(scale.val*fade_scale.val, scale.val*fade_scale.val);
+ ctx.translate(cos(direction)*radius, sin(direction)*radius);
+
+ ctx.push_group();
+
+ ctx.set_operator(Cairo.Operator.ADD);
+
+ if (fade.val > 0.0) active_icon.paint_on(ctx, this.alpha.val*this.fade.val);
+ if (fade.val < 1.0) inactive_icon.paint_on(ctx, this.alpha.val*(1.0 - fade.val));
+
+ if (this.parent.show_hotkeys) {
+ ctx.set_operator(Cairo.Operator.ATOP);
+ ctx.set_source_rgba(0, 0, 0, 0.5);
+ ctx.paint();
+ }
+
+ ctx.set_operator(Cairo.Operator.OVER);
+
+
+ ctx.pop_group_to_source();
+ ctx.paint();
+
+ if (this.parent.show_hotkeys)
+ this.hotkey.paint_on(ctx, 1.0);
+
+ ctx.restore();
+ }
+}
+
+}
diff --git a/src/themes/centerLayer.vala b/src/themes/centerLayer.vala
new file mode 100644
index 0000000..3469fd0
--- /dev/null
+++ b/src/themes/centerLayer.vala
@@ -0,0 +1,111 @@
+/*
+Copyright (c) 2011 by Simon Schneegans
+
+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 3 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, see <http://www.gnu.org/licenses/>.
+*/
+
+namespace GnomePie {
+
+/////////////////////////////////////////////////////////////////////////
+/// This class representing a layer of the center of a pie. Each theme
+/// may have plenty of them.
+/////////////////////////////////////////////////////////////////////////
+
+public class CenterLayer : GLib.Object {
+
+ /////////////////////////////////////////////////////////////////////
+ /// Possible rotation modes.
+ /// AUTO: Turns the layer continously.
+ /// TO_MOUSE: Turns the layer always to the pointer.
+ /// TO_ACTIVE: Turns the layer to the active slice.
+ /////////////////////////////////////////////////////////////////////
+
+ public enum RotationMode {AUTO, TO_MOUSE, TO_ACTIVE}
+
+ /////////////////////////////////////////////////////////////////////
+ /// Information on the contained image.
+ /////////////////////////////////////////////////////////////////////
+
+ public Image image {get; private set;}
+ public string image_file;
+
+ /////////////////////////////////////////////////////////////////////
+ /// Properties for the active state of this layer.
+ /////////////////////////////////////////////////////////////////////
+
+ public double active_scale {get; private set;}
+ public double active_rotation_speed {get; private set;}
+ public double active_alpha {get; private set;}
+ public bool active_colorize {get; private set;}
+ public RotationMode active_rotation_mode {get; private set;}
+
+ /////////////////////////////////////////////////////////////////////
+ /// Properties for the inactive state of this layer.
+ /////////////////////////////////////////////////////////////////////
+
+ public double inactive_scale {get; private set;}
+ public double inactive_rotation_speed {get; private set;}
+ public double inactive_alpha {get; private set;}
+ public bool inactive_colorize {get; private set;}
+ public RotationMode inactive_rotation_mode {get; private set;}
+
+ /////////////////////////////////////////////////////////////////////
+ /// The current rotation of this layer. TODO: Remove this.
+ /////////////////////////////////////////////////////////////////////
+
+ public double rotation {get; set;}
+
+ /////////////////////////////////////////////////////////////////////
+ /// Helper variable for image loading.
+ /////////////////////////////////////////////////////////////////////
+
+ private int center_radius;
+
+ /////////////////////////////////////////////////////////////////////
+ /// C'tor, initializes all members of the layer.
+ /////////////////////////////////////////////////////////////////////
+
+ public CenterLayer(string image_file, int center_radius, double active_scale, double active_rotation_speed,
+ double active_alpha, bool active_colorize, RotationMode active_rotation_mode,
+ double inactive_scale, double inactive_rotation_speed,
+ double inactive_alpha, bool inactive_colorize, RotationMode inactive_rotation_mode) {
+
+ this.image_file = image_file;
+ this.center_radius = center_radius;
+
+ this.active_scale = active_scale;
+ this.active_rotation_speed = active_rotation_speed;
+ this.active_alpha = active_alpha;
+ this.active_colorize = active_colorize;
+ this.active_rotation_mode = active_rotation_mode;
+
+ this.inactive_scale = inactive_scale;
+ this.inactive_rotation_speed = inactive_rotation_speed;
+ this.inactive_alpha = inactive_alpha;
+ this.inactive_colorize = inactive_colorize;
+ this.inactive_rotation_mode = inactive_rotation_mode;
+
+ this.rotation = 0.0;
+ }
+
+ /////////////////////////////////////////////////////////////////////
+ /// Loads the contained image.
+ /////////////////////////////////////////////////////////////////////
+
+ public void load_image() {
+ this.image = new Image.from_file_at_size(image_file, 2*center_radius, 2*center_radius);
+ }
+}
+
+}
diff --git a/src/themes/sliceLayer.vala b/src/themes/sliceLayer.vala
new file mode 100644
index 0000000..2620912
--- /dev/null
+++ b/src/themes/sliceLayer.vala
@@ -0,0 +1,65 @@
+/*
+Copyright (c) 2011 by Simon Schneegans
+
+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 3 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, see <http://www.gnu.org/licenses/>.
+*/
+
+namespace GnomePie {
+
+/////////////////////////////////////////////////////////////////////////
+/// This class representing a layer of a slice of a pie. Each theme may
+/// have plenty of them.
+/////////////////////////////////////////////////////////////////////////
+
+public class SliceLayer : GLib.Object {
+
+ /////////////////////////////////////////////////////////////////////
+ /// Information on the contained image.
+ /////////////////////////////////////////////////////////////////////
+
+ public Image image {get; set;}
+ public string icon_file {get; private set;}
+
+ /////////////////////////////////////////////////////////////////////
+ /// Properties of this layer.
+ /////////////////////////////////////////////////////////////////////
+
+ public bool colorize {get; private set; }
+ public bool is_icon {get; private set;}
+ public int icon_size {get; private set;}
+
+ /////////////////////////////////////////////////////////////////////
+ /// C'tor, initializes all members of the layer.
+ /////////////////////////////////////////////////////////////////////
+
+ public SliceLayer(string icon_file, int icon_size, bool colorize, bool is_icon) {
+ this.icon_file = icon_file;
+ this.colorize = colorize;
+ this.is_icon = is_icon;
+ this.icon_size = icon_size;
+ }
+
+ /////////////////////////////////////////////////////////////////////
+ /// Loads the contained image.
+ /////////////////////////////////////////////////////////////////////
+
+ public void load_image() {
+ if (this.icon_file == "" && this.is_icon == true)
+ this.image = new Image.empty(this.icon_size, this.icon_size, new Color.from_rgb(1, 1, 1));
+ else
+ this.image = new Image.from_file_at_size(this.icon_file, this.icon_size, this.icon_size);
+ }
+}
+
+}
diff --git a/src/themes/theme.vala b/src/themes/theme.vala
new file mode 100644
index 0000000..fa6f55a
--- /dev/null
+++ b/src/themes/theme.vala
@@ -0,0 +1,489 @@
+/*
+Copyright (c) 2011 by Simon Schneegans
+
+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 3 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, see <http:www.gnu.org/licenses/>.
+*/
+
+using GLib.Math;
+
+namespace GnomePie {
+
+/////////////////////////////////////////////////////////////////////////
+/// A theme of Gnome-Pie. Can be loaded from XML-Files.
+/////////////////////////////////////////////////////////////////////////
+
+public class Theme : GLib.Object {
+
+ /////////////////////////////////////////////////////////////////////
+ /// Properties of a theme.
+ /////////////////////////////////////////////////////////////////////
+
+ public string directory {get; private set; default="";}
+ public string name {get; private set; default="";}
+ public string description {get; private set; default="";}
+ public string author {get; private set; default="";}
+ public string email {get; private set; default="";}
+ public double radius {get; private set; default=150;}
+ public double max_zoom {get; private set; default=1.2;}
+ public double zoom_range {get; private set; default=0.2;}
+ public double transition_time {get; private set; default=0.5;}
+ public double fade_in_time {get; private set; default=0.2;}
+ public double fade_out_time {get; private set; default=0.1;}
+ public double fade_in_zoom {get; private set; default=1.0;}
+ public double fade_out_zoom {get; private set; default=1.0;}
+ public double fade_in_rotation {get; private set; default=0.0;}
+ public double fade_out_rotation{get; private set; default=0.0;}
+ public double springiness {get; private set; default=0.0;}
+ public double center_radius {get; private set; default=90.0;}
+ public double active_radius {get; private set; default=45.0;}
+ public double slice_radius {get; private set; default=32.0;}
+ public double slice_gap {get; private set; default=14.0;}
+ public bool caption {get; private set; default=false;}
+ public string caption_font {get; private set; default="sans 12";}
+ public int caption_width {get; private set; default=100;}
+ public int caption_height {get; private set; default=100;}
+ public double caption_position {get; private set; default=0.0;}
+ public Color caption_color {get; private set; default=new Color();}
+
+ public Gee.ArrayList<CenterLayer?> center_layers {get; private set;}
+ public Gee.ArrayList<SliceLayer?> active_slice_layers {get; private set;}
+ public Gee.ArrayList<SliceLayer?> inactive_slice_layers {get; private set;}
+
+ /////////////////////////////////////////////////////////////////////
+ /// C'tor, creates a theme object for a given theme directory. This
+ /// directory should contain a theme.xml file.
+ /////////////////////////////////////////////////////////////////////
+
+ public Theme(string dir) {
+ this.center_layers = new Gee.ArrayList<CenterLayer?>();
+ this.active_slice_layers = new Gee.ArrayList<SliceLayer?>();
+ this.inactive_slice_layers = new Gee.ArrayList<SliceLayer?>();
+
+ this.directory = dir;
+
+ this.load();
+ }
+
+ /////////////////////////////////////////////////////////////////////
+ /// Loads the theme from its directory. Images have to be loaded
+ /// explicitly.
+ /////////////////////////////////////////////////////////////////////
+
+ public void load() {
+ this.center_layers.clear();
+ this.active_slice_layers.clear();
+ this.inactive_slice_layers.clear();
+
+ Xml.Parser.init();
+ string path = this.directory + "/theme.xml";
+
+ Xml.Doc* themeXML = Xml.Parser.parse_file(path);
+ if (themeXML == null) {
+ warning("Error parsing theme: \"" + path + "\" not found!");
+ return;
+ }
+
+ Xml.Node* root = themeXML->get_root_element();
+ if (root == null) {
+ delete themeXML;
+ warning("Invalid theme \"" + this.directory + "\": theme.xml is empty!");
+ return;
+ }
+
+ this.parse_root(root);
+
+ delete themeXML;
+ Xml.Parser.cleanup();
+
+ this.radius *= max_zoom;
+ }
+
+ /////////////////////////////////////////////////////////////////////
+ /// Loads all images of the theme.
+ /////////////////////////////////////////////////////////////////////
+
+ public void load_images() {
+ foreach (var layer in this.center_layers)
+ layer.load_image();
+ foreach (var layer in this.active_slice_layers)
+ layer.load_image();
+ foreach (var layer in this.inactive_slice_layers)
+ layer.load_image();
+ }
+
+ /////////////////////////////////////////////////////////////////////
+ /// The following methods parse specific parts of the theme file.
+ /// Nothing special here, just some boring code.
+ /////////////////////////////////////////////////////////////////////
+
+ private void parse_root(Xml.Node* root) {
+ for (Xml.Attr* attribute = root->properties; attribute != null; attribute = attribute->next) {
+ string attr_name = attribute->name.down();
+ string attr_content = attribute->children->content;
+
+ switch (attr_name) {
+ case "name":
+ name = attr_content;
+ break;
+ case "description":
+ description = attr_content;
+ break;
+ case "email":
+ email = attr_content;
+ break;
+ case "author":
+ author = attr_content;
+ break;
+ default:
+ warning("Invalid attribute \"" + attr_name + "\" in <theme> element!");
+ break;
+ }
+ }
+ for (Xml.Node* node = root->children; node != null; node = node->next) {
+ if (node->type == Xml.ElementType.ELEMENT_NODE) {
+ parse_pie(node);
+ }
+ }
+ }
+
+ /////////////////////////////////////////////////////////////////////
+ /// Parses a <pie> element from the theme.xml file.
+ /////////////////////////////////////////////////////////////////////
+
+ private void parse_pie(Xml.Node* pie) {
+ for (Xml.Attr* attribute = pie->properties; attribute != null; attribute = attribute->next) {
+ string attr_name = attribute->name.down();
+ string attr_content = attribute->children->content;
+
+ switch (attr_name) {
+ case "radius":
+ radius = double.parse(attr_content) * Config.global.global_scale;
+ break;
+ case "maxzoom":
+ max_zoom = double.parse(attr_content);
+ break;
+ case "zoomrange":
+ zoom_range = double.parse(attr_content);
+ break;
+ case "transitiontime":
+ transition_time = double.parse(attr_content);
+ break;
+ case "fadeintime":
+ fade_in_time = double.parse(attr_content);
+ break;
+ case "fadeouttime":
+ fade_out_time = double.parse(attr_content);
+ break;
+ case "fadeinzoom":
+ fade_in_zoom = double.parse(attr_content);
+ break;
+ case "fadeoutzoom":
+ fade_out_zoom = double.parse(attr_content);
+ break;
+ case "fadeinrotation":
+ fade_in_rotation = double.parse(attr_content);
+ break;
+ case "fadeoutrotation":
+ fade_out_rotation = double.parse(attr_content);
+ break;
+ case "springiness":
+ springiness = double.parse(attr_content);
+ break;
+ default:
+ warning("Invalid attribute \"" + attr_name + "\" in <pie> element!");
+ break;
+ }
+ }
+ for (Xml.Node* node = pie->children; node != null; node = node->next) {
+ if (node->type == Xml.ElementType.ELEMENT_NODE) {
+ string element_name = node->name.down();
+ switch (element_name) {
+ case "center":
+ parse_center(node);
+ break;
+ case "slices":
+ parse_slices(node);
+ break;
+ case "caption":
+ caption = true;
+ parse_caption(node);
+ break;
+ default:
+ warning("Invalid child element \"" + element_name + "\" in <pie> element!");
+ break;
+ }
+ }
+ }
+ }
+
+ /////////////////////////////////////////////////////////////////////
+ /// Parses a <center> element from the theme.xml file.
+ /////////////////////////////////////////////////////////////////////
+
+ private void parse_center(Xml.Node* center) {
+ for (Xml.Attr* attribute = center->properties; attribute != null; attribute = attribute->next) {
+ string attr_name = attribute->name.down();
+ string attr_content = attribute->children->content;
+
+ switch (attr_name) {
+ case "radius":
+ center_radius = double.parse(attr_content) * Config.global.global_scale;
+ break;
+ case "activeradius":
+ active_radius = double.parse(attr_content) * Config.global.global_scale;
+ break;
+ default:
+ warning("Invalid attribute \"" + attr_name + "\" in <center> element!");
+ break;
+ }
+ }
+ for (Xml.Node* node = center->children; node != null; node = node->next) {
+ if (node->type == Xml.ElementType.ELEMENT_NODE) {
+ string element_name = node->name.down();
+
+ if (element_name == "center_layer") {
+ parse_center_layer(node);
+ } else {
+ warning("Invalid child element \"" + element_name + "\" in <center> element!");
+ }
+ }
+ }
+ }
+
+ /////////////////////////////////////////////////////////////////////
+ /// Parses a <slices> element from the theme.xml file.
+ /////////////////////////////////////////////////////////////////////
+
+ private void parse_slices(Xml.Node* slices) {
+ for (Xml.Attr* attribute = slices->properties; attribute != null; attribute = attribute->next) {
+ string attr_name = attribute->name.down();
+ string attr_content = attribute->children->content;
+
+ switch (attr_name) {
+ case "radius":
+ slice_radius = double.parse(attr_content) * Config.global.global_scale;
+ break;
+ case "mingap":
+ slice_gap = double.parse(attr_content) * Config.global.global_scale;
+ break;
+ default:
+ warning("Invalid attribute \"" + attr_name + "\" in <slices> element!");
+ break;
+ }
+ }
+ for (Xml.Node* node = slices->children; node != null; node = node->next) {
+ if (node->type == Xml.ElementType.ELEMENT_NODE) {
+ string element_name = node->name.down();
+
+ if (element_name == "activeslice" || element_name == "inactiveslice") {
+ parse_slice_layers(node);
+ } else {
+ warning("Invalid child element \"" + element_name + "\" in <slices> element!");
+ }
+ }
+ }
+ }
+
+ /////////////////////////////////////////////////////////////////////
+ /// Parses a <center_layer> element from the theme.xml file.
+ /////////////////////////////////////////////////////////////////////
+
+ private void parse_center_layer(Xml.Node* layer) {
+
+ string file = "";
+ double active_rotation_speed = 0.0;
+ double inactive_rotation_speed = 0.0;
+ double active_scale = 1.0;
+ double inactive_scale = 1.0;
+ double active_alpha = 1.0;
+ double inactive_alpha = 1.0;
+ bool active_colorize = false;
+ bool inactive_colorize = false;
+ CenterLayer.RotationMode active_rotation_mode = CenterLayer.RotationMode.AUTO;
+ CenterLayer.RotationMode inactive_rotation_mode = CenterLayer.RotationMode.AUTO;
+
+ for (Xml.Attr* attribute = layer->properties; attribute != null; attribute = attribute->next) {
+ string attr_name = attribute->name.down();
+ string attr_content = attribute->children->content;
+
+ switch (attr_name) {
+ case "file":
+ file = attr_content;
+ break;
+ case "active_scale":
+ active_scale = double.parse(attr_content);
+ break;
+ case "active_alpha":
+ active_alpha = double.parse(attr_content);
+ break;
+ case "active_rotationmode":
+ switch (attr_content.down()) {
+ case "auto":
+ active_rotation_mode = CenterLayer.RotationMode.AUTO;
+ break;
+ case "turn_to_active":
+ active_rotation_mode = CenterLayer.RotationMode.TO_ACTIVE;
+ break;
+ case "turn_to_mouse":
+ active_rotation_mode = CenterLayer.RotationMode.TO_MOUSE;
+ break;
+ default:
+ warning("Invalid value \"" + attr_content + "\" for attribute \"" + attr_name + "\" in <center_layer> element!");
+ break;
+ }
+ break;
+ case "active_rotationspeed":
+ active_rotation_speed = double.parse(attr_content);
+ break;
+ case "active_colorize":
+ active_colorize = bool.parse(attr_content);
+ break;
+ case "inactive_scale":
+ inactive_scale = double.parse(attr_content);
+ break;
+ case "inactive_alpha":
+ inactive_alpha = double.parse(attr_content);
+ break;
+ case "inactive_rotationmode":
+ switch (attr_content.down()) {
+ case "auto":
+ inactive_rotation_mode = CenterLayer.RotationMode.AUTO;
+ break;
+ case "turn_to_active":
+ inactive_rotation_mode = CenterLayer.RotationMode.TO_ACTIVE;
+ break;
+ case "turn_to_mouse":
+ inactive_rotation_mode = CenterLayer.RotationMode.TO_MOUSE;
+ break;
+ default:
+ warning("Invalid value \"" + attr_content + "\" for attribute \"" + attr_name + "\" in <center_layer> element!");
+ break;
+ }
+ break;
+ case "inactive_rotationspeed":
+ inactive_rotation_speed = double.parse(attr_content);
+ break;
+ case "inactive_colorize":
+ inactive_colorize = bool.parse(attr_content);
+ break;
+ default:
+ warning("Invalid attribute \"" + attr_name + "\" in <center_layer> element!");
+ break;
+ }
+ }
+
+ double max_scale = GLib.Math.fmax(active_scale, inactive_scale);
+ center_layers.add(new CenterLayer(directory + "/" + file, (int)(center_radius*max_scale), active_scale/max_scale, active_rotation_speed, active_alpha, active_colorize, active_rotation_mode,
+ inactive_scale/max_scale, inactive_rotation_speed, inactive_alpha, inactive_colorize, inactive_rotation_mode));
+ }
+
+ /////////////////////////////////////////////////////////////////////
+ /// Parses a <slice_layer> element from the theme.xml file.
+ /////////////////////////////////////////////////////////////////////
+
+ private void parse_slice_layers(Xml.Node* slice) {
+ for (Xml.Node* layer = slice->children; layer != null; layer = layer->next) {
+ if (layer->type == Xml.ElementType.ELEMENT_NODE) {
+ string element_name = layer->name.down();
+
+ if (element_name == "slice_layer") {
+ string file = "";
+ double scale = 1.0;
+ bool is_icon = false;
+ bool colorize = false;
+
+ for (Xml.Attr* attribute = layer->properties; attribute != null; attribute = attribute->next) {
+ string attr_name = attribute->name.down();
+ string attr_content = attribute->children->content;
+
+ switch (attr_name) {
+ case "file":
+ file = attr_content;
+ break;
+ case "scale":
+ scale = double.parse(attr_content);
+ break;
+ case "type":
+ if (attr_content == "icon")
+ is_icon = true;
+ else if (attr_content != "file")
+ warning("Invalid attribute content " + attr_content + " for attribute " + attr_name + " in <slice_layer> element!");
+ break;
+ case "colorize":
+ colorize = bool.parse(attr_content);
+ break;
+ default:
+ warning("Invalid attribute \"" + attr_name + "\" in <slice_layer> element!");
+ break;
+ }
+ }
+
+ if (file != "")
+ file = directory + "/" + file;
+
+ int size = 2*(int)(slice_radius*scale*max_zoom);
+
+ if (slice->name.down() == "activeslice") {
+ active_slice_layers.add(new SliceLayer(file, size, colorize, is_icon));
+ } else {
+ inactive_slice_layers.add(new SliceLayer(file, size, colorize, is_icon));
+ }
+
+ } else {
+ warning("Invalid child element \"" + element_name + "\" in <" + slice->name + "> element!");
+ }
+ }
+ }
+ }
+
+ /////////////////////////////////////////////////////////////////////
+ /// Parses a <caption> element from the theme.xml file.
+ /////////////////////////////////////////////////////////////////////
+
+ private void parse_caption(Xml.Node* caption) {
+ for (Xml.Attr* attribute = caption->properties; attribute != null; attribute = attribute->next) {
+ string attr_name = attribute->name.down();
+ string attr_content = attribute->children->content;
+
+ switch (attr_name) {
+ case "font":
+ caption_font = attr_content;
+ break;
+ case "width":
+ caption_width = (int)(int.parse(attr_content) * Config.global.global_scale);
+ if (caption_width % 2 == 1)
+ --caption_width;
+ break;
+ case "height":
+ caption_height = (int)(int.parse(attr_content) * Config.global.global_scale);
+ if (caption_height % 2 == 1)
+ --caption_height;
+ break;
+ case "position":
+ caption_position = double.parse(attr_content) * Config.global.global_scale;
+ break;
+ case "color":
+ caption_color = new Color.from_string(attr_content);
+ break;
+ default:
+ warning("Invalid attribute \"" + attr_name + "\" in <caption> element!");
+ break;
+ }
+ }
+
+ }
+
+}
+
+}
diff --git a/src/utilities/animatedValue.vala b/src/utilities/animatedValue.vala
new file mode 100644
index 0000000..32ab889
--- /dev/null
+++ b/src/utilities/animatedValue.vala
@@ -0,0 +1,190 @@
+/*
+Copyright (c) 2011 by Simon Schneegans
+
+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 3 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, see <http://www.gnu.org/licenses/>.
+*/
+
+namespace GnomePie {
+
+/////////////////////////////////////////////////////////////////////////
+/// A class which interpolates smoothly between to given values.
+/// Duration and interpolation mode can be specified.
+/////////////////////////////////////////////////////////////////////////
+
+public class AnimatedValue : GLib.Object {
+
+ /////////////////////////////////////////////////////////////////////
+ /// The direction of the interpolation.
+ /////////////////////////////////////////////////////////////////////
+
+ public enum Direction { IN, OUT, IN_OUT, OUT_IN }
+
+ /////////////////////////////////////////////////////////////////////
+ /// Type of the interpolation, linear or cubic.
+ /////////////////////////////////////////////////////////////////////
+
+ private enum Type { LINEAR, CUBIC }
+
+ /////////////////////////////////////////////////////////////////////
+ /// Current value, interpolated.
+ /////////////////////////////////////////////////////////////////////
+
+ public double val { get; private set; }
+
+ /////////////////////////////////////////////////////////////////////
+ /// Starting value of the interpolation.
+ /////////////////////////////////////////////////////////////////////
+
+ public double start { get; private set; default=0.0; }
+
+ /////////////////////////////////////////////////////////////////////
+ /// Final value of the interpolation.
+ /////////////////////////////////////////////////////////////////////
+
+ public double end { get; private set; default=0.0; }
+
+ /////////////////////////////////////////////////////////////////////
+ /// The current state. In range 0 .. 1
+ /////////////////////////////////////////////////////////////////////
+
+ private double state = 0.0;
+
+ /////////////////////////////////////////////////////////////////////
+ /// Duration of the interpolation. Should be in the same unit as
+ /// taken for the update() method.
+ /////////////////////////////////////////////////////////////////////
+
+ private double duration = 0.0;
+
+ /////////////////////////////////////////////////////////////////////
+ /// The amount of over-shooting of the cubicly interpolated value.
+ /////////////////////////////////////////////////////////////////////
+
+ private double multiplier = 0.0;
+
+ /////////////////////////////////////////////////////////////////////
+ /// Type of the interpolation, linear or cubic.
+ /////////////////////////////////////////////////////////////////////
+
+ private Type type = Type.LINEAR;
+
+ /////////////////////////////////////////////////////////////////////
+ /// The direction of the interpolation.
+ /////////////////////////////////////////////////////////////////////
+
+ private Direction direction = Direction.IN;
+
+ /////////////////////////////////////////////////////////////////////
+ /// Creates a new linearly interpolated value.
+ /////////////////////////////////////////////////////////////////////
+
+ public AnimatedValue.linear(double start, double end, double duration) {
+ this.val = start;
+ this.start = start;
+ this.end = end;
+ this.duration = duration;
+ }
+
+ /////////////////////////////////////////////////////////////////////
+ /// Creates a new cubicly interpolated value.
+ /////////////////////////////////////////////////////////////////////
+
+ public AnimatedValue.cubic(Direction direction, double start, double end, double duration, double multiplier = 0) {
+ this.val = start;
+ this.start = start;
+ this.end = end;
+ this.duration = duration;
+ this.direction = direction;
+ this.type = Type.CUBIC;
+ this.multiplier = multiplier;
+ }
+
+ /////////////////////////////////////////////////////////////////////
+ /// Resets the final value of the interpolation to a new value. The
+ /// current state is taken for the beginning from now.
+ /////////////////////////////////////////////////////////////////////
+
+ public void reset_target(double end, double duration) {
+ this.start = this.val;
+ this.end = end;
+ this.duration = duration;
+ this.state = 0.0;
+ }
+
+ /////////////////////////////////////////////////////////////////////
+ /// Updates the interpolated value according to it's type.
+ /////////////////////////////////////////////////////////////////////
+
+ public void update(double time) {
+ this.state += time/this.duration;
+
+ if (state < 1) {
+
+ switch (this.type) {
+ case Type.LINEAR:
+ this.val = update_linear();
+ break;
+ case Type.CUBIC:
+ switch (this.direction) {
+ case Direction.IN:
+ this.val = update_ease_in();
+ return;
+ case Direction.OUT:
+ this.val = update_ease_out();
+ return;
+ case Direction.IN_OUT:
+ this.val = update_ease_in_out();
+ return;
+ case Direction.OUT_IN:
+ this.val = update_ease_out_in();
+ return;
+ }
+ break;
+ }
+ } else if (this.val != this.end) {
+ this.val = this.end;
+ }
+ }
+
+ /////////////////////////////////////////////////////////////////////
+ /// The following equations are based on Robert Penner's easing
+ /// equations. See (http://www.robertpenner.com/easing/) and their
+ /// adaption by Zeh Fernando, Nate Chatellier and Arthur Debert for
+ /// the Tweener class. See (http://code.google.com/p/tweener/).
+ /////////////////////////////////////////////////////////////////////
+
+ private double update_linear(double t = this.state, double s = this.start, double e = this.end) {
+ return (s + t*(e - s));
+ }
+
+ private double update_ease_in(double t = this.state, double s = this.start, double e = this.end) {
+ return (s + (t*t*((multiplier+1)*t-multiplier))*(e - s));
+ }
+
+ private double update_ease_out(double t = this.state, double s = this.start, double e = this.end) {
+ return (s + ((t-1) * (t-1) * ((multiplier+1)*(t-1)+multiplier) + 1) * (e - s));
+ }
+
+ private double update_ease_in_out(double t = this.state, double s = this.start, double e = this.end) {
+ if (this.state < 0.5) return update_ease_in(t*2, s, e - (e-s)*0.5);
+ else return update_ease_out(t*2-1, s + (e-s)*0.5, e);
+ }
+
+ private double update_ease_out_in(double t = this.state, double s = this.start, double e = this.end) {
+ if (this.state < 0.5) return update_ease_out(t*2, s, e - (e-s)*0.5);
+ else return update_ease_in(t*2-1, s + (e-s)*0.5, e);
+ }
+}
+
+}
diff --git a/src/utilities/bindingManager.vala b/src/utilities/bindingManager.vala
new file mode 100644
index 0000000..8795124
--- /dev/null
+++ b/src/utilities/bindingManager.vala
@@ -0,0 +1,196 @@
+/*
+Copyright (c) 2011 by Simon Schneegans
+
+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 3 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, see <http://www.gnu.org/licenses/>.
+*/
+
+namespace GnomePie {
+
+/////////////////////////////////////////////////////////////////////////
+/// Globally binds key stroke to given ID's. When one of the bound
+/// strokes is invoked, a signal with the according ID is emitted.
+/////////////////////////////////////////////////////////////////////////
+
+public class BindingManager : GLib.Object {
+
+ /////////////////////////////////////////////////////////////////////
+ /// Called when a stored binding is invoked. The according ID is
+ /// passed as argument.
+ /////////////////////////////////////////////////////////////////////
+
+ public signal void on_press(string id);
+
+ /////////////////////////////////////////////////////////////////////
+ /// A list storing bindings, which are invoked even if Gnome-Pie
+ /// doesn't have the current focus
+ /////////////////////////////////////////////////////////////////////
+
+ private Gee.List<Keybinding> bindings = new Gee.ArrayList<Keybinding>();
+
+ /////////////////////////////////////////////////////////////////////
+ /// Ignored modifier masks, used to grab all keys even if these locks
+ /// are active.
+ /////////////////////////////////////////////////////////////////////
+
+ private static uint[] lock_modifiers = {
+ 0,
+ Gdk.ModifierType.MOD2_MASK,
+ Gdk.ModifierType.LOCK_MASK,
+ Gdk.ModifierType.MOD5_MASK,
+ Gdk.ModifierType.MOD2_MASK|Gdk.ModifierType.LOCK_MASK,
+ Gdk.ModifierType.MOD2_MASK|Gdk.ModifierType.MOD5_MASK,
+ Gdk.ModifierType.LOCK_MASK|Gdk.ModifierType.MOD5_MASK,
+ Gdk.ModifierType.MOD2_MASK|Gdk.ModifierType.LOCK_MASK|Gdk.ModifierType.MOD5_MASK
+ };
+
+ /////////////////////////////////////////////////////////////////////
+ /// Helper class to store keybinding
+ /////////////////////////////////////////////////////////////////////
+
+ private class Keybinding {
+
+ public Keybinding(string accelerator, int keycode, Gdk.ModifierType modifiers, string id) {
+ this.accelerator = accelerator;
+ this.keycode = keycode;
+ this.modifiers = modifiers;
+ this.id = id;
+ }
+
+ public string accelerator { get; set; }
+ public int keycode { get; set; }
+ public Gdk.ModifierType modifiers { get; set; }
+ public string id { get; set; }
+ }
+
+ /////////////////////////////////////////////////////////////////////
+ /// C'tor adds the event filter to the root window.
+ /////////////////////////////////////////////////////////////////////
+
+ public BindingManager() {
+ // init filter to retrieve X.Events
+ Gdk.Window rootwin = Gdk.get_default_root_window();
+ if(rootwin != null) {
+ rootwin.add_filter(event_filter);
+ }
+ }
+
+ /////////////////////////////////////////////////////////////////////
+ /// Binds the ID to the given accelerator.
+ /////////////////////////////////////////////////////////////////////
+
+ public void bind(string accelerator, string id) {
+ uint keysym;
+ Gdk.ModifierType modifiers;
+ Gtk.accelerator_parse(accelerator, out keysym, out modifiers);
+
+ if (keysym == 0) {
+ warning("Invalid keystroke: " + accelerator);
+ return;
+ }
+
+ Gdk.Window rootwin = Gdk.get_default_root_window();
+ X.Display display = Gdk.x11_drawable_get_xdisplay(rootwin);
+ X.ID xid = Gdk.x11_drawable_get_xid(rootwin);
+ int keycode = display.keysym_to_keycode(keysym);
+
+ if(keycode != 0) {
+ Gdk.error_trap_push();
+
+ foreach(uint lock_modifier in lock_modifiers) {
+ display.grab_key(keycode, modifiers|lock_modifier, xid, false, X.GrabMode.Async, X.GrabMode.Async);
+ }
+
+ Gdk.flush();
+
+ Keybinding binding = new Keybinding(accelerator, keycode, modifiers, id);
+ bindings.add(binding);
+ }
+ }
+
+ /////////////////////////////////////////////////////////////////////
+ /// Unbinds the accelerator of the given ID.
+ /////////////////////////////////////////////////////////////////////
+
+ public void unbind(string id) {
+ Gdk.Window rootwin = Gdk.get_default_root_window();
+ X.Display display = Gdk.x11_drawable_get_xdisplay(rootwin);
+ X.ID xid = Gdk.x11_drawable_get_xid(rootwin);
+ Gee.List<Keybinding> remove_bindings = new Gee.ArrayList<Keybinding>();
+ foreach(var binding in bindings) {
+ if(id == binding.id) {
+ foreach(uint lock_modifier in lock_modifiers) {
+ display.ungrab_key(binding.keycode, binding.modifiers, xid);
+ }
+ remove_bindings.add(binding);
+ }
+ }
+
+ bindings.remove_all(remove_bindings);
+ }
+
+ /////////////////////////////////////////////////////////////////////
+ /// Returns a human readable accelerator for the given ID.
+ /////////////////////////////////////////////////////////////////////
+
+ public string get_accelerator_label_of(string id) {
+ string accelerator = this.get_accelerator_of(id);
+
+ if (accelerator == "")
+ return _("Not bound");
+
+ uint key = 0;
+ Gdk.ModifierType mods;
+ Gtk.accelerator_parse(accelerator, out key, out mods);
+ return Gtk.accelerator_get_label(key, mods);
+ }
+
+ /////////////////////////////////////////////////////////////////////
+ /// Returns the accelerator to which the given ID is bound.
+ /////////////////////////////////////////////////////////////////////
+
+ public string get_accelerator_of(string id) {
+ foreach (var binding in bindings) {
+ if (binding.id == id) {
+ return binding.accelerator;
+ }
+ }
+
+ return "";
+ }
+
+ /////////////////////////////////////////////////////////////////////
+ /// Event filter method needed to fetch X.Events
+ /////////////////////////////////////////////////////////////////////
+
+ private Gdk.FilterReturn event_filter(Gdk.XEvent gdk_xevent, Gdk.Event gdk_event) {
+ Gdk.FilterReturn filter_return = Gdk.FilterReturn.CONTINUE;
+
+ void* pointer = &gdk_xevent;
+ X.Event* xevent = (X.Event*) pointer;
+
+ if(xevent->type == X.EventType.KeyPress) {
+ foreach(var binding in bindings) {
+ // remove NumLock, CapsLock and ScrollLock from key state
+ uint event_mods = xevent.xkey.state & ~ (lock_modifiers[7]);
+ if(xevent->xkey.keycode == binding.keycode && event_mods == binding.modifiers) {
+ on_press(binding.id);
+ }
+ }
+ }
+
+ return filter_return;
+ }
+}
+
+}
diff --git a/src/utilities/color.vala b/src/utilities/color.vala
new file mode 100644
index 0000000..836411e
--- /dev/null
+++ b/src/utilities/color.vala
@@ -0,0 +1,305 @@
+/*
+Copyright (c) 2011 by Simon Schneegans
+
+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 3 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, see <http://www.gnu.org/licenses/>.
+*/
+
+using GLib.Math;
+
+namespace GnomePie {
+
+/////////////////////////////////////////////////////////////////////////
+/// A Color class with full rgb/hsv support
+/// and some useful utility methods.
+/////////////////////////////////////////////////////////////////////////
+
+public class Color: GLib.Object {
+
+ /////////////////////////////////////////////////////////////////////
+ /// Private members, storing the actual color information.
+ /// In range 0 .. 1
+ /////////////////////////////////////////////////////////////////////
+
+ private float _r;
+ private float _g;
+ private float _b;
+ private float _a;
+
+ /////////////////////////////////////////////////////////////////////
+ /// Creates a white Color.
+ /////////////////////////////////////////////////////////////////////
+
+ public Color() {
+ Color.from_rgb(1.0f, 1.0f, 1.0f);
+ }
+
+ /////////////////////////////////////////////////////////////////////
+ /// Creates a solid color with the given RGB values.
+ /////////////////////////////////////////////////////////////////////
+
+ public Color.from_rgb(float red, float green, float blue) {
+ Color.from_rgba(red, green, blue, 1.0f);
+ }
+
+ /////////////////////////////////////////////////////////////////////
+ /// Creates a translucient color with the given RGBA values.
+ /////////////////////////////////////////////////////////////////////
+
+ public Color.from_rgba(float red, float green, float blue, float alpha) {
+ r = red;
+ g = green;
+ b = blue;
+ a = alpha;
+ }
+
+ /////////////////////////////////////////////////////////////////////
+ /// Creates a color from the given Gdk.Color
+ /////////////////////////////////////////////////////////////////////
+
+ public Color.from_gdk(Gdk.Color color) {
+ Color.from_rgb(
+ (float)color.red/65535.0f,
+ (float)color.green/65535.0f,
+ (float)color.blue/65535.0f
+ );
+ }
+
+ /////////////////////////////////////////////////////////////////////
+ /// Creates a color, parsed from a string, such as #22EE33
+ /////////////////////////////////////////////////////////////////////
+
+ public Color.from_string(string hex_string) {
+ Gdk.Color color;
+ Gdk.Color.parse(hex_string, out color);
+ Color.from_gdk(color);
+ }
+
+ /////////////////////////////////////////////////////////////////////
+ /// Gets the main color from an Image. Code from Unity.
+ /////////////////////////////////////////////////////////////////////
+
+ public Color.from_icon(Image icon) {
+ unowned uchar[] data = icon.surface.get_data();
+
+ uint width = icon.surface.get_width();
+ uint height = icon.surface.get_height();
+ uint row_bytes = icon.surface.get_stride();
+
+ double total = 0.0;
+ double rtotal = 0.0;
+ double gtotal = 0.0;
+ double btotal = 0.0;
+
+ for (uint i = 0; i < width; ++i) {
+ for (uint j = 0; j < height; ++j) {
+ uint pixel = j * row_bytes + i * 4;
+ double b = data[pixel + 0]/255.0;
+ double g = data[pixel + 1]/255.0;
+ double r = data[pixel + 2]/255.0;
+ double a = data[pixel + 3]/255.0;
+
+ double saturation = (fmax (r, fmax (g, b)) - fmin (r, fmin (g, b)));
+ double relevance = 0.1 + 0.9 * a * saturation;
+
+ rtotal += (r * relevance);
+ gtotal += (g * relevance);
+ btotal += (b * relevance);
+
+ total += relevance;
+ }
+ }
+
+ Color.from_rgb((float)(rtotal/total), (float)(gtotal/total), (float)(btotal/total));
+
+ if (s > 0.15f) s = 0.65f;
+
+ v = 1.0f;
+ }
+
+ /////////////////////////////////////////////////////////////////////
+ /// The reddish part of the color.
+ /////////////////////////////////////////////////////////////////////
+
+ public float r {
+ get {
+ return _r;
+ }
+ set {
+ if (value > 1.0f) _r = 1.0f;
+ else if (value < 0.0f) _r = 0.0f;
+ else _r = value;
+ }
+ }
+
+ /////////////////////////////////////////////////////////////////////
+ /// The greenish part of the color.
+ /////////////////////////////////////////////////////////////////////
+
+ public float g {
+ get {
+ return _g;
+ }
+ set {
+ if (value > 1.0f) _g = 1.0f;
+ else if (value < 0.0f) _g = 0.0f;
+ else _g = value;
+ }
+ }
+
+ /////////////////////////////////////////////////////////////////////
+ /// The blueish part of the color.
+ /////////////////////////////////////////////////////////////////////
+
+ public float b {
+ get {
+ return _b;
+ }
+ set {
+ if (value > 1.0f) _b = 1.0f;
+ else if (value < 0.0f) _b = 0.0f;
+ else _b = value;
+ }
+ }
+
+ /////////////////////////////////////////////////////////////////////
+ /// The transparency of the color.
+ /////////////////////////////////////////////////////////////////////
+
+ public float a {
+ get {
+ return _a;
+ }
+ set {
+ if (value > 1.0f) _a = 1.0f;
+ else if (value < 0.0f) _a = 0.0f;
+ else _a = value;
+ }
+ }
+
+ /////////////////////////////////////////////////////////////////////
+ /// The hue of the color.
+ /////////////////////////////////////////////////////////////////////
+
+ public float h {
+ get {
+ if (s > 0.0f) {
+ float maxi = fmaxf(fmaxf(r, g), b);
+ float mini = fminf(fminf(r, g), b);
+
+ if (maxi == r)
+ return fmodf(60.0f*((g-b)/(maxi-mini))+360.0f, 360.0f);
+ else if (maxi == g)
+ return fmodf(60.0f*(2.0f + (b-r)/(maxi-mini))+360.0f, 360.0f);
+ else
+ return fmodf(60.0f*(4.0f + (r-g)/(maxi-mini))+360.0f, 360.0f);
+ }
+ else return 0.0f;
+ }
+ set {
+ setHSV(value, s, v);
+ }
+ }
+
+ /////////////////////////////////////////////////////////////////////
+ /// The saturation of the color.
+ /////////////////////////////////////////////////////////////////////
+
+ public float s {
+ get {
+ if (v == 0.0f) return 0.0f;
+ else return ((v-fminf(fminf(r, g), b)) / v);
+ }
+ set {
+ if (value > 1.0f) setHSV(h, 1.0f, v);
+ else if (value < 0.0f) setHSV(h, 0.0f, v);
+ else setHSV(h, value, v);
+ }
+ }
+
+ /////////////////////////////////////////////////////////////////////
+ /// The value of the color.
+ /////////////////////////////////////////////////////////////////////
+
+ public float v {
+ get {
+ return fmaxf(fmaxf(r, g), b);
+ }
+ set {
+ if (value > 1) setHSV(h, s, 1.0f);
+ else if (value < 0) setHSV(h, s, 0.0f);
+ else setHSV(h, s, value);
+ }
+ }
+
+ /////////////////////////////////////////////////////////////////////
+ /// Inverts the color.
+ /////////////////////////////////////////////////////////////////////
+
+ public void invert() {
+ h += 180.0f;
+ v = 1.0f - v;
+ }
+
+ /////////////////////////////////////////////////////////////////////
+ /// Private member, used to apply color changes.
+ /////////////////////////////////////////////////////////////////////
+
+ private void setHSV(float hue, float saturation, float val) {
+ if(saturation == 0) {
+ r = val;
+ g = val;
+ b = val;
+ return;
+ }
+ hue = fmodf(hue, 360);
+ hue /= 60;
+ int i = (int) floorf(hue);
+ float f = hue - i;
+
+ switch(i) {
+ case 0:
+ r = val;
+ g = val * (1.0f - saturation * (1.0f - f));
+ b = val * (1.0f - saturation);
+ break;
+ case 1:
+ r = val * (1.0f - saturation * f);
+ g = val;
+ b = val * (1.0f - saturation);
+ break;
+ case 2:
+ r = val * (1.0f - saturation);
+ g = val;
+ b = val * (1.0f - saturation * (1.0f - f));
+ break;
+ case 3:
+ r = val * (1.0f - saturation);
+ g = val * (1.0f - saturation * f);
+ b = val;
+ break;
+ case 4:
+ r = val * (1.0f - saturation * (1.0f - f));
+ g = val * (1.0f - saturation);
+ b = val;
+ break;
+ default:
+ r = val;
+ g = val * (1.0f - saturation);
+ b = val * (1.0f - saturation * f);
+ break;
+ }
+ }
+}
+
+}
diff --git a/src/utilities/config.vala b/src/utilities/config.vala
new file mode 100644
index 0000000..c5dedd5
--- /dev/null
+++ b/src/utilities/config.vala
@@ -0,0 +1,202 @@
+/*
+Copyright (c) 2011 by Simon Schneegans
+
+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 3 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, see <http://www.gnu.org/licenses/>.
+*/
+
+namespace GnomePie {
+
+/////////////////////////////////////////////////////////////////////////
+/// A singleton class for storing global settings. These settings can
+/// be loaded from and saved to an XML file.
+/////////////////////////////////////////////////////////////////////////
+
+public class Config : GLib.Object {
+
+ /////////////////////////////////////////////////////////////////////
+ /// The singleton instance of this class.
+ /////////////////////////////////////////////////////////////////////
+
+ private static Config _instance = null;
+
+ /////////////////////////////////////////////////////////////////////
+ /// Returns the singleton instance.
+ /////////////////////////////////////////////////////////////////////
+
+ public static Config global {
+ get {
+ if (_instance == null) {
+ _instance = new Config();
+ _instance.load();
+ }
+ return _instance;
+ }
+ private set {
+ _instance = value;
+ }
+ }
+
+ /////////////////////////////////////////////////////////////////////
+ /// All settings variables.
+ /////////////////////////////////////////////////////////////////////
+
+ public Theme theme { get; set; }
+ public double refresh_rate { get; set; default = 60.0; }
+ public double global_scale { get; set; default = 1.0; }
+ public bool show_indicator { get; set; default = true; }
+ public bool open_at_mouse { get; set; default = true; }
+ public bool turbo_mode { get; set; default = false; }
+ public bool auto_start { get; set; default = false; }
+ public Gee.ArrayList<Theme?> themes { get; private set; }
+
+ /////////////////////////////////////////////////////////////////////
+ /// Saves all above variables to a file.
+ /////////////////////////////////////////////////////////////////////
+
+ public void save() {
+ var writer = new Xml.TextWriter.filename(Paths.settings);
+ writer.start_document("1.0");
+ writer.start_element("settings");
+ writer.write_attribute("theme", theme.name);
+ writer.write_attribute("refresh_rate", refresh_rate.to_string());
+ writer.write_attribute("global_scale", global_scale.to_string());
+ writer.write_attribute("show_indicator", show_indicator ? "true" : "false");
+ writer.write_attribute("open_at_mouse", open_at_mouse ? "true" : "false");
+ writer.write_attribute("turbo_mode", turbo_mode ? "true" : "false");
+ writer.end_element();
+ writer.end_document();
+ }
+
+ /////////////////////////////////////////////////////////////////////
+ /// Loads all settings variables from a file.
+ /////////////////////////////////////////////////////////////////////
+
+ private void load() {
+
+ // check for auto_start filename
+ this.auto_start = FileUtils.test(Paths.autostart, FileTest.EXISTS);
+
+ // parse the settings file
+ Xml.Parser.init();
+ Xml.Doc* settingsXML = Xml.Parser.parse_file(Paths.settings);
+ bool error_occrured = false;
+ string theme_name = "";
+
+ if (settingsXML != null) {
+
+ Xml.Node* root = settingsXML->get_root_element();
+ if (root != null) {
+
+ for (Xml.Attr* attribute = root->properties; attribute != null; attribute = attribute->next) {
+ string attr_name = attribute->name.down();
+ string attr_content = attribute->children->content;
+
+ switch (attr_name) {
+ case "theme":
+ theme_name = attr_content;
+ break;
+ case "refresh_rate":
+ refresh_rate = double.parse(attr_content);
+ break;
+ case "global_scale":
+ global_scale = double.parse(attr_content);
+ global_scale.clamp(0.5, 2.0);
+ break;
+ case "show_indicator":
+ show_indicator = bool.parse(attr_content);
+ break;
+ case "open_at_mouse":
+ open_at_mouse = bool.parse(attr_content);
+ break;
+ case "turbo_mode":
+ turbo_mode = bool.parse(attr_content);
+ break;
+ default:
+ warning("Invalid setting \"" + attr_name + "\" in gnome-pie.conf!");
+ break;
+ }
+ }
+
+ Xml.Parser.cleanup();
+
+ } else {
+ warning("Error loading settings: gnome-pie.conf is empty! Using defaults...");
+ error_occrured = true;
+ }
+
+ delete settingsXML;
+
+ } else {
+ warning("Error loading settings: gnome-pie.conf not found! Using defaults...");
+ error_occrured = true;
+ }
+
+ load_themes(theme_name);
+
+ if (error_occrured) save();
+ }
+
+ /////////////////////////////////////////////////////////////////////
+ /// Registers all themes in the user's and in the global
+ /// theme directory.
+ /////////////////////////////////////////////////////////////////////
+
+ public void load_themes(string current) {
+ themes = new Gee.ArrayList<Theme?>();
+ try {
+ string name;
+
+ // load global themes
+ var d = Dir.open(Paths.global_themes);
+ while ((name = d.read_name()) != null) {
+ var theme = new Theme(Paths.global_themes + "/" + name);
+ if (theme != null)
+ themes.add(theme);
+ }
+
+ // load local themes
+ d = Dir.open(Paths.local_themes);
+ while ((name = d.read_name()) != null) {
+ var theme = new Theme(Paths.local_themes + "/" + name);
+ if (theme != null)
+ themes.add(theme);
+ }
+
+ } catch (Error e) {
+ warning (e.message);
+ }
+
+ if (themes.size > 0) {
+ if (current == "") {
+ current = "Unity";
+ warning("No theme specified! Using default...");
+ }
+ foreach (var t in themes) {
+ if (t.name == current) {
+ theme = t;
+ theme.load_images();
+ break;
+ }
+ }
+ if (theme == null) {
+ theme = themes[0];
+ warning("Theme \"" + current + "\" not found! Using fallback...");
+ }
+ }
+ else error("No theme found!");
+ }
+
+}
+
+}
diff --git a/src/utilities/icon.vala b/src/utilities/icon.vala
new file mode 100644
index 0000000..1c8a9f4
--- /dev/null
+++ b/src/utilities/icon.vala
@@ -0,0 +1,102 @@
+/*
+Copyright (c) 2011 by Simon Schneegans
+
+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 3 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, see <http://www.gnu.org/licenses/>.
+*/
+
+namespace GnomePie {
+
+/////////////////////////////////////////////////////////////////////////
+/// A class representing a square-shaped icon, loaded from the users
+/// icon theme.
+/////////////////////////////////////////////////////////////////////////
+
+public class Icon : Image {
+
+ /////////////////////////////////////////////////////////////////////
+ /// A cache which stores loaded icon. It is cleared when the icon
+ /// theme of the user changes. The key is in form <filename>@<size>.
+ /////////////////////////////////////////////////////////////////////
+
+ private static Gee.HashMap<string, Cairo.ImageSurface?> cache { private get; private set; }
+
+ /////////////////////////////////////////////////////////////////////
+ /// Initializes the cache.
+ /////////////////////////////////////////////////////////////////////
+
+ public static void init() {
+ clear_cache();
+
+ Gtk.IconTheme.get_default().changed.connect(() => {
+ clear_cache();
+ });
+ }
+
+ /////////////////////////////////////////////////////////////////////
+ /// Clears the cache.
+ /////////////////////////////////////////////////////////////////////
+
+ public static void clear_cache() {
+ cache = new Gee.HashMap<string, Cairo.ImageSurface?>();
+ }
+
+ /////////////////////////////////////////////////////////////////////
+ /// Loads an icon from the current icon theme of the user.
+ /////////////////////////////////////////////////////////////////////
+
+ public Icon(string icon_name, int size) {
+ var cached = this.cache.get("%s@%u".printf(icon_name, size));
+
+ if (cached == null) {
+ this.load_file_at_size(this.get_icon_file(icon_name, size), size, size);
+ this.cache.set("%s@%u".printf(icon_name, size), this.surface);
+ } else {
+ this.surface = cached;
+ }
+ }
+
+ /////////////////////////////////////////////////////////////////////
+ /// Returns the size of the icon in pixels. Greetings to Liskov.
+ /////////////////////////////////////////////////////////////////////
+
+ public int size() {
+ return base.width();
+ }
+
+ /////////////////////////////////////////////////////////////////////
+ /// Returns the filename for a given system icon.
+ /////////////////////////////////////////////////////////////////////
+
+ public static string get_icon_file(string icon_name, int size) {
+ string result = "";
+
+ var icon_theme = Gtk.IconTheme.get_default();
+ var file = icon_theme.lookup_icon(icon_name, size, 0);
+ if (file != null) result = file.get_filename();
+
+ if (result == "") {
+ warning("Icon \"" + icon_name + "\" not found! Using default icon...");
+ icon_name = "application-default-icon";
+ file = icon_theme.lookup_icon(icon_name, size, 0);
+ if (file != null) result = file.get_filename();
+ }
+
+ if (result == "")
+ warning("Icon \"" + icon_name + "\" not found! Will be ugly...");
+
+ return result;
+ }
+}
+
+}
diff --git a/src/utilities/image.vala b/src/utilities/image.vala
new file mode 100644
index 0000000..836e4e2
--- /dev/null
+++ b/src/utilities/image.vala
@@ -0,0 +1,163 @@
+/*
+Copyright (c) 2011 by Simon Schneegans
+
+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 3 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, see <http://www.gnu.org/licenses/>.
+*/
+
+namespace GnomePie {
+
+/////////////////////////////////////////////////////////////////////////
+/// A class which loads image files. It can load image files in various
+/// formats, including jpeg, png and svg.
+/////////////////////////////////////////////////////////////////////////
+
+public class Image : GLib.Object {
+
+ /////////////////////////////////////////////////////////////////////
+ /// The internally used surface.
+ /////////////////////////////////////////////////////////////////////
+
+ public Cairo.ImageSurface surface { public get; protected set; default=null; }
+
+ /////////////////////////////////////////////////////////////////////
+ /// Creates an empty Image.
+ /////////////////////////////////////////////////////////////////////
+
+ public Image.empty(int width, int height, Color? color = null) {
+ this.surface = new Cairo.ImageSurface(Cairo.Format.ARGB32, width, height);
+
+ if (color != null) {
+ var ctx = this.context();
+ ctx.set_source_rgb(color.r, color.g, color.b);
+ ctx.paint();
+ }
+ }
+
+ /////////////////////////////////////////////////////////////////////
+ /// Creates an image from the the given filename.
+ /////////////////////////////////////////////////////////////////////
+
+ public Image.from_file(string filename) {
+ this.load_file(filename);
+ }
+
+ /////////////////////////////////////////////////////////////////////
+ /// Creates an image from the the given filename at a given size.
+ /////////////////////////////////////////////////////////////////////
+
+ public Image.from_file_at_size(string filename, int width, int height) {
+ this.load_file_at_size(filename, width, height);
+ }
+
+ /////////////////////////////////////////////////////////////////////
+ /// Creates an image from the the given Gdk.Pixbuf.
+ /////////////////////////////////////////////////////////////////////
+
+ public Image.from_pixbuf(Gdk.Pixbuf pixbuf) {
+ this.load_pixbuf(pixbuf);
+ }
+
+ public Image.capture_screen(int posx, int posy, int width, int height) {
+ Gdk.Window root = Gdk.get_default_root_window();
+ Gdk.Pixbuf pixbuf = Gdk.pixbuf_get_from_drawable(null, root, null, posx, posy, 0, 0, width, height);
+
+ this.load_pixbuf(pixbuf);
+ }
+
+ /////////////////////////////////////////////////////////////////////
+ /// Loads an image from the the given filename.
+ /////////////////////////////////////////////////////////////////////
+
+ public void load_file(string filename) {
+ try {
+ var pixbuf = new Gdk.Pixbuf.from_file(filename);
+
+ if (pixbuf != null) {
+ this.load_pixbuf(pixbuf);
+ } else {
+ warning("Failed to load " + filename + "!");
+ }
+ } catch (GLib.Error e) {
+ message("Error loading image file: %s", e.message);
+ this.surface = new Cairo.ImageSurface(Cairo.Format.ARGB32, 1, 1);
+ }
+ }
+
+ /////////////////////////////////////////////////////////////////////
+ /// Loads an image from the the given filename at a given size.
+ /////////////////////////////////////////////////////////////////////
+
+ public void load_file_at_size(string filename, int width, int height) {
+ try {
+ var pixbuf = new Gdk.Pixbuf.from_file_at_size(filename, width, height);
+
+ if (pixbuf != null) {
+ this.load_pixbuf(pixbuf);
+ } else {
+ warning("Failed to load " + filename + "!");
+ }
+ } catch (GLib.Error e) {
+ message("Error loading image file: %s", e.message);
+ this.surface = new Cairo.ImageSurface(Cairo.Format.ARGB32, width, height);
+ }
+ }
+
+ /////////////////////////////////////////////////////////////////////
+ /// Loads an image from the the given Gdk.Pixbuf.
+ /////////////////////////////////////////////////////////////////////
+
+ public void load_pixbuf(Gdk.Pixbuf pixbuf) {
+ this.surface = new Cairo.ImageSurface(Cairo.Format.ARGB32, pixbuf.width, pixbuf.height);
+
+ var ctx = this.context();
+ Gdk.cairo_set_source_pixbuf(ctx, pixbuf, 1.0, 1.0);
+ ctx.paint();
+ }
+
+ /////////////////////////////////////////////////////////////////////
+ /// Paints the image onto the given Cairo.Context
+ /////////////////////////////////////////////////////////////////////
+
+ public void paint_on(Cairo.Context ctx, double alpha = 1.0) {
+ ctx.set_source_surface(this.surface, -0.5*this.width()-1, -0.5*this.height()-1);
+ if (alpha >= 1.0) ctx.paint();
+ else ctx.paint_with_alpha(alpha);
+ }
+
+ /////////////////////////////////////////////////////////////////////
+ /// Returns a Cairo.Context for the Image.
+ /////////////////////////////////////////////////////////////////////
+
+ public Cairo.Context context() {
+ return new Cairo.Context(this.surface);;
+ }
+
+ /////////////////////////////////////////////////////////////////////
+ /// Returns the width of the image in pixels.
+ /////////////////////////////////////////////////////////////////////
+
+ public int width() {
+ return this.surface.get_width();
+ }
+
+ /////////////////////////////////////////////////////////////////////
+ /// Returns the height of the image in pixels.
+ /////////////////////////////////////////////////////////////////////
+
+ public int height() {
+ return this.surface.get_height();
+ }
+}
+
+}
diff --git a/src/utilities/key.vala b/src/utilities/key.vala
new file mode 100644
index 0000000..6700b16
--- /dev/null
+++ b/src/utilities/key.vala
@@ -0,0 +1,139 @@
+/*
+Copyright (c) 2011 by Simon Schneegans
+
+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 3 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, see <http://www.gnu.org/licenses/>.
+*/
+
+namespace GnomePie {
+
+/////////////////////////////////////////////////////////////////////////
+/// A class which represents a key stroke. It can be used to "press"
+/// the associated keys.
+/////////////////////////////////////////////////////////////////////////
+
+public class Key : GLib.Object {
+
+ /////////////////////////////////////////////////////////////////////
+ /// Some static members, which are often used by this class.
+ /////////////////////////////////////////////////////////////////////
+
+ private static X.Display display;
+
+ private static int shift_code;
+ private static int ctrl_code;
+ private static int alt_code;
+ private static int super_code;
+
+ /////////////////////////////////////////////////////////////////////
+ /// A human readable form of the Key's accelerator.
+ /////////////////////////////////////////////////////////////////////
+
+ public string label { get; private set; }
+
+ /////////////////////////////////////////////////////////////////////
+ /// The accelerator of the Key.
+ /////////////////////////////////////////////////////////////////////
+
+ public string accelerator { get; private set; }
+
+ /////////////////////////////////////////////////////////////////////
+ /// Keycode and modifiers of this stroke.
+ /////////////////////////////////////////////////////////////////////
+
+ private int key_code;
+ private Gdk.ModifierType modifiers;
+
+ /////////////////////////////////////////////////////////////////////
+ /// C'tor, initializes all members.
+ /////////////////////////////////////////////////////////////////////
+
+ public Key(string stroke) {
+ this.accelerator = stroke;
+
+ uint keysym;
+ Gtk.accelerator_parse(stroke, out keysym, out this.modifiers);
+ this.key_code = display.keysym_to_keycode(keysym);
+ this.label = Gtk.accelerator_get_label(keysym, this.modifiers);
+ }
+
+ /////////////////////////////////////////////////////////////////////
+ /// Initializes static members.
+ /////////////////////////////////////////////////////////////////////
+
+ static construct {
+ display = new X.Display();
+
+ shift_code = display.keysym_to_keycode(Gdk.keyval_from_name("Shift_L"));
+ ctrl_code = display.keysym_to_keycode(Gdk.keyval_from_name("Control_L"));
+ alt_code = display.keysym_to_keycode(Gdk.keyval_from_name("Alt_L"));
+ super_code = display.keysym_to_keycode(Gdk.keyval_from_name("Super_L"));
+ }
+
+ /////////////////////////////////////////////////////////////////////
+ /// Simulates the pressing of the Key .
+ /////////////////////////////////////////////////////////////////////
+
+ public void press() {
+ // store currently pressed modifier keys
+ Gdk.ModifierType current_modifiers = get_modifiers();
+
+ // release them and press the desired ones
+ press_modifiers(current_modifiers, false);
+ press_modifiers(this.modifiers, true);
+
+ // send events to X
+ display.flush();
+
+ // press and release the actual key
+ X.Test.fake_key_event(this.display, this.key_code, true, 0);
+ X.Test.fake_key_event(this.display, this.key_code, false, 0);
+
+ // release the pressed modifiers and re-press the keys hold down by the user
+ press_modifiers(this.modifiers, false);
+ press_modifiers(current_modifiers, true);
+
+ // send events to X
+ display.flush();
+ }
+
+ /////////////////////////////////////////////////////////////////////
+ /// Helper method returning currently hold down modifier keys.
+ /////////////////////////////////////////////////////////////////////
+
+ private Gdk.ModifierType get_modifiers() {
+ Gdk.ModifierType modifiers;
+ Gdk.Display.get_default().get_pointer(null, null, null, out modifiers);
+ return modifiers;
+ }
+
+ /////////////////////////////////////////////////////////////////////
+ /// Helper method which 'presses' the desired modifier keys.
+ /////////////////////////////////////////////////////////////////////
+
+ private void press_modifiers(Gdk.ModifierType modifiers, bool down) {
+ if ((modifiers & Gdk.ModifierType.CONTROL_MASK) > 0)
+ X.Test.fake_key_event(this.display, this.ctrl_code, down, 0);
+
+ if ((modifiers & Gdk.ModifierType.SHIFT_MASK) > 0)
+ X.Test.fake_key_event(this.display, this.shift_code, down, 0);
+
+ if ((modifiers & Gdk.ModifierType.MOD1_MASK) > 0)
+ X.Test.fake_key_event(this.display, this.alt_code, down, 0);
+
+ if ((modifiers & Gdk.ModifierType.SUPER_MASK) > 0)
+ X.Test.fake_key_event(this.display, this.super_code, down, 0);
+ }
+}
+
+}
diff --git a/src/utilities/logger.vala b/src/utilities/logger.vala
new file mode 100644
index 0000000..3108ba3
--- /dev/null
+++ b/src/utilities/logger.vala
@@ -0,0 +1,194 @@
+/*
+Copyright (c) 2011 by Simon Schneegans
+
+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 3 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, see <http://www.gnu.org/licenses/>.
+*/
+
+namespace GnomePie {
+
+/////////////////////////////////////////////////////////////////////////
+/// A static class which beautifies the messages of the default logger.
+/// Some of this code is inspired by plank's written by Robert Dyer.
+/// Thanks a lot for this project!
+/////////////////////////////////////////////////////////////////////////
+
+public class Logger {
+
+ /////////////////////////////////////////////////////////////////////
+ /// If these are set to false, the according messages are not shown
+ /////////////////////////////////////////////////////////////////////
+
+ public static bool display_info { get; set; default = true; }
+ public static bool display_debug { get; set; default = true; }
+ public static bool display_warning { get; set; default = true; }
+ public static bool display_error { get; set; default = true; }
+
+ /////////////////////////////////////////////////////////////////////
+ /// If true, a time stamp is shown in each message.
+ /////////////////////////////////////////////////////////////////////
+
+ public static bool display_time { get; set; default = true; }
+
+ /////////////////////////////////////////////////////////////////////
+ /// If true, the origin of the message is shown. In form file:line
+ /////////////////////////////////////////////////////////////////////
+
+ public static bool display_file { get; set; default = false; }
+
+ /////////////////////////////////////////////////////////////////////
+ /// A regex, used to format the standard message.
+ /////////////////////////////////////////////////////////////////////
+
+ private static Regex regex = null;
+
+ /////////////////////////////////////////////////////////////////////
+ /// Possible terminal colors.
+ /////////////////////////////////////////////////////////////////////
+
+ private enum Color {
+ BLACK,
+ RED,
+ GREEN,
+ YELLOW,
+ BLUE,
+ PURPLE,
+ TURQUOISE,
+ WHITE
+ }
+
+ /////////////////////////////////////////////////////////////////////
+ /// Creates the regex and binds the handler.
+ /////////////////////////////////////////////////////////////////////
+
+ public static void init() {
+ try {
+ regex = new Regex("""(.*)\.vala(:\d+): (.*)""");
+ } catch {}
+
+ GLib.Log.set_default_handler(log_func);
+ }
+
+ /////////////////////////////////////////////////////////////////////
+ /// Displays an Info message.
+ /////////////////////////////////////////////////////////////////////
+
+ private static void info(string message) {
+ if (display_info) {
+ stdout.printf(set_color(Color.GREEN, false) + "[" + get_time() + "MESSAGE]" + message);
+ }
+ }
+
+ /////////////////////////////////////////////////////////////////////
+ /// Displays a Debug message.
+ /////////////////////////////////////////////////////////////////////
+
+ private static void debug(string message) {
+ if (display_debug) {
+ stdout.printf(set_color(Color.BLUE, false) + "[" + get_time() + " DEBUG ]" + message);
+ }
+ }
+
+ /////////////////////////////////////////////////////////////////////
+ /// Displays a Warning message.
+ /////////////////////////////////////////////////////////////////////
+
+ private static void warning(string message) {
+ if (display_warning) {
+ stdout.printf(set_color(Color.YELLOW, false) + "[" + get_time() + "WARNING]" + message);
+ }
+ }
+
+ /////////////////////////////////////////////////////////////////////
+ /// Displays a Error message.
+ /////////////////////////////////////////////////////////////////////
+
+ private static void error(string message) {
+ if (display_error) {
+ stdout.printf(set_color(Color.RED, false) + "[" + get_time() + " ERROR ]" + message);
+ }
+ }
+
+ /////////////////////////////////////////////////////////////////////
+ /// Helper method which resets the terminal color.
+ /////////////////////////////////////////////////////////////////////
+
+ private static string reset_color() {
+ return "\x001b[0m";
+ }
+
+ /////////////////////////////////////////////////////////////////////
+ /// Helper method which sets the terminal color.
+ /////////////////////////////////////////////////////////////////////
+
+ private static string set_color(Color color, bool bold) {
+ if (bold) return "\x001b[1;%dm".printf((int)color + 30);
+ else return "\x001b[0;%dm".printf((int)color + 30);
+ }
+
+ /////////////////////////////////////////////////////////////////////
+ /// Returns the current time in hh:mm:ss:mmmmmm
+ /////////////////////////////////////////////////////////////////////
+
+ private static string get_time() {
+ if (display_time) {
+ var now = new DateTime.now_local ();
+ return "%.2d:%.2d:%.2d:%.6d ".printf (now.get_hour (), now.get_minute (), now.get_second (), now.get_microsecond ());
+ } else {
+ return "";
+ }
+ }
+
+ /////////////////////////////////////////////////////////////////////
+ /// Helper method to format the message.
+ /////////////////////////////////////////////////////////////////////
+
+ private static string create_message(string message) {
+ if (display_file && regex != null && regex.match(message)) {
+ var parts = regex.split(message);
+ return " [%s%s]%s %s\n".printf(parts[1], parts[2], reset_color(), parts[3]);
+ } else if (regex != null && regex.match(message)) {
+ var parts = regex.split(message);
+ return "%s %s\n".printf(reset_color(), parts[3]);
+ } else {
+ return reset_color() + " " + message + "\n";
+ }
+ }
+
+ /////////////////////////////////////////////////////////////////////
+ /// The handler function.
+ /////////////////////////////////////////////////////////////////////
+
+ private static void log_func(string? d, LogLevelFlags flags, string message) {
+
+ switch (flags) {
+ case LogLevelFlags.LEVEL_ERROR:
+ case LogLevelFlags.LEVEL_CRITICAL:
+ error(create_message(message));
+ break;
+ case LogLevelFlags.LEVEL_INFO:
+ case LogLevelFlags.LEVEL_MESSAGE:
+ info(create_message(message));
+ break;
+ case LogLevelFlags.LEVEL_DEBUG:
+ debug(create_message(message));
+ break;
+ case LogLevelFlags.LEVEL_WARNING:
+ default:
+ warning(create_message(message));
+ break;
+ }
+ }
+}
+
+}
diff --git a/src/utilities/paths.vala b/src/utilities/paths.vala
new file mode 100644
index 0000000..1c42176
--- /dev/null
+++ b/src/utilities/paths.vala
@@ -0,0 +1,211 @@
+/*
+Copyright (c) 2011 by Simon Schneegans
+
+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 3 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, see <http://www.gnu.org/licenses/>.
+*/
+
+namespace GnomePie {
+
+/////////////////////////////////////////////////////////////////////////
+/// A static class which stores all relevant paths used by Gnome-Pie.
+/// These depend upon the location from which the program was launched.
+/////////////////////////////////////////////////////////////////////////
+
+public class Paths : GLib.Object {
+
+ /////////////////////////////////////////////////////////////////////
+ /// The file settings file,
+ /// usually ~/.config/gnome-pie/gnome-pie.conf.
+ /////////////////////////////////////////////////////////////////////
+
+ public static string settings { get; private set; default=""; }
+
+ /////////////////////////////////////////////////////////////////////
+ /// The file pie configuration file
+ /// usually ~/.config/gnome-pie/pies.conf.
+ /////////////////////////////////////////////////////////////////////
+
+ public static string pie_config { get; private set; default=""; }
+
+ /////////////////////////////////////////////////////////////////////
+ /// The directory containing themes installed by the user
+ /// usually ~/.config/gnome-pie/themes.
+ /////////////////////////////////////////////////////////////////////
+
+ public static string local_themes { get; private set; default=""; }
+
+ /////////////////////////////////////////////////////////////////////
+ /// The directory containing pre-installed themes
+ /// usually /usr/share/gnome-pie/themes.
+ /////////////////////////////////////////////////////////////////////
+
+ public static string global_themes { get; private set; default=""; }
+
+ /////////////////////////////////////////////////////////////////////
+ /// The directory containing locale files
+ /// usually /usr/share/locale.
+ /////////////////////////////////////////////////////////////////////
+
+ public static string locales { get; private set; default=""; }
+
+ /////////////////////////////////////////////////////////////////////
+ /// The autostart file of gnome-pie_config
+ /// usually ~/.config/autostart/gnome-pie.desktop.
+ /////////////////////////////////////////////////////////////////////
+
+ public static string autostart { get; private set; default=""; }
+
+ /////////////////////////////////////////////////////////////////////
+ /// The path where all pie-launchers are stored
+ /// usually ~/.config/gnome-pie/launchers.
+ /////////////////////////////////////////////////////////////////////
+
+ public static string launchers { get; private set; default=""; }
+
+ /////////////////////////////////////////////////////////////////////
+ /// Initializes all values above.
+ /////////////////////////////////////////////////////////////////////
+
+ public static void init() {
+
+ // append resources to icon search path to icon theme, if neccasary
+ try {
+ var icon_dir = GLib.File.new_for_path(GLib.Path.get_dirname(
+ GLib.FileUtils.read_link("/proc/self/exe"))).get_child("resources");
+
+ if (icon_dir.query_exists()) {
+ string path = icon_dir.get_path();
+ Gtk.IconTheme.get_default().append_search_path(path);
+ }
+
+ Gtk.IconTheme.get_default().append_search_path("/usr/share/pixmaps/");
+
+ } catch (GLib.FileError e) {
+ warning("Failed to get path of executable!");
+ }
+
+ // get global paths
+ var default_dir = GLib.File.new_for_path("/usr/share/gnome-pie/");
+ if(!default_dir.query_exists()) {
+ default_dir = GLib.File.new_for_path("/usr/local/share/gnome-pie/");
+
+ if(!default_dir.query_exists()) {
+ try {
+ default_dir = GLib.File.new_for_path(GLib.Path.get_dirname(
+ GLib.FileUtils.read_link("/proc/self/exe"))).get_child("resources");
+ } catch (GLib.FileError e) {
+ warning("Failed to get path of executable!");
+ }
+ }
+ }
+
+ global_themes = default_dir.get_path() + "/themes";
+
+ // get locales path
+ var locale_dir = GLib.File.new_for_path("/usr/share/locale/de/LC_MESSAGES/gnomepie.mo");
+ if(locale_dir.query_exists()) {
+ locale_dir = GLib.File.new_for_path("/usr/share/locale");
+ } else {
+ locale_dir = GLib.File.new_for_path("/usr/local/share/locale/de/LC_MESSAGES/gnomepie.mo");
+ if(locale_dir.query_exists()) {
+ locale_dir = GLib.File.new_for_path("/usr/local/share/locale");
+ } else {
+
+ try {
+ locale_dir = GLib.File.new_for_path(GLib.Path.get_dirname(
+ GLib.FileUtils.read_link("/proc/self/exe"))).get_child(
+ "resources/locale/de/LC_MESSAGES/gnomepie.mo");
+ } catch (GLib.FileError e) {
+ warning("Failed to get path of executable!");
+ }
+
+ if(locale_dir.query_exists()) {
+ try {
+ locale_dir = GLib.File.new_for_path(GLib.Path.get_dirname(
+ GLib.FileUtils.read_link("/proc/self/exe"))).get_child("resources/locale");
+ } catch (GLib.FileError e) {
+ warning("Failed to get path of executable!");
+ }
+ }
+ }
+ }
+
+ locales = locale_dir.get_path();
+
+ // get local paths
+ var config_dir = GLib.File.new_for_path(
+ GLib.Environment.get_user_config_dir()).get_child("gnome-pie");
+
+ // create config_dir if neccasary
+ if(!config_dir.query_exists()) {
+ try {
+ config_dir.make_directory();
+ } catch (GLib.Error e) {
+ error(e.message);
+ }
+ }
+
+ // create local themes directory if neccasary
+ var themes_dir = config_dir.get_child("themes");
+ if(!themes_dir.query_exists()) {
+ try {
+ themes_dir.make_directory();
+ } catch (GLib.Error e) {
+ error(e.message);
+ }
+ }
+
+ local_themes = themes_dir.get_path();
+
+ // create launchers directory if neccasary
+ var launchers_dir = config_dir.get_child("launchers");
+ if(!launchers_dir.query_exists()) {
+ try {
+ launchers_dir.make_directory();
+ } catch (GLib.Error e) {
+ error(e.message);
+ }
+ }
+
+ launchers = launchers_dir.get_path();
+
+ // check for config file
+ var config_file = config_dir.get_child("pies.conf");
+
+ pie_config = config_file.get_path();
+ settings = config_dir.get_path() + "/gnome-pie.conf";
+
+ // autostart file name
+ autostart = GLib.Path.build_filename(GLib.Environment.get_user_config_dir(),
+ "autostart", "gnome-pie.desktop", null);
+
+ // print results
+ if (!GLib.File.new_for_path(pie_config).query_exists())
+ warning("Failed to find pie configuration file \"pies.conf\"! (This should only happen when Gnome-Pie is started for the first time...)");
+
+ if (!GLib.File.new_for_path(settings).query_exists())
+ warning("Failed to find settings file \"gnome-pie.conf\"!");
+
+ if (!GLib.File.new_for_path(local_themes).query_exists())
+ warning("Failed to find local themes directory!");
+
+ if (!GLib.File.new_for_path(launchers).query_exists())
+ warning("Failed to find launchers directory!");
+
+ if (!GLib.File.new_for_path(global_themes).query_exists())
+ warning("Failed to find global themes directory!");
+ }
+}
+
+}
diff --git a/src/utilities/renderedText.vala b/src/utilities/renderedText.vala
new file mode 100644
index 0000000..924742a
--- /dev/null
+++ b/src/utilities/renderedText.vala
@@ -0,0 +1,110 @@
+/*
+Copyright (c) 2011 by Simon Schneegans
+
+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 3 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, see <http://www.gnu.org/licenses/>.
+*/
+
+namespace GnomePie {
+
+/////////////////////////////////////////////////////////////////////////
+/// A class representing string, rendered on an Image.
+/////////////////////////////////////////////////////////////////////////
+
+public class RenderedText : Image {
+
+ /////////////////////////////////////////////////////////////////////
+ /// A cache which stores images. It is cleared when the theme of
+ /// Gnome-Pie changes.
+ /// The key is in form <string>@<width>x<height>:<font>.
+ /////////////////////////////////////////////////////////////////////
+
+ private static Gee.HashMap<string, Cairo.ImageSurface?> cache { private get; private set; }
+
+ /////////////////////////////////////////////////////////////////////
+ /// Initializes the cache.
+ /////////////////////////////////////////////////////////////////////
+
+ public static void init() {
+ clear_cache();
+
+ Config.global.notify["theme"].connect(() => {
+ clear_cache();
+ });
+ }
+
+ /////////////////////////////////////////////////////////////////////
+ /// Clears the cache.
+ /////////////////////////////////////////////////////////////////////
+
+ static void clear_cache() {
+ cache = new Gee.HashMap<string, Cairo.ImageSurface?>();
+ }
+
+ /////////////////////////////////////////////////////////////////////
+ /// C'tor, creates a new image representation of a string.
+ /////////////////////////////////////////////////////////////////////
+
+ public RenderedText(string text, int width, int height, string font) {
+ var cached = this.cache.get("%s@%ux%u:%s".printf(text, width, height, font));
+
+ if (cached == null) {
+ this.render_text(text, width, height, font);
+ this.cache.set("%s@%ux%u:%s".printf(text, width, height, font), this.surface);
+ } else {
+ this.surface = cached;
+ }
+ }
+
+ /////////////////////////////////////////////////////////////////////
+ /// Creates a new transparent image, with text written onto.
+ /////////////////////////////////////////////////////////////////////
+
+ public void render_text(string text, int width, int height, string font) {
+ this.surface = new Cairo.ImageSurface(Cairo.Format.ARGB32, width, height);
+
+ var ctx = this.context();
+
+ // set the color as specified in the current theme
+ Color color = Config.global.theme.caption_color;
+ ctx.set_source_rgb(color.r, color.g, color.g);
+
+ var layout = Pango.cairo_create_layout(ctx);
+ layout.set_width(Pango.units_from_double(width));
+
+ var font_description = Pango.FontDescription.from_string(font);
+ font_description.set_size((int)(font_description.get_size() * Config.global.global_scale));
+
+ layout.set_font_description(font_description);
+ layout.set_text(text, -1);
+
+ // add newlines at the end of each line, in order to allow ellipsizing
+ string broken_string = "";
+ foreach (var line in layout.get_lines()) {
+ broken_string = broken_string.concat(text.substring(line.start_index, line.length), "\n");
+ }
+ layout.set_text(broken_string, broken_string.length-1);
+
+ layout.set_ellipsize(Pango.EllipsizeMode.END);
+ layout.set_alignment(Pango.Alignment.CENTER);
+
+ Pango.Rectangle extents;
+ layout.get_pixel_extents(null, out extents);
+ ctx.move_to(0, (int)(0.5*(height - extents.height)));
+
+ Pango.cairo_update_layout(ctx, layout);
+ Pango.cairo_show_layout(ctx, layout);
+ }
+}
+
+}
diff --git a/src/utilities/themedIcon.vala b/src/utilities/themedIcon.vala
new file mode 100644
index 0000000..29ae380
--- /dev/null
+++ b/src/utilities/themedIcon.vala
@@ -0,0 +1,161 @@
+/*
+Copyright (c) 2011 by Simon Schneegans
+
+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 3 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, see <http://www.gnu.org/licenses/>.
+*/
+
+namespace GnomePie {
+
+/////////////////////////////////////////////////////////////////////////
+/// A class representing a square-shaped icon, themed according to the
+/// current theme of Gnome-Pie.
+/////////////////////////////////////////////////////////////////////////
+
+public class ThemedIcon : Image {
+
+ /////////////////////////////////////////////////////////////////////
+ /// A cache which stores loaded icon. The key is the icon name. When
+ /// the users icon theme or the theme of Gnome-Pie changes, these
+ /// cahces are cleared.
+ /////////////////////////////////////////////////////////////////////
+
+ private static Gee.HashMap<string, Cairo.ImageSurface?> active_cache { private get; private set; }
+ private static Gee.HashMap<string, Cairo.ImageSurface?> inactive_cache { private get; private set; }
+
+ /////////////////////////////////////////////////////////////////////
+ /// Initializes the caches.
+ /////////////////////////////////////////////////////////////////////
+
+ public static void init() {
+ clear_cache();
+
+ Config.global.notify["theme"].connect(() => {
+ clear_cache();
+ });
+
+ Gtk.IconTheme.get_default().changed.connect(() => {
+ clear_cache();
+ });
+ }
+
+ /////////////////////////////////////////////////////////////////////
+ /// Clears the cache.
+ /////////////////////////////////////////////////////////////////////
+
+ public static void clear_cache() {
+ active_cache = new Gee.HashMap<string, Cairo.ImageSurface?>();
+ inactive_cache = new Gee.HashMap<string, Cairo.ImageSurface?>();
+ }
+
+ /////////////////////////////////////////////////////////////////////
+ /// Paint a slice icon according to the current theme.
+ /////////////////////////////////////////////////////////////////////
+
+ public ThemedIcon(string icon_name, bool active) {
+ // check cache
+ var current_cache = active ? active_cache : inactive_cache;
+ var cached = current_cache.get(icon_name);
+
+ if (cached != null) {
+ this.surface = cached;
+ return;
+ }
+
+ // get layers for the desired slice type
+ var layers = active ? Config.global.theme.active_slice_layers : Config.global.theme.inactive_slice_layers;
+
+ // get max size
+ int size = 0;
+ foreach (var layer in layers) {
+ if (layer.image.width() > size) size = layer.image.width();
+ }
+
+ this.surface = new Cairo.ImageSurface(Cairo.Format.ARGB32, size, size);
+
+ // get size of icon layer
+ int icon_size = size;
+ foreach (var layer in layers) {
+ if (layer.is_icon) icon_size = layer.image.width();
+ }
+
+ Image icon;
+ if (icon_name.contains("/"))
+ icon = new Image.from_file_at_size(icon_name, icon_size, icon_size);
+ else
+ icon = new Icon(icon_name, icon_size);
+
+ var color = new Color.from_icon(icon);
+ var ctx = this.context();
+
+ ctx.translate(size/2, size/2);
+ ctx.set_operator(Cairo.Operator.OVER);
+
+ // now render all layers on top of each other
+ foreach (var layer in layers) {
+
+ if (layer.colorize) {
+ ctx.push_group();
+ }
+
+ if (layer.is_icon) {
+
+ ctx.push_group();
+
+ layer.image.paint_on(ctx);
+
+ ctx.set_operator(Cairo.Operator.IN);
+
+ if (layer.image.width() != icon_size) {
+ if (icon_name.contains("/"))
+ icon = new Image.from_file_at_size(icon_name, layer.image.width(), layer.image.width());
+ else
+ icon = new Icon(icon_name,layer.image.width());
+ }
+
+ icon.paint_on(ctx);
+
+ ctx.pop_group_to_source();
+ ctx.paint();
+ ctx.set_operator(Cairo.Operator.OVER);
+
+ } else {
+ layer.image.paint_on(ctx);
+ }
+
+ // colorize the whole layer if neccasary
+ if (layer.colorize) {
+ ctx.set_operator(Cairo.Operator.ATOP);
+ ctx.set_source_rgb(color.r, color.g, color.b);
+ ctx.paint();
+
+ ctx.set_operator(Cairo.Operator.OVER);
+ ctx.pop_group_to_source();
+ ctx.paint();
+ }
+ }
+
+ // store the surface in cache
+ current_cache.set(icon_name, this.surface);
+ }
+
+ /////////////////////////////////////////////////////////////////////
+ /// Returns the size of the icon in pixels. Greetings to Liskov.
+ /////////////////////////////////////////////////////////////////////
+
+ public int size() {
+ return base.width();
+ }
+}
+
+}
diff --git a/vapi/appindicator-0.1.vapi b/vapi/appindicator-0.1.vapi
new file mode 100644
index 0000000..b2d3b34
--- /dev/null
+++ b/vapi/appindicator-0.1.vapi
@@ -0,0 +1,94 @@
+/* appindicator-0.1.vapi generated by vapigen, do not modify. */
+
+[CCode (cprefix = "App", lower_case_cprefix = "app_", gir_namespace = "AppIndicator", gir_version = "0.1")]
+namespace AppIndicator {
+ [CCode (cheader_filename = "libappindicator/app-indicator.h")]
+ public class Indicator : GLib.Object {
+ public AppIndicator.IndicatorPrivate priv;
+ [CCode (has_construct_function = false)]
+ public Indicator (string id, string icon_name, AppIndicator.IndicatorCategory category);
+ public void build_menu_from_desktop (string desktop_file, string desktop_profile);
+ public unowned string get_attention_icon ();
+ public unowned string get_attention_icon_desc ();
+ public AppIndicator.IndicatorCategory get_category ();
+ public unowned string get_icon ();
+ public unowned string get_icon_desc ();
+ public unowned string get_icon_theme_path ();
+ public unowned string get_id ();
+ public unowned string get_label ();
+ public unowned string get_label_guide ();
+ public unowned Gtk.Menu get_menu ();
+ public uint32 get_ordering_index ();
+ public unowned Gtk.Widget get_secondary_activate_target ();
+ public AppIndicator.IndicatorStatus get_status ();
+ public void set_attention_icon (string icon_name);
+ public void set_attention_icon_full (string icon_name, string icon_desc);
+ public void set_icon (string icon_name);
+ public void set_icon_full (string icon_name, string icon_desc);
+ public void set_icon_theme_path (string icon_theme_path);
+ public void set_label (string label, string guide);
+ public void set_menu (Gtk.Menu? menu);
+ public void set_ordering_index (uint32 ordering_index);
+ public void set_secondary_activate_target (Gtk.Widget? menuitem);
+ public void set_status (AppIndicator.IndicatorStatus status);
+ [NoWrapper]
+ public virtual void unfallback (Gtk.StatusIcon status_icon);
+ [CCode (has_construct_function = false)]
+ public Indicator.with_path (string id, string icon_name, AppIndicator.IndicatorCategory category, string icon_theme_path);
+ public string attention_icon_desc { get; set; }
+ [NoAccessorMethod]
+ public string attention_icon_name { get; set; }
+ public string category { get; construct; }
+ [NoAccessorMethod]
+ public bool connected { get; }
+ public string icon_desc { get; set; }
+ [NoAccessorMethod]
+ public string icon_name { get; set; }
+ public string icon_theme_path { get; set construct; }
+ public string id { get; construct; }
+ public string label { get; set; }
+ public string label_guide { get; set; }
+ public uint ordering_index { get; set; }
+ public string status { get; set; }
+ public virtual signal void connection_changed (bool indicator);
+ public virtual signal void new_attention_icon ();
+ public virtual signal void new_icon ();
+ public virtual signal void new_icon_theme_path (string indicator);
+ public virtual signal void new_label (string indicator, string label);
+ public virtual signal void new_status (string indicator);
+ public virtual signal void scroll_event (int indicator, uint delta);
+ }
+ [CCode (type_id = "APP_TYPE_INDICATOR_PRIVATE", cheader_filename = "libappindicator/app-indicator.h")]
+ public struct IndicatorPrivate {
+ }
+ [CCode (cprefix = "APP_INDICATOR_CATEGORY_", cheader_filename = "libappindicator/app-indicator.h")]
+ public enum IndicatorCategory {
+ APPLICATION_STATUS,
+ COMMUNICATIONS,
+ SYSTEM_SERVICES,
+ HARDWARE,
+ OTHER
+ }
+ [CCode (cprefix = "APP_INDICATOR_STATUS_", cheader_filename = "libappindicator/app-indicator.h")]
+ public enum IndicatorStatus {
+ PASSIVE,
+ ACTIVE,
+ ATTENTION
+ }
+ [CCode (cheader_filename = "libappindicator/app-indicator.h")]
+ public const string INDICATOR_SHORTY_NICK;
+ [CCode (cheader_filename = "libappindicator/app-indicator.h")]
+ public const string INDICATOR_SIGNAL_CONNECTION_CHANGED;
+ [CCode (cheader_filename = "libappindicator/app-indicator.h")]
+ public const string INDICATOR_SIGNAL_NEW_ATTENTION_ICON;
+ [CCode (cheader_filename = "libappindicator/app-indicator.h")]
+ public const string INDICATOR_SIGNAL_NEW_ICON;
+ [CCode (cheader_filename = "libappindicator/app-indicator.h")]
+ public const string INDICATOR_SIGNAL_NEW_ICON_THEME_PATH;
+ [CCode (cheader_filename = "libappindicator/app-indicator.h")]
+ public const string INDICATOR_SIGNAL_NEW_LABEL;
+ [CCode (cheader_filename = "libappindicator/app-indicator.h")]
+ public const string INDICATOR_SIGNAL_NEW_STATUS;
+ [CCode (cheader_filename = "libappindicator/app-indicator.h")]
+ public const string INDICATOR_SIGNAL_SCROLL_EVENT;
+}
diff --git a/vapi/gee-1.0.vapi b/vapi/gee-1.0.vapi
new file mode 100644
index 0000000..fe9ea6c
--- /dev/null
+++ b/vapi/gee-1.0.vapi
@@ -0,0 +1,416 @@
+/* gee-1.0.vapi generated by valac-0.12 0.12.1, do not modify. */
+
+[CCode (cprefix = "Gee", lower_case_cprefix = "gee_", gir_namespace = "Gee", gir_version = "1.0")]
+namespace Gee {
+ [CCode (cprefix = "GeeFunctions", lower_case_cprefix = "gee_functions_")]
+ namespace Functions {
+ [CCode (cheader_filename = "gee.h")]
+ public static GLib.CompareFunc get_compare_func_for (GLib.Type t);
+ [CCode (cheader_filename = "gee.h")]
+ public static GLib.EqualFunc get_equal_func_for (GLib.Type t);
+ [CCode (cheader_filename = "gee.h")]
+ public static GLib.HashFunc get_hash_func_for (GLib.Type t);
+ }
+ [CCode (cheader_filename = "gee.h")]
+ public abstract class AbstractCollection<G> : GLib.Object, Gee.Iterable<G>, Gee.Collection<G> {
+ public AbstractCollection ();
+ public abstract bool add (G item);
+ public virtual bool add_all (Gee.Collection<G> collection);
+ public abstract void clear ();
+ public abstract bool contains (G item);
+ public virtual bool contains_all (Gee.Collection<G> collection);
+ public abstract Gee.Iterator<G> iterator ();
+ public abstract bool remove (G item);
+ public virtual bool remove_all (Gee.Collection<G> collection);
+ public virtual bool retain_all (Gee.Collection<G> collection);
+ public virtual G[] to_array ();
+ public virtual bool is_empty { get; }
+ public virtual Gee.Collection<G> read_only_view { owned get; }
+ public abstract int size { get; }
+ }
+ [CCode (cheader_filename = "gee.h")]
+ public abstract class AbstractList<G> : Gee.AbstractCollection<G>, Gee.List<G> {
+ public AbstractList ();
+ public virtual G first ();
+ public abstract new G @get (int index);
+ public abstract int index_of (G item);
+ public abstract void insert (int index, G item);
+ public virtual void insert_all (int index, Gee.Collection<G> collection);
+ public virtual G last ();
+ public abstract Gee.ListIterator<G> list_iterator ();
+ public abstract G remove_at (int index);
+ public abstract new void @set (int index, G item);
+ public abstract Gee.List<G>? slice (int start, int stop);
+ public virtual Gee.List<G> read_only_view { owned get; }
+ }
+ [CCode (cheader_filename = "gee.h")]
+ public abstract class AbstractMap<K,V> : GLib.Object, Gee.Iterable<Gee.Map.Entry<K,V>>, Gee.Map<K,V> {
+ public AbstractMap ();
+ public abstract void clear ();
+ public abstract new V @get (K key);
+ public abstract bool has (K key, V value);
+ public virtual bool has_all (Gee.Map<K,V> map);
+ public abstract bool has_key (K key);
+ public abstract Gee.MapIterator<K,V> map_iterator ();
+ public abstract new void @set (K key, V value);
+ public virtual void set_all (Gee.Map<K,V> map);
+ public abstract bool unset (K key, out V value = null);
+ public virtual bool unset_all (Gee.Map<K,V> map);
+ public abstract Gee.Set<Gee.Map.Entry<K,V>> entries { owned get; }
+ public virtual bool is_empty { get; }
+ public abstract Gee.Set<K> keys { owned get; }
+ public virtual Gee.Map<K,V> read_only_view { owned get; }
+ public abstract int size { get; }
+ public abstract Gee.Collection<V> values { owned get; }
+ }
+ [CCode (cheader_filename = "gee.h")]
+ public abstract class AbstractMultiMap<K,V> : GLib.Object, Gee.MultiMap<K,V> {
+ protected Gee.Map<K,Gee.Collection<V>> _storage_map;
+ public AbstractMultiMap (Gee.Map<K,Gee.Collection<V>> storage_map);
+ protected abstract Gee.MultiSet<K> create_multi_key_set ();
+ protected abstract Gee.Collection<V> create_value_storage ();
+ protected abstract GLib.EqualFunc get_value_equal_func ();
+ }
+ [CCode (cheader_filename = "gee.h")]
+ public abstract class AbstractMultiSet<G> : Gee.AbstractCollection<G>, Gee.MultiSet<G> {
+ protected Gee.Map<G,int> _storage_map;
+ public AbstractMultiSet (Gee.Map<G,int> storage_map);
+ public override bool add (G item);
+ public override void clear ();
+ public override bool contains (G item);
+ public override Gee.Iterator<G> iterator ();
+ public override bool remove (G item);
+ public override int size { get; }
+ }
+ [CCode (cheader_filename = "gee.h")]
+ public abstract class AbstractQueue<G> : Gee.AbstractCollection<G>, Gee.Queue<G> {
+ public AbstractQueue ();
+ public abstract int drain (Gee.Collection<G> recipient, int amount = -1);
+ public abstract bool offer (G element);
+ public abstract G peek ();
+ public abstract G poll ();
+ public abstract int capacity { get; }
+ public abstract bool is_full { get; }
+ public abstract int remaining_capacity { get; }
+ }
+ [CCode (cheader_filename = "gee.h")]
+ public abstract class AbstractSet<G> : Gee.AbstractCollection<G>, Gee.Set<G> {
+ public AbstractSet ();
+ public virtual Gee.Set<G> read_only_view { owned get; }
+ }
+ [CCode (cheader_filename = "gee.h")]
+ public class ArrayList<G> : Gee.AbstractList<G> {
+ public ArrayList (GLib.EqualFunc? equal_func = null);
+ public override bool add (G item);
+ public override bool add_all (Gee.Collection<G> collection);
+ public override void clear ();
+ public override bool contains (G item);
+ public override G @get (int index);
+ public override int index_of (G item);
+ public override void insert (int index, G item);
+ public override Gee.Iterator<G> iterator ();
+ public override Gee.ListIterator<G> list_iterator ();
+ public override bool remove (G item);
+ public override G remove_at (int index);
+ public override void @set (int index, G item);
+ public override Gee.List<G>? slice (int start, int stop);
+ public void sort_with_data (GLib.CompareDataFunc compare);
+ public GLib.EqualFunc equal_func { get; private set; }
+ public override int size { get; }
+ }
+ [CCode (cheader_filename = "gee.h")]
+ public class HashMap<K,V> : Gee.AbstractMap<K,V> {
+ public HashMap (GLib.HashFunc? key_hash_func = null, GLib.EqualFunc? key_equal_func = null, GLib.EqualFunc? value_equal_func = null);
+ public override void clear ();
+ public override V @get (K key);
+ public override bool has (K key, V value);
+ public override bool has_key (K key);
+ public override Gee.MapIterator<K,V> map_iterator ();
+ public override void @set (K key, V value);
+ public override bool unset (K key, out V value = null);
+ public override Gee.Set<Gee.Map.Entry<K,V>> entries { owned get; }
+ public GLib.EqualFunc key_equal_func { get; private set; }
+ public GLib.HashFunc key_hash_func { get; private set; }
+ public override Gee.Set<K> keys { owned get; }
+ public override int size { get; }
+ public GLib.EqualFunc value_equal_func { get; private set; }
+ public override Gee.Collection<V> values { owned get; }
+ }
+ [CCode (cheader_filename = "gee.h")]
+ public class HashMultiMap<K,V> : Gee.AbstractMultiMap<K,V> {
+ public HashMultiMap (GLib.HashFunc? key_hash_func = null, GLib.EqualFunc? key_equal_func = null, GLib.HashFunc? value_hash_func = null, GLib.EqualFunc? value_equal_func = null);
+ protected override Gee.MultiSet<K> create_multi_key_set ();
+ protected override Gee.Collection<V> create_value_storage ();
+ protected override GLib.EqualFunc get_value_equal_func ();
+ public GLib.EqualFunc key_equal_func { get; }
+ public GLib.HashFunc key_hash_func { get; }
+ public GLib.EqualFunc value_equal_func { get; private set; }
+ public GLib.HashFunc value_hash_func { get; private set; }
+ }
+ [CCode (cheader_filename = "gee.h")]
+ public class HashMultiSet<G> : Gee.AbstractMultiSet<G> {
+ public HashMultiSet (GLib.HashFunc? hash_func = null, GLib.EqualFunc? equal_func = null);
+ public GLib.EqualFunc equal_func { get; }
+ public GLib.HashFunc hash_func { get; }
+ }
+ [CCode (cheader_filename = "gee.h")]
+ public class HashSet<G> : Gee.AbstractSet<G> {
+ public HashSet (GLib.HashFunc? hash_func = null, GLib.EqualFunc? equal_func = null);
+ public override bool add (G key);
+ public override void clear ();
+ public override bool contains (G key);
+ public override Gee.Iterator<G> iterator ();
+ public override bool remove (G key);
+ public GLib.EqualFunc equal_func { get; private set; }
+ public GLib.HashFunc hash_func { get; private set; }
+ public override int size { get; }
+ }
+ [CCode (cheader_filename = "gee.h")]
+ public class LinkedList<G> : Gee.AbstractList<G>, Gee.Queue<G>, Gee.Deque<G> {
+ public LinkedList (GLib.EqualFunc? equal_func = null);
+ public override bool add (G item);
+ public override void clear ();
+ public override bool contains (G item);
+ public override G first ();
+ public override G @get (int index);
+ public override int index_of (G item);
+ public override void insert (int index, G item);
+ public override Gee.Iterator<G> iterator ();
+ public override G last ();
+ public override Gee.ListIterator<G> list_iterator ();
+ public override bool remove (G item);
+ public override G remove_at (int index);
+ public override void @set (int index, G item);
+ public override Gee.List<G>? slice (int start, int stop);
+ public GLib.EqualFunc equal_func { get; private set; }
+ public override int size { get; }
+ }
+ [CCode (cheader_filename = "gee.h")]
+ public class PriorityQueue<G> : Gee.AbstractQueue<G> {
+ public PriorityQueue (GLib.CompareFunc? compare_func = null);
+ public override bool add (G item);
+ public override void clear ();
+ public override bool contains (G item);
+ public override int drain (Gee.Collection<G> recipient, int amount = -1);
+ public override Gee.Iterator<G> iterator ();
+ public override bool offer (G element);
+ public override G peek ();
+ public override G poll ();
+ public override bool remove (G item);
+ public override int capacity { get; }
+ public GLib.CompareFunc compare_func { get; private set; }
+ public override bool is_full { get; }
+ public override int remaining_capacity { get; }
+ public override int size { get; }
+ }
+ [CCode (cheader_filename = "gee.h")]
+ public class TreeMap<K,V> : Gee.AbstractMap<K,V> {
+ public TreeMap (GLib.CompareFunc? key_compare_func = null, GLib.EqualFunc? value_equal_func = null);
+ public override void clear ();
+ public override V @get (K key);
+ public override bool has (K key, V value);
+ public override bool has_key (K key);
+ public override Gee.MapIterator<K,V> map_iterator ();
+ public override void @set (K key, V value);
+ public override bool unset (K key, out V value = null);
+ public override Gee.Set<Gee.Map.Entry<K,V>> entries { owned get; }
+ public GLib.CompareFunc key_compare_func { get; private set; }
+ public override Gee.Set<K> keys { owned get; }
+ public override int size { get; }
+ public GLib.EqualFunc value_equal_func { get; private set; }
+ public override Gee.Collection<V> values { owned get; }
+ }
+ [CCode (cheader_filename = "gee.h")]
+ public class TreeMultiMap<K,V> : Gee.AbstractMultiMap<K,V> {
+ public TreeMultiMap (GLib.CompareFunc? key_compare_func = null, GLib.CompareFunc? value_compare_func = null);
+ protected override Gee.MultiSet<K> create_multi_key_set ();
+ protected override Gee.Collection<V> create_value_storage ();
+ protected override GLib.EqualFunc get_value_equal_func ();
+ public GLib.CompareFunc key_compare_func { get; }
+ public GLib.CompareFunc value_compare_func { get; private set; }
+ }
+ [CCode (cheader_filename = "gee.h")]
+ public class TreeMultiSet<G> : Gee.AbstractMultiSet<G> {
+ public TreeMultiSet (GLib.CompareFunc? compare_func = null);
+ public GLib.CompareFunc compare_func { get; }
+ }
+ [CCode (cheader_filename = "gee.h")]
+ public class TreeSet<G> : Gee.AbstractSet<G>, Gee.SortedSet<G> {
+ public TreeSet (GLib.CompareFunc? compare_func = null);
+ public override bool add (G item);
+ public override void clear ();
+ public override bool contains (G item);
+ public override Gee.Iterator<G> iterator ();
+ public override bool remove (G item);
+ public GLib.CompareFunc compare_func { get; private set; }
+ public override int size { get; }
+ }
+ [CCode (cheader_filename = "gee.h")]
+ public interface BidirIterator<G> : Gee.Iterator<G> {
+ public abstract bool has_previous ();
+ public abstract bool last ();
+ public abstract bool previous ();
+ }
+ [CCode (cheader_filename = "gee.h")]
+ public interface Collection<G> : Gee.Iterable<G> {
+ public abstract bool add (G item);
+ public abstract bool add_all (Gee.Collection<G> collection);
+ public abstract void clear ();
+ public abstract bool contains (G item);
+ public abstract bool contains_all (Gee.Collection<G> collection);
+ public static Gee.Collection<G> empty<G> ();
+ public abstract bool remove (G item);
+ public abstract bool remove_all (Gee.Collection<G> collection);
+ public abstract bool retain_all (Gee.Collection<G> collection);
+ public abstract G[] to_array ();
+ public abstract bool is_empty { get; }
+ public abstract Gee.Collection<G> read_only_view { owned get; }
+ public abstract int size { get; }
+ }
+ [CCode (cheader_filename = "gee.h")]
+ public interface Comparable<G> : GLib.Object {
+ public abstract int compare_to (G object);
+ }
+ [CCode (cheader_filename = "gee.h")]
+ public interface Deque<G> : Gee.Queue<G> {
+ public abstract int drain_head (Gee.Collection<G> recipient, int amount = -1);
+ public abstract int drain_tail (Gee.Collection<G> recipient, int amount = -1);
+ public abstract bool offer_head (G element);
+ public abstract bool offer_tail (G element);
+ public abstract G peek_head ();
+ public abstract G peek_tail ();
+ public abstract G poll_head ();
+ public abstract G poll_tail ();
+ }
+ [CCode (cheader_filename = "gee.h")]
+ public interface Iterable<G> : GLib.Object {
+ public abstract Gee.Iterator<G> iterator ();
+ public abstract GLib.Type element_type { get; }
+ }
+ [CCode (cheader_filename = "gee.h")]
+ public interface Iterator<G> : GLib.Object {
+ public abstract bool first ();
+ public abstract G @get ();
+ public abstract bool has_next ();
+ public abstract bool next ();
+ public abstract void remove ();
+ }
+ [CCode (cheader_filename = "gee.h")]
+ public interface List<G> : Gee.Collection<G> {
+ public static Gee.List<G> empty<G> ();
+ public abstract G first ();
+ public abstract G @get (int index);
+ public abstract int index_of (G item);
+ public abstract void insert (int index, G item);
+ public abstract void insert_all (int index, Gee.Collection<G> collection);
+ public abstract G last ();
+ public abstract new Gee.ListIterator<G> list_iterator ();
+ public abstract G remove_at (int index);
+ public abstract void @set (int index, G item);
+ public abstract Gee.List<G>? slice (int start, int stop);
+ public abstract void sort (GLib.CompareFunc? compare_func = null);
+ public abstract Gee.List<G> read_only_view { owned get; }
+ }
+ [CCode (cheader_filename = "gee.h")]
+ public interface ListIterator<G> : Gee.BidirIterator<G> {
+ public abstract void add (G item);
+ public abstract int index ();
+ public abstract void insert (G item);
+ public abstract void @set (G item);
+ }
+ [CCode (cheader_filename = "gee.h")]
+ public interface Map<K,V> : GLib.Object, Gee.Iterable<Gee.Map.Entry<K,V>> {
+ [CCode (cheader_filename = "gee.h")]
+ public abstract class Entry<K,V> : GLib.Object {
+ public Entry ();
+ public abstract K key { get; }
+ public abstract V value { get; set; }
+ }
+ public abstract void clear ();
+ [Deprecated]
+ public abstract bool contains (K key);
+ [Deprecated]
+ public abstract bool contains_all (Gee.Map<K,V> map);
+ public static Gee.Map<K,V> empty<K,V> ();
+ public abstract V @get (K key);
+ public abstract bool has (K key, V value);
+ public abstract bool has_all (Gee.Map<K,V> map);
+ public abstract bool has_key (K key);
+ public abstract Gee.MapIterator<K,V> map_iterator ();
+ [Deprecated]
+ public abstract bool remove (K key, out V value = null);
+ [Deprecated]
+ public abstract bool remove_all (Gee.Map<K,V> map);
+ public abstract void @set (K key, V value);
+ public abstract void set_all (Gee.Map<K,V> map);
+ public abstract bool unset (K key, out V value = null);
+ public abstract bool unset_all (Gee.Map<K,V> map);
+ public abstract Gee.Set<Gee.Map.Entry<K,V>> entries { owned get; }
+ public abstract bool is_empty { get; }
+ public abstract GLib.Type key_type { get; }
+ public abstract Gee.Set<K> keys { owned get; }
+ public abstract Gee.Map<K,V> read_only_view { owned get; }
+ public abstract int size { get; }
+ public abstract GLib.Type value_type { get; }
+ public abstract Gee.Collection<V> values { owned get; }
+ }
+ [CCode (cheader_filename = "gee.h")]
+ public interface MapIterator<K,V> : GLib.Object {
+ public abstract bool first ();
+ public abstract K get_key ();
+ public abstract V get_value ();
+ public abstract bool has_next ();
+ public abstract bool next ();
+ public abstract void set_value (V value);
+ public abstract void unset ();
+ }
+ [CCode (cheader_filename = "gee.h")]
+ public interface MultiMap<K,V> : GLib.Object {
+ public abstract void clear ();
+ public abstract bool contains (K key);
+ public abstract Gee.Collection<V> @get (K key);
+ public abstract Gee.MultiSet<K> get_all_keys ();
+ public abstract Gee.Set<K> get_keys ();
+ public abstract Gee.Collection<V> get_values ();
+ public abstract bool remove (K key, V value);
+ public abstract bool remove_all (K key);
+ public abstract void @set (K key, V value);
+ public abstract int size { get; }
+ }
+ [CCode (cheader_filename = "gee.h")]
+ public interface MultiSet<G> : Gee.Collection<G> {
+ public abstract int count (G item);
+ }
+ [CCode (cheader_filename = "gee.h")]
+ public interface Queue<G> : Gee.Collection<G> {
+ public const int UNBOUNDED_CAPACITY;
+ public abstract int drain (Gee.Collection<G> recipient, int amount = -1);
+ public abstract bool offer (G element);
+ public abstract G peek ();
+ public abstract G poll ();
+ public abstract int capacity { get; }
+ public abstract bool is_full { get; }
+ public abstract int remaining_capacity { get; }
+ }
+ [CCode (cheader_filename = "gee.h")]
+ public interface Set<G> : Gee.Collection<G> {
+ public static Gee.Set<G> empty<G> ();
+ public abstract Gee.Set<G> read_only_view { owned get; }
+ }
+ [CCode (cheader_filename = "gee.h")]
+ public interface SortedSet<G> : Gee.Set<G> {
+ public abstract Gee.BidirIterator<G> bidir_iterator ();
+ public abstract G ceil (G element);
+ public abstract G first ();
+ public abstract G floor (G element);
+ public abstract Gee.SortedSet<G> head_set (G before);
+ public abstract G higher (G element);
+ public abstract Gee.BidirIterator<G>? iterator_at (G element);
+ public abstract G last ();
+ public abstract G lower (G element);
+ public abstract Gee.SortedSet<G> sub_set (G from, G to);
+ public abstract Gee.SortedSet<G> tail_set (G after);
+ }
+ [CCode (cheader_filename = "gee.h")]
+ public static int direct_compare (void* _val1, void* _val2);
+}
diff --git a/vapi/libgnome-menu-3.0.vapi b/vapi/libgnome-menu-3.0.vapi
new file mode 100644
index 0000000..0afbea0
--- /dev/null
+++ b/vapi/libgnome-menu-3.0.vapi
@@ -0,0 +1,93 @@
+/* libgnome-menu-3.0.vapi generated by vapigen, do not modify. */
+
+namespace GMenu {
+ [CCode (cheader_filename = "gnome-menus-3.0/gmenu-tree.h")]
+ public class Tree : GLib.Object {
+ [CCode (has_construct_function = false)]
+ public Tree (string menu_basename, GMenu.TreeFlags flags);
+ [CCode (has_construct_function = false)]
+ public Tree.for_path (string menu_path, GMenu.TreeFlags flags);
+ public unowned string get_canonical_menu_path ();
+ public unowned GMenu.TreeDirectory get_directory_from_path (string path);
+ public unowned GMenu.TreeEntry get_entry_by_id (string id);
+ public unowned GMenu.TreeDirectory get_root_directory ();
+ public static void* item_ref (void* item);
+ public static void item_unref (void* item);
+ public bool load_sync () throws GLib.Error;
+ [NoAccessorMethod]
+ public GMenu.TreeFlags flags { get; construct; }
+ [NoAccessorMethod]
+ public string menu_basename { owned get; construct; }
+ [NoAccessorMethod]
+ public string menu_path { owned get; construct; }
+ public virtual signal void changed ();
+ }
+ [CCode (cheader_filename = "gnome-menus-3.0/gmenu-tree.h")]
+ [Compact]
+ public class TreeAlias {
+ public unowned GMenu.TreeDirectory get_aliased_directory ();
+ public unowned GMenu.TreeEntry get_aliased_entry ();
+ public GMenu.TreeItemType get_aliased_item_type ();
+ public unowned GMenu.TreeDirectory get_directory ();
+ }
+ [CCode (cheader_filename = "gnome-menus-3.0/gmenu-tree.h")]
+ [Compact]
+ public class TreeDirectory {
+ public unowned string get_comment ();
+ public unowned string get_desktop_file_path ();
+ public unowned string get_generic_name ();
+ public unowned GLib.Icon get_icon ();
+ public bool get_is_nodisplay ();
+ public unowned string get_menu_id ();
+ public unowned string get_name ();
+ public unowned GMenu.TreeDirectory get_parent ();
+ public unowned GMenu.TreeIter iter ();
+ public unowned string make_path (GMenu.TreeEntry entry);
+ }
+ [CCode (cheader_filename = "gnome-menus-3.0/gmenu-tree.h")]
+ [Compact]
+ public class TreeEntry {
+ public unowned GLib.DesktopAppInfo get_app_info ();
+ public unowned string get_desktop_file_id ();
+ public unowned string get_desktop_file_path ();
+ public bool get_is_excluded ();
+ public unowned GMenu.TreeDirectory get_parent ();
+ }
+ [CCode (cheader_filename = "gnome-menus-3.0/gmenu-tree.h")]
+ [Compact]
+ public class TreeHeader {
+ public unowned GMenu.TreeDirectory get_directory ();
+ }
+ [CCode (cheader_filename = "gnome-menus-3.0/gmenu-tree.h", ref_function = "gmenu_tree_iter_ref", unref_function = "gmenu_tree_iter_unref")]
+ [Compact]
+ public class TreeIter {
+ public unowned GMenu.TreeAlias get_alias ();
+ public unowned GMenu.TreeDirectory get_directory ();
+ public unowned GMenu.TreeEntry get_entry ();
+ public unowned GMenu.TreeHeader get_header ();
+ public GMenu.TreeItemType next ();
+ }
+ [CCode (cheader_filename = "gnome-menus-3.0/gmenu-tree.h")]
+ [Compact]
+ public class TreeSeparator {
+ }
+ [CCode (cheader_filename = "gnome-menus-3.0/gmenu-tree.h", cprefix = "GMENU_TREE_FLAGS_")]
+ [Flags]
+ public enum TreeFlags {
+ NONE,
+ INCLUDE_EXCLUDED,
+ SHOW_EMPTY,
+ INCLUDE_NODISPLAY,
+ SHOW_ALL_SEPARATORS,
+ SORT_DISPLAY_NAME
+ }
+ [CCode (cheader_filename = "gnome-menus-3.0/gmenu-tree.h", cprefix = "GMENU_TREE_ITEM_", has_type_id = false)]
+ public enum TreeItemType {
+ INVALID,
+ DIRECTORY,
+ ENTRY,
+ SEPARATOR,
+ HEADER,
+ ALIAS
+ }
+}
diff --git a/vapi/x11.vapi b/vapi/x11.vapi
new file mode 100644
index 0000000..cf80228
--- /dev/null
+++ b/vapi/x11.vapi
@@ -0,0 +1,996 @@
+/* x11.vapi
+ *
+ * Copyright (C) 2009 Jürg Billeter
+ * Copyright (C) 2011 Alexander Kurtz
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Authors:
+ * Jürg Billeter <j@bitron.ch>
+ * Alexander Kurtz <kurtz.alex@googlemail.com>
+ */
+
+[CCode (cprefix = "", lower_case_cprefix = "", cheader_filename = "X11/Xlib.h,X11/Xatom.h,X11/Xutil.h,X11/Xregion.h")]
+namespace X {
+ // Note: must be called before opening a display or calling any other Xlib function,
+ // see http://tronche.com/gui/x/xlib/display/XInitThreads.html
+ [CCode (cname = "XInitThreads")]
+ public Status init_threads ();
+
+ [Compact]
+ [CCode (cname = "Display", ref_function = "", unref_function = "")]
+ public class Display {
+ [CCode (cname = "XOpenDisplay")]
+ public Display (string? name = null);
+
+ [CCode (cname = "XAllPlanes")]
+ public static ulong get_all_planes ();
+
+ [CCode (cname = "XActivateScreenSaver")]
+ public void activate_screensaver ();
+
+ [CCode (cname = "XAddToSaveSet")]
+ public int add_to_save_set (Window w);
+
+ [CCode (cname = "XAllowEvents")]
+ public int allow_events (int event_mode, int time);
+
+ [CCode (cname = "XBitmapBitOrder")]
+ public int bitmap_bit_order ();
+
+ [CCode (cname = "XBitmapUnit")]
+ public int bitmap_scanline_unit ();
+
+ [CCode (cname = "XBitmapPad")]
+ public int bitmap_scanline_padding ();
+
+ [CCode (cname = "XChangeProperty")]
+ public int change_property (Window w, Atom property, Atom type, int format, int mode, [CCode (array_length = false)] uchar[] data, int nelements);
+
+ [CCode (cname = "XChangeWindowAttributes")]
+ public int change_window_attributes (Window w, ulong valuemask, SetWindowAttributes attributes);
+
+ [CCode (cname = "XConfigureWindow")]
+ public int configure_window (Window w, uint value_mask, WindowChanges values);
+
+ [CCode (cname = "ConnectionNumber")]
+ public int connection_number ();
+
+ [CCode (cname = "DefaultRootWindow")]
+ public Window default_root_window ();
+
+ [CCode (cname = "XDefaultScreenOfDisplay")]
+ public unowned Screen default_screen ();
+
+ [CCode (cname = "XScreenOfDisplay")]
+ public unowned Screen screen_by_id (int screen_number);
+
+ [CCode (cname = "DisplayString")]
+ public string display_string ();
+
+ [CCode (cname = "XQLength")]
+ public int event_queue_length ();
+
+ [CCode (cname = "XFlush")]
+ public int flush ();
+
+ [CCode (cname = "XForceScreenSaver")]
+ public void force_screensaver (int mode);
+
+ [CCode (cname = "XGetKeyboardMapping", array_length = false)]
+ public unowned uint[] get_keyboard_mapping (uint first_keycode, int keycode_count, ref int keysyms_per_keycode_return);
+
+ [CCode (cname = "XGetModifierMapping")]
+ public ModifierKeymap get_modifier_mapping ();
+
+ [CCode (cname = "XGetScreenSaver")]
+ public void get_screensaver (out int timeout, out int interval, out int prefer_blanking, out int allow_exposures);
+
+ [CCode (cname = "XGetSelectionOwner")]
+ public Window get_selection_owner (Atom selection);
+
+ [CCode (cname = "XGetWindowAttributes")]
+ public void get_window_attributes (Window w, out WindowAttributes window_attributes_return);
+
+ [CCode (cname = "XGetWindowProperty")]
+ public int get_window_property (Window w, Atom property, long long_offset, long long_length, bool delete, Atom req_type, out Atom actual_type_return, out int actual_format_return, out ulong nitems_return, out ulong bytes_after_return, [CCode (type = "unsigned char **")] out void* prop_return);
+
+ [CCode (cname = "XGrabButton")]
+ public int grab_button (uint button, uint modifiers, Window grab_window, bool owner_events, uint event_mask, int pointer_mode, int keyboard_mode, Window confine_to, uint cursor);
+
+ [CCode (cname = "XGrabKey")]
+ public int grab_key (int keycode, uint modifiers, Window grab_window, bool owner_events, int pointer_mode, int keyboard_mode);
+
+ [CCode (cname = "XGrabPointer")]
+ public int grab_pointer (Window grab_window, bool owner_events, uint event_mask, int pointer_mode, int keyboard_mode, Window confine_to, uint cursor, int time);
+
+ [CCode (cname = "XGrabServer")]
+ public int grab_server ();
+
+ [CCode (cname = "XImageByteOrder")]
+ public int image_byte_order ();
+
+ [CCode (cname = "XInternAtom")]
+ public Atom intern_atom (string atom_name, bool only_if_exists);
+
+ [CCode (cname = "XInternAtoms")]
+ public void intern_atoms (string[] names, bool only_if_exists, [CCode (array_length = false)] Atom[] atoms_return);
+
+ [CCode (cname = "XInternalConnectionNumbers")]
+ public Status internal_connection_numbers (ref int[] fd_return);
+
+ [CCode (cname = "XDisplayKeycodes")]
+ public int keycodes (ref int min_keycodes_return, ref int max_keycodes_return);
+
+ [CCode (cname = "XKeysymToKeycode")]
+ public int keysym_to_keycode (uint keysym);
+
+ [CCode (cname = "XLastKnownRequestProcessed")]
+ public ulong last_known_request_processed ();
+
+ [CCode (cname = "XLockDisplay")]
+ public void lock_display ();
+
+ [CCode (cname = "XMapWindow")]
+ public int map_window (Window w);
+
+ [CCode (cname = "XMaxRequestSize")]
+ public long max_request_size ();
+
+ [CCode (cname = "XExtendedMaxRequestSize")]
+ public long max_extended_request_size ();
+
+ [CCode (cname = "XEventsQueued")]
+ public int events_queued (int mode);
+
+ [CCode (cname = "XNextEvent")]
+ public int next_event (ref Event event_return);
+
+ [CCode (cname = "XNextRequest")]
+ public ulong next_request ();
+
+ [CCode (cname = "XNoOp")]
+ public void no_operation ();
+
+ [CCode (cname = "XScreenCount")]
+ public int number_of_screens ();
+
+ [CCode (cname = "XPending")]
+ public int pending ();
+
+ [CCode (cname = "XProcessInternalConnection")]
+ public void process_internal_connection (int fd);
+
+ [CCode (cname = "XProtocolVersion")]
+ public int protocol_version ();
+
+ [CCode (cname = "XProtocolRevision")]
+ public int protocol_revision ();
+
+ [CCode (cname = "XRaiseWindow")]
+ public int raise_window (Window w);
+
+ [CCode (cname = "XReparentWindow")]
+ public int reparent_window (Window w, Window parent, int x, int y);
+
+ [CCode (cname = "XResetScreenSaver")]
+ public void reset_screensaver ();
+
+ [CCode (cname = "XResizeWindow")]
+ public int resize_window (Window w, uint width, uint height);
+
+ [CCode (cname = "XRootWindow")]
+ public Window root_window (int screen_number);
+
+ [CCode (cname = "ScreenCount")]
+ public int screen_count ();
+
+ [CCode (cname = "XScreenOfDisplay")]
+ public unowned Screen screen_of_display (int screen_number);
+
+ [CCode (cname = "XSelectInput")]
+ public int select_input (Window w, long event_mask);
+
+ [CCode (cname = "XSendEvent")]
+ public void send_event (Window w, bool propagate, long event_mask, ref Event event_send);
+
+ [CCode (cname = "XSetCloseDownMode")]
+ public void set_close_down_mode (int close_mode);
+
+ [CCode (cname = "XSetScreenSaver")]
+ public void set_screensaver (int timeout, int interval, int prefer_blanking, int allow_exposures);
+
+ [CCode (cname = "XSetSelectionOwner")]
+ public Window set_selection_owner (Atom selection, Window owner, int time);
+
+ [CCode (cname = "XSetInputFocus")]
+ public int set_input_focus (Window focus, int revert_to, int time);
+
+ [CCode (cname = "XUngrabButton")]
+ public int ungrab_button (uint button, uint modifiers, Window grab_window);
+
+ [CCode (cname = "XUngrabKey")]
+ public int ungrab_key (int keycode, uint modifiers, Window grab_window);
+
+ [CCode (cname = "XUngrabPointer")]
+ public int ungrab_pointer (int time);
+
+ [CCode (cname = "XUngrabServer")]
+ public int ungrab_server ();
+
+ [CCode (cname = "XUnlockDisplay")]
+ public void unlock_display ();
+
+ [CCode (cname = "XUnmapWindow")]
+ public int unmap_window (Window w);
+
+ [CCode (cname = "XQueryTree")]
+ public void query_tree (Window w, out Window root_return, out Window parent_return, out Window[] children_return);
+
+ [CCode (cname = "XWindowEvent")]
+ public int window_event (Window w, EventMask event_mask, out Event event_return);
+
+ [CCode (cname = "XServerVendor")]
+ public string xserver_vendor_name ();
+
+ [CCode (cname = "XVendorRelease")]
+ public string xserver_vendor_release ();
+
+ [CCode (cname = "XMoveWindow")]
+ public void move_window (Window window, int x, int y);
+ }
+
+ [Compact]
+ [CCode (cname = "XModifierKeymap", free_function = "XFreeModifiermap")]
+ public class ModifierKeymap {
+ // The server's max # of keys per modifier
+ public int max_keypermod;
+ // An 8 by max_keypermod array of modifiers
+ public uchar[] modifiermap;
+ }
+
+ [SimpleType]
+ [IntegerType (rank = 9)]
+ [CCode (cname = "Atom")]
+ public struct Atom {
+ }
+
+ [SimpleType]
+ [IntegerType (rank = 9)]
+ [CCode (cname = "Colormap")]
+ public struct Colormap {
+ }
+
+ [SimpleType]
+ [CCode (cname = "GC")]
+ public struct GC {
+ }
+
+ [SimpleType]
+ [IntegerType (rank = 9)]
+ [CCode (cname = "Status")]
+ public struct Status {
+ }
+
+ [SimpleType]
+ [IntegerType (rank = 9)]
+ [CCode (cname = "XID", type_id = "G_TYPE_INT",
+ marshaller_type_name = "INT",
+ get_value_function = "g_value_get_int",
+ set_value_function = "g_value_set_int", default_value = "0",
+ type_signature = "i")]
+ public struct ID {
+ }
+
+ [SimpleType]
+ [IntegerType (rank = 9)]
+ [CCode (cname = "Drawable", type_id = "G_TYPE_INT",
+ marshaller_type_name = "INT",
+ get_value_function = "g_value_get_int",
+ set_value_function = "g_value_set_int", default_value = "0",
+ type_signature = "i")]
+ public struct Drawable : ID
+ {
+ }
+
+ [SimpleType]
+ [IntegerType (rank = 9)]
+ [CCode (cname = "Window", type_id = "G_TYPE_INT",
+ marshaller_type_name = "INT",
+ get_value_function = "g_value_get_int",
+ set_value_function = "g_value_set_int", default_value = "0",
+ type_signature = "i")]
+ public struct Window : Drawable {
+ }
+
+
+ [SimpleType]
+ [IntegerType (rank = 9)]
+ [CCode (cname = "Pixmap", type_id = "G_TYPE_INT",
+ marshaller_type_name = "INT",
+ get_value_function = "g_value_get_int",
+ set_value_function = "g_value_set_int", default_value = "0",
+ type_signature = "i")]
+ public struct Pixmap : Drawable {
+ }
+
+ [SimpleType]
+ [IntegerType (rank = 9)]
+ [CCode (cname = "Mask")]
+ public struct Mask {
+ }
+
+ [SimpleType]
+ [IntegerType (rank = 9)]
+ [CCode (cname = "VisualID")]
+ public struct VisualID {
+ }
+
+ [SimpleType]
+ [IntegerType (rank = 9)]
+ [CCode (cname = "Time")]
+ public struct Time {
+ }
+
+ [SimpleType]
+ [IntegerType (rank = 9)]
+ [CCode (cname = "Cursor")]
+ public struct Cursor {
+ }
+
+ [SimpleType]
+ [IntegerType (rank = 9)]
+ [CCode (cname = "GContext")]
+ public struct GContext {
+ }
+
+ [SimpleType]
+ [IntegerType (rank = 9)]
+ [CCode (cname = "KeySym")]
+ public struct KeySym {
+ }
+
+ [SimpleType]
+ [IntegerType (rank = 9)]
+ [CCode (cname = "KeyCode")]
+ public struct KeyCode {
+ }
+
+ public struct Visual {
+ }
+
+ public struct WindowChanges {
+ public int x;
+ public int y;
+ public int width;
+ public int height;
+ public int border_width;
+ public Window sibling;
+ public int stack_mode;
+ }
+ public struct SizeHints {
+ public long @flags;
+ public int x;
+ public int y;
+ public int width;
+ public int height;
+ }
+
+ [CCode (cname = "XCreateWindow")]
+ public Window create_window (Display display, Window parent, int x, int y, uint width, uint height, uint border_width, int depth, uint @class, Visual? visual, X.CW valuemask, ref SetWindowAttributes attributes);
+
+ [CCode (cname = "XSetWindowAttributes")]
+ public struct SetWindowAttributes {
+ // public Pixmap background_pixmap; /* background or None or ParentRelative */
+ public ulong background_pixel; /* background pixel */
+ // public Pixmap border_pixmap; /* border of the window */
+ public ulong border_pixel; /* border pixel value */
+ public int bit_gravity; /* one of bit gravity values */
+ public int win_gravity; /* one of the window gravity values */
+ public int backing_store; /* NotUseful, WhenMapped, Always */
+ public ulong backing_planes;/* planes to be preseved if possible */
+ public ulong backing_pixel;/* value to use in restoring planes */
+ public bool save_under; /* should bits under be saved? (popups) */
+ public long event_mask; /* set of events that should be saved */
+ public long do_not_propagate_mask; /* set of events that should not propagate */
+ public bool override_redirect; /* boolean value for override-redirect */
+ // public Colormap colormap; /* color map to be associated with window */
+ // public Cursor cursor; /* cursor to be displayed (or None) */
+ }
+
+ [CCode(cname = "XWindowAttributes",
+ cheader_filename = "X11/Xlib.h,X11/Xatom.h,X11/Xutil.h")]
+ public struct WindowAttributes {
+ public int x;
+ public int y; /* location of window */
+ public int width;
+ public int height; /* width and height of window */
+ public int border_width; /* border width of window */
+ public int depth; /* depth of window */
+ public Visual visual; /* the associated visual structure */
+ public Window root; /* root of screen containing window */
+ public int @class; /* InputOutput, InputOnly*/
+ public int bit_gravity; /* one of bit gravity values */
+ public int win_gravity; /* one of the window gravity values */
+ public int backing_store; /* NotUseful, WhenMapped, Always */
+ public ulong backing_planes;/* planes to be preserved if possible */
+ public ulong backing_pixel;/* value to be used when restoring planes */
+ public bool save_under; /* boolean, should bits under be saved? */
+ // public Colormap colormap; /* color map to be associated with window */
+ public bool map_installed; /* boolean, is color map currently installed*/
+ public int map_state; /* IsUnmapped, IsUnviewable, IsViewable */
+ public long all_event_masks; /* set of events all people have interest in*/
+ public long your_event_mask; /* my event mask */
+ public long do_not_propagate_mask; /* set of events that should not propagate */
+ public bool override_redirect; /* boolean value for override-redirect */
+ // public Screen screen; /* back pointer to correct screen */
+ }
+
+ [CCode (cname = "CopyFromParent")]
+ public const int COPY_FROM_PARENT;
+
+ [CCode (cname = "CurrentTime")]
+ public const ulong CURRENT_TIME;
+
+ [CCode (cname = "Success")]
+ public int Success;
+
+ [CCode (cname = "XFree")]
+ public int free (void* data);
+
+ [CCode (cprefix = "CW", cname = "int")]
+ public enum CW {
+ BackPixmap,
+ BackPixel,
+ BackingStore,
+ BackingPlanes,
+ BackingPixel,
+ BitGravity,
+ BorderPixmap,
+ BorderPixel,
+ BorderWidth,
+ Colormap,
+ Cursor,
+ DontPropagate,
+ EventMask,
+ Height,
+ OverrideRedirect,
+ SaveUnder,
+ Sibling,
+ StackMode,
+ X,
+ Y,
+ Width,
+ WinGravity
+ }
+
+ [CCode (cprefix = "GrabMode")]
+ public enum GrabMode {
+ Sync,
+ Async
+ }
+
+ [CCode (cprefix = "")]
+ public enum EventMask {
+ NoEventMask,
+ KeyPressMask,
+ KeyReleaseMask,
+ ButtonPressMask,
+ ButtonReleaseMask,
+ EnterWindowMask,
+ LeaveWindowMask,
+ PointerMotionMask,
+ PointerMotionHintMask,
+ Button1MotionMask,
+ Button2MotionMask,
+ Button3MotionMask,
+ Button4MotionMask,
+ Button5MotionMask,
+ ButtonMotionMask,
+ KeymapStateMask,
+ ExposureMask,
+ VisibilityChangeMask,
+ StructureNotifyMask,
+ ResizeRedirectMask,
+ SubstructureNotifyMask,
+ SubstructureRedirectMask,
+ FocusChangeMask,
+ PropertyChangeMask,
+ ColormapChangeMask,
+ OwnerGrabButtonMask
+ }
+
+ [CCode (cprefix = "")]
+ public enum KeyMask {
+ ShiftMask,
+ LockMask,
+ ControlMask,
+ Mod1Mask,
+ Mod2Mask,
+ Mod3Mask,
+ Mod4Mask,
+ Mod5Mask
+ }
+
+ [CCode (cprefix = "")]
+ public enum EventType {
+ KeyPress,
+ KeyRelease,
+ ButtonPress,
+ ButtonRelease,
+ MotionNotify,
+ EnterNotify,
+ LeaveNotify,
+ FocusIn,
+ FocusOut,
+ KeymapNotify,
+ Expose,
+ GraphicsExpose,
+ NoExpose,
+ VisibilityNotify,
+ CreateNotify,
+ DestroyNotify,
+ UnmapNotify,
+ MapNotify,
+ MapRequest,
+ ReparentNotify,
+ ConfigureNotify,
+ ConfigureRequest,
+ GravityNotify,
+ ResizeRequest,
+ CirculateNotify,
+ CirculateRequest,
+ PropertyNotify,
+ SelectionClear,
+ SelectionRequest,
+ SelectionNotify,
+ ColormapNotify,
+ ClientMessage,
+ MappingNotify
+ }
+
+ // union
+ [CCode (cname = "XEvent")]
+ public struct Event {
+ public int type;
+ public AnyEvent xany;
+ public KeyEvent xkey;
+ public ButtonEvent xbutton;
+ public MotionEvent xmotion;
+ public CrossingEvent xcrossing;
+ public CreateWindowEvent xcreatewindow;
+ public DestroyWindowEvent xdestroywindow;
+ public UnmapEvent xunmap;
+ public MapEvent xmap;
+ public MapRequestEvent xmaprequest;
+ public ReparentEvent xreparent;
+ public ConfigureEvent xconfigure;
+ public GravityEvent xgravity;
+ public ConfigureRequestEvent xconfigurerequest;
+ public CirculateEvent xcirculate;
+ public CirculateRequestEvent xcirculaterequest;
+ public PropertyEvent xproperty;
+ public SelectionEvent xselection;
+ public ClientMessageEvent xclient;
+ }
+
+ [CCode (cname = "XAnyEvent")]
+ public struct AnyEvent {
+ public int type;
+ public ulong serial;
+ public bool send_event;
+ public unowned Display display;
+ public Window window;
+ }
+
+ [CCode (cname = "XKeyEvent")]
+ public struct KeyEvent {
+ public int type;
+ public ulong serial;
+ public bool send_event;
+ public unowned Display display;
+ public Window window;
+ public Window root;
+ public Window subwindow;
+ public ulong time;
+ public int x;
+ public int y;
+ public int x_root;
+ public int y_root;
+ public uint state;
+ public uint keycode;
+ public bool same_screen;
+ }
+
+ [CCode (cname = "XButtonEvent")]
+ public struct ButtonEvent {
+ public int type;
+ public ulong serial;
+ public bool send_event;
+ public unowned Display display;
+ public Window window;
+ public Window subwindow;
+ public ulong time;
+ public int x;
+ public int y;
+ public int x_root;
+ public int y_root;
+ public uint state;
+ public uint button;
+ public bool same_screen;
+ }
+
+ [CCode (cname = "XMotionEvent")]
+ public struct MotionEvent {
+ public int type;
+ public ulong serial;
+ public bool send_event;
+ public unowned Display display;
+ public Window window;
+ public Window subwindow;
+ public ulong time;
+ public int x;
+ public int y;
+ public int x_root;
+ public int y_root;
+ public uint state;
+ public char is_hint;
+ public bool same_screen;
+ }
+
+ [CCode (cname = "XCrossingEvent")]
+ public struct CrossingEvent {
+ public int type;
+ public ulong serial;
+ public bool send_event;
+ public unowned Display display;
+ public Window window;
+ public Window root;
+ public Window subwindow;
+ public ulong time;
+ public int x;
+ public int y;
+ public int x_root;
+ public int y_root;
+ public int mode;
+ public int detail;
+ public bool same_screen;
+ public bool focus;
+ public uint state;
+ }
+
+ [CCode (cname = "XCreateWindowEvent")]
+ public struct CreateWindowEvent {
+ public int type;
+ public ulong serial;
+ public bool send_event;
+ public unowned Display display;
+ public Window parent;
+ public Window window;
+ public int x;
+ public int y;
+ public int width;
+ public int height;
+ public int border_width;
+ public bool override_redirect;
+ }
+
+ [CCode (cname = "XDestroyWindowEvent")]
+ public struct DestroyWindowEvent {
+ public int type;
+ public ulong serial;
+ public bool send_event;
+ public unowned Display display;
+ public Window event;
+ public Window window;
+ }
+
+ [CCode (cname = "XUnmapEvent")]
+ public struct UnmapEvent {
+ public int type;
+ public ulong serial;
+ public bool send_event;
+ public unowned Display display;
+ public Window event;
+ public Window window;
+ public bool from_configure;
+ }
+
+ [CCode (cname = "XMapEvent")]
+ public struct MapEvent {
+ public int type;
+ public ulong serial;
+ public bool send_event;
+ public unowned Display display;
+ public Window event;
+ public Window window;
+ public bool override_redirect;
+ }
+
+ [CCode (cname = "XMapRequestEvent")]
+ public struct MapRequestEvent {
+ public int type;
+ public ulong serial;
+ public bool send_event;
+ public unowned Display display;
+ public Window parent;
+ public Window window;
+ }
+
+ [CCode (cname = "XReparentEvent")]
+ public struct ReparentEvent {
+ public int type;
+ public ulong serial;
+ public bool send_event;
+ public unowned Display display;
+ public Window event;
+ public Window window;
+ public Window parent;
+ public int x;
+ public int y;
+ public bool override_redirect;
+ }
+
+ [CCode (cname = "XConfigureEvent")]
+ public struct ConfigureEvent {
+ public int type;
+ public ulong serial;
+ public bool send_event;
+ public unowned Display display;
+ public Window event;
+ public Window window;
+ public int x;
+ public int y;
+ public int width;
+ public int height;
+ public int border_width;
+ public Window above;
+ public bool override_redirect;
+ }
+
+ [CCode (cname = "XGravityEvent")]
+ public struct GravityEvent {
+ public int type;
+ public ulong serial;
+ public bool send_event;
+ public unowned Display display;
+ public Window event;
+ public Window window;
+ public int x;
+ public int y;
+ }
+
+ [CCode (cname = "XConfigureRequestEvent")]
+ public struct ConfigureRequestEvent {
+ public int type;
+ public ulong serial;
+ public bool send_event;
+ public unowned Display display;
+ public Window parent;
+ public Window window;
+ public int x;
+ public int y;
+ public int width;
+ public int height;
+ public int border_width;
+ public Window above;
+ public int detail;
+ public ulong value_mask;
+ }
+
+ [CCode (cname = "XCirculateEvent")]
+ public struct CirculateEvent {
+ public int type;
+ public ulong serial;
+ public bool send_event;
+ public unowned Display display;
+ public Window event;
+ public Window window;
+ public int place;
+ }
+
+ [CCode (cname = "XCirculateRequestEvent")]
+ public struct CirculateRequestEvent {
+ public int type;
+ public ulong serial;
+ public bool send_event;
+ public unowned Display display;
+ public Window parent;
+ public Window window;
+ public int place;
+ }
+
+ [CCode (cname = "XPropertyEvent")]
+ public struct PropertyEvent {
+ public int type;
+ public ulong serial;
+ public bool send_event;
+ public unowned Display display;
+ public Window window;
+ public Atom atom;
+ public ulong time;
+ public int state;
+ }
+
+ [CCode (cname = "XSelectionEvent")]
+ public struct SelectionEvent {
+ public int type;
+ public ulong serial;
+ public bool send_event;
+ public unowned Display display;
+ public Window requestor;
+ public Atom selection;
+ public Atom target;
+ public Atom property;
+ public ulong time;
+ }
+
+ [CCode (cname = "XClientMessageEvent")]
+ public struct ClientMessageEvent {
+ public int type;
+ public ulong serial; /* # of last request processed by server */
+ public bool send_event; /* true if this came from a SendEvent request */
+ public unowned Display display; /* Display the event was read from */
+ public Window window;
+ public Atom message_type;
+ public int format;
+ public ClientMessageEventData data;
+ }
+
+ [CCode (cname = "RECTANGLE", has_type_id = false)]
+ public struct Rectangle {
+ public short x;
+ public short y;
+ public short width;
+ public short height;
+ }
+
+ // union
+ public struct ClientMessageEventData {
+ public unowned char[] b;
+ public unowned short[] s;
+ public unowned long[] l;
+ }
+
+ [CCode (cprefix = "Queued")]
+ public enum QueuedMode {
+ Already,
+ AfterFlush,
+ AfterReading
+ }
+
+ [CCode (cprefix = "PropMode")]
+ public enum PropMode {
+ Replace,
+ Prepend,
+ Append
+ }
+
+ [CCode (cprefix = "")]
+ public enum AllowEventsMode {
+ AsyncPointer,
+ SyncPointer,
+ ReplayPointer,
+ AsyncKeyboard,
+ SyncKeyboard,
+ ReplayKeyboard,
+ AsyncBoth,
+ SyncBoth
+ }
+
+ [CCode (cprefix = "")]
+ public enum MapState {
+ IsUnmapped,
+ IsUnviewable,
+ IsViewable
+ }
+
+ [CCode (cprefix = "RevertTo")]
+ public enum RevertTo {
+ None,
+ PointerRoot,
+ Parent
+ }
+
+ [Compact]
+ [CCode (cname = "Screen")]
+ public class Screen {
+ public Display display;
+ public Window root;
+ public int width;
+ public int height;
+
+ [CCode (cname = "XScreenOfDisplay")]
+ public static unowned Screen get_screen (Display disp, int screen_number);
+
+ [CCode (cname = "XBlackPixelOfScreen")]
+ public ulong black_pixel_of_screen ();
+
+ [CCode (cname = "XCellsOfScreen")]
+ public int cells_of_screen ();
+
+ [CCode (cname = "XDefaultColormapOfScreen")]
+ public Colormap default_colormap_of_screen ();
+
+ [CCode (cname = "XDefaultDepthOfScreen")]
+ public int default_depth_of_screen ();
+
+ [CCode (cname = "XDefaultGCOfScreen")]
+ public GC default_gc_of_screen ();
+
+ [CCode (cname = "XDefaultVisualOfScreen")]
+ public Visual default_visual_of_screen ();
+
+ [CCode (cname = "XDisplayOfScreen")]
+ public unowned Display display_of_screen ();
+
+ [CCode (cname = "XDoesBackingStore")]
+ public int does_backing_store ();
+
+ [CCode (cname = "XDoesSaveUnders")]
+ public bool does_save_unders ();
+
+ [CCode (cname = "XEventMaskOfScreen")]
+ public long event_mask_of_Screen ();
+
+ [CCode (cname = "XHeightMMOfScreen")]
+ public int height_in_mm_of_screen ();
+
+ [CCode (cname = "XHeightOfScreen")]
+ public int height_of_screen ();
+
+ [CCode (cname = "XMaxCmapsOfScreen")]
+ public int max_colormaps_of_screen ();
+
+ [CCode (cname = "XMinCmapsOfScreen")]
+ public int min_colormaps_of_screen ();
+
+ [CCode (cname = "XPlanesOfScreen")]
+ public int planes_of_screen ();
+
+ [CCode (cname = "XRootWindowOfScreen")]
+ public Window root_window_of_screen ();
+
+ [CCode (cname = "XScreenNumberOfScreen")]
+ public int screen_number_of_screen ();
+
+ [CCode (cname = "XWhitePixelOfScreen")]
+ public ulong white_pixel_of_screen ();
+
+ [CCode (cname = "XWidthMMOfScreen")]
+ public int width_in_mm_of_screen ();
+
+ [CCode (cname = "XWidthOfScreen")]
+ public int width_of_screen ();
+ }
+
+ public const X.ID None;
+
+ public const X.Atom XA_ATOM;
+ public const X.Atom XA_CARDINAL;
+ public const X.Atom XA_WINDOW;
+ public const X.Atom XA_WM_CLASS;
+ public const X.Atom XA_WM_HINTS;
+ public const X.Atom XA_WM_ICON_NAME;
+ public const X.Atom XA_WM_NAME;
+ public const X.Atom XA_WM_NORMAL_HINTS;
+ public const X.Atom XA_WM_TRANSIENT_FOR;
+
+ public const uint XK_Num_Lock;
+ public const uint XK_Scroll_Lock;
+ public const uint XK_Super_L;
+ public const uint XK_Super_R;
+}
+
diff --git a/vapi/xtst.vapi b/vapi/xtst.vapi
new file mode 100644
index 0000000..a773dfa
--- /dev/null
+++ b/vapi/xtst.vapi
@@ -0,0 +1,60 @@
+/* xtst.vapi
+ *
+ * Copyright (C) 2011 Alexander Kurtz
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author:
+ * Alexander Kurtz <kurtz.alex@googlemail.com>
+ */
+
+
+[CCode (cprefix = "", lower_case_cprefix = "", cheader_filename = "X11/extensions/XTest.h")]
+namespace X {
+ class Test {
+ [CCode (cname = "XTestQueryExtension")]
+ public static bool query_extension(Display display, out int event_base_return, out int error_base_return, out int major_version_return, out int minor_version_return);
+
+ [CCode (cname = "XTestCompareCursorWithWindow")]
+ public static bool compare_cursor_with_window(Display display, Window window, Cursor cursor);
+
+ [CCode (cname = "XTestCompareCurrentCursorWithWindow")]
+ public static bool compare_current_cursor_with_window(Display display, Window window);
+
+ [CCode (cname = "XTestFakeKeyEvent")]
+ public static int fake_key_event(Display display, uint keycode, bool is_press, ulong delay);
+
+ [CCode (cname = "XTestFakeButtonEvent")]
+ public static int fake_button_event(Display display, uint button, bool is_press, ulong delay);
+
+ [CCode (cname = "XTestFakeMotionEvent")]
+ public static int fake_motion_event(Display display, int screen_number, int x, int y, ulong delay);
+
+ [CCode (cname = "XTestFakeRelativeMotionEvent")]
+ public static int fake_relative_motion_event(Display display, int screen_number, int x, int y, ulong delay);
+
+ [CCode (cname = "XTestGrabControl")]
+ public static int grab_control(Display display, bool impervious);
+
+ [CCode (cname = "XTestSetGContextOfGC")]
+ public static void set_g_context_of_gc(GC gc, GContext gid);
+
+ [CCode (cname = "XTestSetVisualIDOfVisual")]
+ public static void set_visual_id_of_visual(Visual visual, VisualID visualid);
+
+ [CCode (cname = "XTestDiscard")]
+ public static Status discard(Display display);
+ }
+}