Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

added files

  • Loading branch information...
commit d7561567e14641f210a2b2947cd42fa0e305671f 1 parent 6ea172f
Simon Schneegans authored
76 CMakeLists.txt
View
@@ -0,0 +1,76 @@
+################################################################
+# 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(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)
+
+set(CFLAGS
+ ${GTK_CFLAGS} ${GTK_CFLAGS_OTHER}
+ ${CAIRO_CFLAGS} ${CAIRO_CFLAGS_OTHER}
+ ${GEE_CFLAGS} ${CAIRO_CFLAGS_OTHER}
+)
+add_definitions(${CFLAGS})
+
+set(LIBS
+ ${GTK_LIBRARIES}
+ ${CAIRO_LIBRARIES}
+ ${GEE_LIBRARIES}
+)
+link_libraries(${LIBS})
+
+set(LIB_PATHS
+ ${GTK_LIBRARY_DIRS}
+ ${CAIRO_LIBRARY_DIRS}
+ ${GEE_LIBRARY_DIRS}
+)
+link_directories(${LIB_PATHS})
+
+################################################################
+# Add executable
+################################################################
+
+set(EXECUTABLE_OUTPUT_PATH ${gnomepie_SOURCE_DIR})
+
+add_subdirectory(src)
+
+################################################################
+# Summary
+################################################################
+
+message( "" )
+message( "Summary:" )
+message( " EXECUTABLE_OUTPUT_PATH = ${EXECUTABLE_OUTPUT_PATH}" )
+message( " VALA_EXECUTABLE = ${VALA_EXECUTABLE}" )
+message( "Libs:" )
+message( " GTK_LIBRARIES = ${GTK_LIBRARIES}" )
+message( " GTK_LIBRARY_DIRS = ${GTK_LIBRARY_DIRS}" )
+message( " CAIRO_LIBRARIES = ${CAIRO_LIBRARIES}" )
+message( " CAIRO_LIBRARY_DIRS = ${CAIRO_LIBRARY_DIRS}" )
+message( " GEE_LIBRARIES = ${GEE_LIBRARIES}" )
+message( " GEE_LIBRARY_DIRS = ${GEE_LIBRARY_DIRS}" )
+message( "" )
65 cmake/vala/FindVala.cmake
View
@@ -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)
36 cmake/vala/ParseArguments.cmake
View
@@ -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)
175 cmake/vala/ValaPrecompile.cmake
View
@@ -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)
96 cmake/vala/ValaVersion.cmake
View
@@ -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)
22 src/CMakeLists.txt
View
@@ -0,0 +1,22 @@
+################################################################
+# Actually compile the executable
+################################################################
+
+# determine source and header files
+file(GLOB VALA_SRC RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.vala)
+
+# use valac to compile sources to c files
+vala_precompile(
+ VALA_C
+ ${VALA_SRC}
+ PACKAGES
+ gtk+-2.0
+ gdk-2.0
+ gdk-x11-2.0
+ cairo
+ gee-1.0
+ x11
+ gio-unix-2.0
+)
+
+add_executable(gnome-pie ${VALA_C})
187 src/color.vala
View
@@ -0,0 +1,187 @@
+/*
+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 {
+
+ public class Color : GLib.Object {
+
+ private float _r;
+ private float _g;
+ private float _b;
+ private float _a;
+
+ 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;
+ }
+ }
+
+ 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;
+ }
+ }
+
+ 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;
+ }
+ }
+
+ 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;
+ }
+ }
+
+ 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);
+ }
+ }
+
+ 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);
+ }
+ }
+
+ 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);
+ }
+ }
+
+ public Color() {
+ _r = 1.0f;
+ _g = 1.0f;
+ _b = 1.0f;
+ _a = 1.0f;
+ }
+
+ public Color.from_rgb(float red, float green, float blue) {
+ Color.from_rgba(red, green, blue, 1.0f);
+ }
+
+ public Color.from_rgba(float red, float green, float blue, float alpha) {
+ _r = red;
+ _g = green;
+ _b = blue;
+ _a = alpha;
+ }
+
+ 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;
+ }
+ }
+
+ public void invert() {
+ h += 180.0f;
+ v = 1.0f - v;
+ }
+
+ }
+
+}
48 src/deamon.vala
View
@@ -0,0 +1,48 @@
+/*
+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 {
+
+ public class Deamon : GLib.Object {
+
+ private KeybindingManager keys_;
+
+ private Ring ring_;
+
+ private void showRing() {
+ ring_.show();
+ Utils.present_window(ring_);
+
+ Timeout.add ((uint)(1000.0/Utils.refresh_rate), () => {
+ ring_.queue_draw ();
+ return true;
+ });
+ }
+
+ public Deamon() {
+ ring_ = new Ring();
+ keys_ = new KeybindingManager();
+ keys_.bind("<Alt>V", showRing);
+ }
+
+ public void run() {
+ Gtk.main();
+ }
+
+ }
+
+}
128 src/keybindings.vala
View
@@ -0,0 +1,128 @@
+
+namespace GnomePie {
+
+ public class KeybindingManager : GLib.Object {
+
+ private Gee.List<Keybinding> bindings = new Gee.ArrayList<Keybinding>();
+
+ // Locked modifiers used to grab all keys whatever lock key is pressed.
+ private static uint[] lock_modifiers = {
+ 0,
+ Gdk.ModifierType.MOD2_MASK, // NUM_LOCK
+ Gdk.ModifierType.LOCK_MASK, // CAPS_LOCK
+ Gdk.ModifierType.MOD5_MASK, // SCROLL_LOCK
+ 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, KeybindingHandlerFunc handler) {
+ this.accelerator = accelerator;
+ this.keycode = keycode;
+ this.modifiers = modifiers;
+ this.handler = handler;
+ }
+
+ public string accelerator { get; set; }
+ public int keycode { get; set; }
+ public Gdk.ModifierType modifiers { get; set; }
+ public KeybindingHandlerFunc handler { get; set; }
+ }
+
+ // Keybinding func needed to bind key to handler
+ public delegate void KeybindingHandlerFunc(Gdk.Event event);
+
+ public KeybindingManager() {
+ // init filter to retrieve X.Events
+ Gdk.Window rootwin = Gdk.get_default_root_window();
+ if(rootwin != null) {
+ rootwin.add_filter(event_filter);
+ }
+ }
+
+ // Bind accelerator to given handler
+ public void bind(string accelerator, KeybindingHandlerFunc handler) {
+ debug("Binding key " + accelerator);
+
+ // convert accelerator
+ uint keysym;
+ Gdk.ModifierType modifiers;
+ Gtk.accelerator_parse(accelerator, out keysym, out modifiers);
+
+ 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) {
+ // trap XErrors to avoid closing of application
+ // even when grabing of key fails
+ Gdk.error_trap_push();
+
+ // grab key finally
+ // also grab all keys which are combined with a lock key such NumLock
+ foreach(uint lock_modifier in lock_modifiers) {
+ display.grab_key(keycode, modifiers|lock_modifier, xid, false, X.GrabMode.Async, X.GrabMode.Async);
+ }
+
+ // wait until all X request have been processed
+ Gdk.flush();
+
+ // store binding
+ Keybinding binding = new Keybinding(accelerator, keycode, modifiers, handler);
+ bindings.add(binding);
+
+ debug("Successfully bound key " + accelerator);
+ }
+ }
+
+ // Unbind given accelerator.
+ public void unbind(string accelerator) {
+ debug("Unbinding key " + accelerator);
+
+ 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);
+
+ // unbind all keys with given accelerator
+ Gee.List<Keybinding> remove_bindings = new Gee.ArrayList<Keybinding>();
+ foreach(Keybinding binding in bindings) {
+ if(str_equal(accelerator, binding.accelerator)) {
+ foreach(uint lock_modifier in lock_modifiers) {
+ display.ungrab_key(binding.keycode, binding.modifiers, xid);
+ }
+ remove_bindings.add(binding);
+ }
+ }
+
+ // remove unbinded keys
+ bindings.remove_all(remove_bindings);
+ }
+
+ // Event filter method needed to fetch X.Events
+ public 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(Keybinding 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) {
+ // call all handlers with pressed key and modifiers
+ binding.handler(gdk_event);
+ }
+ }
+ }
+
+ return filter_return;
+ }
+ }
+
+}
25 src/main.vala
View
@@ -0,0 +1,25 @@
+/*
+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/>.
+*/
+
+int main (string[] args) {
+ Gtk.init (ref args);
+
+ var deamon = new GnomePie.Deamon();
+ deamon.run();
+
+ return 0;
+}
171 src/ring.vala
View
@@ -0,0 +1,171 @@
+/*
+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 {
+
+ public class Ring : Gtk.Window {
+
+ private Cairo.ImageSurface imgRing_;
+ private Cairo.ImageSurface imgGlow_;
+ private Cairo.ImageSurface imgArrow_;
+
+ private double rot_= 0.0;
+ private double baseRot_ = 0.0;
+
+ private Slice[] slices_;
+ private int _activeSlice = -1;
+
+ private int size_ = 400;
+
+ private void mousePressed(int button, int x, int y) {
+ if (button == 1) {
+ for (int s=0; s<slices_.length; ++s) {
+ slices_[s].mousePressed();
+ }
+ hide();
+ }
+ }
+
+ private void addSlice(string command, string icon) {
+ slices_ += new Slice(command, icon);
+ }
+
+ private bool draw(Gtk.Widget da, Gdk.EventExpose event) {
+
+ double mouse_x = 0;
+ double mouse_y = 0;
+ get_pointer(out mouse_x, out mouse_y);
+
+ var ctx = Gdk.cairo_create(da.window);
+
+ // clear the window
+ ctx.set_operator (Cairo.Operator.CLEAR);
+ ctx.paint();
+
+ mouse_x -= size_*0.5;
+ mouse_y -= size_*0.5;
+ double distance = sqrt(mouse_x*mouse_x + mouse_y*mouse_y);
+
+ baseRot_ += 0.5/Utils.refresh_rate;
+
+ ctx.set_operator(Cairo.Operator.DEST_OVER);
+ ctx.set_source_rgb(1, 1, 1);
+
+ double angle = -1;
+
+ if (distance > 45) {
+
+ angle = acos(mouse_x/distance);
+ double test = mouse_x*sin(rot_) - mouse_y*cos(rot_);
+
+ if (mouse_y < 0)
+ angle = 2*PI - angle;
+
+ if (fabs(angle - rot_) > 0.15) {
+ if (test < 0) rot_ += 8.0/Utils.refresh_rate;
+ else rot_ -= 8.0/Utils.refresh_rate;
+ }
+ else {
+ rot_ = angle;
+ }
+
+ rot_ = fmod(rot_+2*PI, 2*PI);
+
+ ctx.translate(size_*0.5, size_*0.5);
+ ctx.rotate(rot_);
+
+ double alpha = distance > 65 ? 1.0 : 1.0 - 0.05*(65-distance);
+
+ ctx.set_source_surface(imgArrow_, -75, -75);
+ ctx.paint_with_alpha(alpha);
+
+ ctx.identity_matrix();
+ }
+
+ ctx.translate(size_*0.5, size_*0.5);
+ ctx.rotate(baseRot_);
+
+ ctx.set_source_surface(imgRing_, -75, -75);
+ ctx.paint();
+
+ ctx.set_source_surface(imgGlow_, -75, -75);
+ ctx.paint_with_alpha(0.7);
+
+ ctx.set_operator(Cairo.Operator.ATOP);
+ if (_activeSlice >= 0)
+ ctx.set_source_rgb(slices_[_activeSlice].color.r, slices_[_activeSlice].color.g, slices_[_activeSlice].color.b);
+ else
+ ctx.set_source_rgb(0.5, 0.5, 0.5);
+
+ ctx.rectangle (-size_*0.5, -size_*0.5, size_, size_);
+ ctx.fill ();
+ ctx.stroke ();
+
+ ctx.set_operator(Cairo.Operator.OVER);
+
+ _activeSlice = -1;
+
+ for (int s=0; s<slices_.length; ++s) {
+ ctx.identity_matrix();
+ ctx.translate(size_*0.5, size_*0.5);
+ slices_[s].draw(ctx, angle, s, slices_.length);
+
+ if(slices_[s].active)
+ _activeSlice = s;
+ }
+
+ return true;
+ }
+
+ public Ring() {
+ title = "Gnome-Pie";
+ set_default_size (size_, size_);
+ set_skip_taskbar_hint(true);
+ set_skip_pager_hint(true);
+ set_keep_above(true);
+ set_type_hint(Gdk.WindowTypeHint.NORMAL);
+ set_colormap(this.screen.get_rgba_colormap());
+ position = Gtk.WindowPosition.MOUSE;
+ decorated = false;
+ app_paintable = true;
+
+ add_events(Gdk.EventMask.BUTTON_PRESS_MASK);
+
+ this.button_press_event.connect ((e) => {
+ mousePressed((int) e.button, (int) e.x, (int) e.y);
+ return true;
+ });
+
+ expose_event.connect(draw);
+ destroy.connect (Gtk.main_quit);
+
+ imgRing_ = new Cairo.ImageSurface.from_png("data/ring.png");
+ imgGlow_ = new Cairo.ImageSurface.from_png("data/glow.png");
+ imgArrow_ = new Cairo.ImageSurface.from_png("data/arrow.png");
+
+ slices_ = new Slice[0];
+
+ addSlice("firefox.desktop", "firefox");
+ addSlice("eog.desktop", "eog");
+ addSlice("gnome-terminal.desktop", "terminal");
+ addSlice("thunderbird.desktop", "thunderbird");
+ addSlice("blender.desktop", "blender");
+ }
+ }
+}
0  src/settings.vala
View
No changes.
89 src/slice.vala
View
@@ -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/>.
+*/
+
+using GLib.Math;
+
+namespace GnomePie {
+
+ public class Slice : GLib.Object {
+
+ private Cairo.ImageSurface _img;
+ private string _command;
+
+ public Color color {get; private set;}
+ public bool active {get; private set; default=false;}
+
+ public Slice(string command, string icon) {
+ _command = command;
+
+ var icon_theme = Gtk.IconTheme.get_default();
+ var file = icon_theme.lookup_icon(icon, 48, Gtk.IconLookupFlags.NO_SVG);
+
+ debug(file.get_filename());
+
+ _img = new Cairo.ImageSurface.from_png(file.get_filename());
+ //img_active = _img;
+
+ Utils.get_icon_color(_img, out _color);
+ }
+
+ public void mousePressed() {
+ if (_active) {
+ try{
+ GLib.DesktopAppInfo item = new GLib.DesktopAppInfo(_command);
+ item.launch (null, new AppLaunchContext());
+ debug("launched " + _command);
+ } catch (Error e) {
+ warning (e.message);
+ }
+ }
+ }
+
+ public void draw(Cairo.Context ctx, double mouse_dir, int position, int total) {
+ double maxZoom = 1.3;
+ double affected = 0.3;
+ double distance = 110;
+ double direction = 2.0*PI*position/total;
+ double scale = 1;
+
+ // if mouse is not inside ring
+ if (mouse_dir > 0) {
+ double diff = fabs(mouse_dir-direction);
+ if (diff > PI)
+ diff = 2*PI - diff;
+
+ if (diff < 2*PI*affected)
+ scale = maxZoom/(diff*(maxZoom-1)/(2*PI*affected)+1);
+
+ if (diff < PI/total) _active = true;
+ else _active = false;
+
+ } else {
+ _active = false;
+ }
+
+ ctx.scale(scale, scale);
+ ctx.translate(cos(direction)*distance, sin(direction)*distance);
+
+ //if (_active) ctx.set_source_surface(img_active, -0.5*_img.get_width(), -0.5*_img.get_height());
+ /*else*/ ctx.set_source_surface(_img, -0.5*_img.get_width(), -0.5*_img.get_height());
+
+ ctx.paint();
+ }
+ }
+
+}
112 src/utils.vala
View
@@ -0,0 +1,112 @@
+/*
+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.Utils {
+
+ public double refresh_rate = 60.0;
+
+ // Code from Unity
+ public void get_icon_color(Cairo.ImageSurface icon, out Color color) {
+
+ unowned uchar[] data = icon.get_data();
+
+ uint width = icon.get_width();
+ uint height = icon.get_height();
+ uint row_bytes = icon.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;
+
+ // stdout.printf("%4i", (int)(saturation*255.0));
+
+ rtotal += (r * relevance);
+ gtotal += (g * relevance);
+ btotal += (b * relevance);
+
+ total += relevance;
+ }
+
+ // stdout.printf("%\n");
+ }
+
+ color = new Color.from_rgb((float)(rtotal/total), (float)(gtotal/total), (float)(btotal/total));
+
+ if (color.s > 0.15f)
+ color.s = 0.65f;
+
+ color.v = 1.0f;
+ }
+
+ // Code from Gnome-Do/Synapse
+ public static void present_window(Gtk.Window window) {
+ // raise without grab
+ uint32 timestamp = Gtk.get_current_event_time();
+ window.present_with_time(timestamp);
+ window.get_window().raise();
+ window.get_window().focus(timestamp);
+
+ // grab
+ int i = 0;
+ Timeout.add (100, ()=>{
+ if (i >= 100) return false;
+ ++i;
+ return !try_grab_window(window);
+ });
+ }
+
+ // Code from Gnome-Do/Synapse
+ public static void unpresent_window(Gtk.Window window) {
+ uint32 time = Gtk.get_current_event_time();
+
+ Gdk.pointer_ungrab (time);
+ Gdk.keyboard_ungrab (time);
+ Gtk.grab_remove (window);
+ }
+
+ // Code from Gnome-Do/Synapse
+ private static bool try_grab_window(Gtk.Window window) {
+ uint time = Gtk.get_current_event_time();
+ if (Gdk.pointer_grab (window.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(window.get_window(), true, time) == Gdk.GrabStatus.SUCCESS) {
+ Gtk.grab_add(window);
+ return true;
+ } else {
+ Gdk.pointer_ungrab(time);
+ return false;
+ }
+ }
+ return false;
+ }
+}
Please sign in to comment.
Something went wrong with that request. Please try again.